Re: Obtaining argument names in (variadic) functions
On Thursday, 17 March 2016 at 14:12:38 UTC, Edwin van Leeuwen wrote: On Thursday, 17 March 2016 at 13:53:00 UTC, JR wrote: Interesting, any idea if it is possible to do assignment within template.. Either: printVars!(int abc=5,string def="58")(); or something like printVars!("abc","def",ghi)(5,"58"); What would the use-cases for those be? I don't think the first is valid grammar, and I'm not sure what you want the second to do. Resolve symbols by string literals of their names? That might need a string mixin as they wouldn't be in scope when in the called template function, but I've never tried it. Both use cases are when you want a named parameter, without having to assign it first. I know the first is not valid grammar, was just wondering if you might be smarter than me and see a way to make it valid :) Second one is another possible alternative that I have been thinking about. Basically, say I want to have the named (optional) parameters x and y. In your initial example I would be required to do: ``` int x = 1; string y = "2"; doSomethingWithNamedPars!(x,y)(); ``` I just hoped to shorten that to a one liner similar to: ``` doSomethingWithNamedPars!(x=1,y="2")(); ``` or alternatively ``` doSomethingWithNamedPars!("x","y")(1,"2"); ``` (where doSomethingWithNamedPars's behaviour depends on which named parameters it is passed) Just as a reference, my current approach (in ggplotd) is with named tuples, but that is slightly more verbose than I had hoped: ``` doSomethingWithNamedPars( Tuple!(int, "x", string, "y")( 1, 2 ) ); ``` http://dpaste.dzfl.pl/1625122e4f01 is the best I can do, and it's ugly. It's something akin to your doSomethingWithNamedPars!("x","y")(1,"2"). I may even have missed the point. It *neccessitates* that the called function knows the parameter names, because they're not self-documented in the signature. It will also have to deal with any missing ones to actually compile. I'm not sure how to do this and still enjoy things like const and ref and friends. I imagine there *might* be a way to do this with normal non-templated functions given a similar wrapper, if the functions are annotated so that it can get the names of the parameters. It feels like you should be able to get it to naïvely reorder the arguments, default-initialise any missing ones, etc. But you quickly run into "xyz cannot be read at compile-time", even when it feels like everything should be known.
Re: No property error message
On Saturday, 19 March 2016 at 18:36:10 UTC, ric maicle wrote: I got an error message with the following code saying: Error: no property 'length' for type 'int[string]' Shouldn't the error message say 'length()'? ~~~ import std.stdio; void main() { int[string] a; a["one"] = 1; a["two"] = 2; a["three"] = 3; auto len = a.length(); } ~~~ DMD 2.070.2 Well, if we think of it as separate steps, resolving the function "length" is what's failing here. The subsequent () would just call it, if it existed, but the name of the property/symbol would still be "length". But yes; you could make a case that, in the case of invalid function calls, it should include the whole erroneous attempted function signature in the error message. I can imagine it becoming ambiguous once templates enter the picture however, and for not much gain.
Re: How do I extend an enum?
On Saturday, 19 March 2016 at 17:41:29 UTC, Lass Safin wrote: On Saturday, 19 March 2016 at 17:40:27 UTC, Lass Safin wrote: Why: enum Base { A, B, } enum Derived : Base { C, // Gives error, says it can't implicitly convert expression to Base. D = 1, // Same error E = cast(Base)294, // Finally works. Can only be cast(Derived) instead. } void func(Derived d) {} func(Derived.E); // works. func(Derived.A); // Gives error, says it can't call function with Base.A. func(cast(Derived)Derived.A); // Works. So, what's the proper way of extending an enum? Meant "Can also be cast(Derived) instead." "enum B : A" doesn't mean "B extends A", but rather "enum B containing members of type A". Not specifying a type makes it implicitly convertible to int, I think. If you're looking to extend a named enum, I think you have to create a new one. It will become a new type too, though that might not matter. enum Foo { first=123, second=456, third=789 } // int type inferred enum Bar : int { // the ": int" here is important first = Foo.first, // implicit cast to int second = Foo.second, third = Foo.third, fourth = 42, fifth = 0 } If you don't define Bar as having members of type int, it will guess that you want Foo (because we're assigning members with values of Foo's). They would be limited to the range of values Foo offers, and Bar.fourth = 42 is irreconcilabe with that.
Re: Obtaining argument names in (variadic) functions
On Thursday, 17 March 2016 at 11:52:13 UTC, Edwin van Leeuwen wrote: On Wednesday, 16 March 2016 at 20:53:42 UTC, JR wrote: void printVars(Args...)() if (Args.length > 0) { import std.stdio : writefln; foreach (i, arg; Args) { writefln("%s\t%s:\t%s", typeof(Args[i]).stringof, Args[i].stringof, arg); } } void main() { int abc = 3; string def = "58"; float ghi = 3.14f; double jkl = 3.14; printVars!(abc,def,ghi,jkl)(); } Interesting, any idea if it is possible to do assignment within template.. Either: printVars!(int abc=5,string def="58")(); or something like printVars!("abc","def",ghi)(5,"58"); What would the use-cases for those be? I don't think the first is valid grammar, and I'm not sure what you want the second to do. Resolve symbols by string literals of their names? That might need a string mixin as they wouldn't be in scope when in the called template function, but I've never tried it. You *can* cook up something that modifies the values of variables you pass in -- like modifyVars!(abc,def,ghi)("asdf", 123, 3.14) -- but you just might be better off with runtime ref parameters then.
Re: Obtaining argument names in (variadic) functions
On Wednesday, 16 March 2016 at 20:24:38 UTC, data pulverizer wrote: Hi D gurus, is there a way to obtain parameter names within the function body? I am particularly interested in variadic functions. Something like: void myfun(T...)(T x){ foreach(i, arg; x) writeln(i, " : ", arg); } void main(){ myfun(a = 2, b = "two", c = 2.0); } // should print a : 2 b : two c : 2.0 Thanks in advance Loving the mixins and tuples You can do it precisely like that if the variables/symbols you pass as (template) arguments are properly declared first. http://dpaste.dzfl.pl/0b452efeaaab void printVars(Args...)() if (Args.length > 0) { import std.stdio : writefln; foreach (i, arg; Args) { writefln("%s\t%s:\t%s", typeof(Args[i]).stringof, Args[i].stringof, arg); } } void main() { int abc = 3; string def = "58"; float ghi = 3.14f; double jkl = 3.14; printVars!(abc,def,ghi,jkl)(); }
Re: Obtaining argument names in (variadic) functions
On Wednesday, 16 March 2016 at 20:43:09 UTC, jkpl wrote: I try to anticipate the reason why you want this. [...] I use something *kinda* sort of similar in my toy project to print all fields of a struct, for debugging purposes when stuff goes wrong. Getting the names of the member variables is crucial then. http://dpaste.dzfl.pl/748c4dd97de6
Re: How to return a const handle (view) to a mutable member of an agregate
On Sunday, 13 March 2016 at 20:13:03 UTC, Basile B. wrote: On Sunday, 13 March 2016 at 20:10:57 UTC, Basile B. wrote: [...] Basile beat me to it. Yes, ref const(Array!T) accessor. http://dpaste.dzfl.pl/cb2bc5cf9917
Re: efficient and safe way to iterate on associative array?
On Friday, 4 March 2016 at 14:16:55 UTC, Minas Mina wrote: On Friday, 4 March 2016 at 13:53:22 UTC, aki wrote: I think what you can do is extract its contents to an array, iterate it and modify it as you like, and then insert back to another associative array. I don't think it's efficient but I don't know if it's possible to do something else. You can populate an array of key values (here string, so string[]) of the entries to delete, then iterate through it afterwards and call .remove to clean up. http://dpaste.dzfl.pl/b63a8e8e5c3b
New forum mobile appearance feedback
Unsure where else to post this, since it feels like it would intrude on the more serious discussions in the main D forum. The new forum design is overall great, but it really doesn't work well on mobile devices. Coupled with field padding the font is simply too large. (This holds for the normal desktop too, to a certain subjective extent.) http://i.imgur.com/6U5gTfE.png Although the screenshot is of Firefox, which is fairly feature-complete in this context, the native browser on this Jolla phone doesn't have an "enable desktop view" to fake a larger, zoomable resolution. I don't see an option to force this in the forum settings either.
Re: alias butAtLeast = max; 5.butAtLeast(6);
On Saturday, 12 December 2015 at 12:43:36 UTC, SimonN wrote: DMD v2.069.2-b1 on Linux. import std.algorithm; int a = max(5, 6);// works, a == 6 int b = max!(int, int)(5, 6); // works, manual instantiation int c = 5.max(6); // works, UFCS call I would like to use the last syntax, but with an alias. alias butAtLeast = max; // works int d = butAtLeast(5, 6); // works int e = 5.butAtLeast(6); // error: no property 'butAtLeast' for type 'int' Aliasing the instantiated function 'max!(int, int)' instead of aliasing 'max' doesn't help: The 'int e' line will fail with the exact same error. Can I get the alias to work somehow in an UFCS chain? -- Simon By putting it in the top level. I believe this is intentional but I don't remember the reasoning.
Re: benchmark on binary trees
On Friday, 4 December 2015 at 14:06:26 UTC, Alex wrote: [...] hoping it would be faster. This was not the case. Why? [...] Is there anything else to improve performance significantly? Profile. Profile profile profile. Callgrind. Find bottlenecks instead of guessing them.
Re: Help with Concurrency
On Tuesday, 3 November 2015 at 23:16:59 UTC, bertg wrote: Running the following code I get 3 different tid's, multiple "sock in" messages printed, but no receives. I am supposed to get a "received!" for each "sock in", but I am getting hung up on "receiving...". [...] while (true) { writeln("receiving..."); std.concurrency.receive( (string msg) { writeln("conn: received ws message: " ~ msg); } ); writeln("received!"); } Unless I'm reading it wrong, you want std.concurrency.receiveTimeout. import core.time; import std.concurrency; bool received = receiveTimeout(1.seconds, // negative makes it not wait at all (string msg) { writeln("conn: received ws message: " ~ msg); }); if (received) { writeln("received!"); } else { writeln("timed out..."); // stuff? } } Tries to receive but will give up if no matches arrive within duration. Won't wait at all if provided core.time.Duration is negative.
Re: Help with Concurrency
On Wednesday, 4 November 2015 at 16:49:59 UTC, JR wrote: [...] And my indentation and brace-balancing there is wrong. Shows how dependent I've become on syntax highlighting. import core.time; import std.concurrency; bool received = receiveTimeout(1.seconds, writeln("conn: received ws message: " ~ msg); } ); if (received) { writeln("received!"); } else { writeln("timed out..."); // stuff? }
writefln patterns with mismatching compile-time known number of arguments
I was chatting with a friend and showed him how printf(%s) printed random memory in C, whereas writefln(%s) in D threw an Exception upon execution. It's probably not a completely fair comparison but that's a different topic. I admit to being confused as to why it passed compilation at all in the first place. Surely the %s literal is just as known at compilation as an enum would be. Is there any button in D that could be leveraged to statically assert that the number of arguments precisely match the number of format specifiers, iff the pattern is static/enum/literal? I asked in #d and had it pointed out that this could be solved via an overload of writefln that took the pattern as a template instantiation argument, to which I conceed. The main con would naturally be that you end up with template bloat. You could also have tooling (dfix/dscanner) handle it for you. But the compiler has all the pieces of information needed to see it's wrong, doesn't it? How much of this kind of thing is evaluated during the CTFE passes?
Re: printing array of strings with writefln?
On Sunday, 16 November 2014 at 14:16:55 UTC, Artem Tarasov wrote: writefln(%(%s-%), [a, b, c]) doesn't print the intended a-b-c but surrounds each string with double quotes - a-b-c, which I find inconsistent with the fact that writefln(%s, a string) prints the string without any quotes. How do I get the desired behaviour using just the format string? writefln(%-(%s-%), [a, b, c]) http://ddili.org/ders/d.en/formatted_output.html
Re: how to call class' template constructor
On Sunday, 12 October 2014 at 19:46:41 UTC, ketmar via Digitalmars-d-learn wrote: Hello. please, how to call template constructor of a class? it's completely escaped my mind. i.e. i have this class: class A { this(alias ent) (string name) { ... } } and i want to do: void foo () { ... } auto a = new A!foo(xFn); Template the whole class? class A(alias ent)?
Re: Template instantiation and string vs const char[]
On Wednesday, 3 September 2014 at 05:18:42 UTC, Jason den Dulk wrote: [...] While not really answering your question, I believe the idiomatic way is to use enum here instead of string/char[]. Conjecture: strings are final but the symbol can be redirected to point to new arrays, such as results of concatenations. Concatenations create new and unique arrays upon each operation as each by definition cannot be altered. char[] can be *appended* to, technically retaining the same array and merely reallocating (potentially moving) to fit the extra content. This sounds like something the compiler should be able to work around but apparently it doesn't. Also, note that your check of (R.length) will only evaluate to false if the template is instantiated as somet!().
Appender.put return value
Is there a big reason why Appender.put doesn't return this? http://dpaste.dzfl.pl/bb840e3e349e It would allow for convenient chaining. :
Re: Insert a char in string
On Thursday, 10 July 2014 at 19:33:15 UTC, simendsjo wrote: On 07/10/2014 06:05 PM, Alexandre wrote: I have a string X and I need to insert a char in that string... auto X = 100; And I need to inser a ',' in position 3 of this string..., I try to use the array.insertInPlace, but, not work... I try this: auto X = 100; auto N = X.insertInPlace(1,'0'); Do you really want to insert a comma in the string, or do you want to format a number as 100,000,000,000.00? For that, one approach would be as in http://dpaste.dzfl.pl/bddb71eb75bb.
Re: Opinions: The Best and Worst of D (for a lecture/talk I intend to give)
On Monday, 7 July 2014 at 23:47:26 UTC, Aerolite wrote: So, if you would be so kind, give me a bullet list of the aspects of D you believe to be good, awesome, bad, and/or ugly. If you have the time, some code examples wouldn't go amiss either! Try not to go in-depth to weird edge cases - remain general, yet informative. E.g. I consider D's string mixins to be in the 'awesome' category, but its reliance on the GC for large segments of the standard library to be in the 'ugly' category. I'm a big fan of (templated) UFCS. Along with parameterless function calls it goes a long way toward improving readability with its pipe-like flow. And like with all templates, allowing for breaking out common functionality *without* resorting to inheritance. Templates overall are sexy. void main() { import std.stdio; import std.conv; import std.string; import std.range; import core.thread; // values known at compile-time -- CTFE kicks in~ static assert(12345.to!string == 12345); immutable period = 1.seconds + 100.msecs + 100.usecs; writeln(period); Thread.sleep(period); immutable line = fedcba .retro .to!string .toUpper; // wish this worked: typeof(line).is!string; static assert(is(typeof(line) : string)); static assert(line == ABCDEF); }
Re: stack trace output on exception
On Tuesday, 8 July 2014 at 07:11:26 UTC, Stephan Schiffels wrote: Hi, I am using dmd with version: DMD64 D Compiler v2.065-devel-db2a73d My program throws a custom exception with a custom error message at some point. The stack trace (below) is very uninformative. Is there a way to output the function names of each position in the stack? I already compile using -g and I also tried -gc and -gs and all three of them together. I also tried -debug. The stack trace looks always like this: popGenFunc.IllegalParametersException@popGenFunc.d(556): gamma out of range /nfs/users/nfs_s/ss27/Projects/hfit/build/hfit() [0x42752b] /nfs/users/nfs_s/ss27/Projects/hfit/build/hfit() [0x423ee7] /nfs/users/nfs_s/ss27/Projects/hfit/build/hfit() [0x404bab] /nfs/users/nfs_s/ss27/Projects/hfit/build/hfit() [0x402d7e] /nfs/users/nfs_s/ss27/Projects/hfit/build/hfit() [0x4028d6] /nfs/users/nfs_s/ss27/Projects/hfit/build/hfit() [0x433cc4] /nfs/users/nfs_s/ss27/Projects/hfit/build/hfit() [0x433c1e] /nfs/users/nfs_s/ss27/Projects/hfit/build/hfit() [0x433c84] /nfs/users/nfs_s/ss27/Projects/hfit/build/hfit() [0x433c1e] /nfs/users/nfs_s/ss27/Projects/hfit/build/hfit() [0x433b9f] /nfs/users/nfs_s/ss27/Projects/hfit/build/hfit() [0x421121] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7ffe8440e76d] Thanks for your help, Stephan Tried building with -L--export-dynamic?
Re: Capture offset of matches in std.regex.matchAll?
On Monday, 7 July 2014 at 21:32:30 UTC, JD wrote: I'm using a compile time regex to find some tags in an input string. Is it possible to capture the offset of the matches in some way? Otherwise I have to calculate the offsets myself by iterating over the results of matchAll. Thanks, Jeroen I believe what matchAll returns evaluates its .front lazily, so aye; you need to pop it until you get to the match you want. : (assuming I understand the question correctly) You can however index the *captured fields* in a specific match. I couldn't wrap my head around your example pattern but see http://dpaste.dzfl.pl/f693db93c3a4 for a dumbed-down version. You can't slice match, nor can you have foreach provide an index variable. This may be to have foreach include named fields? Not sure.
Re: Permutation Sort Algorithm Very Slow
On Sunday, 8 June 2014 at 08:44:42 UTC, monarch_dodra wrote: of. If you want to use a bad algorithm, you could also go for bogosort: void main() { auto data = [2, 7, 4, 3, 5, 1, 0, 9, 8, 6, -1]; while (!isSorted(data)) randomShuffle(data); data.writeln; } I'm partial to MiracleSort[1] myself. void main() { import core.thread; immutable period = 1.seconds; auto data = [2, 7, 4, 3, 5, 1, 0, 9, 8, 6, -1]; while (!isSorted(data)) { Thread.sleep(period); } data.writeln(); } [1]: http://stackoverflow.com/questions/2609857/are-there-any-worse-sorting-algorithms-than-bogosort-a-k-a-monkey-sort/6947808#6947808
Re: receiveTimeout minimum reasonable timeout value?
On Thursday, 15 May 2014 at 18:15:46 UTC, Charles Hixson via Digitalmars-d-learn wrote: Duration can be specified in nanoseconds, but does it make any sense to have a value of 1 nanosecond? 0? My desire is to check whether a message is in the queue, and then either move it local to the thread, or continue, depending. I use 0.seconds for such oneshot receive attempts. Snippet: while (!halt) { if (++readCounter messageCheckFrequency) { receiveTimeout(0.seconds, _verbose.fun, _quiet.fun, _unknown.fun ); readCounter = 0; } slice = conn.stream.readLine(buf); // ... }
Templating everything? One module per function/struct/class/etc, grouped by package?
Given that... 1. importing a module makes it compile the entirety of it, as well as whatever it may be importing in turn 2. templates are only compiled if instantiated 3. the new package.d functionality ...is there a reason *not* to make every single function/struct/class separate submodules in a package, and make *all* of those templates? Unnused functionality would never be imported nor instantiated, and as such never be compiled, so my binary would only include what it actually uses. std/stdio/package.d: module std.stdio; // still allows for importing the entirety of std.stdio public import std.stdio.foo; public import std.stdio.writefln; __EOF__ std/stdio/foo.d: module std.stdio.foo; void fooify(Args...)(Args args) if (Args.length 0) { // ... } void fooify()() { // don't need this, won't compile this } __EOF__ std/stdio/writefln.d; module std.stdio.writefln; // nevermind the incompatible signature auto writefln(string pattern, Args...)(Args args) if (!pattern.canFind(PatternIdentifier.json)) { // code that doesn't need std.json -- it is never imported } __EOF__ What am I missing?
Re: Templating everything? One module per function/struct/class/etc, grouped by package?
On Monday, 12 May 2014 at 09:16:53 UTC, Jonathan M Davis via Digitalmars-d-learn wrote: Well, that would be a lot of extraneous files, which would be very messy IMHO. It also makes it much harder to share private functionality, because everything is scattered across modules - you'd be force to use the package for that. It also wouldn't surprise me if it cost more to compile the code that way if you were actually using most of it (though it may very well save compilation time if you're using a relatively small number of the functions and types). So, from a purely organization perspective, I think that it's a very bad idea, though others may think that it's a good one. And since package.d imports all of those modules anyway, separating them out into separate files didn't even help you any. Thank you for answering. The package.d example was mostly to highlight that the current syntax and practice of importing everything in a package wouldn't change. To be a bit more specific I'm new to everything beyond advanced scripting, so my code has grown organically. Partly due to shotgun programming, and partly due to exploratory programming. In the process of figuring out what code depends on what, to allow for making pieces of it more self-contained, I realized that with my current practice of gathering everything related to the same topic into one module made it all unneccesarily tangled. (--gc-sections seems to cause segfaults.) As an example, both the homebrew string builder 'Yarn' and the simple 'string plurality(ptrdiff_t, string, string)' belong in mylib.string. But if I want to reuse only plurality there in other projects I would end up pulling in all the ancillary stuff Yarn needs to validate input, and it only segways from there. Correct? The logical step would be to split the all-encompassing mylib.string module into submodules, and the logical followup question would be why I shouldn't do that everywhere. Knowing that templates aren't built unless concretely instantiated, the idea of templatizing everything fell into the same basket. I hope you understand my concerns that I was falling into an anti-pattern.
Re: The writeln() function's args can't be [一 ,二]?
On Tuesday, 6 May 2014 at 09:43:10 UTC, FrankLike wrote: Hi,everyone, I find the The writeln() function's args can't be [一 ,二]? why? Thank you. Frank. The problem is that you have a wide-character comma (,) there. This works: void main() { writeln([一, 二]); }
Allocation-free message passing?
I'm trying to impose limits upon myself to, well, learn. Currently I'm exploring ways to avoid allocations -- but my program is running in three threads with considerable amounts of message passing between them. Unless I'm misinterpreting my callgraph, std.concurrency.MessageBox contains a struct Node, which MessageBox.put does a new on. That's the only explicit allocation I can find in there. void put( T val ) { put( new Node( val ) ); } It makes sense to store messages on the heap. Even so, is there a different way of doing it? (Again, it's more of a challenge than it is micro-optimizing.)
Re: number formatting
On Sunday, 20 April 2014 at 12:53:11 UTC, steven kladitis wrote: Note sure if you can edit messages once sent. $13,456.67 245,678,541 On Sunday, 20 April 2014 at 12:50:52 UTC, steven kladitis wrote: How do you format numbers to have things like. Leading $ or , or CR with or without leading zeros. for example $56.00 $056.00 $1,3456.67 345.89CR As for grouping by thousands http://dpaste.dzfl.pl/bddb71eb75bb *does* work, but I'm not particularly happy with the approach. As monarch_dodra said, representing money via a struct or similar would be wiser than dealing with raw doubles/reals (as that paste does).