Re: How to do "inheritance" in D structs
On Wednesday, 12 October 2016 at 02:18:47 UTC, TheFlyingFiddle wrote: On Wednesday, 12 October 2016 at 01:22:04 UTC, lobo wrote: Hi, I'm coming from C++ and wondered if the pattern below has an equivalent in D using structs. I could just use classes and leave it up to the caller to use scoped! as well but I'm not sure how that will play out when others start using my lib. Thanks, lobo module A; class Base1 { int ival = 42; } class Base2 { int ival = 84; } module B; class S(ABase) : ABase { string sval = "hello"; } module C; import A; import B; void main() { auto s= scoped!(S!Base1); // scoped!(S!Base2) } You could use "alias this" to simulate that type of inheritence. module A; struct Base1 { int ival = 42; } module B; struct Base2 { int ival = 84; } module C; import A, B; struct S(Base) if(is(Base == struct)) { Base base; alias base this; string sval = "Hello "; } void foo(ref ABase base) { base.ival = 32; } void main() { S!Base1 a; S!Base2 b; writeln(a.sval, a.ival); writeln(b.sval, b.ival); foo(a); writeln(a.sval, a.ival); } This approach works nicely although it feels clumsy but that's probably just because I'm so used to C++. It also handles private members as I'd expect, i.e. they're not accessible outside module scope through the alias struct instance, but there is no protected. Protected appears to behave the same way as private. I think I can live with that because I usually try to avoid protected anyway. Thanks, lobo
Re: How to do "inheritance" in D structs
On Wednesday, 12 October 2016 at 02:18:47 UTC, TheFlyingFiddle wrote: void foo(ref ABase base) { base.ival = 32; } This should be: void foo(ref Base1 base) { base.ival = 32; }
Re: How to do "inheritance" in D structs
On Wednesday, 12 October 2016 at 01:22:04 UTC, lobo wrote: Hi, I'm coming from C++ and wondered if the pattern below has an equivalent in D using structs. I could just use classes and leave it up to the caller to use scoped! as well but I'm not sure how that will play out when others start using my lib. Thanks, lobo module A; class Base1 { int ival = 42; } class Base2 { int ival = 84; } module B; class S(ABase) : ABase { string sval = "hello"; } module C; import A; import B; void main() { auto s= scoped!(S!Base1); // scoped!(S!Base2) } You could use "alias this" to simulate that type of inheritence. module A; struct Base1 { int ival = 42; } module B; struct Base2 { int ival = 84; } module C; import A, B; struct S(Base) if(is(Base == struct)) { Base base; alias base this; string sval = "Hello "; } void foo(ref ABase base) { base.ival = 32; } void main() { S!Base1 a; S!Base2 b; writeln(a.sval, a.ival); writeln(b.sval, b.ival); foo(a); writeln(a.sval, a.ival); }
How to do "inheritance" in D structs
Hi, I'm coming from C++ and wondered if the pattern below has an equivalent in D using structs. I could just use classes and leave it up to the caller to use scoped! as well but I'm not sure how that will play out when others start using my lib. Thanks, lobo module A; class Base1 { int ival = 42; } class Base2 { int ival = 84; } module B; class S(ABase) : ABase { string sval = "hello"; } module C; import A; import B; void main() { auto s= scoped!(S!Base1); // scoped!(S!Base2) }
Determining if a class has a template function
I have a class T with a templated function foo(string name)(int, int, float) that will be mixed in via template, and I want to determine if that class has mixed it in such that foo(name = "bar"). How could I go about this? Thanks. eg: mixin template A(string name, Args...) { void foo(string fooName)(Args args) if (fooName == name) {} } template hasFoo(string name, A) { enum hasFoo = ??? } class B { mixin A!("mash", int, int, string); }
Re: passing static arrays to each! with a ref param [Re: Why can't static arrays be sorted?]
On Tuesday, 11 October 2016 at 19:46:31 UTC, Jon Degenhardt wrote: On Tuesday, 11 October 2016 at 18:18:41 UTC, ag0aep6g wrote: On 10/11/2016 06:24 AM, Jon Degenhardt wrote: The example I gave uses ref parameters. On the surface it would seem reasonable to that passing a static array by ref would allow it to be modified, without having to slice it first. Your ref parameters are only for the per-element operations. You're not passing the array as a whole by reference. And you can't, because `each` itself takes the whole range by copy. So, the by-ref increments themselves do work, but they're applied to a copy of your original static array. I see. Thanks for the explanation. I wasn't thinking it through properly. Also, I guess I had assumed that the intent was that each! be able to modify the elements, and therefore the whole array it would be pass by reference, but didn't consider it properly. Another perspective where the current behavior could be confusing is that it is somewhat natural to assume that 'each' is the functional equivalent of foreach, and that they can be used interchangeably. However, for static arrays they cannot be.
Re: passing static arrays to each! with a ref param [Re: Why can't static arrays be sorted?]
On Tuesday, 11 October 2016 at 18:18:41 UTC, ag0aep6g wrote: On 10/11/2016 06:24 AM, Jon Degenhardt wrote: The example I gave uses ref parameters. On the surface it would seem reasonable to that passing a static array by ref would allow it to be modified, without having to slice it first. Your ref parameters are only for the per-element operations. You're not passing the array as a whole by reference. And you can't, because `each` itself takes the whole range by copy. So, the by-ref increments themselves do work, but they're applied to a copy of your original static array. I see. Thanks for the explanation. I wasn't thinking it through properly. Also, I guess I had assumed that the intent was that each! be able to modify the elements, and therefore the whole array it would be pass by reference, but didn't consider it properly. I'm not going to make any suggestions about whether the behavior should be changed. At some point when I get a bit of time I'll try to submit a documentation change to make the current behavior clearer. --Jon
Re: Working with ranges: mismatched function return type inference
On Tuesday, October 11, 2016 10:42:42 Ali Çehreli via Digitalmars-d-learn wrote: > Those interfaces already exist in Phobos: :) > >https://dlang.org/phobos/std_range_interfaces.html > > auto foo(int[] ints) { >import std.range; >if (ints.length > 10) { >return > cast(RandomAccessFinite!int)inputRangeObject(chain(ints[0..5], ints[8..$])); > } else { >return cast(RandomAccessFinite!int)inputRangeObject(ints); >} > } > > void main() { > import std.stdio; > import std.range; > import std.algorithm; > writeln(foo([1, 2, 3])); > writeln(foo(iota(20).array)); > } And in this case, if you were considering doing that, you might as well just concatenate the dynamic arrays rather than chaining them, because using interfaces means allocating on the heap just like you would with concatenating. About the only time that using interfaces is the right solution with ranges is when you're dealing with virtual functions (which can't be templatized), and even then, it's not necessarily the best choice. Here, IMHO, it makes no sense at all. - Jonathan M Davis
Re: Working with ranges: mismatched function return type inference
On Tuesday, 11 October 2016 at 18:09:26 UTC, ag0aep6g wrote: You've got some options: Wow, thanks everyone, great information! I think I understand my options now.
Re: passing static arrays to each! with a ref param [Re: Why can't static arrays be sorted?]
On 10/11/2016 06:24 AM, Jon Degenhardt wrote: The example I gave uses ref parameters. On the surface it would seem reasonable to that passing a static array by ref would allow it to be modified, without having to slice it first. Your ref parameters are only for the per-element operations. You're not passing the array as a whole by reference. And you can't, because `each` itself takes the whole range by copy. So, the by-ref increments themselves do work, but they're applied to a copy of your original static array. Question is, should `each` 1) take all inputs (ranges, arrays, other foreachables) by reference, or 2) take some inputs (like static arrays) by reference, or 3) take all inputs by value (current behavior)? #1 would break code. Would probably need some deprecating and name shuffling to be acceptable. Would also need to make sure that this is actually the most desirable behavior. #2 would probably create surprising corner cases. I don't think we can tell for sure if a range needs to be passed by reference in order to see updates to its elements. I'd be against this. #3 may be a little surprising in how it doesn't affect value types (like static arrays). However, before switching to #1, you'd need to make sure that that one doesn't have worse corner cases. I don't see any deal breakers, but that doesn't mean they're not there ;) You also have to see if changing to #1 is worth the effort. It would be an effort not only for the implementer, but also for the users who have to update all their code.
Re: Working with ranges: mismatched function return type inference
On 10/11/2016 09:55 AM, orip wrote: auto foo(int[] ints) { import std.range; if (ints.length > 10) { return chain(ints[0..5], ints[8..$]); } else { //return ints; // Error: mismatched function return type inference of int[] and Result return chain(ints[0..0], ints[0..$]); // This workaround compiles } } Is there a compatible return type that can be used, or some other workaround? You've got some options: 1) OOP with std.range.interfaces. Ali already showed how this work. Comes at the cost of extra allocations and indirections. 2) std.range.choose wraps two different range types and uses forwards to one of them based on a condition. Should be cheap. But you need restructure your code a little: auto foo(int[] ints) { import std.range: chain, choose; return choose(ints.length > 10, chain(ints[0..5], ints[8..$]), ints); } 3) The workaround you already discovered: making a seemingly pointless call to `chain` to get the types to match. Possibly the most efficient solution. Looks a little odd.
Re: Working with ranges: mismatched function return type inference
On Tuesday, October 11, 2016 07:55:36 orip via Digitalmars-d-learn wrote: > I get "Error: mismatched function return type inference" errors > with choosing the return type for functions that work on ranges > using, e.g, std.algorithm or std.range functions, but have > different behavior based on runtime values. The return type is > always a range with the same underlying type. > > Here's an example: > > auto foo(int[] ints) { >import std.range; >if (ints.length > 10) { > return chain(ints[0..5], ints[8..$]); >} else { > //return ints; // Error: mismatched function return type > inference of int[] and Result > return chain(ints[0..0], ints[0..$]); // This workaround > compiles >} > } > > Is there a compatible return type that can be used, or some other > workaround? > I couldn't find one when searching for the error or looking at > the phobos source code. > > Thanks! orip You're workaround is basically doing what you need to do. A function can only return one type. The fact that both return statements are returning ranges over the same kind of elements is irrelevant. They have to be _exactly_ the same type. So, either you need to convert the range for the first return statement into int[] so that it matches the second (e.g. by calling array on the result or just using ~), or you need to call chain on two int[]s for the second return statement so that it matches the first. The second option (which your workaround does) is better if you don't intend to convert the result to an array, since it avoids allocating an array, but if you're just going to convert the result to int[] anyway, the first option would be better. Regardless, you can't have a function returning different types from different return statements - even with auto. The compiler needs to know exactly what the return type is whether you type it or not; auto just infers it for you rather than requiring you to type it out. - Jonathan M Davis
Re: Working with ranges: mismatched function return type inference
On 10/11/2016 10:28 AM, TheFlyingFiddle wrote: On Tuesday, 11 October 2016 at 15:46:20 UTC, orip wrote: On Tuesday, 11 October 2016 at 13:06:37 UTC, pineapple wrote: Rewrite `return chain(ints[0..5], ints[8..$]);` as `return ints[0..5] ~ ints[8..$];` The `chain` function doesn't return an array, it returns a lazily-evaluated sequence of an entirely different type from `int[]`. Of course it does! I would like the function to return an "input range of int", no matter which one specifically. Is this possible? It is, but you will have to use an interface / class to achieve this behavior (or use some sort of polymorphic struct). Something like this will do the trick: import std.range; import std.stdio; interface IInputRange(T) { bool empty(); T front(); void popFront(); } final class InputRange(Range) if(isInputRange!Range) : IInputRange!(ElementType!Range) { Range r; this(Range r) { this.r = r; } bool empty() { return r.empty; } ElementType!Range front() { return r.front; } void popFront() { r.popFront; } } auto inputRange(Range)(Range r) { return new InputRange!Range(r); } IInputRange!int foo(int[] ints) { import std.range; if(ints.length > 10) { return inputRange(chain(ints[0 .. 5], ints[8 .. $])); } else { return inputRange(ints); } } void main() { auto ir = foo([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); auto ir2 = foo([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); writeln(ir); writeln(ir2); } Those interfaces already exist in Phobos: :) https://dlang.org/phobos/std_range_interfaces.html auto foo(int[] ints) { import std.range; if (ints.length > 10) { return cast(RandomAccessFinite!int)inputRangeObject(chain(ints[0..5], ints[8..$])); } else { return cast(RandomAccessFinite!int)inputRangeObject(ints); } } void main() { import std.stdio; import std.range; import std.algorithm; writeln(foo([1, 2, 3])); writeln(foo(iota(20).array)); } Ali
Re: Working with ranges: mismatched function return type inference
On Tuesday, 11 October 2016 at 15:46:20 UTC, orip wrote: On Tuesday, 11 October 2016 at 13:06:37 UTC, pineapple wrote: Rewrite `return chain(ints[0..5], ints[8..$]);` as `return ints[0..5] ~ ints[8..$];` The `chain` function doesn't return an array, it returns a lazily-evaluated sequence of an entirely different type from `int[]`. Of course it does! I would like the function to return an "input range of int", no matter which one specifically. Is this possible? It is, but you will have to use an interface / class to achieve this behavior (or use some sort of polymorphic struct). Something like this will do the trick: import std.range; import std.stdio; interface IInputRange(T) { bool empty(); T front(); void popFront(); } final class InputRange(Range) if(isInputRange!Range) : IInputRange!(ElementType!Range) { Range r; this(Range r) { this.r = r; } bool empty() { return r.empty; } ElementType!Range front() { return r.front; } void popFront() { r.popFront; } } auto inputRange(Range)(Range r) { return new InputRange!Range(r); } IInputRange!int foo(int[] ints) { import std.range; if(ints.length > 10) { return inputRange(chain(ints[0 .. 5], ints[8 .. $])); } else { return inputRange(ints); } } void main() { auto ir = foo([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); auto ir2 = foo([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); writeln(ir); writeln(ir2); }
Re: dmd -o- option meaning changed recently? Now not creating OBJ but also not creating EXE
On Monday, 3 October 2016 at 09:06:32 UTC, Dicebot wrote: Purpose is to skip code generation and only do syntax/semantic validation. Very helpful when testing compiler because: a) it takes less time speeding up overall test suite b) doesn't require runtime static library to succeed, thus simplifying setup Thanks, Dicebot. Only saw your message now, sorry.
Re: Working with ranges: mismatched function return type inference
11.10.2016 18:46, orip пишет: On Tuesday, 11 October 2016 at 13:06:37 UTC, pineapple wrote: Rewrite `return chain(ints[0..5], ints[8..$]);` as `return ints[0..5] ~ ints[8..$];` The `chain` function doesn't return an array, it returns a lazily-evaluated sequence of an entirely different type from `int[]`. Of course it does! I would like the function to return an "input range of int", no matter which one specifically. Is this possible? it doesn't. Using runtime argument you can't choose compile time parameter - returned type. So it's impossible. Almost - b/c you can use Algebraic. Again you can do the following: ```D return chain(ints[0..5], ints[8..$]).array; // it returns int[] ```
Re: Working with ranges: mismatched function return type inference
On Tuesday, 11 October 2016 at 13:06:37 UTC, pineapple wrote: Rewrite `return chain(ints[0..5], ints[8..$]);` as `return ints[0..5] ~ ints[8..$];` The `chain` function doesn't return an array, it returns a lazily-evaluated sequence of an entirely different type from `int[]`. Of course it does! I would like the function to return an "input range of int", no matter which one specifically. Is this possible?
Re: Trait hasIndexing
On Tuesday, October 11, 2016 10:08:02 Nordlöw via Digitalmars-d-learn wrote: > I can't find any traits `hasIndexing!R` corresponding to > `std.range.primitives.hasSlicing!R` > > that is `true` iff `R` has `opIndex[size_t]` defined. Is there > one? > > If not what should I use instead? The traits in std.range are specifically for ranges, and isRandomAccessRange already covers indexing, which is why there isn't a separate trait for indexing in there. There certainly _could_ be one in std.traits, but there isn't at present. - Jonathan M Davis
Re: Current State of the GC?
On Monday, 10 October 2016 at 21:12:42 UTC, Martin Lundgren wrote: So what's been happening in memory management land lately? Bad GC seems like one of the Dlangs weak points, so showing improvements here could definitely bring more people in. It's not that the D GC is bad per se, but rather than having a GC there requires understanding of what it does and why. It is like a knowledge debt that has to be paid back sooner or later. Once you've paid this cost in understanding (how to be deterministic, how to recognize GC errors, how to keep the heap small, how to maintain traceability and why) the GC becomes some kind of helpful friend, if only a bit creepy. BTW the GC has seen some improvement with regards to preciseness.
Re: Working with ranges: mismatched function return type inference
On Tuesday, 11 October 2016 at 07:55:36 UTC, orip wrote: I get "Error: mismatched function return type inference" errors with choosing the return type for functions that work on ranges using, e.g, std.algorithm or std.range functions, but have different behavior based on runtime values. The return type is always a range with the same underlying type. Here's an example: auto foo(int[] ints) { import std.range; if (ints.length > 10) { return chain(ints[0..5], ints[8..$]); } else { //return ints; // Error: mismatched function return type inference of int[] and Result return chain(ints[0..0], ints[0..$]); // This workaround compiles } } Is there a compatible return type that can be used, or some other workaround? I couldn't find one when searching for the error or looking at the phobos source code. Thanks! orip Rewrite `return chain(ints[0..5], ints[8..$]);` as `return ints[0..5] ~ ints[8..$];` The `chain` function doesn't return an array, it returns a lazily-evaluated sequence of an entirely different type from `int[]`.
Re: Trait hasIndexing
On Tuesday, 11 October 2016 at 10:08:02 UTC, Nordlöw wrote: I can't find any traits `hasIndexing!R` corresponding to `std.range.primitives.hasSlicing!R` My definition of `hasIndexing` so far: https://github.com/nordlow/phobos-next/blob/master/src/typecons_ex.d#L83
Trait hasIndexing
I can't find any traits `hasIndexing!R` corresponding to `std.range.primitives.hasSlicing!R` that is `true` iff `R` has `opIndex[size_t]` defined. Is there one? If not what should I use instead?
Working with ranges: mismatched function return type inference
I get "Error: mismatched function return type inference" errors with choosing the return type for functions that work on ranges using, e.g, std.algorithm or std.range functions, but have different behavior based on runtime values. The return type is always a range with the same underlying type. Here's an example: auto foo(int[] ints) { import std.range; if (ints.length > 10) { return chain(ints[0..5], ints[8..$]); } else { //return ints; // Error: mismatched function return type inference of int[] and Result return chain(ints[0..0], ints[0..$]); // This workaround compiles } } Is there a compatible return type that can be used, or some other workaround? I couldn't find one when searching for the error or looking at the phobos source code. Thanks! orip
Re: weighted round robin
On Monday, 10 October 2016 at 09:18:16 UTC, Marc Schütz wrote: On Saturday, 8 October 2016 at 22:48:53 UTC, vino wrote: Hi, Can some one guide me on how to implement the weighted round robin, below is what i tried or any other better ways to do it Main Requirement : Incoming socket connection has to be sent to 3 servers in the weighted round robin fashion. Prog:1 import std.stdio; import std.range; import std.range.primitives; void main() { auto a = [1,2,3]; // E.g :Server Array auto b = [1,2,3,4,5]; // E.g: Socket Array auto r = roundRobin(a, b); writeln(r); } OUTPUT : [1, 1, 2, 2, 3, 3, 4, 5] Requirement : [1, 1, 2, 2, 3, 3,1,4,2,5] auto r = roundRobin(a.cycle, b.cycle); Beware though that this yields an infinite range. If you just need one round, you can use: import std.algorithm.comparison : max; writeln(r.take(max(a.length, b.length))); Hi Marc, Thank you, I have made a small update as the Server Array is fixed length and the Socket array would be dynamic so made the below changes as now it is working as expected Prog:1 import std.stdio; import std.range; import std.range.primitives; import std.algorithm.comparison : max; void main() { auto a = [1,2,3]; // E.g :Server Array auto b = [1,2,3,4,5,6,7,8,9,10,11,12]; // E.g: Socket Array auto r = roundRobin(a.cycle, b.cycle); writeln(r.take(max(a.length, b.length * 2))); } From, Vino.B
Re: ptrdiff_t of class.tupleof entry
On Monday, 10 October 2016 at 18:21:10 UTC, Jonathan M Davis wrote: On Monday, October 10, 2016 17:57:15 Satoshi via Digitalmars-d-learn wrote: [...] You can use the offsetof property of a member variable to find out the offset between its address and the address of the beginning of the class or struct that it's a member of. - Jonathan M Davis Thanks a lot!