Re: non-constant expression ["foo":5, "bar":10, "baz":2000]
On Sunday, 27 November 2016 at 22:25:51 UTC, John Colvin wrote: On Saturday, 26 November 2016 at 17:37:57 UTC, Paolo Invernizzi wrote: This is stated in documentation [1]: immutable long[string] aa = [ "foo": 5, "bar": 10, "baz": 2000 ]; unittest { assert(aa["foo"] == 5); assert(aa["bar"] == 10); assert(aa["baz"] == 2000); } But results to: Error: non-constant expression ["foo":5L, "bar":10L, "baz":2000L] Known bug? If yes, Is there the need to emend the documentation, till the bug is open? --- /Paolo Known bug. If you need a workaround, initialising the variable at load-time with `static this` should help in some cases. Thank Joan, The point is that I was trying to avoid some cycle between modules, detected by 2.072. This bug leads to pollution in the use of static this only to workaround the limitation... -- Paolo
Re: Parsing a string to instantiate classes at runtime
On 2016-11-27 22:19, Marduk wrote: Sure, it's here: http://forum.dlang.org/post/xmnnsdiuwyjrhkasy...@forum.dlang.org In that thread they also mention Object.factory, but the documentation says that the class must have either no constructor or the default constructor, which is not my case. It's possible to bypass the constructors [1]. [1] https://github.com/jacob-carlborg/orange/blob/master/orange/util/Reflection.d#L166 -- /Jacob Carlborg
Use class template as a type
Hi. Is it possible to write in D something like this? ``` abstract class MyClass(T) { public: @property const(T) value(){return _value;} @property void value(T val){_value = val;} ... private: T _value; ... } ... class MyClassFloat: MyClass!float ... class MyClassInt: MyClass!int ... void main() { MyClass[] someArray; someArray ~= new MyClassFloat(); ... someArray ~= new MyClassInt(); ... foreach(myClass; someArray) if(typeid(myClass) == typeid(MyClassInt)) myClass.value = 999; else myClass.value = 123.45f; ... } ``` When I trying to compile code like above I got Error: class MyClass(T) is used as a type.
Re: Use class template as a type
In your case I'd just swap out ``MyClass[] someArray;`` to ``Object[] someArray;``. But only because there are no members added without the extra typing in MyClass. Remember types in meta-programming in D are not erased, they exist in the assembly and are unique. Unlike Java who did the implementation rather wrong.
Re: Use class template as a type
On Monday, 28 November 2016 at 11:26:41 UTC, dm wrote: Hi. Is it possible to write in D something like this? ``` abstract class MyClass(T) { public: @property const(T) value(){return _value;} @property void value(T val){_value = val;} ... private: T _value; ... } ... class MyClassFloat: MyClass!float ... class MyClassInt: MyClass!int ... void main() { MyClass[] someArray; ---^ someArray ~= new MyClassFloat(); ... someArray ~= new MyClassInt(); ... foreach(myClass; someArray) if(typeid(myClass) == typeid(MyClassInt)) myClass.value = 999; else myClass.value = 123.45f; ... } ``` When I trying to compile code like above I got Error: class MyClass(T) is used as a type. Thats because MyClass is a template class. Templates are note types, instansiations of templates can be types. e.g. Myclass!float[] arr; // note this is not MyClass!(float[]); will work. As Rikki suggested using Object[] instead will allow use to store classes of different types.
Re: Use class template as a type
On Monday, 28 November 2016 at 11:30:23 UTC, rikki cattermole wrote: In your case I'd just swap out ``MyClass[] someArray;`` to ``Object[] someArray;``. But only because there are no members added without the extra typing in MyClass. Remember types in meta-programming in D are not erased, they exist in the assembly and are unique. Unlike Java who did the implementation rather wrong. I'm tried to use Object[], but got error Error: no property 'value' for type 'object.Object' I guess I must cast() to MyClassInt or MyClassFloat, but how can I do it?
Re: Use class template as a type
On 29/11/2016 2:56 AM, dm wrote: On Monday, 28 November 2016 at 11:30:23 UTC, rikki cattermole wrote: In your case I'd just swap out ``MyClass[] someArray;`` to ``Object[] someArray;``. But only because there are no members added without the extra typing in MyClass. Remember types in meta-programming in D are not erased, they exist in the assembly and are unique. Unlike Java who did the implementation rather wrong. I'm tried to use Object[], but got error Error: no property 'value' for type 'object.Object' I guess I must cast() to MyClassInt or MyClassFloat, but how can I do it? We have a handy dandy syntax for this: if (MyClassInt subclass = cast(MyClassInt)value) { writeln(subclass.value); } If it doesn't cast to said type (it will be null) that branch won't execute.
Re: Use class template as a type
Thats because MyClass is a template class. Templates are note types, instansiations of templates can be types. e.g. Myclass!float[] arr; // note this is not MyClass!(float[]); will work. As Rikki suggested using Object[] instead will allow use to store classes of different types. Maybe I must use some stub class or interface and override all methods... But I so like D templates, as a result it's a small and easy to understand code. Or actually it's maybe a XY problem. I'm trying to implement OpenGL material manager and for OpenGL uniforms I tried to write: ``` abstract class Uniform(T) @property ... @property ... T _val;... void method()... ... class FloatUniform: Uniform!float ... override void method()... And in material class class Material ... Texture[] textures; Uniform[] uniforms; ... ``` Maybe i'm totally wrong and better just use glUniformXXX... in my main app instead of ``` auto uniform = new SomeTypeUniform... ... uniform.value = someValue; ``` ?
Re: Use class template as a type
We have a handy dandy syntax for this: if (MyClassInt subclass = cast(MyClassInt)value) { writeln(subclass.value); } If it doesn't cast to said type (it will be null) that branch won't execute. Hell yeah! It's works! Thank you!
Re: Use class template as a type
We have a handy dandy syntax for this: if (MyClassInt subclass = cast(MyClassInt)value) { writeln(subclass.value); } If it doesn't cast to said type (it will be null) that branch won't execute. Just out of interest: it looks like a dynamic_cast in C++ which is considered as slow operation. Is that D cast also a dynamic cast and also slow? I've never used it, so I'm a bit curious.
Re: non-constant expression ["foo":5, "bar":10, "baz":2000]
On Monday, 28 November 2016 at 09:06:34 UTC, Paolo Invernizzi wrote: The point is that I was trying to avoid some cycle between modules, detected by 2.072. This bug leads to pollution in the use of static this only to workaround the limitation... Wasn't someone working on a Associative Array static type that could be created at CTFE and run at runtime?
Re: the best language I have ever met(?)
On Saturday, November 26, 2016 00:43:04 Artur Skawina via Digitalmars-d- learn wrote: > IOW you want to improve IFTI, so that `n` is inferred from the > length of the passed argument. That would indeed work for array > literals and CTFE-able expressions. Any improvement to IFTI is a > good thing, but the RT cost of this helper could be high if it ever > doesn't get inlined and completely optimized away. That's what pragma(inline, true) is for. And if someone wants a different solution that's completely compile-time and doesn't work with variables, then fine. I'm talking about adding something to the standard library, and for that, I think that a solution that is as close as possible to being identical to simply declaring the static array with the length is what would be appropriate. > If the cost isn't an issue and a different syntax is acceptable > then this should already work: > >template staticArray(T, E...) { > T[E.length] staticArray() @property { return [E]; } >} >template staticArray(E...) { > typeof([E][0])[E.length] staticArray() @property { return [E]; } >} > >ubyte a; >auto sa = staticArray!(ubyte, 1, 2, 3, 4, a); >auto sb = staticArray!(1, 2, 3, 4, a); I'm not married to the syntax. I tried that syntax, but I couldn't figure out how to get it to work with runtime values. The closest that I could come up with was what I showed before, and the fact that IFTI wasn't smart enough with VRP was the only blocker. It looks like you've found a way to do it with all template arguments though, which is fine with me. - Jonathan M Davis
Re: Use class template as a type
On 29/11/2016 3:35 AM, Namespace wrote: We have a handy dandy syntax for this: if (MyClassInt subclass = cast(MyClassInt)value) { writeln(subclass.value); } If it doesn't cast to said type (it will be null) that branch won't execute. Just out of interest: it looks like a dynamic_cast in C++ which is considered as slow operation. Is that D cast also a dynamic cast and also slow? I've never used it, so I'm a bit curious. I wouldn't worry about it. You're already using classes and they are dog slow in general.
Re: How to get hash value of an object?
On 11/27/16 2:10 AM, panmengh wrote: How to get hash value of an object? Use hashOf? or typeid(T).getHash(&o)? hashOf is kind of this horrible hacky thing that nobody should be using. It literally takes whatever you pass it and hashes the local bytes. It doesn't care about opHash or if any of those bytes are actually references to the things you want hashed. In fact, for class references, it just hashes the bytes that point at the class. Useless. Long story short, use typeid(T).getHash(&o). Does only hashOf with ldc2 return the right value? If it does, that's a coincidence. Happened to allocate in the same place. -Steve
Re: Use class template as a type
On Monday, 28 November 2016 at 14:35:36 UTC, Namespace wrote: We have a handy dandy syntax for this: if (MyClassInt subclass = cast(MyClassInt)value) { writeln(subclass.value); } If it doesn't cast to said type (it will be null) that branch won't execute. Just out of interest: it looks like a dynamic_cast in C++ which is considered as slow operation. Is that D cast also a dynamic cast and also slow? I've never used it, so I'm a bit curious. The cast from a class type to a sub class in itself does absolutely nothing. It has only an effect when you call a virtual method. This is slow because of the indirection that happens when the right offset has to be found in the VTBL.
Re: Parsing a string to instantiate classes at runtime
On Sunday, 27 November 2016 at 21:28:52 UTC, ag0aep6g wrote: Ok, that's a hypothetical. It's "if D had a 'dynamic mixin', then we could do fancy things with it." D doesn't have a 'dynamic mixin', so you can't do those fancy things, at least not in the envisioned way. You are right. I misread.
Re: Parsing a string to instantiate classes at runtime
On Monday, 28 November 2016 at 09:33:08 UTC, Jacob Carlborg wrote: It's possible to bypass the constructors [1]. [1] https://github.com/jacob-carlborg/orange/blob/master/orange/util/Reflection.d#L166 Aha! Interesting. Thanks.
Re: Instantiating a class with different types at runtime
On Sunday, 27 November 2016 at 21:06:58 UTC, ag0aep6g wrote: Turn Example into a template, and add a free function for nice construction: class Example(Type_left, Type_right) { /* ... as you had it ... */ } Example!(L, R) makeExample(L, R)(L x, R y) { return new Example!(L, R)(x, y); } void main() { auto foo = makeExample(1, 2); auto bar = makeExample(3, "baz"); } Note that Example is not a type, but a template. That means, foo and bar have different types, because their types are different instantiations of the Example template. You can define a common interface or (possibly abstract) base class. Great! Many thanks.
Re: Instantiating a class with different types at runtime
On Sunday, 27 November 2016 at 20:57:28 UTC, Namespace wrote: class Example(L, R) { L _left; R _right; this(L l, R r) { _left = l; _right = r; } } That was fast! But I needed the second reply in order to understand yours. Thanks anyway.
Re: Parsing a string to instantiate classes at runtime
On 2016-11-29 07:46, Marduk wrote: Aha! Interesting. Thanks. Then you can call a custom method that acts as a constructor when the instance is created this way, if there's a need for it. -- /Jacob Carlborg