Re: object.factory with template classes for serializing subclasses automatically
On 2012-09-11 07:57, Chris Cain wrote: Ah, I see now. Well regardless, it couldn't be done so conveniently/transparently because Serializable!B wouldn't exist in the binary unless it was actually created in code. Hence proper runtime reflection is needed. I see no way out of this. -- /Jacob Carlborg
Re: object.factory with template classes for serializing subclasses automatically
On Tuesday, 11 September 2012 at 04:47:11 UTC, timotheecour wrote: Also, now that I think about it, why couldn't you do this? (it's equivalent): auto serialize(T)(T a) { auto c = cast(SerializerBase) new Serializer!T; return c.serialize(a); } that won't work with my example: class A{} class B:A{int x;} A a=new B; auto c=serialize(a); => T is A, but we want B so that serialization includes field x. Ah, I see now. Well regardless, it couldn't be done so conveniently/transparently because Serializable!B wouldn't exist in the binary unless it was actually created in code.
Re: bigint <-> python long
On Mon, 2012-09-10 at 15:54 -0700, Ellery Newcomer wrote: […] > Bugger, I'm going to have to go through pyd and replace all usages > of str with unicode. Python 2 and Python 3 are totally different in this regard. I don't have a obvious proposal to make to avoid having PyD for Python 2 and a different PyD for Python 3, but the six package might have some hints as it is intended to support creating Python codebases guaranteed to run under Python 2 and Python 3. It is a pity the world doesn't just spontaneously switch to Python 3 so that Python 2 is just a "we used to use that" technology." -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: object.factory with template classes for serializing subclasses automatically
Also, now that I think about it, why couldn't you do this? (it's equivalent): auto serialize(T)(T a) { auto c = cast(SerializerBase) new Serializer!T; return c.serialize(a); } that won't work with my example: class A{} class B:A{int x;} A a=new B; auto c=serialize(a); => T is A, but we want B so that serialization includes field x.
Re: object.factory with template classes for serializing subclasses automatically
On Tuesday, 11 September 2012 at 03:18:40 UTC, timotheecour wrote: auto serialize(T)(T a){ auto c=cast(SerializerBase)Object.factory("Serializer!("~typeid(a).to!string~").Serializer"); return c.serialize(a); } Also, now that I think about it, why couldn't you do this? (it's equivalent): auto serialize(T)(T a) { auto c = cast(SerializerBase) new Serializer!T; return c.serialize(a); }
Re: object.factory with template classes for serializing subclasses automatically
On Tuesday, 11 September 2012 at 03:18:40 UTC, timotheecour wrote: So the question is: is that technically impossible or not to enhance Object.factory in such ways? Unless someone else wants to correct me, I'm going to say technically impossible. Object.factory constructs a class at runtime given a string of the name of the class. Templates, however, are created at compile-time only. Basically, the compiler creates a new type every time it sees a template being used with new template arguments. So, as you can imagine, there doesn't exist any object for Object.factory to find at run time. Technically, code like this MIGHT be possible: --- import std.stdio; class MyB(T) { this() { writeln("hello MyB!(" ~ T.stringof ~")"); } } void main() { // create the actual type at compile-time Object b = Object.factory(MyB!int.classinfo.name); writeln("b = ", b); } --- In this case, the type (I'd think) is actually created at compile-time, so it actually exists so that Object.factory can get it. However, the code you showed in your previous post (just purely existing in the string) could never work.
Re: object.factory with template classes for serializing subclasses automatically
I don't understand how Object.factory could help with serializing. But what would help is if we did get proper runtime reflection. All that'd be needed would be to have Object.factory working with templates, here's how: unittest{ class A{} class B{int x;} A a=new B; auto c=serialize(a);//will serialize field "x", no need to register!B } auto serialize(T)(T a){ auto c=cast(SerializerBase)Object.factory("Serializer!("~typeid(a).to!string~").Serializer"); return c.serialize(a); } class SerializerBase{//could also be an interface auto serialize(Object a){} } class Serializer(T):SerializerBase{ auto serialize(Object a){ auto b=cast(T)a; foreach (name; __traits(allMembers, T)) { //now we have access to fields of most derived type; //we can get the fields from base class as well. } } } I've left out details to focus on the key part. Deserialization is very similar. So the question is: is that technically impossible or not to enhance Object.factory in such ways?
Re: bigint <-> python long
On 09/10/2012 12:11 PM, bearophile wrote: I understand. The point of Pyd is to interface D and Python, while NumPy is something external. So if you find difficulties just keep it out. Adding it later is possible. Thing is, pyd will convert a ndarray to d array already, it just won't do it as quickly as it could if it made use of the underlying c array, and _py(d_type!(double[][])(ndarray)) will result in a list of lists. So it's really a question of should I add more oddness to an already odd situation. Bugger, I'm going to have to go through pyd and replace all usages of str with unicode.
Re: bigint <-> python long
Ellery Newcomer: I've been thinking about this one a bit more, and I am not sure it belongs in pyd. I understand. The point of Pyd is to interface D and Python, while NumPy is something external. So if you find difficulties just keep it out. Adding it later is possible. Bye, bearophile
Re: bigint <-> python long
On 09/05/2012 07:10 PM, bearophile wrote: NumPy arrays <==> D arrays I've been thinking about this one a bit more, and I am not sure it belongs in pyd. First, the conversion is not symmetric. One can convert a numpy.ndarray to a d array like so: PyObject* ndarray; double[][] matrix = d_type!(double[][])(ndarray); however, going back PyObject* res = _py(matrix); It is not at all clear that the user wants res to be a numpy.ndarray. The problem is partially that d arrays would be overloaded to a few too many things (list, str, array, any iterable, any buffer). That last one is a doozy. d_type never actually touches ndarray's type, so _py can hardly know what to use to convert matrix. (what if ndarray is actually a foo.BizBar matrix?) I could just specialize _py for numpy.ndarrays, defaulting to lists of lists (which is what we do already), but I kinda want a specialized type for numpy.ndarrays. Also, all these conversions imply data copying; is this reasonable for numpy arrays? It is easy enough to get a void* and shape information out of the ndarray, but building a decent matrix type out of them is not trivial. Is there a good matrix library for D that would be suitable for this? Oh yeah, also: rectangular matrices. For static arrays, the conversion is 1 memcpy. For dynamic arrays: lots of memcpys. I suppose I could abuse slicing much.
Re: since when was this valid syntax?
On 09/10/2012 07:07 AM, Ellery Newcomer wrote: On 09/08/2012 09:01 AM, Timon Gehr wrote: On 09/08/2012 04:11 PM, Ellery Newcomer wrote: alias enum int e; It is valid according to the grammar I don't believe you. Show me the derivation. The grammar as shown on dlang.org indeed seems not to allow this, but it is out of date as it also wouldn't allow alias extern(C) void function() fun;
Re: How to change DList elements by means of foreach?
On Monday, 10 September 2012 at 12:44:36 UTC, Alexandr Druzhinin wrote: 10.09.2012 18:37, monarch_dodra пишет: There is a know bug: foreach with ref does not currently work these containers. The reason is that the container's front does not actually expose a reference, but a value, and that is what is being changed (the returned value). There is no hope in sight to really *ever* make it work, because "container.front += 5" can't be made to work if the returned value is not a reference: Unlike indexes that define opIndexOpAssign, there is no opFrontOpAssign. What bothers *me* though is that the code compiles fine, biting more than 1 user in the process. Anyways... the workaround is* making an explicit loop, with temporary object that is fed back into front, like this: import std.container; void main() { // double-linked list; DList!int dlist; dlist.insertFront(0); auto slice = dlist[]; //Extract a range manually for( ; !slice.empty ; slice.popFront() ) { auto value = slice.front; //Extract the value value += 50; //Increment the value slice.front() = value;//Feed back into the range* } foreach(value; dlist) { assert(value == 50); //Now this works fine } } Well... this *would* work, but apparently, the implementation of DList.Range doesn't define front(T value). This makes the Range pretty much read-only. My guess is that this was an omission on the part of the implementer. I will fix it so that it works. Good to know, but bad to do... If in std.container: 1553:@property T front() { return _first._payload; } change to: 1553:@property *ref* T front() { return _first._payload; } doesn't it solve the problem or I don't know/understand something else? Arguably yes, however, the idea is that a container is supposed to have an implementation defined allocator, meaning that operations "may or may mot" invalidate references. So it is not allowed to return a reference. IMO, this is a valid argument for things like Array, that "can and will" move objects around, without ever telling the accessing ranges. Giving reference access here would be most dangerous. Not impossible, but very unsafe, and Phobos strives to be safe. The same argument applies to BinaryHeap, which is just a container adaptor. However, for any "node" based structure (such as {SD}List), which are structures that users usually chose *because* references are *always* valid, the argument doesn't hold as well. In particular, even with an implementation defined allocator, there is no reason a reference can't be returned. I'll try to push for reference access, but I may be turned down on the simple argument of "container uniformity" :/ Finally, regarding RedBlackTree, technically, you shouldn't assign to a node in the tree, but rather remove re-insert, so that is a non-issue.
Re: D and SCons [ was Re: bigint <-> python long ]
Am Mon, 10 Sep 2012 14:48:30 +0200 schrieb Johannes Pfau : > Sorry, I should have said 'It'll _probably_ never be supported in > gdc'. There are some possible solutions but: > > * It must be good enough to get approved when gdc is merged into gcc. > (remember it must be portable and gpl and you can't use > stdout/stdin...) > * Someone would have to implement the solution. I guess Iain had his > reasons not to implement it so somebody else would have to do that. > > Of course you can always try to make it work with external build > tools. But a solution _in_ gdc seems not very likely. For reference: Here's the gdc bug report for pragma(lib): http://d.puremagic.com/issues/show_bug.cgi?id=1690 Filed 2007, closed 2012 as RESOLVED/WONTFIX.
Re: D and SCons [ was Re: bigint <-> python long ]
Am Sun, 09 Sep 2012 12:55:19 -0700 schrieb Brad Roberts : > On 9/9/2012 1:15 AM, Johannes Pfau wrote: > > Am Sat, 08 Sep 2012 16:25:49 +0100 > > schrieb Russel Winder : > > > >> On Sat, 2012-09-08 at 07:20 -0700, Ellery Newcomer wrote: > >> […] > >>> Okay, here: > >>> https://bitbucket.org/ariovistus/deimos-elfutils/overview > >>> > >>> I have some code with a working makefile and a nonworking > >>> SConstruct file. > >>> > >>> I believe the issue is the header files have pragma(lib, X) in > >>> them, and a single call to dmd links the appropriate lib in, but > >>> scons' link step loses that information. > >>> > >>> Do you have any intention of supporting pragma(lib) in scons? > >> > >> If that is valid Dv2 and SCons doesn't deal with it then the SCons > >> D tools are broken and need fixing. > >> > >> Is there a tiny project replicating this that I can turn into a > >> unit/system test. The red so caused will necessitate action :-) > >> > > > > Please note that pragma(lib) is an evil feature. For example it will > > never work in gdc. > > > > It's not impossible and never is rather defeatist. Using the > frontend as is and grabing the json output, part of which includes > the pragmas, would be easy. Then invoking gdc with the appropriate > options to get the library linked in. rdmd is a good example of this > sort of process. > > Is there a special flag to enable pragmas for the json output? It does not work with gdc right now, but it should be possible to make it work. Sorry, I should have said 'It'll _probably_ never be supported in gdc'. There are some possible solutions but: * It must be good enough to get approved when gdc is merged into gcc. (remember it must be portable and gpl and you can't use stdout/stdin...) * Someone would have to implement the solution. I guess Iain had his reasons not to implement it so somebody else would have to do that. Of course you can always try to make it work with external build tools. But a solution _in_ gdc seems not very likely. I don't want to badmouth the pragma(lib) feature, in some cases it's nice to have (mainly building simple script-like programs with few source files). But for bigger projects, pragma(lib) makes things difficult (incremental compilation; build tools usually check if a library is available before trying to link against it so they can put out a nice warning. pragma(lib) in dmd subverts this feature; can't specify linker path with pragma lib, can't specify static vs dynamic linking, ...). The C/C++ architecture splits compilation and linking. Trying to conflate those concepts as pragma(lib) does, might even be a good idea(other languages have done it for some time now). But as we have to deal with tools that were designed for C/C++ (linkers, gcc) we'll always hit some issues with pragma(lib).
Re: How to change DList elements by means of foreach?
10.09.2012 18:37, monarch_dodra пишет: There is a know bug: foreach with ref does not currently work these containers. The reason is that the container's front does not actually expose a reference, but a value, and that is what is being changed (the returned value). There is no hope in sight to really *ever* make it work, because "container.front += 5" can't be made to work if the returned value is not a reference: Unlike indexes that define opIndexOpAssign, there is no opFrontOpAssign. What bothers *me* though is that the code compiles fine, biting more than 1 user in the process. Anyways... the workaround is* making an explicit loop, with temporary object that is fed back into front, like this: import std.container; void main() { // double-linked list; DList!int dlist; dlist.insertFront(0); auto slice = dlist[]; //Extract a range manually for( ; !slice.empty ; slice.popFront() ) { auto value = slice.front; //Extract the value value += 50; //Increment the value slice.front() = value;//Feed back into the range* } foreach(value; dlist) { assert(value == 50); //Now this works fine } } Well... this *would* work, but apparently, the implementation of DList.Range doesn't define front(T value). This makes the Range pretty much read-only. My guess is that this was an omission on the part of the implementer. I will fix it so that it works. Good to know, but bad to do... If in std.container: 1553:@property T front() { return _first._payload; } change to: 1553:@property *ref* T front() { return _first._payload; } doesn't it solve the problem or I don't know/understand something else?
Re: How to change DList elements by means of foreach?
On Monday, September 10, 2012 13:37:15 monarch_dodra wrote: > What bothers *me* though is that the code compiles fine, biting > more than 1 user in the process. Which is definitely a bug. If it hasn't been reported, it should be (I suspect that it has, but I don't know for sure and don't want to go digging for it at the moment). - Jonathan M Davis
Re: How to change DList elements by means of foreach?
On Monday, 10 September 2012 at 11:36:42 UTC, monarch_dodra wrote: slice.front() = value;//Feed back into the range* Typo in my code when I was investigating, this should be: slice.front = value; //Feed back into the range*
Re: How to change DList elements by means of foreach?
On Monday, 10 September 2012 at 11:18:29 UTC, Alexandr Druzhinin wrote: I have code: import std.container; int main() { // array int[] array = [0]; foreach(ref value; array) { value += 50; assert(value == 50); } foreach(value; array) { assert(value == 50); } // double-linked list; DList!int dlist; dlist.insertFront(0); foreach(ref value; dlist) { value += 50; assert(value == 50); } foreach(value; dlist) { assert(value == 50); // Why do I have assertion failure here? } } How to change the value of elements of DList? There is a know bug: foreach with ref does not currently work these containers. The reason is that the container's front does not actually expose a reference, but a value, and that is what is being changed (the returned value). There is no hope in sight to really *ever* make it work, because "container.front += 5" can't be made to work if the returned value is not a reference: Unlike indexes that define opIndexOpAssign, there is no opFrontOpAssign. What bothers *me* though is that the code compiles fine, biting more than 1 user in the process. Anyways... the workaround is* making an explicit loop, with temporary object that is fed back into front, like this: import std.container; void main() { // double-linked list; DList!int dlist; dlist.insertFront(0); auto slice = dlist[]; //Extract a range manually for( ; !slice.empty ; slice.popFront() ) { auto value = slice.front; //Extract the value value += 50; //Increment the value slice.front() = value;//Feed back into the range* } foreach(value; dlist) { assert(value == 50); //Now this works fine } } Well... this *would* work, but apparently, the implementation of DList.Range doesn't define front(T value). This makes the Range pretty much read-only. My guess is that this was an omission on the part of the implementer. I will fix it so that it works.
How to change DList elements by means of foreach?
I have code: import std.container; int main() { // array int[] array = [0]; foreach(ref value; array) { value += 50; assert(value == 50); } foreach(value; array) { assert(value == 50); } // double-linked list; DList!int dlist; dlist.insertFront(0); foreach(ref value; dlist) { value += 50; assert(value == 50); } foreach(value; dlist) { assert(value == 50); // Why do I have assertion failure here? } } How to change the value of elements of DList?
Re: import all except specified symbols: eg import std.stdio:!writeln,write;
On 09/10/12 01:33, timotheecour wrote: > I'd like to have something like: > --- > import std.stdio:!writeln,write; > --- > which would import all symbols from std.stdio except the ones listed > (writeln,write). > > Use case: > The reason is to avoid writing verbose code (specifying all symbols to import > except those 2), example when writing a module (eg overrides.stdio) which > overrides just those 2 symbols (eg for logging to a file each call to > write,writeln) but keeps the rest intact. > > Is there a way or can that be implemented? import std.stdio; float writeln(double a) { return a*a; } void main() { writeln(3.14); writeln("original no longer accesible"); } artur
Re: Find indexes of elements matching a given value in an array
Thank you guys, that's fantastic! I'll try out your functions.
Re: const attribute makes whole element const?
On Monday, 10 September 2012 at 09:54:46 UTC, Jonathan M Davis wrote: On Monday, September 10, 2012 11:49:48 monarch_dodra wrote: It appears that when writting: tests[4] = Test("Foobar"); It *looks* like compiler is eliding the opAssign/CC completely, opting for a bit copy, which is illegal. As I believe was mentioned elsewhere in this thread, that's due to http://d.puremagic.com/issues/show_bug.cgi?id=6906 AA's work fine for the most part, but they're really quite buggy when it comes to corner cases. A new implementation is being worked on, but it's slow in coming. - Jonathan M Davis Oops, sorry. TY.
Re: regexex, enforce and purity
Thank you both for your replies, they make perfect sense. I filed a bug report here: http://d.puremagic.com/issues/show_bug.cgi?id=8637
Re: const attribute makes whole element const?
On Monday, September 10, 2012 11:49:48 monarch_dodra wrote: > It appears that when writting: > tests[4] = Test("Foobar"); > It *looks* like compiler is eliding the opAssign/CC completely, > opting for a bit copy, which is illegal. As I believe was mentioned elsewhere in this thread, that's due to http://d.puremagic.com/issues/show_bug.cgi?id=6906 AA's work fine for the most part, but they're really quite buggy when it comes to corner cases. A new implementation is being worked on, but it's slow in coming. - Jonathan M Davis
Re: const attribute makes whole element const?
On Sunday, 9 September 2012 at 23:54:45 UTC, Jonathan M Davis wrote: [SNIP] the default assignment operator illegal. You could overload it, and as long as it doesn't touch any of the const member variables, it would work, but the const member variable is stuck as it is, and anything trying to mutate is illegal. [SNIP] - Jonathan M Davis Not to that it is my goal to be a pain, but the example I provided *does* overload opAssign (and the CC), but it *doesn't* work. Notice the error message is: "Error: tests[4] isn't mutable" Which is simply not true. The default assignment operator, when trying to do an assignment creates: "Error: variable XXX cannot modify struct with immutable members." But that is not what we are seeing. It appears that when writting: tests[4] = Test("Foobar"); It *looks* like compiler is eliding the opAssign/CC completely, opting for a bit copy, which is illegal.
Re: filter out compile error messages involving _error_
On 10/09/12 02:31, Jonathan M Davis wrote: On Monday, September 10, 2012 02:16:19 Timon Gehr wrote: Don has expressed the desire to weed those out completely. If he can do it in a way that leaves in all of the necessary information, then great, but you need to be able to know what the instantiation chain was. - Jonathan M Davis Yes, that's the idea. It's pretty much working for CTFE now (you get a complete call stack, with no spurious error messages).
Re: const attribute makes whole element const?
On Monday, September 10, 2012 09:30:59 Jacob Carlborg wrote: > On 2012-09-10 09:24, Jonathan M Davis wrote: > > And it works just fine in D2. It's const that's the problem. In general, > > if you want a member variable to be "read-only" on a struct, I'd strongly > > advise using a getter property without a setter property rather than > > making it const, because const makes it so that stuff like the assignment > > operator doesn't work. > Well, in D1 const was a nice shortcut for this. Whereas in D2, const is both something of fantastic wonder and utter despair. :) - Jonathan M Davis
Re: const attribute makes whole element const?
On 2012-09-10 09:24, Jonathan M Davis wrote: And it works just fine in D2. It's const that's the problem. In general, if you want a member variable to be "read-only" on a struct, I'd strongly advise using a getter property without a setter property rather than making it const, because const makes it so that stuff like the assignment operator doesn't work. Well, in D1 const was a nice shortcut for this. -- /Jacob Carlborg
Re: const attribute makes whole element const?
On Monday, September 10, 2012 09:13:04 Jacob Carlborg wrote: > On 2012-09-10 02:05, Namespace wrote: > > I had never problems with that in C++. > > If I have members which are const because they are assigned only one > > time and needs no other assignment, why should I declare this member not > > as const? > > > > In the example I know exactly that I assign only one time a name to this > > struct, so why I should not declare it as const? > > Perhaps declare "Name" as private and create a property getter for the > field. I think this is a bit annoying as well, it worked in D1. And it works just fine in D2. It's const that's the problem. In general, if you want a member variable to be "read-only" on a struct, I'd strongly advise using a getter property without a setter property rather than making it const, because const makes it so that stuff like the assignment operator doesn't work. - Jonathan M Davis
Re: const attribute makes whole element const?
On 2012-09-10 02:05, Namespace wrote: I had never problems with that in C++. If I have members which are const because they are assigned only one time and needs no other assignment, why should I declare this member not as const? In the example I know exactly that I assign only one time a name to this struct, so why I should not declare it as const? Perhaps declare "Name" as private and create a property getter for the field. I think this is a bit annoying as well, it worked in D1. -- /Jacob Carlborg
Re: delegate from lambda expression
On 2012-09-10 01:20, timotheecour wrote: I'd like to achieve the following: import std.stdio,std.range,std.algorithm,std.array; void main(){ auto dg=a=>a*2; auto a=iota(0,10); writeln(a.map!dg.array); } but this doesn't compile: Error: variable [...]dg type void is inferred from initializer delegate (__T26 a) { return a * 2; } , and variables cannot be of type void However this works: writeln(a.map!(a=>a*2).array); but I want to reuse dg in other expressions (and avoid repeating myself) Also, I want to avoid using string litteral enum dg=`a*2` as in my case dg is much more complicated and this is cleaner without a string IMHO. My questions: 1) why can't the compiler infer the type int(int) for dg? 2) how to convert a lambda a=>a*2 to a delegate or function? Try this: auto dg = (int a) => a * 2; If that doesn't work, this should: auto dg = (int a) { return a * 2; }; -- /Jacob Carlborg