Re: Deriving a struct from another one via template: Easy way to propagate UDAs?
On Saturday, 16 March 2024 at 13:09:13 UTC, Adam D Ruppe wrote: On Thursday, 14 March 2024 at 23:19:37 UTC, Inkrementator wrote: @(__traits(getAttributes, thingYouWantToForward)) void yourNewThing() {} Thanks, that should solve my problem. http://dpldocs.info/this-week-in-d/Blog.Posted_2020_01_20.html#understanding-mixin-templates Nice. Btw I vaguely remember you also wrote about how and why to reduce the usage string mixins, with some real example of alternative techniques you used, but I can't find it anymore. The search query 'site:dpldocs.info string mixin "This week in D"' as well as "site:arsdnet.net mixin" don't produce it. Can you link it to me?
Re: Deriving a struct from another one via template: Easy way to propagate UDAs?
On Friday, 15 March 2024 at 19:13:38 UTC, cc wrote: This is trivially easy if your types are visible at module level, and mixin is a fine tool for the job. It doesn't work quite so well with [Voldemort types](https://wiki.dlang.org/Voldemort_types). I used the following lines to make it work for Unknown and I think even Voldemort types. ```d static foreach(att; allFieldTypes){ //pragma(msg, "alias %s =att;\n".format(att.stringof)); mixin("alias %s = att;\n".format(att.stringof)); } ``` But I don't know how to do this (in a general) for UDAs, since they can be values instead of types too, i.e. @UDA(Voldemort!2(3))
Re: dub: Could not resolve configuration for package demo
On Friday, 15 March 2024 at 17:48:26 UTC, mw wrote: ``` $ dub build Could not resolve configuration for package demo ``` Trying to build your dependency msgpack-rpc, it spits out ``` Warning The sub configuration directive "vibe-d" -> [libevent] references a configuration that does not exist. Error Could not resolve configuration for package msgpack-rpc ``` In version 0.7, vibe-d depended on libevent, this got removed in the meantime https://github.com/vibe-d/vibe.d/commit/196096407ec27b2c107f0038c6751ce07e7a9507 Just patching msgpack-rpc dub.json to use the exact vibe-d version, and not a minimum, like this ```json "dependencies": { "msgpack-d": ">=0.9.2", "vibe-d": "==0.7.25" }, ``` fails too, because this old vibe-d version doesn't compile anymore. You'll have to either fix the old vibe-d version, or fork msgpack-rpc to work with current vibe-d, whatever is more appropriate and easier.
Deriving a struct from another one via template: Easy way to propagate UDAs?
Hello, I am trying to derive a struct from another. I want to modify each field such that type of it goes from some T to Nullable!T, preserving all fieldnames and UDAs. I think that fieldnames and UDAs can only be duplicated via string-mixins. This means that all field-types that aren't visible in the template scope have to first be aliased to some name that can be referenced in the string mixin. I got this to work for simple types, but as soon as the field types are some templated type, doing this naively stops to work. Same story for UDAs. As soon as multiple unknown types are involved, I can't simply take an alias anymore. The one workaround I found is to make my introspective struct part of a template mixin, this way it can access all symbols of the callsite and can use all the symbols. Is this the recommended way to do it? Generating a string mixin directly would probably work just as well, but that seems even more ugly and will probably be more susceptible to collisions. This not so simple gist demonstrates what I tried so far. injectedNameFields generates a string that when mixed in, will create all the field names with the desired types. I suggest first looking at main and compiling+running to get an idea what is supposed to happen. https://gitlab.com/-/snippets/3687470 After describing my problem, here is a non-exhaustive list of questions I have: * Is UDA propagation possible without string mixins? * To make it run without template mixin, I will need to write a recursive template (recursive over template args as well as UDA instantiated structs) that accounts for cases: normal type, templated type, enum (C style), enum value compile time constant, etc. ... Is this correct, or is there a way to just grab any compile time alias/enum without giving each "type" special treatment? * Are template mixins vulnerable to name collisions?
Re: Recommendation about templating engine library
On Monday, 11 March 2024 at 16:10:24 UTC, Andrea wrote: just trying it out and kinda fits my needs; the main issues are lack of documentation and the need to explicit loop on array data structures in the code (using sub-contexts) instead of having a "foreach" loop statement in the template itself; at the end the template turns out to be cleaner but you need to write some code to feed it the proper way. Having used djinn, it is "mostly unmaintained" because it is feature complete. It addresses your criticisms while potentially introducing new problems. It is very simple and the documentation is complete (due to the simplicity). It is easy to get into, because it just allows you to insert D code into textfiles. So constructs like foreach are a given, no need for subcontexts. this is what I came up as a quick hack: https://gist.github.com/ilmanzo/3163cad4e2246f2553f1a90735e79e6b In djinn, you wouldn't have to convert your struct to a dict first to use it. Your template would look something like this tests.d.dj ``` [: foreach(test; testcase){:] // --- [= test.description ] --- unittest { [:foreach(case, test.cases){ :] // Description: [= case.description ] ... }; [: }} :] ``` Then you'd have a main.d file with: ```d void main(){ // The template can use all your variables in the current scope due to being mixed in auto jsonString = stdin.byLineCopy.array.join; auto json = parseJSON(jsonString); string slug = json["exercise"].str; auto tests = fromJSON!(TestSuite[])(json["cases"]); auto output = stdout.lockingTextWriter(); // magic variable, output range that the template will write to mixin(translate!"tests.d.dj"); } ``` The boilerplate in your main function would be reduced, but the disadvantage is that is doesn't place constraints on you like mustache. If you insert place too much logic inside your template, it might become hard to reason about.
Re: Function Composition
On Thursday, 25 January 2024 at 18:44:26 UTC, atzensepp wrote: However this works: ```d int delegate (int) td = (x) => compose!(f,g,g,f,g,g,f,g,g,f)(x); ``` While not a real function pointer, this might already fit your needs. ```d alias td = compose!(f,g); ```
Re: DMD: How to compile executable without producing .obj file?
On Sunday, 5 November 2023 at 18:58:48 UTC, BoQsc wrote: When you compile using `dmd` compiler you will often get `.exe` and `.obj` file. I would like to only produce `.exe` file: On linux, gdc automatically cleans up object files by default. Passing it the -pipe option will prevent their creation in the first place. Maybe it will have the same behaviour on windows.
Re: Member field of type nested struct must be initialized in constructor: Why?
On Sunday, 22 October 2023 at 23:49:40 UTC, Paul Backus wrote: Nested structs contain a context pointer that needs to be initialized at runtime. If you don't initialize them, the pointer gets set to `null`, and the struct will not be able to access its context. I see, thanks for the explanation. Using `.init` doesn't fix this because `.init` is determined at compile time, and also has `null` in place of the context pointer. In my case, it makes sense to not initialize the object, so this isn't an issue. Void-initialization would probably be better to document my intent, but the compiler won't let me do that.
Re: Member field of type nested struct must be initialized in constructor: Why?
On Sunday, 22 October 2023 at 21:02:32 UTC, Inkrementator wrote: Running the code with `rdmd -version=fix app.d` works, but running `rdmd -version=fix app.d` produces: `Error: field `member` must be initialized in constructor, because it is nested struct` Sorry, obviously it should be: Running the code with `rdmd -version=fix app.d` works, but running just `rdmd app.d` produces: `Error: field `member` must be initialized in constructor, because it is nested struct`
Member field of type nested struct must be initialized in constructor: Why?
Consider this almost minimal example: ``` import std.algorithm; import std.range; import std.stdio; struct S(Nested){ Nested member; // = I.init; // Uncommenting this wouldn't help int g; this(Nested member){ this.member = member; } this(int g){ this.g = g; version(fix) member = Nested.init; } } // IFTI to handle type of map auto makeS(Nested)(Nested member) => S!(Nested)(member); import std.sumtype; // This just works and needs no fix auto makeSum(I)(I i) => SumType!(string, I)(i); void main(){ auto input = iota(5).map!(b => b + 1).map!(b => b - 1); auto s = makeS(input); auto s2 = makeSum(input); writeln(s); writeln(s2); } ``` Running the code with `rdmd -version=fix app.d` works, but running `rdmd -version=fix app.d` produces: `Error: field `member` must be initialized in constructor, because it is nested struct` Why? I didn't find anything about this in [the spec.](https://dlang.org/spec/struct.html#nested)
Re: Proper way to handle "alias this" deprecation for classes
On Sunday, 7 May 2023 at 21:12:22 UTC, Chris Piker wrote: On the other hand, your first suggestion of using opCast() does seem like a reasonable choice to me. Can you provide a short code snippet using opCast to achieve the same result? I've never used it, and particularly I know that I don't know whether making the the return type of opCast ref can lead to issues down the road and whether the template specialization is dangerous, as it will trigger for all types implicitly convertible to int* (whatever they are) Another potential future pitfall I discovered is that code might break if you change your class into a struct. Code example is in a gist since the system thinks I've added HTML entities to it and won't let me post it: https://gist.github.com/run-dlang/9b7aec72710b1108fc8277789776962a
Re: Proper way to handle "alias this" deprecation for classes
On Sunday, 7 May 2023 at 18:19:04 UTC, Ali Çehreli wrote: alias this is for implicit type conversions, which can be achieved explicitly as well. Open question to everybody: What you're opinion on using opCast for this? Since it's a type conversion, it seems fitting to me. And another suggestion: Wrap the class in a struct that has visibility on the class members via the "package" access specifier and continue using "alias this".
Re: Step by step tutorials for using bindings in D
On Monday, 27 March 2023 at 00:45:28 UTC, Salih Dincer wrote: Likes **17** Views **265** Released on March **8, 2023** I'm surprised that you can get 300 views in a month on a primarily D video, but it's nice to see
Re: Step by step tutorials for using bindings in D
On Sunday, 26 March 2023 at 18:49:57 UTC, eXodiquas wrote: On Sunday, 26 March 2023 at 14:09:19 UTC, Inkrementator wrote: But you said static bindings are the main portion of bindings we use. So I tried to get static Lua bindings going. Static Binding != Static Linking. Like I said, the terminology is not noob friendly and funnily enough, you might have taken away from the sentence the opposite of what is true. To statically bind, you have to do nothing in 99.9% of cases I have never encountered a library before that handles it like the one you posted and does offers dynamic binding. But for static/ dynamic *linking*, it's the opposite. If you don't type in a full path, but just `"libs": ["lua"]`, the compiler will by default pick the shared library if both static and shared are available. In general I would say it doesn't really matter until you want to distribute your app, then you have to think about it. So **TL;DR**: Don't bother with static linking. Just say `"libs": ["lua"]` and don't worry about it. In the following I try to explain what actually happens in the background, but understanding it is not important in the beginning. The following is only for your interest. `"lflags": ["-L/usr/local/lib/liblua.a"]` I'm surprised this worked, according to `man ld`, the -L flag takes a dir as input, not a full filepath. Can you please post your full dub config? I'm intrigued. This works perfectly fine. I can also use `"libs": ["lua"]` so I don't have to specify the complete path. But now I wonder, do I have to specify all static bindings via linker commands or is there a mechanism which allows me to specify a path where all the libraries can be found? And my other question is, if I have to specify all static libraries by name, how do I know the name of the library? Giving the system path as `lflag` is easy, but where does Lua get the `lua` name from which works in the `"libs": ["lua"]` string? These questions are related. `"libs": ["lua"]` will get translated to the compiler option `\ -llua`, who will search the library search path for files named liblua.so.\, and if it doesn't exist, liblua.a . This is why we have to give full file path of static libraries. You can check the path here: `ld --verbose|grep SEARCH` and can add custom paths via the environment variable LD_LIBRARY_PATH If you want to give (temporary) priority to static library, you can do so via `ld -Bstatic lib1 -Bdynamic lib2 file.o` or if you use a compiler, you have to pass the linkflag, so it's `gdc -Wl,-Bstatic -llib1 file.d`. See: https://stackoverflow.com/questions/6578484/telling-gcc-directly-to-link-a-library-statically (gcc is a C compiler, but many concepts will map to D compilers, and almost all to [gdc](https://wiki.dlang.org/GDC) ) Sidenote: If you use this, you have to always make sure you have an `-Bdynamic` or `-Wl,-Bdynamic` at the end, as libc should always be linked dynamically. Problem is, I don't think dub officially supports this. You could try: `"lflags": ["-Bstatic", "-llua", "-Bdynamic"]` But this would be kind of a hack, since now lua shouldn't be listed in the `"libs":"` section anymore. This is an artifact of the fact that not many people bother with static linking. As you see, it's kind of a mess. To make matters worse, depending on the compiler and linker, these options might look different. gcc, ldc and dmd all use some kind of different options, though some stay the same: `-llua` will work for every compiler. But I suppose this is one of the reasons why not inserting hacks into dub like above makes sense, since then it can abstract over different compilers for you. Thanks for answering my noob questions. I've never dealt with bindings and compiler flags in the languages I come from. :P My pleasure. Answering these has been (un)surprisingly helpful in strengthening my own understanding. PS: To really understand what is happening, you might want to try manually compiling a hello world program that depends on a library instead of using dub. Some pointers: `dub build -v` will print out the compiler and linkflags used. `pkg-config --libs --cflags lua` would generate compiler options for you. Use it like `dmd $(pkg-config --libs --cflags lua) program.d` If you decide to try this, I can walk you through it. But remember that it's not that important this is probably all a bit much.
Re: Step by step tutorials for using bindings in D
On Friday, 24 March 2023 at 23:45:15 UTC, eXodiquas wrote: Hello everyone, once again, I am here for your help. My last questions were answered really competently so I try again. :P So, maybe this is a stupid question, but I have read a lot about Bindings to C and C++ libraries for D. For example the Derelict project (or now [BindBC](https://github.com/BindBC/bindbc-sfml)) is full of them. Now I wanted to use the SMFL2 dynamic bindings. In my head this works like this: 1. I create a project called sfmltest 2. I have to get the original SFML2 from somewhere 3. I have to place some already compiled SFML2 files somewhere in the sfmltest project 4. I have to add the BindBC-SFML dependencies to the sfmltest project 5. I have to load the compiled SFML2 files from within my D code 6. I can use the bindings. But as you see, my idea about the whole workflow is pretty vague. - What files do I really need from SFML2? - Where do I have to store the files from SFML2? - How can I tell the D compiler where to find those SFML2 files? - Is the overall idea I have about those bindings correct at all? - How do dynamic bindings and static bindings differ from each other? Is there a good resource to learn about those bindings? I currently skim through the books "Web Development in D" and "D Cookbook" and there are also mentions of bindings in them, but they assume I know what I am doing, what I am not. :D I hope this question or the array of questions to be real is not too stupid. Thanks in advance and have a nice weekend! eXodiquas Hi, there are two things going on here that we need to pick apart, unfortunately they are confusingly named. On the one hand, we have static and dynamic linking, on the other we have static /dynamic bindings. _This in written from the linux perspective. For windows, most of it will still apply, but details like executable names or file endings will change_ ## Static/ Dynamic Linking To understand this, we first need to understand a bit more about compilation. Again, we have some unpedagogical nomenclature, so I'll refer to compilation from Source to Executable/ Library as Translation from now on, while the *compilation phase* gets to keep its name. Translation can roughly be divided into two phases: The compilation phase and the linking phase. ### Compilation Phase The compilation phase converts every source file into an object file with the ending ".o". They already contain binary code, with the exception of symbols (function name, global vars), which are still in text form. These symbols can be undefined and point to functions from other object files or libraries, but you need the types to be able to generate binary code, this is why we need binding (more on them later). ### Linking Phase The linker will combine all the object files into one file. It will resolve the undefined (and defined) symbols and insert actual addresses. How it handles external libraries depends on whether you choose a static or dynamic library. Static Library A static library (ending ".a" on linux) is basically just a file containing many different object files. If you link against it, the library gets bundled into your final executable like the rest of your object files. This has the advantage of making your executable independent of the environment where you deploy it, it won't crash when your user updates his libraries. But it leads to space waste when many programs use the same library and also forces you to distribute a recompiled version when you just want to update a library. This is especially problematic when one of your libraries has a security issue as it lengthens the update cycle. Dynamic/ Shared Library Dynamic Libraries (ending ".so" on Linux, ".dll" on windows) get loaded dynamically when the program starts. The environment needs to provide them. Execute `ldconfig -p` to list all shared libraries on the system. `ldd MyExecutable` will list all dynamic libraries required by your executable. # Dynamic Bindings Dynamic Bindings only work when using the dynamic library. bindbc-sfml allows you to instead of using the system dynamic library loader ld.so to instead manually load the dynamic library. https://github.com/BindBC/bindbc-loader/blob/master/source/bindbc/loader/sharedlib.d#L320 Afaict, this is only used so you don't need the original SFML library on your dev system, it will still be needed on the client or if you want to test. I don't understand why you'd want to do this, maybe someone else here can illuminate this issue. Normally, dynamic binding is useful when you want to lazily load shared libraries which in some extreme cases can be benefitial, or want to be able to hotload plugins. Now you might wonder: Why does the dynamic linker need the shared library present on the dev system and doesn't just internally do the same thing as bindbc_loaders? I'm actually not quite sure, I think it has to do with