Re: How to build a specific library version with dub?
On Sunday, 11 April 2021 at 15:01:04 UTC, Mike Parker wrote: On Sunday, 11 April 2021 at 13:43:47 UTC, martinm wrote: I'm trying to use wayland-d which depends on derelict-util-2.0.6. DUB can't download the zip and fails. I download the zip to ~/.dub/packages/derelict-util folder, unzip and build. DUB builds **DerelictUtil.a ~master**. That's not how to go about this. You should never need to manually install a library for dub to use it. I think so, too but when it's not working what can I do. I wrote 2. sentence DUB fails can't download, timeout and fails. Assuming you mean this library: https://github.com/rtbo/wayland-d Yes that one. It's the DerelictUtil dependency is configured as ~>2.0.3. This syntax means >= 2.0.3 and < 2.1.0. So when you build the wayland package for the first time, dub should pick up the latest version in the 2.0.x series without any special help from you. Like said before. DUB download does not work. Trying to rebuild wayland-d, DUB can't find **derelict-util-2.0.6** dependency. *dub list | grep -i derelict* shows: *derelict-util ~master ~/.dub/packages/derelict-util-2.0.6/derelict-util/* is there. Dub is picking up `~master` in this case because you **manually** copied DerelictUtil into the .dub directory from the zip file. Dub has absolutely no way to know what version of the library that is un less you tell it (see below). Yes, I download DerelictUtil v. 2.0.6 release from github, unzip in .dub/packages and build myself. How can DUB build 2.0.6 version ? *dub build library@2.0.6* fails *(1) : Error: Got JSON of type null_, expected object.* Have you modified DerelictUtil's dub.json in any way? I just ran `dub build` on the 2.0 branch of DerelictUtil and built 2.0.6 without error. Yes, I added "version": "2.0.6" to dub.json and 2.0.6 is now correctly in registry. How can I change registry and manually change **~master** to **2.0.6** ? IMO, the best thing to do is to delete the DerelictUtil folder you unzipped and let dub pull down DerelictUtil automatically, then it will know it has 2.0.6. DUB still fails to download file itself. Maybe DUB should try GITHUB like I did. However, whenever you want to manually install a package, you don't have to put the source files in the .dub directory. You can put them anywhere on your system, then use the dub command line to add that folder to your local registry and specify the version. Something like: `dub add-local . --version=2.0.6`. You could also just run `dub fetch derelict-util --version=2.0.6`. This is good advice. Thank you. I know my way is bad but it works for me and I prefer Makefile than DUB. Makefile can be complex but if problem I search in internet and 5 or 10 minutes later problem is solved. DUB is good when works but when not I see ??? I search in internet and find nothing and need come to forum and after 1h, problem can be fixed or not. But thank you for explanation.
Re: Range Error
On Sunday, 11 April 2021 at 19:48:42 UTC, Ruby The Roobster wrote: On Sunday, 11 April 2021 at 19:45:30 UTC, Ruby The Roobster wrote: What am I doing wrong here? Is it the 'for' loop? Nevermind. I messed up what line it was. It was actually this line: ```d square[i][j] = new Square(Color.none, sColor.white); ``` This is maybe interesting for you: https://wiki.dlang.org/Component_programming_with_ranges
Re: How do I create classes dynamically?
On 4/14/21 1:38 PM, Mario wrote: > Maybe I am just too short in D, but I wanted to find out if it is > possible to create classes dynamically. In D world, "dynamically" means "at run time". > Maybe at mixin templates? Both mixins and templates are compile time features. > Normally I would think of a macro first If we are talking about C (and C++) macros, they are compile time features as well. So, I think you want help from D to generate types, which can happen only at compile time with statically-typed languages like D. And yes, D is a great language for "generative programming" like that. > "I was not written, but still I exist!" Not possible by this "programming language", which wants a source code written, by a human or a machine, to be compiled. Still, anything is possible: For example, you can generate source code, dispatch a compiler, and load dynamically at run time. :) Ali
Re: How do I create classes dynamically?
On Wednesday, 14 April 2021 at 20:38:16 UTC, Mario wrote: Maybe I am just too short in D, but I wanted to find out if it is possible to create classes dynamically. My problem is, I just don't know where to start reading. Maybe at mixin templates? CreateClassWithName!("MyDynamicClassName"); should create the following class to work with dynamically: class MyDynamicClassName { this() { writeln("I was not written, but still I exist!"); } } So that I in the end by means of MyDynamicClassName cls = new MyDynamicClassName; can work with it. Normally I would think of a macro first, but as far as I understood D doesn't know macros (which I'm not really sad about), but maybe I'm just thinking too complicated yet. I would appreciate any hints, because as I said, I don't even know where to start reading. ldc.JIT presumably has smth like that https://gist.github.com/eldar/2294388 Also look up ldc.dynamic_compile
Re: How do I create classes dynamically?
On Wednesday, 14 April 2021 at 20:38:16 UTC, Mario wrote: Maybe I am just too short in D, but I wanted to find out if it is possible to create classes dynamically. My problem is, I just don't know where to start reading. Maybe at mixin templates? CreateClassWithName!("MyDynamicClassName"); should create the following class to work with dynamically: class MyDynamicClassName { this() { writeln("I was not written, but still I exist!"); } } So that I in the end by means of MyDynamicClassName cls = new MyDynamicClassName; String mixins is D replacement of macros for code generation. Works like this: ```d mixin("class MyDynamicClassName { }"); MyDynamicClassName cls = new MyDynamicClassName; ```
Re: How do I create classes dynamically?
On Thursday, 15 April 2021 at 16:39:30 UTC, Kagamin wrote: On Wednesday, 14 April 2021 at 20:38:16 UTC, Mario wrote: Maybe I am just too short in D, but I wanted to find out if it is possible to create classes dynamically. My problem is, I just don't know where to start reading. Maybe at mixin templates? CreateClassWithName!("MyDynamicClassName"); should create the following class to work with dynamically: class MyDynamicClassName { this() { writeln("I was not written, but still I exist!"); } } So that I in the end by means of MyDynamicClassName cls = new MyDynamicClassName; String mixins is D replacement of macros for code generation. Works like this: ```d mixin("class MyDynamicClassName { }"); MyDynamicClassName cls = new MyDynamicClassName; ``` Yes but not at runtime
Re: How do I create classes dynamically?
On Wednesday, 14 April 2021 at 20:38:16 UTC, Mario wrote: I wanted to find out if it is possible to create classes dynamically. out of curiosity: Why you would like to do this? I cannot think of a use case for this - this is why i ask.
AliasSeq different from just using the symbol name(s)?
I've tried to group together a bundle of alias template parameters with AliasSeq, but while without it works just fine, when the verbose parameters are grouped with multiple AliasSeqs, the lengths of the array parameters passed through AliasSeq are 0(inside the templated function, before the call it's still OK) and a range violation/exception occurs. This is weird because the templated function does not change the length of its array parameters, and printing the parameter's string name to stdout at runtime shows that they are supposedly the same(in symbol name at least), but somehow it isn't the same? To see what i mean : https://run.dlang.io/is/VXDRL4 (i could not manage to trigger it here however.) Big thanks
Re: AliasSeq different from just using the symbol name(s)?
On Thursday, 15 April 2021 at 18:43:29 UTC, z wrote: To see what i mean : https://run.dlang.io/is/VXDRL4 (i could not manage to trigger it here however.) Without an example that shows the actual problem you encountered, it will be almost impossible for anyone to help you figure out what is causing it. Since you were not able to trigger it, it seems likely that the problem is related to something other than the AliasSeq which you have left out of the example.
Re: AliasSeq different from just using the symbol name(s)?
On Thursday, 15 April 2021 at 18:58:40 UTC, Paul Backus wrote: Without an example that shows the actual problem you encountered, it will be almost impossible for anyone to help you figure out what is causing it. Since you were not able to trigger it, it seems likely that the problem is related to something other than the AliasSeq which you have left out of the example. I understand that it won't be possible to pinpoint the cause without a reduced test case, but : ```D int[] a,b,c,d,e; void templatef(args...){/*...*/} //... auto seq = AliasSeq!(b,c,d); templatef!(a,seq,e); templatef!(a,b,c,d,e); //am i being mistaken for thinking these two template calls should be equivalent in behavior? ``` And if not, does it mean that the problem i encountered is a possible bug?
Re: AliasSeq different from just using the symbol name(s)?
On Thursday, 15 April 2021 at 19:38:04 UTC, z wrote: ```D int[] a,b,c,d,e; void templatef(args...){/*...*/} //... auto seq = AliasSeq!(b,c,d); templatef!(a,seq,e); templatef!(a,b,c,d,e); //am i being mistaken for thinking these two template calls should be equivalent in behavior? ``` woops, meant `void templatef(args...)(){}`
Re: AliasSeq different from just using the symbol name(s)?
On Thursday, 15 April 2021 at 19:38:04 UTC, z wrote: I understand that it won't be possible to pinpoint the cause without a reduced test case, but : ```D int[] a,b,c,d,e; void templatef(args...){/*...*/} //... auto seq = AliasSeq!(b,c,d); templatef!(a,seq,e); templatef!(a,b,c,d,e); //am i being mistaken for thinking these two template calls should be equivalent in behavior? ``` And if not, does it mean that the problem i encountered is a possible bug? They're not *exactly* the same. When you write auto seq = AliasSeq!(a, b, c); ...you are declaring a sequence of three *new* array variables [1] and initializing them with copies of the original arrays. It's as though you'd written: auto seq_a = a; auto seq_b = b; auto seq_c = c; alias seq = AliasSeq!(a, b, c); If you want to refer directly to the original variables, you need to create your sequence with `alias` instead of `auto`: alias seq = AliasSeq!(a, b, c); [1] https://dlang.org/articles/ctarguments.html#type-seq-instantiation
Re: How do I create classes dynamically?
On Thursday, 15 April 2021 at 18:21:16 UTC, Martin wrote: On Wednesday, 14 April 2021 at 20:38:16 UTC, Mario wrote: I wanted to find out if it is possible to create classes dynamically. out of curiosity: Why you would like to do this? I cannot think of a use case for this - this is why i ask. In response to user input? e.g. createObject(userInputString); of course, one can manually dispatch: if (userInputString == "cat") createCat(); else if (userInputString == "dog") createDog(); ... but this this tedious. I have a similar question: how to dynamically use user's input string as function name can call it? suppose the function has no argument. callFunc(userInputString)(); // call that func. again, one can manually dispatch, but is there a way to avoid this tediousness?
Re: How do I create classes dynamically?
On Thu, Apr 15, 2021 at 08:56:18PM +, mw via Digitalmars-d-learn wrote: [...] > of course, one can manually dispatch: > > if (userInputString == "cat") createCat(); > else if (userInputString == "dog") createDog(); > ... > > but this this tedious. --- // Disclaimer: this is proof of concept, I didn't actually run this yet class Animal {} class Cat : Animal {} class Dog : Animal {} alias SupportedTypes = AliasSeq!(Cat, Dog, /* whatever else you want here */); string userInputString = ...; Animal result; SW: switch (userInputString) { static foreach (T; SupportedTypes) { case T.stringof: result = new T; break SW; } default: throw new Exception("Unknown object type"); } --- > I have a similar question: how to dynamically use user's input string > as function name can call it? suppose the function has no argument. Same idea: --- // Disclaimer: this is proof of concept, I didn't actually run this yet struct Dispatcher { void bark() { ... } void meow() { ... } void moo() { ... } ... // whatever else you want here } Dispatcher disp; string userInputString = ...; SW: switch (userInputString) { static foreach (fieldName; __traits(allMembers, disp)) { static if (is(typeof(__traits(getMember, disp, fieldName)) == function) { case fieldName: __traits(getMember, disp, fieldName)(); break SW; } } } --- Basically, the idea is to obtain a list of types/methods/whatever somehow (either by explicitly listing instances, or via compile-time introspection), then statically generate switch cases from it. You can eliminate many kinds of boilerplate using this little trick. T -- Береги платье снову, а здоровье смолоду.
Re: How do I create classes dynamically?
On Thursday, 15 April 2021 at 17:48:02 UTC, Imperatorn wrote: On Thursday, 15 April 2021 at 16:39:30 UTC, Kagamin wrote: On Wednesday, 14 April 2021 at 20:38:16 UTC, Mario wrote: [...] String mixins is D replacement of macros for code generation. Works like this: ```d mixin("class MyDynamicClassName { }"); MyDynamicClassName cls = new MyDynamicClassName; ``` Yes but not at runtime Could you give an example of what you're trying to archive?
Re: How do I create classes dynamically?
On 4/15/21 1:56 PM, mw wrote: >>> I wanted to find out if it is possible to create classes dynamically. >> >> out of curiosity: Why you would like to do this? I cannot think of a >> use case for this - this is why i ask. > > In response to user input? That's a different question because creating a class is different from creating instances (objects) of existing classes. > again, one can manually dispatch, but is there a way to avoid this > tediousness? H. S. Teoh showed methods where lookup keys are known at compile time and are used to generate e.g. a switch statement. I have a system where the main logic of the program has no idea what types are out there. All it has is a lookup table. (Uncompiled pseude code follows.) struct Functions { void * function deserialize(ubyte[] bytes); void function process(void* input, void* output); void function serialize(ubyte[] bytes); } shared Functions[string] registration; So, the main logic uses user input to look up what the functions are: auto funcs = registration[userInput]; And applies those functions to some data at runtime. This is "dynamic" because registration is populated by the 'shared static this()' blocks of unknown modules that are loaded dynamically (and in my case conditionally): module foo; // This struct is what this module is about: struct Foo { // ... } // The module registers itself with the main lookup system when loaded: shared static this() { register("my lookup string", Functions(&deserializer!Foo, &processor!Foo, &serializer!Foo)); } Note that registered functions are template instances tailored for this specific type. However, the main logic has no klowledge of individual modules, not even the templates like 'deserializer': It only knows about a lookup table that contains some function pointers. I haven't used object creation functions above but that can be added to Functions as well. Ali
How to implement a range?
In order to my array class work with filter, I went to implement an ``InputRange``. But I don't quite get how do that and didn't find much help on the docs. From below code, is ``moveFront()`` implemented correctly? I'm using a simple int i as index of current item and in popFront() just increment it. I must reset the i value once the loop is done, right? where am I supposed to do that? opApply()? not properly reseting it result in obvious bugs like subsequent calls doesn't work because the index is in the end of the array: ```d auto arr = new MyArray!int; arr.Add(1); arr.Add(2); arr.Add(3); arr.Add(4); auto r = arr.filter!(n => (n % 2) == 0); auto r2 = arr.filter!(n => n >= 2); writeln(r); // ok writeln(r2); // empty ``` yeah, i'm a bit confused... here's the code: ```d class MyArray(T) : InputRange!T { private T[] arr; private int i = 0; void Add(T item) { arr ~= item; } void Add(T[] items) { foreach(item; items) { Add(item); } } size_t length() nothrow { return arr.length; } bool empty() { return i == length; } T front() { return arr[i]; } void popFront() { i++; } T moveFront() { auto r = front; popFront(); return r; } int opApply(scope int delegate(ref T) dg) { int result = 0; foreach (item; arr) { result = dg(item); if (result) { break; } } return result; } int opApply(scope int delegate(T) dg) { int result = 0; foreach (item; arr) { result = dg(item); if (result) { break; } } return result; } int opApply(scope int delegate(uint, T) dg) { int result = 0; foreach (j, item; arr) { result = dg(j, item); if (result) { break; } } return result; } } ```
Re: How to implement a range?
On Friday, 16 April 2021 at 06:21:35 UTC, Jack wrote: In order to my array class work with filter, I went to implement an ``InputRange``. But I don't quite get how do that and didn't find much help on the docs. From below code, is ``moveFront()`` implemented correctly? I'm using a simple int i as index of current item and in popFront() just increment it. I must reset the i value once the loop is done, right? where am I supposed to do that? opApply()? not properly reseting it result in obvious bugs like subsequent calls doesn't work because the index is in the end of the array: Generally, you don't want your containers to be ranges themselves. You want them to produce ranges, i.e., separate the duties of iteration from the duties of the container. Also, it's best to make your range types as structs rather than classes for an easier time. A basic input range doesn't need to worry about `moveFront`. So you can get away with `empty`, `front`, and `popFront` on a struct. ```d import std.stdio; class MyArray(T) { private T[] _a; this(T[] a) { _a = a; }; auto opIndex() { return Range(_a[]); } private static struct Range { T[] a; T front() { return a[0]; } void popFront() { a = a[1 .. $]; } bool empty() { return a.length == 0; } } } void main() { auto ma = new MyArray!int([10, 20, 30, 44, 55]); foreach(i; ma[]) { writeln(i); } } ``` I've overloaded the slice operator via the no-arg `opIndex` to provide the range so that you can do `ma[]` to get to it. You'd want to expand on that to handle start & end points for a slice. But anyway, the whole idea behind ranges is you want to keep your iteration separate from the data. Then ranges can be copied around and consumed without every changing the original data structure.