Re: They are not the same
On Saturday, 5 April 2014 at 01:57:59 UTC, Meta wrote: When I put a println inside both functions, they both print out [2, 1, 0]. Shouldn't the first print [0, 1, 2] while the second prints [2, 1, 0]? No, sorry, I was mistaken about what was going on.
Re: They are not the same
On Saturday, 5 April 2014 at 01:28:06 UTC, bearophile wrote: Can you spot the difference between foo1 and foo2? import std.algorithm: map; import std.range: iota; void foo1(in int[] a, in int[] b) pure { int[] r; foreach (immutable i; 0 .. a.length) r ~= (i % 2) ? a[i] : b[i]; } void foo2(in int[] a, in int[] b) pure { int[] r; foreach (x; iota(a.length) .map!(i => (i % 2) ? a[i] : b[i])) r ~= x; } void main() {} Sometimes variants of this problem hit me. I don't even know if this simple problem has a name. Is it impossible to solve? Bye, bearophile When I put a println inside both functions, they both print out [2, 1, 0]. Shouldn't the first print [0, 1, 2] while the second prints [2, 1, 0]?
Re: two questions on enums
By using the interface, it also forces the user to include all of the attributes of each pin such as direction, max load, DC current, etc. Since class type enums are references, they are light, - and they should be immutable - so they are thread safe aslo. I'm not sure how you're using your enum. In Java, the only way to perform a switch over an enum is if you know all the values during compile time. Passing a type Enum into a function (i.e. as opposed to "enum MyEnumType') requires using introspection to pull the actual values out, and then a loop to scan through them for your target value. But if you've programmed a switch for a known enum type, then that means the enum has already been implemented and there is no chance for more than one type to be passed in. So I'm confused. I guess D does not see enums as enums, but rather as whatever type the enum happens to implement. In java, all enums are of enum type. So it's probably me that's confused. -Eric
They are not the same
Can you spot the difference between foo1 and foo2? import std.algorithm: map; import std.range: iota; void foo1(in int[] a, in int[] b) pure { int[] r; foreach (immutable i; 0 .. a.length) r ~= (i % 2) ? a[i] : b[i]; } void foo2(in int[] a, in int[] b) pure { int[] r; foreach (x; iota(a.length) .map!(i => (i % 2) ? a[i] : b[i])) r ~= x; } void main() {} Sometimes variants of this problem hit me. I don't even know if this simple problem has a name. Is it impossible to solve? Bye, bearophile
Re: two questions on enums
On Thursday, 3 April 2014 at 23:16:14 UTC, Eric wrote: Okay - I'm new to D, and I'm comming from a java background. Suppose you are designing an API, and you want the user to supply arguments as an enum. But the user needs to define the enum, so how can the API know in advance what enum to require? The solution is to require an enum that implements a known interface. This is easy to do in java, but I haven't yet tried it in D. I suspect it could be done with CTFE or something. An example where I use this is for electronics software. If I need the user to supply a set of pins, the pins are supplied as an enum which implements an interface. By using the interface, it also forces the user to include all of the attributes of each pin such as direction, max load, DC current, etc. Since class type enums are references, they are light, - and they should be immutable - so they are thread safe aslo. I'm not sure how you're using your enum. In Java, the only way to perform a switch over an enum is if you know all the values during compile time. Passing a type Enum into a function (i.e. as opposed to "enum MyEnumType') requires using introspection to pull the actual values out, and then a loop to scan through them for your target value. But if you've programmed a switch for a known enum type, then that means the enum has already been implemented and there is no chance for more than one type to be passed in. So I'm confused.
templates, enums, CT reflection: compiler bug or not?
i stumbled upon something strange while wondering around meta/codegen-lands. it took me almost a week to reduce it to the following test case. i have no clue what is going on, whether i have entered bug territory or just encountered my own limitations mind you, i have 2 issues with the code: (1) that my template, which uses __traits(compiles, ...), under certain circumstances (aka 'if things are getting complicated') fails to see symbols that one could argue are valid in this scope. (annoying maybe, but not my main problem) (2) the strange compiler error i get when using the template on itself, but only if it is not the first time that the instantiation is used. this is my real issue cause i don't know how to work around this. during my attempts to reduce this, starting from much more complicated code, i encountered all sorts of errors, including ICE and __error stuff. so am i being stupid or is it a compiler bug? cheers, det ===CODE=== module demo; template valid(string mem){ pragma(msg, "instantiation of valid with: "~mem); static if( !__traits( compiles, mixin(mem) ) ){ enum valid = false; }else{ enum valid = true; } } enum ok = valid!"foo"; pragma(msg, ok ); // -> true // fine, recognizes 'foo' in module scope enum works = valid!"fails"; pragma(msg, works );// -> false // problematic, fails to see 'fails' in module scope enum dummy = valid!"fails"; pragma(msg, dummy );// -> false // same behavior, as long as you are not testing yourself enum fails = valid!"fails"; // Error: variable demo.fails had semantic errors when compiling // NOTE: if you comment out the first two usages of valid!"fails", it will work here, // although it will result in "false" // pragma(msg, fails ); enum foo = 42; void main(){}
Re: std.array.array seems to return flatten copy of input
Sorry Steven, I hadn't seen your answer. Thanks for the extra information. O. On Friday, 4 April 2014 at 20:42:32 UTC, Steven Schveighoffer wrote: On Fri, 04 Apr 2014 16:35:57 -0400, Olivier Grant wrote: That is one responsive D community :) Thank you to all three of you for these quick answers. I was really scratching my head on that one. This shows that UFCS can be quite dangerous. Is there any way to hide Splicer.array to the outside world? It just seems that it would be very easy to break client code by updating your implementation if you end up using a name that is already used elsewhere and accessed using UFCS. I advise to call it _array to prevent such issues. Note, you can make the field private, but that is a module-level directive. In order for it to apply, main would have to be in a separate module. In that case, the code would simply fail to compile. As a rule, members ALWAYS have precedence over UFCS functions. -Steve
Re: Manually-allocated memory and maximum array capacity
On 04/05/14 00:54, Joseph Rushton Wakeling wrote: > Hello all, > > If we change the length of a dynamic array using the normal GC-based methods, > e.g. by setting the array's .length property, we find that the array's > capacity typically does not simply equal the length, but some greater value; > there is excess allocation. > > Question: is there a comparable phenomenon for memory that is manually > allocated using malloc? That is, that if we specify a particular number of > bytes to allocate, it may be rounded up to a particular larger number? > > And, if so -- is there any way of guaranteeing what that larger number will > be? > > The reason I ask is because, suppose that I use a dynamic array as a > fixed-size buffer, and that its minimum size must be n. So, I can do: > > arr.length = n; > if (arr.capacity > arr.length) > { > arr.length = arr.capacity; > } > > ... and get the largest possible buffer that is at least size n, but does not > allocate any more memory than setting length = n. > > I'm wondering if I can do something similar with manual memory allocation. Not portably, as it will be libc and/or allocator specific. For example, for glibc this would work: /* static if (using_glibc) */ size_t capacity(const void* p) @property @safe { return malloc_usable_size(p); } artur
Re: Manually-allocated memory and maximum array capacity
Joseph Rushton Wakeling: Question: is there a comparable phenomenon for memory that is manually allocated using malloc? Manually allocated memory can over-allocate, but not geometrically as arrays do. Take a look at the difference between core.memory.extend and core.memory.realloc. Bye, bearophile
Manually-allocated memory and maximum array capacity
Hello all, If we change the length of a dynamic array using the normal GC-based methods, e.g. by setting the array's .length property, we find that the array's capacity typically does not simply equal the length, but some greater value; there is excess allocation. Question: is there a comparable phenomenon for memory that is manually allocated using malloc? That is, that if we specify a particular number of bytes to allocate, it may be rounded up to a particular larger number? And, if so -- is there any way of guaranteeing what that larger number will be? The reason I ask is because, suppose that I use a dynamic array as a fixed-size buffer, and that its minimum size must be n. So, I can do: arr.length = n; if (arr.capacity > arr.length) { arr.length = arr.capacity; } ... and get the largest possible buffer that is at least size n, but does not allocate any more memory than setting length = n. I'm wondering if I can do something similar with manual memory allocation. Thanks in advance for any comments and advice! Best wishes, -- Joe
A simplification error when calculating array lengths
(This was in C and probably a common mistake that I haven't experienced until today.) tldr; The following two expressions are not equivalent: a)length - 1 - length / 2 b)length / 2 - 1 I was trying to write a recursive function similar to binary search: - Process the middle element - Call the same function with the left half - Call the same function with the right half void foo(int * arr, size_t length) { if (!length) { return; } // Process the middle element process(arr[length / 2]); // Handle the left side foo(arr, length / 2); // Handle the right side (+1 to skip the middle element) foo(arr + length / 2 + 1, /* ??? */); } What should be the length of the right half on the last line? Minus 1 for the already-processed middle element and minus length/2 for the left half: a)length - 1 - length / 2 That seems to be correct. Then I simplified: b)length / 2 - 1 And that was a mistake because b produces size_t.max when length==1 to begin with. So, the calculations a and b are not equivalent. You knew it already ;) but it surprised me today. Also, this is not an issue with D's slices because slices remove the need for such calculations: foo(arr[$ / 2 + 1 .. $]);// Simple and correct Which also means that maybe I should have used a pair of pointers in the original function instead of a pointer and a length. Ali
Re: std.array.array seems to return flatten copy of input
Yes, that definitely seems like a good start. To be honest, I not familiar enough yet with how you are suppose to organise your source code in D. Is there any agreed-on naming convention when it comes to member variables to avoid that kind of name clash ? Thanks, O. On Friday, 4 April 2014 at 20:44:36 UTC, bearophile wrote: Olivier Grant: Is there any way to hide Splicer.array to the outside world? If your splice is inside another module, and you tag the array field with private, you will receive an error: auto splice( size_t N, R )( R range ) if(isInputRange!R) { struct Splicer { private R array; This avoids your mistake, but also forbids you to use the std.array.array on a splice with UFCS. Is this acceptable for you? Bye, bearophile
Re: std.array.array seems to return flatten copy of input
Olivier Grant: Is there any way to hide Splicer.array to the outside world? If your splice is inside another module, and you tag the array field with private, you will receive an error: auto splice( size_t N, R )( R range ) if(isInputRange!R) { struct Splicer { private R array; This avoids your mistake, but also forbids you to use the std.array.array on a splice with UFCS. Is this acceptable for you? Bye, bearophile
Re: std.array.array seems to return flatten copy of input
On Fri, 04 Apr 2014 16:35:57 -0400, Olivier Grant wrote: That is one responsive D community :) Thank you to all three of you for these quick answers. I was really scratching my head on that one. This shows that UFCS can be quite dangerous. Is there any way to hide Splicer.array to the outside world? It just seems that it would be very easy to break client code by updating your implementation if you end up using a name that is already used elsewhere and accessed using UFCS. I advise to call it _array to prevent such issues. Note, you can make the field private, but that is a module-level directive. In order for it to apply, main would have to be in a separate module. In that case, the code would simply fail to compile. As a rule, members ALWAYS have precedence over UFCS functions. -Steve
Re: std.array.array seems to return flatten copy of input
That is one responsive D community :) Thank you to all three of you for these quick answers. I was really scratching my head on that one. This shows that UFCS can be quite dangerous. Is there any way to hide Splicer.array to the outside world? It just seems that it would be very easy to break client code by updating your implementation if you end up using a name that is already used elsewhere and accessed using UFCS. Thanks, O. On Friday, 4 April 2014 at 20:29:28 UTC, anonymous wrote: On Friday, 4 April 2014 at 20:19:53 UTC, Olivier Grant wrote: import std.stdio; import std.range; import std.array; auto splice( size_t N, R )( R range ) if(isInputRange!R) { struct Splicer { R array; @property bool empty( ) const { return 0 == array.length; } @property auto front( ) const { return array[0 .. N]; } void popFront( ) { array = array[N .. $]; } } static assert(isInputRange!Splicer); assert(range.length % N == 0); Splicer res = { range }; return res; } unittest { assert(equal([1,2,3,4].splice!(2), [[1,2],[3,4]])); } void main( ) { auto a = [1,2,3,4]; writeln(a.splice!(2)); writeln(a.splice!(2).array); } which weirdly enough gives me the following output : [[1,2],[3,4]] // I expect that. [1,2,3,4] // But what is happening here ? a.splice!(2).array is the field of the Splicer struct. Rename that or call std.array.array not via UFCS.
Re: std.array.array seems to return flatten copy of input
On Friday, 4 April 2014 at 20:19:53 UTC, Olivier Grant wrote: Hi, I've started using D as a scripting language at work and for personal projects as a means to learn the language and I've bumped into a case where I would like to iterate a slice by a certain number of elements at a time such that : foreach(s; [1,2,3,4].splice!(2)) { writeln(s); } would print : [1,2] [3,4] First of all, is there such a function in D's standard library as I didn't seem to be able to find one ? http://dlang.org/phobos/std_range.html#chunks
Re: std.array.array seems to return flatten copy of input
On Friday, 4 April 2014 at 20:19:53 UTC, Olivier Grant wrote: import std.stdio; import std.range; import std.array; auto splice( size_t N, R )( R range ) if(isInputRange!R) { struct Splicer { R array; @property bool empty( ) const { return 0 == array.length; } @property auto front( ) const { return array[0 .. N]; } void popFront( ) { array = array[N .. $]; } } static assert(isInputRange!Splicer); assert(range.length % N == 0); Splicer res = { range }; return res; } unittest { assert(equal([1,2,3,4].splice!(2), [[1,2],[3,4]])); } void main( ) { auto a = [1,2,3,4]; writeln(a.splice!(2)); writeln(a.splice!(2).array); } which weirdly enough gives me the following output : [[1,2],[3,4]] // I expect that. [1,2,3,4] // But what is happening here ? a.splice!(2).array is the field of the Splicer struct. Rename that or call std.array.array not via UFCS.
Re: std.array.array seems to return flatten copy of input
On Friday, 4 April 2014 at 20:19:53 UTC, Olivier Grant wrote: iterate a slice by a certain number of elements at a time such that : foreach(s; [1,2,3,4].splice!(2)) { writeln(s); } would print : [1,2] [3,4] First of all, is there such a function in D's standard library as I didn't seem to be able to find one ? std.range.chunks
std.array.array seems to return flatten copy of input
Hi, I've started using D as a scripting language at work and for personal projects as a means to learn the language and I've bumped into a case where I would like to iterate a slice by a certain number of elements at a time such that : foreach(s; [1,2,3,4].splice!(2)) { writeln(s); } would print : [1,2] [3,4] First of all, is there such a function in D's standard library as I didn't seem to be able to find one ? I ended up implementing the following : import std.stdio; import std.range; import std.array; auto splice( size_t N, R )( R range ) if(isInputRange!R) { struct Splicer { R array; @property bool empty( ) const { return 0 == array.length; } @property auto front( ) const { return array[0 .. N]; } void popFront( ) { array = array[N .. $]; } } static assert(isInputRange!Splicer); assert(range.length % N == 0); Splicer res = { range }; return res; } unittest { assert(equal([1,2,3,4].splice!(2), [[1,2],[3,4]])); } void main( ) { auto a = [1,2,3,4]; writeln(a.splice!(2)); writeln(a.splice!(2).array); } which weirdly enough gives me the following output : [[1,2],[3,4]] // I expect that. [1,2,3,4] // But what is happening here ? I'm obviously doing something wrong but I can't figure out what. Thanks for the help in advance, O.
Re: How to hand in a closure variable
On Friday, 4 April 2014 at 15:13:25 UTC, Bienlein wrote: What I was actually looking for was how to get this to work: immutable int b = if(1 == 1) { return 123; } else { return 456; }; But I'm happy enough with the solution through a delegate. What bearophile said, or: immutable int b = {if(1 == 1) { return 123; } else { return 456; }}();
Re: list in spam blacklist? [OT]
Once every few years spamhaus 'cleans up' their white lists with no notifications. I've already initiated the re-removal. Sigh. I hate spamhaus, they're a pain in every mail sender's backside. On 4/4/14, 10:25 AM, Hugo Florentino wrote: Hi, IP 173.45.241.208 (slice-1.puremagic.com) seems to be blacklisted in zen.spamhaus.org Please check for a possible misuse of the server, or in case of a false positive report to spamhaus.org Regards, Hugo
Re: porting GCC macro to D
On 04/04/2014 08:42 AM, ketmar wrote: You can hack around that limitation if it's acceptable to use a temporary variable: sure, and i can rewrite the whole call, passing destination variable as template argument. but this looks ugly. A regular function would work too: void func0 () { } int func1 () { return 42; } int MYMACRO() { func0(); return func1(); } void main() { int v = MYMACRO() - 16; } Ali
list in spam blacklist? [OT]
Hi, IP 173.45.241.208 (slice-1.puremagic.com) seems to be blacklisted in zen.spamhaus.org Please check for a possible misuse of the server, or in case of a false positive report to spamhaus.org Regards, Hugo
Re: How do I obtain the default hash of a user-defined struct
H. S. Teoh: This means that the hash of MyKey is computed based on its binary representation, disregarding the contents of any array (and other reference) fields. This will certainly break AA's. I'm almost certain this has already been reported as a bug, but I vaguely remember someone mentioning a while back that this is supposed to have been fixed. But I still get the above problem in DMD git HEAD. :-( It needs to be fixed. (Or the code should not compile). Bye, bearophile
Re: How do I obtain the default hash of a user-defined struct
On Fri, Apr 04, 2014 at 04:48:52PM +, dnspies wrote: > On Thursday, 3 April 2014 at 23:01:27 UTC, Steven Schveighoffer wrote: > >On Thu, 03 Apr 2014 17:42:16 -0400, bearophile > >wrote: > > > > > >>I have filed this big problem four years ago or more. > > > >Bug report? > > > >-Steve > > This is the closest I could find: > > https://d.puremagic.com/issues/show_bug.cgi?id=11025 > > Here's a couple other related bugs: > > https://d.puremagic.com/issues/show_bug.cgi?id=12516 > > https://d.puremagic.com/issues/show_bug.cgi?id=10374 > > https://d.puremagic.com/issues/show_bug.cgi?id=1926 I just found this related issue: import std.stdio; struct MyKey { int a; char[] b; } void main() { auto key1 = MyKey(1, "abc".dup); writefln("key1 hash = %x", typeid(typeof(key1)).getHash(&key1)); char[] sneaky = "def".dup; key1.b[] = sneaky[]; // N.B.: change array contents, keep same pointer writefln("key1 hash = %x", typeid(typeof(key1)).getHash(&key1)); } Output: key1 hash = 6cba62173367a870 key1 hash = 6cba62173367a870 This means that the hash of MyKey is computed based on its binary representation, disregarding the contents of any array (and other reference) fields. This will certainly break AA's. I'm almost certain this has already been reported as a bug, but I vaguely remember someone mentioning a while back that this is supposed to have been fixed. But I still get the above problem in DMD git HEAD. :-( T -- GEEK = Gatherer of Extremely Enlightening Knowledge
Re: How do I obtain the default hash of a user-defined struct
On Thursday, 3 April 2014 at 23:01:27 UTC, Steven Schveighoffer wrote: On Thu, 03 Apr 2014 17:42:16 -0400, bearophile wrote: I have filed this big problem four years ago or more. Bug report? -Steve This is the closest I could find: https://d.puremagic.com/issues/show_bug.cgi?id=11025 Here's a couple other related bugs: https://d.puremagic.com/issues/show_bug.cgi?id=12516 https://d.puremagic.com/issues/show_bug.cgi?id=10374 https://d.puremagic.com/issues/show_bug.cgi?id=1926
Re: Why defining alias and not auto when using a template?
On Friday, 4 April 2014 at 13:23:48 UTC, Bienlein wrote: Hello, I took some code snippet from some sample D code and modified it a bit: template TCopy(T, V) { private int i = 2; void copy(out T to, out V to2, T from) { to = from; to2 = from; writeln("i: ", i); } } void main(string[] args) { int x = 2; int y = 2; alias myCopy = TCopy!(int, int); myCopy.copy(x, y, 37); writeln("x: ", x, " y: ", y); } My question is now why I have to declare and alias as in alias myCopy = TCopy!(int, int); If I define auto instead of alias, it does not compile. My question is why defining auto does not work. I would consider this more intuitive. Thanks, Bienlein When you type TCopy!(int, int) you are not creating an expression with a return variable. TCopy!(int, int) has no return variable so auto can't work(What would be the return value?). All TCopy is, is a compile time container that contains a variable i and a method copy. It contains no return value, hence auto can't work. Now, TCopy!(int, int).i or TCopy!(int, int).copy are "things" that are in the template that can be used. About the only thing you could do is use an eponymous template like template TCopy(T, V) { private int i = 2; void copy(out T to, out V to2, T from) { to = from; to2 = from; writeln("i: ", i); } T TCopy() { return null; } } then auto x = TCopy!(int, int)(someTvalue); then x would be of type T, the return value of the TCopy function(not the template because it doesn't have a return value).
Re: porting GCC macro to D
You can hack around that limitation if it's acceptable to use a temporary variable: sure, and i can rewrite the whole call, passing destination variable as template argument. but this looks ugly. thanx for the answer anyway (and bearophile too). Unfortunately, you cannot use template mixins for this, because they can only contain declarations, not statements. yes, i found that hard way — with experiments. it's a pity, i think.
Re: porting GCC macro to D
On Friday, 4 April 2014 at 13:22:39 UTC, ketmar wrote: i have some C code like this: void func0 (void) { … } int func1 (void) { … return smth+42; } #define MYMACRO() ({ func0(); func1(); }) int v; … v = MYMACRO()-16; v = mixin(MYMACRO())-16; and have the same effect as in C code: all MYMACRO content (this can be almost anything) *always* inlined. the only thing i was able to think out is to generate nested functions with immediate call in MYMACRO, but it will not guarantee inlining (i.e. i must trust compiler intellgence here). You can hack around that limitation if it's acceptable to use a temporary variable: enum MYMACRO(alias output) = `func0(); ` ~ output.stringof ~ ` = func1();`; ... int a; mixin(MYMACRO!a); v = a - 16; This uses the new enum template syntax available in current DMD, alternatively use: template MYMACRO(alias output) { enum MYMACRO = ...; } Unfortunately, you cannot use template mixins for this, because they can only contain declarations, not statements.
Re: How to hand in a closure variable
Bienlein: What I was actually looking for was how to get this to work: immutable int b = if(1 == 1) { return 123; } else { return 456; }; immutable b = (1 == 1) ? 123 : 456; Bye, bearophile
Re: How to hand in a closure variable
On Friday, 4 April 2014 at 13:53:33 UTC, bearophile wrote: If your D function has one argument, you have to give it one argument, even if it doesn't have a visible name and it's unused. Ah! Admittedly, I though it's the return type .. So this works now: immutable int b = () { if(1 == 1) { return 123; } else { return 456; } }(); What I was actually looking for was how to get this to work: immutable int b = if(1 == 1) { return 123; } else { return 456; }; But I'm happy enough with the solution through a delegate.
Re: Why defining alias and not auto when using a template?
On Fri, 04 Apr 2014 09:35:57 -0400, Bienlein wrote: "auto" is used to declare an instance, or an object. "alias" is used to declare a name. What you are currently doing is saying "the function TCopy!(int, int) can now be refered to as myCopy". You aren't actually creating any data. All right, thanks. Then I create an instance: auto myCopy = new TCopy!(int, int); alias myCopy = new TCopy!(int, int); Neither nor compiles now. How can? Seems to me a template is not a class in that sense ?! A template is not a structure or class, it is a template. It's basically lexically checked, but not semantically. Once you define it's types and parameters, then the compiler basically substitutes those in, and compiles the result. Note that a class template: class C(T) { } is short for this: template C(T) { class C { } } -Steve
Re: How to hand in a closure variable
Bienlein: Whereas this does not compile: immutable int b = (int) { if(1 == 1) { return 123; } else { return 456; } }(); // line x However, this does compile and displays correctly 123: immutable int b = (int) { if(1 == 1) { return 123; } else { return 456; } }(1); // line y writeln(b); Note it says () in line x and (1) in line y. The (1) in line y is redundant, but the stuff then compiles. If your D function has one argument, you have to give it one argument, even if it doesn't have a visible name and it's unused. Bye, bearophile
Re: Why defining alias and not auto when using a template?
On Friday, 4 April 2014 at 13:23:48 UTC, Bienlein wrote: template TCopy(T, V) { [...] } On Friday, 4 April 2014 at 13:35:58 UTC, Bienlein wrote: auto myCopy = new TCopy!(int, int); alias myCopy = new TCopy!(int, int); Neither nor compiles now. How can? Seems to me a template is not a class in that sense ?! Templates are not classes, yes. You can make a class template: class TCopy(T, V) {...} The template instance TCopy!(int, int) then is a class type which can be newed, etc. The same works with structs, functions, interfaces. Add some (template) parameters and it becomes a template that instantiates to the corresponding entity.
Re: How to hand in a closure variable
Thanks so far. I have another one, though. Not trying to tease people, I really don't know ;-). This compiles and runs: immutable int a = (int val) { if(1 == 1) { return val; } else { return 456; } }(123); writeln(a); Whereas this does not compile: immutable int b = (int) { if(1 == 1) { return 123; } else { return 456; } }(); // line x However, this does compile and displays correctly 123: immutable int b = (int) { if(1 == 1) { return 123; } else { return 456; } }(1); // line y writeln(b); Note it says () in line x and (1) in line y. The (1) in line y is redundant, but the stuff then compiles.
Re: When this will be freed?
On Fri, 04 Apr 2014 09:25:49 -0400, Marc Schütz wrote: On Wednesday, 2 April 2014 at 16:51:57 UTC, Benjamin Thaut wrote: Am 02.04.2014 17:57, schrieb Andrea Fontana: I mean: if it is an exported function (of a shared library) what happens? There's no reference kept anywhere (in D). So if I'm right it could be freed immediatly by GC. Right? If you pass that string to a C function, there is a reference on the stack. So this string will not be freed until that C-function returns. If that C-Function returns, it is very likely however that this was the only reference and the string will be freed the next time the garbage collector runs. This is unfortunately only true on x86 32-bit. For x86_64, the calling conventions (MS, SysV [1]) say that the first few parameters are passed in registers, and the same is probably true for other architectures. Usually this is still safe, as the pointer will normally either stay in its register, or will be spilled to the stack and kept there as long as the function still needs to use it. But one might imagine a corner case where it temporarily stores the pointer in a global or static variable. Even if the pointer will not be kept by the C function longer than the call, in such cases you would need to keep an additional reference where the GC can see it. In cases where it is stored in global data, and that becomes the only reference, or if a C heap allocation is made, and the pointer is stored in there (perhaps to pass to another C function?), then it's quite possible the data could be collected prematurely in another thread. You bring up a good point. This is something that should be considered when calling extern(C) functions. -Steve
Re: Why defining alias and not auto when using a template?
"auto" is used to declare an instance, or an object. "alias" is used to declare a name. What you are currently doing is saying "the function TCopy!(int, int) can now be refered to as myCopy". You aren't actually creating any data. All right, thanks. Then I create an instance: auto myCopy = new TCopy!(int, int); alias myCopy = new TCopy!(int, int); Neither nor compiles now. How can? Seems to me a template is not a class in that sense ?!
Re: porting GCC macro to D
ketmar: and have the same effect as in C code: all MYMACRO content (this can be almost anything) *always* inlined. Define a function. And in D there is no way to require a sure inline. Some people have asked for a __forceinline but Andrei&Walter don't seem sufficiently interested. Bye, bearophile
Re: Why defining alias and not auto when using a template?
On Friday, 4 April 2014 at 13:23:48 UTC, Bienlein wrote: Hello, I took some code snippet from some sample D code and modified it a bit: template TCopy(T, V) { private int i = 2; void copy(out T to, out V to2, T from) { to = from; to2 = from; writeln("i: ", i); } } void main(string[] args) { int x = 2; int y = 2; alias myCopy = TCopy!(int, int); myCopy.copy(x, y, 37); writeln("x: ", x, " y: ", y); } My question is now why I have to declare and alias as in alias myCopy = TCopy!(int, int); If I define auto instead of alias, it does not compile. My question is why defining auto does not work. I would consider this more intuitive. Thanks, Bienlein "auto" is used to declare an instance, or an object. "alias" is used to declare a name. What you are currently doing is saying "the function TCopy!(int, int) can now be refered to as myCopy". You aren't actually creating any data.
Re: When this will be freed?
On Wednesday, 2 April 2014 at 16:51:57 UTC, Benjamin Thaut wrote: Am 02.04.2014 17:57, schrieb Andrea Fontana: I mean: if it is an exported function (of a shared library) what happens? There's no reference kept anywhere (in D). So if I'm right it could be freed immediatly by GC. Right? If you pass that string to a C function, there is a reference on the stack. So this string will not be freed until that C-function returns. If that C-Function returns, it is very likely however that this was the only reference and the string will be freed the next time the garbage collector runs. This is unfortunately only true on x86 32-bit. For x86_64, the calling conventions (MS, SysV [1]) say that the first few parameters are passed in registers, and the same is probably true for other architectures. Usually this is still safe, as the pointer will normally either stay in its register, or will be spilled to the stack and kept there as long as the function still needs to use it. But one might imagine a corner case where it temporarily stores the pointer in a global or static variable. Even if the pointer will not be kept by the C function longer than the call, in such cases you would need to keep an additional reference where the GC can see it. [1] https://en.wikipedia.org/wiki/X86_calling_conventions#x86-64_calling_conventions
Re: Extracting Params of Templated Type
On Friday, 4 April 2014 at 07:23:51 UTC, Andrej Mitrovic wrote: On 4/4/14, Meta wrote: alias TemplateArgs(T: Foo!U, U) = U; It's also in std.traits, TemplateArgsOf, which is more complete. I thought I remembered that being in std.traits, but I couldn't find it after quickly skimming. I must've glanced over it.
Why defining alias and not auto when using a template?
Hello, I took some code snippet from some sample D code and modified it a bit: template TCopy(T, V) { private int i = 2; void copy(out T to, out V to2, T from) { to = from; to2 = from; writeln("i: ", i); } } void main(string[] args) { int x = 2; int y = 2; alias myCopy = TCopy!(int, int); myCopy.copy(x, y, 37); writeln("x: ", x, " y: ", y); } My question is now why I have to declare and alias as in alias myCopy = TCopy!(int, int); If I define auto instead of alias, it does not compile. My question is why defining auto does not work. I would consider this more intuitive. Thanks, Bienlein
porting GCC macro to D
i have some C code like this: void func0 (void) { … } int func1 (void) { … return smth+42; } #define MYMACRO() ({ func0(); func1(); }) int v; … v = MYMACRO()-16; what it does? it uses GCC extension "statement expression" which allows to place almost arbitrary C operator block inside any expression. result of evaluating this "operator block" will be value of the last operator in it (return value of func1() in my case). this block can contain ifs, switches, local vars, local function declarations and so on. in D we have no "statement expressions" in this form, afaik, and comma operator is very limited (and will be deprecated anyway). how can i reproduce such thing in D? i.e. i want to write something like: v = mixin(MYMACRO())-16; and have the same effect as in C code: all MYMACRO content (this can be almost anything) *always* inlined. the only thing i was able to think out is to generate nested functions with immediate call in MYMACRO, but it will not guarantee inlining (i.e. i must trust compiler intellgence here).
Re: How can I specify a location to write the code coverage files generated with '-cov'?
On Friday, 4 April 2014 at 08:52:09 UTC, Daniel Murphy wrote: On Friday, 4 April 2014 at 04:10:51 UTC, Saurabh Das wrote: Hello, Say I compile a program with: dmd -unittest -debug -cov test.d Then, when I run ./test, a file 'test.lst' is generated in the current working directory. Is there a way in which I can instruct the file to be created in a separate './cov_log/' directory? Thanks, Saurabh You actually can do this, through the hidden rt.cover api: extern (C) void dmd_coverSourcePath( string pathname ); extern (C) void dmd_coverDestPath( string pathname ); That is perfect! Many many thanks! Add these prototypes to your code and use them to override the default coverage paths. Saurabh
Re: How can I specify a location to write the code coverage files generated with '-cov'?
On Friday, 4 April 2014 at 04:10:51 UTC, Saurabh Das wrote: Hello, Say I compile a program with: dmd -unittest -debug -cov test.d Then, when I run ./test, a file 'test.lst' is generated in the current working directory. Is there a way in which I can instruct the file to be created in a separate './cov_log/' directory? Thanks, Saurabh You actually can do this, through the hidden rt.cover api: extern (C) void dmd_coverSourcePath( string pathname ); extern (C) void dmd_coverDestPath( string pathname ); Add these prototypes to your code and use them to override the default coverage paths.
Re: Extracting Params of Templated Type
On 4/4/14, Meta wrote: > alias TemplateArgs(T: Foo!U, U) = U; It's also in std.traits, TemplateArgsOf, which is more complete.