Optional braces
This might sound like a crazy idea. I don't expect everyone to drop what they're doing and start to implement this, it's just an idea. In Java (C, C++ and others) braces are optional for statements like if, while, for and so on, containing only one expression. In D this is true as well, but compared with Java, D also allow try, catch and finally statements to have optional braces. What about extending this to allow optional braces everywhere, where the braces contain a single expression? I'm thinking this will be most useful for functions/methods, templates and delegates. Specially for methods acting as properties that just forwards a value. Examples: class Foo { private int a_; int a () return a_; int a (int a) return a_ = a; } template Bar (T) alias T FooBar; auto foo = delegate () return 3; auto bar = return 3; // don't if this would be possible -- /Jacob Carlborg
Re: Is std.log ready for review?
Sorry guys for disappearing. I'll put some time into this... On Wed, Aug 10, 2011 at 12:52 AM, Jonathan M Davis jmdavisp...@gmx.com wrote: Jose, are you ready for std.log to be reviewed? I believe that it's the item which has been in the review queue the longest at this point. So, if you're ready, then it should be reviewed. If you're not ready, then it sounds like the curl wrapper _is_ ready, and we'll probably move on with reviewing that. So, the question is: are you ready for std.log to be reviewed? - Jonathan M Davis
Re: CURL review request
On 08/19/2011 01:50 AM, Jonathan M Davis wrote: On Thursday, August 18, 2011 16:00 Timon Gehr wrote: On 08/19/2011 12:35 AM, Jonathan M Davis wrote: On Thursday, August 18, 2011 14:33 jdrewsen wrote: Den 17-08-2011 18:21, Timon Gehr skrev: On 08/17/2011 05:58 PM, Jonathan M Davis wrote: On Wednesday, August 17, 2011 11:30:06 Steven Schveighoffer wrote: On Wed, 17 Aug 2011 11:05:56 -0400, jdrewsenjdrew...@nospam.com wrote: Den 17-08-2011 15:51, Steven Schveighoffer skrev: On Wed, 17 Aug 2011 05:43:00 -0400, Jonas Drewsen jdrew...@nospam.com wrote: On 17/08/11 00.21, Jonathan M Davis wrote: On Tuesday, August 16, 2011 12:32 Martin Nowak wrote: On Tue, 16 Aug 2011 20:48:51 +0200, jdrewsenjdrew...@nospam.com wrote: Den 16-08-2011 18:55, Martin Nowak skrev: On Tue, 16 Aug 2011 15:13:40 +0200, dsimchadsim...@yahoo.com wrote: On 8/16/2011 7:48 AM, Jonas Drewsen wrote: Hi all, This is a review request for the curl wrapper. Please read the known issues in the top of the source file and if possible suggest a solution. We also need somebody for running the review process. Anyone? Code: https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl .d Docs: http://freeze.steamwinter.com/D/web/phobos/etc_curl.html Demolish! /Jonas From a quick look, this looks very well thought out. I'll review it more thoroughly when I have more time. A few questions/comments from a quick look at the docs: Does the async stuff use D threads, or does Curl have its own async API? In your examples for postData, you have onReceive a ubyte[] and write it out to console. Did you mean to cast this to some kind of string? For onReceive, what's the purpose of the return value? If/when this module makes it into Phobos, are we going to start including a libcurl binary with DMD distributions so that std.curl feels truly **standard** and requires zero extra configuration? I was also wondering about the async handling. In the long-term I'd like to see a bigger picture for async handling in phobos (offering some kind of futures, maybe event-loops etc.). Though this is not a requirement for the curl wrapper now. std.parallelism also has some kind of this stuff and file reading would benefit from it too. This has been discussed before and I also think this is very important. But before that I think some kind of package management should be prioritized (A DIP11 implementaion or a more traditional solution). One thing I spotted at a quick glance, sending to be filled buffers to another thread should not be done by casting to shared not immutable. I'm not entirely sure what you mean. There is no use of shared buffers in the wrapper. I do cast the buffer between mutable/immutable because only immutable or by value data can be passed using std.concurrency. Since the buffers are only used by the thread that currently has the buffer this is safe. I've previously asked for a non-cast solution (ie. some kind of move between threads semantic for std.concurrency) but was advised that this was the way to do it. martin Pardon the typo. What I meant is that AFAIK casting from immutable to mutable has undefined behavior. The intended method for sending a uint[] buffer to another thread is to cast that buffer to shared (cast(shared(uint[])) and casting away the shared on the receiving side. It is allowed to send shared data using std.concurrency. Casting away immutability and then altering data is undefined. Actually casting it away is defined. So, if you have data in one thread that you know is unique, you can cast it to immutable (or std.exception.assumeUnique to do it) and then send it to another thread. On that thread, you can then cast it to mutable and alter it. However, you're circumventing the type system when you do this. So, you have to be very careful. You're throwing away the guarantees that the compiler makes with regards to const and immutable. It _is_ guaranteed to work though. And I'm not sure that there's really any difference between casting to shared and back and casting to immutable and back. In both cases, you're circumventing the type system. The main difference would be that if you screwed up with immutable and cast away immutable on something that really was immutable rather than something that you cast to immutable just to send it to another thread, then you could a segfault when you tried to alter it, since it could be in ROM. - Jonathan M Davis Yeah I know you have to be careful when doing these kind of things. I ran into the problem of sending buffers between threads (using std.concurrency) so that they could be reused. There isn't any move ownership support in place so Andrei suggested I could do it by casting immutable. If anyone knows of a cleaner way to do this please tell. casting to shared and back. Passing shared data should be supported by std.concurrency, and casting away shared is defined as long as you know only one thread owns the data after casting. -Steve Why is this
Re: Optional braces
On 08/19/2011 08:50 AM, Jacob Carlborg wrote: This might sound like a crazy idea. I don't expect everyone to drop what they're doing and start to implement this, it's just an idea. In Java (C, C++ and others) braces are optional for statements like if, while, for and so on, containing only one expression. In D this is true as well, but compared with Java, D also allow try, catch and finally statements to have optional braces. What about extending this to allow optional braces everywhere, where the braces contain a single expression? I'm thinking this will be most useful for functions/methods, templates and delegates. Specially for methods acting as properties that just forwards a value. Examples: class Foo { private int a_; int a () return a_; int a (int a) return a_ = a; } I think this makes code harder to read for no obvious benefit. I don't think this is any better than class Foo{ private int a_; int a(){return a_;} int a(int a){return a_ = a;} } template Bar (T) alias T FooBar; This one I'd probably use. auto foo = delegate () return 3; auto bar = return 3; // don't if this would be possible {return 3;} is better than both of them imo.
Re: Why do struct literals count as lvalues?
On Thu, 18 Aug 2011 18:56:01 -0400, bearophile bearophileh...@lycos.com wrote: Jonathan M Davis: I see _zero_ reason to treat a newly constructed object as any different from one which is returned from a function. I have not followed fully this thread, so I am not sure what you are talking about, so sorry if I am misunderstanding the whole topic. I assume you want to disallow code like: struct Vect { float[4] data = 0.0; // lot of operator overloading here, all arguments are by ref } void foo(ref Vect f) {} void main() { foo(Vect([1,2,3,4])); } Such code is common. In foo() and in all the Vect operators ref is required for performance. This code is quite handy. Forcing me to define and assign a Vect to a temporary variable in main is not handy. Think about writing expressions that use Vects with operator overloading, that use ref everywhere. If you can't pass and give Vects defined inside the expressions the code becomes quite more hairy. I believe auto ref is slated to fix this problem. -Steve
Re: Optional braces
Am 19.08.2011, 14:16 Uhr, schrieb Timon Gehr timon.g...@gmx.ch: I think this makes code harder to read for no obvious benefit. I don't think this is any better than class Foo{ private int a_; int a(){return a_;} int a(int a){return a_ = a;} } +1 Optional braces should be limited to statements.
Re: Clang with SAFECode
bearophile wrote: I'd like some optional functionality like SAFECode in the D compiler too. Very little code in a D program needs to be @system, so I see little need for this.
Re: Why do struct literals count as lvalues?
On 08/19/2011 02:16 PM, Steven Schveighoffer wrote: On Thu, 18 Aug 2011 18:56:01 -0400, bearophile bearophileh...@lycos.com wrote: Jonathan M Davis: I see _zero_ reason to treat a newly constructed object as any different from one which is returned from a function. I have not followed fully this thread, so I am not sure what you are talking about, so sorry if I am misunderstanding the whole topic. I assume you want to disallow code like: struct Vect { float[4] data = 0.0; // lot of operator overloading here, all arguments are by ref } void foo(ref Vect f) {} void main() { foo(Vect([1,2,3,4])); } Such code is common. In foo() and in all the Vect operators ref is required for performance. This code is quite handy. Forcing me to define and assign a Vect to a temporary variable in main is not handy. Think about writing expressions that use Vects with operator overloading, that use ref everywhere. If you can't pass and give Vects defined inside the expressions the code becomes quite more hairy. I believe auto ref is slated to fix this problem. -Steve auto ref currently treats struct literals as lvalues too. (therefore, as ref). And passing by value would be considerably less efficient for large structs. As I understand it, the only issue with allowing literals and function results as lvalues is that generic code cannot detect if it is working with a temporary or not. I don't know if this would be useful in D though. each code segment of the form: void foo(ref S); ... foo(S(...)); is equivalent to one explicitly declaring the temporary: {auto __temp=S(...); foo(__temp);} The difference is that the first is more pleasant to write. If temporaries would become rvalues everyone would always have to write the second form manually. So imho it is just a syntax sugar issue. I'd actually argue that ref-passing should work for arbitrary function results too.
Re: Why do struct literals count as lvalues?
2011/8/19 Timon Gehr timon.g...@gmx.ch: On 08/19/2011 02:16 PM, Steven Schveighoffer wrote: On Thu, 18 Aug 2011 18:56:01 -0400, bearophile bearophileh...@lycos.com wrote: Jonathan M Davis: I see _zero_ reason to treat a newly constructed object as any different from one which is returned from a function. I have not followed fully this thread, so I am not sure what you are talking about, so sorry if I am misunderstanding the whole topic. I assume you want to disallow code like: struct Vect { float[4] data = 0.0; // lot of operator overloading here, all arguments are by ref } void foo(ref Vect f) {} void main() { foo(Vect([1,2,3,4])); } Such code is common. In foo() and in all the Vect operators ref is required for performance. This code is quite handy. Forcing me to define and assign a Vect to a temporary variable in main is not handy. Think about writing expressions that use Vects with operator overloading, that use ref everywhere. If you can't pass and give Vects defined inside the expressions the code becomes quite more hairy. I believe auto ref is slated to fix this problem. -Steve auto ref currently treats struct literals as lvalues too. (therefore, as ref). And passing by value would be considerably less efficient for large structs. As I understand it, the only issue with allowing literals and function results as lvalues is that generic code cannot detect if it is working with a temporary or not. I don't know if this would be useful in D though. each code segment of the form: void foo(ref S); ... foo(S(...)); is equivalent to one explicitly declaring the temporary: {auto __temp=S(...); foo(__temp);} The difference is that the first is more pleasant to write. If temporaries would become rvalues everyone would always have to write the second form manually. So imho it is just a syntax sugar issue. I'd actually argue that ref-passing should work for arbitrary function results too. As far as I know, Andrei's original 'auto ref' means always receive argument *by reference* either it is lvalue or rvalue, and it works with non template function. But, unfortunately, it doesn't exist in current D. Kenji Hara
Re: Why do struct literals count as lvalues?
On 08/19/2011 03:04 PM, kenji hara wrote: 2011/8/19 Timon Gehrtimon.g...@gmx.ch: On 08/19/2011 02:16 PM, Steven Schveighoffer wrote: On Thu, 18 Aug 2011 18:56:01 -0400, bearophile bearophileh...@lycos.com wrote: Jonathan M Davis: I see _zero_ reason to treat a newly constructed object as any different from one which is returned from a function. I have not followed fully this thread, so I am not sure what you are talking about, so sorry if I am misunderstanding the whole topic. I assume you want to disallow code like: struct Vect { float[4] data = 0.0; // lot of operator overloading here, all arguments are by ref } void foo(ref Vect f) {} void main() { foo(Vect([1,2,3,4])); } Such code is common. In foo() and in all the Vect operators ref is required for performance. This code is quite handy. Forcing me to define and assign a Vect to a temporary variable in main is not handy. Think about writing expressions that use Vects with operator overloading, that use ref everywhere. If you can't pass and give Vects defined inside the expressions the code becomes quite more hairy. I believe auto ref is slated to fix this problem. -Steve auto ref currently treats struct literals as lvalues too. (therefore, as ref). And passing by value would be considerably less efficient for large structs. As I understand it, the only issue with allowing literals and function results as lvalues is that generic code cannot detect if it is working with a temporary or not. I don't know if this would be useful in D though. each code segment of the form: void foo(ref S); ... foo(S(...)); is equivalent to one explicitly declaring the temporary: {auto __temp=S(...); foo(__temp);} The difference is that the first is more pleasant to write. If temporaries would become rvalues everyone would always have to write the second form manually. So imho it is just a syntax sugar issue. I'd actually argue that ref-passing should work for arbitrary function results too. As far as I know, Andrei's original 'auto ref' means always receive argument *by reference* either it is lvalue or rvalue, and it works with non template function. But, unfortunately, it doesn't exist in current D. Kenji Hara Oh, interesting. So why were they implemented with different semantics then? Also, how would they work in a non-templated function? Would they just be conservatively treated as rvalues in the function body?
newsgroup availability
Has there been some strange issue with the newsgroup lately? Frequently, I'm getting load errors (I assume this means the NG load is too large to deal with my communication). It seems to be happening daily... -Steve
Re: Why do struct literals count as lvalues?
Timon Gehr timon.g...@gmx.ch wrote: auto ref currently treats struct literals as lvalues too. (therefore, as ref). And passing by value would be considerably less efficient for large structs. As I understand it, the only issue with allowing literals and function results as lvalues is that generic code cannot detect if it is working with a temporary or not. I don't know if this would be useful in D though. each code segment of the form: void foo(ref S); ... foo(S(...)); is equivalent to one explicitly declaring the temporary: {auto __temp=S(...); foo(__temp);} The difference is that the first is more pleasant to write. If temporaries would become rvalues everyone would always have to write the second form manually. So imho it is just a syntax sugar issue. I'd actually argue that ref-passing should work for arbitrary function results too. Here I propose that we go a step further and abolish the notion of rvalue and lvalue entirely, and let the compiler insert necessary temporary variable when needed, so that we can finally write things like uint w; memcpy(w, 5.0f, w.sizeof); 13u = w; /joking
Re: newsgroup availability
On 08/19/2011 03:44 PM, Steven Schveighoffer wrote: Has there been some strange issue with the newsgroup lately? Frequently, I'm getting load errors (I assume this means the NG load is too large to deal with my communication). It seems to be happening daily... -Steve It has been the same for me.
Re: Why do struct literals count as lvalues?
On 08/19/2011 03:46 PM, kennytm wrote: Timon Gehrtimon.g...@gmx.ch wrote: auto ref currently treats struct literals as lvalues too. (therefore, as ref). And passing by value would be considerably less efficient for large structs. As I understand it, the only issue with allowing literals and function results as lvalues is that generic code cannot detect if it is working with a temporary or not. I don't know if this would be useful in D though. each code segment of the form: void foo(ref S); ... foo(S(...)); is equivalent to one explicitly declaring the temporary: {auto __temp=S(...); foo(__temp);} The difference is that the first is more pleasant to write. If temporaries would become rvalues everyone would always have to write the second form manually. So imho it is just a syntax sugar issue. I'd actually argue that ref-passing should work for arbitrary function results too. Here I propose that we go a step further and abolish the notion of rvalue and lvalue entirely, and let the compiler insert necessary temporary variable when needed, so that we can finally write things like uint w; memcpy(w,5.0f, w.sizeof); 13u = w; /joking And then of course you could do: 5=6; assert(5==6); It hasn't been working since the good ol' days of fortran =(.
Re: Why do struct literals count as lvalues?
2011/8/19 Timon Gehr timon.g...@gmx.ch: Oh, interesting. So why were they implemented with different semantics then? I don't know the background, sorry. Also, how would they work in a non-templated function? In my opinion, that might work like C++ const T, that allows receiving a rvalue argument. Would they just be conservatively treated as rvalues in the function body? Maybe it doesn't. In D, a variable is always treated as lvalue, even if it is a parameter. The follows are my opinion: D might be designed as which ref parameter receives only lvalue, and non-ref parameter receives only rvalue. Today ref storage class also means that the parameter binds corresponding argument by reference, but it is not a language design, but that is performance decision. It seems to me that ref storage class is designed for automatic move semantics. According to my think, struct literal should be rvalue. That is temporary, and we want to move it automatically. Kenji Hara
Re: Optional braces
There is one case where it might make sense. I've brought up a variation of this before, but basically; Object getMeSome() try { // Really try } catch (SpecificFailure e) { return null; } vs. Object getMeSome() { try { // Really try } catch (SpecificFailure e) { return null; } } Of course, every optional feature needs good judgement for appropriate usage, for example the ternary statement vs. if/else. 2011/8/19 Trass3r u...@known.com: Am 19.08.2011, 14:16 Uhr, schrieb Timon Gehr timon.g...@gmx.ch: I think this makes code harder to read for no obvious benefit. I don't think this is any better than class Foo{ private int a_; int a(){return a_;} int a(int a){return a_ = a;} } +1 Optional braces should be limited to statements.
Re: newsgroup availability
On Fri, 19 Aug 2011 15:52:40 +0200, Timon Gehr wrote: On 08/19/2011 03:44 PM, Steven Schveighoffer wrote: Has there been some strange issue with the newsgroup lately? Frequently, I'm getting load errors (I assume this means the NG load is too large to deal with my communication). It seems to be happening daily... -Steve It has been the same for me. Yep, I get it all the time.
Re: newsgroup availability
Timon Gehr timon.g...@gmx.ch wrote: On 08/19/2011 03:44 PM, Steven Schveighoffer wrote: Has there been some strange issue with the newsgroup lately? Frequently, I'm getting load errors (I assume this means the NG load is too large to deal with my communication). It seems to be happening daily... -Steve It has been the same for me. It's the same for everyone because it's a problem of the newsgroup server, not the client. I guess the server(s) needs more CPU running in parallel to reduce load.
Re: Why do struct literals count as lvalues?
Timon Gehr timon.g...@gmx.ch wrote: On 08/19/2011 03:46 PM, kennytm wrote: Timon Gehrtimon.g...@gmx.ch wrote: auto ref currently treats struct literals as lvalues too. (therefore, as ref). And passing by value would be considerably less efficient for large structs. As I understand it, the only issue with allowing literals and function results as lvalues is that generic code cannot detect if it is working with a temporary or not. I don't know if this would be useful in D though. each code segment of the form: void foo(ref S); ... foo(S(...)); is equivalent to one explicitly declaring the temporary: {auto __temp=S(...); foo(__temp);} The difference is that the first is more pleasant to write. If temporaries would become rvalues everyone would always have to write the second form manually. So imho it is just a syntax sugar issue. I'd actually argue that ref-passing should work for arbitrary function results too. Here I propose that we go a step further and abolish the notion of rvalue and lvalue entirely, and let the compiler insert necessary temporary variable when needed, so that we can finally write things like uint w; memcpy(w,5.0f, w.sizeof); 13u = w; /joking And then of course you could do: 5=6; assert(5==6); It hasn't been working since the good ol' days of fortran =(. Actually that assignment would just become an expensive no-op because it will be rewritten into (int __lvalue1243 = 5, __lvalue1243) = 6; So the assert would still assert.
Re: Optional braces
Trass3r u...@known.com wrote: Am 19.08.2011, 14:16 Uhr, schrieb Timon Gehr timon.g...@gmx.ch: I think this makes code harder to read for no obvious benefit. I don't think this is any better than class Foo{ private int a_; int a(){return a_;} int a(int a){return a_ = a;} } +1 Optional braces should be limited to statements. I agree. Besides, a minor problem is that 'if' statements may be mistaken as template conditions: void f1(T)(T x) if (isFoo!T) { x ++; } void f2(T)(T x) { if (isFoo!T) { x ++; } }
Re: Why do struct literals count as lvalues?
On 08/19/2011 04:33 PM, kennytm wrote: Timon Gehrtimon.g...@gmx.ch wrote: On 08/19/2011 03:46 PM, kennytm wrote: Timon Gehrtimon.g...@gmx.ch wrote: auto ref currently treats struct literals as lvalues too. (therefore, as ref). And passing by value would be considerably less efficient for large structs. As I understand it, the only issue with allowing literals and function results as lvalues is that generic code cannot detect if it is working with a temporary or not. I don't know if this would be useful in D though. each code segment of the form: void foo(ref S); ... foo(S(...)); is equivalent to one explicitly declaring the temporary: {auto __temp=S(...); foo(__temp);} The difference is that the first is more pleasant to write. If temporaries would become rvalues everyone would always have to write the second form manually. So imho it is just a syntax sugar issue. I'd actually argue that ref-passing should work for arbitrary function results too. Here I propose that we go a step further and abolish the notion of rvalue and lvalue entirely, and let the compiler insert necessary temporary variable when needed, so that we can finally write things like uint w; memcpy(w,5.0f, w.sizeof); 13u = w; /joking And then of course you could do: 5=6; assert(5==6); It hasn't been working since the good ol' days of fortran =(. Actually that assignment would just become an expensive no-op because it will be rewritten into (int __lvalue1243 = 5, __lvalue1243) = 6; So the assert would still assert. Nah, no-ops should be a compile error :o).
More name hiding
After translating some buggy C code (full of gotos and global variables) to D and going hunting for bugs for some time, I have grown a desire to write this post. Variable name hiding is a source of bugs. A typical example: int x; void foo() { int x = 5; // lot of code code here x++; } The local name 'x' hides the global variable name 'x'. Sometimes the programmer thinks she is using a global variable, when instead she is using the local one, of vice versa. Coding guidelines suggest to rename such local variable x to avoid possible future troubles, and I agree with this advice. Some ways to face this problem: 1) Do nothing. 2) Give optional explicit information about the source of all variable names used in a function, using the optional @outer() I have proposed elsewhere. 3) Statically disallow (gives an error) local variables from shadowing global ones. 4) Produce a warning when a local variable shadows a global ones, in a smart way. 5) As the leading dot to denote global variables, require the use of another leading symbol (or some other mean) to denote local variable, when there is ambiguity. -- Regarding option 1, in D global variables are uncommon if you follow modern programming practices, and if you keep functions short it's easy to see if they are shadowing an outer name. But the situation is sometimes different if you are porting legacy C code to D, or if you have bad D programmers :-) -- Option 3 is not so bad, D language already contains some examples of this: struct Foo { int j; } void main() { foreach (i; 0 .. 10) foreach (i; 0 .. 10) {} // error Foo f; int j; with (f) { j++; // error } } -- Option 4 too is not bad, especially if some care is given to avoid producing warnings where they are not needed: int x, y, z; void main() { int x; .x++; // no warning, the scope is known x++; // warning string y; y = foo; // no warning, .y y have incompatible types int z; float z; z++; // warning, int is implicitly convertible to float } -- Option 5 means requiring explicit scope information when there there is a collision: int x; void main() { int x; .x++; // no error, the scope is known main.x++; // no error, the scope is known } -- I have discussed about hiding global variables from local ones, but D allows nesting of functions, so this discussion applies to such variables too: void main() { int x; void foo() { int x; // code here x++; } } Bye, bearophile
Re: Optional braces
On 8/19/11 1:50 AM, Jacob Carlborg wrote: This might sound like a crazy idea. I don't expect everyone to drop what they're doing and start to implement this, it's just an idea. In Java (C, C++ and others) braces are optional for statements like if, while, for and so on, containing only one expression. In D this is true as well, but compared with Java, D also allow try, catch and finally statements to have optional braces. What about extending this to allow optional braces everywhere, where the braces contain a single expression? I'm thinking this will be most useful for functions/methods, templates and delegates. Specially for methods acting as properties that just forwards a value. Examples: class Foo { private int a_; int a () return a_; int a (int a) return a_ = a; } template Bar (T) alias T FooBar; auto foo = delegate () return 3; auto bar = return 3; // don't if this would be possible One thing I'd subjectively like is to require braces on both branches of if/else if at least one has braces. Andrei
Re: More name hiding
It's not just globals. It's hiding fields as well: class A { int x; this() { int x; // - hides this.x } } I've had this happen during a cut/paste session, which happens when I'm refactoring my code.
Re: newsgroup availability
On 19/08/2011 16:18, kennytm wrote: Timon Gehrtimon.g...@gmx.ch wrote: On 08/19/2011 03:44 PM, Steven Schveighoffer wrote: Has there been some strange issue with the newsgroup lately? Frequently, I'm getting load errors (I assume this means the NG load is too large to deal with my communication). It seems to be happening daily... -Steve It has been the same for me. It's the same for everyone because it's a problem of the newsgroup server, not the client. I guess the server(s) needs more CPU running in parallel to reduce load. Could it be the cause of frequent Thunderbird freezes? I can't tell because I only started using it for the newsgroup a few weeks ago.
Re: Should unreachable code be considered an error?
Why not a warning but when compiling using the -release flag throw an error? Sounds logical to me as unreachable code can be there because of debugging,etc but any released executable should not contain unreachable code. 2011/8/18 Don nos...@nospam.com Timon Gehr wrote: On 08/18/2011 02:38 PM, Bernard Helyer wrote: Faramir on the Ars forums makes an excellent point: With the c preprocessor, both theoretically and as it is used in practice, you can easily get dead code in certain compile paths that is live in others. I think template mixins can achieve the same sort of shenanigans. I think warning it is. You mean string mixins? As string mixins are so much more expressive than C macros, one should actually almost never get trivial dead code in well designed string mixins. Yes, the equivalent to the C preprocessor is version statements. Obviously anything wrapped in a version(none) block shouldn't generate an unreachable code error...
Re: Optional braces
On 08/19/2011 05:12 PM, Andrei Alexandrescu wrote: On 8/19/11 1:50 AM, Jacob Carlborg wrote: This might sound like a crazy idea. I don't expect everyone to drop what they're doing and start to implement this, it's just an idea. In Java (C, C++ and others) braces are optional for statements like if, while, for and so on, containing only one expression. In D this is true as well, but compared with Java, D also allow try, catch and finally statements to have optional braces. What about extending this to allow optional braces everywhere, where the braces contain a single expression? I'm thinking this will be most useful for functions/methods, templates and delegates. Specially for methods acting as properties that just forwards a value. Examples: class Foo { private int a_; int a () return a_; int a (int a) return a_ = a; } template Bar (T) alias T FooBar; auto foo = delegate () return 3; auto bar = return 3; // don't if this would be possible One thing I'd subjectively like is to require braces on both branches of if/else if at least one has braces. Andrei if(condition){ ...; }();else ...; if(condition) ...; else{ ... }(); :o)
Re: Why do struct literals count as lvalues?
Am 19.08.2011, 14:50 Uhr, schrieb Timon Gehr timon.g...@gmx.ch: void foo(ref S); ... foo(S(...)); is equivalent to one explicitly declaring the temporary: {auto __temp=S(...); foo(__temp);} The difference is that the first is more pleasant to write. If temporaries would become rvalues everyone would always have to write the second form manually. So imho it is just a syntax sugar issue. I'd actually argue that ref-passing should work for arbitrary function results too. +1, but const should be required.
Re: Should unreachable code be considered an error?
On Aug 18, 2011, at 10:29 AM, Nick Sabalausky wrote: Bernard Helyer b.hel...@gmail.com wrote in message news:j2ithq$12kd$1...@digitalmars.com... I asked the Ars forums ( http://arstechnica.com/civis/viewtopic.php? f=20t=1153378p=21965411 ) and I ask the same of you: should unambiguously unreachable code be an error or a warning? ( see the linked forum post for more details ). No. That would be a royal pain in the ass during debugging. I expect to be able to stick a return ; anywhere I want to test something and not have the compiler crap out because I didn't deal with the overhead of commenting out the rest. A warning might be nice, though. A warning if anything. I've never encountered a situation where code was made unreachable by accident. I also get unreachable code warnings periodically, for code that is absolutely reachable. I don't want my code to not compile simply because the compiler can't perform adequate flow analysis.
Re: Optional braces
On 2011-08-19 17:12, Andrei Alexandrescu wrote: On 8/19/11 1:50 AM, Jacob Carlborg wrote: This might sound like a crazy idea. I don't expect everyone to drop what they're doing and start to implement this, it's just an idea. In Java (C, C++ and others) braces are optional for statements like if, while, for and so on, containing only one expression. In D this is true as well, but compared with Java, D also allow try, catch and finally statements to have optional braces. What about extending this to allow optional braces everywhere, where the braces contain a single expression? I'm thinking this will be most useful for functions/methods, templates and delegates. Specially for methods acting as properties that just forwards a value. Examples: class Foo { private int a_; int a () return a_; int a (int a) return a_ = a; } template Bar (T) alias T FooBar; auto foo = delegate () return 3; auto bar = return 3; // don't if this would be possible One thing I'd subjectively like is to require braces on both branches of if/else if at least one has braces. Andrei Why is that? -- /Jacob Carlborg
Re: Optional braces
On 2011-08-19 16:33, kennytm wrote: Trass3ru...@known.com wrote: Am 19.08.2011, 14:16 Uhr, schrieb Timon Gehrtimon.g...@gmx.ch: I think this makes code harder to read for no obvious benefit. I don't think this is any better than class Foo{ private int a_; int a(){return a_;} int a(int a){return a_ = a;} } +1 Optional braces should be limited to statements. I agree. Besides, a minor problem is that 'if' statements may be mistaken as template conditions: void f1(T)(T x) if (isFoo!T) { x ++; } void f2(T)(T x) { if (isFoo!T) { x ++; } } Oh, never thought of that. -- /Jacob Carlborg
Re: newsgroup availability
On 2011-08-19 15:44, Steven Schveighoffer wrote: Has there been some strange issue with the newsgroup lately? Frequently, I'm getting load errors (I assume this means the NG load is too large to deal with my communication). It seems to be happening daily... -Steve I'm getting the same error. -- /Jacob Carlborg
Re: newsgroup availability
On 19/08/2011 14:44, Steven Schveighoffer wrote: Has there been some strange issue with the newsgroup lately? Frequently, I'm getting load errors (I assume this means the NG load is too large to deal with my communication). It seems to be happening daily... -Steve Yes, I've also had the same error in the last few days...maybe we can have a mirror (that is sync'd regularly)? ~filgood
Re: newsgroup availability
Am 19.08.2011, 17:15 Uhr, schrieb Stijn Herreman stijn.herre...@telenet.be: On 19/08/2011 16:18, kennytm wrote: Timon Gehrtimon.g...@gmx.ch wrote: On 08/19/2011 03:44 PM, Steven Schveighoffer wrote: Has there been some strange issue with the newsgroup lately? Frequently, I'm getting load errors (I assume this means the NG load is too large to deal with my communication). It seems to be happening daily... -Steve It has been the same for me. It's the same for everyone because it's a problem of the newsgroup server, not the client. I guess the server(s) needs more CPU running in parallel to reduce load. Could it be the cause of frequent Thunderbird freezes? I can't tell because I only started using it for the newsgroup a few weeks ago. You could use the web interface to the newsgroup when you see the lockup and check if that loads or displays an error message about some load factor
Re: newsgroup availability
On Fri, 19 Aug 2011 15:18:34 -0400, Marco Leise marco.le...@gmx.de wrote: Am 19.08.2011, 17:15 Uhr, schrieb Stijn Herreman stijn.herre...@telenet.be: On 19/08/2011 16:18, kennytm wrote: Timon Gehrtimon.g...@gmx.ch wrote: On 08/19/2011 03:44 PM, Steven Schveighoffer wrote: Has there been some strange issue with the newsgroup lately? Frequently, I'm getting load errors (I assume this means the NG load is too large to deal with my communication). It seems to be happening daily... -Steve It has been the same for me. It's the same for everyone because it's a problem of the newsgroup server, not the client. I guess the server(s) needs more CPU running in parallel to reduce load. Could it be the cause of frequent Thunderbird freezes? I can't tell because I only started using it for the newsgroup a few weeks ago. You could use the web interface to the newsgroup when you see the lockup and check if that loads or displays an error message about some load factor It does. BTW, this problem really makes me want to avoid the newsgroup... I get no indication from my newsreader when it's working, only when it's broken. So as a consequence, if I want to send a message or read messages, I have to keep polling to see if it works. This seems like an artificial problem, does anyone know what the cause is? -Steve
Re: CURL review request
Den 19-08-2011 00:55, Timon Gehr skrev: On 08/18/2011 11:33 PM, jdrewsen wrote: Den 17-08-2011 18:21, Timon Gehr skrev: On 08/17/2011 05:58 PM, Jonathan M Davis wrote: On Wednesday, August 17, 2011 11:30:06 Steven Schveighoffer wrote: On Wed, 17 Aug 2011 11:05:56 -0400, jdrewsenjdrew...@nospam.com wrote: Den 17-08-2011 15:51, Steven Schveighoffer skrev: On Wed, 17 Aug 2011 05:43:00 -0400, Jonas Drewsen jdrew...@nospam.com wrote: On 17/08/11 00.21, Jonathan M Davis wrote: On Tuesday, August 16, 2011 12:32 Martin Nowak wrote: On Tue, 16 Aug 2011 20:48:51 +0200, jdrewsenjdrew...@nospam.com wrote: Den 16-08-2011 18:55, Martin Nowak skrev: On Tue, 16 Aug 2011 15:13:40 +0200, dsimchadsim...@yahoo.com wrote: On 8/16/2011 7:48 AM, Jonas Drewsen wrote: Hi all, This is a review request for the curl wrapper. Please read the known issues in the top of the source file and if possible suggest a solution. We also need somebody for running the review process. Anyone? Code: https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl .d Docs: http://freeze.steamwinter.com/D/web/phobos/etc_curl.html Demolish! /Jonas From a quick look, this looks very well thought out. I'll review it more thoroughly when I have more time. A few questions/comments from a quick look at the docs: Does the async stuff use D threads, or does Curl have its own async API? In your examples for postData, you have onReceive a ubyte[] and write it out to console. Did you mean to cast this to some kind of string? For onReceive, what's the purpose of the return value? If/when this module makes it into Phobos, are we going to start including a libcurl binary with DMD distributions so that std.curl feels truly **standard** and requires zero extra configuration? I was also wondering about the async handling. In the long-term I'd like to see a bigger picture for async handling in phobos (offering some kind of futures, maybe event-loops etc.). Though this is not a requirement for the curl wrapper now. std.parallelism also has some kind of this stuff and file reading would benefit from it too. This has been discussed before and I also think this is very important. But before that I think some kind of package management should be prioritized (A DIP11 implementaion or a more traditional solution). One thing I spotted at a quick glance, sending to be filled buffers to another thread should not be done by casting to shared not immutable. I'm not entirely sure what you mean. There is no use of shared buffers in the wrapper. I do cast the buffer between mutable/immutable because only immutable or by value data can be passed using std.concurrency. Since the buffers are only used by the thread that currently has the buffer this is safe. I've previously asked for a non-cast solution (ie. some kind of move between threads semantic for std.concurrency) but was advised that this was the way to do it. martin Pardon the typo. What I meant is that AFAIK casting from immutable to mutable has undefined behavior. The intended method for sending a uint[] buffer to another thread is to cast that buffer to shared (cast(shared(uint[])) and casting away the shared on the receiving side. It is allowed to send shared data using std.concurrency. Casting away immutability and then altering data is undefined. Actually casting it away is defined. So, if you have data in one thread that you know is unique, you can cast it to immutable (or std.exception.assumeUnique to do it) and then send it to another thread. On that thread, you can then cast it to mutable and alter it. However, you're circumventing the type system when you do this. So, you have to be very careful. You're throwing away the guarantees that the compiler makes with regards to const and immutable. It _is_ guaranteed to work though. And I'm not sure that there's really any difference between casting to shared and back and casting to immutable and back. In both cases, you're circumventing the type system. The main difference would be that if you screwed up with immutable and cast away immutable on something that really was immutable rather than something that you cast to immutable just to send it to another thread, then you could a segfault when you tried to alter it, since it could be in ROM. - Jonathan M Davis Yeah I know you have to be careful when doing these kind of things. I ran into the problem of sending buffers between threads (using std.concurrency) so that they could be reused. There isn't any move ownership support in place so Andrei suggested I could do it by casting immutable. If anyone knows of a cleaner way to do this please tell. casting to shared and back. Passing shared data should be supported by std.concurrency, and casting away shared is defined as long as you know only one thread owns the data after casting. -Steve Why is this cleaner than casting to immutable and back? Once it's immutable, it can never be mutable again. Casting to immutable is a one-way
Re: CURL review request
Den 18-08-2011 20:12, Martin Nowak skrev: On Tue, 16 Aug 2011 13:48:57 +0200, Jonas Drewsen jdrew...@nospam.com wrote: Hi all, This is a review request for the curl wrapper. Please read the known issues in the top of the source file and if possible suggest a solution. We also need somebody for running the review process. Anyone? Code: https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl.d Docs: http://freeze.steamwinter.com/D/web/phobos/etc_curl.html Demolish! /Jonas Just want to make sure these two code comments don't get lost. https://github.com/jcd/phobos/commit/9177203c1e54c4be959fb0b81e9d84f3d5e861f9#etc/curl.d-P132 https://github.com/jcd/phobos/commit/9177203c1e54c4be959fb0b81e9d84f3d5e861f9#etc/curl.d-P192 martin I did see them. Thanks /Jonas
Re: CURL review request
On Friday, August 19, 2011 04:58 Timon Gehr wrote: On 08/19/2011 01:50 AM, Jonathan M Davis wrote: On Thursday, August 18, 2011 16:00 Timon Gehr wrote: On 08/19/2011 12:35 AM, Jonathan M Davis wrote: On Thursday, August 18, 2011 14:33 jdrewsen wrote: Den 17-08-2011 18:21, Timon Gehr skrev: On 08/17/2011 05:58 PM, Jonathan M Davis wrote: On Wednesday, August 17, 2011 11:30:06 Steven Schveighoffer wrote: On Wed, 17 Aug 2011 11:05:56 -0400, jdrewsenjdrew...@nospam.com wrote: Den 17-08-2011 15:51, Steven Schveighoffer skrev: On Wed, 17 Aug 2011 05:43:00 -0400, Jonas Drewsen jdrew...@nospam.com wrote: On 17/08/11 00.21, Jonathan M Davis wrote: On Tuesday, August 16, 2011 12:32 Martin Nowak wrote: On Tue, 16 Aug 2011 20:48:51 +0200, jdrewsenjdrew...@nospam.com wrote: Den 16-08-2011 18:55, Martin Nowak skrev: On Tue, 16 Aug 2011 15:13:40 +0200, dsimchadsim...@yahoo.com wrote: On 8/16/2011 7:48 AM, Jonas Drewsen wrote: Hi all, This is a review request for the curl wrapper. Please read the known issues in the top of the source file and if possible suggest a solution. We also need somebody for running the review process. Anyone? Code: https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl .d Docs: http://freeze.steamwinter.com/D/web/phobos/etc_curl.html Demolish! /Jonas From a quick look, this looks very well thought out. I'll review it more thoroughly when I have more time. A few questions/comments from a quick look at the docs: Does the async stuff use D threads, or does Curl have its own async API? In your examples for postData, you have onReceive a ubyte[] and write it out to console. Did you mean to cast this to some kind of string? For onReceive, what's the purpose of the return value? If/when this module makes it into Phobos, are we going to start including a libcurl binary with DMD distributions so that std.curl feels truly **standard** and requires zero extra configuration? I was also wondering about the async handling. In the long-term I'd like to see a bigger picture for async handling in phobos (offering some kind of futures, maybe event-loops etc.). Though this is not a requirement for the curl wrapper now. std.parallelism also has some kind of this stuff and file reading would benefit from it too. This has been discussed before and I also think this is very important. But before that I think some kind of package management should be prioritized (A DIP11 implementaion or a more traditional solution). One thing I spotted at a quick glance, sending to be filled buffers to another thread should not be done by casting to shared not immutable. I'm not entirely sure what you mean. There is no use of shared buffers in the wrapper. I do cast the buffer between mutable/immutable because only immutable or by value data can be passed using std.concurrency. Since the buffers are only used by the thread that currently has the buffer this is safe. I've previously asked for a non-cast solution (ie. some kind of move between threads semantic for std.concurrency) but was advised that this was the way to do it. martin Pardon the typo. What I meant is that AFAIK casting from immutable to mutable has undefined behavior. The intended method for sending a uint[] buffer to another thread is to cast that buffer to shared (cast(shared(uint[])) and casting away the shared on the receiving side. It is allowed to send shared data using std.concurrency. Casting away immutability and then altering data is undefined. Actually casting it away is defined. So, if you have data in one thread that you know is unique, you can cast it to immutable (or std.exception.assumeUnique to do it) and then send it to another thread. On that thread, you can then cast it to mutable and alter it. However, you're circumventing the type system when you do this. So, you have to be very careful. You're throwing away the guarantees that the compiler makes with regards to const and immutable. It _is_ guaranteed to work though. And I'm not sure that there's really any difference between casting to shared and back and casting to immutable and back. In both cases, you're circumventing the type system. The main difference would be that if you screwed up with immutable and cast away immutable on something that really was immutable rather than something that you cast to immutable just to send it to another thread, then you could a segfault when you tried to alter it, since it could be in ROM. - Jonathan M Davis Yeah I know you have to be careful when doing these kind of things. I ran into the problem of sending buffers between threads (using std.concurrency) so that they could be reused.
Re: CURL review request
On 08/19/2011 10:36 PM, Jonathan M Davis wrote: On Friday, August 19, 2011 04:58 Timon Gehr wrote: On 08/19/2011 01:50 AM, Jonathan M Davis wrote: On Thursday, August 18, 2011 16:00 Timon Gehr wrote: On 08/19/2011 12:35 AM, Jonathan M Davis wrote: On Thursday, August 18, 2011 14:33 jdrewsen wrote: Den 17-08-2011 18:21, Timon Gehr skrev: On 08/17/2011 05:58 PM, Jonathan M Davis wrote: On Wednesday, August 17, 2011 11:30:06 Steven Schveighoffer wrote: On Wed, 17 Aug 2011 11:05:56 -0400, jdrewsenjdrew...@nospam.com wrote: Den 17-08-2011 15:51, Steven Schveighoffer skrev: On Wed, 17 Aug 2011 05:43:00 -0400, Jonas Drewsen jdrew...@nospam.com wrote: On 17/08/11 00.21, Jonathan M Davis wrote: On Tuesday, August 16, 2011 12:32 Martin Nowak wrote: On Tue, 16 Aug 2011 20:48:51 +0200, jdrewsenjdrew...@nospam.com wrote: Den 16-08-2011 18:55, Martin Nowak skrev: On Tue, 16 Aug 2011 15:13:40 +0200, dsimchadsim...@yahoo.com wrote: On 8/16/2011 7:48 AM, Jonas Drewsen wrote: Hi all, This is a review request for the curl wrapper. Please read the known issues in the top of the source file and if possible suggest a solution. We also need somebody for running the review process. Anyone? Code: https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl .d Docs: http://freeze.steamwinter.com/D/web/phobos/etc_curl.html Demolish! /Jonas From a quick look, this looks very well thought out. I'll review it more thoroughly when I have more time. A few questions/comments from a quick look at the docs: Does the async stuff use D threads, or does Curl have its own async API? In your examples for postData, you have onReceive a ubyte[] and write it out to console. Did you mean to cast this to some kind of string? For onReceive, what's the purpose of the return value? If/when this module makes it into Phobos, are we going to start including a libcurl binary with DMD distributions so that std.curl feels truly **standard** and requires zero extra configuration? I was also wondering about the async handling. In the long-term I'd like to see a bigger picture for async handling in phobos (offering some kind of futures, maybe event-loops etc.). Though this is not a requirement for the curl wrapper now. std.parallelism also has some kind of this stuff and file reading would benefit from it too. This has been discussed before and I also think this is very important. But before that I think some kind of package management should be prioritized (A DIP11 implementaion or a more traditional solution). One thing I spotted at a quick glance, sending to be filled buffers to another thread should not be done by casting to shared not immutable. I'm not entirely sure what you mean. There is no use of shared buffers in the wrapper. I do cast the buffer between mutable/immutable because only immutable or by value data can be passed using std.concurrency. Since the buffers are only used by the thread that currently has the buffer this is safe. I've previously asked for a non-cast solution (ie. some kind of move between threads semantic for std.concurrency) but was advised that this was the way to do it. martin Pardon the typo. What I meant is that AFAIK casting from immutable to mutable has undefined behavior. The intended method for sending a uint[] buffer to another thread is to cast that buffer to shared (cast(shared(uint[])) and casting away the shared on the receiving side. It is allowed to send shared data using std.concurrency. Casting away immutability and then altering data is undefined. Actually casting it away is defined. So, if you have data in one thread that you know is unique, you can cast it to immutable (or std.exception.assumeUnique to do it) and then send it to another thread. On that thread, you can then cast it to mutable and alter it. However, you're circumventing the type system when you do this. So, you have to be very careful. You're throwing away the guarantees that the compiler makes with regards to const and immutable. It _is_ guaranteed to work though. And I'm not sure that there's really any difference between casting to shared and back and casting to immutable and back. In both cases, you're circumventing the type system. The main difference would be that if you screwed up with immutable and cast away immutable on something that really was immutable rather than something that you cast to immutable just to send it to another thread, then you could a segfault when you tried to alter it, since it could be in ROM. - Jonathan M Davis Yeah I know you have to be careful when doing these kind of things. I ran into the problem of sending buffers between threads (using std.concurrency) so that they could be reused. There isn't any move ownership support in place so Andrei suggested I could do it by casting immutable. If anyone knows of a cleaner way to do this please tell. casting to shared and back. Passing shared data should be supported by std.concurrency, and casting away shared is
Re: newsgroup availability
On 08/19/2011 02:51 PM, filgood wrote: Yes, I've also had the same error in the last few days...maybe we can have a mirror (that is sync'd regularly)? ~filgood It's available through Gmane: nntp://news.gmane.org/gmane.comp.lang.d.general
Re: CURL review request
On Friday, August 19, 2011 15:27 Timon Gehr wrote: On 08/19/2011 10:36 PM, Jonathan M Davis wrote: On Friday, August 19, 2011 04:58 Timon Gehr wrote: On 08/19/2011 01:50 AM, Jonathan M Davis wrote: On Thursday, August 18, 2011 16:00 Timon Gehr wrote: On 08/19/2011 12:35 AM, Jonathan M Davis wrote: On Thursday, August 18, 2011 14:33 jdrewsen wrote: Den 17-08-2011 18:21, Timon Gehr skrev: On 08/17/2011 05:58 PM, Jonathan M Davis wrote: On Wednesday, August 17, 2011 11:30:06 Steven Schveighoffer wrote: On Wed, 17 Aug 2011 11:05:56 -0400, jdrewsenjdrew...@nospam.com wrote: Den 17-08-2011 15:51, Steven Schveighoffer skrev: On Wed, 17 Aug 2011 05:43:00 -0400, Jonas Drewsen jdrew...@nospam.com wrote: On 17/08/11 00.21, Jonathan M Davis wrote: On Tuesday, August 16, 2011 12:32 Martin Nowak wrote: On Tue, 16 Aug 2011 20:48:51 +0200, jdrewsenjdrew...@nospam.com wrote: Den 16-08-2011 18:55, Martin Nowak skrev: On Tue, 16 Aug 2011 15:13:40 +0200, dsimchadsim...@yahoo.com wrote: On 8/16/2011 7:48 AM, Jonas Drewsen wrote: Hi all, This is a review request for the curl wrapper. Please read the known issues in the top of the source file and if possible suggest a solution. We also need somebody for running the review process. Anyone? Code: https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl .d Docs: http://freeze.steamwinter.com/D/web/phobos/etc_curl.html Demolish! /Jonas From a quick look, this looks very well thought out. I'll review it more thoroughly when I have more time. A few questions/comments from a quick look at the docs: Does the async stuff use D threads, or does Curl have its own async API? In your examples for postData, you have onReceive a ubyte[] and write it out to console. Did you mean to cast this to some kind of string? For onReceive, what's the purpose of the return value? If/when this module makes it into Phobos, are we going to start including a libcurl binary with DMD distributions so that std.curl feels truly **standard** and requires zero extra configuration? I was also wondering about the async handling. In the long-term I'd like to see a bigger picture for async handling in phobos (offering some kind of futures, maybe event-loops etc.). Though this is not a requirement for the curl wrapper now. std.parallelism also has some kind of this stuff and file reading would benefit from it too. This has been discussed before and I also think this is very important. But before that I think some kind of package management should be prioritized (A DIP11 implementaion or a more traditional solution). One thing I spotted at a quick glance, sending to be filled buffers to another thread should not be done by casting to shared not immutable. I'm not entirely sure what you mean. There is no use of shared buffers in the wrapper. I do cast the buffer between mutable/immutable because only immutable or by value data can be passed using std.concurrency. Since the buffers are only used by the thread that currently has the buffer this is safe. I've previously asked for a non-cast solution (ie. some kind of move between threads semantic for std.concurrency) but was advised that this was the way to do it. martin Pardon the typo. What I meant is that AFAIK casting from immutable to mutable has undefined behavior. The intended method for sending a uint[] buffer to another thread is to cast that buffer to shared (cast(shared(uint[])) and casting away the shared on the receiving side. It is allowed to send shared data using std.concurrency. Casting away immutability and then altering data is undefined. Actually casting it away is defined. So, if you have data in one thread that you know is unique, you can cast it to immutable (or std.exception.assumeUnique to do it) and then send it to another thread. On that thread, you can then cast it to mutable and alter it. However, you're circumventing the type system when you do this. So, you have to be very careful. You're throwing away the guarantees that the compiler makes with regards to const and immutable. It _is_ guaranteed to work though. And I'm not sure that there's really any difference between casting to shared and back and casting to immutable and back. In both cases, you're circumventing the type system. The main difference would be that if you screwed up with immutable and cast away immutable on something that really was immutable rather than something that you cast to immutable just to send it to another thread, then you could a segfault when you tried to alter it, since it could be in ROM. - Jonathan M Davis Yeah I know you have to be careful when doing these kind of things. I ran into
Re: Should unreachable code be considered an error?
On 18/08/2011 13:19, Bernard Helyer wrote: snip I'm talking about the unambiguous cases, the ones where a basic block has no parents (i.e. there is no way to enter that code block). So essentially you're looking to catch cases where, if you consider the function as a flow chart, there is no chain of arrows from the start of the function to the statement in question. That should be straightforward. But you're not worrying about catching cases where some arrow would never be followed. Have I got that right? snip No, only if statements followed the assert(0) (which marks the control flow block as terminated, just like return). Not sure whether it should be allowed to be used e.g. to prevent execution of code that is under construction. Stewart.
Re: More name hiding
On 8/19/2011 8:17 AM, Andrej Mitrovic wrote: It's not just globals. It's hiding fields as well: class A { int x; this() { int x; //- hides this.x } } I've had this happen during a cut/paste session, which happens when I'm refactoring my code. I actually use this on PURPOSE -- I always use the 'this' pointer when referring to members anyway. It's a great way to avoid unnecessarily renaming x to things like x1, x_1, x_, _x, x0, x_0, this_x, my_x, myx, etc... Even more common with constructor parameters and instance fields.
Allocators in Phobos
I've massively improved my RegionAllocator (formerly TempAlloc) module thanks to the excellent suggestions from Andrei and from Dimitri Olshansky (the GSoC student working on regexes). For the curious: http://cis.jhu.edu/~dsimcha/d/phobos/std_regionallocator.html https://github.com/dsimcha/TempAlloc/blob/master/regionallocator.d The main point of this massive overhaul was Andrei's suggestion that TempAlloc/RegionAllocator be converted from something fairly ad-hoc to an implementation of the more general allocator interface that he proposed. I also think that three high-level functions were missing from Andrei's proposal. All of these will be included in RegionAllocator even if we decide they're not standard allocator functions: newArray: Creates a new array. Can be syntactic sugar for (cast(T*) allocate(T.sizeof * nElements))[0..nElements] or can do something more complicated based on knowing what type T is. uninitializedArray: Same as newArray but doesn't initialize elements. array: Converts a range into an array. While I'm waiting in the review queue, I'm thinking of broadening the allocator proposal to include a few more low-hanging fruit allocators: GCAllocator: An allocator wrapper over the garbage collector. Question: Should GCAllocator.free() call core.memory.GC.free() or be a no-op? CAllocator: An allocator wrapper over C's malloc and free. FreeListAllocator: A meta-allocator that allocates blocks of some fixed, user-specified size off of some other base allocator and makes them available via the allocate() function. All allocation requests larger than the block size throw. All allocations smaller than the blolck size use whatever fraction of a block they need and waste the rest. Freeing memory via free() puts it on a free list maintained by the FreeListAllocator object. FreeListAllocator attempts to satisfy allocation requests from its free list before allocating off the base allocator. I'd probably make each FreeListAllocator instance reference counted, and when the the last copy of an instance goes out of scope, all blocks on the free list get freed. Are there any other allocators that might be useful and could reasonably be implemented as Phobos modules without major modifications to druntime or the compiler?
Re: More name hiding
On Fri, 19 Aug 2011 11:07:12 -0400 bearophile bearophileh...@lycos.com wrote: Some ways to face this problem: 1) Do nothing. 2) Give optional explicit information about the source of all variable names used in a function, using the optional @outer() I have proposed elsewhere. 3) Statically disallow (gives an error) local variables from shadowing global ones. 4) Produce a warning when a local variable shadows a global ones, in a smart way. 5) As the leading dot to denote global variables, require the use of another leading symbol (or some other mean) to denote local variable, when there is ambiguity. Well, D currently says I can't shadow variables: void foo() { int x = 10; { int x = 5; // error } } which pisses me off personally. It's such a handy feature. And there is exactly one way to solve your problem which comes in two parts: 1. Don't violate the rule: one or two screens of text per function. 2. Keep the low number of variables in a function, people say it should be close to seven. /me wants to be able to shadow his variables everywhere
Re: More name hiding
nsf: Well, D currently says I can't shadow variables: Right, that's a third way to shadow variables that D forbids, thank you. But in my post I've shown other kinds of shadowing that currently D accepts. Shadowing global variables has caused some problems in my C code. One good commercial C lint lists all such cases with a warning. which pisses me off personally. It's such a handy feature. It's a handy anti-feature, good source of bugs. Style guides suggest to rename one of them. If I see production C/C++ code that does that, I rename one of the two variables. In Haskell in your situation you are allowed to use x and x'. And there is exactly one way to solve your problem which comes in two parts: Surely there are some alternative ways to solve this problem, SPARK and Java doesn't use your solution. 1. Don't violate the rule: one or two screens of text per function. 2. Keep the low number of variables in a function, people say it should be close to seven. I like to add a third rule, for D code: 3. Use pure functions everywhere possible. This avoids the shadowing problem. But: 1) Old C code translated to D often doesn't follow your rules, unfortunately. 2) I have had colleagues that don't always follow your rules. 3) Even good codebases sometimes have longer functions. You find them even in the C sources of Python. 4) Even if you always follow your two rules, you are able to shadow a global (or outer) variable still, and 20 lines later sometimes you think that you are using the global variable, while you are modifying the local one. I have seen this happen even in code written by expert programmers, and it causes problems. /me wants to be able to shadow his variables everywhere Good luck :-) Bye and thank you for your comments, bearophile
Re: Native Client in Chrome Beta
Marco Leise marco.le...@gmx.de wrote in message news:op.v0f018nh9y6...@dslb-088-070-152-209.pools.arcor-ip.net... By not adopting a technology capable of competing with native apps on iOS, Android, Windows, and Mac, web vendors are preventing important classes of applications such as high-end games and simulations from moving to the open web. That actually brings up an interestng point I hadn't really thought of before: I've always liked the idea of using native code instead of JS, because it just makes so much more sense on a technical level. But, if something better than JS, like NaCl, is adopted on the web, something that can compete with real apps in efficiency, then that will only further encourage people to hop onto Google's bullshit web-as-an-OS agenda. Even if NaCl is universally adopted and completely eliminates the efficiency issues, the web will still be horrid as a so-called applicatins platform for other reasons, like UI (a big one), reliability, centralization, user-ownership, privacy... And those issues aren't realistically fixable within the confines of a web browser. So I think it's best if such a thing as NaCl *doesn't* get adopted, since it would only further encourage the biggest plague of the 21st century.
Removing entries from AAs
Hi, I've create a little example of my problem: module example; class ExampleClass { public { int mi; this(int i) { mi = i; } } } int main(string[] args) { ExampleClass[hash_t] exp; ExampleClass cex = new ExampleClass(1); exp[cex.toHash()] = cex; cex = new ExampleClass(2); exp[cex.toHash()] = cex; cex = new ExampleClass(3); exp[cex.toHash()] = cex; foreach (ExampleClass c; exp) { if (c.mi == 2) {exp.remove(c.toHash()); } } return 0; } When I run this small example-app, I get an Access Violation. When I insert a break into my foreach-loop like: foreach (ExampleClass c; exp) { if (c.mi == 2) {exp.remove(c.toHash()); break; } } it works, but this means, I leave the foreach-loop. What I'm doing wrong by using the foreach-block? Thanks for any help!
Re: Removing entries from AAs
On 08/19/2011 02:01 PM, useo6 wrote: Hi, I've create a little example of my problem: module example; class ExampleClass { public { int mi; this(int i) { mi = i; } } } int main(string[] args) { ExampleClass[hash_t] exp; ExampleClass cex = new ExampleClass(1); exp[cex.toHash()] = cex; cex = new ExampleClass(2); exp[cex.toHash()] = cex; cex = new ExampleClass(3); exp[cex.toHash()] = cex; foreach (ExampleClass c; exp) { if (c.mi == 2) {exp.remove(c.toHash()); } } return 0; } When I run this small example-app, I get an Access Violation. When I insert a break into my foreach-loop like: foreach (ExampleClass c; exp) { if (c.mi == 2) {exp.remove(c.toHash()); break; } } it works, but this means, I leave the foreach-loop. What I'm doing wrong by using the foreach-block? Thanks for any help! The problem is that you change the AA while iterating over it. You could eg iterate over it and save all keys you want to remove into an array and then iterate over the array to remove the keys from the AA. This works: module example; class ExampleClass { public { int mi; this(int i) { mi = i; } } } int main(string[] args) { ExampleClass[hash_t] exp; ExampleClass cex = new ExampleClass(1); exp[cex.toHash()] = cex; cex = new ExampleClass(2); exp[cex.toHash()] = cex; cex = new ExampleClass(3); exp[cex.toHash()] = cex; hash_t[] toRemove; foreach (c; exp) { if (c.mi == 2) { toRemove~=c.toHash(); } } foreach (h; toRemove) { exp.remove(h); } return 0; }
Re: Insert array into an AA
On Thu, 18 Aug 2011 06:47:32 -0400, nrgyzer nrgy...@gmail.com wrote: == Auszug aus Robert Clipsham (rob...@octarineparrot.com)'s Artikel On 16/08/2011 20:17, nrgyzer wrote: Hi everyone, I've the following: private static ubyte[][2][hash_t] classInstances; this() { classInstances[toHash()] = new ubyte[2]; // does not work } I want insert every class instance into the hashmap. Every class instance should be contained in the map after the constructor was called. When I compile my code, I get Error: cannot implicitly convert expression (new ubyte[](2u)) of type ubyte[] to ubyte[][] which is logical. But is there any way to insert every instance into the array and define the array/map for this entry? Thanks in advance! Is there any particular reason you're using ubyte[][2][hash_t] there? To keep a reference to each instance simply use: class MyClass { static MyClass[] classInstances; this() { classInstances ~= this; } } If you in fact want to have a hashmap indexed by the instances with values of type ubyte[][2], you can do this: class MyClass { static ubyte[][2][MyClass] classInstances; this() { classInstances[this] = new ubyte[][2]; } } The problem in your original code is that you were using = new ubyte[2] rather than = new ubyte[][2]. Hope this helps. Ok, that works - thx. @Steve: I'll delete the entries from the map, but what's about overriding the toHash()-function and return a simply int value? If two instances return the same hash value (as is easily possible, but maybe not for your context), then a collision occurs. Then opCmp is used to determine if they are actually identical. If you use hash_t as your key, then only one object is stored in the map, the other is simply overwritten. I also need this map-structure for further steps in my application. I's possible to change it to ubyte[][hash_t] classInstancesOne; // or ubyte[][MyClass] ubyte[][hash_t] classInstancesTwo; // or ubyte[][MyClass] but I thought one map for the same sense is better. ubyte[][Object] should work for all class types. Btw: I've two classes where one inherits: class MyClassOne { protected { static __gshared { uint counter; uint[MyClassOne] fixedData; } uint otherData; this(uint d) { otherData = d; } } this() { fixedData[this] = ++counter; } @property ref { uint myPropOne() { return fixedData[this]; } uint myPropTwo() { return otherData; } } } class MyClassTwo : MyClassOne { shared(MyClassOne) supInstance; this(uint d, MyClassOne mco) { super(d); supInstance = mco; } override ref alias supInstance.myPropOne myPropOne; } When I create an instance of MyClassOne and call myPropOne on it, I get 1. When I'm using this instance to create an instance of MyClassTwo and call myPropOne, I get 0. Is there anything I'm doing wrong? That crazy override ref alias line, I have no idea what you're doing there. For sure, override ref is not needed. I'm surprised all of this compiles. What I'm trying to do is: One super-class which contains some fixed data (not inheritable) and some data which are different for each class. Note that protected does not prevent MyClassTwo from changing it. Also note that even though you've only created one instance of MyClassOne, every MyClassTwo instance is a MyClassOne (and calls MyClassOne's constructor). I think you have applied the wrong techniques to solving your design. Without knowing further your design/context, I can't really help. -Steve
Re: Removing entries from AAs
== Auszug aus Timon Gehr (timon.g...@gmx.ch)'s Artikel On 08/19/2011 02:01 PM, useo6 wrote: Hi, I've create a little example of my problem: module example; class ExampleClass { public { int mi; this(int i) { mi = i; } } } int main(string[] args) { ExampleClass[hash_t] exp; ExampleClass cex = new ExampleClass(1); exp[cex.toHash()] = cex; cex = new ExampleClass(2); exp[cex.toHash()] = cex; cex = new ExampleClass(3); exp[cex.toHash()] = cex; foreach (ExampleClass c; exp) { if (c.mi == 2) {exp.remove(c.toHash()); } } return 0; } When I run this small example-app, I get an Access Violation. When I insert a break into my foreach-loop like: foreach (ExampleClass c; exp) { if (c.mi == 2) {exp.remove(c.toHash()); break; } } it works, but this means, I leave the foreach-loop. What I'm doing wrong by using the foreach-block? Thanks for any help! The problem is that you change the AA while iterating over it. You could eg iterate over it and save all keys you want to remove into an array and then iterate over the array to remove the keys from the AA. This works: module example; class ExampleClass { public { int mi; this(int i) { mi = i; } } } int main(string[] args) { ExampleClass[hash_t] exp; ExampleClass cex = new ExampleClass(1); exp[cex.toHash()] = cex; cex = new ExampleClass(2); exp[cex.toHash()] = cex; cex = new ExampleClass(3); exp[cex.toHash()] = cex; hash_t[] toRemove; foreach (c; exp) { if (c.mi == 2) { toRemove~=c.toHash(); } } foreach (h; toRemove) { exp.remove(h); } return 0; } I already thought about that situation, but some explained the removing/clearing of an array by iterate over each element and remove it from the AA. I just solved the problem by using the HashSet-class from the dcollection's.
Re: Empy program running time
On Fri, 19 Aug 2011 01:29:05 -0400, Marco Leise marco.le...@gmx.de wrote: Am 29.07.2011, 17:23 Uhr, schrieb Steven Schveighoffer schvei...@yahoo.com: On Fri, 29 Jul 2011 10:50:52 -0400, bearophile bearophileh...@lycos.com wrote: Steven Schveighoffer: For example, D needs to call all the module ctors and do the import cycle detection algorithm. Even for an empty program? Yes. I bet even an empty program has on the order of 50 module ctor/dtors to run. All the runtime can contain module ctor/dtors, and those modules are compiled in no matter what. Plus dmd adds hidden modules with ctor/dtors. There are other initializations, such as the GC, setting up the main thread, etc. 0.11 seconds is not unreasonable. It means about 170_000_000 CPU clock ticks, to me it seems a lot. I guess if you want to have an empty program benchmark? It doesn't seem to mean much to me... If it was on the order of seconds, I'd agree with you. .11 seconds is barely noticeable. You think in the wrong category. Imagine where this would matter, where you would invoke a program multiple times. From the top of my head there is batch execution. If your program is a converter of some sort that takes one input file and one output file at a time and someone writes a script to convert all files in a directory structure. Every 545 files you get an additional minute of initialization on that test machine! If the actual conversion algorithms is fast and the files are small (i.e. converting character encodings in text files) this is well noticeable. A more abstract idea is the boot process of an old-school Linux installation. Every start script (mail server, keyboard layout, swap, logging, ...) invokes the shell several times. If the shell was written in D it would slow down the boot process more than necessary. But here efforts were made to reduce the amount of processes spawned during the boot process so this can not be a valid argument. The file utility opens files and prints their mime-type looking at magic bytes and other identifiers. This is another good example of a program that may be run on a large number of files, but doesn't run for long. It could be used by a file system browser to display the file-type of every file in a directory. I agree for simple frequently used utilities, the initialization time can be bad. But I have actually written scripting utility programs (ironically, to help boot a custom linux OS that I built), and I didn't notice terrible slowdown. Another question is, would someone who is using D be more likely to write their script in D, and simply use D libraries, or write a file utility in D, and use a shell script? It all depends on the situation, and to me, .11 seconds isn't that terrible. If it can be improved, then I think we should do it, but IMO it's not a critical piece right now. -Steve
core.stdc.stdio.stderr != std.stdio.stderr ?
Is this all correct? static import core.stdc.stdio; static import std.stdio; void main() { std.stdio.fprintf(core.stdc.stdio.stderr, Error\n); // OK std.stdio.fprintf(std.stdio.stderr, Error\n); // line 5, error } The latest DMD gives: test.d(5): Error: function core.stdc.stdio.fprintf (shared(_iobuf)* stream, in const(char*) format,...) is not callable using argument types (File,string) test.d(5): Error: cannot implicitly convert expression (stderr) of type File to shared(_iobuf)* Bye, bearophile
Re: core.stdc.stdio.stderr != std.stdio.stderr ?
On Fri, 19 Aug 2011 10:12:11 -0400, bearophile bearophileh...@lycos.com wrote: Is this all correct? static import core.stdc.stdio; static import std.stdio; void main() { std.stdio.fprintf(core.stdc.stdio.stderr, Error\n); // OK std.stdio.fprintf(std.stdio.stderr, Error\n); // line 5, error } The latest DMD gives: test.d(5): Error: function core.stdc.stdio.fprintf (shared(_iobuf)* stream, in const(char*) format,...) is not callable using argument types (File,string) test.d(5): Error: cannot implicitly convert expression (stderr) of type File to shared(_iobuf)* Yes, std.stdio.stderr is a D File struct, whereas core.stdc.stdio.stderr is a C FILE * opaque type. -Steve
Re: assertion failure in std.range.iota
http://d.puremagic.com/issues/show_bug.cgi?id=6531
Re: core.stdc.stdio.stderr != std.stdio.stderr ?
On 8/19/11 4:12 PM, bearophile wrote: static import core.stdc.stdio; static import std.stdio; void main() { std.stdio.fprintf(core.stdc.stdio.stderr, Error\n); // OK std.stdio.fprintf(std.stdio.stderr, Error\n); // line 5, error } std.stdio.stderr is a wrapper around core.stdc.stdio.stderr (a D File), you can use std.stdio.stderr.getFP() to get the C FILE pointer from it. David
help understanding import libraries
I'm really getting confused as to how import libraries actually work. Someone once told me that in order to use an import library one has to write d files declaring the functions so that the dmd compiler knows what's in the lib files. I've never thought any further untill I compiled the gtkd project to a lib file. the compiler flags I needed to add was -I for every src directory and -L for the lib file. The problem with that was that those files in the src dir don't declare the functions but also define them. They are the real source code files so I didn't understand why the -L flag was necessary. I never experimented further though :) Today I've looked in the lib files and saw that phobos.lib was there. just for fun I decided to compile a simple hello world file and compile it with the standard compiler options. Then I compiled without linking and did the linking manually. The resulting executable was 146 kb while the executable using the standard compiler options was almost 2 megabytes. Is the compiler really including all the garbage I use from phobos from the source files instead of linking to the phobos.lib file? Can I avoid this? does the -L flag pointing to my gtkd.lib file actually do something? Secondly I've also used implib to convert a dll file to a .lib file. The resulting lib file was WAY smaller then the dll file so I concluded that the lib file only contains information like this: in dll XXX function YYY at export adress Y function ZZZ at export adress Z ... But where does the lib file searches for the dll file? how can we control that? Is my hunch right? Maarten
Re: Insert array into an AA
== Auszug aus Steven Schveighoffer (schvei...@yahoo.com)'s Artikel On Thu, 18 Aug 2011 06:47:32 -0400, nrgyzer nrgy...@gmail.com wrote: == Auszug aus Robert Clipsham (rob...@octarineparrot.com)'s Artikel On 16/08/2011 20:17, nrgyzer wrote: Hi everyone, I've the following: private static ubyte[][2][hash_t] classInstances; this() { classInstances[toHash()] = new ubyte[2]; // does not work } I want insert every class instance into the hashmap. Every class instance should be contained in the map after the constructor was called. When I compile my code, I get Error: cannot implicitly convert expression (new ubyte[](2u)) of type ubyte[] to ubyte[] [] which is logical. But is there any way to insert every instance into the array and define the array/map for this entry? Thanks in advance! Is there any particular reason you're using ubyte[][2][hash_t] there? To keep a reference to each instance simply use: class MyClass { static MyClass[] classInstances; this() { classInstances ~= this; } } If you in fact want to have a hashmap indexed by the instances with values of type ubyte[][2], you can do this: class MyClass { static ubyte[][2][MyClass] classInstances; this() { classInstances[this] = new ubyte[][2]; } } The problem in your original code is that you were using = new ubyte[2] rather than = new ubyte[][2]. Hope this helps. Ok, that works - thx. @Steve: I'll delete the entries from the map, but what's about overriding the toHash()-function and return a simply int value? If two instances return the same hash value (as is easily possible, but maybe not for your context), then a collision occurs. Then opCmp is used to determine if they are actually identical. If you use hash_t as your key, then only one object is stored in the map, the other is simply overwritten. I also need this map-structure for further steps in my application. I's possible to change it to ubyte[][hash_t] classInstancesOne; // or ubyte[][MyClass] ubyte[][hash_t] classInstancesTwo; // or ubyte[][MyClass] but I thought one map for the same sense is better. ubyte[][Object] should work for all class types. Btw: I've two classes where one inherits: class MyClassOne { protected { static __gshared { uint counter; uint[MyClassOne] fixedData; } uint otherData; this(uint d) { otherData = d; } } this() { fixedData[this] = ++counter; } @property ref { uint myPropOne() { return fixedData[this]; } uint myPropTwo() { return otherData; } } } class MyClassTwo : MyClassOne { shared(MyClassOne) supInstance; this(uint d, MyClassOne mco) { super(d); supInstance = mco; } override ref alias supInstance.myPropOne myPropOne; } When I create an instance of MyClassOne and call myPropOne on it, I get 1. When I'm using this instance to create an instance of MyClassTwo and call myPropOne, I get 0. Is there anything I'm doing wrong? That crazy override ref alias line, I have no idea what you're doing there. For sure, override ref is not needed. I'm surprised all of this compiles. What I'm trying to do is: One super-class which contains some fixed data (not inheritable) and some data which are different for each class. Note that protected does not prevent MyClassTwo from changing it. Also note that even though you've only created one instance of MyClassOne, every MyClassTwo instance is a MyClassOne (and calls MyClassOne's constructor). I think you have applied the wrong techniques to solving your design. Without knowing further your design/context, I can't really help. -Steve I'm working on a game where the player can build different buildings. There are some general building-structures which defines the costs to build it and some other things, but the name of each building can be modified by the player. So, each building can have it's own name, but the costs to build are always the same for each building. To prevent the redefinition of all the property-methods, I want redirect the properties of a simple building-property to it's building structure. For example: class BuildingShell { private float[BuildingShell] pCostsToBuild; protected { string pName; this(string name) { pName = name; } } this(string name, float costs) { pName = name; pCostsToBuild[this] = costs; } @property { ref float costsToBuild() { return pCostsToBuild[this]; } string name() { return pName; } } } class Building : BuildingShell { shared(BuildingShell) pShell; this(BuldingShell bs, string name) { super(name); pShell = cast(shared) bs; } override @property
Re: help understanding import libraries
maarten van damme Wrote: the compiler flags I needed to add was -I for every src directory and -L for the lib file. The problem with that was that those files in the src dir don't declare the functions but also define them. They are the real source code files so I didn't understand why the -L flag was necessary. I never experimented further though :) The process of creating an executable goes from generating machine code from source to linking the machine code for execution, as you know. The -I flag is the compiler import/include directory while -L is flags passed to the linker. That so while you may have complete source code in the import directory the compiler is only looking at the declaration and does not compile the files, it then informs the linker where the symbols can be found from the information you provide after the -L flag. If you wanted (and didn't run out of command line characters) you could list all .d files in every library you are using and have dmd compile everything for you. Then the -L would not be required.
Re: help understanding import libraries
You don't need the damn -L flag, just pass the .lib file directly and DMD will pass it to the linker.
Re: help understanding import libraries
On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote: If you wanted (and didn't run out of command line characters) you could list all .d files in every library you are using and have dmd compile everything for you. Then the -L would not be required. Just a reminder, you have dmd @cmdfile for cases where you want to put a long command line's options into a file for easier management. Graham
Re: help understanding import libraries
On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote: If you wanted (and didn't run out of command line characters) you could list all .d files in every library you are using and have dmd compile everything for you. Then the -L would not be required. Just a reminder, you have dmd @cmdfile for cases where you want to put a long command line's options into a file for easier management. Graham
Re: help understanding import libraries
On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote: If you wanted (and didn't run out of command line characters) you could list all .d files in every library you are using and have dmd compile everything for you. Then the -L would not be required. Just a reminder, you have dmd @cmdfile for cases where you want to put a long command line's options into a file for easier management. Graham
Re: help understanding import libraries
On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote: If you wanted (and didn't run out of command line characters) you could list all .d files in every library you are using and have dmd compile everything for you. Then the -L would not be required. Just a reminder, you have dmd @cmdfile for cases where you want to put a long command line's options into a file for easier management. Graham
Re: help understanding import libraries
On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote: If you wanted (and didn't run out of command line characters) you could list all .d files in every library you are using and have dmd compile everything for you. Then the -L would not be required. Just a reminder, you have dmd @cmdfile for cases where you want to put a long command line's options into a file for easier management. Graham
Re: help understanding import libraries
On Fri, Aug 19, 2011 at 9:38 AM, Jesse Phillips jessekphillip...@gmail.comwrote: maarten van damme Wrote: the compiler flags I needed to add was -I for every src directory and -L for the lib file. The problem with that was that those files in the src dir don't declare the functions but also define them. They are the real source code files so I didn't understand why the -L flag was necessary. I never experimented further though :) The process of creating an executable goes from generating machine code from source to linking the machine code for execution, as you know. The -I flag is the compiler import/include directory while -L is flags passed to the linker. That so while you may have complete source code in the import directory the compiler is only looking at the declaration and does not compile the files, it then informs the linker where the symbols can be found from the information you provide after the -L flag. Technically it's not saying anything about where the symbols can be found, it's just putting them into the object file as external symbols that the linker needs to resolve, but yes. The compiler basically ignores lib files and passes them to the linker.
Re: help understanding import libraries
and how come the executable I manually linked was 17 times smaller then the other executable? and how does the dll searching works?
Re: duplicates (Re: help understanding import libraries)
I saw the same with another user using the web interface, seems like it's buggy 2011/8/19 Graham Fawcett fawc...@uwindsor.ca On Fri, 19 Aug 2011 17:35:00 +, Graham Fawcett wrote: On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote: If you wanted (and didn't run out of command line characters) you could list all .d files in every library you are using and have dmd compile everything for you. Then the -L would not be required. Just a reminder, you have dmd @cmdfile for cases where you want to put a long command line's options into a file for easier management. Graham Sorry for the duplicate posts, I have no idea why that happened. Graham
Re: help understanding import libraries
Graham Fawcett Wrote: On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote: If you wanted (and didn't run out of command line characters) you could list all .d files in every library you are using and have dmd compile everything for you. Then the -L would not be required. Just a reminder, you have dmd @cmdfile for cases where you want to put a long command line's options into a file for easier management. Graham Yes but that just adds an extra lesson on top of learning what -I and -L do, why they are different and why both are used together.
gdc ldc problems
so I have installed ldc,gdc and dmd on my linux box(debian testing) the problem now is that when I try to compiler something using gdc or ldc that imports from core it gives an error (core.* can not be found). the versions of phobos between the 3 are completely out of sync, did I install it the wrong way (simple apt-getting?)
Re: gdc ldc problems
On Sat, 20 Aug 2011 03:37:52 +0200, maarten van damme wrote: so I have installed ldc,gdc and dmd on my linux box(debian testing) the problem now is that when I try to compiler something using gdc or ldc that imports from core it gives an error (core.* can not be found). the versions of phobos between the 3 are completely out of sync, did I install it the wrong way (simple apt-getting?) The compilers found in the repository support D1, core.* is part of D2.
Re: gdc ldc problems
ooh, thank you :) 2011/8/20 Jesse Phillips jessekphillip...@gmail.com On Sat, 20 Aug 2011 03:37:52 +0200, maarten van damme wrote: so I have installed ldc,gdc and dmd on my linux box(debian testing) the problem now is that when I try to compiler something using gdc or ldc that imports from core it gives an error (core.* can not be found). the versions of phobos between the 3 are completely out of sync, did I install it the wrong way (simple apt-getting?) The compilers found in the repository support D1, core.* is part of D2.
[Issue 6365] AutoTupleDeclaration
http://d.puremagic.com/issues/show_bug.cgi?id=6365 --- Comment #30 from bearophile_h...@eml.cc 2011-08-18 23:35:27 PDT --- (In reply to comment #26) We should step back and figure out what we want to do with tuples in the much more general case. I think this point is mostly solved, because while tuples are useful for many different purposes and situations, such purposes are well known. Languages like Python, Haskell and Scala show and contain most significant usages for tuples. I am nervous we are building a special case for tuples. I think any expansion of tuple support should be part of a more comprehensive design for tuples. I agree. This is why I have created issue 6383 . It deals with more general idea of unpacking. Issue 6383 doesn't cover all possible situations, but they are enough to start. If we grow tuple support by adding piecemeal special cases for this and that, without thinking about them more globally, we are liable to build ourselves into a box we can't get out of. I have done my best. But the discussion has stopped. So my suggestion is to put this in the next DMD release as *experimental* feature, and let people: 1) Try it and find what's good and bad of it through practical experience, and even trial and error; 2) Use this concrete implementation as a trampoline to think in abstract about that good and bad of this current design. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 6365] AutoTupleDeclaration
http://d.puremagic.com/issues/show_bug.cgi?id=6365 --- Comment #31 from bearophile_h...@eml.cc 2011-08-18 23:47:46 PDT --- Regarding this change, removing tuple unpacking for arrays is not a good idea, in my opinion. You are making tuples less handy, with zero gain in doing so. https://github.com/9rnsr/dmd/commit/6fa008162fe29a1459c35dccb9e08009598206d0 Conceptually it's the same thing as doing: void main() { int[] a = [1, 2]; int[2] b = a; } The compiler will need to verify at runtime that a has length 2. Given this precedent in the language, there is no point in forbidding a similar operation on tuples: void main() { int[] a1 = [1, 2]; auto (x, y) = a1; int[2] a2 = [1, 2]; auto (z, w) = a2; // no need to verify a2 length at runtime here } I think this is what Walter was talking about in comment 26: I think any expansion of tuple support should be part of a more comprehensive design for tuples. Python tuples support this operation, that feels natural enough to Python programmers: a1 = [1, 2] (x, y) = a1 x 1 y 2 So in my opinion Andrei is wrong here. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 6510] [CTFE] internal error: illegal stack value when compiled with -inline
http://d.puremagic.com/issues/show_bug.cgi?id=6510 --- Comment #9 from Don clugd...@yahoo.com.au 2011-08-19 05:53:36 PDT --- Further reduced, showing that templates are not required. Seems to require an inlined member function call to a member of a nested struct, called from a nested function. No alias trick works in this case. struct Stack6510 { struct Proxy { void shrink() {} } Proxy stack; void pop() { stack.shrink(); } } int bug6510() { static int used() { Stack6510 junk; junk.pop(); return 3; } return used(); } void main() { static assert(bug6510()==3); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5710] cannot use delegates as parameters to non-global template
http://d.puremagic.com/issues/show_bug.cgi?id=5710 --- Comment #10 from David Simcha dsim...@yahoo.com 2011-08-19 07:03:02 PDT --- (In reply to comment #9) My idea: doStuff receives a context pointer that points 'an array of context pointers'. Backend receives code like follows... uint doStuff(uint a, uint b, void** this) // not void* this { // (*this + 0) points the object Foo // (*this + 1) points the stack frame of main() //return fun(a, b); return fun(a, b, (*this + 1)); } Caller of doStuff have to create array of context pointers. void main(){ ... //foo.doStuff!add(1, 2); void*[2] thisarray = [(stack frame of main), foo]; doStuff(a, b, thisarray.ptr); } Sounds great if you can pull it off. I was thinking the same thing, but I'm not familiar enough with the DMD codebase to know how easy/hard it would be to implement. This would remove some really silly/annoying limitations from std.parallelism. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 6531] New: assertion failure in std.range.iota
http://d.puremagic.com/issues/show_bug.cgi?id=6531 Summary: assertion failure in std.range.iota Product: D Version: D2 Platform: Other OS/Version: Windows Status: NEW Severity: major Priority: P2 Component: Phobos AssignedTo: nob...@puremagic.com ReportedBy: andrej.mitrov...@gmail.com --- Comment #0 from Andrej Mitrovic andrej.mitrov...@gmail.com 2011-08-19 07:49:29 PDT --- import std.range; import std.stdio; void main() { auto r1 = iota(0.0, 4.0, 0.03); // ok auto r2 = iota(0.0, 3.0, 0.03); // core.exception.AssertError@std.range(4001): Assertion failure } I want a range in steps of 0.03, beginning at 0.0 and ending at the closest point to 3.0. Line 4001 is: assert(start + count * step = end); There's no documentation, and no custom assert message, so I don't know what was the intention of the author. It doesn't help that this fails in debug mode but works fine in release mode. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 1001] print stack trace (in debug mode) when program die
http://d.puremagic.com/issues/show_bug.cgi?id=1001 --- Comment #56 from Sean Kelly s...@invisibleduck.org 2011-08-19 14:12:24 PDT --- If you want exceptions for these events on Posix, create a signal handler and throw one. On some OSes it will work and on others it won't. Assuming you're targeting a platform where it works though, doing so might be a net win. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 6533] New: Compiler should catch duplicate overrides
http://d.puremagic.com/issues/show_bug.cgi?id=6533 Summary: Compiler should catch duplicate overrides Product: D Version: D2 Platform: Other OS/Version: Windows Status: NEW Severity: enhancement Priority: P2 Component: DMD AssignedTo: nob...@puremagic.com ReportedBy: andrej.mitrov...@gmail.com --- Comment #0 from Andrej Mitrovic andrej.mitrov...@gmail.com 2011-08-19 19:26:40 PDT --- class Foo { abstract void foo(); } class Bar : Foo { override void foo() { // code } override void foo() { } } void main() {} This ends up being a linker error such as: Offset 00542H Record Type 00C3 Error 1: Previous Definition Different : _D12overridetest3Bar3fooMFZv The problem is in a large class you might end up mistakenly defining an overriden function twice, and you won't get a compile-time error, you will get a linker error instead. Making this a compile-time error would be an improvement. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---