Re: What's the rationale here? alias this and function arguments
On Tuesday, 10 March 2015 at 10:36:21 UTC, ketmar wrote: On Tue, 10 Mar 2015 10:27:13 +, John Colvin wrote: struct S { int a; this(T)(T v) { this = v; } void foo(T)(T v) { import std.conv : to; a = v.to!int; } alias foo this; } void bar(S s){} void main() { S s0; s0 = 3; //OK S s = 3; //OK bar(3); //Not OK } It would seem logical that the last one would work as well. What's the reasoning behind this? autoconversion for function arguments can lead to bug-ridden code, and is a perfect way to disaster. besides, it's ambiguous. let's imagine that we have struct `S1`, which can be created from string too, and overload of `bar` as `void bar (S1 s)`. what `bar` compiler should choose for `bar (3)`? Ah yep, overloading, that was it. I have the feeling i've asked this before and someone else explained it to me but I had forgotten. Cheers
Re: How to use UFCS and std.algorithm.sort?
Thanks a lot! Kind regards André On Tuesday, 10 March 2015 at 08:40:28 UTC, Jonathan M Davis wrote: On Tuesday, March 10, 2015 07:24:52 Andre via Digitalmars-d-learn wrote: Hi, with the new beta I get the warning I should use std.algorithm.sort instead the .sort property. I thought the std.algorithm.sort method is used in this example? void main() { import std.algorithm: sort, uniq, map; import std.array: array; string[] arr = [A,B,B,C]; string[] result = arr .map!(n = n) // minified .array .sort .uniq .array; } I want to use the sort template with the default less a b without specifying !(a b) .sort on an array is going to use the built-in sort property. You need to use parens if you want to use the function in std.algorithm with an array and UFCS, e.g. arr.sort(); - Jonathan M Davis
What's the rationale here? alias this and function arguments
struct S { int a; this(T)(T v) { this = v; } void foo(T)(T v) { import std.conv : to; a = v.to!int; } alias foo this; } void bar(S s){} void main() { S s0; s0 = 3; //OK S s = 3; //OK bar(3); //Not OK } It would seem logical that the last one would work as well. What's the reasoning behind this?
Re: What's the rationale here? alias this and function arguments
On Tue, 10 Mar 2015 10:27:13 +, John Colvin wrote: struct S { int a; this(T)(T v) { this = v; } void foo(T)(T v) { import std.conv : to; a = v.to!int; } alias foo this; } void bar(S s){} void main() { S s0; s0 = 3; //OK S s = 3; //OK bar(3); //Not OK } It would seem logical that the last one would work as well. What's the reasoning behind this? autoconversion for function arguments can lead to bug-ridden code, and is a perfect way to disaster. besides, it's ambiguous. let's imagine that we have struct `S1`, which can be created from string too, and overload of `bar` as `void bar (S1 s)`. what `bar` compiler should choose for `bar (3)`? so compiler doesn't try to guess how to convert your function argument from valid constructor args to structs. this decreases the change to introduce a hard-to-detect bugs with implicit construction, and also increases the readability (imagine surprised reader that sees `bar(3)` in the code, but no `bar` overload that accepts string). C++ tries to be smart here, and fails. D doesn't try to be smart, as it's not a compiler work to guess what you meant. signature.asc Description: PGP signature
Re: What's the rationale here? alias this and function arguments
On Tuesday, 10 March 2015 at 10:27:14 UTC, John Colvin wrote: struct S { int a; this(T)(T v) { this = v; } void foo(T)(T v) { import std.conv : to; a = v.to!int; } alias foo this; } void bar(S s){} void main() { S s0; s0 = 3; //OK S s = 3; //OK bar(3); //Not OK } It would seem logical that the last one would work as well. What's the reasoning behind this? Do you think that the parameter should be automatically created from the argument ? Is this kind of thing even possible in another context ? Your alias looks more like an ```opCall()```. To my eyes the strange thing is that if you add the following statement at the end of you sample: --- s(0); --- DMD outputs: ```Error: cannot resolve type for s.foo(T)(T v)```
Re: Derelict Assimp not loading mesh properly? (Maybe index buffer)
On Monday, 9 March 2015 at 14:25:54 UTC, Michael Robertson wrote: On Friday, 6 March 2015 at 02:41:19 UTC, Bennet wrote: I wrote a custom OBJ file importer which worked fairly well however was not robust enough to support everything. I've decided to give AssImp a shot. I followed some tutorials and have set up my code to read in the vertices, tex coords, normals, and indices of an OBJ cube model that I have had success loading with my custom importer. The cube model's faces do not render properly, instead only rendering a few tri's of the cube. The way AssImp handles the data is obviously a bit different than my solution because the normals, positions/vertices, tex coords, and indices do not match my custom solution. I would very much appreciate some insight into why I'm having issues as all of the tutorials I've found have matched my approach. If a picture of the faulty rendered cube would be helpful I can work on getting a screenshot up. Thank you. My Asset importing class is at: http://codebin.org/view/4d2ec4d3 The rest of my code is at (Mesh Class is in source/graphics): https://github.com/BennetLeff/PhySim Imagine a square mesh made up of two triangles, the un-indexed version has 6 vertices, but the indexed version that you would be using has 4 vertices because a side is shared by the two triangles (which is managed by the index array). This is why you can't assume each face has 3 vertices. I have been trying to learn opengl and D recently together and this is the simple code I have been using to load models from assimp. for(int i = 0; i mesh.mNumVertices; i++) { aiVector3D vert = mesh.mVertices[i]; verts ~= vec3(vert.x, vert.y, vert.z); aiVector3D uvw = mesh.mTextureCoords[0][i]; uvs ~= vec2(uvw.x, uvw.y); aiVector3D n = mesh.mNormals[i]; normals ~= vec3(n.x, n.y, n.z); } for(int i = 0; i mesh.mNumFaces; i++) { const aiFace face = mesh.mFaces[i]; indices ~= face.mIndices[0]; indices ~= face.mIndices[1]; indices ~= face.mIndices[2]; } My code roughly matches yours at this point however I get a weird bug with only my cube model where the top face and one of the side tri's are not rendered. However it seems to work fine with a model of a pitcher and a model of a monkey.
Re: 2.067 Beta: Behavior of enum and ref changed
Thanks a lot! Kind regards André On Tuesday, 10 March 2015 at 09:25:02 UTC, Meta wrote: On Tuesday, 10 March 2015 at 08:37:46 UTC, Jonathan M Davis wrote: It's the base type that isn't implicitly convertible to the enum type. Err, yes. I had that the wrong way around. Anyway, I filed an issue. https://issues.dlang.org/show_bug.cgi?id=14269
Re: Parallelization of a large array
On Tuesday, 10 March 2015 at 22:37:29 UTC, Ali Çehreli wrote: On 03/10/2015 03:16 PM, Meta wrote: Just add a condition variable. import std.stdio; import std.algorithm; import std.parallelism; void main() { int b = 2; auto a = [1, 2, 2, 3]; if (find(a, b).length != 0) writeln(Yes_); auto found = false; foreach (elem; a.parallel) if (!found elem == b) { writeln(Yes); found = true; I thought about the same solution but then realized that it's a race condition, which needs to be taken care of. It's true that the value always changes from false to true but still... } } Ali Yes, it's a non-deterministic solution, but I don't think it matters all that much as we don't care which element fulfills the criterion, just that such an element exists. That's my reasoning, anyway. I know next to nothing about parallel processing.
Re: is eC alot like D?
On 11/03/2015 4:16 p.m., Taylor Hillegeist wrote: So I found http://ec-lang.org/ it seems alot like D, But it has a company backing it. It just seems interesting. There is almost no meta programming support. Let alone CTFE. And no generics in the form of e.g. Java's is not the same as D's meta-programming support.
Re: New package behaviour in 2.067
Looks like bug, investigating.
Re: New package behaviour in 2.067
https://issues.dlang.org/show_bug.cgi?id=14275
Re: 2.067 Beta: Behavior of enum and ref changed
On 03/10/2015 01:37 AM, Jonathan M Davis via Digitalmars-d-learn wrote: However, the code in question still shouldn't compile because while a Bits variable may be implicitly convertible to ulong, it _isn't_ a ulong, In other words, the result of the implicit conversion is an rvalue, created on the spot, not the actual lvalue. References cannot be bound to rvalues. Ali
is eC alot like D?
So I found http://ec-lang.org/ it seems alot like D, But it has a company backing it. It just seems interesting.
Re: is eC alot like D?
On Wednesday, 11 March 2015 at 03:55:21 UTC, Rikki Cattermole wrote: On 11/03/2015 4:16 p.m., Taylor Hillegeist wrote: So I found http://ec-lang.org/ it seems alot like D, But it has a company backing it. It just seems interesting. There is almost no meta programming support. Let alone CTFE. And no generics in the form of e.g. Java's is not the same as D's meta-programming support. Yes, D is a very powerful language with a boatload of features. eC almost seems like a subset. but what I find fascinating is the infrastructure built around it. Of course when someone's full time job is to build infrastructure, I tends to happen more predictably. But like all things in life you have to take the good, and carry it with you into the future. I bet there is alot we can learn from eC. I wonder how compatible the two languages are, I have been experimenting with language to language porting techniques, every language is in similar in some way to another, but to varying degrees.
Re: How does laziness and UFCS interact?
On Monday, 9 March 2015 at 22:15:43 UTC, Ali Çehreli wrote: You are right. I had the same observation at minute 11:27 below, where I warn against UFCS with assumeWontThrow: http://www.youtube.com/watch?feature=player_detailpagev=oF8K4-bieaw#t=687 Ali Sorry, which is right? I know ifThrown is lazy, I'm curious about the amount of the expression that is evaluated lazily. a.b().c().assumeWontThrow vs. a.b().c().assumeWontThrow ^--+^^-^ | | +- lazy? +- lazy? The video seems to say don't use lazy functions with UFCS because you might think the lazy part gets evaluated first, when it does not. Seems reasonable, although I don't know it's any different than assumeWontThrow(f()).
Re: How does laziness and UFCS interact?
On Tuesday, 10 March 2015 at 14:41:00 UTC, Logan Capaldo wrote: On Monday, 9 March 2015 at 22:15:43 UTC, Ali Çehreli wrote: You are right. I had the same observation at minute 11:27 below, where I warn against UFCS with assumeWontThrow: http://www.youtube.com/watch?feature=player_detailpagev=oF8K4-bieaw#t=687 Ali Sorry, which is right? I know ifThrown is lazy, I'm curious about the amount of the expression that is evaluated lazily. a.b().c().assumeWontThrow vs. a.b().c().assumeWontThrow ^--+^^-^ | | +- lazy? +- lazy? The video seems to say don't use lazy functions with UFCS because you might think the lazy part gets evaluated first, when it does not. Seems reasonable, although I don't know it's any different than assumeWontThrow(f()). a.b().c().assumeWontThrow is rewritten as assumeWontThrow(a.b().c()) and therefore the whole chain is lazy.
Re: 2.067 Beta: Behavior of enum and ref changed
On 03/10/2015 11:05 AM, Ali Çehreli wrote: In other words, the result of the implicit conversion is an rvalue Steven Schveighoffer says there is no rvalue in this case; an enum is a derivative: https://issues.dlang.org/show_bug.cgi?id=14269#c14 Ali
Parallelization of a large array
Hi. How to parallelize a large array to check for the presence of an element matching the value with the data? std.stdio; std.algorithm; std.parallelism; void main() { int[] a = new int[100]; foreach (i, ref elem; a) elem = i; /*if (find(parallel(a), 895639).length != 0) writeln(Yes); else writeln(No);*/ }
expand variadic template parameters
Hi, in this minified example I try to expand the variadic parmaters of foo to bar: import std.typecons; void foo(T ...)(T args) { bar(args.expand); } void bar(int i, string s){} void main() { foo(1, a); } I got the syntax error: no property 'expand' for type '(int, string)' I understand args is a TypeTuple and therefore expand is not working. Is there a simple way to get it working? Kind regards André
Re: expand variadic template parameters
On Tuesday, 10 March 2015 at 19:11:22 UTC, André wrote: Is there a simple way to get it working? The simplest: just write `bar(args);` - the variadic arguments will automatically expand.
Re: expand variadic template parameters
On Tue, 10 Mar 2015 19:11:21 +, André wrote: Hi, in this minified example I try to expand the variadic parmaters of foo to bar: import std.typecons; void foo(T ...)(T args) { bar(args.expand); } void bar(int i, string s){} void main() { foo(1, a); } I got the syntax error: no property 'expand' for type '(int, string)' I understand args is a TypeTuple and therefore expand is not working. Is there a simple way to get it working? sure. just remove `.expand`. ;-) void foo(T...) (T args) { bar(args); } signature.asc Description: PGP signature
Re: expand variadic template parameters
too many trees in front of my eyes. Thanks for the answers. Kind regards André On Tuesday, 10 March 2015 at 19:16:23 UTC, Adam D. Ruppe wrote: On Tuesday, 10 March 2015 at 19:11:22 UTC, André wrote: Is there a simple way to get it working? The simplest: just write `bar(args);` - the variadic arguments will automatically expand.
Re: How to use UFCS and std.algorithm.sort?
.array .sort buildin arrays have a .sort-property that is called.
2.067 Beta: Behavior of enum and ref changed
Hi, following coding raises a compiler error with the beta of 2.067. Is this error intended or not? It is working if I change first line of main to: ulong bits; enum Bits: ulong { none = 0 } bool hasBit(ref ulong rBits, ulong rBit) { return cast(bool)(rBits rBit); } void main() { Bits bits; hasBit(bits, Bits.none); } function app.hasBit (ref ulong rBits, ulong rBit) is not callable using argument types (Bits, Bits) Kind regards André
How to use UFCS and std.algorithm.sort?
Hi, with the new beta I get the warning I should use std.algorithm.sort instead the .sort property. I thought the std.algorithm.sort method is used in this example? void main() { import std.algorithm: sort, uniq, map; import std.array: array; string[] arr = [A,B,B,C]; string[] result = arr .map!(n = n) // minified .array .sort .uniq .array; } I want to use the sort template with the default less a b without specifying !(a b) Kind regards André
Re: Parallelization of a large array
On Tuesday, 10 March 2015 at 20:41:14 UTC, Dennis Ritchie wrote: Hi. How to parallelize a large array to check for the presence of an element matching the value with the data? Here's a simple method (warning: has pitfalls): import std.stdio; import std.parallelism; void main() { int[] a = new int[100]; foreach (i, ref elem; a) elem = cast(int)i; bool found; foreach (elem; a.parallel) if (elem == 895639) found = true; if (found) writeln(Yes); else writeln(No); }
Re: Parallelization of a large array
On Tuesday, 10 March 2015 at 21:15:17 UTC, safety0ff wrote: On Tuesday, 10 March 2015 at 20:41:14 UTC, Dennis Ritchie wrote: Hi. How to parallelize a large array to check for the presence of an element matching the value with the data? Here's a simple method (warning: has pitfalls): import std.stdio; import std.parallelism; void main() { int[] a = new int[100]; foreach (i, ref elem; a) elem = cast(int)i; bool found; foreach (elem; a.parallel) if (elem == 895639) found = true; if (found) writeln(Yes); else writeln(No); } Thanks.
Purity not enforced for default arguments?
The following code fails to compile because unpredictableSeed is impure: void main() { foreach(i; 0..10) writeln(pureRandom); } pure uint pureRandom() { auto r = Random(unpredictableSeed); return r.front; } However, make unpredictableSeed a default argument, wrap the call in another pure function, and it compiles: void main() { foreach(i; 0..10) writeln(pureRandom2); } pure uint pureRandom2() { return pureRandom; } pure uint pureRandom(uint seed = unpredictableSeed) { auto r = Random(seed); return r.front; } I'm inclined to believe this is a bug. While pureRandom could be considered weakly pure, pureRandom2 has no arguments so it should be strongly pure. Yet, it yields a different value on every call.
Re: Purity not enforced for default arguments?
On Tuesday, 10 March 2015 at 21:56:39 UTC, Xinok wrote: I'm inclined to believe this is a bug. https://issues.dlang.org/show_bug.cgi?id=11048
Re: Parallelization of a large array
On Tuesday, 10 March 2015 at 22:11:57 UTC, Dennis Ritchie wrote: No, it does not suit me, because of the parallel array in a foreach loop there is no break. I already understood everything: found = true;
Re: Parallelization of a large array
On Tuesday, 10 March 2015 at 21:27:42 UTC, Dennis Ritchie wrote: Thanks. No, it does not suit me, because of the parallel array in a foreach loop there is no break. import std.stdio; import std.algorithm; import std.parallelism; void main() { int b = 2; auto a = [1, 2, 2, 3]; if (find(a, b).length != 0) writeln(Yes_); foreach (elem; a.parallel) if (elem == b) writeln(Yes); // prints Yes twice }
Re: Parallelization of a large array
On Tuesday, 10 March 2015 at 20:41:14 UTC, Dennis Ritchie wrote: Hi. How to parallelize a large array to check for the presence of an element matching the value with the data? std.stdio; std.algorithm; std.parallelism; You forgot a couple imports here. void main() { int[] a = new int[100]; foreach (i, ref elem; a) elem = i; Type mismatch here. i is a size_t, but elem is an int. /*if (find(parallel(a), 895639).length != 0) writeln(Yes); else writeln(No);*/ } I guess you'd have to write your own find. Since std.algorithm.find is just linear search, that shouldn't be hard. Something like this: bool found = false; foreach(x; parallel(a)) { if(x == 895639) { found = true; /* Maybe figure out how to break all parallel loops. */ } } std.algorithm.find would work on mere input ranges, and it would return the tail of the range and not just a bool. Both of those don't make sense with a parallel search, though. Also, with a trivial predicate like integer equality, parallelization might not buy you anything.
Re: expand variadic template parameters
On Tuesday, 10 March 2015 at 19:11:22 UTC, André wrote: Hi, in this minified example I try to expand the variadic parmaters of foo to bar: import std.typecons; void foo(T ...)(T args) { bar(args.expand); } void bar(int i, string s){} void main() { foo(1, a); } I got the syntax error: no property 'expand' for type '(int, string)' I understand args is a TypeTuple and therefore expand is not working. Is there a simple way to get it working? Kind regards André Just to be clear, TypeTuple is a library construct defined in std.typetuple. It doesn't have a .expand member as far as I know. You're probably thinking of tuple.expand. The type of `T ...` is not TypeTuple, but an internal tuple type used by the compiler. TypeTuple is just some syntactic sugar allowing you to create one of these compiler tuples.
Re: Purity not enforced for default arguments?
On Tuesday, 10 March 2015 at 22:00:29 UTC, safety0ff wrote: On Tuesday, 10 March 2015 at 21:56:39 UTC, Xinok wrote: I'm inclined to believe this is a bug. https://issues.dlang.org/show_bug.cgi?id=11048 Thanks for the link, and I didn't mean to post this in D.learn. .
Re: Parallelization of a large array
On Tuesday, 10 March 2015 at 22:11:57 UTC, Dennis Ritchie wrote: On Tuesday, 10 March 2015 at 21:27:42 UTC, Dennis Ritchie wrote: Thanks. No, it does not suit me, because of the parallel array in a foreach loop there is no break. import std.stdio; import std.algorithm; import std.parallelism; void main() { int b = 2; auto a = [1, 2, 2, 3]; if (find(a, b).length != 0) writeln(Yes_); foreach (elem; a.parallel) if (elem == b) writeln(Yes); // prints Yes twice } Just add a condition variable. import std.stdio; import std.algorithm; import std.parallelism; void main() { int b = 2; auto a = [1, 2, 2, 3]; if (find(a, b).length != 0) writeln(Yes_); auto found = false; foreach (elem; a.parallel) if (!found elem == b) { writeln(Yes); found = true; } } This program pints: Yes_ Yes
Re: Parallelization of a large array
On 03/10/2015 01:41 PM, Dennis Ritchie wrote: Hi. How to parallelize a large array to check for the presence of an element matching the value with the data? std.stdio; std.algorithm; std.parallelism; void main() { int[] a = new int[100]; foreach (i, ref elem; a) elem = i; /*if (find(parallel(a), 895639).length != 0) writeln(Yes); else writeln(No);*/ } It is possible by accessing the actual range by chunks: import std.stdio; import std.algorithm; import std.parallelism; import std.range; import std.conv; void main() { const size_t elementCount = 895640; int[] a = iota(elementCount) .map!(i = i.to!int) .array; const chunkSize = a.length / taskPool.size; auto chunks = a.chunks(chunkSize); bool[] results = chunks.taskPool.map!(chunk = chunk.canFind(895639)); writeln(results.canFind(true) ? Yes : No); } We can hope to make it simpler by taking advantage of parallel map but it requires a static local function or a global function (a lambda cannot be used): static bool canFindIt(Range)(Range range) { return range.canFind(895639); } auto results = taskPool.map!canFindIt(chunks); Ali
Re: Parallelization of a large array
On Tuesday, 10 March 2015 at 22:43:08 UTC, Ali Çehreli wrote: The following is the program that does NOT use taskPool.map. I am also changing the name of a variable because the local 'chunks' looked like std.range.chunks. import std.stdio; import std.algorithm; import std.parallelism; import std.range; import std.conv; void main() { const size_t elementCount = 895640; int[] a = iota(elementCount) .map!(i = i.to!int) .array; const chunkSize = a.length / taskPool.size; auto ch = a.chunks(chunkSize); bool[] results = new bool[ch.length]; foreach (i, chunk; ch.parallel) { results[i] = chunk.canFind(895639); } writeln(results.canFind(true) ? Yes : No); } Thanks. This code will help me.
New package behaviour in 2.067
I'm unsure, but I think this code should work: module A.B.Foo; import core.stdc.stdio : printf; struct Foo { package(A) void foo() { printf(Hallo\n); } } package(A) void bar() { printf(Hallo\n); } and module A.C.Bar; import A.B.Foo; void main() { Foo f; f.foo(); bar(); } The call of bar() works, but f.foo() triggers the error: Error: struct A.B.Foo.Foo member foo is not accessible Is this intended?
Re: Parallelization of a large array
On Tuesday, 10 March 2015 at 22:34:34 UTC, Ali Çehreli wrote: It is possible by accessing the actual range by chunks: import std.stdio; import std.algorithm; import std.parallelism; import std.range; import std.conv; void main() { const size_t elementCount = 895640; int[] a = iota(elementCount) .map!(i = i.to!int) .array; const chunkSize = a.length / taskPool.size; auto chunks = a.chunks(chunkSize); bool[] results = chunks.taskPool.map!(chunk = chunk.canFind(895639)); writeln(results.canFind(true) ? Yes : No); } We can hope to make it simpler by taking advantage of parallel map but it requires a static local function or a global function (a lambda cannot be used): static bool canFindIt(Range)(Range range) { return range.canFind(895639); } auto results = taskPool.map!canFindIt(chunks); Thanks.
Re: Parallelization of a large array
On 03/10/2015 03:16 PM, Meta wrote: Just add a condition variable. import std.stdio; import std.algorithm; import std.parallelism; void main() { int b = 2; auto a = [1, 2, 2, 3]; if (find(a, b).length != 0) writeln(Yes_); auto found = false; foreach (elem; a.parallel) if (!found elem == b) { writeln(Yes); found = true; I thought about the same solution but then realized that it's a race condition, which needs to be taken care of. It's true that the value always changes from false to true but still... } } Ali
Re: Parallelization of a large array
On 03/10/2015 03:34 PM, Ali Çehreli wrote: It is possible by accessing the actual range by chunks: Sorry, I posted a jumbled program that does not compile. The following is the program that does NOT use taskPool.map. I am also changing the name of a variable because the local 'chunks' looked like std.range.chunks. import std.stdio; import std.algorithm; import std.parallelism; import std.range; import std.conv; void main() { const size_t elementCount = 895640; int[] a = iota(elementCount) .map!(i = i.to!int) .array; const chunkSize = a.length / taskPool.size; auto ch = a.chunks(chunkSize); bool[] results = new bool[ch.length]; foreach (i, chunk; ch.parallel) { results[i] = chunk.canFind(895639); } writeln(results.canFind(true) ? Yes : No); } Ali
Re: How does laziness and UFCS interact?
On Tuesday, 10 March 2015 at 17:42:37 UTC, Ali Çehreli wrote: You are right again. :) However, putting the lazy-taking function outside the whole expression makes it visible right away, making easy for me to realize that the execution order may be different from common chains. lazy aka named parameters semantically works just like macros using textual substitution. Just imagine that it is inlined in situ and it becomes clear what is happening. I believe it was the common parameter transfer mode in Algol, but programmers found it terribly confusing, so just about all languages that followed have avoided it. So if anyone gets confused, then find some comfort in knowing that people found it confusing 50 years ago too. :^)
Re: 2.067 Beta: Behavior of enum and ref changed
On Tuesday, March 10, 2015 08:19:27 Meta via Digitalmars-d-learn wrote: On Tuesday, 10 March 2015 at 07:04:48 UTC, Andre wrote: Hi, following coding raises a compiler error with the beta of 2.067. Is this error intended or not? It is working if I change first line of main to: ulong bits; enum Bits: ulong { none = 0 } bool hasBit(ref ulong rBits, ulong rBit) { return cast(bool)(rBits rBit); } void main() { Bits bits; hasBit(bits, Bits.none); } function app.hasBit (ref ulong rBits, ulong rBit) is not callable using argument types (Bits, Bits) Kind regards André It's because enums are not implicitly convertible to their base type. It was probably a compiler bug that it worked before. It's a regression however, so I'll file an issue in Bugzilla. In the meantime you can do: hasBit(cast(ulong)bits, Bits.none); Or just use a ulong as you mentioned. enums _are_ implicitly convertible to their base type. e.g. this compiles just fine void main() { enum S : string { a = hello, b = world } string s = S.a; } It's the base type that isn't implicitly convertible to the enum type. However, the code in question still shouldn't compile because while a Bits variable may be implicitly convertible to ulong, it _isn't_ a ulong, so passing it as a ref argument of type ulong isn't legal. Implicit conversions aren't used with ref. With ref, the type must match exactly. - Jonathan M Davis
Re: 2.067 Beta: Behavior of enum and ref changed
On Tuesday, 10 March 2015 at 07:04:48 UTC, Andre wrote: Hi, following coding raises a compiler error with the beta of 2.067. Is this error intended or not? It is working if I change first line of main to: ulong bits; enum Bits: ulong { none = 0 } bool hasBit(ref ulong rBits, ulong rBit) { return cast(bool)(rBits rBit); } void main() { Bits bits; hasBit(bits, Bits.none); } function app.hasBit (ref ulong rBits, ulong rBit) is not callable using argument types (Bits, Bits) Kind regards André It's because enums are not implicitly convertible to their base type. It was probably a compiler bug that it worked before. It's a regression however, so I'll file an issue in Bugzilla. In the meantime you can do: hasBit(cast(ulong)bits, Bits.none); Or just use a ulong as you mentioned.
Re: std.stdio.writeln
On Monday, March 09, 2015 22:29:23 Meta via Digitalmars-d-learn wrote: On Monday, 9 March 2015 at 22:00:46 UTC, ketmar wrote: i remember that deprecation was rejected. maybe this is false memory, though. btw, there are legit uses of comma, in c-style `for`, for example. this should be left intact, i think (oh, can c-style `for` be deprecated too?! ). I think the last time there was a big discussion about this everyone agreed that the comma operator in a for loop was acceptable. Yeah. Even Java has that. But IIRC, it was decided that the comma operator in general would be deprecated. I could be wrong though, and it's the sort of thing that could easily be decided and then not actually happen for ages (e.g. it was decided years ago that delete would be deprecated, but it still isn't). - Jonathan M Davis
Re: How to use UFCS and std.algorithm.sort?
On Tuesday, March 10, 2015 07:24:52 Andre via Digitalmars-d-learn wrote: Hi, with the new beta I get the warning I should use std.algorithm.sort instead the .sort property. I thought the std.algorithm.sort method is used in this example? void main() { import std.algorithm: sort, uniq, map; import std.array: array; string[] arr = [A,B,B,C]; string[] result = arr .map!(n = n) // minified .array .sort .uniq .array; } I want to use the sort template with the default less a b without specifying !(a b) .sort on an array is going to use the built-in sort property. You need to use parens if you want to use the function in std.algorithm with an array and UFCS, e.g. arr.sort(); - Jonathan M Davis
Re: string-int[] array
On Sunday, 8 March 2015 at 21:41:44 UTC, FG wrote: Except that with this solution you will confuse empty strings with ints. The idea was to only make it memory-safe without union.
Re: std.stdio.writeln
On Tue, 10 Mar 2015 01:31:39 -0700, Jonathan M Davis via Digitalmars-d-learn wrote: it's the sort of thing that could easily be decided and then not actually happen for ages (e.g. it was decided years ago that delete would be deprecated, but it still isn't). sometimes i'm irritated by this, but with `delete`... ah, i hope nobody will remember about for for next 20 years. signature.asc Description: PGP signature
Re: 2.067 Beta: Behavior of enum and ref changed
On Tuesday, 10 March 2015 at 08:37:46 UTC, Jonathan M Davis wrote: It's the base type that isn't implicitly convertible to the enum type. Err, yes. I had that the wrong way around. Anyway, I filed an issue. https://issues.dlang.org/show_bug.cgi?id=14269
Re: New package behaviour in 2.067
On Tue, 10 Mar 2015 23:17:01 +, Namespace wrote: Is this intended? i doubt so. `struct Foo` is definitely `public`, so there shouldn't be any problems with access rights. signature.asc Description: PGP signature
chaining splitters
Hello, I am parsing some text and I have the following; string text = some very long text; foreach(line; splitter(text, [13, 10])) { foreach(record; splitter(line, '*')) { foreach(field; splitter(record, '=')) { foreach(value; splitter(field, ',')) { // do something... } } } } I know there is a better way to do that but I'm a total D noob. Thanks!