Re: Generically call a function on Variant's payload?
On Sunday, August 19, 2018 9:08:39 PM MDT Nick Sabalausky (Abscissa) via Digitalmars-d-learn wrote: > On 08/19/2018 10:23 PM, Jonathan M Davis wrote: > > On Sunday, August 19, 2018 6:33:06 PM MDT Nick Sabalausky (Abscissa) via > > > > Digitalmars-d-learn wrote: > >> Maybe something involving using Variant.coerce to convert the payload > >> to > >> a single common type? Not sure how I would do that though. > > > > You could always create a wrapper type. Whatever code you're dealing > > with is going to need to statically know what type it's using even > > that's a base type in a class hierarchy. So, you need to present a type > > which actually has the appropriate API even if internally, it can > > dynamically handle several types which have that API, and it's not > > known ahead of time which type that is. > > I guess the parts I'm unclear on are: > > 1. What mechanism does Variant.coerce!SomeType use to attempt conversion > to SomeType? > > 2. How (if possible) can I provide a way to convert something to type > SomeType which Variant.coerce!SomeType will then recognize and use? Glancing at coerce's implementation, it just uses std.conv.to, but it's fairly restricted on which types it will convert to. The target type has to be numeric, bool, convertible to Object, or an array of characters. It looks like it will convert the object to string to do the conversion, so it's doing slightly more than just using std.conv.to and restricting the conversions, but really, it's basically just calling std.conv.to in a restricted manner. So, looking at coerce, I don't really understand why it exists. It just seems like it would make more sense to tell folks to get the object out with get and then convert it themselves using std.conv.to or whatever makes the most sense for their use case. Presenting a function that uses std.conv.to but restricts which conversions work really doesn't make sense to me. Either way, if you're doing something like using a Variant to hold multiple range types, I very much doubt that coerce is going to do you much good. - Jonathan M Davis
Re: Generically call a function on Variant's payload?
On Monday, 20 August 2018 at 00:27:04 UTC, Nick Sabalausky (Abscissa) wrote: Suppose I've wrapped a Variant in a struct/class which ensures the Variant *only* ever contains types which satisfy a particular constraint (for example: isInputRange, or hasLength, etc...). Is there a way to call a function (ex: popFront) on the Variant, *without* knowing ahead of time all the possible static types it might might contain? You are basically reinventing OOP here. Instead of Variants, use objects that implement an interface (e.g., `std.range.interfaces.InputRange`). Then you can call methods that belong to that interface and rely on virtual method dispatch to choose the correct implementation at runtime.
Re: Generically call a function on Variant's payload?
On 08/19/2018 10:23 PM, Jonathan M Davis wrote: On Sunday, August 19, 2018 6:33:06 PM MDT Nick Sabalausky (Abscissa) via Digitalmars-d-learn wrote: Maybe something involving using Variant.coerce to convert the payload to a single common type? Not sure how I would do that though. You could always create a wrapper type. Whatever code you're dealing with is going to need to statically know what type it's using even that's a base type in a class hierarchy. So, you need to present a type which actually has the appropriate API even if internally, it can dynamically handle several types which have that API, and it's not known ahead of time which type that is. I guess the parts I'm unclear on are: 1. What mechanism does Variant.coerce!SomeType use to attempt conversion to SomeType? 2. How (if possible) can I provide a way to convert something to type SomeType which Variant.coerce!SomeType will then recognize and use?
D need an ORM library!
hi, I thinks D need an ORM library for Sqlite/Mysql/PostgreSQL, entity currently support all the three targets, but entity's API is too complex and cumbersome for using. Is there a more light-weight and simpler implementation like ActiveAndroid ? Thanks! --- Binghoo Dang
Re: InputRange help: (1) repeated dtor calls and (2) managing resources needing free()
On Monday, 13 August 2018 at 13:20:25 UTC, Seb wrote: BTW it's very uncommon for empty to do work, it's much more common to do such lazy initialization in `.front`. Thanks Seb, that entire reply is a huge help. By lazy initialization in `.front`, do you mean that I should find a way for `front` to preload the first record? If so, could you help me understand what you mean by lazy init with `front`? `empty` is called before `front` upon first iteration through the Range, so really the init has to be done in the constructor, yes?
Re: Generically call a function on Variant's payload?
On Sunday, August 19, 2018 6:33:06 PM MDT Nick Sabalausky (Abscissa) via Digitalmars-d-learn wrote: > On 08/19/2018 08:27 PM, Nick Sabalausky (Abscissa) wrote: > > Suppose I've wrapped a Variant in a struct/class which ensures the > > Variant *only* ever contains types which satisfy a particular constraint > > (for example: isInputRange, or hasLength, etc...). > > > > Is there a way to call a function (ex: popFront) on the Variant, > > *without* knowing ahead of time all the possible static types it might > > might contain? > > Maybe something involving using Variant.coerce to convert the payload to > a single common type? Not sure how I would do that though. You could always create a wrapper type. Whatever code you're dealing with is going to need to statically know what type it's using even that's a base type in a class hierarchy. So, you need to present a type which actually has the appropriate API even if internally, it can dynamically handle several types which have that API, and it's not known ahead of time which type that is. - Jonathan M Davis
Re: Are properties mature enough?
On Sunday, August 19, 2018 12:32:17 PM MDT QueenSvetlana via Digitalmars-d- learn wrote: > In the D Style Guide, it says: > > Properties > https://dlang.org/dstyle.html#properties > > Functions should be property functions whenever appropriate. In > particular, getters and setters should generally be avoided in > favor of property functions. And in general, whereas functions > should be verbs, properties should be nouns, just like if they > were member variables. Getter properties should not alter state. > > In the Properties function section, it says: > > https://dlang.org/spec/function.html#property-functions > > WARNING: The definition and usefulness of property functions is > being reviewed, and the implementation is currently incomplete. > Using property functions is not recommended until the definition > is more certain and implementation more mature. > > So which is it? Feel free to use @property or not, but the main point in the style guide is about naming functions, not about @property. The idea is that functions that wrap or emulate variables should act like variables themselves. So, they should be named as if they were variables and syntactically used as if they were variables rather than prepending their names with get or set and calling them as functions. e.g. struct S { int prop() { return _prop; } int prop(int val) { return _prop = prop; } private int _prop; } with auto r = s.prop; s.prop = 42; instead of struct S { int getProp() { return _prop; } int setProp(int val) { return _prop = prop; } private int _prop; } auto r = s.getProp(); s.setProp(42). Marking property functions with @property is an extremely popular thing to do, but all it really does at this point is document that the programmer intends for it to be used as a property rather than enforce anything. IMHO, the spec words that bit too strongly, and it should be fixed. That bit got added recently, because one of the devs didn't understand the @property situation, and when he found out what it was, he felt that the spec needed to be clarified about it so that folks didn't think that it was what the spec was claiming, but clearly, he's just confused matters in a different way. Here's the deal. Using the property syntax with functions really has nothing to do with @property. It's just based on the signature that a function has. If it's a free function, and it has a return value but no arguments, without using UFCS, it can be used as a getter int prop(); auto r = prop; If it has a single argument, or it returns by ref, then it can be used as a setter. ref int prop(); int prop(int); void prop(int); all work with prop = 42; though the first two can also be used in chained assignment operations, since they also return a value, whereas the third can't be. e.g. auto foo = prop = 19; works with the first two but not the third. All of the same signatures as member functions also work in the same way except that you then get auto r = obj.prop; for the getter and obj.prop = 42; for the setter. And if they're free functions, and you want to use them with UFCS, then they each need one more parameter. e.g. int prop(MyObj); auto r = obj.prop; for the getter and ref int prop(MyObj); int prop(MyObj, int); void prop(MyObj, int); obj.prop = 42; for the setter. All of this works regardless of anything to do with @property and has had since well before @property existed (well, aside from using it with UFCS, since UFCS came later). However, a number of folks thought that it was too messy to allow any old function with the right set of parameters to be used with the property syntax rather than requiring that it be part of the API that it be a property function. Probably the most egregious case is that something like writeln = 42; works just fine, and writeln is clearly a function, not a function emulating a variable (which is what a property function is supposed to be). So, to improve the situation, @property was proposed. The idea was that functions marked with @property and the correct number of parameters would work as property functions and that they would _have_ to use the property syntax when being used, whereas functions that weren't marked with @property were not allowed to use the property syntax. The ad-hoc nature of the whole thing then goes away, and stuff like writeln = 42; is then illegal. It also fixes the problem where the function returns a callable (e.g. a delegate or a functor). If you have the function foo, and it returns a callable, as long as it's legal to call the function with the property syntax - foo - or without - foo() - there's no way to distinguish when the callable that's returned by the function should be called. If foo is treated as a property, then foo() would call the callable that foo returned, whereas if it's treated as a function, then it would be foo()(). Without a way to indicate
Re: Generically call a function on Variant's payload?
On 08/19/2018 08:27 PM, Nick Sabalausky (Abscissa) wrote: Suppose I've wrapped a Variant in a struct/class which ensures the Variant *only* ever contains types which satisfy a particular constraint (for example: isInputRange, or hasLength, etc...). Is there a way to call a function (ex: popFront) on the Variant, *without* knowing ahead of time all the possible static types it might might contain? Maybe something involving using Variant.coerce to convert the payload to a single common type? Not sure how I would do that though.
Generically call a function on Variant's payload?
Suppose I've wrapped a Variant in a struct/class which ensures the Variant *only* ever contains types which satisfy a particular constraint (for example: isInputRange, or hasLength, etc...). Is there a way to call a function (ex: popFront) on the Variant, *without* knowing ahead of time all the possible static types it might might contain?
Re: Using .length returns incorrect number of elements
On Sunday, 19 August 2018 at 16:03:06 UTC, QueenSvetlana wrote: On Sunday, 19 August 2018 at 15:53:25 UTC, Chris M. wrote: On Sunday, 19 August 2018 at 15:49:18 UTC, Chris M. wrote: On Sunday, 19 August 2018 at 15:44:07 UTC, QueenSvetlana wrote: [...] auto appendNumber = appender(arrayofNumbers); This returns a separate object. You probably meant to put this for the last line writeln(appendNumber.length); Whoops writeln(appendNumber.data.length); https://run.dlang.io/is/4aNx1l New to d programming here :D Bare with me. The object that is returned by appendNumber.data is an array reflecting the elements I added using appendNumber correct? So I would have the call length on appendNumber.data instead of the original array? I suggest reading the D tour's page on arrays: https://tour.dlang.org/tour/en/basics/arrays In short, D arrays (more correctly called slices) are structs that look like this: struct Slice(T) { T* ptr; size_t length; } As the name Slice indicates, it represents a slice of memory, with a beginning address and a length. If you have two int[] instances (let's call them A and B) that point to the same data, they have their own copy of the ptr and length fields, and changing the value of a field in A will not change the corresponding field in B. When you append to A, what's happening* is the length is increased, and the appended data is written to the end of the memory pointed to. B does not see this, since it only looks at the first elements of that block. -- Simen * Plus some checking of the length of the block of memory it's pointing to, and possible reallocation if the block isn't big enough.
Re: Are properties mature enough?
On 08/19/2018 08:55 PM, Neia Neutuladh wrote: You *could* add @property to the next and seed functions. That forces people to use them as fields. It doesn't.
Re: Are properties mature enough?
On Sunday, 19 August 2018 at 18:32:17 UTC, QueenSvetlana wrote: In the D Style Guide, it says: Properties https://dlang.org/dstyle.html#properties Functions should be property functions whenever appropriate. In particular, getters and setters should generally be avoided in favor of property functions. And in general, whereas functions should be verbs, properties should be nouns, just like if they were member variables. Getter properties should not alter state. In the Properties function section, it says: https://dlang.org/spec/function.html#property-functions WARNING: The definition and usefulness of property functions is being reviewed, and the implementation is currently incomplete. Using property functions is not recommended until the definition is more certain and implementation more mature. So which is it? The `@property` annotation might not remain in the language. However, the property call syntax for functions will remain. So you can write: --- struct Random { private int value; int next() { value++; return value; } void seed(int value) { this.value = value; } } Random r; r.seed = 21; writeln(r.next); --- That's going to work forever. You *could* add @property to the next and seed functions. That forces people to use them as fields. However, there's some discussion about how that's going to be handled in the future. So you might want to leave it off.
Are properties mature enough?
In the D Style Guide, it says: Properties https://dlang.org/dstyle.html#properties Functions should be property functions whenever appropriate. In particular, getters and setters should generally be avoided in favor of property functions. And in general, whereas functions should be verbs, properties should be nouns, just like if they were member variables. Getter properties should not alter state. In the Properties function section, it says: https://dlang.org/spec/function.html#property-functions WARNING: The definition and usefulness of property functions is being reviewed, and the implementation is currently incomplete. Using property functions is not recommended until the definition is more certain and implementation more mature. So which is it?
Re: Using .length returns incorrect number of elements
On Sunday, 19 August 2018 at 16:03:06 UTC, QueenSvetlana wrote: On Sunday, 19 August 2018 at 15:53:25 UTC, Chris M. wrote: On Sunday, 19 August 2018 at 15:49:18 UTC, Chris M. wrote: On Sunday, 19 August 2018 at 15:44:07 UTC, QueenSvetlana wrote: [...] auto appendNumber = appender(arrayofNumbers); This returns a separate object. You probably meant to put this for the last line writeln(appendNumber.length); Whoops writeln(appendNumber.data.length); https://run.dlang.io/is/4aNx1l New to d programming here :D Bare with me. The object that is returned by appendNumber.data is an array reflecting the elements I added using appendNumber correct? So I would have the call length on appendNumber.data instead of the original array? Yes, the .data field gives the array you're working on.
Re: Using .length returns incorrect number of elements
On Sunday, 19 August 2018 at 15:53:25 UTC, Chris M. wrote: On Sunday, 19 August 2018 at 15:49:18 UTC, Chris M. wrote: On Sunday, 19 August 2018 at 15:44:07 UTC, QueenSvetlana wrote: [...] auto appendNumber = appender(arrayofNumbers); This returns a separate object. You probably meant to put this for the last line writeln(appendNumber.length); Whoops writeln(appendNumber.data.length); https://run.dlang.io/is/4aNx1l New to d programming here :D Bare with me. The object that is returned by appendNumber.data is an array reflecting the elements I added using appendNumber correct? So I would have the call length on appendNumber.data instead of the original array?
Re: Using .length returns incorrect number of elements
On Sunday, 19 August 2018 at 15:49:18 UTC, Chris M. wrote: On Sunday, 19 August 2018 at 15:44:07 UTC, QueenSvetlana wrote: [...] auto appendNumber = appender(arrayofNumbers); This returns a separate object. You probably meant to put this for the last line writeln(appendNumber.length); Whoops writeln(appendNumber.data.length); https://run.dlang.io/is/4aNx1l
Re: Using .length returns incorrect number of elements
On Sunday, 19 August 2018 at 15:44:07 UTC, QueenSvetlana wrote: When using the .length property of a dynamic array why does it return the incorrect number of elements after I use the appender? import std.stdio; import std.array : appender; void main() { //declaring a dynamic array int [] arrayofNumbers; //append an element using the ~= syntax arrayofNumbers ~= 1; arrayofNumbers ~= 2; //print the array writeln(arrayofNumbers); //Using appender auto appendNumber = appender(arrayofNumbers); appendNumber.put(10); writeln(appendNumber.data); writeln(arrayofNumbers.length); } Output: [1, 2] [1, 2, 10] 2 --- > Should be 3 auto appendNumber = appender(arrayofNumbers); This returns a separate object. You probably meant to put this for the last line writeln(appendNumber.length);
Using .length returns incorrect number of elements
When using the .length property of a dynamic array why does it return the incorrect number of elements after I use the appender? import std.stdio; import std.array : appender; void main() { //declaring a dynamic array int [] arrayofNumbers; //append an element using the ~= syntax arrayofNumbers ~= 1; arrayofNumbers ~= 2; //print the array writeln(arrayofNumbers); //Using appender auto appendNumber = appender(arrayofNumbers); appendNumber.put(10); writeln(appendNumber.data); writeln(arrayofNumbers.length); } Output: [1, 2] [1, 2, 10] 2 --- > Should be 3
Re: Static initialization of static arrays is weird
On Sunday, 19 August 2018 at 12:10:08 UTC, kinke wrote: I think the spec is pretty clear; the elements of the right-hand-side initializer array are interpreted as per-element initializer, i.e., `result[0] = 2, result[1] = 1` (rest: default-init). I can't find where in the spec it says that the elements of the right-hand-side initializer array are interpreted as per-element initializer, or that the rest will be default initialized. But that would mean that this works: ``` int[3][3] arr = 0; ``` And it does for a local variable, but for a struct member it says (both dmd and ldc): ``` cannot implicitly convert expression 0 of type int to int[3][3] ``` So that should be fixed too.
Re: Static initialization of static arrays is weird
On Sunday, 19 August 2018 at 11:20:41 UTC, Dennis wrote: I have a two dimensional static array in a game board struct and want to explicitly set the default value for each cell. Now typing the whole 9x9 array out would be cumbersome and I can't change the default constructor of a struct, so I played around with initializers and found some... strange behavior. Demo: ``` import std.stdio: writeln; struct T { int[3][3] arr = [2, 1]; this(int stub) { arr[0][0] = 9; } } void main() { T.init.writeln; T(0).writeln; } ``` Output: ``` T([[2, 1, 0], [0, 0, 118033674], [723976, 0, 4100]]) T([[9, 2, 2], [1, 1, 1], [0, 0, 0]]) ``` So it seems that in the .init value, it puts [2, 1] in the first array and the rest is garbage. But in the constructor case, it filled the first two static arrays with 2 and 1 and the other one is 0 / garbage (can't tell). I turned to the spec: https://dlang.org/spec/arrays.html#static-init-static But that doesn't really help specify this case. Should I submit a bugzilla issue? I don't know what's supposed to happen here. I think the spec is pretty clear; the elements of the right-hand-side initializer array are interpreted as per-element initializer, i.e., `result[0] = 2, result[1] = 1` (rest: default-init). So (latest) LDC outputs ``` T([[2, 2, 2], [1, 1, 1], [0, 0, 0]]) T([[9, 2, 2], [1, 1, 1], [0, 0, 0]]) ``` DMD's T.init featuring garbage is clearly a bug, as is the divergence wrt. T.init and the initialization of the struct literal `T(0)` (which seems to be correct, initializing like LDC, but only starting with v2.072). With a non-literal, `auto t = T(0); t.writeln();`, the result is `[[9, 1, 0], T.init>]` again. So please do file a bugzilla issue.
Static initialization of static arrays is weird
I have a two dimensional static array in a game board struct and want to explicitly set the default value for each cell. Now typing the whole 9x9 array out would be cumbersome and I can't change the default constructor of a struct, so I played around with initializers and found some... strange behavior. Demo: ``` import std.stdio: writeln; struct T { int[3][3] arr = [2, 1]; this(int stub) { arr[0][0] = 9; } } void main() { T.init.writeln; T(0).writeln; } ``` Output: ``` T([[2, 1, 0], [0, 0, 118033674], [723976, 0, 4100]]) T([[9, 2, 2], [1, 1, 1], [0, 0, 0]]) ``` So it seems that in the .init value, it puts [2, 1] in the first array and the rest is garbage. But in the constructor case, it filled the first two static arrays with 2 and 1 and the other one is 0 / garbage (can't tell). I turned to the spec: https://dlang.org/spec/arrays.html#static-init-static But that doesn't really help specify this case. Should I submit a bugzilla issue? I don't know what's supposed to happen here. And in the mean time, what's the easiest way to initialize a (2d) static array with a value?
Re: How to phrase RIP addressing in assembly under Linux AMD64
Okay, I see. I'll try with a shared library. I only have 3 or 4 algorithms that don't auto-vectorize well with modern compilers and have to be written by hand. Patreon have that terrible catch 22 tax form that stopped me writing for US magazines, rather unfortunate.
how to build DSFMLC ?
I keep having the same problem with building DSFMLC https://ibb.co/edRStK
Re: How to phrase RIP addressing in assembly under Linux AMD64
On Sunday, 19 August 2018 at 07:18:20 UTC, Sean O'Connor wrote: How to I phrase RIP addressing in assembly under Linux AMD64 in D. I can't seem to figure it out. Normally I do something like: movq rax,rndphi[rip] Where rndphi is a label pointing to data. I know I have change movq to mov in D and hope the operation works on all 64 bits. If for some reason it is not possible in D I can still put all my special vectorized code in a shared library and access it that way. In fact I should code it on a GPU where it likely would run 100 times faster. Maybe I should set up a Patreon account and see if there are any true believers in evolution out there. https://github.com/S6Regen/Thunderbird Hello, there's an issue opened https://issues.dlang.org/show_bug.cgi?id=17617. RIP is not available ATM.
How to phrase RIP addressing in assembly under Linux AMD64
How to I phrase RIP addressing in assembly under Linux AMD64 in D. I can't seem to figure it out. Normally I do something like: movq rax,rndphi[rip] Where rndphi is a label pointing to data. I know I have change movq to mov in D and hope the operation works on all 64 bits. If for some reason it is not possible in D I can still put all my special vectorized code in a shared library and access it that way. In fact I should code it on a GPU where it likely would run 100 times faster. Maybe I should set up a Patreon account and see if there are any true believers in evolution out there. https://github.com/S6Regen/Thunderbird