Re: using enums as key in associative array
enum deviceType {cpu, gpu} auto execDeviceSuffix = [deviceType.cpu:.cpu, deviceType.gpu:.gpu]; The way to get what you want to work in this case is to use a module constructor. So, you'd do something like this: string[deviceType] execDeviceSuffix; static this() { execDeviceSuffix[deviceType.cpu] = cpu; execDeviceSuffix[deviceType.gpu] = gpu; } The module constructor will be run before main does, so execDeviceSuffix will be properly filled in by then. I didn't get to the point where module constructors are introduced in Andrei's book yet. I really like this idea ! I found a similar workaround which used an useless class so that I could use the static constructor but this is even better !
Re: Access 'this' in inline assembly
Brad Roberts: It's not by design. It's a quality of implementation issue that's solvable given some time to work on it. I intend to, eventually, unless someone has gotten to it ahead of me. Good, I am glad to be wrong then. Currently in LDC you have two different ways to tell the compiler to inline some Asm. Such syntaxes are not present in D/DMD. So do you plan to add something like those two syntaxes to D/DMD too? One of them is this pragma: http://www.dsource.org/projects/ldc/wiki/Docs#allow_inline int add(int a, int b) { pragma(allow_inline); asm { mov EAX, a; add EAX, b; } } And the other one is Inline asm expressions: http://www.dsource.org/projects/ldc/wiki/InlineAsmExpressions That are used like this: // store val into dst void store(ref int dst, int val) { __asm(ldw r4, $1 ; stw r4, $0, =*m,r,~{r4}, dst, val); } Bye, bearophile
Re: Struct constructor and opCall confussion
Tom: Am I missing something or is this another major bug? A major bug (that is not recognized as major, I think). I don't remember its number in bugzilla, sorry (anyone remembers it?). See also: http://d.puremagic.com/issues/show_bug.cgi?id=4053 Bye, bearophile
Re: dmd gdc in archlinux
== Quote from Jonathan M Davis (jmdavisp...@gmx.com)'s article On Monday, March 07, 2011 12:10:27 %u wrote: == Quote from Jonathan M Davis (jmdavisp...@gmx.com)'s article and add /path/to/unzipped/dmd2/linux/bin to your path. how can i add path ? Put it in the appropriate bashrc file - be it your personal .bashrc or /etc/bash.bashrc.local or whatever is appropriate for your system. On my Arch system, I believe that I put it in /etc/bash.bashrc.local. Regardless, you add a line similar to this to your bashrc file: export PATH=$PATH:/path/to/unzipped/dmd2/linux/bin On my system, it's export PATH=$PATH:/home/jmdavis/dmd2/linux/bin - Jonathan M Davis Jonathan M Davis you are the best thanks
Re: using enums as key in associative array
On 03/08/2011 09:26 AM, Wilfried Kirschenmann wrote: enum deviceType {cpu, gpu} auto execDeviceSuffix = [deviceType.cpu:.cpu, deviceType.gpu:.gpu]; The way to get what you want to work in this case is to use a module constructor. So, you'd do something like this: string[deviceType] execDeviceSuffix; static this() { execDeviceSuffix[deviceType.cpu] = cpu; execDeviceSuffix[deviceType.gpu] = gpu; } The module constructor will be run before main does, so execDeviceSuffix will be properly filled in by then. I didn't get to the point where module constructors are introduced in Andrei's book yet. I really like this idea ! I found a similar workaround which used an useless class so that I could use the static constructor but this is even better ! This is a very nice feature, yes. But I personly see it as a workaround for the limitation that dmd, apparently, is not able to correctly evaluate many kinds of assignment expressions. And it's ugly when one has hordes of definitions -- the module is (mainly) a piece of data description: all symbols must first be declared /outside/, then redefined /inside/ static this(). Else, D would be a great data-definition language, in addition to its other qualities, thank to its literals for everything (and conversely its standard to!string for everything, which needs improvements). Think a static Lua. Denis -- _ vita es estrany spir.wikidot.com
Re: using enums as key in associative array
On Tuesday 08 March 2011 04:54:45 spir wrote: On 03/08/2011 09:26 AM, Wilfried Kirschenmann wrote: enum deviceType {cpu, gpu} auto execDeviceSuffix = [deviceType.cpu:.cpu, deviceType.gpu:.gpu]; The way to get what you want to work in this case is to use a module constructor. So, you'd do something like this: string[deviceType] execDeviceSuffix; static this() { execDeviceSuffix[deviceType.cpu] = cpu; execDeviceSuffix[deviceType.gpu] = gpu; } The module constructor will be run before main does, so execDeviceSuffix will be properly filled in by then. I didn't get to the point where module constructors are introduced in Andrei's book yet. I really like this idea ! I found a similar workaround which used an useless class so that I could use the static constructor but this is even better ! This is a very nice feature, yes. But I personly see it as a workaround for the limitation that dmd, apparently, is not able to correctly evaluate many kinds of assignment expressions. And it's ugly when one has hordes of definitions -- the module is (mainly) a piece of data description: all symbols must first be declared /outside/, then redefined /inside/ static this(). Else, D would be a great data-definition language, in addition to its other qualities, thank to its literals for everything (and conversely its standard to!string for everything, which needs improvements). Think a static Lua. ??? It's for stuff that has to be defined at runtime. There's plenty of stuff that _has_ to be done at runtime and could _never_ be done at compile time no matter how great the language is. For instance, what if you want to have a variable with the time that the program started running? You certainly couldn't do that at compile time. Sure, there are things that you'd ideally be able to set with CTFE and currenly can't, but it's not like a better CTFE would negate the need for static constructors. And honestly, in other cases, such as when you have to use a module constructor because of interdependencies between variables when initializing them and they're mutable, the fact that you can't do that at compile time is _fantastic_. In other programming languages, you run into problems because of the order of evaluation of the declarations of such variables. D makes them it so the order truly doesn't matter, because when it does, you have to use a module constructor. That's _huge_. I really don't understand your problem with module constructors. They're fantastic. - Jonathan M Davis
Re: using enums as key in associative array
On 03/08/2011 03:48 PM, Jonathan M Davis wrote: I really don't understand your problem with module constructors. They're fantastic. I may be wrong, but I think this point of view is a where I can from statement. C's char* are fantastic when you have never used a PL with builtin strings. There are languages in which you don't need to list twice everything just to have them available at import time. // data definition X foo; Y bar; Z baz; ... static this { foo = ...; bar = ...; baz = ...; ... } Denis -- _ vita es estrany spir.wikidot.com
Re: Struct constructor and opCall confussion
El 08/03/2011 05:32, bearophile escribió: Tom: Am I missing something or is this another major bug? A major bug (that is not recognized as major, I think). I don't remember its number in bugzilla, sorry (anyone remembers it?). See also: http://d.puremagic.com/issues/show_bug.cgi?id=4053 Bye, bearophile Think I found it: http://d.puremagic.com/issues/show_bug.cgi?id=4253 This is indeed a major bug. Why not tag it as major? I think it's a straight loss of functionality and it happens under almost any circumstance in which one wishes to simply use opCall and a struct... Tom;
Re: using enums as key in associative array
I really don't understand your problem with module constructors. They're fantastic. I may be wrong, but I think this point of view is a where I can from statement. C's char* are fantastic when you have never used a PL with builtin strings. There are languages in which you don't need to list twice everything just to have them available at import time. // data definition X foo; Y bar; Z baz; ... static this { foo = ...; bar = ...; baz = ...; ... } The question is : what are in the dots : static this { // get information from environment ... // load information from a module configuration file ... // make some complex computation ... // initialize data in any order baz = ...; bar = ...; foo = functionOf(baz, bar); } This way, you have made independent the initialization of a module from the initialization of the user's application. However, I agree to the fact that for statically known value (such as my first example), this far from optimal. Wilfried
Re: Struct constructor and opCall confussion
On Tue, 08 Mar 2011 10:52:38 -0500, Tom t...@nospam.com wrote: El 08/03/2011 05:32, bearophile escribió: Tom: Am I missing something or is this another major bug? A major bug (that is not recognized as major, I think). I don't remember its number in bugzilla, sorry (anyone remembers it?). See also: http://d.puremagic.com/issues/show_bug.cgi?id=4053 Bye, bearophile Think I found it: http://d.puremagic.com/issues/show_bug.cgi?id=4253 Those two bugs look almost identical, I think they should be combined... -Steve
Re: Struct constructor and opCall confussion
El 08/03/2011 13:05, Steven Schveighoffer escribió: On Tue, 08 Mar 2011 10:52:38 -0500, Tom t...@nospam.com wrote: El 08/03/2011 05:32, bearophile escribió: Tom: Am I missing something or is this another major bug? A major bug (that is not recognized as major, I think). I don't remember its number in bugzilla, sorry (anyone remembers it?). See also: http://d.puremagic.com/issues/show_bug.cgi?id=4053 Bye, bearophile Think I found it: http://d.puremagic.com/issues/show_bug.cgi?id=4253 Those two bugs look almost identical, I think they should be combined... -Steve I agree. They should be combined into a major (severity) bug.
std.traits and std.string incompatible ?
Hi, When running the following file: #!../dmd2/linux/bin/rdmd -unittest import std.string, std.traits; void main(string[] args){ bool test = isNumeric(args[0]); } I get the error : dmd2/linux/bin/../../src/phobos/std/traits.d(2576): Error: template std.traits.isNumeric(T) is not a function template Is this a bug or is there something deprecated ? Wilfried
Templated struct doesn't need the parameterized type in return type definitions?
import std.stdio; import std.traits; import std.exception; struct CheckedInt(N) if (isIntegral!N) { private N value; ref CheckedInt opUnary(string op)() if (op == ++) { enforce(value != value.max); ++value; return this; } this(N _value) { value = _value; } } I didn't know you could define a return type of a templated struct without defining the type it is parameterized on. I mean this line: ref CheckedInt opUnary(string op)() if (op == ++) I thought for sure I always had to write the parameterized type like so: ref CheckedInt!(N) opUnary(string op)() if (op == ++) So I guess this really isn't a question but more of a oh, I didn't know you could do that. In fact I rarely see this kind of code in Phobos, most of the time the parameterized type is specified in these types of cases. Is this feature described somewhere, because I must have missed it if it is? As a side-note, auto ref is useful in this case, which is pretty cool: auto ref opUnary(string op)() if (op == ++)
Re: Templated struct doesn't need the parameterized type in return type definitions?
On Tue, 08 Mar 2011 12:06:08 -0500, Andrej Mitrovic n...@none.none wrote: import std.stdio; import std.traits; import std.exception; struct CheckedInt(N) if (isIntegral!N) { private N value; ref CheckedInt opUnary(string op)() if (op == ++) { enforce(value != value.max); ++value; return this; } this(N _value) { value = _value; } } I didn't know you could define a return type of a templated struct without defining the type it is parameterized on. I mean this line: ref CheckedInt opUnary(string op)() if (op == ++) I thought for sure I always had to write the parameterized type like so: ref CheckedInt!(N) opUnary(string op)() if (op == ++) So I guess this really isn't a question but more of a oh, I didn't know you could do that. In fact I rarely see this kind of code in Phobos, most of the time the parameterized type is specified in these types of cases. Is this feature described somewhere, because I must have missed it if it is? It is described, but not directly. Look on this page: http://www.digitalmars.com/d/2.0/template.html From there we have these two descriptions: If a template has exactly one member in it, and the name of that member is the same as the template name, that member is assumed to be referred to in a template instantiation: template Foo(T) { T Foo;// declare variable Foo of type T } void test() { Foo!(int) = 6;// instead of Foo!(int).Foo } If a template declares exactly one member, and that member is a class with the same name as the template: template Bar(T) { class Bar { T member; } } then the semantic equivalent, called a ClassTemplateDeclaration can be written as: class Bar(T) { T member; } Also note that structs have the same description. So if you think about it, your code is equivalent to: template CheckedInt(N) if(isIntegral!N) { struct CheckedInt { ... } } If you look at it this way, it makes complete sense that within the struct that's within the template, the struct can refer to itself without the specific instantiation parameters. I think this should really be laid out properly in the docs. I discovered this trick while writing dcollections by accident and thought it so awesome that I changed all my code which self-returned (quite a bit). -Steve
Re: std.traits and std.string incompatible ?
On 03/08/2011 08:24 AM, Wilfried Kirschenmann wrote: Hi, When running the following file: #!../dmd2/linux/bin/rdmd -unittest import std.string, std.traits; void main(string[] args){ bool test = isNumeric(args[0]); } I get the error : dmd2/linux/bin/../../src/phobos/std/traits.d(2576): Error: template std.traits.isNumeric(T) is not a function template Is this a bug or is there something deprecated ? Wilfried isNumeric is a template. You are supposed to give it a type: if (isNumeric!SomeType) or at compile time: static if (isNumeric!SomeType) It doesn't work with string values. Although unnecessary, you could do this: bool test = isNumeric!(typeof(args[0])); Ali
Empty field doesn't exist for arrays, right?
module test; struct MyArray(T) { private T[] data; bool opCast(T)() if (is(T == bool)) { return !data.empty; } } void main() { auto foo = MyArray!(int)(); auto state = foo ? true : false; } test.d(13): Error: undefined identifier module test.empty test.d(20): Error: template instance test.MyArray!(int).MyArray.opCast!(bool) error instantiating This is straight from the book. Did .empty exist for arrays before? Perhaps this was just a typo in the book, and it was supposed to be: bool opCast(T)() if (is(T == bool)) { return data.length != 0; } Also, that error message *really* needs to improve. It's not module 'test' which is missing the method, it's 'data'. This is one of the most confusing error messages that I know of and it pops up all the time.
Re: Empty field doesn't exist for arrays, right?
Nevermind, I'm dumb. It's in std.array, I just need to import it. This needs to be said in TDPL however.
Re: Struct constructor and opCall confussion
Steven Schveighoffe: Those two bugs look almost identical, I think they should be combined... Right, they look similar. I have linked each with the other, so if one gets fixed it's very easy to see if the fix fixes the other too. One bug has 4 votes and one bug 1 vote. Bye, bearophile
Re: Empty field doesn't exist for arrays, right?
On 3/8/11, bearophile bearophileh...@lycos.com wrote: empty is not an array method, it's a free function that is used with a funny syntax. Yes but the compiler doesn't know that until std.array is imported. A better error message is that empty isn't a property of that array. It's much easier to reason about this way.
Re: Empty field doesn't exist for arrays, right?
Andrej Mitrovic Wrote: On 3/8/11, bearophile bearophileh...@lycos.com wrote: empty is not an array method, it's a free function that is used with a funny syntax. Yes but the compiler doesn't know that until std.array is imported. A better error message is that empty isn't a property of that array. It's much easier to reason about this way. What if you are trying to create a method which will act as a property for the array? If you get it wrong you would get the error that an array doesn't have the property and scream, I know that is why I'm building a function for it. Why won't it find my function stead of looking at what array provides! Also doesn't TDPL introduce Ranges by implementing them for arrays and then tell you that you don't have to do this every time because it is an the standard labrary std.array?
Re: Empty field doesn't exist for arrays, right?
On 3/8/11, Jesse Phillips jessekphillip...@gmail.com wrote: What if you are trying to create a method which will act as a property for the array? If you get it wrong you would get the error that an array doesn't have the property and scream, I know that is why I'm building a function for it. Why won't it find my function stead of looking at what array provides! But wouldn't this case be much more obvious with the property error message? Or maybe it wouldn't.. all I know is I got bitten by this error message a couple of times and it always got me that WTF look on my face. How common are typos in invoking methods versus typos in implementing methods like a UFCS function?
Re: Templated struct doesn't need the parameterized type in return type definitions?
On 03/08/2011 06:20 PM, Steven Schveighoffer wrote: On Tue, 08 Mar 2011 12:06:08 -0500, Andrej Mitrovic n...@none.none wrote: import std.stdio; import std.traits; import std.exception; struct CheckedInt(N) if (isIntegral!N) { private N value; ref CheckedInt opUnary(string op)() if (op == ++) { enforce(value != value.max); ++value; return this; } this(N _value) { value = _value; } } I didn't know you could define a return type of a templated struct without defining the type it is parameterized on. I mean this line: ref CheckedInt opUnary(string op)() if (op == ++) I thought for sure I always had to write the parameterized type like so: ref CheckedInt!(N) opUnary(string op)() if (op == ++) So I guess this really isn't a question but more of a oh, I didn't know you could do that. In fact I rarely see this kind of code in Phobos, most of the time the parameterized type is specified in these types of cases. Is this feature described somewhere, because I must have missed it if it is? It is described, but not directly. Look on this page: http://www.digitalmars.com/d/2.0/template.html From there we have these two descriptions: If a template has exactly one member in it, and the name of that member is the same as the template name, that member is assumed to be referred to in a template instantiation: template Foo(T) { T Foo; // declare variable Foo of type T } void test() { Foo!(int) = 6; // instead of Foo!(int).Foo } If a template declares exactly one member, and that member is a class with the same name as the template: template Bar(T) { class Bar { T member; } } then the semantic equivalent, called a ClassTemplateDeclaration can be written as: class Bar(T) { T member; } Also note that structs have the same description. So if you think about it, your code is equivalent to: template CheckedInt(N) if(isIntegral!N) { struct CheckedInt { ... } } If you look at it this way, it makes complete sense that within the struct that's within the template, the struct can refer to itself without the specific instantiation parameters. I think this should really be laid out properly in the docs. I discovered this trick while writing dcollections by accident and thought it so awesome that I changed all my code which self-returned (quite a bit). -Steve I don't share your enthusiasm, Steven, for this feature (which I did not know). In fact, I tend to consider it a mis-feature. Yet another syntactic special-case for special cases in the language. In this case, there are even 3 ways to write the same thing: CheckedInt CheckedInt!N CheckedInt!(N) And note these variants are low-level ones, morphological rather than syntactic properly speaking. Denis -- _ vita es estrany spir.wikidot.com
Re: Empty field doesn't exist for arrays, right?
On 03/08/2011 06:56 PM, Andrej Mitrovic wrote: module test; struct MyArray(T) { private T[] data; bool opCast(T)() if (is(T == bool)) { return !data.empty; } } void main() { auto foo = MyArray!(int)(); auto state = foo ? true : false; } test.d(13): Error: undefined identifier module test.empty test.d(20): Error: template instance test.MyArray!(int).MyArray.opCast!(bool) error instantiating This is straight from the book. Did .empty exist for arrays before? Perhaps this was just a typo in the book, and it was supposed to be: bool opCast(T)() if (is(T == bool)) { return data.length != 0; } Also, that error message *really* needs to improve. It's not module 'test' which is missing the method, it's 'data'. This is one of the most confusing error messages that I know of and it pops up all the time. Agreed. But do you understand why dmd throws that error, anyway? I'm not sure, the following may be plain shit. My guess is, since UFCS (universal function call syntax) exists for arrays, when dmd decodes data.empty and does not find any empty slot on 'data' or on its type, it tries rewriting it into empty(data). Right? then, to execute that, it looks for an empty func in the module, which it does not find... thus the message. Note that if one of your imports happened to hold an empty func, either it would execute by plain chance, or you would get a type error! HTH Denis -- _ vita es estrany spir.wikidot.com
Re: Templated struct doesn't need the parameterized type in return type definitions?
On 3/8/11 8:20 PM, spir wrote: […] Yet another syntactic special-case for special cases in the language. In this case, there are even 3 ways to write the same thing: […] I don't quite get how you think this would be a syntactic special case. As Steve pointed out, »class Foo(T) {}« is merely syntax sugar for »template Foo(T) { class Foo{} }«, and because of this, it would rather be a special case *not* to allow referring to Foo using just that name. When considering this, don't forget that templates in D are little more than parametrized, named scopes. I guess you could argue that »class Foo(T)« as a shorthand is an unnecessary special case, but I very much prefer the benefit in brevity here… David
Re: Templated struct doesn't need the parameterized type in return type definitions?
On Tue, 08 Mar 2011 14:20:40 -0500, spir denis.s...@gmail.com wrote: On 03/08/2011 06:20 PM, Steven Schveighoffer wrote: On Tue, 08 Mar 2011 12:06:08 -0500, Andrej Mitrovic n...@none.none wrote: import std.stdio; import std.traits; import std.exception; struct CheckedInt(N) if (isIntegral!N) { private N value; ref CheckedInt opUnary(string op)() if (op == ++) { enforce(value != value.max); ++value; return this; } this(N _value) { value = _value; } } I didn't know you could define a return type of a templated struct without defining the type it is parameterized on. I mean this line: ref CheckedInt opUnary(string op)() if (op == ++) I thought for sure I always had to write the parameterized type like so: ref CheckedInt!(N) opUnary(string op)() if (op == ++) So I guess this really isn't a question but more of a oh, I didn't know you could do that. In fact I rarely see this kind of code in Phobos, most of the time the parameterized type is specified in these types of cases. Is this feature described somewhere, because I must have missed it if it is? It is described, but not directly. Look on this page: http://www.digitalmars.com/d/2.0/template.html From there we have these two descriptions: If a template has exactly one member in it, and the name of that member is the same as the template name, that member is assumed to be referred to in a template instantiation: template Foo(T) { T Foo; // declare variable Foo of type T } void test() { Foo!(int) = 6; // instead of Foo!(int).Foo } If a template declares exactly one member, and that member is a class with the same name as the template: template Bar(T) { class Bar { T member; } } then the semantic equivalent, called a ClassTemplateDeclaration can be written as: class Bar(T) { T member; } Also note that structs have the same description. So if you think about it, your code is equivalent to: template CheckedInt(N) if(isIntegral!N) { struct CheckedInt { ... } } If you look at it this way, it makes complete sense that within the struct that's within the template, the struct can refer to itself without the specific instantiation parameters. I think this should really be laid out properly in the docs. I discovered this trick while writing dcollections by accident and thought it so awesome that I changed all my code which self-returned (quite a bit). -Steve I don't share your enthusiasm, Steven, for this feature (which I did not know). In fact, I tend to consider it a mis-feature. Yet another syntactic special-case for special cases in the language. In this case, there are even 3 ways to write the same thing: CheckedInt CheckedInt!N CheckedInt!(N) And note these variants are low-level ones, morphological rather than syntactic properly speaking. Here's another thing I found in dcollections which caught me off guard, and which I was glad to be rid of when I switched to not parameterizing the names of self returns: class Collection(T) { Collection!(T) add(T t) { ...; return this; } // 20 other functions like add... } Hey, wouldn't it be cool if I could add a custom allocator to all classes!?... class Collection(T, alloc = DefaultAllocator!T) { Collection!(T) add(T t) { ...; return this; } // 20 other now subtly incorrect functions like add... } See the problem? -Steve
Re: Some weird crashes
On 08.03.2011 01:32, Andrej Mitrovic wrote: Sorry for not seeing this sooner. I think you might have set the wrong calling convention in the translated header file. See my answer on SO. I hope it works for you now. Thanks. Just to get the solution here too: * Use the vs2005 library (to get COFF?) * coffimplib * wrap __stdcall in extern(Windows) One more thing.. Function pointers in structs.. Should they use extern(Windows) too?
Re: Templated struct doesn't need the parameterized type in return
David Nadlinger: and because of this, it would rather be a special case *not* to allow referring to Foo using just that name. Right. On the other hand the current straightforward design leads to some bugs too, the give bad error messages: http://d.puremagic.com/issues/show_bug.cgi?id=3950 Bye, bearophile
Re: std.traits and std.string incompatible ?
Ali Çehreli acehr...@yahoo.com wrote in message news:il5pge$nrr$1...@digitalmars.com... On 03/08/2011 08:24 AM, Wilfried Kirschenmann wrote: Hi, When running the following file: #!../dmd2/linux/bin/rdmd -unittest import std.string, std.traits; void main(string[] args){ bool test = isNumeric(args[0]); } I get the error : dmd2/linux/bin/../../src/phobos/std/traits.d(2576): Error: template std.traits.isNumeric(T) is not a function template Is this a bug or is there something deprecated ? Wilfried isNumeric is a template. You are supposed to give it a type: if (isNumeric!SomeType) or at compile time: static if (isNumeric!SomeType) It doesn't work with string values. Although unnecessary, you could do this: bool test = isNumeric!(typeof(args[0])); No, there's an isNumeric in *both* std.traits and std.string. The one in std.traits is a template that takes a type. But the one in std.string is a function that takes a string and checks if the value of the string is numeric. I'm on the latest D2 (2.052) and I just tried the example and got the same result. But if I *only* import std.string then it works. So it sounds like a bug: I forget the exact details of the rules involving overloading across modules, but one of two things should happen with the original example: A. It should know that you meant std.string.isNumeric because of how you're calling it. or: B. It should complain that there's an ambiguity between std.string.isNumeric and std.traits.isNumeric and require you to disambiguate with either std.traits. or std.string. I'm not sure which of those it's supposed to do, but it's clearly not doing either, so I'd file it as a bug: http://d.puremagic.com/issues/
Re: Empty field doesn't exist for arrays, right?
Andrej Mitrovic Wrote: On 3/8/11, Jesse Phillips jessekphillip...@gmail.com wrote: What if you are trying to create a method which will act as a property for the array? If you get it wrong you would get the error that an array doesn't have the property and scream, I know that is why I'm building a function for it. Why won't it find my function stead of looking at what array provides! But wouldn't this case be much more obvious with the property error message? Or maybe it wouldn't.. all I know is I got bitten by this error message a couple of times and it always got me that WTF look on my face. I don't think so. If you didn't know empty was a library feature then you'd get the message, empty is not a property of array. and be confused thinking that other code uses it. It would probably result in looking up other code which uses it then the properties available to arrays in the documentation and then a post to the NG confused on how other code gets away with it. I don't really know, it just seems like someone is going to be lost no matter what it is. How common are typos in invoking methods versus typos in implementing methods like a UFCS function? But if you know that empty is a function not a property, then the error makes much more sense. I think the confusion comes from not knowing it is a property or a function you are trying to call.
Dynamic array void initialization
import std.stdio; struct S { int i; int j; } int main(string[] args) { S[] ss = void; ss.length = 5; foreach (ref s; ss) s = S(1, 2); return 0; } Is the above code correct? (it doesn't work... it blows away or just give and access violation error). I need to create a dynamic array of some struct, but don't want defer contained elements initialization (for performance reasons). Tom;
Re: Dynamic array void initialization
On 03/08/2011 01:34 PM, Tom wrote: import std.stdio; struct S { int i; int j; } int main(string[] args) { S[] ss = void; ss.length = 5; foreach (ref s; ss) s = S(1, 2); return 0; } Is the above code correct? (it doesn't work... it blows away or just give and access violation error). I need to create a dynamic array of some struct, but don't want defer contained elements initialization (for performance reasons). Tom; There is std.array.reserve: import std.array; struct S { int i; int j; } int main(string[] args) { S[] ss; reserve(ss, 5); // or if you want to confuse yourself (and me): ss.reserve(5); // same thing as above foreach (ref s; ss) s = S(1, 2); return 0; } Ali
Re: Dynamic array void initialization
On Tue, 08 Mar 2011 16:53:08 -0500, Ali Çehreli acehr...@yahoo.com wrote: On 03/08/2011 01:34 PM, Tom wrote: import std.stdio; struct S { int i; int j; } int main(string[] args) { S[] ss = void; ss.length = 5; foreach (ref s; ss) s = S(1, 2); return 0; } Is the above code correct? (it doesn't work... it blows away or just give and access violation error). I need to create a dynamic array of some struct, but don't want defer contained elements initialization (for performance reasons). Tom; There is std.array.reserve: import std.array; struct S { int i; int j; } int main(string[] args) { S[] ss; reserve(ss, 5); // or if you want to confuse yourself (and me): ss.reserve(5); // same thing as above foreach (ref s; ss) s = S(1, 2); return 0; } Some clarifications: it's not std.array.reserve, it's object.reserve, always present, no need to import. I believe if the type contains pointers the GC still writes 0s to the unused data to prevent false pointers. However, reserve on an int or a struct that just contains ints should not pre-initialize. reserve ensures appropriate space for appending, it does *not* alter the array's length. So your foreach loop would not execute (at that point, ss.length is still 0). To work properly, you would need to use the append operator. Bearophile has requested an ability to create a dynamic array uninitialized, and I think there is a bug report for that. Currently, there is no easy way to do it. -Steve
Re: Dynamic array void initialization
On 03/08/2011 02:03 PM, Steven Schveighoffer wrote: it's not std.array.reserve, it's object.reserve, always present, no need to import. Thanks. The reserve that I found in array.d is std.array.Appender(T).reserve. Ali
Re: Dynamic array void initialization
El 08/03/2011 19:03, Steven Schveighoffer escribió: On Tue, 08 Mar 2011 16:53:08 -0500, Ali Çehreli acehr...@yahoo.com wrote: On 03/08/2011 01:34 PM, Tom wrote: import std.stdio; struct S { int i; int j; } int main(string[] args) { S[] ss = void; ss.length = 5; foreach (ref s; ss) s = S(1, 2); return 0; } Is the above code correct? (it doesn't work... it blows away or just give and access violation error). I need to create a dynamic array of some struct, but don't want defer contained elements initialization (for performance reasons). Tom; There is std.array.reserve: import std.array; struct S { int i; int j; } int main(string[] args) { S[] ss; reserve(ss, 5); // or if you want to confuse yourself (and me): ss.reserve(5); // same thing as above foreach (ref s; ss) s = S(1, 2); return 0; } Some clarifications: it's not std.array.reserve, it's object.reserve, always present, no need to import. I believe if the type contains pointers the GC still writes 0s to the unused data to prevent false pointers. However, reserve on an int or a struct that just contains ints should not pre-initialize. reserve ensures appropriate space for appending, it does *not* alter the array's length. So your foreach loop would not execute (at that point, ss.length is still 0). To work properly, you would need to use the append operator. Bearophile has requested an ability to create a dynamic array uninitialized, and I think there is a bug report for that. Currently, there is no easy way to do it. -Steve http://d.puremagic.com/issues/show_bug.cgi?id=5603 This is really sad. This kind of stuff is a must for performance. D is disappointing me too much yet :(
Re: Dynamic array void initialization
On Tue, 08 Mar 2011 17:48:37 -0500, Tom t...@nospam.com wrote: http://d.puremagic.com/issues/show_bug.cgi?id=5603 This is really sad. This kind of stuff is a must for performance. D is disappointing me too much yet :( There is always c's malloc, or you can try using the GC malloc directly. For application specific needs, it might be sufficient. However, a builtin language/library feature must be very robust and handle all cases. -Steve
Re: Empty field doesn't exist for arrays, right?
Well, maybe one day we'll have a compiler with lots of front-end customization options (or some nice analysis tools). In any case this topic is done here since post #2. :)
Re: Templated struct doesn't need the parameterized type in return type definitions?
On 3/8/11, Steven Schveighoffer schvei...@yahoo.com wrote: See the problem? Yup. Btw, does auto ref still suffer from any bugs that I should know about? I've heard it had issues.
Re: using enums as key in associative array
On Tuesday, March 08, 2011 07:40:08 spir wrote: On 03/08/2011 03:48 PM, Jonathan M Davis wrote: I really don't understand your problem with module constructors. They're fantastic. I may be wrong, but I think this point of view is a where I can from statement. C's char* are fantastic when you have never used a PL with builtin strings. There are languages in which you don't need to list twice everything just to have them available at import time. // data definition X foo; Y bar; Z baz; ... static this { foo = ...; bar = ...; baz = ...; ... } In one case, you're declaring a variable. In another, you're giving it a value. They're two _very_ different things. In one case, you're telling the compiler that a particular variable exists. In the other, you're giving it a value. Generally, it is ideal to give a variable its initial value (and final value if it's not mutable) when you declare it, and there's no question that CTFE is currently not as good as we'd like in that regard. However, there are plenty of cases where it makes no sense to give a variable its initial value at compile time. So, given that D requires that _all_ module variables, class/struct variables, and member variables which are directly initialized have that value known at compile time, you have to do it separately to do it runtime. Also, there are plenty of cases where there are dependcies between variables such that you need to actually give them values within a function rather than statically. Constructors do a beautiful job of dealing with this problem. The main alternative is to allow you to set module, class/struct, and member variables directly at runtime. Languages such as C++ and Java do this, and it causes a host of problems. The order of initialization isn't necessarily defined. It's possible to end up using variables before they're actually initialized. Compilation is slower because of all of the interdependencies, whereas in D it's possible to parallelize a lot of what the compiler does with declarations, because they're not interdependent like they are in C++ or Java. Not to mention, if you want to be able to initialize them in a manner which requires you to essentially have a function rather than set them directly, then you _need_ something like a constructor to initialize them. Also, you don't get compile time evaluation of variables in languages like C/C++ and Java like you do in D, so _every_ variable is initialized at runtime. The occasional irritation with the current implementation problems of CTFE is _well_ worth the gain in compile time evaluation. D uses a model similar to C/C++ and Java, but it improves on it _considerably_ by doing things the way it does. The order of initialization in D is _well- defined_ and not bug-prone. It also lends itself to efficient compilation. Granted, until CTFE is able to do anything in SafeD (as its intended to do eventually), there are going to be irritating restrictions with regards to what we can and can't initialize directly using CTFE, but that's an implementation detail which will improve. D's design in this regard is excellent. - Jonathan M Davis
Re: std.traits and std.string incompatible ?
On Tuesday, March 08, 2011 13:24:44 Nick Sabalausky wrote: Ali Çehreli acehr...@yahoo.com wrote in message news:il5pge$nrr$1...@digitalmars.com... On 03/08/2011 08:24 AM, Wilfried Kirschenmann wrote: Hi, When running the following file: #!../dmd2/linux/bin/rdmd -unittest import std.string, std.traits; void main(string[] args){ bool test = isNumeric(args[0]); } I get the error : dmd2/linux/bin/../../src/phobos/std/traits.d(2576): Error: template std.traits.isNumeric(T) is not a function template Is this a bug or is there something deprecated ? Wilfried isNumeric is a template. You are supposed to give it a type: if (isNumeric!SomeType) or at compile time: static if (isNumeric!SomeType) It doesn't work with string values. Although unnecessary, you could do this: bool test = isNumeric!(typeof(args[0])); No, there's an isNumeric in *both* std.traits and std.string. The one in std.traits is a template that takes a type. But the one in std.string is a function that takes a string and checks if the value of the string is numeric. I'm on the latest D2 (2.052) and I just tried the example and got the same result. But if I *only* import std.string then it works. So it sounds like a bug: I forget the exact details of the rules involving overloading across modules, but one of two things should happen with the original example: A. It should know that you meant std.string.isNumeric because of how you're calling it. or: B. It should complain that there's an ambiguity between std.string.isNumeric and std.traits.isNumeric and require you to disambiguate with either std.traits. or std.string. I'm not sure which of those it's supposed to do, but it's clearly not doing either, so I'd file it as a bug: http://d.puremagic.com/issues/ isNumeric in std.string is a function. In std.traits, it's an eponymous template. The eponymous template should require the !. There's no function to feed the argument to. There shouldn't be any ambiguity of any kind. Overload set rules and whatnot should have nothing to do with this. This is definitely a bug. - Jonathan M Davis
Re: std.traits and std.string incompatible ?
On Tuesday, March 08, 2011 16:11:09 Jonathan M Davis wrote: On Tuesday, March 08, 2011 13:24:44 Nick Sabalausky wrote: Ali Çehreli acehr...@yahoo.com wrote in message news:il5pge$nrr$1...@digitalmars.com... On 03/08/2011 08:24 AM, Wilfried Kirschenmann wrote: Hi, When running the following file: #!../dmd2/linux/bin/rdmd -unittest import std.string, std.traits; void main(string[] args){ bool test = isNumeric(args[0]); } I get the error : dmd2/linux/bin/../../src/phobos/std/traits.d(2576): Error: template std.traits.isNumeric(T) is not a function template Is this a bug or is there something deprecated ? Wilfried isNumeric is a template. You are supposed to give it a type: if (isNumeric!SomeType) or at compile time: static if (isNumeric!SomeType) It doesn't work with string values. Although unnecessary, you could do this: bool test = isNumeric!(typeof(args[0])); No, there's an isNumeric in *both* std.traits and std.string. The one in std.traits is a template that takes a type. But the one in std.string is a function that takes a string and checks if the value of the string is numeric. I'm on the latest D2 (2.052) and I just tried the example and got the same result. But if I *only* import std.string then it works. So it sounds like a bug: I forget the exact details of the rules involving overloading across modules, but one of two things should happen with the original example: A. It should know that you meant std.string.isNumeric because of how you're calling it. or: B. It should complain that there's an ambiguity between std.string.isNumeric and std.traits.isNumeric and require you to disambiguate with either std.traits. or std.string. I'm not sure which of those it's supposed to do, but it's clearly not doing either, so I'd file it as a bug: http://d.puremagic.com/issues/ isNumeric in std.string is a function. In std.traits, it's an eponymous template. The eponymous template should require the !. There's no function to feed the argument to. There shouldn't be any ambiguity of any kind. Overload set rules and whatnot should have nothing to do with this. This is definitely a bug. Reported: http://d.puremagic.com/issues/show_bug.cgi?id=5721 - Jonathan M Davis
Re: Templated struct doesn't need the parameterized type in return type definitions?
On Tuesday, March 08, 2011 15:31:37 Andrej Mitrovic wrote: On 3/8/11, Steven Schveighoffer schvei...@yahoo.com wrote: See the problem? Yup. Btw, does auto ref still suffer from any bugs that I should know about? I've heard it had issues. I'm not sure that it works correctly with properties at the moment. It _does_ appear in the docs now though. - Jonathan M Davis
Re: Dynamic array void initialization
On 03/08/2011 02:34 PM, Tom wrote: import std.stdio; struct S { int i; int j; } int main(string[] args) { S[] ss = void; ss.length = 5; foreach (ref s; ss) s = S(1, 2); return 0; } Is the above code correct? (it doesn't work... it blows away or just give and access violation error). I need to create a dynamic array of some struct, but don't want defer contained elements initialization (for performance reasons). Tom; Any reason you don't just do this: S[] ss; ss.reserve(5) foreach(i; 0..i) ss ~= S(1, 2); I think that would not do default initialization on any of the elements, and it would ensure that the dynamic array is own grown once.
Re: Dynamic array void initialization
On 03/08/2011 05:42 PM, Kai Meyer wrote: On 03/08/2011 02:34 PM, Tom wrote: import std.stdio; struct S { int i; int j; } int main(string[] args) { S[] ss = void; ss.length = 5; foreach (ref s; ss) s = S(1, 2); return 0; } Is the above code correct? (it doesn't work... it blows away or just give and access violation error). I need to create a dynamic array of some struct, but don't want defer contained elements initialization (for performance reasons). Tom; Any reason you don't just do this: S[] ss; ss.reserve(5) foreach(i; 0..i) ss ~= S(1, 2); I think that would not do default initialization on any of the elements, and it would ensure that the dynamic array is own grown once. Sorry, foreach(i; 0..5) That's what I get for writing code with out trying to run it
Re: Dynamic array void initialization
El 08/03/2011 21:42, Kai Meyer escribió: On 03/08/2011 02:34 PM, Tom wrote: import std.stdio; struct S { int i; int j; } int main(string[] args) { S[] ss = void; ss.length = 5; foreach (ref s; ss) s = S(1, 2); return 0; } Is the above code correct? (it doesn't work... it blows away or just give and access violation error). I need to create a dynamic array of some struct, but don't want defer contained elements initialization (for performance reasons). Tom; Any reason you don't just do this: S[] ss; ss.reserve(5) foreach(i; 0..i) ss ~= S(1, 2); I think that would not do default initialization on any of the elements, and it would ensure that the dynamic array is own grown once. Nope, you're right. That'll work for me. Thank you, Tom;
Re: Some weird crashes
On 3/8/2011 12:57 PM, simendsjo wrote: One more thing.. Function pointers in structs.. Should they use extern(Windows) too? Yes.
Re: Help learning how to interface with c(++)
Kai Meyer Wrote: gcc -m32 -shared -fPIC Test.cpp -o libTest.so So I monkeyed around a little bit, and found out that if I change extern (C) to extern (C++), the library links correctly and the program runs. That lead me to believe that if I added the -cpp option to htod.exe, it would generate extern(C++) functions. But I got a blank Test.d file doing it that way. So, gcc created a libTest.so with a function in it, and dmd only finds the function with extern(C++) and not with extern(C). Now I'm just confused, yet pleased something worked. Because you compile .cpp file, gcc compiles it with g++ as C++ and mangles functions accordingly. You can tell gcc to compile the file as C.