Re: Dynamic / resizable array type, and a crash problem
On Thursday, 14 May 2015 at 13:26:27 UTC, ivoras wrote: Is it resizable? You can append with the ~= operator and size down by slicing it. Apparently it doesn't even have an insert method: http://dlang.org/phobos/std_array.html . http://dlang.org/phobos/std_array.html#insertInPlace is the one you'd use for that.
Re: Dynamic / resizable array type, and a crash problem
On Thursday, 14 May 2015 at 12:46:48 UTC, Adam D. Ruppe wrote: I would just use a regular `string[]` array... Is it resizable? Somehow I didn't get that impression from the docs. Apparently it doesn't even have an insert method: http://dlang.org/phobos/std_array.html .
Re: Dynamic / resizable array type, and a crash problem
On Thursday, 14 May 2015 at 13:26:27 UTC, ivoras wrote: On Thursday, 14 May 2015 at 12:46:48 UTC, Adam D. Ruppe wrote: I would just use a regular `string[]` array... Is it resizable? Somehow I didn't get that impression from the docs. Apparently it doesn't even have an insert method: http://dlang.org/phobos/std_array.html . string[] arr; arr ~= Foo; arr ~= Bar; writeln(arr, ':', arr.length); It's all built in. ;) A nice article: http://dlang.org/d-array-article.html and the language reference: http://dlang.org/arrays.html
Dynamic / resizable array type, and a crash problem
What is the recommended dynamic array type in D? So far I found Array (specifically Array!string, as I need a dynamic array of strings), but my example program crashes: https://gist.github.com/ivoras/2d7737c214c3dc937c28 The crash is at line 20: core.exception.AssertError@/usr/include/dmd/phobos/std/container/array.d(334): Assertion failure ./markov() [0x80fbfd1] ./markov(uint std.container.array.Array!(immutable(char)[]).Array.Payload.insertBack!(immutable(char)[]).insertBack(immutable(char)[])+0x6f) [0x80fa997] ./markov(uint std.container.array.Array!(immutable(char)[]).Array.insertBack!(immutable(char)[]).insertBack(immutable(char)[])+0x36) [0x80fa866] ./markov(_Dmain+0x167) [0x80d7ce7] This is on DMD32 D Compiler v2.067.1
Re: Returning an empty range of a given type
So I thought this might work: struct MaybeEmpty(R) if (isInputRange!R) { private bool _isEmpty; private R_input; alias _input this; this(bool isEmpty, R input) { _input = input; _isEmpty = isEmpty; } @property bool empty() { return _isEmpty || _input.empty; } } auto maybeEmpty(R)(bool empty, R input = R.init) if (isInputRange!R) { return MaybeEmpty!R(empty, input); } It's kind of ugly, but it can be used like: auto a = maybeEmpty!MyRange(true); auto b = maybeEmpty!MyRange(false, actualRange); static assert(is(typeof(a) == typeof(b))); However, it fails the input range test: static assert(isInputRange!MyRange); //pass static assert(isInputRange!(typeof(a))); // fail But it seems to be something weird with cross-module template instantiation. If I replace `import std.range` with a copy-paste of `isInputRange`, the above passes. Either that or I'm doing something stupid because I'vebeen staring at this too long. I'm wondering if the isInputRange thing is a bug, so here's a gist if anyone wants to play with it: https://gist.github.com/rcorre/7a62395c53baf3c0bfbc
Re: Dynamic / resizable array type, and a crash problem
On Thursday, 14 May 2015 at 12:42:01 UTC, ivoras wrote: https://gist.github.com/ivoras/2d7737c214c3dc937c28 The crash is at line 20: core.exception.AssertError@/usr/include/dmd/phobos/std/container/array.d(334): [...] This is on DMD32 D Compiler v2.067.1 Seems to be fixed in git head.
Re: Dynamic / resizable array type, and a crash problem
I would just use a regular `string[]` array...
Re: Cannot Qualify Variadic Functions with Lazy Arguments as nothrow
On Thursday, 14 May 2015 at 10:18:13 UTC, Maxim Fomin wrote: On Thursday, 14 May 2015 at 09:53:20 UTC, Per Nordlöw wrote: At https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L43 I've implemented a function either() with behaviour similar to the `or` function/operator in dynamic languages such as Python and Lisp. I'm almost satisified with it except that the lazy evaluation at https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L45 cannot be made nothrow. If I qualify the function as nothrow DMD complains as algorithm_ex.d(45,16): Error: 'a' is not nothrow algorithm_ex.d(46,29): Error: '_param_1' is not nothrow I don't see a reason why any of these two cases should throw. Lazy argument is essentially delegate/function. Currently there is no way to mark it as nothrow. The same problem occurs if I make the implementation use only one function and check the recursion termination case with `static if (bs.length == 1)` instead. Is there a workaround for this? One way to address is to use delegate explicitly. int foo(lazy int a) //nothrow { return a; } int bar(int delegate() nothrow dg) nothrow { return dg(); } void main() nothrow { int a; bar(()=a); } That does not feel right at all. D's filosophy is to infer these things.Are you saying that I should create to overloads for the leaf case of either(), namely one that takes a nothrow delegate as argument and another overload that handles the throw case. Further you example functions are not templates. either() must be a template. Could you please show how to modify either() to use your delegate-version instead.
Re: problem with parallel foreach
On Thursday, 14 May 2015 at 10:46:53 UTC, Gerald Jansen wrote: John Colvin's improvements to my D program seem to have resolved the problem. (http://forum.dlang.org/post/ydgmzhlspvvvrbeem...@forum.dlang.org and http://dpaste.dzfl.pl/114d5a6086b7). I have rerun my tests and now the picture is a bit different (see tables below). In the middle table I have used gnu parallel in combination with a slightly modified version of the D program which runs a single trait (specified in argv[1]). This approach runs the jobs as completely isolated processes, but at the extra cost of re-reading the common data for each trait. The elapsed time is very similar with the parallel foreach in the D program or using gnu parallel (for this particular program and these data run on this server...). I'm guessing the program is now essentially limited by disk I/O, so this is about as good as it gets. So, just to wrap up: - there is a nice speed improvement over Python program :-) - one needs to learn a fair bit to fully benefit from D's potential - thanks for all the help! Gerald Jansen Jobs __ time for D parallel foreach w. JC mods 1 4.71user 0.56system 0:05.28elapsed 99%CPU 2 6.59user 0.96system 0:05.48elapsed 137%CPU 411.45user 1.94system 0:07.24elapsed 184%CPU 820.30user 5.18system 0:13.16elapsed 193%CPU 16 68.48user 13.87system 0:27.21elapsed 302%CPU 27 99.66user 18.73system 0:42.34elapsed 279%CPU Jobs __ gnu parallel + D program for single job __ 1 4.71user 0.56system 0:05.28elapsed 99%CPU as above 2 9.66user 1.28system 0:05.76elapsed 189%CPU 418.86user 3.85system 0:08.15elapsed 278%CPU 840.76user 7.53system 0:14.69elapsed 328%CPU 16 135.76user 20.68system 0:31.06elapsed 503%CPU 27 189.43user 28.26system 0:47.75elapsed 455%CPU Jobs _ time for python version _ 145.39user 1.52system 0:46.88elapsed 100%CPU 277.76user 2.42system 0:47.16elapsed 170%CPU 4 141.28user 4.37system 0:48.77elapsed 298%CPU 8 280.45user 8.80system 0:56.00elapsed 516%CPU 16 926.05user 20.48system 1:31.36elapsed 1036%CPU 27 1329.09user 27.18system 2:11.79elapsed 1029%CPU Would it be OK if I showed some parts of this code as examples in my DConf talk in 2 weeks?
Re: Clean way to tell whether a destructor is called by the GC
On Wednesday, 13 May 2015 at 11:24:10 UTC, Kagamin wrote: On Tuesday, 12 May 2015 at 12:53:59 UTC, ponce wrote: I already have such a dispose() function. The problem is that to support Unique! and scoped! and friends, the destructor must call dispose(). Thus my need for a way to separate the GC-induced destructors within dispose() or ~this (same problem). Maybe it's simpler to copy-paste Unique and scoped and modify them to handle disposable objects? But then we would need a standardized name (some use close, some use dispose, some use release) The closest thing we have to a standardized function name is the destructor.
How to simulate a new type
What are the downsides to simulating a new type with a struct. What I have in mind is something along the lines of: struct myType { uint64_t value; } The goal of this type is to prevent accidental conversions from myType into ints, uint64_ts, etc.
Re: Cannot Qualify Variadic Functions with Lazy Arguments as nothrow
On Thursday, 14 May 2015 at 09:53:20 UTC, Per Nordlöw wrote: I'm almost satisified with it except that the lazy evaluation at https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L45 cannot be made nothrow. If I qualify the function as nothrow DMD complains as algorithm_ex.d(45,16): Error: 'a' is not nothrow algorithm_ex.d(46,29): Error: '_param_1' is not nothrow https://issues.dlang.org/show_bug.cgi?id=12647
Re: Returning an empty range of a given type
On 5/13/15 10:58 PM, rcorre wrote: Actually, this doesn't even seem to work with a custom range: import std.range; import std.stdio; import std.algorithm; struct MyContainer { @nogc auto opSlice() { struct Range { @property bool empty() { return true; } @property int front() { return 9; } void popFront() { } } return Range(); } } /// Return a slice of aa[key], or an empty slice if not found @nogc auto maybeGetRange(MyContainer[string] aa, string key) { alias RangeType = typeof(MyContainer.init[]); auto val = key in aa; return (val is null) ? takeNone!RangeType : (*val)[].take(size_t.max); } Is there any way to create an empty MyContainer.Range() without creating a new container? It depends on the guts of MyContainer.Range. I'm assuming MyContainer.Range has SOME sort of references (i.e. pointers) to the data in the container, so why not just have: bool empty() { return someRef == null || yourCurrentTest; } -Steve
Re: Returning an empty range of a given type
On Thursday, 14 May 2015 at 12:40:57 UTC, rcorre wrote: So I thought this might work: struct MaybeEmpty(R) if (isInputRange!R) { private bool _isEmpty; private R_input; alias _input this; this(bool isEmpty, R input) { _input = input; _isEmpty = isEmpty; } @property bool empty() { return _isEmpty || _input.empty; } } auto maybeEmpty(R)(bool empty, R input = R.init) if (isInputRange!R) { return MaybeEmpty!R(empty, input); } It's kind of ugly, but it can be used like: auto a = maybeEmpty!MyRange(true); auto b = maybeEmpty!MyRange(false, actualRange); static assert(is(typeof(a) == typeof(b))); However, it fails the input range test: static assert(isInputRange!MyRange); //pass static assert(isInputRange!(typeof(a))); // fail But it seems to be something weird with cross-module template instantiation. If I replace `import std.range` with a copy-paste of `isInputRange`, the above passes. Either that or I'm doing something stupid because I'vebeen staring at this too long. I'm wondering if the isInputRange thing is a bug, so here's a gist if anyone wants to play with it: https://gist.github.com/rcorre/7a62395c53baf3c0bfbc How about a more flexible solution? http://dpaste.dzfl.pl/2f99cc270651
Re: Array of objects and their inheritance
On Thursday, 14 May 2015 at 19:00:16 UTC, tired_eyes wrote: First, I don't understand why we see array[2] as 'Child'. While it is a 'Child', shouldn't it be shown as a 'Parent' due to we explicitly create an array of 'Parents'? It is getting the name through a virtual interface (a hidden one that has typeinfo). class Base { string getName() { return Base; } } class Derived : Base { override string getName() { return Derived; } } Base b = new Derived(); b.getName() == Derived; // because the virtual function can still be called through an interface Well, if it's still a 'Child', why we can't access it's fields? It is a Child object, but you are talking to it through the Parent interface, so only functions+members available on Parent can be accessed without casting it. And what is the proper way of storing a collection of inherited objects without losing access to their fields and methods? Best you can do is say if(child = cast(Child) parentArray[0]) { // it is a child, now use child to access that } Though often a better way is to add an interface method that does it in the parent and is overridden in the child, just like with the getName above.
Re: Dynamic / resizable array type, and a crash problem
On Thursday, 14 May 2015 at 20:03:16 UTC, ivoras wrote: Where would I look for documentation on the ~= operator? http://dlang.org/arrays.html under the heading array concatenation What would be the difference between Array!string and string[] ? Array!string takes ownership of its own memory and frees it when no longer used making it appropriate in cases where you want that optmization. string[] is a slice - pointer plus length combination - into externally managed memory.
Re: How to simulate a new type
On Thursday, 14 May 2015 at 18:42:56 UTC, Charles Hixson wrote: What are the downsides to simulating a new type with a struct. What I have in mind is something along the lines of: struct myType { uint64_t value; } The goal of this type is to prevent accidental conversions from myType into ints, uint64_ts, etc. http://dlang.org/phobos/std_typecons.html#.Typedef
Re: Dynamic / resizable array type, and a crash problem
On Thursday, 14 May 2015 at 20:32:28 UTC, rumbu wrote: On Thursday, 14 May 2015 at 20:03:16 UTC, ivoras wrote: What would be the difference between Array!string and string[] ? std.array is used to manipulate or create built-in arrays from various sources (ranges). For basic needs, you can safely use built-in arrays: http://dlang.org/arrays.html Concatenation operator (~) is documented here: http://dlang.org/arrays.html#array-concatenation Thanks, everyone! I'm experimenting to get a feel for the language. Do you have a suggestion about this example code: https://goo.gl/F7LCAg to make it more D-like, idiomatic?
Array of objects and their inheritance
Hi. I'm having a hard time understanding D's inheritance. Consider the following code: class Parent { public int x = 10; } class Child : Parent { public int y = 20; } void main() { import std.stdio; Parent[] array; auto obj1 = new Parent(); auto obj2 = new Child(); array ~= obj1; array ~= obj2; writeln(array[0]); // prints Parent, as expected writeln(array[1]); // prints Child, so I assume that if it's a Child, we can access Child's fields writeln(array[0].x); // 10 writeln(array[1].y); // Error: no property 'y' for type 'Parent' } First, I don't understand why we see array[2] as 'Child'. While it is a 'Child', shouldn't it be shown as a 'Parent' due to we explicitly create an array of 'Parents'? Well, if it's still a 'Child', why we can't access it's fields? And what is the proper way of storing a collection of inherited objects without losing access to their fields and methods? Please point me in the right direction. I'm (still) relatively new to D, and will appreciate any help.
Re: What wrong?
On Tuesday, 5 May 2015 at 07:41:04 UTC, sclytrack wrote: On Monday, 4 May 2015 at 01:03:43 UTC, Fyodor Ustinov wrote: On Saturday, 2 May 2015 at 20:46:32 UTC, Dennis Ritchie wrote: On Saturday, 2 May 2015 at 19:38:01 UTC, Fyodor Ustinov wrote: I see it by the lack of 42. :) But why is this receive breaks down? import std.stdio; import std.variant; struct SoMany { int number = 10; ~this() { writeln(number); } } void main() { Variant v = SoMany(); } DMD64 D Compiler v2.067.1 10 10 10 10 gdc (Debian 4.9.2-10) 4.9.2 10 10 For DMD I'm getting 4x10 and for gdc 2x10
Re: Dynamic / resizable array type, and a crash problem
On Thursday, 14 May 2015 at 13:50:17 UTC, Adam D. Ruppe wrote: On Thursday, 14 May 2015 at 13:26:27 UTC, ivoras wrote: Is it resizable? You can append with the ~= operator and size down by slicing it. Apparently it doesn't even have an insert method: http://dlang.org/phobos/std_array.html . http://dlang.org/phobos/std_array.html#insertInPlace is the one you'd use for that. Ok, string[] and ~= work and it doesn't crash now. Where would I look for documentation on the ~= operator? It's not described in http://dlang.org/phobos/std_array.html (though it is mentioned so you need to know what you are looking for before you find it...). What would be the difference between Array!string and string[] ?
Re: Dynamic / resizable array type, and a crash problem
On Thursday, 14 May 2015 at 20:03:16 UTC, ivoras wrote: What would be the difference between Array!string and string[] ? std.array is used to manipulate or create built-in arrays from various sources (ranges). For basic needs, you can safely use built-in arrays: http://dlang.org/arrays.html Concatenation operator (~) is documented here: http://dlang.org/arrays.html#array-concatenation
Re: Feature or bug: print braces
On 05/14/2015 03:39 PM, Dennis Ritchie wrote: On Thursday, 14 May 2015 at 21:55:40 UTC, Alex Parrill wrote: On Thursday, 14 May 2015 at 00:39:25 UTC, Dennis Ritchie wrote: On Thursday, 14 May 2015 at 00:33:33 UTC, Brian Schott wrote: You told it to output a function literal, so it did. Yes, but it would be logical to deduce something like: - writeln({}); // prints literal[{}] Or the compiler will not be able to distinguish the literal from the ordinary function arguments? Literal what? Associative array? That uses square brackets, not curly brackets. Struct? What struct would you be creating? And curly braces only works for initialization. Lambda? Well you can omit the parameters if there are none, and `{}` in a lambda will give you a block to write, so `{}` is a valid lambda that accepts nothing and does nothing. I just wanted to say that writeln function of demand should not print anything else at this challenge, not 804CF88 :) - writeln({}); Yes, it is weird but that value happens to be the address of the function. Here is another test: import std.stdio; void foo() pure nothrow @nogc @safe {} void main() { void printInfo(T)(T t) { writefln(%s %s, T.stringof, t); } auto f = (){};// -- Why the need for () here? printInfo(foo); printInfo(f); printInfo({});// -- No need for () here. } There is an inconsistency where a lambda need to be defined with empty parentheses in one context while it is just fine without in another context. One output shows that they are all of the same type (function pointers): void function() pure nothrow @nogc @safe 473264 void function() pure nothrow @nogc @safe 4732BC void function() pure nothrow @nogc @safe 4732C4 Ali
Re: Feature or bug: print braces
On Thursday, 14 May 2015 at 00:39:25 UTC, Dennis Ritchie wrote: On Thursday, 14 May 2015 at 00:33:33 UTC, Brian Schott wrote: You told it to output a function literal, so it did. Yes, but it would be logical to deduce something like: - writeln({}); // prints literal[{}] Or the compiler will not be able to distinguish the literal from the ordinary function arguments? Literal what? Associative array? That uses square brackets, not curly brackets. Struct? What struct would you be creating? And curly braces only works for initialization. Lambda? Well you can omit the parameters if there are none, and `{}` in a lambda will give you a block to write, so `{}` is a valid lambda that accepts nothing and does nothing.
Re: Feature or bug: print braces
On Thursday, 14 May 2015 at 21:55:40 UTC, Alex Parrill wrote: On Thursday, 14 May 2015 at 00:39:25 UTC, Dennis Ritchie wrote: On Thursday, 14 May 2015 at 00:33:33 UTC, Brian Schott wrote: You told it to output a function literal, so it did. Yes, but it would be logical to deduce something like: - writeln({}); // prints literal[{}] Or the compiler will not be able to distinguish the literal from the ordinary function arguments? Literal what? Associative array? That uses square brackets, not curly brackets. Struct? What struct would you be creating? And curly braces only works for initialization. Lambda? Well you can omit the parameters if there are none, and `{}` in a lambda will give you a block to write, so `{}` is a valid lambda that accepts nothing and does nothing. I just wanted to say that writeln function of demand should not print anything else at this challenge, not 804CF88 :) - writeln({});
Re: How to simulate a new type
On 05/14/2015 01:42 PM, Laeeth Isharc via Digitalmars-d-learn wrote: On Thursday, 14 May 2015 at 18:42:56 UTC, Charles Hixson wrote: What are the downsides to simulating a new type with a struct. What I have in mind is something along the lines of: struct myType { uint64_t value; } The goal of this type is to prevent accidental conversions from myType into ints, uint64_ts, etc. http://dlang.org/phobos/std_typecons.html#.Typedef Yes, that looks as if it would do the job, but what are its advantages over a simple struct? I'd be hesitant to try to predict the RAM layout of a templated variable, but it's my understanding that a struct has neither compile time nor runtime penalties over a simple variable, and that it doesn't increase RAM comsumption when included within another struct, or in a static array. What I was really wondering was whether the limitation of access caused by enclosing a variable within a struct was worth the benefit. Templates add a whole 'nother layer of complexity. For that matter I was thinking that, if I so chose, I could at some point add limits along the lines of Ada's types. I like being *able* to define conversions for types, but frequently I'd rather not have them arbitrarily assumed. Otherwise I'd just use alias, which almost does what I want. (E.g., one thing I might eventually want to do is use a couple of bits at the top of the uint64_t as flags, so if I did define operations I'd need to be able to mask the flag bits off before the operation and reapply them to the result, in some defined way of combining the flags. Not good if sometimes the value is going to be automatically reinterpreted as a plain number.)
Re: How to simulate a new type
On Friday, 15 May 2015 at 01:03:32 UTC, Charles Hixson wrote: Yes, that looks as if it would do the job, but what are its advantages over a simple struct? None really, except perhaps automatic forwarding of operators which is easy enough to do on a struct too (and with a struct, you can do only the ones that actually make sense for you). Typedef has a few major disadvantages too - surprising behavior if you forget the second parameter, for example. The library typedef should really be removed.
Re: Feature or bug: print braces
On Thursday, 14 May 2015 at 22:55:43 UTC, Ali Çehreli wrote: Yes, it is weird but that value happens to be the address of the function. Here is another test: import std.stdio; void foo() pure nothrow @nogc @safe {} void main() { void printInfo(T)(T t) { writefln(%s %s, T.stringof, t); } auto f = (){};// -- Why the need for () here? printInfo(foo); printInfo(f); printInfo({});// -- No need for () here. } There is an inconsistency where a lambda need to be defined with empty parentheses in one context while it is just fine without in another context. One output shows that they are all of the same type (function pointers): void function() pure nothrow @nogc @safe 473264 void function() pure nothrow @nogc @safe 4732BC void function() pure nothrow @nogc @safe 4732C4 Ali Thanks. This example explains a lot. It's like echoes UFCS :)
Re: Returning an empty range of a given type
On Thursday, 14 May 2015 at 06:41:45 UTC, Ali Çehreli wrote: I am lucky because although the returned type is opaque to me, I know that it is constructed by a void lambda. Yeah, in this case I control the container so I may just add an emptySlice property, but it does seem like it might be a common need (to return an empty range of a given type without having that range constructed beforehand).
Re: Returning an empty range of a given type
On 05/13/2015 07:47 PM, rcorre wrote: I've run into this situation a lot: I have a function that returns a range (in this case, a slice of a custom container). In some cases, the function needs to return an empty range. It sounded like takeNone was what I wanted: @nogc auto fun() { return (some_condition) ? getRange() : getRange.takeNone; } but there is a return type ambiguity. I finally ended up doing this: @nogc auto fun() { return (some_condition) ? getRange().take(size_t.max) : getRange.takeNone; } I'm not sure if this is clever or insane. It works, but just looks a bit crazy to me. Does anyone else run into this situation? Have any cool ways to solve it? MyRange is an inputRange, and I can't use a wrapper (InputRange) and keep the @nogc. I needed the same thing in a code example of this chapter: http://ddili.org/ders/d.en/fibers.html There is this function that returns a range: auto byNode(const(Node) * node) { return new FiberRange!(const(Node)*)( () = nextNode(node)); } I am lucky because although the returned type is opaque to me, I know that it is constructed by a void lambda. So, I could pass (){} to the constructor to make an empty range: auto byNode(const(Tree) tree) { alias RangeType = typeof(byNode(tree.root)); return (tree.root ? byNode(tree.root) : new RangeType(() {}));// ← Empty range } Ali
Re: problem with parallel foreach
John Colvin's improvements to my D program seem to have resolved the problem. (http://forum.dlang.org/post/ydgmzhlspvvvrbeem...@forum.dlang.org and http://dpaste.dzfl.pl/114d5a6086b7). I have rerun my tests and now the picture is a bit different (see tables below). In the middle table I have used gnu parallel in combination with a slightly modified version of the D program which runs a single trait (specified in argv[1]). This approach runs the jobs as completely isolated processes, but at the extra cost of re-reading the common data for each trait. The elapsed time is very similar with the parallel foreach in the D program or using gnu parallel (for this particular program and these data run on this server...). I'm guessing the program is now essentially limited by disk I/O, so this is about as good as it gets. So, just to wrap up: - there is a nice speed improvement over Python program :-) - one needs to learn a fair bit to fully benefit from D's potential - thanks for all the help! Gerald Jansen Jobs __ time for D parallel foreach w. JC mods 1 4.71user 0.56system 0:05.28elapsed 99%CPU 2 6.59user 0.96system 0:05.48elapsed 137%CPU 411.45user 1.94system 0:07.24elapsed 184%CPU 820.30user 5.18system 0:13.16elapsed 193%CPU 16 68.48user 13.87system 0:27.21elapsed 302%CPU 27 99.66user 18.73system 0:42.34elapsed 279%CPU Jobs __ gnu parallel + D program for single job __ 1 4.71user 0.56system 0:05.28elapsed 99%CPU as above 2 9.66user 1.28system 0:05.76elapsed 189%CPU 418.86user 3.85system 0:08.15elapsed 278%CPU 840.76user 7.53system 0:14.69elapsed 328%CPU 16 135.76user 20.68system 0:31.06elapsed 503%CPU 27 189.43user 28.26system 0:47.75elapsed 455%CPU Jobs _ time for python version _ 145.39user 1.52system 0:46.88elapsed 100%CPU 277.76user 2.42system 0:47.16elapsed 170%CPU 4 141.28user 4.37system 0:48.77elapsed 298%CPU 8 280.45user 8.80system 0:56.00elapsed 516%CPU 16 926.05user 20.48system 1:31.36elapsed 1036%CPU 27 1329.09user 27.18system 2:11.79elapsed 1029%CPU
Cannot Qualify Variadic Functions with Lazy Arguments as nothrow
At https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L43 I've implemented a function either() with behaviour similar to the `or` function/operator in dynamic languages such as Python and Lisp. I'm almost satisified with it except that the lazy evaluation at https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L45 cannot be made nothrow. If I qualify the function as nothrow DMD complains as algorithm_ex.d(45,16): Error: 'a' is not nothrow algorithm_ex.d(46,29): Error: '_param_1' is not nothrow I don't see a reason why any of these two cases should throw. The same problem occurs if I make the implementation use only one function and check the recursion termination case with `static if (bs.length == 1)` instead. Is there a workaround for this?
Re: Cannot Qualify Variadic Functions with Lazy Arguments as nothrow
On Thursday, 14 May 2015 at 09:53:20 UTC, Per Nordlöw wrote: At https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L43 I've implemented a function either() with behaviour similar to the `or` function/operator in dynamic languages such as Python and Lisp. I'm almost satisified with it except that the lazy evaluation at https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L45 cannot be made nothrow. If I qualify the function as nothrow DMD complains as algorithm_ex.d(45,16): Error: 'a' is not nothrow algorithm_ex.d(46,29): Error: '_param_1' is not nothrow I don't see a reason why any of these two cases should throw. Lazy argument is essentially delegate/function. Currently there is no way to mark it as nothrow. The same problem occurs if I make the implementation use only one function and check the recursion termination case with `static if (bs.length == 1)` instead. Is there a workaround for this? One way to address is to use delegate explicitly. int foo(lazy int a) //nothrow { return a; } int bar(int delegate() nothrow dg) nothrow { return dg(); } void main() nothrow { int a; bar(()=a); }
Re: Returning an empty range of a given type
On Thursday, 14 May 2015 at 14:57:26 UTC, Idan Arye wrote: How about a more flexible solution? http://dpaste.dzfl.pl/2f99cc270651 Neat, thanks! On Thursday, 14 May 2015 at 18:44:58 UTC, Steven Schveighoffer wrote: It depends on the guts of MyContainer.Range. I'm assuming MyContainer.Range has SOME sort of references (i.e. pointers) to the data in the container, so why not just have: bool empty() { return someRef == null || yourCurrentTest; } -Steve In this case, I want to return an empty range when the container instance itself is null. I could have a static method MyContainer.emptySlice, but I feel like I've seen this general situation crop up a lot with small variations.
Linking to Dynamic Library on Mac OS X
I have built a toy dynamic shared library on Mac OS X (in C), and I have verified that it works from C. Now I would like to call it from D. So I have created the following interface file: $ cat hello.di extern (C): void printHelloWorld(); which I try to compile and run. But I get the following error: $ dmd main.d -L-lhello ld: library not found for -lhello clang: error: linker command failed with exit code 1 (use -v to see invocation) --- errorlevel 1 I gather that mac os x doesn't know where to find libhello.dylib (it is in the current directory). So how do I pass that information? Thanks! TJB
Re: Returning an empty range of a given type
On Friday, 15 May 2015 at 03:22:43 UTC, rcorre wrote: On Thursday, 14 May 2015 at 14:57:26 UTC, Idan Arye wrote: How about a more flexible solution? http://dpaste.dzfl.pl/2f99cc270651 Neat, thanks! The range I don't pick may be an expression that would fail, so I tweaked it to: SelectRange!T selectRange(T...)(size_t index, lazy T ranges) Other than that, it seems to be just what I needed. Thanks again!