Make a variable single-assignment?
Hi, Is there any way to make a variable single-assignment, regardless of its type? I.e.: void foo() { some magical keyword? int i = 0; i = 2; // Error: i cannot be reassigned } I realize const and immutable will do this, but they are transitive and infect the type, which I do *not* want. I simply want the variable to be single-assignment. Is it possible? - Alex
Re: Make a variable single-assignment?
Don't think so. You could also wrap it in a struct with disabled opAssign, but this would also change the type.
Re: Make a variable single-assignment?
On 21-11-2011 15:48, Trass3r wrote: Don't think so. You could also wrap it in a struct with disabled opAssign, but this would also change the type. Perhaps allowing 'final' on fields and locals would be a nice way to gain this effect... - Alex
Re: Make a variable single-assignment?
On 11/21/11 11:04 AM, Alex Rønne Petersen wrote: Hi, Is there any way to make a variable single-assignment, regardless of its type? I.e.: void foo() { some magical keyword? int i = 0; i = 2; // Error: i cannot be reassigned } I realize const and immutable will do this, but they are transitive and infect the type, which I do *not* want. I simply want the variable to be single-assignment. Is it possible? - Alex Why do you want that?
Re: Make a variable single-assignment?
For one reason, public fields that lack a set without having to create a backing field, followed by a bulky property. It does sound lazy, but when it's something you have to repeat many times, it gets annoying. On 21/11/2011 9:43 AM, Ary Manzana wrote: On 11/21/11 11:04 AM, Alex Rønne Petersen wrote: Hi, Is there any way to make a variable single-assignment, regardless of its type? I.e.: void foo() { some magical keyword? int i = 0; i = 2; // Error: i cannot be reassigned } I realize const and immutable will do this, but they are transitive and infect the type, which I do *not* want. I simply want the variable to be single-assignment. Is it possible? - Alex Why do you want that?
Re: Make a variable single-assignment?
On 11/21/2011 03:04 PM, Alex Rønne Petersen wrote: Hi, Is there any way to make a variable single-assignment, regardless of its type? I.e.: void foo() { some magical keyword? int i = 0; i = 2; // Error: i cannot be reassigned } I realize const and immutable will do this, but they are transitive and infect the type, which I do *not* want. I simply want the variable to be single-assignment. Is it possible? - Alex How should that be possible without infecting the type? void main(){ magical keyword int i = 0; auto a = i; *a = 2; // oops... }
Re: Make a variable single-assignment?
Le 21/11/2011 15:04, Alex Rønne Petersen a écrit : Hi, Is there any way to make a variable single-assignment, regardless of its type? I.e.: void foo() { some magical keyword? int i = 0; i = 2; // Error: i cannot be reassigned } I realize const and immutable will do this, but they are transitive and infect the type, which I do *not* want. I simply want the variable to be single-assignment. Is it possible? - Alex You can create a struct Final you could use as Final!(type) variable; Overloading opAssign should do whatever you need. I don't think adding to the core language what could ba achived with a nice abstraction should be done.
Re: Queue thread
On 11/20/2011 02:36 PM, bioinfornatics wrote: Le dimanche 20 novembre 2011 à 03:09 -0800, Jonathan M Davis a écrit : On Sunday, November 20, 2011 11:59:14 bioinfornatics wrote: Dear, I would like to know if they are a way to run run a queue thread an run (nb core * 2 + 1) = nb thread in same time something like: size_t nb_core = 9; Queue q = new Queue( 9, process1, process2, process3 ); q.run(); Look at std.parallelism. I don't know if it'll do quite what you want, but it's the closest that you'll find in Phobos. - Jonathan M Davis i have tred to use TaskPool but i fail Error: /parallelism.d(434): Error: no property 'opCall' for type 'fastcgi.application.Page' the problem raise here: https://github.com/bioinfornatics/DFastCGI/blob/master/src/fastcgi/application.d#L74 (i think) Any help are welcome thanks I looked at your code, and saw this: https://github.com/bioinfornatics/DFastCGI/blob/master/src/fastcgi/application.d#L18 _taskPool = new TaskPool( totalCPUs * threadsPerCPU + 1); On my machine, that would come out to 1: [kai.meyer@kai-rhel6 D]$ cat cpu.d import std.stdio; import std.parallelism : totalCPUs, TaskPool, task; import std.cpuid : threadsPerCPU; void main() { writefln(totalCPUs %s, totalCPUs); writefln(threadsPerCPU %s, threadsPerCPU); writefln(totalCPUs * threadsPerCPU + 1 = %s\n, totalCPUs * threadsPerCPU + 1); } [kai.meyer@kai-rhel6 D]$ dmd -run cpu.d totalCPUs 8 threadsPerCPU 0 totalCPUs * threadsPerCPU + 1 = 1 Did you mean this? _taskPool = new TaskPool( totalCPUs * (threadsPerCPU + 1));
Re: Make a variable single-assignment?
On 21-11-2011 17:17, Kapps wrote: For one reason, public fields that lack a set without having to create a backing field, followed by a bulky property. It does sound lazy, but when it's something you have to repeat many times, it gets annoying. On 21/11/2011 9:43 AM, Ary Manzana wrote: On 11/21/11 11:04 AM, Alex Rønne Petersen wrote: Hi, Is there any way to make a variable single-assignment, regardless of its type? I.e.: void foo() { some magical keyword? int i = 0; i = 2; // Error: i cannot be reassigned } I realize const and immutable will do this, but they are transitive and infect the type, which I do *not* want. I simply want the variable to be single-assignment. Is it possible? - Alex Why do you want that? Exactly. In general, it would be useful for guaranteeing that you don't make an accidental assignment to a local or field. Just because you don't want it reassignable doesn't mean you don't want the *contents* reassignable, hence why transitive immutable is not acceptable. - Alex
Re: Make a variable single-assignment?
On 21/11/2011 14:04, Alex Rønne Petersen wrote: Hi, Is there any way to make a variable single-assignment, regardless of its type? I.e.: void foo() { some magical keyword? int i = 0; i = 2; // Error: i cannot be reassigned } I realize const and immutable will do this, but they are transitive and infect the type, which I do *not* want. I simply want the variable to be single-assignment. Is it possible? - Alex In D1 you could use final, in D2 your choices are either const, immutable, or as others have suggested, some sort of a wrapper. You could also use enum if you only want to work with primitive types and the value can be calculated at compile time. -- Robert http://octarineparrot.com/
Re: Queue thread
How come you don't have any threads per CPU? I guess this is a difference between multi-processor and multi-core machines maybe?
Re: Make a variable single-assignment?
What you are describing is Head Const, and is not available. http://www.d-programming-language.org/const-faq.html#head-const It will not be added as it doesn't provide any guarantees about the code that is useful to the compiler. It can't be added to the existing system without complicating the type system even more, which outweighs the benefits. Tail Const, a more useful direction has been shafted for much the same reason. There is however a pull request to add support into the compiler.
Re: Make a variable single-assignment?
The only thing I can think of: struct Once(T) { this(T val) { i = val; } immutable T i; alias i this; } void main() { Once!int i = 1; // ok i = 4; // ng } However it seems I've found a little hole in the system: void foo(ref int x) { x = 2; } void main() { Once!int i = 1; // ok foo(i); assert(i == 1); // fail, changed to 2 } Is this reported somewhere?
mixin on identifier
Hi! I'm trying to do: mixin template StateOne() { int value; } class StateSet(T) { mixin T; } int main(string[] argv) { StateSet!StateOne s = new StateSet!StateOne(); return 0; } Compiler complains with: main.d(18): Error: template instance StateSet!(StateOne) StateSet!(StateOne) does not match template declaration StateSet(T) main.d(18): Error: StateSet!(StateOne) is used as a type I think I understand why. And from what I figured I'd need string mixins? But I can't figure out how... Any hints? Johannes
Re: mixin on identifier
Make T an alias parameter: class StateSet(alias T) { … } David On 11/22/11 12:38 AM, Johannes Totz wrote: mixin template StateOne() { intvalue; } class StateSet(T) { mixin T; } int main(string[] argv) { StateSet!StateOnes = new StateSet!StateOne(); return 0; }
Re: mixin on identifier
On 21/11/2011 23:39, David Nadlinger wrote: Make T an alias parameter: class StateSet(alias T) { … } David Thanks! I was trying to get to something like this: mixin template StateOne() { int value; } mixin template StateTwo() { float data; } class StateSet(alias T ...) { mixin T; } int main(string[] argv) { StateSet!(StateOne, StateTwo) s = new StateSet!(StateOne, StateTwo)(); return 0; } With the docs I got to: template StateSet(alias T, S ...) { class StateSet { mixin T; } } But I have no clue how to expand S into mixin statements. On 11/22/11 12:38 AM, Johannes Totz wrote: mixin template StateOne() { int value; } class StateSet(T) { mixin T; } int main(string[] argv) { StateSet!StateOne s = new StateSet!StateOne(); return 0; }
Why does scopedTask increase memory consumption?
import core.thread; import std.parallelism; import std.stdio; enum loops = 100; void runTask() { static void test() { } auto newTask = scopedTask(test); newTask.executeInNewThread(); newTask.yieldForce(); } void main() { foreach (_; 0 .. loops) runTask(); writeln(done); Thread.sleep(dur!seconds(4)); } Running this consumes 8.024 KB on a win32 quad-core machine. If I set loops to 100_000, it consumes 9.040 KB. I know each thread has its own storage, but I'm invoking only one thread at a time, so after that thread finishes I would assume the thread would clean up after itself and release all memory. In another app using scopedTask keeps eating more and more memory, even though calling the same target function serially doesn't increase memory consumption. I admit I'm very new to concurrency so I don't know whether this is normal or not. I know each thread has its own TLS but afaik when a thread dies it should release those resources.
Is __VERSION__ cross-compiler compatible?
I've seen this code used somwhere: static if (__VERSION__ 2048) { } Does this work for all compilers, or is it DMD-specific? Also, does DMD1 define this too? I'm trying to retain compatibility of some D1 sample code but introduce D2 support as well.
Re: Is __VERSION__ cross-compiler compatible?
On Tuesday, November 22, 2011 02:10:51 Andrej Mitrovic wrote: I've seen this code used somwhere: static if (__VERSION__ 2048) { } Does this work for all compilers, or is it DMD-specific? Also, does DMD1 define this too? I'm trying to retain compatibility of some D1 sample code but introduce D2 support as well. I'd expect it to be compiler-specific. - Jonathan M Davis
Re: Is __VERSION__ cross-compiler compatible?
GDC does seem to use this, now that I've tested it: D:\dev\code\d_codegdc test.d 1067L D:\dev\code\d_codegdc -v2 test.d 2052L I've found the docs, it states this is a compiler token: http://d-programming-language.org/lex.html (section Special Tokens) But being able to target a *language version* in a compiler-neutral way would be great. I don't know if LDC does the same thing as GDC though.
Re: Why does scopedTask increase memory consumption?
Magic uncovered, it's because the Task instantiates its own private task pool: void executeInNewThread() @trusted { pool = new TaskPool(basePtr); } Ok, so I need to keep my own thread pool or use the global one and then use task() to create a task and add it to the pool. I can do this via: taskPool.put(aTask); But where on earth is the start method for taskPool? There's stop, but I don't see start. I've temporarily made doSingleTask() public, and calling it works perfectly (of course I do have to keep using put() every time). So with those changes the memory issues go away. If only we didn't have this awful GC then I wouldn't have to care about these issues! :-) On 11/22/11, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: import core.thread; import std.parallelism; import std.stdio; enum loops = 100; void runTask() { static void test() { } auto newTask = scopedTask(test); newTask.executeInNewThread(); newTask.yieldForce(); } void main() { foreach (_; 0 .. loops) runTask(); writeln(done); Thread.sleep(dur!seconds(4)); } Running this consumes 8.024 KB on a win32 quad-core machine. If I set loops to 100_000, it consumes 9.040 KB. I know each thread has its own storage, but I'm invoking only one thread at a time, so after that thread finishes I would assume the thread would clean up after itself and release all memory. In another app using scopedTask keeps eating more and more memory, even though calling the same target function serially doesn't increase memory consumption. I admit I'm very new to concurrency so I don't know whether this is normal or not. I know each thread has its own TLS but afaik when a thread dies it should release those resources.