Re: Source code output
On Wednesday, 17 July 2013 at 05:29:26 UTC, H. S. Teoh wrote: On Wed, Jul 17, 2013 at 05:27:34AM +0200, JS wrote: With heavy ctfe code generation usage is it possible to have the d compiler output the source code after all mixin templates have been "used"? This way it is easier to visually check for errors in the generated code. I imagine one could use pragma in a "special way" to do this but I was hoping for something more direct. Yeah I've been looking for this too. Once you have templates and mixins nested deeply enough, it can be near impossible to figure out just exactly *what* is being compiled at the end of it all. Though I suppose the common approach is to generate a string representing the code, and then using mixin(str) to compile it; this lets you use pragma(msg) to output str and thereby see what exactly is being compiled. But this may not be possible in some cases. T That is what I use but at some point it will become worthless. I was thinking it may be possible to optionally pragma the code depending on a symbol like __codegen, which would then trigger all the appropriate pragma's, the problem is, the output will be a mess because of the nesting(code duplication). Only the most outside mixin's pragma needs to be triggered, the one directly used in the code(not inside another template).
Re: Source code output
On Wed, Jul 17, 2013 at 05:27:34AM +0200, JS wrote: > With heavy ctfe code generation usage is it possible to have the d > compiler output the source code after all mixin templates have been > "used"? This way it is easier to visually check for errors in the > generated code. > > I imagine one could use pragma in a "special way" to do this but I > was hoping for something more direct. Yeah I've been looking for this too. Once you have templates and mixins nested deeply enough, it can be near impossible to figure out just exactly *what* is being compiled at the end of it all. Though I suppose the common approach is to generate a string representing the code, and then using mixin(str) to compile it; this lets you use pragma(msg) to output str and thereby see what exactly is being compiled. But this may not be possible in some cases. T -- Be in denial for long enough, and one day you'll deny yourself of things you wish you hadn't.
Re: Template explosion
On Wednesday, 17 July 2013 at 03:34:17 UTC, Timothee Cour wrote: On Tue, Jul 16, 2013 at 8:29 PM, Timothee Cour wrote: On Tue, Jul 16, 2013 at 7:52 PM, JS wrote: It seems that one must use two templates to process built in times and strings template A(string a) { ... } template A(a) { enum A = A(typeof(a).stringof); } This is so we can do stuff like A!(double) and A!("double"). The problem is when we have many parameters the number of permutations increases exponentially. Is there a better way to unify the two? template a(T...)if(T.length==1){ enum a=1; } void main(){ auto a1=a!double; auto a2=a!"double"; } However: This syntax sucks. Why not support the following syntax: template a(auto T) {...} with same semantics? Because this is problematic with more arguments: I'd like this: template a(auto T1, double T2){...} but instead have to do that: template a(T...)if(is(T[1]==double)) {...} and it gets quickly more complicated A) actually, I'm not sure if auto would be the best keyword here, but maybe another keyword. B) What's the rationale why alias can't match to a primitive type in the first place? I think this is the real problem, else it would be rather easy. I don't mind writing static if's for each argument as that's linear. C) correction: above, it should be: template a(T...)if(T.length==2 && is(T[1]==double)) {...} which is quite verbose.
Re: Template explosion
On Tue, Jul 16, 2013 at 8:29 PM, Timothee Cour wrote: > On Tue, Jul 16, 2013 at 7:52 PM, JS wrote: > >> >> It seems that one must use two templates to process built in times and >> strings >> >> template A(string a) { ... } >> template A(a) { enum A = A(typeof(a).stringof); } >> >> This is so we can do stuff like A!(double) and A!("double"). >> >> The problem is when we have many parameters the number of permutations >> increases exponentially. >> >> Is there a better way to unify the two? >> > > template a(T...)if(T.length==1){ > enum a=1; > } > void main(){ > auto a1=a!double; > auto a2=a!"double"; > } > > However: > This syntax sucks. > Why not support the following syntax: > template a(auto T) {...} > with same semantics? > > Because this is problematic with more arguments: > I'd like this: > template a(auto T1, double T2){...} > > but instead have to do that: > template a(T...)if(is(T[1]==double)) {...} > and it gets quickly more complicated > > A) actually, I'm not sure if auto would be the best keyword here, but maybe another keyword. B) What's the rationale why alias can't match to a primitive type in the first place? C) correction: above, it should be: template a(T...)if(T.length==2 && is(T[1]==double)) {...} which is quite verbose.
Re: Template explosion
On Tue, Jul 16, 2013 at 7:52 PM, JS wrote: > > It seems that one must use two templates to process built in times and > strings > > template A(string a) { ... } > template A(a) { enum A = A(typeof(a).stringof); } > > This is so we can do stuff like A!(double) and A!("double"). > > The problem is when we have many parameters the number of permutations > increases exponentially. > > Is there a better way to unify the two? > template a(T...)if(T.length==1){ enum a=1; } void main(){ auto a1=a!double; auto a2=a!"double"; } However: This syntax sucks. Why not support the following syntax: template a(auto T) {...} with same semantics? Because this is problematic with more arguments: I'd like this: template a(auto T1, double T2){...} but instead have to do that: template a(T...)if(is(T[1]==double)) {...} and it gets quickly more complicated
Source code output
With heavy ctfe code generation usage is it possible to have the d compiler output the source code after all mixin templates have been "used"? This way it is easier to visually check for errors in the generated code. I imagine one could use pragma in a "special way" to do this but I was hoping for something more direct.
Re: Using static opCall instead of the default constructor.
On Tuesday, 16 July 2013 at 23:00:06 UTC, Namespace wrote: static PriorityQueue opCall(T)() { PriorityQueue!T po; po.A = new T[DEFAULT_QueueSIZE]; po.num = 1; return po; } Thanks a lot.
Template explosion
It seems that one must use two templates to process built in times and strings template A(string a) { ... } template A(a) { enum A = A(typeof(a).stringof); } This is so we can do stuff like A!(double) and A!("double"). The problem is when we have many parameters the number of permutations increases exponentially. Is there a better way to unify the two?
Re: A little of coordination for Rosettacode
OK, the code now works :-) And the results are a bit hilarious: ...>md5_implementation5_dmd md5 digest("") = D41D8CD98F00B204E9800998ECF8427E zmd5 digest("") = D41D8CD98F00B204E9800998ECF8427E Test performance / message size 200MBytes digest(data) = F083432AB71F6177A8EC2CA5157F7B83 std.md5:16.59 M/sec (12.05 secs) digest(data) = F083432AB71F6177A8EC2CA5157F7B83 zmd5 :81.90 M/sec ( 2.44 secs) ...>md5_implementation5_ldc md5 digest("") = D41D8CD98F00B204E9800998ECF8427E zmd5 digest("") = D41D8CD98F00B204E9800998ECF8427E Test performance / message size 200MBytes digest(data) = F083432AB71F6177A8EC2CA5157F7B83 std.md5: 112.36 M/sec ( 1.78 secs) digest(data) = F083432AB71F6177A8EC2CA5157F7B83 zmd5 :98.18 M/sec ( 2.04 secs) The zmd5 version is generated asm with a small part in D. LDC2 compiles the standard D version even better... :-) Bye, bearophile
Re: A little of coordination for Rosettacode
But the code in that link is all wrong because it needs all the code from std.md5 to work. And even then I don't know where Decode() is. OK, the code now works :-) Bye, bearophile
Re: A little of coordination for Rosettacode
http://codepad.org/g4RBio8E this line: .replace("TT", "0x" ~ text(T(n), 16)); Needs to be: .replace("TT", "0x" ~ to!string(T(n), 16)); But the code in that link is all wrong because it needs all the code from std.md5 to work. And even then I don't know where Decode() is. Bye, bearophile
Re: Using static opCall instead of the default constructor.
static PriorityQueue opCall(T)() { PriorityQueue!T po; po.A = new T[DEFAULT_QueueSIZE]; po.num = 1; return po; }
Re: nested enum like template generator
On Tuesday, 16 July 2013 at 21:12:36 UTC, Ali Çehreli wrote: On 07/16/2013 02:01 PM, Ali Çehreli wrote: > On 07/16/2013 01:40 PM, JS wrote: > > It would be nice if we had some way to data globally(in module). > > > > e.g., __ctfestore["name"] = value; > > I would expect model-level objects start their lives after the program > starts running but their initial value can be calculated during compile > time: > > import std.stdio; > import std.conv; > > int[string] ctfestore; > > static this() > { > ctfestore = A!().globalFunc(); > } Ok, I've been silly. That's not CTFE. I meant something like this: static this() { enum initialValue = A!().globalFunc(); ctfestore = initialValue; } And only then I got the problem: > template A() > { > int c; > > int[string] globalFunc() > { > int[string] result; > > void func() > { > for ( ; c < 10; ++c) { Error: static variable c cannot be read at compile time called from here: func() called from here: globalFunc() > result[c.to!string] = c; > } > } > > func(); > return result; > } > } > > void main() > { > writeln(ctfestore); > } > > Prints: > > ["0":0, "4":4, "8":8, "1":1, "5":5, "9":9, "2":2, "6":6, "3":3, "7":7] Ali yes, that error is the bitch that D loves to slap me with constantly when using ctfe's and I have to use wierd methods to get around it. Note that I am mainly talking about string mixins but the issue is that c is a template variable which is a compile time construct that has no real meaning inside a ctfe(if that makes sense). This is why nested functions have to be used... but then if you want global variables(cross-template variables) you need some other technique, if it's even possible. template A() { int c; // doesn't create a variable c for functions in the template to use but tells the template define a variable when used, I guess, as a normal template(not a mixin). That is, I was initially thinking `int c;` created a compile time variable inside the template but it doesn't... c does't even exist until the template is used, but by then, it's too late... specially if the template is used as a string mixin. I think we would need somethign like template A() { template int c; // or possibly internal int c; which defines c as a template variable(not a symbolic expression inserted into code where A is used. here is code that makes it clear: module main; import std.stdio, std.cstream, std.conv; template A() { int c; int foo() { return ++c; } enum A = foo(); // Comment out to change A to a standard template } void main(string[] argv) { alias A!() a; //writeln(a.c, a.foo()); writeln(a); } Note that A is used two different ways. A as a sort of function itself(with return foo() and, if that line is commented out, as a sort of container holding an int and a function. I think this is the confusion that I had not realizing they are two different beasts. When A is acting as a container, foo can use c no problem. When A is acting as a ctfe, foo can't use c. I'm not sure if this is a flaw, bug, or what... I don't see any reason why it can't work both ways, and nesting the template as a function works to solve the compile time error. I think both concepts can be unified by having the compiler implicitly wrap everything inside the template in a function, accept assignments to A, when used as a ctfe. (this may not work well though but a start in the right direction)
Re: A little of coordination for Rosettacode
This entry has stopped working since lot of time: http://rosettacode.org/wiki/MD5/Implementation#D This is an improved version, but help is welcome: http://codepad.org/g4RBio8E Bye, bearophile
Using static opCall instead of the default constructor.
Hello, I am trying to using static opCall instead of the default constructor. When I run it, I got "Error: need 'this' to access member A". How to fix it? Here is my code. struct PriorityQueue(T) { static const int DEFAULT_QueueSIZE = 1; T[] A; int num; this(this){ A = A.dup; } static PriorityQueue opCall() { A = new T[DEFAULT_QueueSIZE]; // Error num = 1;// Error PriorityQueue priorityQueue; return priorityQueue; } bool empty() { return num == 0; } void insert( T item) { if( A.length == num ) A.length *= 2; A[ num++] = item; } T extractMax() { A.sort; return A[ --num]; } }
Re: nested enum like template generator
On 07/16/2013 02:01 PM, Ali Çehreli wrote: > On 07/16/2013 01:40 PM, JS wrote: > > It would be nice if we had some way to data globally(in module). > > > > e.g., __ctfestore["name"] = value; > > I would expect model-level objects start their lives after the program > starts running but their initial value can be calculated during compile > time: > > import std.stdio; > import std.conv; > > int[string] ctfestore; > > static this() > { > ctfestore = A!().globalFunc(); > } Ok, I've been silly. That's not CTFE. I meant something like this: static this() { enum initialValue = A!().globalFunc(); ctfestore = initialValue; } And only then I got the problem: > template A() > { > int c; > > int[string] globalFunc() > { > int[string] result; > > void func() > { > for ( ; c < 10; ++c) { Error: static variable c cannot be read at compile time called from here: func() called from here: globalFunc() > result[c.to!string] = c; > } > } > > func(); > return result; > } > } > > void main() > { > writeln(ctfestore); > } > > Prints: > > ["0":0, "4":4, "8":8, "1":1, "5":5, "9":9, "2":2, "6":6, "3":3, "7":7] Ali
Re: nested enum like template generator
On 07/16/2013 01:40 PM, JS wrote: > The problem is I can't declare my "global" int variables directly inside > the template. This does make it hard to use the same variable across > multiple functions... > > template A > { > int c; // makes c near useless, can't use it like a normal it... > } Could you please provide complete code. The following works: import std.stdio; import std.conv; template A() { int c; } string func(T)() { string result; alias counter = A!().c; for ( ; counter < 10; ++counter) { result ~= counter.to!string; } return result; } void main() { writeln(func!int()); } Prints: 0123456789 This works as well: import std.stdio; import std.conv; template A() { int c; string func() { string result; for ( ; c < 10; ++c) { result ~= c.to!string; } return result; } } void main() { writeln(A!().func()); } Prints the same: 0123456789 > the error message given obfuscates the reason. What is the error message? > Unfortunately it requires a messy technique to get around by using nested > functions. (The parent function holds the global state of the child > functions) Well, this works as well: import std.stdio; import std.conv; template A() { int c; string globalFunc() { string result; void func() { for ( ; c < 10; ++c) { result ~= c.to!string; } } func(); return result; } } void main() { writeln(A!().globalFunc()); } Again, prints the same: 0123456789 > It would be nice if we had some way to data globally(in module). > > e.g., __ctfestore["name"] = value; I would expect model-level objects start their lives after the program starts running but their initial value can be calculated during compile time: import std.stdio; import std.conv; int[string] ctfestore; static this() { ctfestore = A!().globalFunc(); } template A() { int c; int[string] globalFunc() { int[string] result; void func() { for ( ; c < 10; ++c) { result[c.to!string] = c; } } func(); return result; } } void main() { writeln(ctfestore); } Prints: ["0":0, "4":4, "8":8, "1":1, "5":5, "9":9, "2":2, "6":6, "3":3, "7":7] Ali
Re: nested enum like template generator
On Tuesday, 16 July 2013 at 14:05:38 UTC, Ali Çehreli wrote: On 07/15/2013 10:51 PM, JS wrote: > On Tuesday, 16 July 2013 at 04:37:33 UTC, Ali Çehreli wrote: >> On 07/15/2013 08:43 PM, JS wrote: >> >> > http://dpaste.dzfl.pl/7c8b0ba9 >> > >> > Why the heck can't we use integers in ctfe's? There seems to >> be no >> > simple way to create a counter and this is one of the most >> basic >> > programming constructs to use.. yet with ctfe's it's >> impossible. >> > >> > I'd like each variable in the nested structs to be >> incremented properly. >> >> I did not read the code but just from your description, the separate >> compilation model that D uses would preclude that. For example, >> compilation of a.d would not know anything about the counter that b.d >> has counted during its compilation. >> >> Ali > > Huh? what is a.d and b.d? Yeah, I should have read your code before writing that. My comment is for the general case where a.d and b.d are two separte modules that are compiler separately. I thought that you wanted a counter to continue counting between modules. That wold be nice but require external storage to an ctfe which is a limitation of ctfe's. Ok, at least this post has helped me solve my problem. I guess the issue was the error message given. The problem is I can't declare my "global" int variables directly inside the template. This does make it hard to use the same variable across multiple functions... template A { int c; // makes c near useless, can't use it like a normal it... } solution, one has to use nested functions: template A { string templateScope() { int c; // c now acts like a normal global int value to all nested functions. } } I think I understand why this works and is done this way but the error message given obfuscates the reason. Unfortunately it requires a messy technique to get around by using nested functions. (The parent function holds the global state of the child functions) It would be nice if we had some way to data globally(in module). e.g., __ctfestore["name"] = value; I understand this wouldn't probably work well outside the module since compilation order may be not be consistent. (but maybe __ctfeVolitileStore could be used for cross module storage)
Re: Are associative arrays stable in D?
On Tuesday, July 16, 2013 21:37:13 Gary Willoughby wrote: > Are associative arrays stable in D? I have to ask because i'm > having a great deal of problems with them for simple operations. > For example the following crashes. > > import std.stdio; > > void main(string[] args) > { > int[string] waiting; > > waiting["gary"] = 1; > waiting["tess"] = 2; > > foreach (string key; waiting.byKey()) > { > writeln(key); > writeln(waiting[key]); > waiting.remove(key); > } > } > > If however you remove the .byKey() call and use .keys instead, it > works! > > Also if you remove the 'writeln(waiting[key]);' line from the > above code it prints about 40 blank lines. It's not safe to remove anything from the AA while iterating over it. Doing so will invalidate the range. If you did foreach(auto key; waiting.keys()) { writeln(key); writeln(waiting[key]); waiting.remove(key); } then you'd be okay - either that or create a new array which you append the keys to that you want to remove and then have a second loop which loops over that array and removes each of the keys from the AA. In this particular case, since you're removing everything, it's probably more efficient to just allocate the array with all of them up front with keys(), but if you were only removing some of them, then it would probably be more efficient to create an array of the keys to remove and then iterate over those in a second loop. - Jonathan M davis
Are associative arrays stable in D?
Are associative arrays stable in D? I have to ask because i'm having a great deal of problems with them for simple operations. For example the following crashes. import std.stdio; void main(string[] args) { int[string] waiting; waiting["gary"] = 1; waiting["tess"] = 2; foreach (string key; waiting.byKey()) { writeln(key); writeln(waiting[key]); waiting.remove(key); } } If however you remove the .byKey() call and use .keys instead, it works! Also if you remove the 'writeln(waiting[key]);' line from the above code it prints about 40 blank lines.
Re: What is the correct way to test for an empty string?
On Tuesday, 16 July 2013 at 19:33:13 UTC, bearophile wrote: The right, safe and readable way is to use std.array.empty: if (myString.empty) OMG, of course. Thanks!
Re: What is the correct way to test for an empty string?
Gary Willoughby: What is the correct way to test for an empty string? I've used if (string == "") and if (string is null) and both (O_o) in some places, it's starting to do my head in. What is the correct way? The right, safe and readable way is to use std.array.empty: if (myString.empty) If you don't want to import functions, then test for the length: if (string.length == 0) Bye, bearophile
Re: What is the correct way to test for an empty string?
I just use if(string.length == 0) {} which covers both cases and is pretty intuitive too.
What is the correct way to test for an empty string?
What is the correct way to test for an empty string? I've used if (string == "") and if (string is null) and both (O_o) in some places, it's starting to do my head in. What is the correct way?
Re: interacting with a process with redirected stdin/stdout/stderr
On Tue, Jul 16, 2013 at 10:01 AM, Anthony Goins wrote: > On Monday, 15 July 2013 at 06:46:52 UTC, timotheecour wrote: > >> On Monday, 15 July 2013 at 03:49:10 UTC, Timothee Cour wrote: >> >>> I'm trying to interact with a process using std.process and >>> redirected stdin/stdout/stderr. >>> What would be the recommended way? >>> >>> For example: >>> >>> auto pipes=pipeShell("myprocess",**Redirect.all); >>> while(true){ >>> pipes.stdin.rawWrite(some_**command); >>> foreach (line; pipes.stdout.byLine) { >>>//do something with line >>> } >>> } >>> >>> >>> This doesn't work because it might block inside pipes.stdout.byLine, as >>> the >>> process is requesting more inputs to be written to its stdin before >>> outputting more bytes to its stdout. >>> >>> What's the right approach? >>> * fcntl(fd, F_SETFL, O_NONBLOCK); didn't seem to work >>> * reading pipes.stdout inside a separate thread? >>> In that second case, how to cleanly dispose of a blocked thread when we >>> no >>> longer need it? >>> >>> Any detailed example would help. >>> Thanks! >>> >> >> >> >> I tried using a separate thread for reading the process' stdout. It >> works, except that sometimes the output is shuffled out of order. >> >> Is there anything buggy in this: >> >> >> __gshared string output; >> >> void readBlocking(){ >> while ((c = fgetc(filepointer)) >= 0) >> output~=cast(char) c; >> //NOTE: i can use something more efficient here but that's beside the >> question >> } >> >> thread = new Thread(& readBlocking); >> output=null; >> while(true){ >> Thread.sleep(...); >> if(condition) break; >> } >> //now output is shuffled out of order sometimes >> >> >> Furthermore, is there a standard way to tell when a process is waiting >> for stdin input ? (cf condition above). Currently I'm checking whether >> 'output' was modified within a timeout period T, but that's fragile and >> incurs of penalty of T at least. >> > > Are you looking for select() or poll() > Poll I believe is posix only but I think select is more widely available. > Not much of an answer but I hope it helps > > Thanks, I had actually used select to solve another problem I had: [std.process: how to process stdout chunk by chunk without waiting for process termination] That should work for here as well. I think std.process is a bit limited currently, I keep having to implement basic stuff it doesn't support.
Re: interacting with a process with redirected stdin/stdout/stderr
On Monday, 15 July 2013 at 06:46:52 UTC, timotheecour wrote: On Monday, 15 July 2013 at 03:49:10 UTC, Timothee Cour wrote: I'm trying to interact with a process using std.process and redirected stdin/stdout/stderr. What would be the recommended way? For example: auto pipes=pipeShell("myprocess",Redirect.all); while(true){ pipes.stdin.rawWrite(some_command); foreach (line; pipes.stdout.byLine) { //do something with line } } This doesn't work because it might block inside pipes.stdout.byLine, as the process is requesting more inputs to be written to its stdin before outputting more bytes to its stdout. What's the right approach? * fcntl(fd, F_SETFL, O_NONBLOCK); didn't seem to work * reading pipes.stdout inside a separate thread? In that second case, how to cleanly dispose of a blocked thread when we no longer need it? Any detailed example would help. Thanks! I tried using a separate thread for reading the process' stdout. It works, except that sometimes the output is shuffled out of order. Is there anything buggy in this: __gshared string output; void readBlocking(){ while ((c = fgetc(filepointer)) >= 0) output~=cast(char) c; //NOTE: i can use something more efficient here but that's beside the question } thread = new Thread(& readBlocking); output=null; while(true){ Thread.sleep(...); if(condition) break; } //now output is shuffled out of order sometimes Furthermore, is there a standard way to tell when a process is waiting for stdin input ? (cf condition above). Currently I'm checking whether 'output' was modified within a timeout period T, but that's fragile and incurs of penalty of T at least. Are you looking for select() or poll() Poll I believe is posix only but I think select is more widely available. Not much of an answer but I hope it helps
request for a RSS feed of the D Forum
I could not find any posts on this and have not found a link on the site about this either. It would be nice if there was a RSS feed for the forum at least for the announce forum. It is very difficult to monitor changes and updates with so much activity just through the forum. Sorry if this is the wrong place to post this but I did not see a forum for Forum suggestions or web site suggestions.
Re: Need a way to get compressed mangling of a symbol.
On Tuesday, 16 July 2013 at 13:58:10 UTC, Adam D. Ruppe wrote: The reason I snipped the implementations here is the backend is under a more restrictive license so I don't want to get into copying that. But with just what I've said here combined with guess+check against dmd's output it might be enough to do a clean room implementation. Thank you for the reply! My current clean room implementation is limited to: const(char)* mangledSymbol(alias symbol)() { static assert(((symbol.mangleof) ~ "\0").length < 128, "long names won't be available in a library!"); return ((symbol.mangleof) ~ "\0").ptr; } as it turned out i_didn't_need_that_descriptive_names. I'm posting it here, so maybe it'll be easier for some people to follow the currently bumpy road of DLLs in D :)
Re: Optlink search directory path containing spaces?
On 2013-07-16 12:41, Jeremy DeHaan wrote: This seems kind of strange to me, but when I go to specify a search directory for the linker I can't seem to get it to work for a path that contains spaces. It's a known issue. -- /Jacob Carlborg
Re: nested enum like template generator
On 07/15/2013 10:51 PM, JS wrote: > On Tuesday, 16 July 2013 at 04:37:33 UTC, Ali Çehreli wrote: >> On 07/15/2013 08:43 PM, JS wrote: >> >> > http://dpaste.dzfl.pl/7c8b0ba9 >> > >> > Why the heck can't we use integers in ctfe's? There seems to >> be no >> > simple way to create a counter and this is one of the most >> basic >> > programming constructs to use.. yet with ctfe's it's >> impossible. >> > >> > I'd like each variable in the nested structs to be >> incremented properly. >> >> I did not read the code but just from your description, the separate >> compilation model that D uses would preclude that. For example, >> compilation of a.d would not know anything about the counter that b.d >> has counted during its compilation. >> >> Ali > > Huh? what is a.d and b.d? Yeah, I should have read your code before writing that. My comment is for the general case where a.d and b.d are two separte modules that are compiler separately. I thought that you wanted a counter to continue counting between modules. > The template transforms a string into a D code string... which is then > string mixed in. The counter and code generation have nothing to do with > the result. A counter is needed in the generation of the code to > generate enum like characteristics. > > It does use recursion, and I could pass a variable that counts the > number of elements but this too would probably not work due to D > bitching about using ints. I must still be in the dark but I seriously doubt that you would have problems incrementing an int in D. > I imagine one could hack D to make it's flawed CTFE system work, to some > degree... like using strings: > > > template inc(string s) > { > string _(string a) > { > if (a == "0") return "1"; > if (a == "1") return "2"; > if (a == "2") return "3"; > if (a == "3") return "4"; > return "0"; > } > enum inc = _(s); pragma(msg, ":"~_(s)); > } > > which is a modulo 4 incrementer. So, CTFE's have the ability to count... > but extremely short sighted that they don't. I imagine can write a whole > template library using strings to emulate ints in ctfe's... what a shame > though... That would be extreme. Ali
Re: nested enum like template generator
On 07/15/2013 08:43 PM, JS wrote: > http://dpaste.dzfl.pl/7c8b0ba9 > > Why the heck can't we use integers in ctfe's? That is false: import std.range; import std.algorithm; import std.conv; import std.stdio; string makeCode(int begin, int end) { auto result = appender!string(`enum made = "`); iota(begin, end) .map!(a => a.to!string) .joiner(", ") .copy(result); result ~= `";`; return result.data; } unittest { assert(makeCode(3, 7) == `enum made = "3, 4, 5, 6";`); } void main() { mixin (makeCode(-3, 3)); writeln(made); } > There seems to be no > simple way to create a counter and this is one of the most basic > programming constructs to use.. That would be pretty limiting, right? > yet with ctfe's it's impossible. I have a feeling that you had something else in mind. > I'd like each variable in the nested structs to be incremented properly. It should be simple to convert the code above to do that. Ali
Re: Optlink search directory path containing spaces?
Any chance: -L+"C:\Users\Jeremy\Desktop\Search Directory\" works? Nope, same error.
Re: Need a way to get compressed mangling of a symbol.
I'm looking at the dmd source now... The compression is done in the backend, file cgobj.c The conditions are: #define LIBIDMAX 128 if (len > LIBIDMAX) { // Attempt to compress the name name2 = id_compress(name, len); // snip if (len2 > LIBIDMAX)// still too long { /* Form md5 digest of the name and store it in the * last 32 bytes of the name. */ // snip impl, open the source to see specific details /** * Compress an identifier. * Format: if ASCII, then it's just the char * if high bit set, then it's a length/offset pair * Returns: * malloc'd compressed identifier */ char *id_compress(char *id, int idlen) { The implementation, same source file, looks like it compresses by looking for longest duplicate strings and then removes them, using the offset instead. The reason I snipped the implementations here is the backend is under a more restrictive license so I don't want to get into copying that. But with just what I've said here combined with guess+check against dmd's output it might be enough to do a clean room implementation. Or if Walter can give us permission to copy/paste this into a D file we could use id directly.
Need a way to get compressed mangling of a symbol.
I'd like to dynamically load procedures from a dll in my app. To load a symbol from a DLL i need it's mangled name. D currently offers .mangleof which I currently use to generate the name. It works very good, but only for short symbols. Is there any way to get the final mangled name of a symbol during compilation, or maybe there's some documentation describing how compression is done (code'd be fine too)? http://dlang.org/abi.html doesn't cover the compression scheme.
Re: trouble with long
eles: Don C.: "There's a root cause issue -- integer overflow is not an error in general. A good design for a modern language is to offer safe numbers on default, and overflowing/modular integral types for the uncommon cases where the programmer wants such behaviors. Bye, bearophile
Re: trouble with long
eles: Don C.: "There's a root cause issue -- integer overflow is not an error in general. The paper which bearophile keeps posting, which he has apparently never read, shows quite convincingly that you cannot make it an error in a C-family language. There are just too many legitimate uses of integer wraparound. eg. int.max + 200 - 300 should not be an error." See: http://d.puremagic.com/issues/show_bug.cgi?id=9850 Bye, bearophile
Re: trouble with long
On Tuesday, 16 July 2013 at 11:14:44 UTC, bearophile wrote: eles: Bye, bearophile Don C.: "There's a root cause issue -- integer overflow is not an error in general. The paper which bearophile keeps posting, which he has apparently never read, shows quite convincingly that you cannot make it an error in a C-family language. There are just too many legitimate uses of integer wraparound. eg. int.max + 200 - 300 should not be an error." Frankly, I keep thinking if FreePascal didn't nail it the good way: consider all integral values as belonging to the widest integral type, perform calculation (as if) in that type, then truncate (if needed) only the final result, on assignment.
Re: trouble with long
On Tuesday, 16 July 2013 at 11:14:44 UTC, bearophile wrote: eles: Bye, bearophile Walter: "Consider all the addressing modes used - they are all adds, with no overflow checks. Secondly, they all rely on wraparound (overflow) arithmetic, after all, that is how subtraction is done." I think the way to go is to introduce "sanitized" integral types, in conjunction with some compiler flag. If one day Walter agrees with... This way, everybody is free to use whatever it likes.
Re: Reverse Lexical Order
On Tuesday, 16 July 2013 at 01:13:15 UTC, H. S. Teoh wrote: On Mon, Jul 15, 2013 at 08:59:44PM -0400, Jonathan M Davis wrote: On Monday, July 15, 2013 14:48:08 Manfred Nowak wrote: > Jonathan M Davis wrote: > > gotos in such a context seem like a bit > > of a nightmare to me though. > > I did realize this nightmare. Therefore the assurance in the > docs > is probably true only in the absence within the scope of at > least > gotos to targets within the scope. Well, I'd have to study exactly how goto works to say how exactly it would interact with stuff like try-catch. I've pretty much only used goto with case statements and loops and haven't spent the time trying to sort out all of its idiosyncracies. I guess that I should add that to be my todo list. [...] My understanding is that goto translates directly to a jump in assembly, so jumping in/out of blocks with declarations or stuff that needs cleanups should immediately raise red flags. Of course, the compiler may do something intelligent by inserting implicit stack pointer adjustments and/or cleanup blocks, but I wouldn't count on it unless the language spec explicitly requires so. T That's wrong. That's "longjmp", which does a raw ASM jump. C's goto correctly handles stack decrement if the jump would make you leave a scope (destroying a variable), and make a variable disappear. goto's aren't allowed to jump over declarations (unless they "skip" a scope entirelly). Some implementations allow it, but I have no idea how they non-POD type construction :S but stack pointer is always correctly handled. With C++'s destructors, goto has also been "improved" to guarantee that the destructor is called when a goto would make a variable leave a scope. In C++, I don't think it is possible to "leak" a stack variable's destructor, short of doing a longjmp. Long story short, in C, goto always perfectly safe (AFAIK). In C++, it depends on what the compiler will allow you to to do, depending on its "features". If it respects "strict ANSI", though, then you shouldn't be able to go wrong. Related: I use goto fairly often, but I've yet to find a use-case for it outside of loop "improvement", or goto end cleanup. In both these cases, scope blocks should not be a problem.
Re: Optlink search directory path containing spaces?
On Tuesday, 16 July 2013 at 10:41:51 UTC, Jeremy DeHaan wrote: This seems kind of strange to me, but when I go to specify a search directory for the linker I can't seem to get it to work for a path that contains spaces. I tried to put quotes around the switch like I've done for other switches, but when my program goes to link I get some strange errors. If I use something like "-L+C:\Users\Jeremy\Desktop\Search Directory\" (with the quotes) I get the errors C:\Users\Jeremy\Desktop\Search.lib Warning 2: File Not Found C:\Users\Jeremy\Desktop\Search.lib Directory.lib Warning 2: File Not Found Directory.lib It seems to do the same thing even without the space in the path if I leave the quotes around it. The only way I have gotten it to work is by not using quotes and not having any spaces in the path to the directory I want to have searched. Am I doing something wrong? Jeremy Any chance: -L+"C:\Users\Jeremy\Desktop\Search Directory\" works?
Re: trouble with long
On Tuesday, 16 July 2013 at 10:37:59 UTC, eles wrote: Isn't the promotion to int so awful? Better ideas? (yes, I know about casting to long). What do you mean, there is no promotion to int here.
Re: trouble with long
eles: Isn't the promotion to int so awful? Better ideas? (yes, I know about casting to long). Bug report/ER: http://d.puremagic.com/issues/show_bug.cgi?id=4835 There is a pull request, but it's currently stalled: http://d.puremagic.com/issues/show_bug.cgi?id=4835 Bye, bearophile
Re: trouble with long
On Tue, 16 Jul 2013 12:37:58 +0200, eles wrote: $cat test.cpp: #include int main() { long long x = 125000 * 2; std::cout << x << std::endl; return 0; } g++-generated exe displays: -1794967296 $cat test.d: import std.stdio; int main() { long x = 125000 * 2; writefln("%d",x); return 0; } dmd- and gdc-generated exes display: -1794967296 compiling with g++ at least gives a warning: warning: integer overflow in expression [-Woverflow] long long x = 125000 * 2; Both dmd and gdc do not complain in any way. Isn't the promotion to int so awful? Better ideas? (yes, I know about casting to long). This is where integer suffixes can help: long x = 125000L * 2; -- Simen
Optlink search directory path containing spaces?
This seems kind of strange to me, but when I go to specify a search directory for the linker I can't seem to get it to work for a path that contains spaces. I tried to put quotes around the switch like I've done for other switches, but when my program goes to link I get some strange errors. If I use something like "-L+C:\Users\Jeremy\Desktop\Search Directory\" (with the quotes) I get the errors C:\Users\Jeremy\Desktop\Search.lib Warning 2: File Not Found C:\Users\Jeremy\Desktop\Search.lib Directory.lib Warning 2: File Not Found Directory.lib It seems to do the same thing even without the space in the path if I leave the quotes around it. The only way I have gotten it to work is by not using quotes and not having any spaces in the path to the directory I want to have searched. Am I doing something wrong? Jeremy
trouble with long
$cat test.cpp: #include int main() { long long x = 125000 * 2; std::cout << x << std::endl; return 0; } g++-generated exe displays: -1794967296 $cat test.d: import std.stdio; int main() { long x = 125000 * 2; writefln("%d",x); return 0; } dmd- and gdc-generated exes display: -1794967296 compiling with g++ at least gives a warning: warning: integer overflow in expression [-Woverflow] long long x = 125000 * 2; Both dmd and gdc do not complain in any way. Isn't the promotion to int so awful? Better ideas? (yes, I know about casting to long).
Re: Reverse Lexical Order
On Tuesday, 16 July 2013 at 07:19:05 UTC, Jacob Carlborg wrote: The docs say: "Any intervening finally clauses are executed, This does not solve: /begin{ code} markA: if( exp1) goto markB; if( exp2) goto markC; ... scope ... ... markB: if( exp3) goto markA; if( exp4) goto markC; ... scope ... ... markC: /end{ code} where all expi are pairwise different. -manfred
Re: Naming convention for template parameters
On Monday, 15 July 2013 at 23:09:59 UTC, Joseph Rushton Wakeling wrote: On 07/16/2013 01:02 AM, H. S. Teoh wrote: I generally use R 'cos it's less typing and I'm lazy ... ditto ... :-) but Walter has been recently of the opinion that a more descriptive name is necessary for ddoc purposes, e.g., MyStruct(InputRange)(InputRange r) is much more self-documenting than MyStruct(R)(R r). Yes, that was my main consideration for this case. I'm worried about the potential for clashes with other elements of the namespace, though. I'm thinking in particular of the tendency to use Random as the template parameter name for a random number generator, when Random is actually an alias for the default RNG type. I've proposed a blanket rewrite of such template parameter names to Rng: http://d.puremagic.com/issues/show_bug.cgi?id=10434 Particular context is that I'm trying to tidy up/standardize some bits of std.random and I'd like my standards to be future-proof. :-) struct SomeRangeWrapper(Range) { alias R = Range; //... } Fixed. I think "Range" is better, because it shows up in the docs, and is a bit clearer than "R" (although anybody doing D should understand it). But when working, "R" is easier. The above approach solves both.
Re: nested enum like template generator
On Tuesday, 16 July 2013 at 05:51:53 UTC, JS wrote: ... Once again you post a complex and messy snippet and than jump to wrong conclusions. This works: template inc(int i) { enum inc = i + 1; } pragma(msg, inc!3); Integers are treated normally in CTFE/templates, contrary to your last statement. You need to reduce to the real problem.
Re: Allocate N elements
On Monday, 15 July 2013 at 17:39:43 UTC, H. S. Teoh wrote: On Mon, Jul 15, 2013 at 07:32:37PM +0200, monarch_dodra wrote: On Monday, 15 July 2013 at 15:54:57 UTC, bearophile wrote: >monarch_dodra: > >>>But that (of new arrays) is a bad design, it wastes too much >>>memory, and I think it should be fixed. In Python this >>>doesn't >>>overallocate: >> >>So what? The only thing you showed, is that >>minimallyInitialized >>doesn't know how much it allocated. If you allocate 513 >>elements >>with malloc, you'll way over allocate too. What's your point? >>You'll waste memory either way. > >I didn't know it, sorry. I forgot. >Can we let minimallyInitializedArray know the capacity? I'm working on it ;) >Regarding the small arrays, so to avoid the memory wasting you >need to allocate a larger one and slice it. > >Bye, >bearophile One of the problems is that when you want an arbitrarily sized allocation, it is usually standard to allocate 2^N in size. While this is optimal for "traditional" malloc, it's actually the *worst* allocation size you could ask for a GC array with appendable info (eg, traditional new) :/ This is wrong. The 2^N size should be applied *after* GC appendable info (or whatever else bookkeeping info you need) has been accounted for, not before. If the GC header/whatever requires, say, 16 bytes, then the ideal array size should be 2^N-16, so that everything fits neatly within a power of 2. Otherwise you end up with 2^N+16 bytes that are actually allocated, and it just goes downhill from there. T Just to be clear, the GC itself has no overhead. Only the APPENDABLE bookkeeping does any overhead. EG: GC.malloc(1024); This will allocate a 1024 byte block. No problem here. HOWEVER, if you write: int[] arr = new int[](1000); //Allocates a 4Ki block int[] arr = new int[](1024); //Allocates an 8Ki block The example is a bit extreme, but you should get what I mean. If you do a malloc with GC.BlkAttr.APPENDABLE, you will also get exactly what you asked for. However, it will be the user's responsibility to take into account that some of those allocated bytes will not actually be useable (the APPENDABLE block). FYI, the way APPEDNABLE works: Arrays 1-255 bytes: 1 extra byte will be appended for used capacity info at the end of the array. Arrays 256-2046: 2 extra bytes will be appended. 2047+: The array will *start* with a 16 byte block for appendable info. A dummy 1 byte block will also be appended to the end of the block, for "arr[$ .. $]". (So yes, you need to accound for a *17* byte overhead) That said, allocating an array using a straight up malloc(APPEDNABLE) is *very* complicated, and it is all very specific to the current GC anyways: It is very very error prone, and non portable.
Re: Types of regex
AAAh !! Got it ! I will make the switch ! Thanks a lot :) Larry
Re: Types of regex
On Tue, Jul 16, 2013 at 08:15:16AM +0200, Larry wrote: > I have gdc 4.6 on Debian testing. > > Is that so old ? That is extremely old. You want to get gdc-4.8.1 from unstable, if you can. A great number of bugs have been fixed since gdc-4.6; in fact, the entire std.regex has been replaced, which is probably why you're seeing these problems with regexes that the rest of us don't see. T -- If it's green, it's biology, If it stinks, it's chemistry, If it has numbers it's math, If it doesn't work, it's technology.
Re: Reverse Lexical Order
On 2013-07-16 03:11, H. S. Teoh wrote: My understanding is that goto translates directly to a jump in assembly, so jumping in/out of blocks with declarations or stuff that needs cleanups should immediately raise red flags. Of course, the compiler may do something intelligent by inserting implicit stack pointer adjustments and/or cleanup blocks, but I wouldn't count on it unless the language spec explicitly requires so. The docs say: "Any intervening finally clauses are executed, along with releasing any intervening synchronization mutexes." http://dlang.org/statement.html#GotoStatement -- /Jacob Carlborg