Re: Two major problems with dub
On 8/1/21 11:38 AM, Alain De Vos wrote: Dub has two big problems. 1. Unmaintained dub stuff. 2. Let's say you need bindings to postgresql library and you will see dub pulling in numerous of libraries, which have nothing at all to do with postgresql. More like a framework stuff. This creates unneeded complexity, bloatware, dependency hell, maintainability, in my humble opinion. Dub should do one thing and do it good. Feel free to elaborate. My biggest pet peeve is when a library pulls in a unittest framework (which then might pull in all kinds of other things). I get it, and I get why it's needed as a non-optional dependency, but I have no intention on unittesting the library, I just want to use it. It's a shame to pull in everything that it needs because of that. I recently added the [dateparser](https://code.dlang.org/packages/dateparser) project as a library. I found it was pulling in emsi-container, so it could have an array container ([one line of code](https://github.com/JackStouffer/date-parser/blob/55e6218427974051b5179c98e0828b1d2a17629e/source/dateparser/package.d#L807)) that enables use of stdx.allocator. Ironically, the default (and all I cared about) is using the GC allocator. I wish there was a way to make this dependency optional. If more dub projects used optional dependencies, that would be nice. Given the way D works, and often template-heavy coding styles, I think it's going to be hard to do this correctly, without careful attention and lots of `version(has_xxx)` conditionals. -Steve
Re: Is returning void functions inside void functions a feature or an artifact?
On Monday, 2 August 2021 at 14:31:45 UTC, Rekel wrote: I recently found one can return function calls to void functions, though I don't remember any documentation mentioning this even though it doesn't seem trivial. [...] If this is intended, where could I find this in the docs? I haven't been able to find previous mentions on this, neither on the forum. You got the answer in another reply but here is a bit of more fun: ```d void main() { return cast(void) 1; } ``` it's all about the type system and conversions
Re: Find struct not passed by reference
On Monday, 2 August 2021 at 23:06:42 UTC, frame wrote: Is there a way to find a struct which should be passed by reference but accidentally isn't? Maybe with copy constructors? @disable postblit: ```d struct NoCopy { int n; @disable this(this); } void modify(NoCopy nc) { nc.n++; } void main() { NoCopy x; x.modify; // Error: struct `catchcopy.NoCopy` is not copyable ... } ``` std.typecons.Unique: ```d import std.typecons : Unique; class Val { int n; } void incr(Unique!Val v) { v.n++; } void decr(ref Unique!Val v) { v.n--; } void show(Unique!Val v) { import std.stdio : writeln; writeln(v.n); } void main() { Unique!Val x = new Val; // x.incr; // Error: ... is not copyable x.decr; x.release.show; } ```
Find struct not passed by reference
Is there a way to find a struct which should be passed by reference but accidentally isn't? Maybe with copy constructors?
Re: Is returning void functions inside void functions a feature or an artifact?
On Mon, Aug 02, 2021 at 04:42:14PM +, Rekel via Digitalmars-d-learn wrote: [...] > Also slightly off topic, but when would one use an alias instead of a > function/delegate? I haven't used aliases before. When you want a compile-time binding that could potentially elide the indirect function call to a delegate. // This generates a specialized template instance with // `callback` bound to the passed-in compile-time argument, for // each call to `myFunc`. auto myFunc(alias callback)(...) { ... } // This is a single common function that receives an opaque // runtime delegate and binds it at runtime. auto myFunc(int delegate(...) callback, ...) { ... } T -- An elephant: A mouse built to government specifications. -- Robert Heinlein
compare types of functions.
Hello, Why this doesn't work: ```d template DestructorType(T){ alias Get(T) = T; alias DestructorType = Get!(typeof((void*){ T tmp; })); } struct Foo{ ~this()@safe{} } ``` ```d void main(){ //Error: static assert: `is(void function(void*) pure nothrow @nogc @safe : void function(void*) @safe)` is false static assert(is(void function(void*)pure nothrow @safe @nogc : DestructorType!Foo)); } ``` but this work: ```d void main(){ alias X = void function(void*)@safe; static assert(is(void function(void*)pure nothrow @safe @nogc : DestructorType!Foo)); } ```
Re: Is returning void functions inside void functions a feature or an artifact?
On 8/2/21 9:42 AM, Rekel wrote: > when would one use an alias instead of a > function/delegate? I haven't used aliases before. alias will match both functions and delegates... and... any symbol at all. So, if you don't have a reason to constain the user, callable template parameters are most usefully aliases. Ali
Re: Is returning void functions inside void functions a feature or an artifact?
On Monday, 2 August 2021 at 14:51:07 UTC, H. S. Teoh wrote: This is intentional, in order to make it easier to write generic code without always having to special-case functions that don't return anything. Ooh that indeed seems useful. Thanks for the hint. Also slightly off topic, but when would one use an alias instead of a function/delegate? I haven't used aliases before.
Re: cast to pure function stop work after upgrade
On Monday, 2 August 2021 at 15:10:06 UTC, vit wrote: On Monday, 2 August 2021 at 11:28:46 UTC, Tejas wrote: [...] Try this: ```d void main(){ fp = cast(typeof(fp))&VFORMAT; //fails } ``` Agh, stupid me. You the man!!
Re: Is returning void functions inside void functions a feature or an artifact?
On Monday, 2 August 2021 at 14:46:36 UTC, jfondren wrote: C, C++, Rust, and Zig are all fine with this. Nim doesn't like it. I had no clue, never seen it used in any case. I've always assumed one couldn't return void as it's not a value. I guess intuitions aren't always universal 😅. Good to know c is fine with this too! ^^
Re: cast to pure function stop work after upgrade
On Monday, 14 June 2021 at 13:31:51 UTC, baby_tiger wrote: this used work for me, after upgrade I get this error. how to fix it ? import std.traits; enum LogLevel : ubyte { INFO = 0, WARN, ERROR, FATAL, } extern (C) string VFORMAT(LogLevel level, string file, size_t line, char[] tmp, bool line_break, string tag, string fmt, ...) @nogc nothrow { return null; } template asPure(string P, alias Fn) if (isFunctionPointer!(typeof(&Fn))) { enum N = __traits(identifier, Fn); enum string asPure = "private alias " ~ N ~ "_PURE = " ~ typeof(&Fn).stringof ~ " pure;\n" ~ "__gshared immutable " ~ N ~ "_PURE " ~ P ~"= cast(" ~ N ~ "_PURE) &" ~ N ~ " ;" ; } enum xx = asPure!("VFORMATP", VFORMAT); mixin(xx); void main(){ } reinterpreting cast from `nothrow @nogc extern (C) string(LogLevel level, string file, ulong line, char[] tmp, bool line_break, string tag, string fmt, ...)*` to `pure nothrow @nogc extern (C) string(LogLevel, string, ulong, char[], bool, string, string, ...)*` is not supported in CTFE ```d int foo(int x)@safe{ return x; } /* This is valid. @safe CTFE cast, systemFoo has less restrictive function type. */ auto systemFoo = cast(int function(int)@system)&foo; /* ERROR UNSAFE CTFE cast, pureFoo has more restrictive function type. */ //auto pureFoo = cast(void function(int)pure)&foo; int function(int)pure pureFoo; shared static this(){ /* This is valid. UNSAFE RUNTIME cast. */ pureFoo = cast(int function(int)pure)&foo; } void main(){ assert(pureFoo(42) == 42); } ```
Re: cast to pure function stop work after upgrade
On Monday, 2 August 2021 at 11:28:46 UTC, Tejas wrote: On Monday, 14 June 2021 at 13:31:51 UTC, baby_tiger wrote: [...] It seems to not work at runtime either. Maybe they've made this behaviour illegal now? Hopefully someone answers. ```d import std.traits; import core.stdc.stdarg; enum LogLevel : ubyte { INFO = 0, WARN, ERROR, FATAL, } extern (C) string VFORMAT(LogLevel level, string file, size_t line, char[] tmp, bool line_break, string tag, string fmt, ...) @nogc nothrow { return null; } extern (C) string function(LogLevel level, string file, size_t line, char[] tmp, bool line_break, string tag, string fmt, ...) @nogc nothrow pure fp; void main(){ fp = &VFORMAT; //fails } ``` Try this: ```d void main(){ fp = cast(typeof(fp))&VFORMAT; //fails } ```
Re: Is returning void functions inside void functions a feature or an artifact?
On Mon, Aug 02, 2021 at 02:31:45PM +, Rekel via Digitalmars-d-learn wrote: > I recently found one can return function calls to void functions, > though I don't remember any documentation mentioning this even though > it doesn't seem trivial. This is intentional, in order to make it easier to write generic code without always having to special-case functions that don't return anything. E.g.: auto myWrapper(alias func, Args...)(Args args) { // Don't have to special case void return. return func(args); } int hooray(int i) { return i+1; } void boo(int j) { return; } int z = myWrapper!hooray(1); myWrapper!boo(2); Otherwise you'd have to litter your code with redundant special cases: auto myWrapper(alias func, Args...)(Args args) { static if (is(ReturnType!func == void)) func(args); else return func(args); // same thing but different } Allowing `return func(args)` for void functions eliminates the need for such special cases. T -- "640K ought to be enough" -- Bill G. (allegedly), 1984. "The Internet is not a primary goal for PC usage" -- Bill G., 1995. "Linux has no impact on Microsoft's strategy" -- Bill G., 1999.
Re: Is returning void functions inside void functions a feature or an artifact?
On Monday, 2 August 2021 at 14:31:45 UTC, Rekel wrote: I recently found one can return function calls to void functions, though I don't remember any documentation mentioning this even though it doesn't seem trivial. ```d void print(){ writeln("0"); } void doSomething(int a){ if (a==0) return print(); writeln("1"); } void main(string[] args) { doSomething(0); // Prints 0 but not 1. } ``` If this is intended, where could I find this in the docs? I haven't been able to find previous mentions on this, neither on the forum. I don't know where you can find this in the docs, but what doesn't seem trivial about it? The type of the expression `print()` is void. That's the type that `doSomething` returns. That's the type of the expression that `doSomething` does return and the type of the expression following a `return` keyword in `doSomething`. Rather than a rule expressly permitting this, I would expect to find to either nothing (it's permitted because it makes sense) or a rule against it (it's expressly forbidden because it has to be to not work, because it makes sense). C, C++, Rust, and Zig are all fine with this. Nim doesn't like it.
Is returning void functions inside void functions a feature or an artifact?
I recently found one can return function calls to void functions, though I don't remember any documentation mentioning this even though it doesn't seem trivial. ```d void print(){ writeln("0"); } void doSomething(int a){ if (a==0) return print(); writeln("1"); } void main(string[] args) { doSomething(0); // Prints 0 but not 1. } ``` If this is intended, where could I find this in the docs? I haven't been able to find previous mentions on this, neither on the forum.
Re: Registering-unregistering threads
On Friday, 30 July 2021 at 23:48:41 UTC, solidstate1991 wrote: Info on it is quite scarce and a bit confusing. If I unregister from the RT, will that mean it'll be GC independent, or will have other consequences too? The consequence is that the stack memory of that thread isn't traced, so things that are only "owned" pointed to transitively by pointers on the thread stack might get collected under your feet. Your thread should use things that outlive its existence.
Re: cast to pure function stop work after upgrade
On Monday, 14 June 2021 at 13:31:51 UTC, baby_tiger wrote: this used work for me, after upgrade I get this error. how to fix it ? import std.traits; enum LogLevel : ubyte { INFO = 0, WARN, ERROR, FATAL, } extern (C) string VFORMAT(LogLevel level, string file, size_t line, char[] tmp, bool line_break, string tag, string fmt, ...) @nogc nothrow { return null; } template asPure(string P, alias Fn) if (isFunctionPointer!(typeof(&Fn))) { enum N = __traits(identifier, Fn); enum string asPure = "private alias " ~ N ~ "_PURE = " ~ typeof(&Fn).stringof ~ " pure;\n" ~ "__gshared immutable " ~ N ~ "_PURE " ~ P ~"= cast(" ~ N ~ "_PURE) &" ~ N ~ " ;" ; } enum xx = asPure!("VFORMATP", VFORMAT); mixin(xx); void main(){ } reinterpreting cast from `nothrow @nogc extern (C) string(LogLevel level, string file, ulong line, char[] tmp, bool line_break, string tag, string fmt, ...)*` to `pure nothrow @nogc extern (C) string(LogLevel, string, ulong, char[], bool, string, string, ...)*` is not supported in CTFE It seems to not work at runtime either. Maybe they've made this behaviour illegal now? Hopefully someone answers. ```d import std.traits; import core.stdc.stdarg; enum LogLevel : ubyte { INFO = 0, WARN, ERROR, FATAL, } extern (C) string VFORMAT(LogLevel level, string file, size_t line, char[] tmp, bool line_break, string tag, string fmt, ...) @nogc nothrow { return null; } extern (C) string function(LogLevel level, string file, size_t line, char[] tmp, bool line_break, string tag, string fmt, ...) @nogc nothrow pure fp; void main(){ fp = &VFORMAT; //fails } ```
Re: translate C struct char array into D
On Friday, 30 July 2021 at 21:53:48 UTC, russhy wrote: On Friday, 30 July 2021 at 14:05:58 UTC, workman wrote: I get want to define this struct in D: ```c struct test1 { struct test1 *prev; struct test1 *next; size_t v1; size_t v2; size_t v3; char data[]; }; ``` ```d struct test1 { test1 *prev; test1 *next; size_t v1; size_t v2; size_t v3; char* data; }; ``` when I compare the size, test1.sizeof is 48 and sizeof(struct test1) from C is 40. Anyone can explain what should I do with this ? If I use test1 as member of other struct, the total size will not match. ```d struct test1 { test1 *prev; test1 *next; size_t v1; size_t v2; size_t v3; char[0] data; } ``` data.ptr to access its pointer Thanks for you all for the explain and tips, I will try avoid embed this struct into parent.