Re: Deriving a struct from another one via template: Easy way to propagate UDAs?

2024-03-16 Thread Inkrementator via Digitalmars-d-learn

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?

2024-03-16 Thread Inkrementator via Digitalmars-d-learn

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

2024-03-15 Thread Inkrementator via Digitalmars-d-learn

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?

2024-03-14 Thread Inkrementator via Digitalmars-d-learn

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

2024-03-14 Thread Inkrementator via Digitalmars-d-learn

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

2024-01-29 Thread Inkrementator via Digitalmars-d-learn

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?

2023-11-09 Thread Inkrementator via Digitalmars-d-learn

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?

2023-10-23 Thread Inkrementator via Digitalmars-d-learn

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?

2023-10-22 Thread Inkrementator via Digitalmars-d-learn

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?

2023-10-22 Thread Inkrementator via Digitalmars-d-learn

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

2023-05-10 Thread Inkrementator via Digitalmars-d-learn

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

2023-05-07 Thread Inkrementator via Digitalmars-d-learn

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

2023-03-30 Thread Inkrementator via Digitalmars-d-learn

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

2023-03-26 Thread Inkrementator via Digitalmars-d-learn

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

2023-03-26 Thread Inkrementator via Digitalmars-d-learn

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