Re: alias and extern(C) for callbacks
On 2013-08-23 02:00, Andrej Mitrovic wrote: static assert(functionLinkage!test2 != C); // D calling convention Or Windows, Pascal or C++. -- /Jacob Carlborg
SysTime at compile time
There's a way to use a SysTime at compile-time? It seems impossible right now for the presence of the TimeZone. I want to insert some time-related fields in some structs, but I need to have some compile-time check with 'static assert' here and there... Suggestions are welcome, thanks! Paolo Invernizzi
Re: alias and extern(C) for callbacks
On 8/23/13, Jacob Carlborg d...@me.com wrote: On 2013-08-23 02:00, Andrej Mitrovic wrote: static assert(functionLinkage!test2 != C); // D calling convention Or Windows, Pascal or C++. I'd prefer if functionLinkage returned an enum, it's too easy to write c instead of C in some generic code and have a static if branch not taken.
Re: alias and extern(C) for callbacks
On 2013-08-23 13:10, Andrej Mitrovic wrote: I'd prefer if functionLinkage returned an enum, it's too easy to write c instead of C in some generic code and have a static if branch not taken. Yeah, that's a good point. -- /Jacob Carlborg
Re: Associative array key order
https://github.com/Kozzi11/Trash/blob/master/util/orderedaa.d On Thursday, 22 August 2013 at 08:41:13 UTC, monarch_dodra wrote: On Thursday, 22 August 2013 at 07:59:05 UTC, Daniel Kozak wrote: On Wednesday, 31 July 2013 at 14:55:55 UTC, Dicebot wrote: On Wednesday, 31 July 2013 at 14:43:21 UTC, Daniel Kozak wrote: is there a way for AA to behave same as PHP? I doubt it. This snippet suggests that AA's in PHP are not simply AA's and do additionally track insertion order (or use some similar trick). Data in associative arrays is organized in a way that allows fast key lookup and iterating in an original order requires tracking extra state. Contrary to PHP, D does care about performance so I see no way this can happen automatically. I implemented my own OrderedAA type, which is able to preserve insert order and is a little faster and take less memory(30%) then the builtin one :-). But definitly there will be some cases where my own implementation doesn't beat the builtin one. Nice to hear. Perhaps you could share the implementation with us? Even if its not perfect, I'm curious to know how you went at it.
Re: Associative array key order
When I do some cleanups, I find some bugs and after fixing them, my own OrderedAA implementation does not beat builtin hash anymore :(. But speed is still really near to builtin AA's. On Thursday, 22 August 2013 at 07:59:05 UTC, Daniel Kozak wrote: On Wednesday, 31 July 2013 at 14:55:55 UTC, Dicebot wrote: On Wednesday, 31 July 2013 at 14:43:21 UTC, Daniel Kozak wrote: is there a way for AA to behave same as PHP? I doubt it. This snippet suggests that AA's in PHP are not simply AA's and do additionally track insertion order (or use some similar trick). Data in associative arrays is organized in a way that allows fast key lookup and iterating in an original order requires tracking extra state. Contrary to PHP, D does care about performance so I see no way this can happen automatically. I implemented my own OrderedAA type, which is able to preserve insert order and is a little faster and take less memory(30%) then the builtin one :-). But definitly there will be some cases where my own implementation doesn't beat the builtin one.
pointers, null and Typedef...
so, here's the situation: current old code has: typedef const(void*) T0, T1; which is of course deprecated. context that needs to work: struct A { T0 t; this(T0 init) { t = init; } } Also, I need type-safety. is(T0 == T1) *must* be false. I have a modified Typedef I'm using to get things started, allowing Typedef!(const(void*), const(void*).init, T0) to work at all: struct Typedef(T, T init = T.init, string cookie=null) { static if(init != T.init) { private T Typedef_payload = init; } else { private T Typedef_payload; } this(T initial) { Typedef_payload = initial; } this(typeof(this) initial) { Typedef_payload = initial.Typedef_payload; } mixin Proxy!(Typedef_payload); } but that doesn't get me all of the way, there's still no way I can see to get the t = init to work. I wish there was some way to call a constructor on a object after it is declared (perhaps with the same rules as const initialisation?).
Re: Associative array key order
On Fri, Aug 23, 2013 at 01:54:27PM +0200, Daniel Kozak wrote: https://github.com/Kozzi11/Trash/blob/master/util/orderedaa.d [...] Neat! Is a doubly-linked list really necessary for the hash buckets? You could save on some memory improve performance slightly if you use a singly-linked list for the buckets, but still keep the left/right pointers for retaining insertion order. It will also simplify your code a bit. T -- If Java had true garbage collection, most programs would delete themselves upon execution. -- Robert Sewell
Re: Associative array key order
H. S. Teoh: ... On this subject, I added this request to Bugzilla: http://d.puremagic.com/issues/show_bug.cgi?id=10733 Bye, bearophile
Re: Associative array key order
H. S. Teoh: ... Your answer was really too much short, so I have asked you a question in that enhancement request :-) Bye, bearophile
Re: Associative array key order
On Jul 31, 2013, at 7:55 AM, Dicebot pub...@dicebot.lv wrote: On Wednesday, 31 July 2013 at 14:43:21 UTC, Daniel Kozak wrote: is there a way for AA to behave same as PHP? I doubt it. This snippet suggests that AA's in PHP are not simply AA's and do additionally track insertion order (or use some similar trick). Data in associative arrays is organized in a way that allows fast key lookup and iterating in an original order requires tracking extra state. Contrary to PHP, D does care about performance so I see no way this can happen automatically. This seems more likely to be a library type. I have something like this that I use very frequently at work where the behavior is pluggable, so it can be used as a cache that automatically does LIFO/FIFO eviction according to an age window, number of entries, etc. Or none of those if all you want is a plain old hashtable. It's not a tremendous amount of work to adapt an existing implementation to work this way. The only annoying bit I ran into (at least with C++) is that the symbol lookup rules pretty much prevent overrides of existing functions to be mixed in via the policies. Does alias this work around this problem in D? I've never tried.
Re: pointers, null and Typedef...
On Friday, 23 August 2013 at 12:17:08 UTC, John Colvin wrote: so, here's the situation: On 2.063.2 why not something like this: --- import std.typecons; alias T0 = Typedef!(void*, null, T0); alias T1 = Typedef!(void*, null, T1); static assert( ! is(T0 == T1)); struct A { T0 t; this(T0 init) { t = init; } } void foo(){ auto a = A(T0(null)); // auto b = A(T1(null)); Error! } --- Paolo
Re: Associative array key order
On Fri, Aug 23, 2013 at 11:22:47AM -0700, Sean Kelly wrote: On Jul 31, 2013, at 7:55 AM, Dicebot pub...@dicebot.lv wrote: On Wednesday, 31 July 2013 at 14:43:21 UTC, Daniel Kozak wrote: is there a way for AA to behave same as PHP? I doubt it. This snippet suggests that AA's in PHP are not simply AA's and do additionally track insertion order (or use some similar trick). Data in associative arrays is organized in a way that allows fast key lookup and iterating in an original order requires tracking extra state. Contrary to PHP, D does care about performance so I see no way this can happen automatically. This seems more likely to be a library type. I have something like this that I use very frequently at work where the behavior is pluggable, so it can be used as a cache that automatically does LIFO/FIFO eviction according to an age window, number of entries, etc. Or none of those if all you want is a plain old hashtable. It's not a tremendous amount of work to adapt an existing implementation to work this way. The only annoying bit I ran into (at least with C++) is that the symbol lookup rules pretty much prevent overrides of existing functions to be mixed in via the policies. Does alias this work around this problem in D? I've never tried. In http://d.puremagic.com/issues/show_bug.cgi?id=10733 bearophile and I discussed code reuse between the current AA and an ordered AA implementation. It appears that a more fundamental structure is the Set, where the key is the value. An AA can be implemented in terms of a Set, by making the set element a struct containing a key and value field, with a custom toHash() and opCmp() that only hashes/compares the key part. By adding a pair of pointers to this customized set element, we can make an ordered AA in terms of Set. Plus, a Set is something that's very useful on its own as well. T -- Береги платье снову, а здоровье смолоду.
Re: SysTime at compile time
On Friday, August 23, 2013 10:39:56 Paolo Invernizzi wrote: There's a way to use a SysTime at compile-time? It seems impossible right now for the presence of the TimeZone. I want to insert some time-related fields in some structs, but I need to have some compile-time check with 'static assert' here and there... Getting the system time would require calling C functions (which never works in CTFE), so you can't do what you're trying to do with any CTFE solution, let alone SysTime. Even if there were no TimeZone, it couldn't be done. You might be able to do something with __DATE__, __TIME__, or __TIMESTAMP__ though: http://dlang.org/lex.html#specialtokens However, they're generated when they're compiled, not when running a function, so they coludn't be generated by a CTFE function as it ran, and their values might stay the same across the entire build anyway, which may or may not be a problem depending on what you're doing. They also go to seconds at the highest precision, which may or may not be a problem depending on what you're doing. But I think that they're your only chance at getting the time at compile time. - Jonathan M Davis
InExpression with custom type?
Hello! Is it possible to make an InExpression work with a used-defined type? struct MyCollection { ... } MyCollection mc; auto p = 123 in mc; if (p) { ... } Thanks! LMB
Re: InExpression with custom type?
On Friday, 23 August 2013 at 19:57:42 UTC, Leandro Motta Barros wrote: Hello! Is it possible to make an InExpression work with a used-defined type? struct MyCollection { ... } MyCollection mc; auto p = 123 in mc; if (p) { ... } Thanks! LMB Yes, use opBinaryRight: T* opBinaryRight(stirng op : in)(...)
Re: InExpression with custom type?
Thanks! LMB On Fri, Aug 23, 2013 at 4:59 PM, Namespace rswhi...@googlemail.com wrote: On Friday, 23 August 2013 at 19:57:42 UTC, Leandro Motta Barros wrote: Hello! Is it possible to make an InExpression work with a used-defined type? struct MyCollection { ... } MyCollection mc; auto p = 123 in mc; if (p) { ... } Thanks! LMB Yes, use opBinaryRight: T* opBinaryRight(stirng op : in)(...)
Re: Partially constructed objects in various languages
On Tue, Aug 20, 2013 at 04:55:21AM +0200, bearophile wrote: Perhaps this thread deserves a D implementation with a small explanation regarding D: http://www.reddit.com/r/programming/comments/1kof0q/on_partiallyconstructed_objects/ (__ctWriteln is not yet available in D.) [...] One issue he brought up that he didn't really address, was what to do if a ctor throws before fully initializing all fields. For example: class A { ~this() { ... } } class B { ~this() { ... } } class C { A a; B b; this() { a = new A(); if (someCondition) throw new Exception(...); b = new B(); } } The problem is, how would the compiler know to call A.~this, but not B.~this when the Exception is thrown? Also, the whole deal with partially-constructed objects seems to be related to a recent thread about encapsulating ctor parameters and objects being created first then kicked into shape (create-set-call pattern) vs. passing everything to the ctor in one go (long ctor argument list). It seems ultimately to boil down to recognizing that there's a transition point between an object's creation and its reaching a fully-valid initial state. Before this transition takes place, the object is in a partially-constructed state, and may violate class invariants. At the transition point, the ctor (or whatever's responsible for turning the object into a fully-constructed state) verifies that all constraints are met, before the object is regarded as a full instance of its class. This seems reminiscient of Perl's approach of creating an object as a normal hash, then blessing it into a full-fledged class instance once it's fully initialized. T -- Long, long ago, the ancient Chinese invented a device that lets them see through walls. It was called the window.
Re: SysTime at compile time
On Friday, 23 August 2013 at 19:07:06 UTC, Jonathan M Davis wrote: On Friday, August 23, 2013 10:39:56 Paolo Invernizzi wrote: There's a way to use a SysTime at compile-time? It seems impossible right now for the presence of the TimeZone. I want to insert some time-related fields in some structs, but I need to have some compile-time check with 'static assert' here and there... Getting the system time would require calling C functions (which never works in CTFE), so you can't do what you're trying to do with any CTFE solution, let alone SysTime. Even if there were no TimeZone, it couldn't be done. Thank you Jonathan, in reality I'm not interested in obtaining the current time ('Clock.currTIme' et similia), but only in checking some basic behaviour involving already forged times. Something works, in a limited and constrained way, but it seems that there's a problem with 'Rebindable' in CTFE: --- enum t = SysTime(0, UTC()); pragma(msg, t); // SysTime(0L, Rebindable(, (UTC(UTC, UTC, UTC // enum t2 = t + msecs(1000); // typecons.d(956): Error: cannot read uninitialized variable this.original in ctfe enum d = SysTime(1000, UTC()) - SysTime(10, UTC()); pragma(msg, d); // Duration(990L) --- Paolo Invernizzi
Template alias parameter: error: need 'this' for ...
Hello! I've run into this issue that I don't understand, maybe someone can enlighten me. :) This code: --- struct Thing { int i; } void main() { t!(Thing.i)(); } void t(alias a)() { return; } --- fails to compile with: ‘Error: need 'this' for 't' of type 'pure nothrow @safe void()'’. If I declare ‘t’ as static, it works (and does what I want it to do).
Re: Partially constructed objects in various languages
On Fri, Aug 23, 2013 at 01:39:05PM -0700, H. S. Teoh wrote: On Tue, Aug 20, 2013 at 04:55:21AM +0200, bearophile wrote: Perhaps this thread deserves a D implementation with a small explanation regarding D: http://www.reddit.com/r/programming/comments/1kof0q/on_partiallyconstructed_objects/ (__ctWriteln is not yet available in D.) [...] One issue he brought up that he didn't really address, was what to do if a ctor throws before fully initializing all fields. For example: class A { ~this() { ... } } class B { ~this() { ... } } class C { A a; B b; this() { a = new A(); if (someCondition) throw new Exception(...); b = new B(); } } The problem is, how would the compiler know to call A.~this, but not B.~this when the Exception is thrown? [...] Actually, a better example might be: class C { Resource1 res1; Resource2 res2; Resource3 res3; this() { res1 = acquireResource!1(); res2 = acquireResource!2(); if (someCondition) throw new Exception(...); res3 = acquireResource!3(); } ~this() { res3.release(); res2.release(); res1.release(); } } The problem is, once the Exception is thrown, what do you do? You can't call the dtor (res3.release() is invalid because res3 hasn't been acquired yet), but you do need to cleanup (res1 and res2 must be released). This is one area where the conventional ctor/dtor scheme does not work very well. Essentially you have to uglify your code by making Resource1, Resource2, Resource3 nullable, then in the dtor you check for null before releasing it: class C { Nullable!Resource1 res1; ... // etc. this() { /* as before */ } ... ~this() { if (res3 !is null) res3.release(); if (res2 !is null) res2.release(); if (res1 !is null) res1.release(); } } Or, as Adam Ruppe once did in his Terminal code, you implement a kind of class-wide scope guard: class C { void delegate()[] cleanupFuncs; Resource1 res1; Resource2 res2; Resource3 res3; this() { res1 = acquireResource!1(); cleanupFuncs ~= { res1.release(); }; res2 = acquireResource!2(); cleanupFuncs ~= { res2.release(); }; res3 = acquireResource!3(); cleanupFuncs ~= { res3.release(); }; } ~this { foreach_reverse(f; cleanupFuncs) { f(); } } } This has the nice property that, like scope guards, the cleanup sits next to the initialization, so it's less prone to mistakes (e.g. ctor gets changed to acquire a 4th resource, but the author forgot to add a corresponding release() to the dtor). It also has the property that only resources that are actually acquired will get cleaned up, making the dtor safe to call if the ctor throws. So for example, if acquireResource!3() throws an Exception, then only res1 and res2's cleanup delegates are registered, so the dtor will only clean up res1 and res2 and leave res3 untouched, which is correct since res3 was never initialized. Hmm. On second thoughts, maybe we should have language-support for this kind of class-wide (or struct-wide) scope guard, and deprecate dtors, which are unreliable anyways due to the GC. So maybe something like: class C { Resource1 res1; Resource2 res2; Resource3 res3; this() { res1 = acquireResource!1(); scope(class) res1.release(); res2 = acquireResource!2(); scope(class) res2.release(); res3 = acquireResource!3(); scope(class) res3.release(); } // no explicit dtor necessary, compiler supplies one for you // composed of all the scope(class) blocks encountered // in the ctor. } I actually like this idea a lot! It addresses the partially-constructed object problem in a nice way, and also extend scope guards to be applicable in more situations. (It feels like such a pity that a clever feature like scope guards would
Re: SysTime at compile time
On Friday, August 23, 2013 22:46:34 Paolo Invernizzi wrote: Thank you Jonathan, in reality I'm not interested in obtaining the current time ('Clock.currTIme' et similia), but only in checking some basic behaviour involving already forged times. Something works, in a limited and constrained way, but it seems that there's a problem with 'Rebindable' in CTFE: --- enum t = SysTime(0, UTC()); pragma(msg, t); // SysTime(0L, Rebindable(, (UTC(UTC, UTC, UTC // enum t2 = t + msecs(1000); // typecons.d(956): Error: cannot read uninitialized variable this.original in ctfe enum d = SysTime(1000, UTC()) - SysTime(10, UTC()); pragma(msg, d); // Duration(990L) --- Rebindable should work in CTFE eventually: http://d.puremagic.com/issues/show_bug.cgi?id=10035 However, LocalTime will never work in CTFE, because it has to call tzset. So, it may work eventually to create a SysTime with UTC or a SimpleTimeZone but not LocalTime, and unfortunately, that means that I can never make SysTime.init valid without adding a bunch of null checks to SysTime (which I don't want to do) or making it so that LocalTime always has to check whether tzset has been called and call it if it hasn't instead of calling it when you get the singleton (which I don't really want to do either). So, you might be able to get some of what you want eventually, but SysTime will never fully work at compile time with the local time zone or with getting the current time. - Jonathan M Davis
Re: Template alias parameter: error: need 'this' for ...
On Friday, August 23, 2013 23:28:46 Matej Nanut wrote: Hello! I've run into this issue that I don't understand, maybe someone can enlighten me. :) This code: --- struct Thing { int i; } void main() { t!(Thing.i)(); } void t(alias a)() { return; } --- fails to compile with: ‘Error: need 'this' for 't' of type 'pure nothrow @safe void()'’. If I declare ‘t’ as static, it works (and does what I want it to do). Because without static it's a member variable, which means that you have to have a constructed object to access it (since it's part of the object). When you declare a variable in a class or struct static, then there's only one for the entire class or struct, so it can be accessed without an object. And when you do StructName.var or ClassName.var your accessing the variable via the struct or class rather than an object, so the variable must be static. - Jonathan M Davis
is the tools part of the test suite? currently tools/ddemangle doesn't compile on git master
More often than not, the tools submodule ( https://github.com/D-Programming-Language/tools) will not build on git master. So I'm wondering whether it's even being tested before pushing commits. The error I have now is with ddemangle: std.md5 is scheduled for deprecation. Please use std.digest.md instead phobos/std/regex.d(6706): Error: template D main.__lambda3 does not match any function template declaration. Candidates are: ddemangle.d(57):ddemangle.main.__lambda3(__T2)(a) (this is the line: writeln(replace!((a) = demangle(a.hit))(line, r));)
Re: is the tools part of the test suite? currently tools/ddemangle doesn't compile on git master
On Fri, Aug 23, 2013 at 08:20:29PM -0700, Timothee Cour wrote: More often than not, the tools submodule ( https://github.com/D-Programming-Language/tools) will not build on git master. So I'm wondering whether it's even being tested before pushing commits. The error I have now is with ddemangle: std.md5 is scheduled for deprecation. Please use std.digest.md instead phobos/std/regex.d(6706): Error: template D main.__lambda3 does not match any function template declaration. Candidates are: ddemangle.d(57):ddemangle.main.__lambda3(__T2)(a) (this is the line: writeln(replace!((a) = demangle(a.hit))(line, r));) Please file a bug, I'll look into it. T -- The diminished 7th chord is the most flexible and fear-instilling chord. Use it often, use it unsparingly, to subdue your listeners into submission!
Re: is the tools part of the test suite? currently tools/ddemangle doesn't compile on git master
sure, I'll file a bug, but I'd like to know whether the auto tester checks for these before a push is made to master: * tools * tools/update.sh (which is supposed to build everything) * docs each time i check, it fails in some new, creative ways On Fri, Aug 23, 2013 at 9:20 PM, H. S. Teoh hst...@quickfur.ath.cx wrote: On Fri, Aug 23, 2013 at 08:20:29PM -0700, Timothee Cour wrote: More often than not, the tools submodule ( https://github.com/D-Programming-Language/tools) will not build on git master. So I'm wondering whether it's even being tested before pushing commits. The error I have now is with ddemangle: std.md5 is scheduled for deprecation. Please use std.digest.md instead phobos/std/regex.d(6706): Error: template D main.__lambda3 does not match any function template declaration. Candidates are: ddemangle.d(57):ddemangle.main.__lambda3(__T2)(a) (this is the line: writeln(replace!((a) = demangle(a.hit))(line, r));) Please file a bug, I'll look into it. T -- The diminished 7th chord is the most flexible and fear-instilling chord. Use it often, use it unsparingly, to subdue your listeners into submission!