Context-Free Grammars? What about arrays?
Hi, I think I'm having a little trouble understanding what's meant by context-free grammar. I've read that D is context-free, but is it really? What about an expression like: int[U] s; ? You can't tell -- without looking at the context -- whether U is a data type or a number, and so because associative arrays and regular arrays are syntactically different elements of the language, the syntax of D is tied in with its semantics, just like in C++. So is D really context-free? Or am I misunderstanding the meaning of the term? Thanks!
Re: foreach over string enum
On 02/11/2011 05:27 AM, Jesse Phillips wrote: spir Wrote: But in your example the symbol a does not look like a constant, instead it the loop variable. Do, how does it work? Magic. No really, the best I can tell is that the compiler will try to run the foreach loop at compile-time if there is something in the body that must be evaluated at compile time. The type you are iterating over must be known at compile-time, and just like any such value it is identified by its type and not its contents. So your array literal could in fact be built with a variable, the fact that it is not doesn't matter. I'm not sure if much thought has gone into compile-time-looping, the best way to enforce it is to get a function to run at compile time. I think the rule of when the body needs evaluated at compile-time is what's used, but this also means that when you try to iterate something like __traits or tupleof and don't use a compile-time construct in the body, you don't get an error or the loop executed. Oh yes, I see. This explains why my example using plain constants (predefined values, thus known at compile-time) does not run: there is nothing /forcing/ the compiler (such as a ref to a type), thus the compiler does not even try. Even if would be less complicated, probably, than with __traits. Denis -- _ vita es estrany spir.wikidot.com
Re: Context-Free Grammars? What about arrays?
On Friday 11 February 2011 01:03:21 %u wrote: Hi, I think I'm having a little trouble understanding what's meant by context-free grammar. I've read that D is context-free, but is it really? What about an expression like: int[U] s; ? You can't tell -- without looking at the context -- whether U is a data type or a number, and so because associative arrays and regular arrays are syntactically different elements of the language, the syntax of D is tied in with its semantics, just like in C++. So is D really context-free? Or am I misunderstanding the meaning of the term? Yes. You're misunderstanding. It's actually quite difficult to parse a language if its grammar isn't context-free. You really should read up in context-free grammars if you want to understand it properly. Context-free means that it's unambiguous as to which grammar rule is to be applied at any point during the parsing process. In this case, U is a symbol. The parser probably doesn't care about much more than that. That symbol could end up being a number or a type. And actually, it probably isn't even that hard. U is a class, struct, alias, or template argument. The template argument and alias would be substituted with a real type or value before the compiler had to determine what type int[U] was. Not to mention, the context-free grammar is entirely for parsing tokens into an abstract syntax tree. The compiler then has to do whatever it does with the AST to actually generate assembly from it. So, as long as the parser can parse it into the AST, it could be the next stage's problem to determine what that really means. Regardless, I suggest that you read a compiler book if you really want to understand context-free grammars. I have Compiler Construction: Principles and Practices by Kenneth C. Louden, which is quite good, but the most popular one is the so-called dragon book. I'm not sure what it's actual title is though. - Jonathan M Davis
using a binary tree container
Hello, I have a list of strings and I want to determine whether or not a particular string in the is in that list. Assuming I should store the list of strings in a binary tree to facilitate fast searching, I had a look at the std.container documentation and found RedBlackTree, but the documentation for it has no examples. May someone offer an example of how to use it? Thank you, Dominic Jones
Re: Context-Free Grammars? What about arrays?
On 02/11/2011 10:03 AM, %u wrote: Hi, I think I'm having a little trouble understanding what's meant by context-free grammar. I've read that D is context-free, but is it really? What about an expression like: int[U] s; ? You can't tell -- without looking at the context -- whether U is a data type or a number, and so because associative arrays and regular arrays are syntactically different elements of the language, the syntax of D is tied in with its semantics, just like in C++. So is D really context-free? Or am I misunderstanding the meaning of the term? Have you tried it? int[U] cannot be a plain array because the size must be constant. But I agree there is some context in play for the compiler (or rather the linker?) to determine /that/: -- some error if U undefined -- some other error if defined, but neither uint nore type -- some other error if uint but not constant -- ass array if type (I guess) Denis -- _ vita es estrany spir.wikidot.com
Re: Context-Free Grammars? What about arrays?
On Friday 11 February 2011 03:22:54 spir wrote: On 02/11/2011 10:03 AM, %u wrote: Hi, I think I'm having a little trouble understanding what's meant by context-free grammar. I've read that D is context-free, but is it really? What about an expression like: int[U] s; ? You can't tell -- without looking at the context -- whether U is a data type or a number, and so because associative arrays and regular arrays are syntactically different elements of the language, the syntax of D is tied in with its semantics, just like in C++. So is D really context-free? Or am I misunderstanding the meaning of the term? Have you tried it? int[U] cannot be a plain array because the size must be constant. But I agree there is some context in play for the compiler (or rather the linker?) to determine /that/: -- some error if U undefined -- some other error if defined, but neither uint nore type -- some other error if uint but not constant -- ass array if type (I guess) Actually, it _can_ be a plain, static array. U could be a template argument which is a number. - Jonathan M Davis
Re: using a binary tree container
Dominic Jones: I have a list of strings and I want to determine whether or not a particular string in the is in that list. What about using: size_t[sting] yourStringSet; Bye, bearophile
Re: using a binary tree container
== Quote from bearophile (bearophileh...@lycos.com)'s article Dominic Jones: I have a list of strings and I want to determine whether or not a particular string in the is in that list. What about using: size_t[sting] yourStringSet; Bye, bearophile Would that not be constructing an associated array? Whilst an associated array would do the job, there is no value for the key:value pair, just a list of keys. In the C++ STL there are the set and map containers. I want something like set. Dominic
Re: Context-Free Grammars? What about arrays?
On 2/11/11 6:03 AM, %u wrote: Hi, I think I'm having a little trouble understanding what's meant by context-free grammar. I've read that D is context-free, but is it really? What about an expression like: int[U] s; ? You can't tell -- without looking at the context -- whether U is a data type or a number, and so because associative arrays and regular arrays are syntactically different elements of the language, the syntax of D is tied in with its semantics, just like in C++. So is D really context-free? Or am I misunderstanding the meaning of the term? Thanks! That will always parse to an associative array. Then in the semantic pass, if U is a constant expression that turns out to be an integer it is reinterpreted as a static array. Take a look: https://github.com/D-Programming-Language/dmd/blob/master/src/mtype.c#L3924
doesn't work std.cstream.din.readf() with wchar and dchar
doesn't work std.cstream.din.readf() with wchar and dchar. But it works: import std.cstream; void main() { wchar[] w_char = ew.dup; din.readf(w_char); dchar[] d_char = ew.dup; din.readf(d_char); } But it doesn't work: import std.cstream; void main() { wchar w_char = 'e'; din.readf(w_char); wchar d_char = 'e'; din.readf(d_char); } Please note that this works: import std.cstream; void main() { char _char = 'e'; din.readf(_char); } Is that intended, or a bug?
Re: Context-Free Grammars? What about arrays?
That will always parse to an associative array. Then in the semantic pass, if U is a constant expression that turns out to be an integer it is reinterpreted as a static array. Ah, interesting. But that describes the implementation (i.e. how the compiler copes with the ambiguity) and not the language itself. Context-free means that it's unambiguous as to which grammar rule is to be applied at any point during the parsing process. The problem is that it _is_ ambiguous what rule to apply. To me, just because static arrays and associative arrays happen to have similar _looks_ doesn't make parsing them context-free -- they're defined with completely separate syntaxes, and they just happen to look identical. The fact that the compiler has to do a semantic analysis in order to figure this out (which was originally a syntax problem) really makes me wonder why you mention that D is still context-free. Not to mention, the context-free grammar is entirely for parsing tokens into an abstract syntax tree. Again, just because the AST's _happen_ to _look_ the same for static and associative arrays, does that mean that this makes D context-free? The meaning of the expression is still ambiguous, whether or not it fits well within the tree. Furthermore, I would say that a struct like this: struct Temp(T...) { int[T] arr; } should work perfectly if T.length == 0, since it would then be a dynamic array. But the parser is forced to treat it as an associative array, and so _both_ of these break: Temp!() a; Temp!(2) b; //Why does this break? Why should the second one break, in any case?
Re: Context-Free Grammars? What about arrays?
On 2011-02-11 10:37, Jonathan M Davis wrote: On Friday 11 February 2011 01:03:21 %u wrote: Hi, I think I'm having a little trouble understanding what's meant by context-free grammar. I've read that D is context-free, but is it really? What about an expression like: int[U] s; ? You can't tell -- without looking at the context -- whether U is a data type or a number, and so because associative arrays and regular arrays are syntactically different elements of the language, the syntax of D is tied in with its semantics, just like in C++. So is D really context-free? Or am I misunderstanding the meaning of the term? Yes. You're misunderstanding. It's actually quite difficult to parse a language if its grammar isn't context-free. You really should read up in context-free grammars if you want to understand it properly. Context-free means that it's unambiguous as to which grammar rule is to be applied at any point during the parsing process. In this case, U is a symbol. The parser probably doesn't care about much more than that. That symbol could end up being a number or a type. And actually, it probably isn't even that hard. U is a class, struct, alias, or template argument. The template argument and alias would be substituted with a real type or value before the compiler had to determine what type int[U] was. Not to mention, the context-free grammar is entirely for parsing tokens into an abstract syntax tree. The compiler then has to do whatever it does with the AST to actually generate assembly from it. So, as long as the parser can parse it into the AST, it could be the next stage's problem to determine what that really means. Regardless, I suggest that you read a compiler book if you really want to understand context-free grammars. I have Compiler Construction: Principles and Practices by Kenneth C. Louden, which is quite good, but the most popular one is the so-called dragon book. I'm not sure what it's actual title is though. - Jonathan M Davis The title of the so called dragon book is Compilers: Principles, Techniques, and Tools and can be found here: http://www.amazon.com/Compilers-Principles-Techniques-Tools-2nd/dp/0321486811/ref=sr_1_1?s=booksie=UTF8qid=1297440057sr=1-1 It's also listed on the bookshelf page on the DigitalMars site. -- /Jacob Carlborg
name of enum members
Hello, To denote a member 'm' of an enum 'e', one needs to write e.m. Is there a way to get back this name? Here are my best trials: unittest { enum TC : uint {i=1}; writefln(%s %s %s, TC.i, TC.i.stringof, to!string(TC.i)); } == 1 cast(TC)1u i A bit strange that '%s' does not produce the same string as to!string... Anyway, the only solution seems to be parsing the result of stringof to get what's inside (), then compose it with the result of to!string: a bit too much of a burden, what do you think? Hints welcome :-) Thank you for reading, Denis -- _ vita es estrany spir.wikidot.com
Re: name of enum members
spir Wrote: Hello, To denote a member 'm' of an enum 'e', one needs to write e.m. Is there a way to get back this name? Here are my best trials: Maybe to!string(Enum.i) should return the enum name with it's field. This makes since because it is trying to return its name, and for named enums, where it comes from is important.
Re: using a binary tree container
Dominic Jones: Would that not be constructing an associated array? Whilst an associated array would do the job, there is no value for the key:value pair, just a list of keys. In the C++ STL there are the set and map containers. I want something like set. Phobos2 is young, and it doesn't contain a HashSet yet. So you may use built-in associative arrays as a set, with a default value, or you may use the Ordered Tree Set that's in the collections module (look at the its unittests for some usage examples), or you may write a HashSet and then put it in Bugzilla so if it's good enough it will be added to Phobos. My suggestion is to use the built-in associative array. Bye, bearophile
Re: using a binary tree container
On 02/11/2011 01:30 PM, Dominic Jones wrote: == Quote from bearophile (bearophileh...@lycos.com)'s article Dominic Jones: I have a list of strings and I want to determine whether or not a particular string in the is in that list. What about using: size_t[sting] yourStringSet; Bye, bearophile Would that not be constructing an associated array? Whilst an associated array would do the job, there is no value for the key:value pair, just a list of keys. In the C++ STL there are the set and map containers. I want something like set. Dominic Precisely. D does not have a Set type yet, at least officially, it's on the way (std.container is beeing worked on). But a very common way to emulate sets in a language that has associative arrays is to build a bool[Element] AA, with true values only. Then, your keys are the elements, right? Values are just fake, but having them true bools, set[elem] returns true if present. Unfortunately, D would raise an error if absent. But there is even better in D: (key in AA) returns a pointer, which is null if absent. Thus, (elem in set) correctly simulates test membership. Note that in various languages (eg Python), builtin or library Set types are actually built like that. The reason is AAs are precisely built to make key lookup very fast, which is the main operation of a set. I guess (unsure) D's future set type will certainly also be built like that. I have one in stock, if you're interested. Denis -- _ vita es estrany spir.wikidot.com
Re: name of enum members
On 02/11/2011 06:49 PM, Jesse Phillips wrote: spir Wrote: Hello, To denote a member 'm' of an enum 'e', one needs to write e.m. Is there a way to get back this name? Here are my best trials: Maybe to!string(Enum.i) should return the enum name with it's field. This makes since because it is trying to return its name, and for named enums, where it comes from is important. That's what I wrote, precisely (see example in OP), and it returns only i. denis -- _ vita es estrany spir.wikidot.com
Re: using a binary tree container
On 02/11/2011 06:55 PM, spir wrote: On 02/11/2011 01:30 PM, Dominic Jones wrote: == Quote from bearophile (bearophileh...@lycos.com)'s article Dominic Jones: I have a list of strings and I want to determine whether or not a particular string in the is in that list. What about using: size_t[sting] yourStringSet; Bye, bearophile Would that not be constructing an associated array? Whilst an associated array would do the job, there is no value for the key:value pair, just a list of keys. In the C++ STL there are the set and map containers. I want something like set. Dominic By the way, i may be wrong on that, but D's builtin AAs seem /very/ fast on key access. You'd probably have a hard time even approaching their performance using whatever kind of tree (or rather, of trie). I tried ;-) Both with string and bit-seq keys (in the latter case, thus using a bit-trie). If ever you have any good result on this path, I am very interested. denis -- _ vita es estrany spir.wikidot.com
Re: name of enum members
spir: To denote a member 'm' of an enum 'e', one needs to write e.m. Is there a way to get back this name? Is this good enough? import std.stdio, std.conv; enum TC { A, B, C } void main() { writeln(typeof(TC.A).stringof, ., to!string(TC.A)); } A bit strange that '%s' does not produce the same string as to!string... I agree, I have a bug report on this. Bye, bearophile
Inserting nodes into a tree
Please pardon my complete lack of knowledge. Please provide some suggestions/pointers so that I can improve myself. Given a table containing three values (ie, myName, myId, parentId), how does one insert those values into a tree such that the parent/child relationship defined in the table is maintained? Basically I'm given a file containing parents and children in no particular order. I would like to print all children of a given parent regardless of where they fall on the tree. Note, this is not a school related question, simply a retard trying to learn how to do things more efficiently. Thanks
Re: Inserting nodes into a tree
On Fri, 11 Feb 2011 14:28:47 -0500, %u n...@spam.com wrote: Please pardon my complete lack of knowledge. Please provide some suggestions/pointers so that I can improve myself. Given a table containing three values (ie, myName, myId, parentId), how does one insert those values into a tree such that the parent/child relationship defined in the table is maintained? Basically I'm given a file containing parents and children in no particular order. I would like to print all children of a given parent regardless of where they fall on the tree. Note, this is not a school related question, simply a retard trying to learn how to do things more efficiently. With a many-to-one relationship of parent to child, I'd suggest each tree node having a array of child node pointers: struct Node { int id; string myName; Node *parent; // only needed if you want to go up the tree. Node *[] children; } -Steve
Re: using a binary tree container
what with this?: auto arr = [foo, bar, aaa, zzz]; sort(arr); assert(canFind(foo)); assert(canFind(aaa)); assert(!canFind(aa)); I had a Error 1 Error: module algorithem is in file 'std\algorithem.d' which cannot be read main.d when I tried to compile, so I couldn't check it.
Re: Inserting nodes into a tree
On 2/11/11, Steven Schveighoffer schvei...@yahoo.com wrote: struct Node { int id; string myName; Node *parent; // only needed if you want to go up the tree. Node *[] children; } -Steve What are the benefits of using struct pointers instead of classes in this case?
Re: name of enum members
spir Wrote: On 02/11/2011 06:49 PM, Jesse Phillips wrote: spir Wrote: Hello, To denote a member 'm' of an enum 'e', one needs to write e.m. Is there a way to get back this name? Here are my best trials: Maybe to!string(Enum.i) should return the enum name with it's field. This makes since because it is trying to return its name, and for named enums, where it comes from is important. That's what I wrote, precisely (see example in OP), and it returns only i. It look like you were asking how you could do it, not that to!string should do it for you. My thought is added it to bugzilla.
Re: Assert compilation failure with certain message
Andrej Mitrovic napisał: I've managed to screw up the colon placement though, here's a quick fix: import std.stdio; import std.conv; void staticAssert(alias exp, string message, string file = __FILE__, int line = __LINE__)() { static if (!exp) { pragma(msg, file ~ ( ~ to!string(line) ~ ): ~ staticAssert: ~ to!string(message)); assert(0); } } void main() { enum x = false; staticAssert!(x, Oh no we failed!); int y; } How does it help to find out that compilation tripped on a specific static assertion? -- Tomek
Re: name of enum members
On 02/11/2011 07:39 PM, bearophile wrote: spir: To denote a member 'm' of an enum 'e', one needs to write e.m. Is there a way to get back this name? Is this good enough? import std.stdio, std.conv; enum TC { A, B, C } void main() { writeln(typeof(TC.A).stringof, ., to!string(TC.A)); } Yo! thank you Bearophile. A bit strange that '%s' does not produce the same string as to!string... I agree, I have a bug report on this. More generally, I think default %s and to!string should systematically output the literal notation able to reconstruct the string'ed element. I mean, as far as possible without getting into much complication (in cases of struct or class object, which often have data members not read in by the contructor). About the annoying case of strings, is there a tool func somewhere to reconstruct an escaped version? (like eg when the string holds '') I have looked for it without success. Else, i guess Phobos very much needs that. (the equivalent of python's %r or repr() for strings) Simple, clear, consistent, informative, useful. Denis -- _ vita es estrany spir.wikidot.com
Re: Inserting nodes into a tree
On Fri, 11 Feb 2011 14:49:41 -0500, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: On 2/11/11, Steven Schveighoffer schvei...@yahoo.com wrote: struct Node { int id; string myName; Node *parent; // only needed if you want to go up the tree. Node *[] children; } -Steve What are the benefits of using struct pointers instead of classes in this case? Classes are more heavyweight (hidden vtable ptr, monitor) and have less control over their allocation. For example, I used to use classes to represent tree nodes in dcollections' RBTree (which later became std.container.RedBlackTree), but I found structs use up less space and I can create custom allocators for them which significantly increase performance. The only real downside is you occasionally have to deal with the pointer aspect (but most of the time not, since the dot operator auto-dereferences). Plus, classes are good if you need polymorphism, or want to restrict allocation of nodes to the heap. You don't need polymorphism for tree node, and the restriction isn't necessary in all cases. It might be a good idea to make the tree root a class, but the nodes work better as structs. -Steve
Re: using a binary tree container
On 02/11/2011 08:46 PM, Tom wrote: what with this?: auto arr = [foo, bar, aaa, zzz]; sort(arr); assert(canFind(foo)); assert(canFind(aaa)); assert(!canFind(aa)); I had a Error 1 Error: module algorithem is in file 'std\algorithem.d' which cannot be read main.d when I tried to compile, so I couldn't check it. canFind is in std.algorithm: import it. (with the prefix std.) denis -- _ vita es estrany spir.wikidot.com
Re: using a binary tree container
On Fri, 11 Feb 2011 14:46:26 -0500, Tom no.em...@gmail.com wrote: what with this?: auto arr = [foo, bar, aaa, zzz]; sort(arr); assert(canFind(foo)); assert(canFind(aaa)); assert(!canFind(aa)); I had a Error 1 Error: module algorithem is in file 'std\algorithem.d' it's spelled algorithm, no e in there. -Steve
Inheritance problem
Hello, I've a problem with my class inheritance. I have class called Texture which implements the interface IDrawable and the abstract class APickable. The Texture-class contains 3 members which looks like this: GLuint pTextureID; Size pSize1, pSize2; Finally... my Texture-class looks like: class Texture : APickable, IDrawable { protected { GLuint pTextureID; Size pSize, pAnoutherSize; } } now... I have a second class called Animation which looks like this: class Animation : Texture { private { Texture[] pFrames; } public { this(string file, string[] paths...) { super(file); pFrames ~= this; foreach(string cur; paths) { pFrames ~= new Texture(cur); } } Size getSize() { return pFrames[0].pSize; } } } As I know, pFrames[0].pSize can be called... pSize in the Texture- class is marked as protected, but I get the following error: Error: class Texture member pSize is not accessible. When I mark the protected members of the Texture-class as public, it works (should be clear), but why do I get this error when mark them as protected? I hope anyone can help to solve the problem.
Re: Inheritance problem
On Fri, 11 Feb 2011 15:40:18 -0500, %u unkn...@unknown.com wrote: Hello, I've a problem with my class inheritance. I have class called Texture which implements the interface IDrawable and the abstract class APickable. The Texture-class contains 3 members which looks like this: GLuint pTextureID; Size pSize1, pSize2; Finally... my Texture-class looks like: class Texture : APickable, IDrawable { protected { GLuint pTextureID; Size pSize, pAnoutherSize; } } now... I have a second class called Animation which looks like this: class Animation : Texture { private { Texture[] pFrames; } public { this(string file, string[] paths...) { super(file); pFrames ~= this; foreach(string cur; paths) { pFrames ~= new Texture(cur); } } Size getSize() { return pFrames[0].pSize; } } } As I know, pFrames[0].pSize can be called... pSize in the Texture- class is marked as protected, but I get the following error: Error: class Texture member pSize is not accessible. When I mark the protected members of the Texture-class as public, it works (should be clear), but why do I get this error when mark them as protected? I hope anyone can help to solve the problem. protected means you cannot access it outside the *instance*. The pFrames array references *other instances* of Texture, so they are not accessible. http://www.digitalmars.com/d/2.0/attribute.html#ProtectionAttribute If accessing a protected instance member through a derived class member function, that member can only be accessed for the object instance which is the ‘this’ object for the member function call. -Steve
Re: Inheritance problem
== Auszug aus Steven Schveighoffer (schvei...@yahoo.com)'s Artikel On Fri, 11 Feb 2011 15:40:18 -0500, %u unkn...@unknown.com wrote: Hello, I've a problem with my class inheritance. I have class called Texture which implements the interface IDrawable and the abstract class APickable. The Texture-class contains 3 members which looks like this: GLuint pTextureID; Size pSize1, pSize2; Finally... my Texture-class looks like: class Texture : APickable, IDrawable { protected { GLuint pTextureID; Size pSize, pAnoutherSize; } } now... I have a second class called Animation which looks like this: class Animation : Texture { private { Texture[] pFrames; } public { this(string file, string[] paths...) { super(file); pFrames ~= this; foreach(string cur; paths) { pFrames ~= new Texture(cur); } } Size getSize() { return pFrames[0].pSize; } } } As I know, pFrames[0].pSize can be called... pSize in the Texture- class is marked as protected, but I get the following error: Error: class Texture member pSize is not accessible. When I mark the protected members of the Texture-class as public, it works (should be clear), but why do I get this error when mark them as protected? I hope anyone can help to solve the problem. protected means you cannot access it outside the *instance*. The pFrames array references *other instances* of Texture, so they are not accessible. http://www.digitalmars.com/d/2.0/attribute.html#ProtectionAttribute If accessing a protected instance member through a derived class member function, that member can only be accessed for the object instance which is the ‘this’ object for the member function call. -Steve Thanks, but what about the following: import std.stdio : writeln; class a { public this(int v) { myVar = v; } protected int myVar; } class b : a { private a[] moreInstances; this(int v, int[] vars...) { super(v); moreInstances ~= this; foreach(int cur; vars) { moreInstances ~= new a(cur); } } int getVar() { return moreInstances[1].myVar; } } void main(string[] args) { b exp = new b(0, 1, 2); writeln(exp.getVar()); } This compiles fine and prints the number 1. myVar is also protected in class a, I also call myVar in the getVar()-method of class b.
Re: Inheritance problem
Steven Schveighoffer: Any code can access any members defined in the current module, regardless of access attributes I am not sure if Walter understands how much this rule makes it hard for people not already used to protected/private attributes to understand and learn to use those attributes correctly. The C# compiler doesn't have that rule, and it's much more strict. I think this makes learning the usage of those attributes faster. Bye, bearophile
Re: using a binary tree container
Am 11.02.2011 21:38, schrieb Steven Schveighoffer: On Fri, 11 Feb 2011 14:46:26 -0500, Tom no.em...@gmail.com wrote: what with this?: auto arr = [foo, bar, aaa, zzz]; sort(arr); assert(canFind(foo)); assert(canFind(aaa)); assert(!canFind(aa)); I had a Error 1 Error: module algorithem is in file 'std\algorithem.d' it's spelled algorithm, no e in there. -Steve I allways try to import 'algorythm' because of the german word 'Algorythmus'. When this happend for the first time, I spent about five minutes to find out what's wrong. Mafi
Re: Inheritance problem
== Auszug aus bearophile (bearophileh...@lycos.com)'s Artikel Steven Schveighoffer: Any code can access any members defined in the current module, regardless of access attributes I am not sure if Walter understands how much this rule makes it hard for people not already used to protected/private attributes to understand and learn to use those attributes correctly. The C# compiler doesn't have that rule, and it's much more strict. I think this makes learning the usage of those attributes faster. Bye, bearophile I already used protected/private (and other languages like Java and... D too), but it was a bit unintelligible because protected means (for me) that every instance of an inheritanced class can access the protected members. An alternative to protected like modprotected or something like this should be added that people can declare it as modprotected which means that inheritanced classes of another module can also access these attributes.
Re: Assert compilation failure with certain message
I thought you were just looking for a static assert with a custom message?
Re: Inserting nodes into a tree
Cool, thanks for the insight. :)
Re: std.concurrency immutable classes...
Steven Schveighoffer napisał: It would be much easier if he provided the specific case(s) which broke his teeth. Then we'll all know where's the problem. If it's soluble, it'll open the door to tail type modifiers in general, not just in classes. It's a burning issue e.g. with ranges (mostly struct). http://d.puremagic.com/issues/show_bug.cgi?id=5377 Look at the attachment to get a feel of what hoops we'll have to jump through to side-step lack of tail X. I've worked through this very same problem (a few months back), thinking that we need a general solution to tail-const. The large issue with tail-const for structs in the general case is that you cannot control the type of 'this'. It's always ref. This might seem like a very inconsequential detail, but I realized that a ref to X does not implicitly convert to a ref to a tail-const X. This violates a rule of two indirections, in which case you are not able to implicitly convert the indirect type, even if the indirect type would implicitly convert outside the reference. A simple example, you cannot convert an int** to a const(int)**. Reason being, then you could change the indirect pointer to point to something that's immutable, and the original int ** now points to immutable data. I tried to understand this on an example and now I'm even more confused. :) int* p; int** pp = p; const(int)** cpp = pp; // compiles fine immutable int i = 7; *cpp = i; **pp = 5; // mutate the immutable writeln(cpp, ' ', pp); writeln(*cpp, ' ', *pp, ' ', i); writeln(**cpp, ' ', **pp, ' ', i); The output is interesting: 12FE08 12FE08 12FE14 12FE14 12FE14 5 5 7 So even they all point to i at the end, it remains unchanged. What gives? Register caching? It doesn't matter as the int** to a const(int)** conversion should fail in the first place, but I'm curious... The same is for tail-const structs, because you go through one ref via 'this' and the other ref via the referring member. What does this all mean? It basically means that you have to define *separate* functions for tail-const and const, and separate functions for tail-immutable and immutable. This is untenable. I, from the very first discussions, assumed tail-const functions are inevitable. You define empty() as const but popFront() as tail-const. Feels natural. You might ask why doesn't this problem occur with tail-const arrays?, well because you *don't pass them by ref*. With structs we have no choice. I think what we need is a way to define two different structs as being the tail-const version of the other, with some compiler help, and then we do not need to define a new flavor of const functions. We still need to define these tail-const functions, but it comes in a more understandable form. But importantly, the implicit cast makes a *temporary* copy of the struct, allowing the cast to work. I'd like to understand it better. How would you define with this scheme, say, a range on a const collection, to which ranges on an (im)mutable collection are implicitly convertible? -- Tomek
Re: Inheritance problem
On 2/11/11, bearophile bearophileh...@lycos.com wrote: Steven Schveighoffer: Any code can access any members defined in the current module, regardless of access attributes I am not sure if Walter understands how much this rule makes it hard for people not already used to protected/private attributes to understand and learn to use those attributes correctly. The C# compiler doesn't have that rule, and it's much more strict. I think this makes learning the usage of those attributes faster. Bye, bearophile I think one benefit of the current approach is that we'll be able to use free functions which could be called as if they belong to a class (if they have that class as the first parameter), since we could use the uniform function call (UFC) syntax. But UFC doesn't work with classes yet, otherwise we might be able to do this: module foo; import std.stdio; class Foo { private int _x, _y; this(int x, int y) { _x = x; _y = y; } } int sumXY(Foo foo) { return foo._x + foo._y; } module main; import foo; import std.stdio; void main() { auto obj = new Foo(10, 10); writeln(obj.sumXY()); // using UFC, but doesn't work yet //~ writeln(obj._x + obj._y); // not allowed } We could have a bunch of templated functions in the foo module which could work with any class inside that module. So it might help out against the common God class problem. What do you think?
Re: Inserting nodes into a tree
On 02/11/2011 09:21 PM, Steven Schveighoffer wrote: On Fri, 11 Feb 2011 14:49:41 -0500, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: On 2/11/11, Steven Schveighoffer schvei...@yahoo.com wrote: struct Node { int id; string myName; Node *parent; // only needed if you want to go up the tree. Node *[] children; } -Steve What are the benefits of using struct pointers instead of classes in this case? Classes are more heavyweight (hidden vtable ptr, monitor) and have less control over their allocation. For example, I used to use classes to represent tree nodes in dcollections' RBTree (which later became std.container.RedBlackTree), but I found structs use up less space and I can create custom allocators for them which significantly increase performance. I noticed once another overhead, namely time of method call (certainly due to runtime lookup of so-called virtual methods). Was significant, about 3x IIRC. The only real downside is you occasionally have to deal with the pointer aspect (but most of the time not, since the dot operator auto-dereferences). Plus, classes are good if you need polymorphism, or want to restrict allocation of nodes to the heap. You don't need polymorphism for tree node, and the restriction isn't necessary in all cases. It might be a good idea to make the tree root a class, but the nodes work better as structs. ...as long as nodes are all of the same type. But isn't it a very common case to have a hierarchy of node types (which /must/ have a common supertype to all fit into Node* and/or Node*[] slots)? I started my last app with struct nodes, then switched to class because was to much mess to maintain (type annotations and such, manual castings all the way down, somewhat like hand-made tag unions). denis -- _ vita es estrany spir.wikidot.com
Re: Inheritance problem
== Auszug aus Andrej Mitrovic (andrej.mitrov...@gmail.com)'s Artikel On 2/11/11, bearophile bearophileh...@lycos.com wrote: Steven Schveighoffer: Any code can access any members defined in the current module, regardless of access attributes I am not sure if Walter understands how much this rule makes it hard for people not already used to protected/private attributes to understand and learn to use those attributes correctly. The C# compiler doesn't have that rule, and it's much more strict. I think this makes learning the usage of those attributes faster. Bye, bearophile I think one benefit of the current approach is that we'll be able to use free functions which could be called as if they belong to a class (if they have that class as the first parameter), since we could use the uniform function call (UFC) syntax. But UFC doesn't work with classes yet, otherwise we might be able to do this: module foo; import std.stdio; class Foo { private int _x, _y; this(int x, int y) { _x = x; _y = y; } } int sumXY(Foo foo) { return foo._x + foo._y; } module main; import foo; import std.stdio; void main() { auto obj = new Foo(10, 10); writeln(obj.sumXY()); // using UFC, but doesn't work yet //~ writeln(obj._x + obj._y); // not allowed } We could have a bunch of templated functions in the foo module which could work with any class inside that module. So it might help out against the common God class problem. What do you think? Looks really interesting - would be a nice feature :)
Re: using a binary tree container
On 02/11/2011 10:33 PM, Mafi wrote: Am 11.02.2011 21:38, schrieb Steven Schveighoffer: On Fri, 11 Feb 2011 14:46:26 -0500, Tom no.em...@gmail.com wrote: what with this?: auto arr = [foo, bar, aaa, zzz]; sort(arr); assert(canFind(foo)); assert(canFind(aaa)); assert(!canFind(aa)); I had a Error 1 Error: module algorithem is in file 'std\algorithem.d' it's spelled algorithm, no e in there. -Steve I allways try to import 'algorythm' because of the german word 'Algorythmus'. When this happend for the first time, I spent about five minutes to find out what's wrong. It is spelled Algorithmus in German, no ypsilon ;-) http://de.wiktionary.org/wiki/Algorithmus The word is not from greek, but from arabic/persian etymology (like many words starting in al-). From wiktionary: http://en.wiktionary.org/wiki/algorithm: From French algorithme; from the Old French algorisme (the Arabic numeral system), a modification likely due to a mistaken connection with Greek ἀριθμός (number); from Medieval Latin algorismus, a transliteration of the name of the Persian mathematician al-Khwārizmī (Arabic: الخوارزمي, native of Khwarezm.) denis -- _ vita es estrany spir.wikidot.com
Re: Inheritance problem
On 02/11/2011 11:26 PM, Andrej Mitrovic wrote: On 2/11/11, bearophilebearophileh...@lycos.com wrote: Steven Schveighoffer: Any code can access any members defined in the current module, regardless of access attributes I am not sure if Walter understands how much this rule makes it hard for people not already used to protected/private attributes to understand and learn to use those attributes correctly. The C# compiler doesn't have that rule, and it's much more strict. I think this makes learning the usage of those attributes faster. Bye, bearophile I think one benefit of the current approach is that we'll be able to use free functions which could be called as if they belong to a class (if they have that class as the first parameter), since we could use the uniform function call (UFC) syntax. But UFC doesn't work with classes yet, otherwise we might be able to do this: module foo; import std.stdio; class Foo { private int _x, _y; this(int x, int y) { _x = x; _y = y; } } int sumXY(Foo foo) { return foo._x + foo._y; } module main; import foo; import std.stdio; void main() { auto obj = new Foo(10, 10); writeln(obj.sumXY()); // using UFC, but doesn't work yet //~ writeln(obj._x + obj._y); // not allowed } We could have a bunch of templated functions in the foo module which could work with any class inside that module. So it might help out against the common God class problem. What do you think? Interesting. UFC syntax is also criticised (don't remmber on which points exactly), but it brings with nice side-features. Denis -- _ vita es estrany spir.wikidot.com
Re: using a binary tree container
On 02/11/2011 10:35 AM, spir wrote: D's builtin AAs seem /very/ fast on key access. You'd probably have a hard time even approaching their performance using whatever kind of tree (or rather, of trie). That is expected. D AAs are hash tables, meaning that they provide O(1) complexity for element access; compared to the O(log N) complexity of binary trees. For completeness: adding elements is still O(1) for a hash table; compared to O(N log N) of a tree. Ali
Re: using a binary tree container
On 02/12/2011 12:56 AM, Ali Çehreli wrote: On 02/11/2011 10:35 AM, spir wrote: D's builtin AAs seem /very/ fast on key access. You'd probably have a hard time even approaching their performance using whatever kind of tree (or rather, of trie). That is expected. D AAs are hash tables, meaning that they provide O(1) complexity for element access; compared to the O(log N) complexity of binary trees. For completeness: adding elements is still O(1) for a hash table; compared to O(N log N) of a tree. You are right, but O(1) O(log N) do not tell the whole story, --they're just proportional to a given factor that may be whatever. Also, trees are not always O(logN): tries () are O(1) for access, relative to number of elements, in fact their search is not related to that factor, just like hash table instead to the length of keys (O(log(length)). Hash tables actually have an access time firstly depending on hash computation time, which can be costly: they are like O(k), where can like for tries often depends on key size. Then statistically a linear time O(n) inside buckets enters the game; hard to manage evaluate because it depends on average load, meaning numbered of elements relative to number of buckets. Then, it's a question of pondering time vs space cost. FWIW, I have implemented tries as fast as library hash tables for a single key type in freepascal (without even optimising). And both of those sophisticated data structures only were worth it above a threshold of about 100 items; I mean compared to plain arrays of (key,value) pairs! In D, not only there is no way (for me) to even approach builtin AA perf with tries (even with some search for optimisation), but those deadly flash-fast AAs are worth it as early as with a few items! (again, compared to arrays of (key,value) pairs). If you want numbers, search the archives of the PiLuD mailing list, I published much data in a thread there (last year): http://groups.google.com/group/pilud/ People, like me, concluded for instance that to implement namespaces it's really not worth it to use complicated data structures. We were wrong (I had not yet met D's AAs then). Denis -- _ vita es estrany spir.wikidot.com
Number of references to a Class Object
Greetings I am in a situation where I need to know the number of references to a class' object. To explain, I have an array of class objects and I occasionally process this array. But if a particular object in this array is not being garbage collected just because it is part of this array, I would like to loose that object by making it null. So either I need to find out the number of references to that object and in case there is only one reference, I force the object null. If this is not possible, I am sure there would be alternative solutions since this should be a common situation faced by programmers. Please help. Regards - Cherry
Re: Number of references to a Class Object
On Sat, Feb 12, 2011 at 1:20 AM, d coder dlang.co...@gmail.com wrote: Greetings I am in a situation where I need to know the number of references to a class' object. To explain, I have an array of class objects and I occasionally process this array. But if a particular object in this array is not being garbage collected just because it is part of this array, I would like to loose that object by making it null. I believe what you're referring to is generally called a Weak Reference, which is a reference that the GC doesn't consider when deciding to keep an object alive, but that the GC will update if an object dies. There's a feature request at http://d.puremagic.com/issues/show_bug.cgi?id=4151
Re: Number of references to a Class Object
I believe what you're referring to is generally called a Weak Reference, which is a reference that the GC doesn't consider when deciding to keep an object alive, but that the GC will update if an object dies. There's a feature request at http://d.puremagic.com/issues/show_bug.cgi?id=4151 Thanks Andrew Is there a way fro the users like myself to vote up an issue on DMD Bugzilla. Regards - Cherry