Re: Mixin operator 'if' directly
On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh wrote: On Wed, 19 Dec 2018 15:12:14 +, bauss wrote: Or while instantiating it: mixin template foo() { int _ignoreme() { if (readln.strip == "abort") throw new AbortException; return 1; } int _alsoIgnoreMe = _ignoreme(); } void main() { mixin foo; } Awesome hack! Being a hack, it would be even nicer if it worked ouf of the box: mixin template foo(bool b) { int _impl() { writeln(b); return int.init; } int _ipml2 = _impl(); } vs mixin template foo(bool b) { writeln(b); }
Re: Shared static this() not executed for unittest
A look into `dub test --vverbose` showed that ./source/app.d is not even included in the compilcation step...
Shared static this() not executed for unittest
Spec 27.5 states: "Unit tests, when enabled, are run after all static initialization is complete and before the main() function is called. " (https://dlang.org/spec/unittest.html) main.d: --- import std.stdio; shared static this() { import vibe.core.log; setLogLevel(LogLevel.trace); logDebug("log: statc this"); WRITELN("WRiteln: static this"); } void main() { writeln("Edit source/app.d to start your project."); } test.d: --- import std.stdio; unittest { import vibe.core.log; logDebug("log: unittest"); writeln("writeln: unittest"); } Running `dub test` will output: Running ./unit-test-library writeln: unittest All unit tests have been run successfully. Why is the `shared static this()` not executed?
Re: Is it's correct to say that ALL types that can grow are place on heap?
On Wednesday, 12 September 2018 at 14:46:22 UTC, rikki cattermole wrote: On 13/09/2018 2:34 AM, drug wrote: 12.09.2018 15:14, Timoses пишет: On Tuesday, 11 September 2018 at 12:07:14 UTC, drug wrote: If data size is less or equal to total size of available registers (that can be used to pass values) than passing by value is more efficient. Passing data with size less than register size by reference isn't efficient because you pass pointer (that has register size) and access memory using it. Thank you! So if I pass by reference it will ALWAYS use the address in memory to fetch the data, whereas passing it by value enables the (compiler?..) to use the register which has already loaded the data from memory (stack for example)? Honestly, I'm not an expert in this domain, but I think so. Recently used areas of the stack will be available in the cache in most cases. The issue with passing by reference is it increases the indirection (number of pointers) that it must go through to get to the raw bytes. This is why classes are bad but structs are good. Even if the struct is allocated on the heap and you're accessing it via a pointer. This sounds like classes should never be used.. I don't recall right now what issues I'm usually encountering with structs that make me switch to classes (in D). So passing by reference is generally only applicable (logical) to structs and non-reference types + only makes sense when the function being called is supposed to change the referenced value without returning it. Except, as Steven pointed out in his post when dealing with large lvalue structs. This all seems quite complicated to "get right" when writing code. I'm sure there are compiler optimizations run on this? Or is that not possible due to the nature of difference in ref and value passing. Anyhow, thanks for the answers! I bet it's possible to write books on this topic.. Or just mention ones that already were written : ~D.
Re: DMD32 compiling gtkd out of memory on 32bit Windows 7 machine
On Wednesday, 12 September 2018 at 06:06:15 UTC, dangbinghoo wrote: hi , When compiling gtkd using dub, dmd32 reported "Out for memory" and exit. OS: Windows 7 32bit. RAM : 3GB DMD version: v2.0.82.0 32bit. No VC or Windows SDK installed, when setting up dmd, I selected install vc2010 and use mingw lib. try `dub --build-mode=singleFile` ? I believe this will compile each file and then link them together (instead of compiling it all together what dub does, afaik). There's been another topic on memory consumption of compilation [1]. [1]: https://forum.dlang.org/post/ehyfilopozdndjdah...@forum.dlang.org
Re: Is it's correct to say that ALL types that can grow are place on heap?
On Tuesday, 11 September 2018 at 12:07:14 UTC, drug wrote: If data size is less or equal to total size of available registers (that can be used to pass values) than passing by value is more efficient. Passing data with size less than register size by reference isn't efficient because you pass pointer (that has register size) and access memory using it. Thank you! So if I pass by reference it will ALWAYS use the address in memory to fetch the data, whereas passing it by value enables the (compiler?..) to use the register which has already loaded the data from memory (stack for example)?
Re: "immutable string" vs "const string*"
On Sunday, 9 September 2018 at 08:41:37 UTC, Christian Mayer wrote: On Sunday, 9 September 2018 at 08:14:41 UTC, rikki cattermole wrote: Are you aware that a string is just an alias of immutable(char)[]? Yes, I'm aware of that. But it's the same, for example, with just one char. "immutable char" vs "const char*". Or int, or any other data type. As of my current understanding "char" will create a new variable and copy the content of the original to the new variable. "char*" will just use the pointer. And "const char*" is good for when not modifying. But I also can achieve the same using "immutable char". But I'm not sure when better using "immutable char". In C I would rather use a const pointer. But since I just started learing D I'm not so sure because there are so many ways. Since strings are slices (immutable(char)[]) it could also be worth reading into slices [1]. Assigning an existing slice to another slice will not copy the content but only the slice struct (length and pointer to data). [1] https://dlang.org/articles/d-array-article.html
Re: Is it's correct to say that ALL types that can grow are place on heap?
On Saturday, 8 September 2018 at 22:51:17 UTC, Ali Çehreli wrote: On 09/08/2018 02:19 AM, Suliman wrote: > Is it's correct to say that ALL types that can grow are place on heap > and types that not growing (int, char, pointer) are place on stack? The question is not that simple. :) First, there is also the area used for objects that are static and object that are defined at module scope. That is different from both the call stack and the heap. Let's ignore them... There are automatic objects like local variables inside a function and function parameters. They normally live on the stack. (However, the compiler may pass some parameters in CPU registers without allocating any memory at all.) Is this why it is said that passing parameters by value can be more efficient? Cause for a ref parameter it would require passing the address which would require to be allocated? Aww, I really would love some insights into function parameter passing. Why is it said that passing by value can be more efficient at times? Since it is also said that passing large structs by value can be expensive, why then would it not be cheaper to ALWAYS pass everything by reference? What mechanism is behind the scene that follows one to reason that sometimes passing by value is less expensive? I get that passing an int by reference would cause indirections which need to be resolved whereas passing the int by value is just one copy (I guess). This topic kinda seemed fit for my question that I was carrying around for some time.
Re: traits getOverload of a template method
On Thursday, 6 February 2014 at 23:06:03 UTC, QAston wrote: How do i get aliases to overloads of a template method like Class A { int a(T)(T tq,T tw); int a(T)(T tq); } __traits(getOverloads, A, "a(int)")doesnt work Is there any way to "select" overloaded template functions? I require to select one of `std.bitmanip.peek` import std.bitmanip : peek; import std.system : Endian; alias myPeek = peek!(int, Endian.bigEndian, immutable(ubyte)[]); Error: template std.bitmanip.peek matches more than one template declaration: /dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(3269): peek(T, Endian endianness = Endian.bigEndian, R)(R range) if (canSwapEndianness!T && isForwardRange!R && is(ElementType!R : const(ubyte))) and /dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(3306): peek(T, Endian endianness = Endian.bigEndian, R)(R range, size_t* index) if (canSwapEndianness!T && isForwardRange!R && hasSlicing!R && is(ElementType!R : const(ubyte))) How to "select" one?
Re: Mutable ForwardRange save() method not callable using const object
On Tuesday, 4 September 2018 at 14:26:44 UTC, Steven Schveighoffer wrote: [...] As general advice, I wouldn't expect const to work well with Ranges anyway -- const ranges are useless (you can't iterate them). So not much code is expecting to handle const, including the wrappers that Phobos provides. Thanks, that sounds like some good advice. I've actually bumped into this right after when I had an immutable range which was supposed to fill in its cache when being iterated. My argument for why this should work is that "from the outside of the range" it is immutable, since accessing via opIndex will always give the same value. ... In the end, that'll lead nowhere. The immutable attribute would become a "promise" rather than an enforcement (or too hard for the compiler to enforce). Thanks for the clarification, Steve!
Mutable ForwardRange save() method not callable using const object
Hey, I'm fiddling around with ranges a bit and am wondering why save is not callable on a const object: class Range { ForwardRange!(const uint) offsets; this(const S s) { this.offsets = s.s.map!(e => e.i).inputRangeObject; } this(const Range a) // ERROR line 22 { this.offsets = a.offsets.save; } Range save() { return new Range(this); } } struct I { uint i; } struct S { I[] s = [I(1), I(2), I(3)]; } unittest { S s; auto a = new Range(s); } onlineapp.d(22): Error: mutable method std.range.interfaces.ForwardRange!(const(uint)).ForwardRange.save is not callable using a const object onlineapp.d(22):Consider adding const or inout to std.range.interfaces.ForwardRange!(const(uint)).ForwardRange.save In this case the Forwardrange Offsets is a ForwardRange of MapResult(I => uint) of I[] Since the type of MapResult.front is uint, the ForwardRange is essentially a uint[] array. I could imagine that save is not marked as const because it is uncertain whether any indirections are part of the content..? But couldn't the compiler check that? Could anybody explain what exactly is going on? Is there a reason the `save()` is not working on const objects? Given that I haven't done much with ranges yet, any feedback on the above implementation is also greatly appreciated (it's just a reduced example).
Re: Struct immutable data and dict
On Tuesday, 4 September 2018 at 12:27:47 UTC, nkm1 wrote: I also had this problem recently. I think aa.require() should allow to add immutables (feature request). Anyway, my workaround was along the lines of: final class AA(Key, Value) { Value[] _storage; size_t[Key] _aa; void opIndexAssign(Value value, Key key) { if (key !in _aa) { _storage ~= value; _aa[key] = _storage.length - 1; } } Value opIndex(Key key) { if (auto index = key in _aa) return _storage[*index]; throw new Exception("no key"); } } immutable struct S { int num; } void main() { import std.stdio : writeln; auto aa = new AA!(string, S); aa["one"] = S(1); aa["two"] = S(2); writeln(aa["one"]); writeln(aa["two"]); } Thanks for the replies. It seems quite annoying. I just use classes for now.
Re: Struct immutable data and dict
On Thursday, 6 October 2016 at 02:09:44 UTC, Adam D. Ruppe wrote: On Thursday, 6 October 2016 at 01:23:35 UTC, Patric Dexheimer wrote: Why? Because you'd be overwriting that immutable member. Structs just put structure around their contents, but it doesn't change their nature. That struct is no different than if you wrote `immutable size_t` as the value - and of course, overwriting that; changing that violates that promise that you won't change it. You could store pointers to those structs though, and overwrite the pointer. Hm... so is there any way around this? In my case I have a RandomAccessRange which caches it's results. Reduced example: struct Res { immutable int i; } struct Range { Res[size_t] c; Res fun(size_t i) { if (auto p = i in c) return *p; else { c[3] = Res(3); /// ERROR line 26 return c[3]; } } } unittest { auto r = Range(); r.fun(3); } which errors at compilation with onlineapp.d(26): Error: cannot modify struct this.c[3] Res with immutable members A workaround I thought could be to use an array struct Range { //Res[size_t] c; struct Con { Res c; bool valid; } Con[] c; Res fun(size_t i) { if (c.length > i && c[i].valid) return c[i].c; else { if (c.length <= i) c.length = i + 1; auto r = Con(Res(3), true); c[i] = r; /// same ERROR! return c[i].c; } } } However, of course this also fails because randomly assigning the array elements will overwrite it. So the associative array seems like the better idea. However, not being able to INITIALIZE an assoc array element disallows its usage. Is there any solution, trick or workaround??
Re: Concat enum of strings into one string
On Tuesday, 14 August 2018 at 14:37:33 UTC, Andrey wrote: Thank you. Hmm, I thought that standard library already has this stuff. There might be more elegant solutions and I'd be happy to see some more. I'm always just digging into std.traits [1] and Traits spec part [2] and try to fumble things together somehow until I get what I want. It's good practice (as in training/accustomization, not as in method...), but perhaps also a sign that there's an area for improvement. [1] https://dlang.org/phobos/std_traits.html [2] https://dlang.org/spec/traits.html
Re: Concat enum of strings into one string
On Tuesday, 14 August 2018 at 13:42:04 UTC, Andrey wrote: Hello, I have a enum: enum Type : string { One = "Q1", Two = "W2", Three = "R3" } I want to concat it in compile-time: enum result = doConcat!Type(); And get this result: writeln(result); // output: "Q1 W2 R3" Delimiter here is space symbol. How do do it? Here's one version: template StringEnumValues(alias Enum) { import std.traits : EnumMembers; string[] StringEnumValues() { string[] enumValues; static foreach (member; EnumMembers!Enum) enumValues ~= member; return enumValues; } } import std.string : join; pragma(msg, StringEnumValues!Type.join(" "));
Re: How to declare static compile-time assoc array inside struct?
On Monday, 13 August 2018 at 13:21:45 UTC, Andrey wrote: On Monday, 13 August 2018 at 11:53:06 UTC, rikki cattermole wrote: You must use a module constructor to initialize it. Tried this: static this() { Test.DESCRIPTION = [Test.Type.One: "One!", Test.Type.Two: "It's Two...", Test.Type.Three: "And... Three!"]; } struct Test { // ... } I have an error: cannot modify immutable expression DESCRIPTION I suppose something along these lines was meant: immutable string[Test.Type] DESCRIPTION; shared static this() { DESCRIPTION = [Test.Type.One: "One!", Test.Type.Two: "It's Two...", Test.Type.Three: "And... Three!"]; } struct Test { enum Type { One, Two, Three }; } See also: https://forum.dlang.org/post/p941qc$43q$1...@digitalmars.com
Re: Importing struct
On Monday, 13 August 2018 at 14:16:47 UTC, Mike Parker wrote: On Monday, 13 August 2018 at 13:09:24 UTC, Andrey wrote: On Monday, 13 August 2018 at 13:05:28 UTC, evilrat wrote: however the best option is simply avoid naming anything with same name as module. Hmm, I thought that name of class should match name of file... And how to name a file that contains only one class/struct? Like in my case. What usually true D coders do?) The convention is to use lowercase for the module name: module myclass; struct MyClass {} Using lowercase letters for module names (and their respective file names!!) also prevents weird errors when different OSes treat lower/capital case letters differently which can sometimes lead to modules not being found. So from my experience: always use lower-case letters for modules and the file names.
Re: vibe.d: Finding out if currently in webinterface request
On Thursday, 9 August 2018 at 21:59:24 UTC, Johannes Loher wrote: I already posted this in the vibe.d forums (https://forum.rejectedsoftware.com/groups/rejectedsoftware.vibed/thread/58891/), but it seems, there is not a lot of activity over there, so I am cross posting this here: [...] Do you have some code segments boiled down to the problem? Are you using vibe.core.log?
Re: How do you put log calls in constructors when they may be created in a static context?
On Wednesday, 8 August 2018 at 21:54:34 UTC, aliak 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? Cheers, - ali How about debug [1]? struct S()T { this() { debug { writeln("Created..."); } } } and compile with the debug flag. You can also specify a debug identifier or level. [1]: https://dlang.org/spec/version.html#debug
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: Why does templated interface function return something different than final function?
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.
Re: hasUDA with this
On Wednesday, 25 July 2018 at 21:17:38 UTC, jmh530 wrote: On Friday, 20 July 2018 at 18:24:11 UTC, Timoses wrote: [snip] It works in module scope https://run.dlang.io/is/OQKYag I don't know why though... This was reported in 2013. IMO, it should be mentioned in the spec if they don't plan on changing it. https://issues.dlang.org/show_bug.cgi?id=11064 I don't think that bug report relates to the initial question (UDA not applying to run-time instance). Regarding this example void fun() { /*const*/ { double bar; } static assert(!is (typeof(bar))); } it would kind of violate that `bar` is declared within its own scoped block if the static assert failed just because `const` was applied to the block.
Re: How to avoid inout type constructor with Optional type wrapper undoing string type
On Tuesday, 24 July 2018 at 14:11:51 UTC, Ali Çehreli wrote: On 07/24/2018 02:47 AM, Timoses wrote: > Why does this fail while it works when replacing T with U in struct > W(T)?? It's so odd. Both T and U seem to resolve to "string". > > struct W(T) { > const T value; > // Replacing `T value` with `U value` compiles > this(U : T)(auto ref const T value) { That means, "any U that can implicitly be converted to string". However, when U does not appear in the function parameter list, there is no way for the compiler to deduce U. (I don't think there is syntax to specify constructor template parameters explicitly.) And if the parameter is always T, why is the constructor a template? Ok, perhaps U is used inside the constructor and the programmer needs to specify it... Still, I don't think there is such syntax. Ali Ah, thanks!
Re: trait to get the body code of a function?
On Tuesday, 24 July 2018 at 04:43:33 UTC, Guillaume Lathoud wrote: Hello, __traits and std.traits already offer access to function information like input parameters, e.g. in std.traits: ParameterIdentifierTuple ParameterStorageClassTuple Even if that might sound strange, is there a compile time access to the body of the function, e.g. as a code string, or at least to the filename where it was declared? I have not found a direct "string" access, but I found these: https://dlang.org/phobos/std_traits.html#moduleName https://dlang.org/phobos/std_traits.html#packageName ...and I am not sure how to proceed from here to get the code as a string that declared the function. Context: I have some compile-time ideas in mind (code transformation). Best regards, Guillaume Lathoud Not sure if this could be of interest: https://forum.dlang.org/thread/ifllo2$a45$1...@digitalmars.com
Re: How to avoid inout type constructor with Optional type wrapper undoing string type
On Monday, 23 July 2018 at 18:39:59 UTC, aliak wrote: Hi, I'm playing around with an Optional wrapper type. It stores a type T and a bool that defines whether a value is defined or not: struct Optional(T) { T value; bool defined = false; this(U : T)(auto ref inout(U) value) inout { this.value = value; this.defined = true; } } To facilitate it's use I have two type constructors: inout(Optional!T) some(T)(auto ref inout(T) value) { return inout(Optional!T)(value); } Optional!T no(T)() { return Optional!T(); } The above produces a problem when working with strings. Basically the type information gets slightly altered so you can't do this: auto a = [no!string, some("hello")]; You get a type mismatch: * no!string = Optional!string * some("hello") = immutable(Optional!(char[])) I've created a short code gist, so basically I'm wondering how to get it to compile without changing what's in main() https://run.dlang.io/is/BreNdZ I guess I can specialize on string type T, but this is a more general problem that can be shown with: struct S {} alias Thing = immutable S; Thing thing = S(); auto x = some(thing); auto y = no!Thing; auto arr = [x, y]; // no can do buddy Cheers, - Ali I'm not being very helpful here, just throwing in more questions again: Why does this fail while it works when replacing T with U in struct W(T)?? It's so odd. Both T and U seem to resolve to "string". struct W(T) { const T value; // Replacing `T value` with `U value` compiles this(U : T)(auto ref const T value) { pragma(msg, T); // string pragma(msg, U); // string this.value = value; } } auto defined(T)(auto ref const T value) { return W!T(value); } void main() { auto a = defined("hello"); } Is this a bug?
Re: How to get an inout constructor working with a template wrapper
On Monday, 23 July 2018 at 12:02:58 UTC, aliak wrote: Thank you Ali! That helped :) I've gotten most of it sorted out now, and the factory wrap is definitely the way to go, it also turned out that inout(T) and inout T (so inout without parens) was surprisingly different (maybe it's a bug? - to test you can remove the parens around U on line 3 in this sample: https://run.dlang.io/is/gd5oxW Also over there, line 24: auto si = wrap!(immutable int)(3); Both of these seem to work (as you pointed out) // immutable(W!int) auto si = wrap!(int)(cast(immutable)3); // or wrap(cast(immutable)3); // W!(immutable(int)) auto si2 = W!(immutable int)(3); seems to be giving problems. Any ideas there? Error is: onlineapp.d(8): Error: inout on return means inout must be on a parameter as well for pure nothrow @nogc @safe inout(W!(immutable(int)))(immutable(int) t) onlineapp.d(23): Error: template instance `onlineapp.wrap!(immutable(int))` error instantiating To make it compile successfully you can either: 1) Chance immutable to const, then it works for some reason. 2) Change the line to: "auto si = wrap(cast(immutable int)3);" - i.e. do not explicitly provide type information. I don't know why wrap!(immutable int)(3); is not working. The error message "Error: inout on return means inout must be on a parameter as well for pure nothrow @nogc @safe inout(W!(immutable(int)))(return immutable(int) t)" sounds very odd and not at all helpful, at least regarding that removing immutable from the template argument works. Cheers, - Ali The depths of D. Why does the following only work with "return ref"? struct W(T) { T val; this(U : T)(auto ref inout U val) inout { pragma(msg, typeof(val)); this.val = val; } } // Fails without "return ref" (escaping t warning...) auto wrap(T)(return ref inout T t) { return inout W!T(t); } class C {} void main() { immutable C ci = new immutable C; auto i = wrap(im); pragma(msg, typeof(i)); }
Re: hasUDA with this
On Friday, 20 July 2018 at 16:53:12 UTC, jmh530 wrote: Hmm, on that part about the attributes copying their values, I suppose it would be sufficient if I could apply the attributes to a group of declarations. However, it didn't seem to work properly for me with UDAs, and I noticed that even some of the examples in the spec don't compile. Below is taken from section 8.5 and doesn't compile with DMD 2.081.1. (here's a version on run.dlang.org: https://run.dlang.io/is/pKHoBA) void main() { const int foo = 7; static assert(is(typeof(foo) == const(int))); const { double bar = foo + 6; } static assert(is(typeof(bar) == const(double))); } It works in module scope https://run.dlang.io/is/OQKYag I don't know why though...
Re: hasUDA with this
On Thursday, 19 July 2018 at 19:18:43 UTC, jmh530 wrote: I wanted to create a struct with a member function whose behavior was different depending on whether the struct instance had a particular UDA. However, it seems like hasUDA doesn't seem to produce the result I would have expected here. I tried using getAttributes, but that didn't work either. Am I missing something, or should I submit an enhancement request? import std.traits : hasUDA; enum test; struct Foo { int x; bool checkUDA() { static if (hasUDA!(this, test)) { return true; } else { return false; } } } void main() { import std.stdio : writeln; @test Foo foo = Foo(1); static assert(hasUDA!(foo, test)); writeln(foo.checkUDA()); //prints false, expected true } I haven't worked with UDAs myself yet, but I believe that when you apply something like @test Foo foo; then you apply the UDA to `foo` and not to `Foo`. See below: enum test; struct Foo {} bool checkUDA(alias f)() { static if (hasUDA!(f, test)) { return true; } else { return false; } } void main() { @test Foo foo; // same as `hasUDA!(foo, test)` assert(checkUDA!foo); //prints true } Now I'm really not sure how UDAs are best utilized, so above example might not be how it should be done.. However, you could make a templated version of checkUDA depending on what calls it. E.g. bool checkUDA(T, alias f)(T t) { // ... } although this leads to awkward calls like foo.checkUDA!foo which doesn't seem right either. Perhaps wait for somebody more knowledgeable to answer your question : D.
Re: Member function passed through template alias only requiring `this` in certain conditions?
On Thursday, 19 July 2018 at 22:16:22 UTC, Ali Çehreli wrote: On 07/19/2018 08:12 AM, Emma wrote: > [...] > If I try to compile it, dmd complains, which I guess makes sense: > > --- > Error: need this for bar of type void() > Error: need this for baz of type void() > --- > > [...] I think it's a compiler bug. The second template argument should be a lambda as well. When I added the following lines to test() pragma(msg, typeof(fn1)); pragma(msg, typeof(fn2)); the output is different: void delegate() @system void() That is for the version of calling test with one lamdba and one function? (`test!(() => bar, baz)`) Just a question: The compiler should not automatically convert those (functions) to lambdas? Interesting is this: void test(alias fn1, alias fn2)() { pragma(msg, typeof(fn1)); // void delegate() @system pragma(msg, typeof(fn2)); // void() fn1(); fn2(); // Error: this for baz needs to be type Boo not type Foo } struct Foo { void foo() { test!(()=>bar, b.baz); } int i = 1337; struct Boo { int j = 3; void baz() {writeln(j);} } Boo b; void bar() {writeln(i);} } unittest { auto foo = Foo(); foo.foo(); } Looks like the compiler just assumes the context of the first delegate to be applicable for the second function? I think it's a bug probably related to multiple local lambdas. We had similar issues in the past. Although it works as is, I recommend you make the second one a lambda as well. Others, please confirm that it's a bug and let's create a bug report. Ali
Re: Implicit conversion of struct with methods to immutable in pure function fails
On Thursday, 19 July 2018 at 06:35:36 UTC, Simen Kjærås wrote: On Wednesday, 18 July 2018 at 11:28:54 UTC, Timoses wrote: But why is a context pointer a problem? Is it problematic because the context pointer to the main scope can not guarantee `immutable`? E.g. if I happened to use data from main in a function of the immutable struct then... well then what? The struct would still be immutable, but what would prevent a function from using non-immutable data? It's a known bug: https://issues.dlang.org/show_bug.cgi?id=18563 In the associated discussion (https://forum.dlang.org/thread/p7lp2b$1jod$1...@digitalmars.com), Steven Schveighoffer points out that an immutable struct may be passed to other threads, which would give one thread access to another thread's stack. This could be a good enough reason to prevent this kind of conversion, but a better error message would still make sense. -- Simen Thanks so much for the pointer, Simen. Interesting discussion.
Re: Why does templated interface function return something different than final function?
On Wednesday, 18 July 2018 at 11:09:12 UTC, Timoses wrote: Why is the interface templated function not also returning the class C toString return value "in C"?? interface iface { void toString(scope void delegate(const(char)[]) sink) const; final string convert() inout { import std.conv; // assert(std.conv.to!string(this) == "in C"); // fails! return std.conv.to!string(this); } final string convert2() const { import std.conv; assert(std.conv.to!string(this) == "in C"); return std.conv.to!string(this); } } class C : iface { void toString(scope void delegate(const(char)[]) sink) const { sink("in C"); } } void main () { iface i = new C(); import std.stdio; writeln(i.convert); // "app.C" writeln(i.convert2()); // "in C" } It seems like `inout` triggers some odd behaviour?? Sorry, I experimented a bit and forgot to change the topic to something more fitting, e.g. "Why does inout struct function return different results?"
Re: Implicit conversion of struct with methods to immutable in pure function fails
On Tuesday, 17 July 2018 at 06:24:12 UTC, Simen Kjærås wrote: That makes sense. The problem is F has a context pointer to the main() block, since it's a non-static struct with methods inside a block. It doesn't actually use the context pointer for anything, so it possibly shouldn't have one, but it does, so we have to work around it. The fix is to mark F as static, or move it outside the main() block. -- Simen Thanks for the explanation. But why is a context pointer a problem? Is it problematic because the context pointer to the main scope can not guarantee `immutable`? E.g. if I happened to use data from main in a function of the immutable struct then... well then what? The struct would still be immutable, but what would prevent a function from using non-immutable data? E.g. I could do this int gnumber = 3; struct F { int i; void fun() immutable { gnumber = 5; } } void main () { immutable F f = F(); f.fun; } I declared `fun()` to be an immutable function. So calling the immutable struct function `F.fun()` changes a module scope int. The same could be applied to local data of the main scope, however the following fails: void main () { int mnumber = 3; struct F { int i; void fun() immutable { // Error: immutable function onlineapp.main.F.fun cannot access mutable data mnumber mnumber = 5; } } immutable F f = F(); f.fun; } Is this connected why I can't implicitly convert a local struct with a context pointer to immutable? What's the reason behind it?
Why does templated interface function return something different than final function?
Why is the interface templated function not also returning the class C toString return value "in C"?? interface iface { void toString(scope void delegate(const(char)[]) sink) const; final string convert() inout { import std.conv; // assert(std.conv.to!string(this) == "in C"); // fails! return std.conv.to!string(this); } final string convert2() const { import std.conv; assert(std.conv.to!string(this) == "in C"); return std.conv.to!string(this); } } class C : iface { void toString(scope void delegate(const(char)[]) sink) const { sink("in C"); } } void main () { iface i = new C(); import std.stdio; writeln(i.convert); // "app.C" writeln(i.convert2()); // "in C" } It seems like `inout` triggers some odd behaviour??
Re: Is it feasible to slowly rewrite a C++ codebase in D?
On Monday, 16 July 2018 at 11:31:32 UTC, Seb wrote: On Monday, 16 July 2018 at 11:12:20 UTC, Dukc wrote: On Saturday, 14 July 2018 at 03:08:50 UTC, Vladimir Panteleev wrote: I'll follow up with Alawain. Regardless, dscripten-tools borrows very little from the redistributable parts of dscripten - mostly the "minimalistic runtime", which I think was itself borrowed from somewhere else. Indeed, it appears Alawain himself just changed the runtime part to be boost! If he is reading this, thank you! https://github.com/Ace17/dscriptenQ/issues/4 Superfluous Q attack. Working link: https://github.com/Ace17/dscripten/issues/4
Re: Implicit conversion of struct with methods to immutable in pure function fails
On Monday, 16 July 2018 at 12:00:57 UTC, Simen Kjærås wrote: On Monday, 16 July 2018 at 11:43:03 UTC, Timoses wrote: Why does this fail? It doesn't. Not using DMD 2.081.1 under Windows, at least. I tried adding a bitfield since you mentioned it, but it compiles nicely for me. Which version of DMD are you using, and are you having the issues with the exact code you posted here? -- Simen https://run.dlang.io/is/Pgs527 I'm on 2.080.1. But above is on latest 2.081.1 I believe. Note that the bottom code snippet in the original post does work, while the first one does not.
Implicit conversion of struct with methods to immutable in pure function fails
Why does this fail? struct F { int i; ushort _x; void x(ushort v) pure {_x = v;} ushort x() const { return _x; } } immutable F f1 = () pure { F lf = F(); return lf; }(); // Error: cannot implicitly convert expression delegate () => lf() of type F to immutable(F) F makeF() pure { F lf = F(); return lf; } immutable F f2 = makeF(); // Error: cannot implicitly convert expression makeF() of type F to immutable(F) Removing the methods in struct F compiles fine. Background: I have a mixin(bitfields!(...)) in the struct which utilizes member functions. / Idea: Just found out that it works when making the struct static. But why does that help? Is it because the compiler wouldn't be able to check whether methods in the struct are accessing non-immutable data in the enclosing context? That would not make much sense though because the following works: // Compiles fine! int modi = 3; void main () { static struct F { int var() immutable { return modi; } // accessing modi from module scope } immutable f = () pure { F f = F(); return f; }(); } So my explanation wouldn't make sense, since why would it be okay to use module-scope data and not enclosing context data? So where does that limitation come from that I implicitly convert a nested struct to immutable in a pure function?
Re: Is there any tool that will auto publish my changes.
On Sunday, 15 July 2018 at 00:25:22 UTC, Venkat wrote: I am writing a simple vibe.d app. The following is what I do right now. - I make changes. - build - Restart the server. Is there any tool that will auto publish my changes as I save them ? I am using Visual Studio Code. Thanks Venkat I don't believe there currently exists a tool to rebuild the Diet templates on the fly. The Diet templates require a step during compilation (I think), so that the entire application has to be rebuilt (at least the part that has the diet templates). If you have a large project, what I've heard from others what they do, is split the project into smaller pieces and can therefore have shorter compilation times [1]. There's also DiamondMVC which you could try depending on your use case [2], though I haven't tried it out myself. [1] https://forum.dlang.org/post/txgoxzroscysfbvio...@forum.dlang.org [2] https://github.com/DiamondMVC/Diamond
Re: Find out druntime/import and phobos folder on Linux
On Saturday, 14 July 2018 at 19:04:01 UTC, Andre Pany wrote: On Saturday, 14 July 2018 at 19:00:56 UTC, Anonymouse wrote: On Saturday, 14 July 2018 at 17:19:20 UTC, Andre Pany wrote: Is there a way to find out both paths based on the dmd executable folder? What I found out so far, these paths are not always correct: /usr/include/dmd/druntime/import /usr/include/dmd/phobos Arch Linux and derivatives keep them under /usr/include/dlang/{dmd,gdc,ldc}/* You may have to hardcode some common paths and try them in each in turn. I'm happy to be proven wrong here though. Somehow also the DMD executable needs to know which Phobos/DRuntime it should use. How does DMD is working here? Maybe I can do the same... Kind regards André Maybe this helps? https://github.com/dlang/installer/blob/master/linux/dmd_deb.sh#L331 Or check th
Re: Call method with Variant array as parameters
On Saturday, 14 July 2018 at 11:08:21 UTC, Andre Pany wrote: Hi, I have a class with methods and I want to call a method by using a variant array. The length of the array and the types exactly fits the method signature. In the last line of main you see the coding which should be generated. I need some coding which looks at the signature of bar and uses this information to create "(args[0].get!string, args[1].get!long)". I think it is possible with string mixins, but is there some better way? Maybe a staticMap? class Foo { void bar(string s, long l) {} } void main() { import std.variant: Variant; Foo foo = new Foo(); Variant[] args = [Variant("Hello"), Variant(42)]; __traits(getMember, foo, "bar")(args[0].get!string, args[1].get!long); } Kind regards André How about this? import std.variant: Variant; import std.traits : isCallable; class Foo { void bar(string s, long l) { import std.stdio : writeln; writeln(s); writeln(l); } } void call(T)(T fun, in Variant[] args) if (isCallable!fun) { import std.traits : Parameters; alias Params = Parameters!fun; Params params; static foreach(i, param; params) { if (auto p = args[i].peek!(Params[i])) { param = *p; } // perhaps create a warning if peeking was unsuccessful... } fun(params); } unittest { Foo foo = new Foo(); Variant[] args = [Variant("Hello"), Variant(42L)]; call(, args); }
Re: @safe - why does this compile?
On Friday, 13 July 2018 at 22:17:59 UTC, Dukc wrote: On Friday, 13 July 2018 at 13:52:27 UTC, Timoses wrote: I suppose this is another good example of how casting can be dangerous? E.g. also: immutable int i = 3; int* j = cast(int*) assert(i == 3); *j = 4; assert(j == ); // data occupies same address space assert(i == 3 && *j == 4); // yet the values differ No, casting classes to their subclasses is not dangerous to program integrity, because it is checked. It is just a regular bug that terminates the program when encountered. But casting away immutable can break program integrity as your example demonstrates. For that reason the compiler won't let you do that if you wrap that code in @safe, unlike the class cast. Thanks for the explanation. Only read the function safety chapter in depth after posting this : D. Still, is `cast`ing seen as something "dangerous" or as something that should only be done as a last resort? Should std.conv : to be prioritized?
Re: Orange not working?
On Friday, 13 July 2018 at 21:38:18 UTC, JN wrote: I'm curious, are the tests in any way OS specific? I see the tests are passing, but trying the latest DMD on Windows and orange v2.0.0, when I add "@nonSerialized" to a struct member, I get this: C:\Users\jacek\Desktop\test_orange>dub run Performing "debug" build using C:\D\dmd2\windows\bin\dmd.exe for x86. orange 2.0.0: target for configuration "" is up to date. test_orange ~master: building configuration "application"... ..\..\AppData\Local\dub\packages\orange-2.0.0\orange\orange\serialization\Serializer.d(1504,13): Warning: statement is not reachable ..\..\AppData\Local\dub\packages\orange-2.0.0\orange\orange\serialization\Serializer.d(1510,17): Warning: statement is not reachable ..\..\AppData\Local\dub\packages\orange-2.0.0\orange\orange\serialization\Serializer.d(1512,13): Warning: statement is not reachable ..\..\AppData\Local\dub\packages\orange-2.0.0\orange\orange\serialization\Serializer.d(1514,13): Warning: statement is not reachable C:\D\dmd2\windows\bin\dmd.exe failed with exit code 1. Wasn't aware of the `buildRequirements "silenceWarnings"` switch in dub.sdl. Now there should hopefully be no more warnings with below PR. https://github.com/jacob-carlborg/orange/pull/51 Could perhaps bump it to 2.0.1 ? @Jacob
Re: @safe - why does this compile?
On Friday, 13 July 2018 at 11:04:40 UTC, Piotr Mitana wrote: This code: import std.stdio; class X1 {} class X2 : X1 { void run() @safe { writeln("DONE"); } } void main() @safe { X1 x1 = new X1; X2 x2 = cast(X2) x1; x2.run(); } is obviously wrong gets killed by OS's signal. Why is it @safe? I thought @safe should prevent such errors as well. I suppose this is another good example of how casting can be dangerous? E.g. also: immutable int i = 3; int* j = cast(int*) assert(i == 3); *j = 4; assert(j == ); // data occupies same address space assert(i == 3 && *j == 4); // yet the values differ
Re: Orange not working?
On Friday, 13 July 2018 at 05:39:24 UTC, JN wrote: On Friday, 13 July 2018 at 05:29:58 UTC, Timoses wrote: On Thursday, 12 July 2018 at 20:44:43 UTC, JN wrote: I am trying to make use of the Orange package, I added the latest version from dub to my project: "orange": "~>1.0.0" and copy pasted the "simple usage" code from https://github.com/jacob-carlborg/orange , but I am getting a long list of errors: ..\..\AppData\Local\dub\packages\orange-1.0.0\orange\orange\serialization\Serializer.d(714,21): Error: undefined identifier typedef [...] Hm, v1.0.0 is from 2016 and meanwhile typedef was deprecated https://dlang.org/deprecate.html#typedef . Perhaps use "orange": "~master" to use the latest code. Looks better, but still doesn't compile: C:\Users\jacek\Desktop\test_orange>dub run [...] test_orange ~master: building configuration "application"... ..\sertest\orange-master\orange\serialization\archives\Archive.d(1313,9): Warning: statement is not reachable [...] ..\sertest\orange-master\orange\serialization\Serializer.d(1215,9): Warning: statement is not reachable C:\D\dmd2\windows\bin\dmd.exe failed with exit code 1. Huh, see this issue on github: https://github.com/jacob-carlborg/orange/issues/39 which references to https://github.com/jacob-carlborg/mambo . Although that repository has last been updated in 2016 whereas Orange's was Oct. 2017. Went ahead and applied a few fixes for the warnings I encountered: https://github.com/jacob-carlborg/orange/pull/50
Re: Orange not working?
On Thursday, 12 July 2018 at 20:44:43 UTC, JN wrote: I am trying to make use of the Orange package, I added the latest version from dub to my project: "orange": "~>1.0.0" and copy pasted the "simple usage" code from https://github.com/jacob-carlborg/orange , but I am getting a long list of errors: ..\..\AppData\Local\dub\packages\orange-1.0.0\orange\orange\serialization\Serializer.d(714,21): Error: undefined identifier typedef [...] Hm, v1.0.0 is from 2016 and meanwhile typedef was deprecated https://dlang.org/deprecate.html#typedef . Perhaps use "orange": "~master" to use the latest code.
Re: Troubles creating templated inout objects
On Thursday, 12 July 2018 at 12:22:34 UTC, Steven Schveighoffer wrote: On 7/11/18 8:55 AM, Timoses wrote: class TestA(T : T[]) { Test!T[] arr; // ERROR: Can't initialize inout variable in a for loop... this(inout(T[]) arr) inout { // 1: Nope foreach (mem; arr) this.arr ~= test(mem); // 2: Nope //Test!T[] a; //foreach (mem; arr) // a ~= test(mem); On the right track, but inside inout (or const or immutable) constructors, the members can only be initialized once. So you have to initialize a local, and then set the member once. The issue is, your input is *also* inout (a necessary condition), so you didn't declare a properly: inout(Test!T)[] a; foreach (mem; arr) a ~= test(mem); this.arr = a; -Steve Aw, thanks! This is much nicer than casting...
Re: Troubles creating templated inout objects
On Tuesday, 10 July 2018 at 14:34:55 UTC, Timoses wrote: `Unqual` in this case just turns `inout(int[])` into `inout(int)[]`, which is why it complains. That's a side effect of this example [...] See also: https://issues.dlang.org/show_bug.cgi?id=3567
Re: Troubles creating templated inout objects
On Wednesday, 11 July 2018 at 12:55:35 UTC, Timoses wrote: On Tuesday, 10 July 2018 at 18:01:59 UTC, Steven Schveighoffer wrote: You are overthinking :) inout typically is much easier than you expect, until you need to create temporary structs or types with inout members, then it becomes problematic. https://run.dlang.io/is/kosYuC I had to put in a static if, because your function doesn't work once you get down to the array type. See the // fixme comment. Ok, well that helped a tiny bit for the example. I'm trying to reproduce the errors from my project. It's starting to get out of control : D. inout is on a rampage! https://run.dlang.io/is/5TN7XX I guess it's the same as for immutable initialization of arrays. I can't seem to find a proper response to this one.. [...] class TestA(T : T[]) { Test!T[] arr; // ERROR: Can't initialize inout variable in a for loop... this(inout(T[]) arr) inout { // 1: Nope foreach (mem; arr) this.arr ~= test(mem); // 2: Nope //Test!T[] a; //foreach (mem; arr) // a ~= test(mem); import std.algorithm : map; // 3: Nope // this.arr = arr.map!((e) => test(e)).array; } } [...] I guess the problem here is focused around the problem that the incoming type in the constructor is inout and that the constructed object itself is inout. I can't seem to find another way, I'm just blatantly casting now... class TestA(T : T[]) { Test!T[] arr; this(inout(T[]) arr) inout { import std.algorithm : map; import std.range: array; // should be okay to cast to const, won't change anything auto ts = cast(const T[])arr; // should be okay as well, as `test(t)` creates a new object this.arr = cast(inout(Test!T[]))(ts.map!(t => test(t)).array); } } I also found `assumeUnique` in std.exception, or std.experimental.allocator.makeArray. I'm not to sure how they might be able to circumvent the casting though, since I need an inout array of the objects... Am I missing something or is `inout` simply not that well "implemented" yet?
Re: Using dub and rdmd together?
On Wednesday, 11 July 2018 at 16:43:24 UTC, Seb wrote: I don't know of an easy way to do out of the box. However, with dmd's new -i option, it could be as easy as: --- dub fetch requests cat > test.d << EOF import std.stdio; import requests; void main() { auto content = postContent("http://httpbin.org/post;, queryParams("name", "any name", "age", 42)); writeln(content); } EOF dub fetch requests dmd -I~/.dub/packages/requests-0.8.2/requests/source -i -run tests.d --- However, dmd itself doesn't do any caching (though it would work similarly with rdmd). But, of course, this won't work for more complex dub packages. There's `dub describe` (and a backend generator) for which they might be used. So this is kind of similar to what dub does already? Would be nice if dub could cache such compiled scripts somewhere. I mean dub already caches inside .dub folder in a dub project. Why not also cache compiled scripts somewhere?
Re: Troubles creating templated inout objects
On Tuesday, 10 July 2018 at 18:01:59 UTC, Steven Schveighoffer wrote: You are overthinking :) inout typically is much easier than you expect, until you need to create temporary structs or types with inout members, then it becomes problematic. https://run.dlang.io/is/kosYuC I had to put in a static if, because your function doesn't work once you get down to the array type. See the // fixme comment. Ok, well that helped a tiny bit for the example. I'm trying to reproduce the errors from my project. It's starting to get out of control : D. inout is on a rampage! https://run.dlang.io/is/5TN7XX I guess it's the same as for immutable initialization of arrays. I can't seem to find a proper response to this one.. import std.traits; struct S { int[3] arr; } struct SS { S s; } interface I { inout(I) opIndex(size_t idx) inout; } class Test(T) : I { T member; this(inout T mem) inout { this.member = mem; } inout(Test!T) get() inout { return new inout Test!(Unqual!(typeof(member)))(member); } inout(I) opIndex(size_t idx) inout { static if (is(T == struct)) { switch (idx) static foreach (index, t; T.tupleof) { case index: return new inout Test!(Unqual!(typeof(this.member.tupleof[index]))) (this.member.tupleof[index]); default: return null; } } else return null; } } auto test(T)(inout T t) { return new inout Test!(Unqual!T)(t); } class TestA(T : T[]) { Test!T[] arr; // ERROR: Can't initialize inout variable in a for loop... this(inout(T[]) arr) inout { // 1: Nope foreach (mem; arr) this.arr ~= test(mem); // 2: Nope //Test!T[] a; //foreach (mem; arr) // a ~= test(mem); import std.algorithm : map; // 3: Nope // this.arr = arr.map!((e) => test(e)).array; } } void main() { auto ss = SS(S([1,2,3])); auto t = new const Test!SS(ss); auto ta = new const TestA!(Test!SS[])([t]); }
Re: taskPool.reduce vs algorithm.reduce
On Wednesday, 11 July 2018 at 08:31:30 UTC, Dorian Haglund wrote: Hi. I'm trying to use taskPool.reduce with a delegate, for example: import std.parallelism; int main(string[] args) { int f(int a, int b) { if (args.length > 1) return a+b; else return a-b; } auto res = taskPool.reduce!f([1, 2, 3]); return 0; } But it fails to compile (with gdc 8.1.0, dmd v2.081) complaining that template instance reduce!(f) cannot use local 'f' as parameter to non-global template reduce(functions...) The snippet above compiles with the reduce function from std.algorithm. Is there a way to make the code compile with taskPool.reduce ? (I don't want to write two functions and choosing one depending on args.length) Why the interface difference between std.algorithm's reduce and taskPool.reduce ? Best regards, Dorian As the error message says taskPool.reduce is a non-global template. It's embedded in a taskPool struct. I can't say what the reason is that a delegate cannot be used with such a template. I'd be interested in hearing what the reason is. (See Paul's reply). I'm trying to trick around it, but can't get this to work... https://run.dlang.io/is/EGbtuq import std.parallelism; int main(string[] args) { static int f(bool cond)(int a, int b) { static if (cond) return a+b; else return a-b; } template getF(alias func) { auto getF(T)(T arg) { if (args.length > 1) return func!(f!true)(arg); // line 18 else return func!(f!false)(arg); // line 20 } } auto res = getF!(taskPool.reduce)([1,2,3]); return 0; } onlineapp.d(18): Error: need this for reduce of type @system int(int[] _param_0) onlineapp.d(20): Error: need this for reduce of type @system int(int[] _param_0)
Re: Passing function(whose parameter would be dynamic and the type is unknown) as a parameter to another function.
On Tuesday, 10 July 2018 at 14:58:42 UTC, vino.B wrote: Hi Alex, I am getting the output as tuples of multiple arrays, but the requirement is to get the all the tuple in a single array like the below so that we can perform sorting and printing the output is easy. Something along the way unittest { import std.typecons : Tuple, tuple; alias pair = Tuple!(string, int); pair[] values; values ~= tuple("du", 7); values ~= tuple("Vino", 3); values ~= tuple(",", 4); values ~= tuple("hur", 5); values ~= tuple("Hej", 2); values ~= tuple("?", 8); values ~= tuple("mår", 6); import std.algorithm : sort, each; import std.stdio : write; values.sort!((p1, p2) => p1[1] < p2[1]) .each!(p => write(p[0] ~ " ")); } ?
Troubles creating templated inout objects
How do I create an inout object with template parameters? Take following code: import std.stdio; import std.traits; struct S { int[] arr; } interface I { inout(I) opIndex(size_t idx) inout; } class Test(T) : I { // Error: variable `onlineapp.Test!(inout(int)[]).Test.member` only parameters or stack based variables can be inout T member; this(inout T mem) inout { this.member = mem; } inout(Test!T) get() inout { return new inout Test!(Unqual!(typeof(member)))(member); } inout(I) opIndex(size_t idx) inout { switch (idx) static foreach (index, t; T.tupleof) { case index: // Error: template instance `onlineapp.Test!(inout(int)[])` error instantiating return new inout Test!(Unqual!(typeof(this.member.tupleof[index]))) (this.member.tupleof[index]); default: return null; } } } unittest { auto s = S([1,2,3]); auto t = new const Test!S(s); } `Unqual` in this case just turns `inout(int[])` into `inout(int)[]`, which is why it complains. That's a side effect of this example, however the main question is how one would go about achieving something like this idiomatically? I would like to return a new object and that object should have the same mutability as the one creating it.
Re: guard clause style static if
On Tuesday, 10 July 2018 at 12:10:27 UTC, Jonathan M Davis wrote: On Tuesday, 10 July 2018 05:38:33 MDT kdevel via Digitalmars-d-learn wrote: I would like to suggest an extension of the language by introducing static return Expression_opt; which shall have the effect of a return plus that the remaining lines in the current block are treated as if they were enclosed in an else block. Well, you can propose it, but it really doesn't fit with how static if works. static if doesn't have anything to do with control flow, whereas what you're proposing here would, which would arguably make it that much more confusing. I confess that I don't understand what the problem is with simply adding an else block. It's simple, and it works right now without any language changes. - Jonathan M Davis Actually, it's kind of controlling "compile-time control flow". If you had auto func(T)(T args) { static if (T.length == 0) static return; return args[0]; } then `static return;` would instruct the compiler to skip the rest of the code and only insert a `return;`, omitting any code that follows. So the result in above case with `T.length == 0` would be: void func() { return; } To me that sounds like a very nice feature, considering that I often found myself in the same situation where I didn't feel like the static `else` statement was really necessary (comparing to the usual way to control flow (at run-time) with convential if-else statements).
Re: guard clause style static if
On Tuesday, 10 July 2018 at 12:05:11 UTC, kdevel wrote: On Saturday, 7 July 2018 at 13:12:59 UTC, Alex wrote: The site you cited for the guard clause above (c2.com) works at runtime. ? static if works at compile team and only inserts code into the final code for run-time depending on the condition (which has to be known at compile time). In your case void bar (T ...) (T args) { static if (args.length == 0) return; writeln (args [0]); return bar (args [1 .. $]); } you could also write static if (T.length == 0) so in case T.length == 0 the resulting run-time code would yield void bar (T args) // in that case T is nothing { return; writeln (args [0]); return bar (args [1 .. $]); } So the only thing you can control with static if statements is "what code to run" depending on the template arguments. The problem with the error messages you are getting (https://forum.dlang.org/post/yndsroswikghknzlx...@forum.dlang.org) is that the compiler checks during compilation time whether `args[0]` is valid (which in above case it is not). So you can't use args like a "normal array" as you would in control statements during run-time. I don't know what exactly `args` represents in the background. [...]
Re: Passing function(whose parameter would be dynamic and the type is unknown) as a parameter to another function.
On Monday, 9 July 2018 at 05:54:27 UTC, vino.B wrote: On Sunday, 8 July 2018 at 19:22:32 UTC, Timoses wrote: Perhaps you could tell us what your goal is. People here might come up with a nice solution. Why do you feel like having to use templated functions in the first place? That is, what is the generic goal of the functions you are trying to define? Hi Timoses, We are converting a Power shell script to D in phased manner; the PS script has many functions and we converted few function to D in Phase 1. Phase 1: Structure of the Program Main -> Thread Manager->CoFunction1(Fs1,2,3,4,5) Main -> Thread Manager->CoFunction2(Fs1,2,3,4,5) The thread manager will call the Cofunctions and the function gets executed on “N” of file systems each of size 5-10 TB. The function that we transformed all has the same number of parameters (3) and the type was same (string, string, int), so we wrote a static thread manager as below void ptManager (T)(T function(string, string, int) coRoutine, Array!string Dirlst, string Step, int Size) { alias scRType = typeof(coRoutine(string.init, string.init, int.init)); auto PFresult = taskPool.workerLocalStorage!scRType(); ReturnType!coRoutine rData; foreach (string FFs; parallel(Dirlst[0 .. $],1)) { PFresult.get ~= coRoutine(FFs.strip, Step); } foreach(i; PFresult.toRange) { writeln(i[][]); } } void main () { ptManager(, Fn1Dirlst, Step, Size); ptManager(, Fn2Dirlst, Step, Age); } Phase 2: In phase 2 we are transferring few more function to the existing D code, and these functions has variable number of parameter and different type eg: Function3(string, string, string), Function(string, int, string, int). Initially I tried to re-write the ptManager function for each type of function which ended with 8 ptManager functions, Eg : ptManager1(string, string, int), ptManager2(string, string, string), ptManager3(string,int), so now trying as to whether we can use 1 ptManager function which can process function with “N” of parameter and types to process all the function, hence trying to implement the Variadic function. Hence request your help and suggestion to achieve this. Command Parameter to all the functions: Array!string Dirlist : This parameter will contain the the Fs names File logF: This parameter is used to store the outoput File logE: This parameter is used to store the Error Information. Rest of the function has variable parameters/type. From, Vino.B Ok, interesting. I don't really know my way around parallelism, though I think you should take a look at Alex's suggestion (https://forum.dlang.org/post/adepbwetsiuwguuaa...@forum.dlang.org) for a template solution. You could e.g. do void ptManager(alias func, T ...)(T args) { import std.traits : Parameters, ReturnType; static assert(is(Parameters!func == T), "Arguments don't fit function!"); alias RetType = ReturnType!func; // only receive value if return type is not void static if (!is(RetType == void)) RetType mVal = func(args); // write it to stdout if mVal is a valid symbol // (could also combine that in the above static if...) static if (is(typeof(mVal))) { import std.stdio : writeln; writeln(mVal); } } unittest { ptManager!((int i) => i+1)(2); void someDelegate(string s1, string s2, int i1) { /* ... */ } ptManager!someDelegate("hello", "ptManager", 100); }
Re: Passing function(whose parameter would be dynamic and the type is unknown) as a parameter to another function.
On Sunday, 8 July 2018 at 18:46:31 UTC, vino.B wrote: Hi All, Request you help, in the below code we pass the function "Testfun" as a parameter to another function "process" in order for the function "process" to work we have to specify the type of the parameter that is passed to the function "(T function(string, int) coRoutine, string Test, int Size) ", so now how do we pass a function whose parameter would be dynamic and the type is unknown. void process(T)(T function(string, int) coRoutine, string Test, int Size) { This would templetize the return type of the coRoutine, thus within that function you could do T returnedValue = coRoutine(string.init, int.init); alias scRType = typeof(coRoutine(string.init, int.init)); Eg: Run1 : process(, Test, Size); void process(T ...)(T function(string, int) coRoutine, string Test) { alias scRType = typeof(coRoutine(string.init, int.init)); Run2 : process(, Test, Size, Str1); void process(T)(T function(string, int, string) coRoutine, string Test, int Size, string Str1) { alias scRType = typeof(coRoutine(string.init, int.init, string.int)); Run3 : process(, Test); void process(T)(T function(string, string) coRoutine, string Test, int Size) { alias scRType = typeof(coRoutine(string.init)); PFresult.get = coRoutine(args); Some what like this auto Testfun (string FFs, int Size) { return tuple(FFs, Size); } void process(T ...)(T function(T args) coRoutine, T args) { This would mean that if you pass a function that returns for example an int, it must also - take an int as argument - and process has to accept another int e.g. process((int i) => i+1, 3); if T would be (int, string) you would have to pass something like process((int i, string s) { return AliasSeq!(int, string); }, // error: not even sure how to express this 3, "hello"); where I'm not sure how to express the return type of (int, string)... Does anybody know this? Would the Tuple Dip make this possible? (https://forum.dlang.org/post/p3bdp1$2b4e$1...@digitalmars.com) alias scRType = typeof(coRoutine(T.init)); PFresult.get = coRoutine(T); void main() { string Test ="C:\\Temp\\BACKUP1"; int Size = 1; process(, Test, Size); } Code : Working import std.stdio: writeln; import std.container.array; import std.typecons: tuple; import std.parallelism: taskPool; auto Testfun (string FFs, int Size) { return tuple(FFs, Size); } void process(T)(T function(string, int) coRoutine, string Test, int Size) { alias scRType = typeof(coRoutine(string.init, int.init)); auto PFresult = taskPool.workerLocalStorage!scRType(); PFresult.get = coRoutine(Test, Size); foreach(i; PFresult.toRange) { writeln(i[][]); } } void main() { string Test ="C:\\Temp\\BACKUP1"; int Size = 1; process(, Test, Size); } From, Vino.B I suggest taking a look at https://dlang.org/phobos/std_traits.html . E.g. ReturnType and Parameters: int func() { return 3; } assert(is(ReturnType!func == int)); void gunc(int i, double j) {} import std.meta : AliasSeq; assert(is(Parameters!gunc == AliasSeq!(int, double))); Perhaps you could tell us what your goal is. People here might come up with a nice solution. Why do you feel like having to use templated functions in the first place? That is, what is the generic goal of the functions you are trying to define?
Re: Outside array bounds
On Saturday, 7 July 2018 at 15:25:51 UTC, vino.B wrote: Hi All, If we replace the statement as args[$ -1] the program works are expected, if we apply the same logic in different approach it does not work, in the below code if we command the first block "if (fnID == "ListFilesNames") {} " then the second "if (fnID == "ListFilesSize") {}" works fine, and vice versa but if both the "if" block is un-commented it does not work , rather it passes wrong parameter to the function. Tried change the args as args[$] , args[1], args[2], Error: Test.d(31): Error: function Test.ListFilesSize(string FFs, int Size) is not callable using argument types (string, Array!string) VarTest.d(31):cannot pass argument _param_1 of type Array!string to parameter int Size Test.d(42): Error: template instance `Test.process!(Array!string)` error instantiating Code: [...] void process(T ...)(string fnID, T args) { Throw in a pragma here: void process(T ...)(string fnID, T args) { pragma(msg, T); ... } [...] void main() { Array!string NameDir, SizeDir; NameDir.insert("C:\\Temp\\BACKUP1"); SizeDir.insert("C:\\Temp\\TEAM1"); int Size = 1; string fnID1 = "ListFilesNames", fnID2 = "ListFilesSize"; process(fnID1, NameDir); // 1 process(fnID2, SizeDir, Size); // 2 If you call '// 1' first, then the output would be (Array!string) ... ERROR and switch the order: process(fnID2, SizeDir, Size); // 2 process(fnID1, NameDir); // 1 Now you'll see from the pragma output: (Array!string, int) (Array!string) ... ERROR So the '// 2' call actually compiled fine. The compiler complains because the function would try to call ListFilesSize(int) with the parameter args[$-1], which in this case would be the last element, so Array!string. `args` is a compile time-construct. In effect you instantiate two templates with the following calls: process(fnID1, NameDir); // same as process!(Array!string)(fnID1, NameDir) instantiates the function void process(string fnID, (Array!string) args) { ... // accessing args[$-1] equals accessing args[0] (only one element) ListFilesSize(FFs, args[$ - 1]); // above function will call ListFilesSize(string, Array!string).. which does not exist, hence the error } and process(fnID2, SizeDir, Size); // same as process!(Array!string, int)(fnID1, NameDir, Size) instantiates the function void process(string fnID, (Array!string, int) args) { ... // this time args.length == 2 // hence the call to args[$-1] == args[1] == int ListFilesSize(FFs, args[$-1]); // compiles!!! args[$-1] fits ListFilesSize signature! It helps me to think in two domains. There is the "static" CT (compile-time) and the RT (run-time) domain. You can vary how CT code is laid out with "static" statements (such as "static if" or "static foreach", or use aliases. Beware that "static this()" or static functions are something different once again). So you would have to determine _at compile time_ how the 'process' function should look given it's arguments: void process(T ...)(T args) { static if (T.length == 1 && is(T[0] == Array!string)) { // 1 } else static if (T.length == 2 && is(T[0] == Array!string) && is(T[1] == int)) { // 2 } } So in case above function get's called with only one argument which is an Array!string, only the '// 1' part is left for the run-time to be executed. OR you could test if the function compiles void process(T ...)(T args) { static if (is(typeof(ListFilesSize(args[$-1] ListFilesSize(args[$-1]); else static assert(false); } Another option would be to use template constraints void process(T ...)(T args) if (is(typeof(ListFilesSize(args[$-1] { ListFilesSize(args[$-1]); } This is a nice chapter to read (in fact the whole book is a great read): http://ddili.org/ders/d.en/cond_comp.html
Re: Outside array bounds
On Saturday, 7 July 2018 at 08:35:27 UTC, Alex wrote: On Saturday, 7 July 2018 at 08:24:21 UTC, Timoses wrote: Interesting.. Looks like the compiler does some boundschecking during compile time. You could circumvent this: void process(T ...)(string ID, T args) { if (ID == "I1") { writeln(args.length, "\t", args[0]); } static if (T.length > 1) // only add below code if cond. true if (ID == "I2") { writeln(args.length, "\t", args[1]);} } Oddly, when leaving out the "static if" statement, the error still occurs when compiling with "-release" or with "-boundscheck=off"... I thought those would/should disable bounds checking at compile time??? Nonono )) In this case, the bound checks are like interface checking... or like type checking... As there are different processes instantiations for different number of args. I hope this can't be turned off so easily... Aw, got it. So args is actually a tuple type where accessing beyond the defined tuple (T) is invalid? auto a = [1, 2, 4]; // works pragma(msg, typeof(a[3])); auto t = tuple(3, 4, 5.3); // ERROR: // pragma(msg, typeof(t[3]));
Re: Outside array bounds
On Saturday, 7 July 2018 at 08:09:51 UTC, vino.B wrote: Hi All, Request you help, on the below code import std.stdio: writeln; void process(T ...)(string ID, T args) { if (ID == "I1") { writeln(args.length, "\t", args[0]); } else if (ID == "I2") { writeln(args.length, "\t", args[1]);} } void main() { string S1 = "Test1", S2 = "Test2", ID1 = "I1", ID2 = "I2"; int Size = 1; process(ID1, S1); process(ID2, S2, Size); } Error: Test.d(5): Error: array index [1] is outside array bounds [0 .. 1] Test.d(11): Error: template instance `Test.process!string` error instantiating From, Vino.B Interesting.. Looks like the compiler does some boundschecking during compile time. You could circumvent this: void process(T ...)(string ID, T args) { if (ID == "I1") { writeln(args.length, "\t", args[0]); } static if (T.length > 1) // only add below code if cond. true if (ID == "I2") { writeln(args.length, "\t", args[1]);} } Oddly, when leaving out the "static if" statement, the error still occurs when compiling with "-release" or with "-boundscheck=off"... I thought those would/should disable bounds checking at compile time???
Re: how to link self made lib using dub
On Friday, 6 July 2018 at 17:08:48 UTC, Flaze07 wrote: [...] then, I made a project, with this main in this path : Z:\programming\D\experimentLib\source\main.d it contains this module main; import std.stdio; import source.output; Shouldn't this be 'import output'? void main( string[] args ) { Output.write( "lol" ); readln(); } and then, I have a dub file in this path : Z:\programming\D\experimentLib\dub.json it contains : { "name" : "experimentlib", "targetType": "executable", "targetPath": "bin", "importPaths": [ "Z:\\programming\\D\\usefulFiles\\experiment\\", and this '...\\experiment\\source\\'? (I'm not accustomed to Windows..) ], "lflags": [ "+Z:\\programming\\D\\usefulFiles\\experiment\\lib\\", ], } so, I have made lflags to include the lib in experiment, but still, it failed to linker ( it compiles fine, but the linker fails ) You could also add a dependency to your other dub project and dub should automatically add the import and linker flags. Add this to your dub.json: "dependencies": { "experiment": {"version": "*", "path": "../experiment"} } I didn't test this now, but it should work something like that (again, not sure about Windows path...). See also: http://code.dlang.org/package-format?lang=json#version-specs
Re: immutable / inout / pure headaches
On Friday, 6 July 2018 at 15:44:28 UTC, Steven Schveighoffer wrote: I'm long overdue for an inout article... I can point you at my talk from 2016: https://www.youtube.com/watch?v=UTz55Lv9FwQ Thanks, will definitely take a look when I get home. I never really used 'pure' and just now found a use case with immutable [1], i.e. to return unique objects from functions which can be assigned to a mutable or immutable reference. What other "use cases" or reasons to use 'pure' are there (aside from compiler optimizations)? The reason pure functions allow mutability changes is due to the nature of what pure means semantically -- you have guarantees that nothing else goes in or out, so it's possible to deduce what is unique and what is not. This is powerful to a human reader of a function as well! Without seeing the insides, it tells you exactly what it can and cannot affect, giving you more understanding of when it can be used and when it can't. It helps write safer more tractable code, IMO. In the end, all these attributes are to help reason about large code bases without having to read ALL the code. Sounds like a good idea to always use it whenever possible. For me as a kind of novice it takes time to understand the purpose and meaning of each of those attributes. I guess I got one step closer to understanding "Why pure?". That leaves @nogc, @safe and @trusted :D. I feel the best way to understand these idioms is to experience the "trouble" oneself. I knew in some way what pure functions were from the spec, but I didn't have an example at hand that made "non-usage" of pure painful.
Re: Passing a reference to a returned reference
On Friday, 6 July 2018 at 15:51:34 UTC, Michael wrote: Also, yes, I am using the setter method to play around with the precision of the double values, and do some normalising. While writing I realized that the following is even the case without the 'ref' parameter: The caller of the setter will still be able to change the content of your private data after you checked it for validity. Take following example: class A { private static string[] _disallowed = ["damn"]; private string[int] _dict; // called before and after every member method call invariant { import std.algorithm : any, canFind; // don't allow _dict to contain any from _disallowed assert(!this._dict.byValue() .any!((entry) => _disallowed.canFind(entry))); } @property dict(string[int] dict) { // checks ... this._dict = dict; } void check() { import std.stdio : writeln; writeln(this._dict); } } unittest { string[int] loc; auto a = new A(); loc[1] = "hello john"; a.dict = loc; // using the @property setter loc[1] = "damn"; a.check; } What might be safer is using 'opIndexAssign' void opIndexAssign(string value, int key) { import std.algorithm.searching : canFind; if (!_disallowed.canFind(value)) this._dict[key] = value; } and also duping the dictionary that is handed to the Agent @property dict(string[int] dict) { // checks ... this._dict = dict.dup; } So you can call string[int] loc; auto a = new A(); loc[1] = "hello john"; a.dict = loc; a[1] = "damn"; loc[1] = "damn"; a.check; without assigning bad values. I always want it to access the setter method, but I had hoped that, given it's an associative array, that the creation of the object in create() would simply create it on the heap and I could pass back a reference. It seems that I was incorrect, as if I set create() to explicitly return a reference, it complains about returning a reference to a local variable. Any advice on the best way to pass it as a reference? I suppose this might already answer your question: https://forum.dlang.org/post/edrejkakhaylivlqj...@forum.dlang.org
Re: Passing a reference to a returned reference
On Friday, 6 July 2018 at 15:33:18 UTC, Michael wrote: This is definitely to do with my use of the setter syntax, which maybe I am misunderstanding? Because if I change it to a normal function call like so: a.beliefs(Operator.create()); then it complains if I use ref, and doesn't complain if I don't. You can try removing the "auto" from the Operator class method // Error: returning dict escapes a reference to local variable dict false static ref create() { double[int] dict; dict[2] = 1.0; dict[1] = 0.0; return dict; } That indicates that 'dict' is actually returned by value (at least the reference). This sounds a bit confusing. AFAIK, in above code a reference 'dict' is created pointing towards memory that stores that dictionary entries. The reference itself is a "pointer"(?) which will "die" when running out of the method's scope. This pointer lives on the function's stack. So returning this "pointer" (essentially a value type, e.g. int) will return it by value. You could return a reference like so: class Operator { static double[int] hdict; static this() { hdict[2] = 1.0; hdict[1] = 0.0; } static ref create() { return hdict; } } then a.beliefs(Operator.create()); should work on the "ref" setter.
Re: Passing a reference to a returned reference
On Friday, 6 July 2018 at 15:14:01 UTC, Michael wrote: class Agent { private { double[int] mDict; } // Setter: copy void beliefs(ref double[int] dict) { import std.stdio : writeln; writeln("Setter function."); this.mDict = dict; } // Getter auto ref beliefs() { return this.mDict; } } class Operator { static auto ref create() { double[int] dict; dict[2] = 1.0; dict[1] = 0.0; return dict; } } Throw in a writeln statement in getter and be amazed : D class Agent { private { double[int] mDict; } // Setter: copy void beliefs(ref double[int] dict) { import std.stdio : writeln; writeln("Setter function."); this.mDict = dict; } // Getter auto ref beliefs() { writeln("getter"); return this.mDict; } } class Operator { static auto ref create() { double[int] dict; dict[2] = 1.0; dict[1] = 0.0; return dict; } } unittest { import std.stdio : writeln; Agent a = new Agent(); writeln("Statement 1"); a.beliefs = Operator.create(); writeln("Statement 2"); assert(a.beliefs.keys.length == 2); writeln("Statement 3"); writeln(a.beliefs); } If you remove the ref then "Statement 1" will use the setter method. Otherwise it calls the "auto ref" function to get a reference of 'mDict' and assign it a value. Essentially // Getter auto ref beliefs() { return this.mDict; } makes your "private" variable not private any more, since you are leaking a reference to it. So any program calling "a.beliefs" can get a reference to your private data and modify it. My guess is that (if ref is removed from the setter) it serves as a @property function: https://dlang.org/spec/function.html#property-functions So this allows the function to work in a statement like: a.beliefs = And apparently it is prioritized over the "ref beliefs()" function. I guess it is nicer to actually use the "setter" function, as it allows you to inspect what the private data will be assigned to and take appropriate measures, whereas with the "ref beliefs()" method the private data is open for any manipulation out of your control.
Re: immutable / inout / pure headaches
On Friday, 6 July 2018 at 14:28:39 UTC, Steven Schveighoffer wrote: inout is not a compile-time wildcard, it's a runtime one. So it doesn't know how to convert an immutable to an inout. Essentially, inside this function, the compiler has no idea whether the real thing is an immutable, const, mutable, etc. The fix is simple, replace both your constructors with one inout constructor: this(inout(S) t) inout { this.s = t; } Slowly getting acquainted to inout... Feels like magic. And it will work for everything. One word of caution though -- inout is viral (just like immutable). Everything you use has to support it, or it breaks down. "viral" is very fitting. Throw in pure and I quickly reach the bottom of my program hitting a library function I used which is not pure. I never really used 'pure' and just now found a use case with immutable [1], i.e. to return unique objects from functions which can be assigned to a mutable or immutable reference. What other "use cases" or reasons to use 'pure' are there (aside from compiler optimizations)? [1]: https://forum.dlang.org/post/nmcnuenazaghjlxod...@forum.dlang.org
Re: Passing a reference to a returned reference
On Friday, 6 July 2018 at 13:13:43 UTC, Michael wrote: static auto ref consensus( ... ) `auto ref` infers the return type from the return statement [1]. So it's not necessarily returning a ref type. However, I don't think this matters if the only concern you have is that the setter function actually modifies the passed object. and the agent's setter method looks like the following: void beliefs(ref double[int] beliefs) Now obviously if I remove ref in the above signature, everything works fine, but I am surprised I wasn't getting any kind of warning about the reference because the setter function just doesn't run at all. I tried checking if (beliefs is null) but perhaps this isn't the correct way to check if an associative array's reference is no longer reachable? Some explanation would be great, thanks! This works for me: auto create() { string[int] dict; dict[2] = "hello"; return dict; } void modifyNoRef(string[int] m) { writeln("Address not ref: ", ); m[0] = "modified"; } void modifyRef(ref string[int] m) { writeln("Address ref: ", ); m[1] = "modified"; } unittest { auto r = create(); writeln("Address r: ", ); assert(r.keys.length == 1); modifyNoRef(r); assert(r.keys.length == 2); modifyRef(r); assert(r.keys.length == 3); } So either with ref or not as parameter storage class the assoc. array is modified. Note the address in the "ref" one is the same as "r" in the unittest. [1]: https://dlang.org/spec/function.html#auto-ref-functions
immutable / inout / pure headaches
I dared once again getting into immutable by adding an "immutable" keyword which causes a chain of actions to be taken. I feel like I'm lost in a jungle of immutable, inout and pure (perhaps more will join the party...). To start off, why does this not work? class Test { private S s; this(S t) { this.s = t; } this(immutable S t) immutable { this.s = t; } inout(Test) get() inout { // Error: none of the overloads of __ctor are callable using a inout object, candidates are: //onlineapp.d(10):onlineapp.Test.this(S t) //onlineapp.d(11):onlineapp.Test.this(immutable(S) t) return new inout Test(this.s); } } struct S { int[] a; } void main() { immutable S s = immutable S([1,2,3]); auto t = new immutable Test(s); }
Re: Function Template for Dynamic Parameter
On Thursday, 5 July 2018 at 16:23:36 UTC, vino.B wrote: Hi All, Request your help on the below code auto coCleanFiles(T ...) (T FFs) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(FFs, SpanMode.depth).map!(a => tuple(a.name, a.timeCreated))); return dFiles; } void process(T)(T pfunction, Array!string Dirlst) { alias wlsType = typeof(pfunction(T)); auto Result = taskPool.workerLocalStorage!wlsType(); foreach (FFs; parallel(Dirlst[],1)) { Result.get ~= pfunction(FFs); } foreach(i; Result.toRange) { writeln(i[][]); } } void main() { Array!string Cleanlst; Cleanlst.insert("C:\\Temp\\BACKUP1"); process(, Cleanlst); } Error : Error: coCleanFiles(T...)(T FFs) is not an lvalue and cannot be modified I guess since in above code `coCleanFiles` is a template, you can not simply take the address of that function template. You'd have to instantiate the template first process(!string, ...) If you want to pass the template to process you could define process as something like void process(alias func)(Array!string Dirlst) { func!string(Dirlst[0]); } and call process!coCleanFiles(Cleanlst);
Re: Safe to cast to immutable and return?
On Thursday, 5 July 2018 at 12:15:35 UTC, vit wrote: Try pure functions: class A {} A getA()pure @safe //pure whitout mutable parameters guarantees that function doesn't leak data. { A a; // .. do stuff with a // not leaking a to any functions // is this safe return a; } A getA2(A x)pure @safe //pure with mutable param { A a; // .. do stuff with a // not leaking a to any functions // is this safe return a; } void test()@safe{ immutable(A) a1 = getA();//ok immutable(A) a2 = getA2(null); //ok immutable(A) a3 = getA2(new A); //ok immutable(A) a4 = getA2(a3);//error in theory can leak } Very nice! I assume the @safe is not a must? Good read: https://dlang.org/spec/function.html#pure-functions
Re: 'is(T==return)' How does is expression with return keyword as TypeSpecialization
On Thursday, 5 July 2018 at 10:32:01 UTC, Timoses wrote: int fun(T)(T i) { static assert(is(typeof(return) == T)); //true pragma(msg, is(T == return)); // false static if (is(T ReturnType == return)) pragma(msg, ReturnType); // does not enter return i; } unittest { fun(3); } What's the purpose of 'is(T == return)' if not the above? Found it: http://ddili.org/ders/d.en/is_expr.html Section "is (T identifier == Specifier)" int fun() { return 1337; } template Temp(T) { //pragma(msg, typeof(T)); // is T a function, if so assign its return type to 'retType' static if (is(T retType == return)) { retType Temp(T func) { return func(); } } } void main() { int i = Temp!(typeof())(); assert(i == 1337); } So, 'return' checks if T is a callable and if so assigns its return type to 'identifier'.
Re: 'is(T==return)' How does is expression with return keyword as TypeSpecialization
On Thursday, 5 July 2018 at 11:37:16 UTC, Timoses wrote: I think it refers to this section: https://dlang.org/spec/expression.html#is_expression should mention that I mean the 6th paragraph.
Re: 'is(T==return)' How does is expression with return keyword as TypeSpecialization
On Thursday, 5 July 2018 at 11:21:41 UTC, Alex wrote: On Thursday, 5 July 2018 at 10:32:01 UTC, Timoses wrote: int fun(T)(T i) { static assert(is(typeof(return) == T)); //true pragma(msg, is(T == return)); // false static if (is(T ReturnType == return)) pragma(msg, ReturnType); // does not enter return i; } unittest { fun(3); } What's the purpose of 'is(T == return)' if not the above? I always thought that "return" is a keyword. https://dlang.org/spec/lex.html#keywords And the fact, that you can ask the keyword about its type is just a nice feature... ;) I think it refers to this section: https://dlang.org/spec/expression.html#is_expression I don't remember where I read this usage (think it was in a book), but I noted it down and now I wonder how it can be used.
Safe to cast to immutable and return?
Is this safe? class A {} immutable(A) getA() { A a; // .. do stuff with a // not leaking a to any functions // is this safe return cast(immutable A)a; } What if A is replaced with A[] or A[int]? If it's not safe, what would be the proper way to return an immutable instance from a function which needs to make adjustments to the instance before returning it as immutable?
'is(T==return)' How does is expression with return keyword as TypeSpecialization
int fun(T)(T i) { static assert(is(typeof(return) == T)); //true pragma(msg, is(T == return)); // false static if (is(T ReturnType == return)) pragma(msg, ReturnType); // does not enter return i; } unittest { fun(3); } What's the purpose of 'is(T == return)' if not the above?
Re: ranges.chunks and map! does not work
On Thursday, 5 July 2018 at 09:47:32 UTC, Andre Pany wrote: Hi, the purpose of this code is to generate CSV based on 3 double arrays. I wonder why map cannot directly use the result of the chunks function. import std.experimental.all; void main() { double[] timestamps = [1.1]; double[] temperatures = [2.2]; double[] pressures = [3.3]; string content = roundRobin(timestamps, temperatures, pressures) .chunks(3) //.map!(c => c.array) .map!(c => "%.10g,%.10g,%.10g".format(c[0],c[1],c[2])) .join("\n"); writeln(content); } I always find this kind of confusing as well. What kind of ranges are returned by functions handling ranges and returning another range? It is clear what type of range can be passed by looking at the constraint for chunks[1]: Chunks!Source chunks(Source)(Source source, size_t chunkSize) if (isInputRange!Source); It would be awesome to have something like and output constraint: out(Output; isForwardRange!Output && isInputRange!(ElementType!Output)) or something similar to know what the function will return.. In your case it seems like the typeof(c.front) is not a random access range: auto c = roundRobin(timestamps, temperatures, pressures) .chunks(3); pragma(msg, isRandomAccessRange!(typeof(c.front))); // prints false So you could do auto content = roundRobin(timestamps, temperatures, pressures) .evenChunks(timestamps.length) .map!(c => c.map!(a => format("%.10g", a)) .join(",") ) .join("\n"); although there might be more elegant solutions. [1]: https://dlang.org/phobos/std_range.html#chunks
Re: how to import file from another path in dub ?
On Thursday, 5 July 2018 at 05:38:29 UTC, Flaze07 wrote: I have a dub project, and I put the importPath to the path of the file I want to import and the source file to the source folder, and it appears that I have succeeded at importing the module, but there's one problem, it appears like I need to define some sort of thing, because the error says " Error 42: Symbol Undefined __D9animation12__ModuleInfoZ" ( I am using coedit ), do I need to compile the file into .lib ? You can follow what happens when you do `dub -v`. When using the `importPaths` the compiler will import the path during compilation, but not compile the files in importPath and put it in the object file. The call is something like this: dmd -I Afterwards the linker tries to find the function defined in import path, which however is not found as it was not compiled. My guess is that this could be useful when using something like interface files (in D .di files, or in C/C++ header files) which only has declarations). Then you would have to pass the linker the library or object file which actually contains the compiled functions. Otherwise you get an error like the one you have. Depending on your use case I see these options: - If you have a library that defines the symbols that you are using in the imported files you could use the dub `libs` setting - Otherwise, if you're just using the other folder to separate code you can redefine dub's `sourcePaths`. I believe it overwrites the previous, so you have to include your 'source' folder again: "sourcePaths": ["source", ""] When using sourcePaths, dub actually passes all files within all mentioned paths to dmd to compile. Hope I got it right : D.
Re: Inference of auto storage classes for interface function return type
On Wednesday, 4 July 2018 at 15:12:15 UTC, Jonathan M Davis wrote: You can make opIndex inout instead of const. That way, inout applies to the invisible this reference, just like it would with const. Awww, thanks! I was kinda hovering around this[1] section and didn't quite see the MemberFunctionAttribute list[2]. Is there no further description of the behaviour with the inout attribute other than for parameters[1] in the spec? There's an empty 19.10.10 point without content[3] : D. Maybe a placeholder? [1]: https://dlang.org/spec/function.html#inout-functions [2]: https://dlang.org/spec/function.html#MemberFunctionAttribute [3]: https://dlang.org/spec/function.html#inout-functions
Inference of auto storage classes for interface function return type
How can I return inferred storage class from interface functions? I can't use auto as return value in interface. Neither can I use "inout" as I don't pass a parameter. // Ref Type interface IRef { Ref opIndex(size_t idx) const; } class CRef : IRef { Ref[] a; this() immutable { this.a = [new Ref()]; } Ref opIndex(size_t idx) const { return a[idx]; } // Error: cannot implicitly convert expression this.a[idx] of type const(Ref) to app.Ref } class Ref{} void main() { auto a = new immutable(CRef)(); auto s = a[3]; } For value types it works, I presume since they are passed by value, so the instance returned is an actual copy of the stored value. // Value Type interface IValue { Value opIndex(size_t idx) const; } class CValue : IValue { this() immutable { i = [Value()]; } Value[] i; Value opIndex(size_t idx) const { return i[idx]; } } struct Value{} However, for ref types this doesn't work. Do I have to define two `opIndex` in the interface? One mutable, one for immutable type instances?
Re: template alias that includes a parameter
On Sunday, 1 July 2018 at 13:01:20 UTC, Timoses wrote: Aw, okay, then that won't work. Still, this looks like it should work: void foo(F, T)(T param) { writeln("Called with type: ", T.stringof); } alias tfoo = ApplyLeft!(foo, int); tfoo!string("hi"); // tfoo("hi"); // Error https://issues.dlang.org/show_bug.cgi?id=9365
Re: template alias that includes a parameter
On Sunday, 1 July 2018 at 11:55:15 UTC, Simen Kjærås wrote: On Sunday, 1 July 2018 at 09:46:55 UTC, Timoses wrote: Would be nice if std.meta.ApplyLeft did the job here.. Is there no way of achieving that? [snip] Would have to find a way to determine whether Template would resolve to a function or not. Can't find anything in Traits[1] or std.traits[2]. Template inspection looks rather limited : /. It is, but for a fairly good reason. This is perfectly valid D: template foo(int n) { static if (n == 0) { struct foo {} } else static if (n == 1) { enum foo = 24; } else { void foo() {} } } Given an uninstantiated foo, you can't know if it'll resolve to a function or not, so I guess some version of the template I wrote could be added to Phobos as ApplyLeftFn or something. Aw, okay, then that won't work. Still, this looks like it should work: void foo(F, T)(T param) { writeln("Called with type: ", T.stringof); } alias tfoo = ApplyLeft!(foo, int); tfoo!string("hi"); // tfoo("hi"); // Error
Re: Function Template for Dynamic Parameter
On Sunday, 1 July 2018 at 11:58:30 UTC, vino.B wrote: On Sunday, 1 July 2018 at 11:52:19 UTC, Alex wrote: NewType.d(19): Error: function declaration without return type. (Note that constructors are always named this) [...] auto coCleanFiles(T ...)(T args) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(FFs, SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name, a.timeLastModified))); return dFiles; } void ptManagecoRoutine(T)(T function(T ...)(T args), Array!string Dirlst) { alias scRType = typeof(coRoutine(args.init)); auto PFresult = taskPool.workerLocalStorage!scRType; ReturnType!coRoutine rData; foreach (string FFs; Dirlst[]) { PFresult.get ~= coRoutine(FFs.strip); } foreach(i; PFresult.toRange) { rData ~= i[][]; } if (!rData[].empty) { rData[].sort!((a,b) => a[1] < b[1]).each!(e => writefln!"%-83s %.20s"(e[0], e[1].to!string)); } } void main () { Array!string CleanDirlst; CleanDirlst.insertBack("C:\\Temp\\BACKUP1"); ptManagecoRoutine(, CleanDirlst); } auto coCleanFiles(T ...)(T args) { ... } void ptManagecoRoutine(T)(T fun, Array!string DirList) { foreach (dir; DirList) fun(dir); } or void ptManagecoRoutine2(alias func)(Array!string DirList) if (is (typeof(func!(typeof(DirList[0]))) == function)) { alias t = typeof(DirList[0]); ptManagecoRoutine(!t, DirList); } callable via Array!string CleanDirlst; ptManagecoRoutine(!string, CleanDirlst); ptManagecoRoutine2!coCleanFiles(CleanDirlst);
Re: Function Template for Dynamic Parameter
On Sunday, 1 July 2018 at 11:19:50 UTC, vino.B wrote: On Sunday, 1 July 2018 at 09:55:34 UTC, Timoses wrote:> Hi Timoses, Thank you very much, can you help me on how to rewrite the below using Variadic template Passing function as a parameter to another function: void ptFun(T)(T function(string, string, int) coRoutine, Array!string Dirlst, ) { alias scRType = typeof(coRoutine(string.init, string.init, int.init)); where the "function(string, string, int) coRoutine" should be a variadic function What's your use case? You can pretty much pass anything to a template and use "static if" and "static foreach" in the template to steer how the template is instantiated. void func(T ...)(T args) { foreach (i, arg; args) { static if (isSomeFunction!(T[i])) { arg(); } else writeln(arg); } } unittest { func(() => writeln("I'm a lambda function), "I'm a string", 3); } which would print: I'm a lambda function I'm a string 3 I'm actually a bit suprised that `isSomeFunction!(T[i])` works here, I'd expect an error because `i` looks like a run-time variable... And using that in a compile-time (static if) statement usually throws a CT error. With templates one has to think "compile-time". Any "static if", "static foreach" or alias declarations are compile time constructs. What results from that after compilation is an instantiated template for a specific use case. For example in above case the template exists (is instantiated) with the template parameters `(void function() @safe, string, int)`. A good source to get some more insights is always: http://ddili.org/ders/d.en/templates.html (including all other sections of the book)
Re: Function Template for Dynamic Parameter
On Sunday, 1 July 2018 at 09:46:32 UTC, vino.B wrote: All, Request your help, the D document states that "Template functions are useful for avoiding code duplication - instead of writing several copies of a function, each with a different parameter type, a single function template can be sufficient" which mean we can passing any type of parameter using function template, similarly who we we pass in any number of parameter of any type(dynamic parameters) , like in python Python def myfunc(*arg) def myfunc(**kwargs) // multiple key-value def myfunc(*args, **kwargs): mix Do we have any thing similar to the above python in D void (func(T)( T *args) // Example Examples: void func(T)(T x) { writeln(x); } void main() { func("x"); // pass a string } void func(T)(T n3) { writeln(n); // where n = 3 parameters (1, string, char) } void func(T)(T n2) { writeln(n); // where n = 3 parameters (1, string) } void func(T)(T n1) { writeln(n); // where n = 3 parameters (1 or string or char) } From, Vino.B Perhaps https://dlang.org/spec/template.html#variadic-templates void func(T ...)(T args) { static assert(T.length <= 3); static assert(is(T[0] == int)); // 1 pragma(msg, T.stringof); foreach (arg; args) { writeln(arg); } } void main() { func(3, "s", 1.3); //func(1.3); // error, first argument is not an int, see // 1 }
Re: template alias that includes a parameter
On Sunday, 1 July 2018 at 01:48:15 UTC, Simen Kjærås wrote: I'd send you straight to std.meta.ApplyLeft, but it seems to do the wrong thing here, in that it doesn't handle IFTI. This thing does: void fooImpl(int n, T)(const T line) { } unittest { alias fun = applyLeft!(fooImpl, 3); fun(`aaa`); applyLeft!(fooImpl, 3)(`aaa`); } template applyLeft(alias Fn, T...) { auto applyLeft(U...)(U args) { return Fn!T(args); } } Would be nice if std.meta.ApplyLeft did the job here.. Is there no way of achieving that? It's current implementation looks like this: template ApplyLeft(alias Template, args...) { alias ApplyLeft(right...) = SmartAlias!(Template!(args, right)); } private template SmartAlias(T...) { static if (T.length == 1) { alias SmartAlias = Alias!T; } else { alias SmartAlias = AliasSeq!T; } } Would have to find a way to determine whether Template would resolve to a function or not. Can't find anything in Traits[1] or std.traits[2]. Template inspection looks rather limited : /. [1]: https://dlang.org/spec/traits.html [2]: https://dlang.org/phobos/std_traits.html
Re: Call different member functions on object sequence with a generic handler function?
On Sunday, 1 July 2018 at 06:55:35 UTC, Robert M. Münch wrote: The looping needs to be done in the handler because there are two loops running one after the other and the range to loop over is detected in the handler too. Otherwise a lot of code duplication would happen. Maybe an application for filter? C[] cs = ...; cs.filter!((c) => ) .each!((c) => c.a())
Re: template alias that includes a parameter
On Saturday, 30 June 2018 at 21:11:54 UTC, Anonymouse wrote: I have a template that I want to provide easy aliases for, where the aliases includes (partially applies?) a template parameter. void fooImpl(char token, T)(const T line) { // ... } alias quoteFoo(T) = fooImpl!('"', T); would be the same as template quoteFoo(T) { alias quoteFoo = fooImpl!('"', T); } There is no "Implicit Function Template Instantiation (IFTI)" (https://dlang.org/spec/template.html#function-templates) here, as that only works for function templates. That means the compiler won't deduce the template parameter type. So that alias would have to be called with quoteFoo!string("I'm a quoted sentence."); alias singlequoteFoo(T) = fooImpl!('\'', T); void main() { quoteFoo(`"asdf"`); singlequoteFoo(`'asdf'`); } ...was how I'd imagined it would look. onlineapp.d(11): Error: template onlineapp.quoteFoo cannot deduce function from argument types !()(string), candidates are: onlineapp.d(6):onlineapp.quoteFoo(T) If I manually pass string as a template parameter, like quoteFoo!string("bar") or singlequoteFoo!string("baz"), it works. Can I do it this way or do I need to write wrapping functions? Instead of using aliases you could instantiate the function and use a function pointer to it (I hope my lingo is correct...). auto quoteFooString = !('"', string); and use it with quoteFooString("I'm another quoted sentence."); I'm trying to find a way to partially apply something to the template like //alias quoteFoo = ApplyLeft!(fooImpl, '"', AliasSeq!(int)); //quoteFoo(3); so the template fooImpl would only be partly instantiated with a '"', but the second argument would be left for when calling the function.. Unfortunately, above yields the error std/meta.d(1232): Error: template instance `Template!'"'` does not match template declaration fooImpl(char token, T)(const T line) ... Hm.. https://run.dlang.io/is/di8zjl import std.stdio; void fooImpl(char token, T)(const T line) { writefln("%s%s%s", token, line, token); } auto quoteFooString = !('"', string); auto singlequoteFooString = !('\'', string); void main() { quoteFooString("test quote"); singlequoteFooString("test single quote"); import std.meta; // std/meta.d(1232): Error: template instance `Template!'"'` does not match template //alias quoteFoo = ApplyLeft!(fooImpl, '"'); //quoteFoo(3); }
Re: Call different member functions on object sequence with a generic handler function?
On Friday, 29 June 2018 at 20:28:55 UTC, Timoses wrote: On Friday, 29 June 2018 at 16:44:36 UTC, Robert M. Münch wrote: Trying to fiddle around a bit with delegates.. But why is the context for delegates not working for classes?? Aw.. Class = reference type so class A { } struct B { } void delegate() del; A a = new A(); del.ptr = a; // NOT its address, as that would be the address of the reference on the stack B b = B(); del.ptr =// value type => address of object in stack ... How would one print the address of the object then though? Since is the address of the reference' types stack location. cast(void*)a would be on solution I guess.
Re: Call different member functions on object sequence with a generic handler function?
On Friday, 29 June 2018 at 16:44:36 UTC, Robert M. Münch wrote: I hope this is understandable... I have: class C { void A(); void B(); void C(); } I'm iterating over a set of objects of class C like: foreach(obj; my_selected_objs){ ... } The iteration and code before/afterwards always looks the same, I need this iteration for many of the memember functions like C.A() and C.B(), etc. foreach(obj; my_selected_objs){ ... obj.A|B|C() ... } So, how can I write a generic handler that does the iteration, where I can specify which member function to call? void do_A() { handler(C.A()); ??? } void do_B() { handler(C.B()); ??? } handler(???){ foreach(obj: my_selected_objs){ ??? } } Viele Grüsse. Trying to fiddle around a bit with delegates.. But why is the context for delegates not working for classes?? https://run.dlang.io/is/Rxeukg import std.stdio; class Aclass { int i; void foo() { writeln("called ", i); } } struct Bstruct { int i; void foo() { writeln("called ", i); } } template callFoo(T) { alias Dun = void delegate(); void callFoo(T t) { Dun fun; fun.funcptr = fun.ptr = cast(void*)(); Dun gun; gun = writeln(fun.ptr, " (fun.ptr of " ~ T.stringof ~ ")"); writeln(gun.ptr, " (gun.ptr of " ~ T.stringof ~ ")"); writeln(, " (Address of instance (context))"); fun(); gun(); } } void main() { auto a = new Aclass(); a.i = 5; auto b = Bstruct(); b.i = 7; writeln(" Doesn't work "); callFoo(a); writeln("\n Works "); callFoo(b); }
Re: Call different member functions on object sequence with a generic handler function?
On Friday, 29 June 2018 at 20:08:56 UTC, Robert M. Münch wrote: On 2018-06-29 18:05:00 +, Ali ‡ehreli said: On 06/29/2018 09:44 AM, Robert M. Münch wrote: void handler(alias func)(C[] cs) { foreach (c; cs) { func(c); } } Is it possible to make C[] a template type so that I can use different classes and lambdas? My guess would be: void handler(alias func, T)(T[] ts) { } Ok, the "strange" syntax for me is the handler(alias func) or handler(string func) ... I'm alway thinkin in lines of a parameter... which of course doesn't work. Looking at the D grammer for functions these things should be the FuncDeclaratorSuffix, is this right? And then, which part does this fall into? FuncDeclaratorSuffix: Parameters MemberFunctionAttributesopt TemplateParameters Parameters MemberFunctionAttributesop It's definitely the "TemplateParameters" one: void func()() { ... } is the short form of template() { void func() { ... } } https://dlang.org/spec/template.html
Re: Issues with undefined symbols when using Vibe on Windows
On Friday, 29 June 2018 at 19:25:42 UTC, Chris M. wrote: This doesn't appear to specifically be a Vibe issue, just noticing this error when I use eventcore from it (trying to use async). C:\dmd2\windows\bin\lld-link.exe: warning: eventcore.lib(sockets_101f_952.obj): undefined symbol: SetWindowLongPtrA C:\dmd2\windows\bin\lld-link.exe: warning: eventcore.lib(sockets_101f_952.obj): undefined symbol: GetWindowLongPtrA I'm using DMD 2.080 from the zip file provided on the downloads page, plus DMC (unfortunately acquiring a Visual Studio license would not be easy at my workplace, and I don't see how to use the provided DMD installer without it). As far as I can tell, this issue seems to be happening because user32.lib from the windows/lib64/mingw folder does not define these two functions. Seems to work when I build the project as 32-bit though. Wondering if someone could double-check my reasoning here. Did you see this? https://github.com/vibe-d/vibe.d#note-for-building-on-win64 Perhaps it could be that?
Re: Why tuples are not ranges?
On Thursday, 28 June 2018 at 14:35:33 UTC, Mr.Bingo wrote: Seems like it would unify things quite a bit. import std.typecons, std.range, std.array, std.algorithm, std.stdio; void main() { auto t = tuple(3,4,5,6); //auto t = [3,4,5,6]; writeln(t.map!(a => 3*a).sum()); } You could make a range out of tuples. This seems to work: import std.typecons, std.range, std.array, std.algorithm, std.stdio; void main() { auto t = tuple(3,4,5,6); auto m = t.expand.only; writeln(m.map!(a => 3*a).sum()); } Tuple.expand will expand the elements when calling a function (in this case only from std.range). https://dlang.org/library/std/typecons/tuple.expand.html
Re: Getting Source code from complied code.
On Thursday, 28 June 2018 at 08:01:42 UTC, vino.B wrote: Hi All, Request your help on how to get the source code, i wrote a program named clean.d, complied it and by mistake deleted the source code(clean.d), so can we get back the source using the complied program(clean), if yes, can you any one help on the same. From, Vino.B Use a versioning system and push important changes as soon as you're done with smth to a remote location ; ). E.g. Git
Re: anyway to pass the context of an inner type to a template so it can be constructed?
On Wednesday, 27 June 2018 at 12:02:10 UTC, aliak wrote: This currently fails unless you mark the class as static: auto construct(T)() { return new T; } void main() { class C {} auto s = construct!C; } So wondering if there's anything that can be done to get the above working? Or if there isn't then how could the compiler be enhanced to allow for something like this if possible? === The use case is for a non-nullable type, where I want to guarantee that the value inside will never be null. I can't do it for inner classes though. And I can't allow the user to do something like: void main() { class C {} auto s = construct(new C); } Because I can't guarantee that's not null. Cheers, - Ali After a bit of experimentation import std.stdio; template construct1(T) { enum construct1 = "new " ~ T.stringof; } template construct2(T) { // Attempt 1 // can't do this : / //alias construct2 = mixin(construct1!T); // Attempt 2 T construct2() { // Error: outer function context of D main is needed to new nested class onlineapp.main.C //return new T; // Error: undefined identifier C //mixin("return new " ~ T.stringof ~ ";"); return null; // ... } } mixin template construct3(string s, T) { mixin("auto " ~ s ~ " = new " ~ T.stringof ~ ";"); } void main() { class C { int i = 4;} auto a = mixin(construct1!C); assert(a.i == 4); mixin construct3!("b", C); b.i = 3; assert(b.i == 3); // trying to get around using mixin here... auto c = construct2!C; } Can't seem to avoid using mixin in main..
Re: Making sense of recursion
On Monday, 25 June 2018 at 17:45:01 UTC, zbr wrote: Hi, this question is not specifically D related but I'll just ask anyway. Consider the following snippet: void mergeSort(int[] arr, int l, int r) { if (l < r) // 1 { int m = l+(r-l)/2;// 2 mergeSort(arr, l, m); // 3 mergeSort(arr, m+1, r); // 4 merge(arr, l, m, r); // 5 }// 6 } // 7 mergeSort(arr, 0, 4); When I see this, I visualize the recursion to perform this way: mergeSort(arr, 0, 4): 0 < 4 ? true: mergeSort(0, 2): 0 < 2 ? true: mergeSort(0, 1): 0 < 1 ? true: mergeSort(0, 0): 0 < 0 ? false: //reach the end of mergeSort / reach line 6 and then 7 I don't see the computer ever reaching line 4 and 5? Obviously I'm wrong but where is my mistake? Thanks. It's a stack (https://en.wikipedia.org/wiki/Call_stack). When the program calls a function it is pushed onto the stack. If that function returns it pops from the stack and the previous function gets to continue execution from where it stopped before.
Re: Using systemDependencies in DUB
On Sunday, 24 June 2018 at 11:44:06 UTC, Dechcaudron wrote: Hi, I'm trying to use dub to compile a quick experiment that uses Deimos libclang bindings, which of course requires linking against an installed libclang. I believe this is what I need to include in dub.json: "systemDependencies": "libclang-6.0" But it just won't link against the lib in the compilation process. Using the -v option reveals the linking stage call: /usr/bin/dmd -of.dub/build/application-debug-linux.posix-x86_64-dmd_2081-7C29937BC9011750CFA15D7325224156/damnc .dub/build/application-debug-linux.posix-x86_64-dmd_2081-7C29937BC9011750CFA15D7325224156/damnc.o -L--no-as-needed -g It does not mention libclang at all. I've tried with all "clang", "libclang-6.0.so.1", but I just don't seem to be able to make it work. Would anyone mind helping me out? BTW, I am aware Deimos bindings for libclang are based on v3.7 and not 6.0, but 3.7 is not available for Ubuntu 18.04 and I was wagering the interface probably hasn't changed much. Hm, the description sounds like it might not be used for passing linker arguments, but serves for adding documentation to linker errors: "A textual description of the required system dependencies (external C libraries) required by the package. This will be visible on the registry and will be displayed in case of linker errors - this setting does not support platform suffixes". What about the "libs" build settings (or "lflags")? (http://code.dlang.org/package-format?lang=json) "libs": "clang"
Re: Can I parse this kind of HTML with arsd.dom module?
On Sunday, 24 June 2018 at 03:46:09 UTC, Dr.No wrote: string html = get(page, client).text; auto document = new Document(); document.parseGarbage(html); Element attEle = document.querySelector("span[id=link2]"); Element aEle = attEle.querySelector("a"); string link = aEle.href; // <-- if the href contains space, it return "href" rather the link [...] Hello, dear world! https://hostname.com/?file=foo.png=baa;>G! missing Seems to be buggy, the parsed document part refering to "a" looks like this: G!
Re: Is HibernateD dead?
On Thursday, 3 May 2018 at 10:27:47 UTC, Pasqui23 wrote: Last commit on https://github.com/buggins/hibernated was almost a year ago So what is the status of HibernateD?Should I use it if I need an ORM? Or would I risk unpatched security risks? Okay... wall of text. TLDR: project definition / future of HibernateD?; prospects of an OGM layer integration (personally interested in Neo4j)? I've been thinking of trying to implement an OGM (Object-graph mapping; i.e. NoSQL) for Neo4j in D as I'd love using it for a project of mine. The question is, whether it should be a separate project or whether something like this could be integrated with HibernateD. I've taken a look at Hibernate ORM and OGM. There OGM is a separate project leveraging a lot of ORMs capabilities. I'm still in the process of diving deeper into Hibernate's ORM/OGM documentation(/implementation) to get an idea of how it all works. I'm not particularly experienced with it. One question that arises in respect to HibernateD is: What is the purpose of HibernateD? The README states "HibernateD is ORM for D language (similar to Hibernate)". I guess there are two Extremes: A. Replicate the structure of Hibernate into D, in a way porting it 1:1, B. Implement an ORM from scratch. Both approaches would be impractical for the following reasons: contra A. An exact replica would leave no room for optimizations or creating a more D-idiomatic library, contra B. Creating a completely new solution and interface would miss out on leveraging what Hibernate already "knows". Further, Hibernate users might love seeing a familiar interface they can work with. Option B wouldn't deserve the name "HibernateD".. This solely highlights that the project's purpose/description might need some more explanation. A small look into the code reveals that the approach leans towards implementing the component structure of Hibernate (such as dialects, a Hibernate(D) basic type system, ...). I'd guess this would be the most practical approach: Leverage Hibernate's insights into what components are required to implement an ORM(/OGM) (Dialects, Hibernate(D) types, annotations, Persistence Strategies, ...) and find D-idiomatic ways for implementation. Any space for optimization should naturally be capitalized on. A complete 1:1 replica does not seem practical as for example I've stumbled across the "@Immutable" annotation in the Hibernate documentation. As there is the "immutable" qualifier in D, through introspection, this quality could be deduced from entities/members. This leads to thinking that solutions tailored towards D need to be found and therefore deviation from Hibernate sounds reasonable. I am in no way an expert in ORMs (I just started reading Hibernate's ORM documentation) and I have no idea what other ORMs are out there (D or non-D). However, Hibernate seems quite popular (and it offers a Neo4j OGM interface) and the fact that it exists for D (at least in a "starting positition") caught my attention. What do you think? Especially bauss, Matthias and singingbush, as you seem motivated to move the project forward. Maybe Vadim also has a standpoint : ).
Re: Convert path to file system path on windows
On Thursday, 21 June 2018 at 18:46:05 UTC, Dr.No wrote: How can I do that with D? In C# you can do that: var filename = @"C:\path\to\my\file.txt"; var file = new Uri(filename).AbsoluteUri; // file is "file:///C:/path/to/my/file.txt" How can I do that in D? I don't know of a specific implementation that does the same, but I can point you to some spots you might look into: std.path: https://dlang.org/phobos/std_path.html std.uri: https://dlang.org/phobos/std_uri.html vibe.inet.url: http://vibed.org/api/vibe.inet.url/URL vibe.core.path: http://vibed.org/api/vibe.core.path/ I really feel like vibed's documentation api site is missing some nice examples of usage to get a quick feel of the provided api.
Re: scope(success) lowered to try-catch ?
On Sunday, 17 June 2018 at 10:58:29 UTC, Cauterite wrote: Hello, I'm not sure whether I'm missing something obvious here, but is there a reason for scope(success) being lowered to a try-catch statement? I would have expected only scope(exit) and scope(failure) to actually interact with exception handling, while scope(success) simply places code on the path of normal control flow. Example (windows x32): --- // main.d void main() { scope(success) {} } dmd -betterC main.d Error: Cannot use try-catch statements with -betterC --- Regardless of whether -betterC is used, you can see in the disassembly that having a scope(success) anywhere in the function causes the SEH prologue to be emitted in the code. Is there a reason scope(success) needs to set up for exception handling? Or is this a bug / potential enhancement ? In Andrei's book 'The D Programming Language' the following is written: { scope(success) } is lowered to { bool __succeeded = true; try { } catch(Exception e) { __succeeded = false; throw e; } finally { if (__succeeded) // vice-versa for scope(failure): `if (!__succeeded) ...` } } If it weren't and it would simply be integrated one would have to write potentiallyThrowingFunc(); scope(success) {...}; I suppose? And this seems like breaking how scope works with failure and exit?!
Re: foreach DFS/BFS for tree data-structure?
On Thursday, 14 June 2018 at 11:31:50 UTC, Robert M. Münch wrote: I have a simple tree C data-structure that looks like this: node { node parent: vector[node] children; } I would like to create two foreach algorthims, one follwing the breadth first search pattern and one the depth first search pattern. Is this possible? I read about Inputranges, took a look at the RBTree code etc. but don't relly know/understand where to start. What I found really interesting when reading Ali Çehreli's book 'Programming in D' was using fibers for tree iteration. Check out http://ddili.org/ders/d.en/fibers.html and skip to the section "Fibers in range implementations"