Re: Non-ugly ways to implement a 'static' class or namespace?
On Thursday, 9 February 2023 at 20:05:06 UTC, Ali Çehreli wrote: Besides, D has zero problems with its private implementation in the sense that there has been zero bugs related to it being that way. That is how a Python aficionado would defend the absence of visibility attributes therein. "We don't have them, because _ is enough, and there are no bugs". And I would agree that D would be better off without visibility attributes entirely instead of having unending issues with them (private aliases, private + reflection, private + synchronized/invariant, etc). In contrast, I use D every day and love its relaxed attitude towards private. Having class-private doesn't preclude module-private. Dennis even submitted a PR implementing class-private, but it stalled because people couldn't agree on whether class-private should be "private to class" or "private to class instance".
Re: How to reliably detect an alias sequence?
On Sunday, 27 December 2020 at 18:25:10 UTC, sighoya wrote: This should work: ``` static assert(is(int == AliasSeq!int)); Drepl: static assert: `is(int == (int))` is false ``` That will only work for type tuples. We need a general solution that would work for any alias tuple. The most appropriate solution would be: ``` AliasSeq!int.stringof == (int); ``` But it wouldn't exclude false positives Yes, stringof is inadequate.
How to reliably detect an alias sequence?
Given a name bound to an alias sequence, what is a reliable way to detect that? import std.meta: AliasSeq; alias a = AliasSeq!int; static if () { } __traits(isSame, a, AliasSeq!a) could work but doesn't, because it flattens singletons, which means __traits(isSame, int, AliasSeq!int) is true. (A bug/bad design, IMO. If the intended behavior is not to flatten tuples passed to __traits, there is no reason to make a special case for singletons).
Re: How to get address of a nested function?
On Tuesday, 10 November 2020 at 20:13:30 UTC, Daniel Kozak wrote: non static nested function is a delegate, so you can just assign it to delegate like I have posted or you can du this: import std.stdio; void main() { void foo() { writeln("It works as expected"); } enum pfoo = void delegate() dg; dg.ptr = pfoo.ptr; dg.funcptr = pfoo.funcptr; dg(); } I need the funcptr at *compile time*, just as I can do "enum p = " for a non-static member function. I wrote "weird" not because '&' returns a delegate, but because I was surprised that we can have enum delegates at all, given that delegates carry a context pointer, which is not known at compile time. That is, the enum delegate appears to be some kind of alias of the '&' expression. Not that the issue is critical, but it makes a library I am writing incomplete.
Re: How to get address of a nested function?
On Tuesday, 10 November 2020 at 14:36:04 UTC, Steven Schveighoffer wrote: Is there a way to get a pointer to a non-static nested function? I don't think you can do it at compile time. You can at runtime by accessing the funcptr of the delegate. -Steve Thanks for the reply. I will post the issue to bugzilla.
How to get address of a nested function?
We can get the compile time equivalent of a member function's address by applying '&' to the function in a static context: struct S { void foo() {} } enum pfoo = // ok void main() { // now we can use the pointer to create, for example, a delegate S s; void delegate() dg; dg.ptr = dg.funcptr = pfoo; dg(); } However, we can't do that to a nested function: void main() { void foo() { } enum pfoo = // weird kind of an enum delegate; pfoo.funcptr can't be accessed at compile time. } Is there a way to get a pointer to a non-static nested function?
Re: What is the difference between enum and shared immutable?
On Thursday, 29 October 2020 at 16:45:51 UTC, Ali Çehreli wrote: immutable string p; shared static this() { p = environment["PATH"]; // <-- Run time } Immutable static variables being implicitly non-thread-local is a design mistake. Thread-local immutable variables have the same right to exist as immutable class/struct instance fields. This should be possible without hacks: immutable int val; // thread-specific value static this() { val = ...; } ...because it is logically the same as: struct V { immutable int val; } V val; static this() { val = V(...); }
Re: Send empty assoc array to function
On Friday, 10 July 2020 at 08:15:24 UTC, Max Samukha wrote: a unfortunate an unfortunate
Re: Send empty assoc array to function
On Thursday, 9 July 2020 at 21:04:57 UTC, Steven Schveighoffer wrote: Why isn't [] accepted as an empty AA literal? Because it's an empty dynamic array literal. If D were to accept an empty AA literal, I'd expect it to be [:]. -Steve Just as typeof(null) is a subtype of all nullable types, you could make typeof([]) a subtype of both AAs and dynamic arrays. [:] could still be made a specifically AA literal. BTW, writeln((int[int]).init) prints "[]" (to!string((V[K]).init) == "[]"), but pragma(msg, (int[int]).init) - the more general 'null' ((V[K]).init.stringof == "null"), which is a unfortunate inconsistency.
Re: Send empty assoc array to function
On Thursday, 9 July 2020 at 20:24:11 UTC, Steven Schveighoffer wrote: Yes, that is correct. -Steve Why isn't [] accepted as an empty AA literal?
Re: Send empty assoc array to function
On Thursday, 9 July 2020 at 19:53:42 UTC, JN wrote: foo( [] ) doesn't Should work in principle, but you can foo(null) to work around.
Re: How to ensure template function can be processed during compile time
On Wednesday, 8 July 2020 at 20:11:05 UTC, IGotD- wrote: Now since mySize is a template, shouldn't this work mySize!v, but it doesn't? What essential understanding have I missed here? You are trying to use a run-time value of v at compile-time, which is not possible. If you want the modified size of the type of a variable, you can pass the variable to the compile-time function by alias: enum mySize(alias e) = e.sizeof + 42; int v; enum size = mySize!v; pragma(msg, size); // 46LU If you want to the size of the type of a run-time expression, you will have to use typeof: static assert(mySize!(typeof(v + 1)) == 46);
Re: DMD 2.092 and DIP 25
On Saturday, 30 May 2020 at 07:00:07 UTC, Mike Parker wrote: I find it rather annoying, as I'm returning `const(char)*` and not `char*`, but it is what it is. My question is, if I add `return` to the function declarations, will this compile all the way back to DMD 2.067 *without* `-preview=dip25`? It works on 2.091.0. I always assumed a preview feature's syntax wasn't supported without the preview switch. https://run.dlang.io/is/aOZqww Since 2.067.1: Success and no output
Re: Is it legal to have physical package structure not corresponding to logical one? How to generate .di from that?
On Monday, 16 September 2019 at 13:13:50 UTC, Adam D. Ruppe wrote: On Monday, 16 September 2019 at 07:02:04 UTC, Max Samukha wrote: [...] Well, sort of, your code is perfectly legal and has worked since the beginning of D. The thing in the spec is referring to the assumption the compiler uses to find files not explicitly referenced on the build command. [...] Thank you, Adam.
Is it legal to have physical package structure not corresponding to logical one? How to generate .di from that?
Please consider a project: src/p2/ |---a.d |---b.d in which it is desirable that the logical package tree does not fully correspond to the filesystem subtree: src/p2/a.d: module p1.p2.a; ... src/p2/b.d: module p1.p2.b; import p1.p2.a; ... dmd compiles the above structure successfully, even though the spec explicitly states that "The packages correspond to directory names in the source file path" (https://dlang.org/spec/module.html#module_declaration, item 2): dmd -lib src/p2/a.d src/p2/b.d // ok Is the spec wrong? Can the current dmd behavior be relied on? If yes, how does one create an import tree from the structure like that? 'dmd -H -o- -Hdimport -op src/p1/a.d src/p2/b.d' is close, but it places the .di files into 'import/src/p1' directory (which is useless for automatic importing) instead of the expected 'import/p1/p2'. Is it possible to achieve that without making the build process unreasonably complex?
Re: Using CSS Data from Within My Code
On Thursday, 12 September 2019 at 09:54:35 UTC, Ron Tarrant wrote: I found this presented as a solution in a 2016 post: On Wednesday, 15 June 2016 at 22:05:37 UTC, captaindet wrote: enum myCSS = q{ GtkNotebook { background-color: #e9e9e9; } GtkNotebook tab { background-color: #d6d6d6; } }; But when I try to use it, I get the following errors: Warning: C preprocessor directive #e9e9e9 is not supported Warning: C preprocessor directive #d6d6d6 is not supported I thought it was odd having 'q' in front of the opening curly brace... is this a typo? Shorthand for "string quote"? Something like that? Or do I need to escape these somehow? q{} is a string that must only contain valid D tokens. D lexer does not like C directives. https://dlang.org/spec/lex.html#token_strings
Re: How to force an array literal into a read-only data segment?
On Thursday, 12 September 2019 at 08:54:09 UTC, a11e99z wrote: On Thursday, 12 September 2019 at 07:04:19 UTC, Max Samukha wrote: How to achieve the same for an array literal? The closest I could come: enum immutable(int[3]) _tmp = [1, 2, 3]; __gshared a = _tmp.ptr; Is it possible to force the array into rodata? https://p0nce.github.io/d-idioms/#Precomputed-tables-at-compile-time-through-CTFE static immutable(int[3]) _tmp = [1, 2, 3]; ? That looks the same as my example, where 'static' is redundant at the module level, and enum just removes the unneeded reference to the temporary from the object file. However, __gshared in my example does seem to be redundant - 'immutable' implies thread-shared in this case.
How to force an array literal into a read-only data segment?
test.d: __gshared t = "text".ptr; As expected, the "text" literal ends up in a read-only data segment, with a pointer to it stored in a writable data segment (_TMP0 pointing into .rodata.str1.1): .data segment _D4test1tPya: dd offset FLAT:_TMP0@64 db 000h,000h,000h,000h ; .data ends Hex dump of section '.rodata.str1.1': 0x 74657874 00 text. How to achieve the same for an array literal? The closest I could come: enum immutable(int[3]) _tmp = [1, 2, 3]; __gshared a = _tmp.ptr; But the array is still placed into the writable segment: .data segment internal: db 001h,000h,000h,000h,002h,000h,000h,000h ; db 003h,000h,000h,000h,000h,000h,000h,000h ; _D4test1aPyi: dd offset FLAT:internal@64 db 000h,000h,000h,000h ; .data ends Is it possible to force the array into rodata?
Re: Learning delegates
On Sunday, 8 September 2019 at 10:04:57 UTC, Joel wrote: I'm trying to understand delegates. Is there any good ways I can get a better understanding of them? You may want to read this: https://tour.dlang.org/tour/en/basics/delegates
Re: Should an 'extern(C++, "ns"):' override previous ones in the same scope?
On Sunday, 8 September 2019 at 09:35:03 UTC, Jonathan M Davis wrote: The C++ support has been improved kind of piecemeal over time, and initially, none of it was documented. So, it wasn't exactly fully planned out when it was added. IIRC, it was added originally so that the dmd frontend could be moved to D. The DIP process was very different at that point, and it was much more common then for Walter or one of the other core developers to just propose a feature in a PR and get it merged. I expect that the oddities in the implementation stem from stuff that whoever implemented it didn't think to try. The whole process is much more rigorous now than it used to be. - Jonathan M Davis Good to know, thank you.
Re: Should an 'extern(C++, "ns"):' override previous ones in the same scope?
On Saturday, 7 September 2019 at 22:19:48 UTC, Jonathan M Davis wrote: On Saturday, September 7, 2019 3:40:58 PM MDT Exil via Digitalmars-d-learn wrote: On Saturday, 7 September 2019 at 17:22:07 UTC, Jonathan M Davis wrote: > @safe: > @system: > > then @system overrides @safe. Just to add onto this, you can't do: @safe @system void foo(); // error but you can do: extern(C++, ns1) extern(C++, ns2) void foo(); // ok It makes no sense to apply multiple namespaces to the same symbol. I expect that this behavior is due to a lack of testing (the same with the out of order weirdness in the other post). It's the sort of thing that you test when you're trying to make sure that the feature does the right thing when people use it incorrectly, not the sort of thing when you're trying to make sure that the feature works as intended, so it's easy to forget. My guess is that this behavior leaked its way in due to the fact that you need to be able to put multiple extern(C++) declarations on a symbol when you use extern(C++, struct) or extern(C++, class) in addition to the extern(C++) for the namespace. - Jonathan M Davis I wonder how that undocumented and not well thought-through (or having some unobvious justifications) feature made it into a stable release. Anyway, thank you for your help. I will probably file a bug report when I have time.
Should an 'extern(C++, "ns"):' override previous ones in the same scope?
extern(C++, "ns1"): extern(C++, "ns2"): // Not in nested scope. Should it supersede? void foo(); pragma(msg, foo.mangleof); // _ZN3ns13ns23fooEv instead of expected _ZN3ns23fooEv Is that by design?
Mingling string and identifier namespaces in nested extern(C++) decls
extern(C++, "ns1") { extern(C++, ns2) { extern(C++, "ns3") { extern(C++, ns4) { void foo(); } } } } pragma(msg, foo.mangleof); // _ZN3ns23ns43ns13ns33fooEv That produces 'ns2::ns4::ns1::ns3::foo' path instead of the intuitively expected 'ns1::ns2::ns3::ns4::foo'. The identifier namespaces are grouped before the string ones. Bug or feature?
Re: Why are extern(C/C++) definitions and references mangled differently in separately compiled modules?
On Saturday, 7 September 2019 at 13:01:38 UTC, Jacob Carlborg wrote: On 2019-09-06 21:03, Max Samukha wrote: Is there any practical use of having identically named .d and .di alongside? Same as in C/C++. This allows you to have a header file if you want to distribute a closed source library. I know, but I have never seen a D project that would generate headers into the source directory. C++ requires headers for sharing declarations with other translation units in the project, even if the headers are not intended for distribution. That is why having headers alongside implementations is a common case there. D doesn't require that. Anyway, that's a minor concern. Thank you.
Re: Why are extern(C/C++) definitions and references mangled differently in separately compiled modules?
On Friday, 6 September 2019 at 17:54:51 UTC, Adam D. Ruppe wrote: On Friday, 6 September 2019 at 17:42:08 UTC, Max Samukha wrote: That file was silently imported by the compiler (probably, a bug). That's by design - the automatic module import lookups actually always look for .di file first, then .d files. Is there any practical use of having identically named .d and .di alongside?
Re: Why are extern(C/C++) definitions and references mangled differently in separately compiled modules?
On Friday, 6 September 2019 at 16:55:31 UTC, Max Samukha wrote: On Friday, 6 September 2019 at 15:52:46 UTC, Stefan Koch wrote: If that is happening you hit a bug. It seems unlikely though. Could you elaborate a bit? How should extern(C/C++) definitions be mangled - fully qualified or not, and why is the reference to extern(C/C++) D-mangled? The spec seems to say nothing about it. Ok, I have figured it out. There was 'a.di' file along with 'a.d' in the same directory, with a definition of extern(D) foo. That file was silently imported by the compiler (probably, a bug). Thank you for your attention.
Re: Why are extern(C/C++) definitions and references mangled differently in separately compiled modules?
On Friday, 6 September 2019 at 15:52:46 UTC, Stefan Koch wrote: On Friday, 6 September 2019 at 15:09:22 UTC, Max Samukha wrote: Consider the following two modules: 1. test.d: module test; import lib.a; void main() { foo(); } 2. lib/a.d: module lib.a; extern(C) void foo() {} When compiled separately (dmd -c lib/a.d; dmd test.d a.o), the function in 'a.o' is mangled as 'foo', but the reference in 'test.o' is mangled as '_D3lib1a3fooFZv', which leads to a link error. I would expect both of them to be either plain C mangling, or fully qualified D (better). What is the reason for current behavior? If that is happening you hit a bug. It seems unlikely though. Could you elaborate a bit? How should extern(C/C++) definitions be mangled - fully qualified or not, and why is the reference to extern(C/C++) D-mangled? The spec seems to say nothing about it.
Re: Why are extern(C/C++) definitions and references mangled differently in separately compiled modules?
On Friday, 6 September 2019 at 15:32:07 UTC, 0xEAB wrote: On Friday, 6 September 2019 at 15:09:22 UTC, Max Samukha wrote: Consider the following two modules: What compiler version are you using? DMD64 D Compiler v2.088.0-1-g4011382ea, linux
Why are extern(C/C++) definitions and references mangled differently in separately compiled modules?
Consider the following two modules: 1. test.d: module test; import lib.a; void main() { foo(); } 2. lib/a.d: module lib.a; extern(C) void foo() {} When compiled separately (dmd -c lib/a.d; dmd test.d a.o), the function in 'a.o' is mangled as 'foo', but the reference in 'test.o' is mangled as '_D3lib1a3fooFZv', which leads to a link error. I would expect both of them to be either plain C mangling, or fully qualified D (better). What is the reason for current behavior?
Why are constructor definitions are preserved in interface files?
module lib.a; class C { this() { } void foo() { } ~this() { } } dmd -H -o- a.d: // D import file generated from 'a.d' module lib.a; class C { this() { } void foo(); ~this(); } The destructor and member function definitions have been removed as expected. What is the reason for keeping the constructor definition?
Why are constructor definitions preserved in interface files?
module lib.a; class C { this() { } void foo() { } ~this() { } } dmd -H -o- a.d: // D import file generated from 'a.d' module lib.a; class C { this() { } void foo(); ~this(); } The destructor and member function definitions have been removed as expected. What is the reason for keeping the constructor definition?
How to get the type of a derived class in a method of its base class?
class A { this(T = this)() { static assert(is(T == B)); } } class B { } auto b = new B; Here, T becomes A, which may be reasonable but is completely useless. Is there a way to obtain the type of the class (or class instance reference) the method is called on?
Re: Why aren't overloaded nested functions allowed?
On Tuesday, 31 May 2016 at 11:54:40 UTC, Timon Gehr wrote: On 30.05.2016 18:22, Max Samukha wrote: From the spec (https://dlang.org/spec/function.html#nested): "Nested functions cannot be overloaded." Anybody knows what's the rationale? The rationale is that nobody has implemented it in DMD. https://issues.dlang.org/show_bug.cgi?id=12578 Ah, that "seems pointless" argument again.
Re: Why aren't overloaded nested functions allowed?
On Monday, 30 May 2016 at 23:17:15 UTC, pineapple wrote: On Monday, 30 May 2016 at 16:22:26 UTC, Max Samukha wrote: From the spec (https://dlang.org/spec/function.html#nested): "Nested functions cannot be overloaded." Anybody knows what's the rationale? I'm guessing it's related to - Unlike module level declarations, declarations within function scope are processed in order. And I'd suspect that the cleanest solution would be similar to the one given for interdependent functions: Declare the nested functions in a static nested struct instead. Ok, thanks.
Why aren't overloaded nested functions allowed?
From the spec (https://dlang.org/spec/function.html#nested): "Nested functions cannot be overloaded." Anybody knows what's the rationale?
Re: D, GTK, Qt, wx,…
On Sunday, 29 May 2016 at 11:03:36 UTC, Russel Winder wrote: From what I can tell QtD is in need of effort or restarting. I will probably give it another shot when D has better interop with C++. Particularly, when multiple inheritance of C++ interfaces is implemented, Walter admits that mingling C++ namespaces into D name hierarchy is a horrible idea, and so on.
Weird "nested function cannot be accessed" error
This code fails to compile: void bar(alias f)() { f(); } void foo(alias f)() { bar!f(); } void main() { void f()() { } foo!f(); } Error: function test.main.f!().f is a nested function and cannot be accessed from test.bar!(f).bar But non-template nested functions are accepted: void main() { void f() { } foo!f(); // ok } What's going on here?
Re: C header file: tagged enumerations
On Tuesday, 26 April 2016 at 22:57:36 UTC, Jesse Phillips wrote: typedef enum tagINSTALLMESSAGE { // 12 others ... INSTALLMESSAGE_INITIALIZE , INSTALLMESSAGE_TERMINATE , INSTALLMESSAGE_SHOWDIALOG , #if (_WIN32_MSI >= 500) INSTALLMESSAGE_PERFORMANCE, #endif // (_WIN32_MSI >= 500) #if (_WIN32_MSI >= 400) INSTALLMESSAGE_RMFILESINUSE , #endif // (_WIN32_MSI >= 400) #if (_WIN32_MSI >= 450) INSTALLMESSAGE_INSTALLSTART , INSTALLMESSAGE_INSTALLEND , #endif // (_WIN32_MSI >= 450) } INSTALLMESSAGE; enum _WIN32_MSI = 450; mixin((int _WIN32_MSI = _WIN32_MSI) { string r ="enum INSTALLMESSAGE { INSTALLMESSAGE_INITIALIZE, INSTALLMESSAGE_TERMINATE, INSTALLMESSAGE_SHOWDIALOG,"; if (_WIN32_MSI >= 500) r ~= "INSTALLMESSAGE_PERFORMANCE,"; if (_WIN32_MSI >= 400) r ~= "INSTALLMESSAGE_RMFILESINUSE ,"; if (_WIN32_MSI >= 450) { r ~= "INSTALLMESSAGE_INSTALLSTART , INSTALLMESSAGE_INSTALLEND ,"; } return r ~ "}"; }()); ))) // sardonic laugh, which is not part of the source
Re: Patterns for functions in template parameters
On Friday, 24 October 2014 at 08:53:05 UTC, Kagamin wrote: maybe template Foo(T a, T: T[U], U) No luck. Error: undefined identifier T
Re: Patterns for functions in template parameters
On Friday, 24 October 2014 at 14:13:10 UTC, ketmar via Digitalmars-d-learn wrote: sorry if this is not what you mean, template magic sometimes scares me and i'm loosing my mind. ;-) What I meant was your example with the delegate parameter moved to the template list: template Foo(T delegate(U) a, T, U) {} Foo!((int x) = true); // T == bool, U == int Or generalized to functions (and maybe functors in the unfortunate C++ sense): template Foo(T(U) a, T, U) {} Apparently, D doesn't allow type variables in value parameters at all.
Re: Patterns for functions in template parameters
On Friday, 24 October 2014 at 17:08:00 UTC, Max Samukha wrote: Apparently, D doesn't allow type variables in value parameters at all. Nor does it allow passing delegates to value parameters, only alias parameters.
Patterns for functions in template parameters
If I remember correctly, at some point a syntax was introduced for pattern-matching functions passed to templates. Something like: template Foo(B(A) foo, A, B) { } alias f = Foo!((int x) = x % 2 == 0); That would instantiate Foo with B == bool, A == int and foo bound to the lambda. The compiler has rejected all syntax variations I have tried and the specs is not helpful. Does anybody know if the feature exists and what is the syntax exactly?
Re: Patterns for functions in template parameters
On Thursday, 23 October 2014 at 11:25:01 UTC, Kagamin wrote: Maybe, argument deduction? template Foo(T: T[U], U) { ... } Foo!(int[long]) // instantiates Foo with T set to int, U set to long Yes, but for a value template parameter. template Foo(int[long] a); { } Foo!([1: 2]); // ok, this passes. Now I'd like to loosen the template so it accepts AAs of any type: template Foo(T[U] a /* forall T, U */) { } And then unary functions of any type: template Foo(T a(U) /* forall T, U */) { } In other words, to move the run-time parameter below to the template parameter list: void foo(T, U)(T delegate(U) a) { } Or in other other words (for any callables): template Foo(alias a) if (isCallable!a ParameterTypes!a.length == 1) { alias T = ReturnType!a; alias U = ParameterTypes!a[0]; } I vaguely remember some syntax tweaks were introduced, presumably for that effect. Trying to find out what they were exactly. I might have dreamt it as well.