Re: Insufficient Documentation?
On Wednesday, 31 July 2013 at 04:05:48 UTC, Manfred Nowak wrote: Jesse Phillips wrote: How did you know about "convert object"? -manfred If I had an object (argument) then I'd want to know how it would become (convert to) "text." Similarly if I had an int I'd want to know how that converts to text. If I didn't know what an argument was: https://www.google.com/search?q=what+is+a+function+argument You mentioned that nothing came up about toString, if information on toString was applicable to you then it is likely because your argument being passed was an object (of a class or a struct). Thus the question becomes how does my object convert to text for this write function. To further that, strings are the type of text so if I am familiar with any language I can attempt to be more specific. I just don't understand why you think "arguments in text format" should direct you toward toString. At most I could see std.string.format, but I doubt that would answer the question. I certainly could see reason for the documentation of write to mention toString, but based on the information provided it is hard to say what about "Writes its arguments in text format to the file" is unclear. I feel, " Converts all arguments to strings and catenates those strings to `File' in lexical order of appearance of the arguments." Needlessly complicates communicating the operation performed. But maybe it is of value to most people.
Re: Insufficient Documentation?
Jesse Phillips wrote: >> Writes its arguments in text format to the file. > I'm not sure what results you are interest in when searching for > "arguments in text format." I expected a closer explanation for the broad explanation "arguments in text format". If the explanation for `write' would be Converts all arguments to strings and catenates those strings to `File' in lexical order of appearance of the arguments. then I still would not search for `object', but for conversion. > If I search for "convert object to > string/text" then I get some references to toString or std.conv. How did you know about "convert object"? -manfred
Re: Thread-local copy of data structure
On 07/30/2013 01:15 PM, Marek Janukowicz wrote: > class A { > B [] arr; > } > Now "a" in my task is the same as "a" in main thread and I'd like a local > copy - to be precise I need to make changes to a in the task, but they > should not affect main copy. Fine: That is a requirement of your program. Another program may have different requirements. > Is it possible to somehow create copy automatically when creating a task, or > do I need to create it myself? It is possible to write a general function that performs deep copying of members and others have implemented such functions. > If the latter - is there anything in std lib that helps with creation of > deep clones I doubt it. Ali
Re: Profiling graph library
On 07/31/2013 01:02 AM, bearophile wrote: > There are many ways to design a graph data structure. All of them have > tradeoffs, they can't be very good for everything. Sure, it's just that in this case the reference code (igraph) is _much_ more performant. I'm keen to try and identify the major issues that are holding the D code back. I _could_ just copy the C algorithms from igraph into my own code, but nothing would be learned from that, and it would seem to defeat the purpose of using a more elegant language like D. > For your benchmarks are you using the ldc2 compiler with correct compilation > switches? No, gdmd -O -release -inline -g -profile, and then gprof to generate the profile. > map() should not allocate memory. > > Sometimes lazy code is faster and sometimes it's slower. A good compiler (like > Haskell GHC) should be able to optimize map well. That's what I'd assumed, which was why I was so disappointed that in this case performance was _very_ bad. I particularly don't understand the major GC hit. Or rather, I should say, I don't see why that GC hit should be there, unless it's that there is a fault in the implementation of iota, map and/or chain. > Also try to use a bitvector from Phobos instead of bool[]. I did consider that, I haven't tried yet. Obviously it's superior from a storage point of view, I wasn't sure if it would be worse or equivalent performance-wise (I seem to recall reading that it's slightly slower than a bool[]). I'll try it. :-) > Sometimes you can keep memory allocation low, performance almost acceptable, > and > code easy to read using a pre-allocated scratch space plus using map() and > copy() from std.algorithm. Could you expand a little on that point? I don't mean to ask you to write my code for me, it's just that (like most non-computer-science researchers) my knowledge of programming is somewhat specialized, and there are blank spots on the map. So when in your reply to John you say, "Allocate a buffer somewhere, on the stack or heap", I'm still not sure exactly what you mean or how you'd use it. It'd really help to see a concrete example (it doesn't need to be tailored to the use-case here). In any case, thanks as ever for all the useful remarks and advice. :-)
Re: Profiling graph library
John Colvin: Any chance of some nice examples of this? Allocate a buffer somewhere, on the stack or heap, and then instead of using a map()+array() as in that code use map()+copy() plus a test to be sure the space is sufficient. But in the end I don't know how much well even ldc2 will compile that. You have to take a look at the produced asm with the "-output-s" switch of ldc2. Bye, bearophile
Re: Profiling graph library
On Tuesday, 30 July 2013 at 23:02:40 UTC, bearophile wrote: Sometimes you can keep memory allocation low, performance almost acceptable, and code easy to read using a pre-allocated scratch space plus using map() and copy() from std.algorithm. Any chance of some nice examples of this?
Re: Weird bug in IFTI
On Tuesday, 30 July 2013 at 22:22:38 UTC, JS wrote: http://dpaste.dzfl.pl/cdabf9fa But adding one more parameter gives an error! http://dpaste.dzfl.pl/a5cfac37 Template has no effect simply because I added an parameter with a default?!?!?!? Definitely some compiler logic problems there with the error message at least. What I'd like to see: pragma(msg) should be immune from "has no effect" errors as it does have an observable effect at compile-time.
Re: Profiling graph library
There are many ways to design a graph data structure. All of them have tradeoffs, they can't be very good for everything. For your benchmarks are you using the ldc2 compiler with correct compilation switches? map() should not allocate memory. Sometimes lazy code is faster and sometimes it's slower. A good compiler (like Haskell GHC) should be able to optimize map well. Also try to use a bitvector from Phobos instead of bool[]. Sometimes you can keep memory allocation low, performance almost acceptable, and code easy to read using a pre-allocated scratch space plus using map() and copy() from std.algorithm. Bye, bearophile
Re: Weird bug in IFTI
On Tuesday, 30 July 2013 at 22:22:38 UTC, JS wrote: But adding one more parameter gives an error! http://dpaste.dzfl.pl/a5cfac37 Copying the code for readability and for future generations: template SomeName(T...) { void SomeName(string file = __FILE__, string line = __LINE__, string f = __FUNCTION__)() { pragma(msg, f~";"); } } void main() { SomeName!("x"); } And the error: /d608/f685.d(8): Error: template SomeName(string file = __FILE__, string line = __LINE__, string f = __FUNCTION__)() has no effect Template has no effect simply because I added an parameter with a default?!?!?!? You have a bug in there!!! __LINE__ is not a string!!?!!?! Make it `size_t line = __LINE__` and you're good... The error message really doesn't help much, though.
Weird bug in IFTI
http://dpaste.dzfl.pl/cdabf9fa But adding one more parameter gives an error! http://dpaste.dzfl.pl/a5cfac37 Template has no effect simply because I added an parameter with a default?!?!?!?
Re: Get template name
On Tuesday, 30 July 2013 at 11:25:38 UTC, Dicebot wrote: On Tuesday, 30 July 2013 at 11:04:10 UTC, JS wrote: 1. No, the code actually will print the message but the error shows up right after(well, depends on which error, the one I get inside templates works fine except the without the assignment/alias, no further compilation is done due to the error(but the message is printed). http://dpaste.dzfl.pl/e232e3ac And what is a stub function? http://dpaste.dzfl.pl/133230f8 http://dpaste.dzfl.pl/c4cb0dfb For some reason the code doesn't work on my machine... works in dpaste though... My machine just returns an empty string for __FUNCTION__. I think this is a bug somewhere... I'll post another post showing it.
Re: use template function without assignment
BTW, when I use mixin in my code, the error goes away but no pragma msg is produced, so it is not a solution.
Re: use template function without assignment
On Tuesday, 30 July 2013 at 20:34:32 UTC, Ali Çehreli wrote: On 07/30/2013 12:09 PM, JS wrote: > I already stated why this is not a proper example, I'm not using Pragma > in run time code(for lack of a better term). > > module main; > > import std.stdio; > > > template Pragma(alias amsg) > { > void Pragma(string file = __FILE__) > { > pragma(msg, amsg); > } > } > > template t() > { > Pragma!("help, this does not work!"); > } > > void main() > { > enum msg = "hello"; > Pragma!msg; > t!(); > } Thank you. Now we have something to work on. The program above produces the following error: Error: no identifier for declarator Pragma!"help, this does not work!" The error is fixed by adding a mixin: mixin Pragma!("help, this does not work!"); Or just assigning it to enum... both are not great solutions... Despite another error it actually works: hello help, this does not work!<-- IT WORKED Error: t!() has no effect The second error is fixed by another mixin: mixin t!(); Perhaps the example is too simplistic. Still, let's stay with it for further issues. Ali I think that such behavior should not be an error but possibly a warning, if at all. And if you cared to read what I initially posted you would realize I already explained the same thing. The example maybe more clear but I stated, maybe in some convoluted and jumped way, that Pragma doesn't work *in* templates.. "When I try to use void instead of string and do something like Pragma!(msg) I get an error that the template has no effect." and later "It's goal is to debug templates and essentially just wrapping pragma to supply the __FILE__ info automatically. e.g., instead of having to do pragma(msg, __FILE__~amsg); I want to do Pragma!(amsg); "
Re: use template function without assignment
On 07/30/2013 12:09 PM, JS wrote: > I already stated why this is not a proper example, I'm not using Pragma > in run time code(for lack of a better term). > > module main; > > import std.stdio; > > > template Pragma(alias amsg) > { > void Pragma(string file = __FILE__) > { > pragma(msg, amsg); > } > } > > template t() > { > Pragma!("help, this does not work!"); > } > > void main() > { > enum msg = "hello"; > Pragma!msg; > t!(); > } Thank you. Now we have something to work on. The program above produces the following error: Error: no identifier for declarator Pragma!"help, this does not work!" The error is fixed by adding a mixin: mixin Pragma!("help, this does not work!"); Despite another error it actually works: hello help, this does not work!<-- IT WORKED Error: t!() has no effect The second error is fixed by another mixin: mixin t!(); Perhaps the example is too simplistic. Still, let's stay with it for further issues. Ali
Thread-local copy of data structure
I have quite complicated data structure (class-based) and I need a copy of it in a Task (std.parallelism). There is a simplification of data structure and my program: class A { B [] arr; } class B { C c; } class C { A a; } void main () { a = new A(); ... // Further initialization of data structure auto taskObject = new TaskObject( a ); auto t = task(taskObject); taskPool.put( t ); } Now "a" in my task is the same as "a" in main thread and I'd like a local copy - to be precise I need to make changes to a in the task, but they should not affect main copy. Is it possible to somehow create copy automatically when creating a task, or do I need to create it myself? If the latter - is there anything in std lib that helps with creation of deep clones or an I completely on my own? -- Marek Janukowicz
Re: use template function without assignment
On Tuesday, 30 July 2013 at 18:38:23 UTC, Ali Çehreli wrote: On 07/30/2013 06:16 AM, Meta wrote: > Can you post some more code that exhibits exactly the behaviour you're > describing? I can't replicate the problem you're having with the code > you provided (nor the code *I* provided). Ditto. JS, I wrote the following code for you. Could you please start with it and show us the problem that we are trying to solve. template Pragma(alias amsg) { void Pragma(string file = __FILE__) { pragma(msg, amsg); } } void main() { enum msg = "hello"; Pragma!msg; } Ali I already stated why this is not a proper example, I'm not using Pragma in run time code(for lack of a better term). module main; import std.stdio; template Pragma(alias amsg) { void Pragma(string file = __FILE__) { pragma(msg, amsg); } } template t() { Pragma!("help, this does not work!"); } void main() { enum msg = "hello"; Pragma!msg; t!(); }
Re: use template function without assignment
On 07/30/2013 06:16 AM, Meta wrote: > Can you post some more code that exhibits exactly the behaviour you're > describing? I can't replicate the problem you're having with the code > you provided (nor the code *I* provided). Ditto. JS, I wrote the following code for you. Could you please start with it and show us the problem that we are trying to solve. template Pragma(alias amsg) { void Pragma(string file = __FILE__) { pragma(msg, amsg); } } void main() { enum msg = "hello"; Pragma!msg; } Ali
Re: Insufficient Documentation?
On Monday, 29 July 2013 at 06:17:10 UTC, Manfred Nowak wrote: http://dlang.org/phobos/std_stdio.html: void write(S...)(S args); Writes its arguments in text format to the file. 1) Feeding "arguments in text format" into the search-function for the whole site does not give a hint to `toString'. What am I missing? I'm not sure what results you are interest in when searching for "arguments in text format." If I search for "convert object to string/text" then I get some references to toString or std.conv.
Re: use template function without assignment
On Tuesday, 30 July 2013 at 07:02:51 UTC, JS wrote: If I use enum or alias they both have the same problem(The annoying mandatory assignment). Can you post some more code that exhibits exactly the behaviour you're describing? I can't replicate the problem you're having with the code you provided (nor the code *I* provided). BTW, is void Pragma(alias amsg)(string file = __FILE__) short for template Pragma(alias amsg) { void Pragma(string file = __FILE__) or is there some real difference? They're semantically equivalent. The first form is just shorthand for the second. I could potential do something like template Group(alias G1) { void Group(alias G2)(int s) { writeln(s); } } Group!("x")("y")(3); // doesn't work, Group!("x")!("y")(3); // doesn't work What you're doing here is pretty weird. That code is equivalent to: template Group(alias G1) { template Group(alias G2) { void Group(int s) { writeln(s); } } } And I really have no idea how it *should* behave. It definitely doesn't work on dpaste.dzfl.pl.
Profiling graph library
Hello all, I thought I'd share some profiling results from the graph/network library that I've been working on -- see: https://github.com/WebDrake/Dgraph http://braingam.es/2013/07/complex-networks-in-d/ http://braingam.es/2013/07/complex-networks-in-d-part-2-building-the-network/ I'd like to get others' thoughts and insight on these -- obviously I have some ideas of my own about how to interpret them and move forward, but it's always good to have feedback (and there are several things I'd like to make sure I have my facts straight on before making any more "public" comment). The basic data structure, which is taken from the igraph library, consists of a pair of arrays of head and tail vertices for edges, together with indices which sort the edges according to head or tail vertex, and sums of the total number of edges whose head/tail ID is less than a certain value: https://github.com/WebDrake/Dgraph/blob/master/dgraph/graph.d#L33-L38 Taken together this offers a very memory-efficient structure that should also be able to minimize the total number of allocations required to build a graph. When I started working on the code the initial goal was to have something that gave a very simple and obvious representation of the algorithms at work, which would be easy to understand. So, for example, I used std.algorithm.map quite freely to make an "easy" representation of how a vertex's neighbours were calculated: https://github.com/WebDrake/Dgraph/blob/master/dgraph/graph.d#L260-L286 It turns out this results in a fairly major speed hit that stems from a variety of factors. The following is the result of profiling a simple function that just iterates over all the neighbours of each vertex in turn, and sums the neighbour IDs. The code is attached in neighbours.d. - Flat profile: Each sample counts as 0.01 seconds. % cumulative self self total time seconds secondscalls ms/call ms/call name 19.20 0.24 0.24 5000 0.00 0.00 _D6dgraph5graph13__T5GraphVb0Z5Graph10neighboursMxFymZS3std5range380__T5chainTS6dgraph5graph13__T5GraphVb0Z5Graph10neighboursM123__T9MapResultS596dgraph5graph13__T5GraphVb0Z5Graph10neighboursM10__lambda46TS3std5range15__T4iotaTxmTxmZ4iotaFxmxmZ6ResultZ9MapResultTS6dgraph5graph13__T5GraphVb0Z5Graph10neighboursM123__T9MapResultS596dgraph5graph13__T5GraphVb0Z5Graph10neighboursM10__lambda48TS3std5range15__T4iotaTxmTxmZ4iotaFxmxmZ6ResultZ9MapResultZ5chainFS6dgraph5graph13__T5GraphVb0Z5Graph10neighboursM123__T9MapResultS596dgraph5graph13__T5GraphVb0Z5Graph10neighboursM10__lambda46TS3std5range15__T4iotaTxmTxmZ4iotaFxmxmZ6ResultZ9MapResultS6dgraph5graph13__T5GraphVb0Z5Graph10neighboursM123__T9MapResultS596dgraph5graph13__T5GraphVb0Z5Graph10neighboursM10__lambda48TS3std5range15__T4iotaTxmTxmZ4iotaFxmxmZ6ResultZ9MapResultZ6Result18__T10__lambda46TmZ10__lambda46MFNbNfmZxm 18.40 0.47 0.23 _D2gc3gcx2GC12mallocNoSyncMFmkPmZPv 15.60 0.67 0.20 5000 0.00 0.00 _D6dgraph5graph13__T5GraphVb0Z5Graph10neighboursMxFymZS3std5range380__T5chainTS6dgraph5graph13__T5GraphVb0Z5Graph10neighboursM123__T9MapResultS596dgraph5graph13__T5GraphVb0Z5Graph10neighboursM10__lambda46TS3std5range15__T4iotaTxmTxmZ4iotaFxmxmZ6ResultZ9MapResultTS6dgraph5graph13__T5GraphVb0Z5Graph10neighboursM123__T9MapResultS596dgraph5graph13__T5GraphVb0Z5Graph10neighboursM10__lambda48TS3std5range15__T4iotaTxmTxmZ4iotaFxmxmZ6ResultZ9MapResultZ5chainFS6dgraph5graph13__T5GraphVb0Z5Graph10neighboursM123__T9MapResultS596dgraph5graph13__T5GraphVb0Z5Graph10neighboursM10__lambda46TS3std5range15__T4iotaTxmTxmZ4iotaFxmxmZ6ResultZ9MapResultS6dgraph5graph13__T5GraphVb0Z5Graph10neighboursM123__T9MapResultS596dgraph5graph13__T5GraphVb0Z5Graph10neighboursM10__lambda48TS3std5range15__T4iotaTxmTxmZ4iotaFxmxmZ6ResultZ9MapResultZ6Result18__T10__lambda48TmZ10__lambda48MFNbNfmZxm 9.60 0.79 0.12 50 0.00 0.00 _D10neighbours24__T15checkNeighboursVb0Z15checkNeighboursFKC6dgraph5graph13__T5GraphVb0Z5GraphZm 8.00 0.89 0.10 2500 0.00 0.00 _D6dgraph5graph13__T5GraphVb0Z5Graph10neighboursMxFymZS3std5range380__T5chainTS6dgraph5graph13__T5GraphVb0Z5Graph10neighboursM123__T9MapResultS596dgraph5graph13__T5GraphVb0Z5Graph10neighboursM10__lambda46TS3std5range15__T4iotaTxmTxmZ4iotaFxmxmZ6ResultZ9MapResultTS6dgraph5graph13__T5GraphVb0Z5Graph10neighboursM123__T9MapResultS596dgraph5graph13__T5GraphVb0Z5Graph10neighboursM10__lambda48TS3std5range15__T4iotaTxmTxmZ4iotaFxmxmZ6ResultZ9MapResultZ5chainFS6dgraph5graph13__T5GraphVb0Z5Graph10neighboursM123__T9MapResultS596dgraph5graph13__T5GraphVb0Z5Graph10neighboursM10__lambda46TS3std5range15__T4iotaTxmTxmZ4iotaFxmxmZ6ResultZ9MapResultS6dgraph5graph13__T5GraphVb0Z5Graph10neighboursM123__T9MapResultS596dgraph5graph13__T5GraphVb0Z5Graph10neighboursM10__lambda48TS3std5range15__T4iotaTxmTxmZ4iotaFxmxmZ6ResultZ9MapResultZ6Result 8.00
Re: Get template name
On Tuesday, 30 July 2013 at 11:25:38 UTC, Dicebot wrote: On Tuesday, 30 July 2013 at 11:04:10 UTC, JS wrote: 1. No, the code actually will print the message but the error shows up right after(well, depends on which error, the one I get inside templates works fine except the without the assignment/alias, no further compilation is done due to the error(but the message is printed). http://dpaste.dzfl.pl/e232e3ac And what is a stub function? http://dpaste.dzfl.pl/133230f8 The first is what I already do, but it is messy. The second may work, it is also a bit messy(requiring an extra function) but might solve the problem...
Re: Get template name
On Tuesday, 30 July 2013 at 11:04:10 UTC, JS wrote: 1. No, the code actually will print the message but the error shows up right after(well, depends on which error, the one I get inside templates works fine except the without the assignment/alias, no further compilation is done due to the error(but the message is printed). http://dpaste.dzfl.pl/e232e3ac And what is a stub function? http://dpaste.dzfl.pl/133230f8
Re: Whats the difference between a final and non-final switch statement?
On Tuesday, 30 July 2013 at 10:29:45 UTC, Namespace wrote: On Tuesday, 30 July 2013 at 10:14:50 UTC, Gary Willoughby wrote: Whats the difference between a final and non-final switch statement? I know the compiler complains when i don't use a default case in a non-final switch statement but i've no idea why. http://dlang.org/statement.html#FinalSwitchStatement That's great thanks.
Re: Get template name
On Tuesday, 30 July 2013 at 10:45:26 UTC, Dicebot wrote: On Tuesday, 30 July 2013 at 06:45:31 UTC, JS wrote: void f() { pragma(msg, __FUNCTION__); } template t() { pragma(msg, __FUNCTION__); } void main(string[] argv) { readln(); } the function displays main.f. The template displays nothing. I'd prefer it to display main.t! or something unique so I can use it as a hash. 1) Pragma's are printed upon instantiation. You need to use something like alias _ = t!(); to force it. 2) You may workaround it by wrapping pragma in stub function. Though I do agree that something like __ENCLOSING__ may be useful (assuming it also covers aggregates) 1. No, the code actually will print the message but the error shows up right after(well, depends on which error, the one I get inside templates works fine except the without the assignment/alias, no further compilation is done due to the error(but the message is printed). And what is a stub function?
Re: Get template name
On Tuesday, 30 July 2013 at 06:45:31 UTC, JS wrote: void f() { pragma(msg, __FUNCTION__); } template t() { pragma(msg, __FUNCTION__); } void main(string[] argv) { readln(); } the function displays main.f. The template displays nothing. I'd prefer it to display main.t! or something unique so I can use it as a hash. 1) Pragma's are printed upon instantiation. You need to use something like alias _ = t!(); to force it. 2) You may workaround it by wrapping pragma in stub function. Though I do agree that something like __ENCLOSING__ may be useful (assuming it also covers aggregates)
Re: Whats the difference between a final and non-final switch statement?
On Tuesday, 30 July 2013 at 10:14:50 UTC, Gary Willoughby wrote: Whats the difference between a final and non-final switch statement? I know the compiler complains when i don't use a default case in a non-final switch statement but i've no idea why. http://dlang.org/statement.html#FinalSwitchStatement
Whats the difference between a final and non-final switch statement?
Whats the difference between a final and non-final switch statement? I know the compiler complains when i don't use a default case in a non-final switch statement but i've no idea why.
Re: use template function without assignment
On Tuesday, 30 July 2013 at 07:12:11 UTC, Namespace wrote: On Monday, 29 July 2013 at 23:09:20 UTC, JS wrote: I have created a template Pragma that emulates pragma but better, the problem is that I have to assign it to something which is very redundant in my code: enum temp = Pragma!(msg) e.g., template Pragma(alias amsg) { string Pragma(string file = __FILE__) { pragma(msg, amsg); return ""; } } When I try to use void instead of string and do something like Pragma!(msg) I get an error that the template has no effect. It does have an effect but what it is complaining about is exactly what I want. I've tried all kinds of combinations(mixins work but I then can't ise __FILE__) and nothing works. Maybe someone has an idea. You could call your template in a static CTor: import std.stdio; template Pragma(alias amsg) { void Pragma(string file = __FILE__) { pragma(msg, amsg); } } static this() { Pragma!("foo")(); } void main() { writeln("Hello world!"); } Maybe this helps? This is useless. It's goal is to debug templates and essentially just wrapping pragma to supply the __FILE__ info automatically. e.g., instead of having to do pragma(msg, __FILE__~amsg); I want to do Pragma!(amsg); where Pragma custom formats the error or info message with the location where the message was initiated. Sticking it in a ctor will only print a message from that location.
Re: use template function without assignment
On Monday, 29 July 2013 at 23:09:20 UTC, JS wrote: I have created a template Pragma that emulates pragma but better, the problem is that I have to assign it to something which is very redundant in my code: enum temp = Pragma!(msg) e.g., template Pragma(alias amsg) { string Pragma(string file = __FILE__) { pragma(msg, amsg); return ""; } } When I try to use void instead of string and do something like Pragma!(msg) I get an error that the template has no effect. It does have an effect but what it is complaining about is exactly what I want. I've tried all kinds of combinations(mixins work but I then can't ise __FILE__) and nothing works. Maybe someone has an idea. You could call your template in a static CTor: import std.stdio; template Pragma(alias amsg) { void Pragma(string file = __FILE__) { pragma(msg, amsg); } } static this() { Pragma!("foo")(); } void main() { writeln("Hello world!"); } Maybe this helps?
Re: use template function without assignment
On Tuesday, 30 July 2013 at 01:19:23 UTC, Meta wrote: On Tuesday, 30 July 2013 at 01:06:39 UTC, Meta wrote: Does this code do what you want, or are there other requirements as well? void Pragma(alias amsg)(string file = __FILE__) { pragma(msg, amsg); } Actually, sorry, that's the exact same code, just with some syntactic sugar. To avoid the "expression has no effect" problem, you could use an alias instead of an enum. You're getting the error when you try to use pragma in the "global" scope, right? void Pragma(alias amsg)(string file = __FILE__) { pragma(msg, amsg); } alias temp = Pragma!("test"); In general, D doesn't have top-level expressions like what I think you want to do here. Maybe somebody else knows a way to work around that. If I use enum or alias they both have the same problem(The annoying mandatory assignment). I see the reason why it does it but I don't know it because in this case I do not want an effect. (pragma has no "effect" which is what I'm trying to emulate... works well except for that annoying quirk of having to assign it to something). BTW, is void Pragma(alias amsg)(string file = __FILE__) short for template Pragma(alias amsg) { void Pragma(string file = __FILE__) or is there some real difference? I could potential do something like template Group(alias G1) { void Group(alias G2)(int s) { writeln(s); } } Group!("x")("y")(3); // doesn't work, Group!("x")!("y")(3); // doesn't work