Re: KQueue and Fibers
On 2021-04-09 11:00, rashir wrote: Goodmorning everyone, I'm trying to understand both Kqueue and Fiber's operation on Mac. Why don't I get the correct data as long as I read from the socket? It seems to be reading too early, but Kquue tells me that the socket is readable. ```D const bytesRead = recv(fd, b.ptr, readableAmount < b.length ? readableAmount : b.length, 0); writeln("read bytesRead: ", bytesRead, "readableAmount:", readableAmount, " errno:", errno); assert(bytesRead != EAGAIN && bytesRead != EWOULDBLOCK); ``` `recv` returns the number of bytes received or `-1` if an error occurred. `EAGAIN` and `EWOULDBLOCK` are error codes. You should not compare the value returned by `recv` with error codes. The error code will be placed in `errno`. ```D assert(eventList[0].filter & EVFILT_READ); ``` The `filter` field of an event is not a flag/bit field. It's just a plain value, you should use `==` to check if it's a read event. I'm not sure if fixing these things will solve your issue. But at least some problems I noticed. -- /Jacob Carlborg
Re: Gui toolkits alive and gui toolkits dead
On 2021-04-06 21:57, Alain De Vos wrote: Can we say tk ang gtk toolkits are alive. But wxwidgets , fox an fltk are dead ? Do you mean these libraries in general or D bindings to these libraries? -- /Jacob Carlborg
Re: Contributing CDF bindings to Deimos
On 2021-03-25 05:00, Chris Piker wrote: I've attempted to follow all guidelines as best I understood them, but this is my first package. It likely has some style and functionality issues. There's a general convention to name the top level module or package the same as the project. To avoid causing conflict with other projects. I see that you have used DStep to create the bindings. I also see that you had to make some changes to the output. Please report any issues or enhancement requests to [1]. I you need any DStep specific help or have any questions, please ask here in the learn forum or on the DStep specific discussions section (which I just enabled) on GitHub [2]. I'll do my best to help you. [1] https://github.com/jacob-carlborg/dstep [2] https://github.com/jacob-carlborg/dstep/discussions -- /Jacob Carlborg
Re: Is it possible to suppress standard lib and dlang symbols in dylib (macos)
On Wednesday, 17 March 2021 at 15:16:36 UTC, Jacob Carlborg wrote: macOS doesn't support static linking. The proper way to solve this is to bundle the dynamic libraries with the application. If it's a GUI application it can be located in the application bundle. It seems like David already figured this out [1]. [1] https://forum.dlang.org/post/wsvlwdgzswxprtfjz...@forum.dlang.org -- /Jacob Carlborg
Re: Is it possible to suppress standard lib and dlang symbols in dylib (macos)
On Wednesday, 17 March 2021 at 13:52:48 UTC, Guillaume Piolat wrote: On Sunday, 14 March 2021 at 11:33:00 UTC, David wrote: Anyone else done this? Pointers welcome. Sorry for delay. Just add "dflags-osx-ldc": ["-static"], macOS doesn't support static linking. -- /Jacob Carlborg
Re: lockstep works with .each, but fails with .map
On 2021-03-05 19:49, realhet wrote: Why it works with each (or foreach), but not with map? o.O `lockstep` is specifically designed to work with `foreach`. I think `each` has a special case to work with `lockstep`. If you want to use other range functions, you should use `zip` instead of `lockstep`. -- /Jacob Carlborg
Re: ldc on a raspberry pi 3 running freebsd
On 2021-02-23 16:34, Decabytes wrote: ldc2 is the winner thank you! I'd like to get gdc and dmd up and running to at some point Unfortunately, DMD doesn't support ARM. -- /Jacob Carlborg
Re: How can I get this UDA at compile time?
On 2021-02-21 07:12, Jack wrote: I've had a struct like this: struct Attr { string value; } struct Foo { @(Attr("a attr")) enum a = Foo(10); @(Attr("b attr")) enum b = Foo(11); int x; int y; bool doY = true; int value() { return x; } } I'd like to get that atrribute's value at compile time, something like this: enum s = Foo.a.baa; enum s2 = Foo.b.baa; writeln(s); // a attr writeln(s2); // b attr I did this: string baa() { import std.traits : getUDAs, hasUDA; static foreach(field; __traits(allMembers, Foo)) {{ alias m = __traits(getMember, Foo, field); static if(is(typeof(m) == Foo)) { if(m.value == this.value) return getUDAs!(m, Attr)[0].value; } }} return null; } that was working fine, but I needed to switch value property from Foo struct, so that I can't read this value at CTFE anymore, so this fails now: if(m.value == this.value) return getUDAs!(m, Attr)[0].value; How can I solve this? You can't look at the value when trying to find the correct member. You need to look at the name. I don't think it's possible to solve that with the exact same API as you have used above. The simplest solution would be to just use `__traits(getAttributes)` and wrap that in a help function: string getAttribute(T, string name)() { return __traits(getAttributes, mixin(T.stringof, ".", name))[0].value; } void main() { writeln(getAttribute!(Foo, "a")); } Or you can create a proxy struct and use opDispatch like this, to get something a bit closer to your original example: // add this to the Foo struct static Proxy attributes() { return Proxy(); } struct Proxy { string opDispatch(string name)() { return __traits(getAttributes, mixin("Foo.", name))[0].value; } } void main() { writeln(Foo.attributes.a); } -- /Jacob Carlborg
Re: Type of string literal concatenated with non-immutable char array
On Sunday, 31 January 2021 at 21:48:09 UTC, Per Nordlöw wrote: Given char x[]; why is typeof("a" ~ x) `char[]` when typeof("a" ~ x.idup) is `string`? My case is class NameLookupException : Exception { this(string name) { super("Name " ~ name ~ " could not be found"); } this(scope const(char)[] name) { super("Name " ~ name.idup ~ " could not be found"); } } where I instead would like to only need class NameLookupException : Exception { this(scope const(char)[] name) { super("Name " ~ name ~ " could not be found"); } } Why isn't "Name " ~ name ~ " could not be found" implicitly convertible to `string`? Because if you have arrays of reference types, it's possible to change an element of the mutable array, which will affect the immutable array, those breaking the immutability. Example: class Foo { int a; } void main() { Foo[] a = [new Foo]; immutable(Foo)[] b = [new Foo]; // `string` is an alias for `immutable(char)[]` auto c = b ~ a; a[0].a = 3; assert(c[1].a == 3); } Due to language consistency it should behave the same for all types. In the above example, `c` is typed as `const(Foo)[]`. Although, I wonder why in your example the concatenation is typed as `char[]` instead of `const(char)[]`. Perhaps that's a bug. -- /Jacob Carlborg
Re: Why are multiple instances of the single enum created?
On Monday, 1 February 2021 at 09:40:20 UTC, Per Nordlöw wrote: An enum only exists at compile-time, and does not occupy any space. Each time it's referenced, a new instance of the value is created. Why is that? Seems like a waste of resources to the compiler. It makes perfect sense for numeric values, strings, characters and similar values. Why waste extra space on a variable if it's not needed? If you don't want a new instance, then don't use `enum`. Use `immutable` instead. -- /Jacob Carlborg
Re: std.expreimantal.allocator deallocate
On Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote: void destruct(Base base){ void[] x = (cast(void*)base)[0 .. __traits(classInstanceSize, Base)]; writeln("deallocate: ", x.length); theAllocator.deallocate(x); } You can get the dynamic size of an object using `typeid(base).initializer.length`. Base base = new Derived; assert(__traits(classInstanceSize, Derived) == typeid(base).initializer.length); -- /Jacob Carlborg
Re: [Understanding] Classes and delegate inheritance vs function pointers
On 2021-01-09 19:16, Q. Schroll wrote: Say I have a class hierarchy like this: class Base { } class Derived : Base { } A Derived object cannot be referenced as a Base object, but as a const(Base) object. That makes sense to me. It can: Base b = new Derived(); One can replace Base by a @system delegate type (SysDG) and Derived by a @safe delegate type (SafeDG) and it works the same way: a SafeDG object cannot be referenced as a SysDG object, but as a const(SysDG) object. However, if I try that with function pointers instead of delegates (SysFP, SafeFP), for some reason, a SafeFP cannot be referenced as a const(SysFP). This makes no sense in my head. Is there some reason I'm unable to see? Example code is here: https://run.dlang.io/is/zSNArx Is there a reason all you're examples are using pointers? Classes are already reference types, delegates are kind of like reference types. They consist of a context pointer and a function pointer. Function pointer are, as the name suggest, already pointers. -- /Jacob Carlborg
Re: DConf talk : Exceptions will disappear in the future?
On 2021-01-07 01:01, sighoya wrote: Thanks, reminds on swift error types which are enum cases. Swift can throw anything that implements the Error protocol. Classes, structs and enums can implement protocols. Oh, no please not. Interestingly we don't use longjmp in default exception handling, but that would be a good alternative to Herb Sutter’s proposal Some platforms implement C++ exception using longjmp, for example, iOS. because exceptions are likewise faster, but have likewise an impact on normal running code in case a new landing pad have to be registered. But interestingly, the occurrence of this is much more seldom than checking the return value after each function. It's claimed that exceptions are not zero cost, even when an exception is not thrown. Because the compiler cannot optimize functions that may throw as well as those that cannot throw. -- /Jacob Carlborg
Re: DConf talk : Exceptions will disappear in the future?
On 2021-01-06 22:27, H. S. Teoh wrote: That's the whole point of Sutter's proposal: they are all unified with the universal Error struct. There is only one "backend": normal function return values, augmented as a tagged union to distinguish between normal return and error return. We are throwing out nonlocal jumps in favor of normal function return mechanisms. We are throwing out libunwind and all the heavy machinery it entails. This is not what Sutter is proposing. He's proposing to add a new "backend", so you end up with three different types of functions (when it comes to error handling): * Functions annotated with `throws`. This is the new "backend": void foo() throws; * Functions annotated with `noexcept`. This indicates a function will not throw an exception (of the existing style): void foo() noexcept; * Functions without annotation. This indicates a function that may or may not throw an exception (of the existing style): void foo(); From the proposal, paragraph 4.1.7: "Compatibility: Dynamic exceptions and conditional noexcept still work. You can call a function that throws a dynamic exception from one that throws a static exception (and vice versa); each is translated to the other automatically by default or you can do it explicitly if you prefer." But perhaps you're proposing something different for D? -- /Jacob Carlborg
Re: dmd 2.093.1: duplicate method definitions ignored altogether
On 2021-01-05 03:02, kdevel wrote: expected output: none. The compiler should have rejected the code after the duplicate definition def #2. dmd 2.093.1 ignores both definitions instead. Is this a bug or a bug? DMD 2.095.0 now reports an error for this. -- /Jacob Carlborg
Re: How to store a pointer to class contructor
On Thursday, 24 December 2020 at 10:23:09 UTC, Dmitriy Asondo wrote: I expect code like this: -- class OloloService {} class BlablaService {} auto servicesList = [OloloService, BlablaService]; auto serviceInstance = new servicesList[1](args); -- Here's a slightly different version that I think is closer to your original example: import std; interface Service {} mixin template Constructor() { this(int a) { } } class OloloService : Service { mixin Constructor; } class BlablaService : Service { mixin Constructor; } Service function(int) create(T)() { return a => new T(a); } void main() { auto servicesList = [create!OloloService, create!BlablaService]; auto serviceInstance = servicesList[1](3); writeln(serviceInstance); } Since D is a statically typed language you need a form of base type if you want to store a list of values of different types. In this case, the base type is `Service`. If you want to have a constructor, as you do in your original example, the constructor needs to have the same signature for all types, the mixin template helps with that. You can use a tuple as well to store different values of different types. But then everything need to be known at compile time. That is, the index, in your case. -- /Jacob Carlborg
Re: extern(C) and name mangling
On 2020-12-16 16:18, Dave P. wrote: Is this a bug in the spec or in the implementation? Yeah, that's a good question. That's always problematic with D. The spec is incomplete. How do we get this fixed? The simplest would be to change the spec. -- /Jacob Carlborg
Re: extern(C) and name mangling
On Wednesday, 16 December 2020 at 04:17:13 UTC, Mike Parker wrote: So what you're asking for is a way to retain the D name mangling on an extern C function. The way to do that is with `pragma(mangle, "new_name")`. To match the original D function mangling, declare the function first without extern(C) and print `func.mangleof`. Use that as the parameter to pragma(mangle). I can't imagine any benefit you'd get from doing that, though. I actually had a use case for this. An initialization function that is called by the C runtime, i.e. `pragma(crt_constructor)`. That function needs to have C calling convention. But to avoid any conflicts with other `extern(C)` functions I wanted to keep the D mangling. https://github.com/dlang/druntime/blob/master/src/core/memory.d#L212-L232 -- /Jacob Carlborg
Re: extern(C) and name mangling
On Wednesday, 16 December 2020 at 04:17:13 UTC, Mike Parker wrote: However, the D calling convention is defined to be identical to the C calling convention on the host system for everything except Windows x86. Also keep in mind that D supports other types than C does, like D arrays and delegates. In those cases the D calling convention needs to be extended since there's no way to just relay on the C calling convention. One could think it would be possible to passes D arrays and delegates as structs, but that's not how DMD passes them. On some platforms it matches how a struct is passed, on some it doesn't. -- /Jacob Carlborg
Re: extern(C) and name mangling
On Wednesday, 16 December 2020 at 04:17:13 UTC, Mike Parker wrote: However, the D calling convention is defined to be identical to the C calling convention on the host system for everything except Windows x86. That's what's specified, but that's not how DMD actually behaves. DMD passes the arguments in reverse order. That's easily observable by calling a C function with D linkage: $ cat foo.c #include void foo(int a, int b) { printf("a=%d b=%d\n", a, b); } $ cat main.d module main; import std; pragma(mangle, "foo") // override D mangling to get the same name as the C function void foo(int a, int b); // D calling convention void main() { foo(1, 2); } $ clang -o foo.o foo.c -c $ dmd main.d foo.o $ ./main a=2 b=1 LDC behaves the same way as DMD and, IIRC, GDC follows how GCC passes the arguments. -- /Jacob Carlborg
Re: Hex constant method starts from ".a": 0xCCCCCC.argb
On Monday, 14 December 2020 at 05:51:28 UTC, Виталий Фадеев wrote: It's parsing the `.a` in `.argb` as part of the number: auto color = 0x00AABBCC.a rgb; // what the compiler sees You can fix it with parentheses: auto color = (0x00AABBCC).argb; Thanks! It is not perfect, but also beauty! Or you can call it `rgba`. It seems to be what Wikipedia prefers [1]. [1] https://en.wikipedia.org/wiki/RGBA_color_model -- /Jacob Carlborg
Re: Request assistance initializing struct instance at global scope
On Tuesday, 8 December 2020 at 01:47:51 UTC, Andrew Edwards wrote: Thanks Jacob. The extern(C) is temporary. I'm doing a direct port of the code to D using -betterC. Wanted to keep it as close to the original as possible until everything compiles. Yes, that's always a good idea. Do the initial port as close as possible to the original code. Then refactor and start adding D specific features. I noticed that static this() does not work if either it or main() (or both) is marked extern(C). Yes, that's expected. If you have a regular D main function, the compiler will recognize that and output an undefined symbol to the C main function. The C main function is implemented in the D runtime. The C runtime will call the C main function in the D runtime. The C main function is responsible for initializing the D runtime. This includes (not a complete list): * Converting the arguments passed to the C main function to `string[]` * Initializing the garbage collector * Calling `shared static this()` in all modules * Calling `static this()` in all modules * Running the any unit tests * Finally calling the D main function When you define a C main function the compiler will recognize that and not output an undefined symbol. That means the C main function in the D runtime will never be called. That means the D runtime is never initialized. This is to allow you to use D without its runtime or get more control of the startup phase. So either either you define a D main function and everything works as expected or you define a C main function and then you need to manually initialize and deinitialize the D runtime, if you want to use it. This can be done with [1] and [2]. [1] https://dlang.org/phobos/core_runtime.html#.rt_init [2] https://dlang.org/phobos/core_runtime.html#.rt_term -- /Jacob Carlborg
Re: Request assistance initializing struct instance at global scope
On Monday, 7 December 2020 at 04:13:16 UTC, Andrew Edwards wrote: Given: === extern(C): char*[] hldr; enum I = (1<<0); struct S { char* ft; char** fm; int f; } void main(){} === // Error Deprecation: static constructor can only be of D linkage S[] s; static this() { s = [ S(cast(char*)"c", &hldr[0], I) ]; } This is the correct way to do it. The problem is that you have added `extern(C):` at the top. This means that ever symbol below will have C linkage. As the error message says, `static this` can only have D linkage. `static this` is transformed into a function which is automatically called by the runtime. When you add `extern(C):` at the top, this function will also get the C linkage. A simple way to make sure that there are not multiple C functions with the same name (caused by multiple `static this`, in the same file or another file) is to mangle the function name the same way as a D function. You can either use `extern(C) char*[] hldr` to make only `hldr` have C linkage. Use `extern(C) {}` to group several symbols which should have C linkage or rearrange the code so that `static this` is above `extern(C):`. -- /Jacob Carlborg
Re: Ways to parse D code.
On 2020-11-25 17:27, Jan Hönig wrote: dmd has to do it somewhere as well. Although I don't know exactly where. I do know ldc uses dmd's frontend for parsing. https://dlang.org/phobos/dmd_parse.html Using DMD as a library will be most accurate and up to date. Because it's the same code as the compiler is using. Here's an example on how to use DMD to parse some code [1]. Here's some more advance usages [2]. [1] https://github.com/dlang/dmd/blob/b35572b07a6994385b6459a430674d32e9a97279/test/dub_package/frontend.d#L10-L24 [2] https://github.com/jacob-carlborg/dlp/blob/master/source/dlp/commands/infer_attributes.d#L61 -- /Jacob Carlborg
Re: How can I convert Hexadecimal to RGB Color and vice-versa?
On Friday, 16 October 2020 at 20:10:58 UTC, Marcone wrote: How can I convert Hexadecimal to RGB Color and vice-versa? Not sure if this is what you're looking for: struct Color { private uint hex; int red() out(result; result >= 0 && result <= 255) // assert that the result is within bounds { return (hex & 0xFF) >> 16; } void red(int value) in(value >= 0 && value <= 255) // assert that the value is within bounds { hex = (hex & 0x00) | (value << 16); } int green() out(result; result >= 0 && result <= 255) // assert that the result is within bounds { return (hex & 0x00FF00) >> 8; } void green(int value) in(value >= 0 && value <= 255) // assert that the value is within bounds { hex = (hex & 0xFF00FF) | (value << 8); } int blue() out(result; result >= 0 && result <= 255) // assert that the result is within bounds { return hex & 0xFF; } void blue(int value) in(value >= 0 && value <= 255) // assert that the value is within bounds { hex = (hex & 0x00) | value; } string toString() { return format!"Color(red: %s, green: %s, blue: %s)"(red, green, blue); } } void main() { Color color; color.red = 255; color.green = 143; color.blue = 89; writeln(color); } -- /Jacob Carlborg
Re: betterC question
On Thursday, 19 November 2020 at 00:20:50 UTC, Dibyendu Majumdar wrote: On Thursday, 19 November 2020 at 00:18:54 UTC, rikki cattermole You don't need the brackets to call a function (and with a little help from UFCS): void main() { import std.stdio; "Hello!".writeln; writeln; } Okay thanks. Bad idea IMO. Yes, calling `writeln` like that is a bad idea. That was a bad example. But the actual reason is, this is how D implements properties [1]. Any function that doesn't take an argument can be called without parentheses. Any function which takes a single argument can be called like setting a field. Here's an example: struct Color { private uint hex; int red() out(result; result >= 0 && result <= 255) // assert that the result is within bounds { return (hex & 0xFF) >> 16; } void red(int value) in(value >= 0 && value <= 255) // assert that the value is within bounds { hex = (hex & 0x00) | (value << 16); } // similar functions for green and blue } void main() { Color color; color.red = 255; assert(color.red == 255); } [1] https://en.wikipedia.org/wiki/Property_(programming) -- /Jacob Carlborg
Re: question as to when a new command gets executed
On 2020-11-11 06:29, WhatMeWorry wrote: Which begs the question, how would the statement, m_State = new BreakState() ever get executed? class DebuggerSession { private BreakState m_State = new BreakState(); private UnrealCallback m_UnrealCallback; this( ) { } // rest of class } It gets executed at compile time. All instances of `DebuggerSession` will share the same single instance of `BreakState`. -- /Jacob Carlborg
Re: How add class or struct member after construction?
On 2020-11-05 23:48, Marcone wrote: How add class or struct member after construction? Is it possible in D? How? It depends on what needs you have. You can declare a free function that takes the class/struct as the first parameter and call it like a method [1]: class Foo { int a; } void printA(Foo foo) { writeln(foo.a); } foo.printA(); printA(foo); The two above lines are exactly the same. [1] https://dlang.org/spec/function.html#pseudo-member -- /Jacob Carlborg
Re: DMD: invalid UTF character `\U0000d800`
On 2020-11-08 13:39, Kagamin wrote: Surrogate pairs are used in rules because java strings are utf-16 encoded, it doesn't make much sense for other encodings. D supports the UTF-16 encoding as well. The compiler doesn't accept the surrogate pairs even for UTF-16 strings. -- /Jacob Carlborg
Re: DMD: invalid UTF character `\U0000d800`
On Saturday, 7 November 2020 at 16:12:06 UTC, Per Nordlöw wrote: CtoLexer_parser.d 665 57 error invalid UTF character \Ud800 CtoLexer_parser.d 665 67 error invalid UTF character \Udbff CtoLexer_parser.d 666 28 error invalid UTF character \Ud800 CtoLexer_parser.d 666 38 error invalid UTF character \Udbff CtoLexer_parser.d 666 53 error invalid UTF character \Udc00 CtoLexer_parser.d 666 63 error invalid UTF character \Udfff Doesn't DMD support these Unicodes yet? They're not valid: "The Unicode standard permanently reserves these code point values for UTF-16 encoding of the high and low surrogates, and they will never be assigned a character, so there should be no reason to encode them. The official Unicode standard says that no UTF forms, including UTF-16, can encode these code points" [1]. "... the standard states that such arrangements should be treated as encoding errors" [1]. Perhaps they need to be combined with other code points to form a valid character. [1] https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF -- /Jacob Carlborg
Re: why `top` report is not consistent with the memory freed by core.stdc.stdlib : free?
On Friday, 6 November 2020 at 06:17:42 UTC, mw wrote: https://wiki.dlang.org/Memory_Management#Explicit_Class_Instance_Allocation using core.stdc.stdlib : malloc and free to manually manage memory, I tested two scenarios: -- malloc & free -- malloc only and I use Linux command `top` to check the memory used by the program, there is no difference in this two scenarios. I also tried to use `new` to allocate the objects, and GC.free(). The memory number reported by `top` is much less than those reported by using core.stdc.stdlib : malloc and free. I'm wondering why? shouldn't core.stdc.stdlib : malloc and free be more raw (low-level) than new & GC.free()? why `top` shows stdlib free() is not quite working? In general, any GC (not just the one in D) are not likely to give back memory to the OS. Because it's less overhead for the GC to keep the memory and reuse it. But I'm guessing `GC.free()` is supposed to give back memory to the OS, which leads into the other scenario. When it comes to maclloc/free. I would guess it's doing something similar. It probably splitting up the memory in blocks and/or pools. It might keep the memory just as the GC does for efficiency, even if `free` is called. Otherwise it would be not much point in using over the syscalls like `mmap` or `sbrk` (and whatever the corresponding calls are on Windows). -- /Jacob Carlborg
Re: Does dmd's -i "include imported modules in the compilation" switch generate object files?
On 2020-11-03 20:02, H. S. Teoh wrote: I believe -i behaves as though you manually typed the names of the source files on the command line. So it would do what the compiler would usually do in the latter case. Yes, this is correct. AFAIK, that means it loads everything into memory and produces only a single object file for the final executable. Separate compilation only happens if you invoke the compiler separately for each source file or group of source files. If the `-c` flag is passed, the compiler will produce one object file for each source file. If the `-c` flag is **not** passed, it will produce one executable and one single object file. -- /Jacob Carlborg
Re: synthesising instantiated template parameters and arguments
On Wednesday, 28 October 2020 at 05:51:14 UTC, Nicholas Wilson wrote: but for a templated C this is tricker as I can't use a template sequence parameter (...) unless C uses it in the same position (I'm trying to generate a mangle from it so it needs to be exact). Given class A(T,int,args...) {} alias C = A!(int, 0, float); I need `ScopeClass!C` to be template ScopeClass(C) { class Anon(T,int,args...) // name doesn't matter { // implement members with compile time reflection } alias ScopeClass = Anon!(int, 0, float); } How do I do this? Are you looking for `TemplateArgsOf` [1] ? [1] https://dlang.org/phobos/std_traits.html#TemplateArgsOf -- /Jacob Carlborg
Re: Dynamic Template-Expansion of (Token) Strings
On Tuesday, 27 October 2020 at 08:33:08 UTC, Per Nordlöw wrote: I'm looking for elegant ways of expressing expansion of parameterized strings written to a file at run-time. My primary use case is run-time generation of D code. In the lazy case, something like import std.file : write; import std.algorithm : substitute; const s = q{int $X = $Y;}; // templated source foreach (part; s.substitute("$X", "x", "$Y", "42")) write(somePath, part); is my current best bet. You might want to have a look at Mustache [1]. Here's a Dub package [2]. [1] http://mustache.github.io/mustache.5.html [2] https://code.dlang.org/packages/mustache-d -- /Jacob Carlborg
Re: this T / variadic template and interfaces
On Tuesday, 27 October 2020 at 09:40:33 UTC, frame wrote: Hmm, a question of design. Is there also a convenient way to pass the arguments to a template or get a Variant[] from it? Convenient, no not that I know of. You can use a type safe variadic function that takes Variant, if you want to end up with Variant[] anyway. It depends on how you want the API to look like. Here are some examples: void foo(...); void bar(Variant[] args ...); foo(3, "foo", 'a'); // pass in the arguments as is bar(Variant(3), Variant("foo"), Variant('a')); // need to wrap each argument in Variant The advantage of using the type safe variadic function is that all the arguments are bundle into one array, make it easier to work with. -- /Jacob Carlborg
Re: this T / variadic template and interfaces
On Monday, 26 October 2020 at 11:14:47 UTC, frame wrote: Is there any way to get this working? I know, I could use a known object to feed the arguments and use that instead - but I want to keep things simple as possible. As Simen mentioned, templates cannot be virtual. But you don't need to use a template, you can use a regular variadic method [1]. It's a bit more clunky to work with than template variadic functions. Or if all the arguments will be of the same type, you can use type safe variadic functions [2], which are easier to work with. [1] https://dlang.org/spec/function.html#d_style_variadic_functions [2] https://dlang.org/spec/function.html#typesafe_variadic_functions -- /Jacob Carlborg
Re: Template pattern delegate?
On Monday, 26 October 2020 at 00:56:26 UTC, frame wrote: I see that your approach can handle functions and delegates but isn't that not equivalent like this template for a function? auto myStuff(T)(T function() fn) { try { return fn(); } catch (Exception e) { // } } You cannot pass a delegate to something that expects a function pointer. I wonder if I could use such a template as static variant and the compiler just expands the code? Just thinking that using a function or delegate is an overhead. Maybe not a function but a delegate will allocate GC memory I think. If you pass the delegate as a template parameter/alias parameter, it's more likely to be inlined: auto myStuff(alias fn)() { try return fn(); catch (Exception e) { } } myStuff!( { /* some code */ } ); -- /Jacob Carlborg
Re: Can we do compile time reading part of a file using import?
On Sunday, 25 October 2020 at 16:50:09 UTC, Jack wrote: Which build tool are you refering to? an existing one or build one oneself to do this job? It should work with any build tool that has hooks to execute arbitrary commands. -- /Jacob Carlborg
Re: Two ways of receiving arrays on the C ABI
On 2020-10-20 02:16, Ali Çehreli wrote: Everything works at least on Linux. Is this kosher, or am I using some internal knowledge? Yes, you're using some internal knowledge. You cannot assume it works on any other platform or architecture. In theory, the D compiler could choose to change the ABI for passing D arrays and this would break. If fact, the ABI documentation [1] doesn't mention how a D array is passed. A different compiler could choose to pass it differently. [1] https://dlang.org/spec/abi.html#arrays -- /Jacob Carlborg
Re: Can we do compile time reading part of a file using import?
On 2020-10-23 18:42, data pulverizer wrote: For me it's not make-or-break, it just something very useful and I think has clear use case. Please let me know if there are aspects or alternatives I am missing. You could always have the build tool split up the file in multiple smaller files and read one of the smaller files with the import expression. -- /Jacob Carlborg
Re: Druntime without pthreads?
On Tuesday, 20 October 2020 at 16:58:12 UTC, Severin Teona wrote: Hi guys. I have a curiosity, regarding [1] - I had encountered some "undefined reference" errors when trying to link the druntime (compiled for an embedded architecture) without some implementation of the POSIX thread calls (and other stuff too). First, keep in mind that druntime and Phobos depends heavily on the C standard library, the Posix APIs, Windows APIs and other platform specific APIs. There's no list of what features or APIs need to be supported by a platform. There's no general concept of optional platform features, i.e. druntime will not automatically adopt if your platform doesn't support a specific feature (like threads). For example, on iOS (and related platforms) `std.process` is not supported (because you're not allowed to call `fork`). This is just hardcoded: if the platform is iOS, don't provide `std.process`. What I'm saying, if you modify druntime to remove threads and locks, and resolve your undefined references, you might end up with new undefined references for other symbols. My curiosity is what would change if I removed from the druntime everything that has to do with mutexes or threads. Would it be possible for the druntime to run and work properly on a microcontroller - where those concepts are not necessary? Could I just remove everything about synchronisation from the druntime, and classes or Garbage Collector to still work properly? The garbage collector will probably work (if you remove the interaction with threads from it). Classes are a bit more complicated, they have a hidden monitor field [1]. There's also the concept of synchronized classes [2]. There's also the `synchronized` statement [3]. All these depend on mutex/monitors/locks in some form (I don't know exactly how the implementation works). Hopefully it should be fine as long as your code doesn't use the `synchronized` statement or synchronized classes. But all classes do come with a hidden monitor field. [1] https://dlang.org/spec/abi.html#classes [2] https://dlang.org/spec/class.html#synchronized-classes [3] https://dlang.org/spec/statement.html#synchronized-statement -- /Jacob Carlborg
Re: Escape this in pure members
On 2020-09-19 21:50, Per Nordlöw wrote: On Saturday, 19 September 2020 at 18:48:31 UTC, Jacob Carlborg wrote: A nested class seems to be able to escape the `this` reference: Ahh, thanks. I just realized that it can escape into other parameters without the `scope` qualifier? This class Bar { void bar(scope Bar b) @safe pure { b = this; } } compiles but this class Bar { scope void bar(scope Bar b) @safe pure { b = this; // Error: scope variable `this` assigned to `b` with longer lifetime } } Hmm, why would `b` have longer lifetime? Isn't the lifetime of `b` throughout `bar`? -- /Jacob Carlborg
Re: Escape this in pure members
On 2020-09-19 18:07, Per Nordlöw wrote: If an aggregate member is pure but not scope when can it escape the `this` pointer?. Only via return? I'm not sure if returning the `this` pointer is considered escaping it. The caller already had access to it. Under the hood, the `this` pointer is just another argument passed to the function. In the struct and class case? A nested class seems to be able to escape the `this` reference: class Foo { Bar b; class Bar { void bar() pure { b = this; } } } -- /Jacob Carlborg
Re: Good repos to learn D
On Saturday, 19 September 2020 at 08:26:36 UTC, Imperatorn wrote: What are some good examples of pretty large/medium size, good structured repos in D? I'm looking for examples to learn from Thanks! Here are some examples of large projects: * DWT [1]. This is one of the largest D projects I'm aware of. It's a port from Java so it's structured like a Java project. I think it works pretty well for D projects as well. But it's not common to have the reverse domain name package structure like in Java. It's more common to have the top level package be named after the project. * Mecca [2]. This one is not as large as DWT, but I think it nicely shows how to separate the platform specific code from the platform independent code. Instead of having `version` statements sprinkled all over the code most platform specific code is located in the `platform` packages. Then it provides a common interface that is used by the rest of the project. * Ocean [3]. This one is quite large as well. [1] https://github.com/d-widget-toolkit/dwt [2] https://github.com/weka-io/mecca [3] https://github.com/sociomantic-tsunami/ocean -- /Jacob Carlborg
Re: DDoc generation
On Saturday, 19 September 2020 at 07:43:24 UTC, Russel Winder wrote: Doesn't that then make the whole DDoc system fairly useless, despite it's use in Phobos? If you use Dub, you can run `dub build -b ddox` and it will use Ddox to build the documentation. This will include an index page listing all modules. This will actually start a local web server to show the documentation. It's possible to generate documentation offline as well [1]. Or it should be pretty straightforward to write a simple script that iterates all D files and generates documentation. Then iterate all HTML files and output a simple index.html file. [1] https://github.com/rejectedsoftware/ddox#generating-offline-documentation -- /Jacob Carlborg
Re: DDoc generation
On Saturday, 19 September 2020 at 07:43:24 UTC, Russel Winder wrote: Doesn't that then make the whole DDoc system fairly useless, despite it's use in Phobos? Yes. The problem is that most things in D are compared with C or C++. People are praising that the built-in support for unit tests and Ddoc are the best things that have happened since sliced bread. But if you compare with C or C++ the bar isn't very high. -- /Jacob Carlborg
Re: Question about linker errors when using slices
On 2020-09-19 04:45, tspike wrote: I’ve been using D for personal projects for almost a year now and I really love it. I recently ran across a linker error that I’m a little confused by. Consider the following files: platform.d: module platform; import app; struct PlatformData { AppData a; } void main() { } app.d: module app; struct AppData { //int* items; int[] items; } If you only compile platform.d, the linker will complain about “undefined references.” This is true when using dmd and gdc, though platform.d compiles just fine when using ldc. But the file only fails to compile when the “items” member of AppData is a slice; if “items” is an int* platform.d will compile. The linker spits the following: platform.o:(.data._D22TypeInfo_S3app7AppData6__initZ+0x30): undefined reference to `_D3app7AppData9__xtoHashFNbNeKxSQBeQBdZm' platform.o:(.data._D22TypeInfo_S3app7AppData6__initZ+0x38): undefined reference to `_D3app7AppData11__xopEqualsFKxSQBdQBcKxQjZb' I was just wondering if anyone knows if this behavior is expected or if this is a compiler bug. Thank you in advance for your time! You should compile both files. I'm guessing LDC might be doing some form of optimization to figure out that it doesn't need those symbols. PS: I hope this is the right sub-forum for asking this sort of question! Yes. -- /Jacob Carlborg
Re: Proper way to exit with specific exit code?
On 2020-09-17 16:58, drathier wrote: What's the proper way to exit with a specific exit code? I found a bunch of old threads discussing this, making sure destructors run and the runtime terminates properly, all of which seemingly concluding that it's sad that there isn't a way to do this easily, but hopefully things have changed in the last 5-10 years and I'm just missing the obvious solution. The proper way is: int main() { return 42; } I highly recommend against trying to terminate the application using `exit` or any other way. Just let the control flow return back to the `main` function. -- /Jacob Carlborg
Re: DDoc generation
On 2020-09-18 13:41, Russel Winder wrote: Hi, I am trying to get to grips with DDoc for documenting an application. Getting the individual module HTML files seems to be the easy bit. The question is how to get an index.html (or equivalent) so as to have an application level entry point to the generated documentation. There's no built-in support for that. You might want to look at some other doc generating tool if those support that. -- /Jacob Carlborg
Re: get element index when using each!(x)
On 2020-09-17 05:16, Paul Backus wrote: Worth knowing that the tuples you get from enumerate actually have named members, so you can write: s.enumerate.each!(x => writeln(x.index, ":", x.value)); It actually works out of the box for `each`: s.each!((index, value) => writeln(index, ":", value)); https://dlang.org/phobos/std_algorithm_iteration.html#.each -- /Jacob Carlborg
Re: Neater "not version (...)" ?
On 2020-09-16 21:04, Vladimirs Nordholm wrote: Ah, I guess it boils down to this then. Doesn't really make it "neater", but thank you for the tip! You only need to declare the enums ones. -- /Jacob Carlborg
Re: Neater "not version (...)" ?
On 2020-09-16 19:53, Vladimirs Nordholm wrote: Hello. I wonder if there is a better way to compile something if the current operating system is _not_ a specific platform. For example, I only want some code to compile if the operating system is not Windows. Currently I do this: version (Windows) { } else { // ... my code } Is there a neater version of this, like `!version (Windows) { /+ ... my code +/ }` ? The workaround for that is to define booleans for all versions and then use `static if`: version (Windows) enum windows = true; else enum windows = false; static if (!windows) { // ... my code } -- /Jacob Carlborg
Re: tupleof seems to break encapsulation
On 2020-09-05 07:14, 60rntogo wrote: I wouldn't dispute that it is useful, but that's besides the point. If I declare something private, it's usually because I want to preserve certain invariants and I want the compiler to provide a guarantee that I don't accidentally violate them. As it stands, the compiler cannot guarantee that if I use tupleof. I don't really have an issue with read-only access to private fields (but arguments could be made against it) and then serialization would still be possible. However, if my struct is supposed to maintain invariants, then any attempt at deserialization that naively reads from a tuple without establishing these invariants should fail to compile. I wouldn't mind if `tupleof` was not allowed in @safe code, which Walter mentions in one of the linked issues. Although it would be a breaking change. Secondly, my serialization library, Orange [1], uses `tupleof` to read and write fields. It also supports before and after hooks for both serialization and deserialization. This allows to implement any invariants that are not covered by just restoring the fields. It also supports implementing a method that allows to take full control of the (de)serialization of a specific type. Thirdly, you can do the same thing with pointer arithmetic. Although this is not allowed if @safe code. [1] https://github.com/jacob-carlborg/orange -- /Jacob Carlborg
Re: tupleof seems to break encapsulation
On 2020-09-04 12:16, 60rntogo wrote: Consider the following code. foo.d --- module foo; struct Foo { private int i; } --- main.d --- void main() { import std.stdio; import foo; auto x = Foo(); writeln(x); // ++x.i; ++x.tupleof[0]; writeln(x); } --- As expected, the commented line does not compile. If I uncomment it, I get the error "no property i for type foo.Foo". However, the rest of the code compiles just fine and outputs: --- Foo(0) Foo(1) --- This appears to defeat the purpose of declaring i private. What am I missing? It's useful for serialization and, as you can see in your example, for debugging as well. `writeln` will print the values of the fields in a struct, even for private fields. -- /Jacob Carlborg
Re: Install multiple executables with DUB
On 2020-09-03 14:41, glis-glis wrote: Yes I already tried that, but I get the error Error: only one main allowed. Previously found main at src/scripts/copy.d Looks like DUB doesn't like multiple binaries? Oh, multiple binaries, I missed that. You can try to add multiple configurations [1]. Or if you have executables depending on only one source file, you can use single-file packages [2]. Here are some real-world examples [3][4]. [1] https://dub.pm/package-format-sdl.html#configurations [2] https://dub.pm/advanced_usage.html [3] https://github.com/jacob-carlborg/dstep/blob/master/dub.json#L26 [4] https://github.com/d-widget-toolkit/dwt/blob/master/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet10.d -- /Jacob Carlborg
Re: Install multiple executables with DUB
On Thursday, 3 September 2020 at 08:22:25 UTC, glis-glis wrote: I usually would just write a makefile for that, but I thought I'd give DUB a go. Unfortunately, the DUB-documentation is a little thin and I cannot find a way to tell DUB "compile all the files in the scripts folder and put the binary to the bin folder". How do I do that? By default Dub will compile all files in the `source` or `src` directory and place the binary in the root directory of the project. If you want to override that you can use the following build settings `sourcePaths` or `sourceFiles` to override the source directory. To override the output directory you can use `targetPath` build setting. They are documented here [1][2]. [1] For the SDL format: https://dub.pm/package-format-sdl.html#build-settings [2] For the JSON format: https://dub.pm/package-format-json.html#build-settings -- /Jacob Carlborg
Re: Installing D on Fresh Windows 10 machine is a pain
On Friday, 28 August 2020 at 05:38:59 UTC, novice3 wrote: DMD x86 on Windows have no dependencies, just unpack .zip and use. It's a pitty, that DMD x64 depend on VS :( It does not. If VS is not installed the MinGW provided libraries, which are bundled, will be used. -- /Jacob Carlborg
Re: How does D's templated functions implementation differ from generics in C#/Java?
On 2020-08-07 23:03, aberba wrote: Syntactically they look the same (although D's can do more things) so I'm trying to understand how why in D it's called template but in languages like C#/Java they're generics. I guess I have fair understanding of D's code generation but isn't it same as what what is available in those languages too? How are the implementation different? Objective-C recently added support for generics. It uses the same approach as Java, type erasure. Basically the only reason why this was added is to make the Swift APIs better and more type safe. Swift also has quite an interesting implementation of generics. IIRC correctly it supports both a more Java like implementation where you only get one instantiation and a more D/C++ like implementation where the compiler generates one instantiation per type. This is supposed to give the best of both worlds. Little binary bloat and high performance. -- /Jacob Carlborg
Re: How does D's templated functions implementation differ from generics in C#/Java?
On 2020-08-07 23:39, H. S. Teoh wrote: They are *very* different. Java generics are based on "type erasure", i.e., at the syntactic level, containers are parametrized with the element types, but at the implementation level, the element types are merely "erased" and replaced with Object (a top type of sorts). There is only one container instantiation, which is shared across all parametrizations. I don't know exactly why this approach was chosen I'm guessing a strong reason was to be backwards compatible with earlier versions of Java. The type erasure is also most likely the reason why Java generic types don't accept primitive types. They need to be boxed, i.e. `int` need to be wrapped in an object of type `Integer`. -- /Jacob Carlborg
Re: Invoking the compiler during runtime
On 2020-08-05 09:57, cy wrote: Well, I did find this: https://dlang.org/blog/2017/08/01/a-dub-case-study-compiling-dmd-as-a-library/ That is more for using the frontend, not the backend for generating code. But it's pretty advanced... probably just invoking dmd would be good... You can start with that at least. -- /Jacob Carlborg
Re: Using D within a rust codebase
On 2020-07-27 13:43, Ali Çehreli wrote: They should be taken care of when the program is linked with a D compiler. Just linking with a D compiler is not sufficient. There needs to be a D main function for the runtime to automatically be initialized. If you make the D code a bit more complicated, for example: static this() { import std.stdio: writeln; writeln("static this"); } Then that won't be printed without a D main function or manually initializing the runtime. The initial question was about linking D code into an already existing Rust code base. I don't think the first thing to try is to replace the Rust main function with a D main function. -- /Jacob Carlborg
Re: Using D within a rust codebase
On 2020-07-27 03:03, Paul Backus wrote: extern(C) void hello() { import std.stdio: writeln; writeln("Hello from D!"); } The D runtime needs to be initialized first [1]. Then it should be terminated as well [2]. [1] https://dlang.org/phobos/core_runtime.html#.rt_init [2] https://dlang.org/phobos/core_runtime.html#.rt_term -- /Jacob Carlborg
Re: Question about publishing a useful function I have written
On 2020-07-14 23:58, Cecil Ward wrote: What’s the best way to publish a D routine ? As others have already said, on GitHub. Then as a Dub package as well [1]. [1] https://code.dlang.org -- /Jacob Carlborg
Re: misc questions about a DUB package
On 2020-07-15 04:20, 9il wrote: No. Usually, a DUB package supports a range of C library version or just a fixes set of C API. The version behavior of the dub package is up to you. Usually, D API changes more frequently than the underlying C library. If you support a specific version of the C API, I recommend adding the version of the C library as metadata: 0.0.1+5.3 In the above example "0.0.1" would be the version of the Dub package. "5.3" would be the version of the C API. The plus sign and anything after is ignored by Dub. See semantic versioning docs for more information: https://semver.org -- /Jacob Carlborg
Re: Bind C++ class to DLang : undefined reference to `Canvas::Foo()'
On 2020-07-14 05:33, Boris Carvajal wrote: Can you try passing -D_GLIBCXX_USE_CXX11_ABI=0 to g++ and -version=_GLIBCXX_USE_CXX98_ABI to dmd. That comes from: https://dlang.org/changelog/2.088.0.html#std_string C++11 ABI is currently not supported. I based on previous messages and the usage of Clang, I think zoujiaqing is using a Mac. On Mac libc++ is used. That above might not apply. -- /Jacob Carlborg
Re: Choosing a non-default linker for dmd (via dub)
On 2020-07-12 18:36, Per Nordlöw wrote: The line dflags "-linker=gold" platform="linux-ldc" # use GNU gold linker in dub.sdl enables me to change linker for LDC. Is it possible to choose a specific linker for DMD aswell in a similar way? I only find the flag `-L` that sets flags but no linker executable. One way is to link /usr/bin/ld to either /usr/bin/ld.gold or /usr/bin/ld.lld but it would be nice to be able to do this from the dub.sdl or the command-line call to dub. There's an environment variable "CC" that can be used to select which C compiler is used. Is there any equivalence for selecting the linker, "LD" perhaps? -- /Jacob Carlborg
Re: App/lib config system
On Thursday, 9 July 2020 at 06:57:22 UTC, Kagamin wrote: If you suspect there's a contradiction in requirements, you need to specify them with better precision. What are the contradictions in the requirements? I don't see any. -- /Jacob Carlborg
App/lib config system
I'm looking for a way to configure applications and libraries. I'm imagining a way for libraries to hook into a single point to provide the configuration parameters the library provides. These parameters can then be changed in one location from the user of the libraries (usually an application). My main requirement is that it should be possible to configure compile time values. I think the best way to explain what I'm looking for is with an example: module log; import config; void log(Level level, string message) { static if (config.log.isEnabled) { if (config.log.level >= level) writeln(message); } } In the above example, the code would be part of the "log" library. The configuration parameters `config.log.isEnabled` and `config.log.level` can be changed by the application that is using the "log" library. `config.log.isEnabled` is a compile time value, that can only be changed at compile time. `config.log.level` is a runtime value that can be changed at runtime as well. Here's a list of my ideal requirements: * Should support both compile time and runtime config parameters * Arbitrary libraries should be able to hook into config system to provide it with its config parameters * There should be one place to change the config * The "config file" should be a regular D module * It should work with Dub. In the above example the "log" library and the application would be in separate Dub packages. I've done some experiments and I have some pieces working, but have not been able to glue everything together. I don't mind if there are any dirty tricks behind the scenes but I would like it to be as easy as the above example to use it, if possible. Does anyone have a system like this that is already available? -- /Jacob Carlborg
Re: How can I make DMD stop on the first fatal error? (-Wfatal-errors)
On Wednesday, 8 July 2020 at 00:54:40 UTC, Marcone wrote: How can I make DMD stop on the first fatal error like -Wfatal-errors on C++? With the `-verrors=1` flag. You can specify exactly how many errors the compiler should emit before halting the compilation. Specify `0` for unlimited. -- /Jacob Carlborg
Re: Construct an used-defined hash table container type from an AA-literal expression
On Tuesday, 7 July 2020 at 12:41:23 UTC, Per Nordlöw wrote: What about construction and assignment from a static array of `Pair`'s? Wouldn't that be easier on the compiler? I you refer to it wouldn't be using templates, then yes, I guess so. -- /Jacob Carlborg
Re: Construct an used-defined hash table container type from an AA-literal expression
On Sunday, 5 July 2020 at 21:06:32 UTC, Per Nordlöw wrote: Is there a way to construct a custom written hash-table container (struct) from an AA-literal expression? I think your best bet is a tuple of pairs, because then you're not limited to compile time values, but it won't look pretty: import std; struct Pair { string key; int value; } void main() @nogc { auto a = tuple(Pair("foo", 1), Pair("bar", 2)); } -- /Jacob Carlborg
Re: Construct an used-defined hash table container type from an AA-literal expression
On Monday, 6 July 2020 at 01:43:43 UTC, user1234 wrote: --- import std; struct AA { void opIndexAssign(int v, string k) @nogc {} } void main(string[] args) @nogc { AA myCustom; enum literal = ["one":1, "two":2].stringof[1..$-1]; enum pairs = literal.split(',').array; static foreach (p; pairs) { myCustom[mixin(p.split(':')[0])] = mixin(p.split(':')[1]); } } --- `static foreach` actual works for AA literals in `@nogc` functions. So there's no need complicate things with `.stringof`: struct Foo { int a; int b; } enum literal = ["one": Foo(1, 2), "two": Foo(3, 4)]; struct AA { void opIndexAssign(Foo value, string k) @nogc { } } void main() @nogc { AA aa; static foreach (k, v; literal) { aa[k] = v; } }
Re: Construct an used-defined hash table container type from an AA-literal expression
On Monday, 6 July 2020 at 01:43:43 UTC, user1234 wrote: Hereh we go ;) --- import std; struct AA { void opIndexAssign(int v, string k) @nogc {} } void main(string[] args) @nogc { AA myCustom; enum literal = ["one":1, "two":2].stringof[1..$-1]; enum pairs = literal.split(',').array; --- That split won't work if you have something more complicated, like struct values: struct Foo { int a; int b; } enum literal = ["one":Foo(1, 2), "two":Foo(3, 4)].stringof[1..$-1]; enum pairs = literal.split(',').array; static assert(pairs == 4); -- /Jacob Carlborg
Re: Print only part of a stack trace
On 2020-07-01 19:44, Dennis wrote: On assertion failure, the default error handler prints a stack trace that looks like this [library functions] [application functions] [druntime start-up functions] I'm only interested in application functions, the rest is noise. I could easily filter unwanted lines out if I had the stack trace in string form, but I don't know how to obtain that. Is there a simple way to do this, or should I delve into Druntime internals? Could `Runtime.traceHandler` [1] be that you're looking for? [1] https://dlang.org/phobos/core_runtime.html#.Runtime.traceHandler -- /Jacob Carlborg
Re: Calling C functions
On Tuesday, 30 June 2020 at 12:22:15 UTC, Steven Schveighoffer wrote: (i.e. one cannot use extern(D) functions for C callbacks). I don't think that's a big issue. Honestly, I don't think it's an issue at all. BTW, the order of arguments is not the only thing. Variadic functions in D and C are completely different. I don't think it's possible to implement a C style variadic function with D linkage (the language doesn't provide a syntax for it). There's also D specific types which C cannot handle (like arrays and delegates). I'm sure there are other differences in the ABIs. -- /Jacob Carlborg
Re: Calling C functions
On Monday, 29 June 2020 at 16:34:33 UTC, Steven Schveighoffer wrote: Are you sure? On the ABI page [1] , it says "The extern (C) and extern (D) calling convention matches the C calling convention used by the supported C compiler on the host system." In that case the documentation is wrong. Here's an example showing the differences: $ cat foo.c #include void foo(int a, int b) { printf("a=%d b=%d\n", a, b); } $ clang -c foo.c $ cat main.d pragma(mangle, "foo") extern (D) void foo_extern_d(int, int); pragma(mangle, "foo") extern (C) void foo_extern_c(int, int); void main() { foo_extern_d(1, 2); foo_extern_c(1, 2); } $ dmd main.d foo.o $ ./main a=2 b=1 a=1 b=2 This is on macOS. -- /Jacob Carlborg
Re: Calling C functions
On 2020-06-26 18:54, Denis wrote: OK, now this makes sense. I tested calling the same callback function directly from D: it compiled and worked correctly. So at least prefixing the callback function with `extern(C)` doesn't prevent the rest of the D program from calling it too. No, of course not. How would you otherwise call your `cfunc` function from your original example ;) -- /Jacob Carlborg
Re: Downloading files over TLS
On 2020-06-26 15:16, Adam D. Ruppe wrote: Yeah, I've been wanting to change that and use the native apis for years but like I just haven't been able to figure out the documentation of them. That would be nice. That's the problem of everything Apple makes. Kinda drives me nuts trying to keep up with their endless churn and constantly Think Different campaigns. Hehe, yeah. https://docs.microsoft.com/en-us/windows/win32/winhttp/winhttp-sessions-overview I guess that is more middle level but it isn't too hard to use. I think there's a flat out url -> bytes function too but I don't remember what it is. Regardless, the Windows functions may look familiar if you have done AJAX - that was based on an IE object which was based on the Windows API. Thanks, I'll take a look. -- /Jacob Carlborg
Re: Downloading files over TLS
On 2020-06-26 14:43, User wrote: It is possible to statically link libcurl into your application. No need to use OpenSSL as libcurl can be built with SChannel. That sounds good. It looks like I remembered wrong. std.net.curl uses `dlopen` on libcurl, not OpenSSL. This might be less of an issue assuming libcurl is built with the platform provided TLS implementation. Just make sure it's possible to statically link libcurl, without using `dlopen`. -- /Jacob Carlborg
Re: Downloading files over TLS
On 2020-06-26 14:41, Kagamin wrote: Maybe just start wget or something like that? The point was to avoid runtime dependencies. Since you want the latest certificate storage, you intend to support only the latest system. Many root certificates will timeout now. I didn't say the latest certificate storage. I said the platform provided. If the system provided certificate expires I guess a lot of things won't work. An alternative would be to both ship with a certificate and be able to use the system provided one and try both https://docs.microsoft.com/en-us/windows/win32/winhttp/about-winhttp I'll take a look, thanks. -- /Jacob Carlborg
Re: Downloading files over TLS
On Friday, 26 June 2020 at 11:10:27 UTC, ikod wrote: Hello, re `requests` - it uses dlopen (and variants for OSX and Windows, see https://github.com/ikod/dlang-requests/blob/master/source/requests/ssl_adapter.d#L50). The reason for dlopen is simple - compatibility with both openssl ver 1.0 and 1.1 (which have incompatible interfaces). To solve this problem I expose common interface for Requests internal needs, and detect and use different underlying openssl interfaces depending on library version. Oh, it's that bad. That's disappointing. I'm sure it is possible to detect library version at build time, and then use static linking. It just require some time investment to find most acceptable solution on how to do this. I'm using a script (written in D) in my tool, DStep [1][2], to identify which versions of libclang is available and to select between dynamic link (not using `dlopen`) and static linking of libclang. It works pretty well. Re Windows - I'd be happy to use native SecureChannel but I have zero windows programming experience. I'm completely open for any help in this field. I don't have much experience with programming on Windows either. macOS is my main platform. Bottom line - problem with SSL/TLS libraries lies in incompatibility between platforms and even inside the single library. Yes. I'm trying to identify the best solution, which ideally requires the least amount of work. [1] https://github.com/jacob-carlborg/dstep/blob/master/configure.d [2] https://github.com/jacob-carlborg/dstep/blob/master/dub.json#L34-L41 -- /Jacob Carlborg
Downloading files over TLS
Downloading files over TLS. This seems that it's something that should be quite simple to do. My high level goals are cross-platform and easy distribution. I don't need anything fancy just a simple API like this: download("https://url.com";, "/local/file"); Because of these goals, I have a few requirements, which I don't think are unreasonable: * Cross-platform (macOS, Linux, Windows, possible FreeBSD) * Minimal runtime requirements (I don't mind a few compile time requirements). I also don't mind runtime requirements that are guaranteed to exist * Ideally using the platform provided TLS implementation, or at least platform provided certificates (I've been bitten several times due to old certificates making request fail) * On Linux I would really like to have a fully statically linked binary, this will make distribution easier * Due to the previous requirement, I think using musl will be required. For most parts glibc works fine for static linking, but I think in the case of networking it does not work. The DNS lookup (or something like that) doesn't work with static linking I think the main problem of all this is picking the right TLS implementation. The obvious candidate is std.net.curl, but I'm going to explain why that is not ideal, at least not how it's currently implemented. std.net.curl relies on OpenSSL, which is deprecated on several platforms. On several platforms it's not the main, platform provided TLS implementation. As far as I know, it also provides its own certificates and doesn't rely on the ones provided by the platform. I going to break down some alternatives per platform. macOS: * std.net.curl. Depends on libcurl and OpenSSL. OpenSSL has been deprecated on macOS for many years. In one wants to use OpenSSL anyway, one need to ship it with the binary (statically link it). For other problems, see above * requests [1]. This is a potential better alternative than std.net.curl since it doesn't rely on libcurl. But, it still relies on OpenSSL, so it has the same problems as std.net.curl * vibe.d [2]. Does not depend on libcurl, but does depend on OpenSSL. But, it also supports Botan, which is promising. I'll discuss Botan separately * Hunt [3]. Same problem as the other ones, relies on OpenSSL * Arsd [4]. Relies on OpenSSL * SecureTransport [5]. This is an Apple specific library provided by the platform. It seems to more or less follow the same idea as OpenSSL, it's independent on the transport layer and works with BSD sockets. Initially this looks perfect, it's provided by the platform and uses certificates provided by the platform. The main problem is that it has been deprecated. It also only supports TLS up to version 1.2 and since it's deprecated, it's likely that it won't support any newer versions * Network [6]. This is an Apple specific library provided by the platform. This is the recommend alternative to SecureTransport. The problem is that this is not just an alternative TLS implementation, it's a completely different alternative to BSD sockets. The API is completely different and will require some extra layers to to provide a cross-platform API. This means that I cannot use any of the existing library to just add TLS, it will be a completely different implementation, which might be ok. Another big problem is that it only available on macOS 10.14 and later. I have not decided yet if this is acceptable or not * NSURLSession [7]. This is an Apple specific Objective-C class, provided by the platform. It's higher level than the Network framework and is available on all versions of macOS. This will again require a some extra layers to hide the platform specific API. There's also a problem with LDC which has very limited support for Objective-C interoperability. Linux: As far as I know, OpenSSL (or some version of it, like LibreSSL) is what's provided by the platform. So I guess that has to be acceptable on Linux. * std.net.curl. The main problem with std.net.curl on Linux is that it uses `dlopen` to load the TLS library. `dlopen` doesn't work for a statically linked executable. Side note, `dlopen` doesn't work on iOS (for other reasons) so it would be nice if this could be fixed * requests. Seems to do that same as std.net.curl, uses `dlopen` * For the other alternatives (mentioned in the macOS section), I haven't investigated if they use `dlopen` or not Windows: I don't know that much of this platform. * std.net.curl and basically all other options already mentioned relies on OpenSSL, which is not provided by the platform * SChannel. As far as I know, this the the platform provided implementation of TLS on Windows. * Are there any high level APIs, like NSURLSession, on Windows that can be used to download files? Botan: This seems like a good candidate. It even exists a full D port of it [8]. * This is not used by any specific platform but it can use the platform provided certific
Re: Calling C functions
On Friday, 26 June 2020 at 00:30:22 UTC, Denis wrote: I have a two questions about calling C functions from D. (1) When passing a D callback to a C function, is there a way to write the code without having to prefix the callback declaration with "extern(C)"? It's not a big deal adding the prefix to the D function declaration. It just seems odd to me to prefix D code with "extern(C)". For example, the following code works: extern(C) void cfunc(void function(int)); extern(C) void dcallback(int x) {...} <-- Why extern(C)? cfunc(&dcallback); Can this be rewritten, dropping the prefix from the second line? If not, it would be helpful to know why "extern(C)" is needed here too. No, it cannot be dropped. `extern(C)` is required because C and D are using different calling conventions (D functions are also mangled). For example, D (at least DMD and LDC) are passing the arguments to the function in reverse. (2) Is there a way to restrict the invocation of a linked C function to one specific D function? If the C header is defined in one of the core.stdc libraries, the import statement can either be global or inside a specific D function -- both work. In contrast, when the C function prototype is written directly into the D program (as above), the linker complains unless this declaration is made global. If it's possible to restrict the scope of the C function to just one D function, I'll take advantage. For functions nested in a D language construct (class, struct, function) the compiler will always use the D mangling, instead of the C mangling. In theory it would be possible to workaround that by forcing the mangled name using `pragma(mangle)`, but for some reason the compiler doesn't allow `pragma(mangle)` inside a function body, on a nested function declaration. You can wrap up everything in a struct, as follows: struct printf { pragma(mangle, "printf") extern (C) private static int printf(in char*, ...); static int opCall(Args...)(Args args) { return printf(args); } } void main() { printf("asd\n".ptr); } The `printf` function can be called from anywhere within the module, but not outside the module. -- /Jacob Carlborg
Re: How to correctly integrate D library to Swift/Obj-C mobile project?
On Monday, 22 June 2020 at 14:32:21 UTC, Anton wrote: I have a static library (.a) compiled with LDC for iOS platform. But I can't figure out how to correctly connect it to the project and call its functions. I've already linked binary with library to the project but IDE still doesn't see its classes and methods. Do I need to do some additional configurations? When you say "IDE", I'm going to assume you're referring to Xcode. Xcode has absolutely no support for D at all. Since the Objective-C support in LDC is so limited I would recommend creating `extern(C)` functions in the D code, which forwards to your D functions (or have the functions being `extern(C)` to begin with). Then you need to have these declarations available in a C header file, either created by using the `-HC` flag or by manually writing the declarations. -- /Jacob Carlborg
Re: How to correctly integrate D library to Swift/Obj-C mobile project?
On Monday, 22 June 2020 at 19:41:22 UTC, Vlad wrote: Is it even possible to compile D for iOS and use it the same way as compiled C++ static library? (We do need a D runtime) Yes, druntime/Phobos will need to be linked like any other static library. -- /Jacob Carlborg
Re: Some questions about strings
On Monday, 22 June 2020 at 04:08:10 UTC, Denis wrote: The terminating null character was one of the reasons I thought strings were different from char arrays. Now I know better. String **literals** have a terminating null character, to help with integrating with C functions. But this null character will disappear when manipulating strings. You cannot assume that a function parameter of type `string` will have a terminating null character, but calling `printf` with a string literal is fine: printf("foobar\n"); // this will work since string literals have have a terminating null character -- /Jacob Carlborg
Re: Dub Error Message "Invalid variable: DUB"
On 2020-06-07 11:24, Russel Winder wrote: Hi, Why on earth is Dub sending out this error message (Invalid variable: DUB) on GitLab but not on Travis-CI or locally? OK, that was slightly rhetorical, more reasonably, why is dub sending out this message at all? Dub is supposed to make an environment variable named "DUB" available to the build script. It should contain the path to the Dub executable. I guess that somehow fails. Might be some unexpected character in the path? -- /Jacob Carlborg
Re: Objective C protocols
On 2020-05-17 11:32, John Colvin wrote: On Saturday, 16 May 2020 at 19:14:51 UTC, John Colvin wrote: What's the best way to implement an Objective C protocol in D? I see mention here https://dlang.org/changelog/2.085.0.html#4_deprecated_objc_interfaces but it's not clear where things are these days. It's the same these days. It's still not implemented. Based on some experimentation, I'm starting to wonder do protocols actually have any runtime component in Objective C? No, not really. Because if I pass in an extern(Objective-C) class with the right interface to a function expecting a protocol everything just works. Yes, that works fine. You can put the methods from the protocol directly in the class that implements them or in a base class. If you really want to have a specific type for the protocol you can use an abstract class to emulate an interface/protocol and cast your actual class to the abstract class: extern (Objective-C) abstract class Printer // the protocol { void print(int value) @selector("print:"); } extern (Objective-C) class Foo : NSObject { override static Foo alloc() @selector("alloc"); override Foo init() @selector("init"); void print(int value) @selector("print:") { writeln(value); } } extern (Objective-C) void print(Printer); void main() { auto foo = Foo.alloc.init; print(cast(Printer) cast(void*) foo); // need to cast through void* } -- /Jacob Carlborg
Re: Get unknown symbol (struct, method, class) tagged with User Defined Attributes
On 2020-05-12 06:02, Steven Schveighoffer wrote: If you want a list of ALL symbols that have the UDA in the application, that would require some form of runtime reflection (like Java). D has very limited support for runtime reflection. In D, you would use some form of registration to tell the system about your symbols. I think it's possible to implement the `RTInfo` template in `object.d`. But that requires a custom druntime. `RTInfo` is a template that is instantiated once for each type in the program. -- /Jacob Carlborg
Re: D and Async I/O
On 2020-05-12 11:23, Russel Winder wrote: As far as I can tell D has no futures… Future and async in vibe.d [1]. Future in Mecca [2]. [1] https://vibed.org/api/vibe.core.concurrency/async [2] https://github.com/weka-io/mecca/blob/0593a35dd1a9978855d7db349fc1172f04cf8013/src/mecca/reactor/sync/future.d#L23 -- /Jacob Carlborg
Re: Error running concurrent process and storing results in array
On 2020-05-07 02:17, data pulverizer wrote: What is the difference between -O2 and -O3 ldc2 compiler optimizations? `--help` says -O2 is "Good optimizations" and -O3 "Aggressive optimizations". Not very specific. -- /Jacob Carlborg
Re: D and Async I/O
On 2020-05-11 16:44, Russel Winder wrote: Crickey, a third option. This wil increase my dithering! ;-) Forth: Mecca [1] :) [1] https://github.com/weka-io/mecca -- /Jacob Carlborg
Re: Error running concurrent process and storing results in array
On 2020-05-06 12:23, data pulverizer wrote: Yes, I'll do a blog or something on GitHub and link it. It would be nice if you could get it published on the Dlang blog [1]. One usually get paid for that. Contact Mike Parker. [1] https://blog.dlang.org -- /Jacob Carlborg
Re: Retrieve the return type of the current function
On 2020-05-05 19:11, learner wrote: On Tuesday, 5 May 2020 at 16:41:06 UTC, Adam D. Ruppe wrote: typeof(return) Thank you, that was indeed easy! Is it possible to retrieve also the caller return type? Something like: Yes, kind of: void foo(string caller = __FUNCTION__)() { import std.traits : ReturnType; alias R = ReturnType!(mixin(caller)); static assert(is(R == int)); } int bar() { foo(); return 0; } -- /Jacob Carlborg
Re: Error running concurrent process and storing results in array
On 2020-05-06 06:04, Mathias LANG wrote: In general, if you want to parallelize something, you should aim to have as many threads as you have cores. That should be _logical_ cores. If the CPU supports hyper threading it can run two threads per core. -- /Jacob Carlborg
Re: Error running concurrent process and storing results in array
On 2020-05-06 08:54, drug wrote: Do you try `--fast-math` in ldc? Don't know if 05 use this flag Try the following flags as well: `-mcpu=native -flto=full -defaultlib=phobos2-ldc-lto,druntime-ldc-lto` -- /Jacob Carlborg
Re: Error running concurrent process and storing results in array
On 2020-05-06 05:25, data pulverizer wrote: I have been using std.parallelism and that has worked quite nicely but it is not fully utilising all the cpu resources in my computation If you happen to be using macOS, I know that when std.parallelism checks how many cores the computer has, it checks physical cores instead of logical cores. That could be a reason, if you're running macOS. -- /Jacob Carlborg
Re: DConf 2017 Videos
On 2020-04-24 22:24, matheus wrote: Hi, please could someone tell me where can I find videos from DConf 2017? I pretty sure I watched them on Youtube sometime ago, but I can't find anymore. By the way, I'm looking from one video where someone shows some "C flaws" and how to D as Better C could solve that. I think it was the second talk in this list: https://dconf.org/2017/schedule/ Any idea? I have previously downloaded the DConf videos. I sent them to Mike for him to upload. -- /Jacob Carlborg
Re: Array fill performance differences between for, foreach, slice
On 2020-03-31 23:30, data pulverizer wrote: $ dmd fill.d && ./fill You have not enabled optimizations. You should compile with `-O -release -inline` to enable all optimizations. Without optimizations I get numbers like these: Slice: Mean time(usecs): 92.91, Standard Deviation: 49.8002 Foreach: Mean time(usecs): 183.95, Standard Deviation: 30.749 For: Mean time(usecs): 239.74, Standard Deviation: 30.753 With optimizations turned on I get quite varying results: Slice: Mean time(usecs): 96.84, Standard Deviation: 52.5676 Foreach: Mean time(usecs): 95.84, Standard Deviation: 21.9244 For: Mean time(usecs): 106.73, Standard Deviation: 31.2545 Slice: Mean time(usecs): 192.03, Standard Deviation: 115.971 Foreach: Mean time(usecs): 177.06, Standard Deviation: 128.012 For: Mean time(usecs): 89.14, Standard Deviation: 25.681 Slice: Mean time(usecs): 97.74, Standard Deviation: 53.2058 Foreach: Mean time(usecs): 79.72, Standard Deviation: 11.0088 For: Mean time(usecs): 80.54, Standard Deviation: 12.06 I you care about performance you should really compile using LDC (with `-O5 -release -flto=full -defaultlib=phobos2-ldc-lto,druntime-ldc-lto`), which usually produces much better code: Slice: Mean time(usecs): 50.58, Standard Deviation: 46.2621 Foreach: Mean time(usecs): 53.92, Standard Deviation: 19.8039 For: Mean time(usecs): 39.89, Standard Deviation: 7.80041 Slice: Mean time(usecs): 76.62, Standard Deviation: 73.0014 Foreach: Mean time(usecs): 49.63, Standard Deviation: 24.5672 For: Mean time(usecs): 40.02, Standard Deviation: 7.67388 -- /Jacob Carlborg
Re: A question about C++ interop
On 2020-03-27 20:17, YD wrote: Hi, I have a C++ header file which looks like class A { public: static A *create(); virtual int f() const = 0; }; And there is a C++ library file which provides the implementation, so that if I write a C++ program and call auto *p = A::create(); std::cout << p->f() << '\n'; It will work. Now I want to interface to this C++ library through D, and I wrote module test; import std.stdio; extern(C++) { class A { static A *create(); abstract int f() const; } } void main() { auto p = A.create(); writeln(p.f()); } This program will compile and link, but it core dumps at the call to f(). If I wrap up the C++ interface into a C interface (using a void *), and interface to the wrapped-up C library through D, it will work fine. So what am I doing wrong here? Thanks! Classes in D are always passed by reference. Try dropping the pointer in the `create` method: static A create(); -- /Jacob Carlborg