Re: variable _param_0 cannot be read at compile time
On Wednesday, 8 August 2018 at 13:13:42 UTC, Simen Kjærås wrote: On Wednesday, 8 August 2018 at 12:57:43 UTC, learnfirst1 wrote: Why this is a error ? ``` struct S { bool v; string x; } S* add(A...)(ref A a) { __gshared s = S(a); return } void main(){ auto p = add(true); } ``` test.d(9): Error: variable _param_0 cannot be read at compile time __gshared and static need to be initialized with a value known at compile-time. You're trying to give it a run-time value. You can set this after it's first created: S* add(A...)(ref A a) { __gshared S s; s = S(a); return } That's a little kludgy, but apparently that's how it be. You also get another error message: Error: function test.add!bool.add(ref bool _param_0) is not callable using argument types (bool) That's because add takes its arguments by ref, and true is a literal that has no canonical address, and thus can't be passed by ref. You might consider using auto ref. -- Simen is there a way to pass A a... as alias into template ? so the code can be just like this: __gshared S s = S(, false); the binary size is short since in this case the s is static build int. and run a bit fast.
Re: How do you put log calls in constructors when they may be created in a static context?
On Wednesday, August 8, 2018 3:54:34 PM MDT aliak via Digitalmars-d-learn wrote: > I'm trying to debug stuff, so I want to add verbose logging > > struct S(T) { >this() { > writeln("created S(T) with properties and ID"); >} > } > > static a = S!int(); // bah > > I guess users can call this code from any context, but when i'd > also like to see the log output for debugging purposes. Is there > a way around this? > > Can I maybe only do a writeln in a non compile-time context? if(__ctfe) { // code here will execute if this is encountered during CTFE } else { // code here will execute if this is encountered outside of CTFE } - Jonathan M Davis
How do you put log calls in constructors when they may be created in a static context?
I'm trying to debug stuff, so I want to add verbose logging struct S(T) { this() { writeln("created S(T) with properties and ID"); } } static a = S!int(); // bah I guess users can call this code from any context, but when i'd also like to see the log output for debugging purposes. Is there a way around this? Can I maybe only do a writeln in a non compile-time context? Cheers, - ali
Re: float/double to string (pure nothrow @nogc)
On Wednesday, 8 August 2018 at 17:08:57 UTC, vit wrote: Hello, is in phobos some function which convert float/double to string and is pure @nogc and nothrow? Short answer: no. Long answer: https://issues.dlang.org/show_bug.cgi?id=17628
Re: float/double to string (pure nothrow @nogc)
vit wrote: thanks, that code can be modified to pure nothrow @nogc @safe. Is that lib ok? Is little complicated... converting float to string is a *very* complicated task. that lib is quite small for what it is doing ('cause it hacks around some... interesting cases). the *real* thing will be a LOT bigger.
Re: float/double to string (pure nothrow @nogc)
On Wednesday, 8 August 2018 at 17:40:11 UTC, ketmar wrote: vit wrote: Hello, is in phobos some function which convert float/double to string and is pure @nogc and nothrow? i don't think that you can make it `pure`, but you certainly can make it `nothrow`, `@nogc` and ctfe-able. it's dangerous to go alone! take this[0]. [0] http://repo.or.cz/iv.d.git/blob_plain/HEAD:/ctfefloat.d thanks, that code can be modified to pure nothrow @nogc @safe. Is that lib ok? Is little complicated...
Cannot dispose const array?
Hi Dlang community! I've stumbled on an interesting issue with allocators. It seems that we can't get disposed of arrays with const or immutable data. Consider example below: Link: https://run.dlang.io/is/frnQI8 import std.stdio; import std.range; import std.algorithm; import std.experimental.allocator; import std.experimental.allocator.mallocator; void main(string[] args) { const(int)[] values = Mallocator.instance.makeArray!(const int)([1, 2, 3, 4]); writeln(values); Mallocator.instance.dispose(values); } We'd get following error: /dlang/dmd/linux/bin64/../../src/phobos/std/experimental/allocator/package.d(2398): Error: function std.experimental.allocator.mallocator.Mallocator.deallocate(void[] b) shared is not callable using argument types (const(int)[]) shared /dlang/dmd/linux/bin64/../../src/phobos/std/experimental/allocator/package.d(2398): cannot pass argument array of type const(int)[] to parameter void[] b onlineapp.d(11): Error: template instance `std.experimental.allocator.dispose!(shared(Mallocator), const(int))` error instantiating Is it expected to not be able to dispose out of immutable or const data, or it is a bug that should be fixed? Regards, Alexandru.
Re: float/double to string (pure nothrow @nogc)
vit wrote: Hello, is in phobos some function which convert float/double to string and is pure @nogc and nothrow? i don't think that you can make it `pure`, but you certainly can make it `nothrow`, `@nogc` and ctfe-able. it's dangerous to go alone! take this[0]. [0] http://repo.or.cz/iv.d.git/blob_plain/HEAD:/ctfefloat.d
Re: float/double to string (pure nothrow @nogc)
On 8/8/18 1:08 PM, vit wrote: Hello, is in phobos some function which convert float/double to string and is pure @nogc and nothrow? Not one that I can see. formattedWrite doesn't seem to be pure. -Steve
float/double to string (pure nothrow @nogc)
Hello, is in phobos some function which convert float/double to string and is pure @nogc and nothrow?
Re: Why does templated interface function return something different than final function?
On Monday, 6 August 2018 at 14:27:01 UTC, Timoses wrote: On Thursday, 2 August 2018 at 20:35:57 UTC, Steven Schveighoffer wrote: Looking at the AST, it appears that toImpl doesn't recognize what inout(iface) is: toImpl!(string, inout(iface)) { @system string toImpl(ref inout(iface) value) { import std.array : appender; import std.format : FormatSpec, formatValue; Appender!string w = appender(); FormatSpec!char f = FormatSpec; formatValue(w, value, f); return w.data(); } } Vs. the nice neat call for const(iface) toImpl!(string, const(iface)) { @system string toImpl(const(iface) value) { return toStr(value); } } Note the ref there, too. This means it can't cast to const. I wonder if that's an issue. -Steve Thanks for the insight. To me it sounds like std.conv `toImpl` doesn't properly handle inout types in this case. Well, my "workaround" now is to simply cast the inout type to const before passing to std.conv.to ... I've experimented a bit more and compiled it a bit together. import std.stdio; import std.conv : to; interface I { void toString(scope void delegate(const(char)[]) sink) const; final void printI() { writeln(this.to!string); // this is class A } final void printIinout() inout { writeln(this.to!string); // app.A } } class A : I { void print() { writeln(this.to!string); // this is class A } // Compilation error // std\format.d(3890,13): Error: template instance `std.format.formatObject!(Appender!string, inout(A), char)` does not match template declaration `formatObject(Writer, T, Char)(ref Writer w, ref T val, ref const FormatSpec!Char f) if (hasToString!(T, Char))` /*void printinout() inout { writeln(this.to!string); }*/ override void toString(scope void delegate(const(char)[]) sink) const { sink("this is class A"); } } unittest { I i = new A(); i.printI(); i.printIinout(); A a = new A(); a.print(); //a.printinout(); } It seems inconsistent to me. What do you think? Should I open a bug report for this? Also the compilation error should not occur, should it?
Re: countUntil's constraints
On 8/7/18 10:28 PM, Nicholas Wilson wrote: On Wednesday, 8 August 2018 at 01:33:26 UTC, Steven Schveighoffer wrote: On 8/7/18 9:20 PM, Nicholas Wilson wrote: the first overload is ptrdiff_t countUntil(alias pred = "a == b", R, Rs...)(R haystack, Rs needles) if (isForwardRange!R && Rs.length > 0 && isForwardRange!(Rs[0]) == isInputRange!(Rs[0]) && is(typeof(startsWith!pred(haystack, needles[0]))) && (Rs.length == 1 || is(typeof(countUntil!pred(haystack, needles[1 .. $]) What does `isForwardRange!(Rs[0]) == isInputRange!(Rs[0]` mean here? Is it just the same as `isForwardRange!(Rs[0])`? Why is it written like that? No, not exactly the same. Superficially, this rejects elements that are input ranges but NOT forward ranges. Other than that, I can't tell you the reason why it's that way. -Steve Ahhh, Rs[0] is not necessarily a range, consider: `assert(countUntil("hello world", 'r') == 8);` so that means `isForwardRange!(Rs[0]) == isInputRange!(Rs[0]` if Rs[0] is a range it must be a forward range. The second overload looks as though it will never be a viable candidate ptrdiff_t countUntil(alias pred = "a == b", R, N)(R haystack, N needle) if (isInputRange!R && is(typeof(binaryFun!pred(haystack.front, needle)) : bool)) { bool pred2(ElementType!R a) { return binaryFun!pred(a, needle); } return countUntil!pred2(haystack); // <--- } because the marked line can't recurse be cause there is only one arg, so it tries to call the first overload, which fails due to Rs.length > 0. Ah, but there is a third overload which just takes a haystack and a predicate. What is a bit more confusing to me is why there isn't an ambiguity error when the needle parameter is one element that is not a range. -Steve
Re: if(int a = 0) lowered to "if (int a = (int a = 1;) , a)" ?
On Wednesday, 8 August 2018 at 13:13:24 UTC, aliak wrote: Go here https://run.dlang.io/is/tJ4vXm and click on the AST button :) It shows you what the code turns in to after all the semantic passes. Yeah... no... I'm aware of this cool thing )) I thought you have a hidden source of knowledge, where all available transformations back and fore are specified, somehow... ))
Re: if(int a = 0) lowered to "if (int a = (int a = 1;) , a)" ?
On Wednesday, 8 August 2018 at 12:58:24 UTC, Alex wrote: On Wednesday, 8 August 2018 at 11:58:50 UTC, aliak wrote: Found this out while just looking at lowerings. How do you "look at lowerings"? Is there a list, I'm not aware of? ;) Go here https://run.dlang.io/is/tJ4vXm and click on the AST button :) It shows you what the code turns in to after all the semantic passes.
Re: variable _param_0 cannot be read at compile time
On Wednesday, 8 August 2018 at 12:57:43 UTC, learnfirst1 wrote: Why this is a error ? ``` struct S { bool v; string x; } S* add(A...)(ref A a) { __gshared s = S(a); return } void main(){ auto p = add(true); } ``` test.d(9): Error: variable _param_0 cannot be read at compile time __gshared and static need to be initialized with a value known at compile-time. You're trying to give it a run-time value. You can set this after it's first created: S* add(A...)(ref A a) { __gshared S s; s = S(a); return } That's a little kludgy, but apparently that's how it be. You also get another error message: Error: function test.add!bool.add(ref bool _param_0) is not callable using argument types (bool) That's because add takes its arguments by ref, and true is a literal that has no canonical address, and thus can't be passed by ref. You might consider using auto ref. -- Simen
Re: variable _param_0 cannot be read at compile time
On Wednesday, 8 August 2018 at 12:57:43 UTC, learnfirst1 wrote: Why this is a error ? this code example can explain what I am try to do here: struct M { int i; S*[100] s; } struct S { M* mp; bool x; } S* add(A...)(ref A a) { __gshared s = S(a); alias m = a[0]; m.s[m.i++] = return } void main(){ __gshared M m = M(0); __gshared S s = S(, false); m.s[m.i++] = auto p = add(, true); // variable _param_0 cannot be read at compile time } because S has the optional ctor parameters, I can not use template alias param here( some how not work) .
variable _param_0 cannot be read at compile time
Why this is a error ? ``` struct S { bool v; string x; } S* add(A...)(ref A a) { __gshared s = S(a); return } void main(){ auto p = add(true); } ``` test.d(9): Error: variable _param_0 cannot be read at compile time test.d(14): Error: template instance `test.add!bool` error instantiating test.d(14): Error: function test.add!bool.add(ref bool _param_0) is not callable using argument types (bool) test.d(14):cannot pass rvalue argument true of type bool to parameter ref bool _param_0 I try pass some into the template to return a __gshared var pointer. the A length is dynamic.
Re: if(int a = 0) lowered to "if (int a = (int a = 1;) , a)" ?
On Wednesday, 8 August 2018 at 11:58:50 UTC, aliak wrote: Found this out while just looking at lowerings. How do you "look at lowerings"? Is there a list, I'm not aware of? ;)
Re: if(int a = 0) lowered to "if (int a = (int a = 1;) , a)" ?
On Wednesday, August 8, 2018 5:58:50 AM MDT aliak via Digitalmars-d-learn wrote: > Found this out while just looking at lowerings. Wondering if > anyone knows the semantics involved here and where they are > documented? It's particularly useful when dealing with stuff like C functions that return 0 on success or getting values from AAs. e.g. if(auto value = key in aa) { } > And, is there anyway to do it with multiple variables? > > I.e. > > if (int a = 0, int b = 0) { > // ... > } I don't believe so. - Jonathan M Davis
if(int a = 0) lowered to "if (int a = (int a = 1;) , a)" ?
Found this out while just looking at lowerings. Wondering if anyone knows the semantics involved here and where they are documented? And, is there anyway to do it with multiple variables? I.e. if (int a = 0, int b = 0) { // ... } Cheers, - Ali
Re: Implicit conversion by return
On Wednesday, August 8, 2018 2:15:16 AM MDT Hakan Aras via Digitalmars-d- learn wrote: > Given this: > > struct Num > { > this(int a) {} > } > > Is there any reason why this works: > > Num n = 5; > > but this doesnt: > > Num funk() > { > return 5; > } > > > I understand that I can construct it explicitely, but that gets > annoying quickly, especially with templates. Num n = 5; doesn't actually do an implict conversion. It's the same as doing Num n = Num(5); So, I guess that you could call it implicit construction, but regardless, it's just a different syntax for calling the constructor. The only way to create an implicit conversion with a user-defined type in D is to use alias this, and that only provides a way to implicitly convert _from_ a user-defined type, not to a type. So, having Num funk() { return 5; } work is impossible in D, just like having something like auto foo(Num n) { ... } foo(5); work is impossible. If you want to return an int and have it converted to a Num, then you're going to need to explicitly construct a Num from the int. - Jonathan M Davis
Re: Implicit conversion by return
On Wednesday, 8 August 2018 at 08:44:03 UTC, Alex wrote: return typeof(return)(5); Ah thanks, I was wondering if something like that exists. Still though, that's 16 extra characters that dont need to be there.
Re: Implicit conversion by return
On Wednesday, 8 August 2018 at 08:15:16 UTC, Hakan Aras wrote: Given this: struct Num { this(int a) {} } Is there any reason why this works: Num n = 5; but this doesnt: Num funk() { return 5; } I understand that I can construct it explicitely, but that gets annoying quickly, especially with templates. I suppose, this is too slack. What would work is Num funk() { return typeof(return)(5); }
Implicit conversion by return
Given this: struct Num { this(int a) {} } Is there any reason why this works: Num n = 5; but this doesnt: Num funk() { return 5; } I understand that I can construct it explicitely, but that gets annoying quickly, especially with templates.