digitalmars.D - Why not move cast to the standard library?
- downs (3/3) Sep 24 2009 With all the neat template tricks we have in 2.0, and since we're widely...
- Jarrett Billingsley (2/5) Sep 24 2009 std.conv.to is more or less a proof-of-concept of this already. :>
- Andrei Alexandrescu (3/8) Sep 24 2009 What would the implementation look like?
- downs (2/15) Sep 24 2009 Unions, and LOTS of static ifs. :)
- Andrei Alexandrescu (4/19) Sep 24 2009 Unions won't work for casting class objects and interfaces because those...
- grauzone (5/25) Sep 24 2009 When casting interfaces and objects, the primitive cast just calls into
- Jeremie Pelletier (4/31) Sep 24 2009 What about cast(int) or cast(string) and whatnot then? You'd have
- downs (2/36) Sep 24 2009 What about cast!int could _not_ be done as a function?
- Jeremie Pelletier (7/40) Sep 24 2009 I don't want to call into functions for simple value casts. If I want
- downs (5/47) Sep 24 2009 What debug overhead?
- Jeremie Pelletier (10/59) Sep 24 2009 Compile with -debug -unittest -g and you get no inlines whatsoever, even...
- downs (2/68) Sep 24 2009 Good argument. Thanks.
- Steven Schveighoffer (10/16) Sep 24 2009 What is the benefit? Does it allow anything that isn't possible today
- language_fan (3/5) Sep 24 2009 I wonder how D scales to 100 MLOC programs as the template instantiation...
- downs (4/11) Sep 24 2009 We write templates in < 1000 LOC programs to avoid having to write 100 M...
- language_fan (13/29) Sep 24 2009 I agree, usually there is *something* wrong with your program if it gets...
- Don (10/40) Sep 25 2009 That's not the reason.
- Robert Jacques (6/14) Sep 25 2009 About the only thing I find lacking today is the ability to do zero weig...
- Yigal Chripun (39/53) Sep 26 2009 My preferred design, which I can't imagine implemented in the near
- Adam D. Ruppe (45/51) Sep 25 2009 I was thinking of a simple one for D2 a while back, but canceled my post
- bearophile (11/14) Sep 25 2009 In std.metastrings there's Format that allows to use a basic form of str...
- Don (9/73) Sep 29 2009 I agree, for a user that'd give you all the syntax sugar you'd hope for
- Sergey Gromov (7/19) Oct 03 2009 While I like and support the idea, I think that hijacking the "macro"
- Jarrett Billingsley (10/16) Oct 03 2009 h
- Sergey Gromov (10/30) Oct 04 2009 I cannot see how this is "very different" from what it does currently.
- Tom S (12/19) Sep 24 2009 It scales to a few hundred kLoC if you don't abuse templates (too much)
- Yigal Chripun (6/12) Sep 24 2009 vote++;
With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?
Sep 24 2009
On Thu, Sep 24, 2009 at 12:35 PM, downs <default_357-line yahoo.de> wrote:With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?std.conv.to is more or less a proof-of-concept of this already. :>
Sep 24 2009
downs wrote:With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?What would the implementation look like? Andrei
Sep 24 2009
Andrei Alexandrescu wrote:downs wrote:Unions, and LOTS of static ifs. :)With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?What would the implementation look like? Andrei
Sep 24 2009
downs wrote:Andrei Alexandrescu wrote:Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive. Andreidowns wrote:Unions, and LOTS of static ifs. :)With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?What would the implementation look like? Andrei
Sep 24 2009
Andrei Alexandrescu wrote:downs wrote:When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly.Andrei Alexandrescu wrote:Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive.downs wrote:Unions, and LOTS of static ifs. :)With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?What would the implementation look like? AndreiAndrei
Sep 24 2009
grauzone wrote:Andrei Alexandrescu wrote:What about cast(int) or cast(string) and whatnot then? You'd have cast!A(B) for classes and cast(int) for values, that would be backwards. Jeremiedowns wrote:When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly.Andrei Alexandrescu wrote:Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive.downs wrote:Unions, and LOTS of static ifs. :)With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?What would the implementation look like? AndreiAndrei
Sep 24 2009
Jeremie Pelletier wrote:grauzone wrote:What about cast!int could _not_ be done as a function?Andrei Alexandrescu wrote:What about cast(int) or cast(string) and whatnot then? You'd have cast!A(B) for classes and cast(int) for values, that would be backwards. Jeremiedowns wrote:When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly.Andrei Alexandrescu wrote:Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive.downs wrote:Unions, and LOTS of static ifs. :)With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?What would the implementation look like? AndreiAndrei
Sep 24 2009
downs wrote:Jeremie Pelletier wrote:I don't want to call into functions for simple value casts. If I want safe casts I use to!int. It may get inlined in release code, but think of the debug overhead it would generate. The current way is great as it is, cast() for straightforward unsafe casting and to!(T)() for safe casting. This is exactly what makes D attractive to me, the choice between safe and unsafe alternatives.grauzone wrote:What about cast!int could _not_ be done as a function?Andrei Alexandrescu wrote:What about cast(int) or cast(string) and whatnot then? You'd have cast!A(B) for classes and cast(int) for values, that would be backwards. Jeremiedowns wrote:When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly.Andrei Alexandrescu wrote:Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive.downs wrote:Unions, and LOTS of static ifs. :)With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?What would the implementation look like? AndreiAndrei
Sep 24 2009
Jeremie Pelletier wrote:downs wrote:What debug overhead? With current casts, all the logic is in the compiler - where you can't get at it. Moving it into the library can only make this better. There is nothing about cast that I can see that requires dedicated compiler assistance. Furthermore, consider it a testcase - if a trivial function like that isn't inlined, _something_ is wrong :)Jeremie Pelletier wrote:I don't want to call into functions for simple value casts. If I want safe casts I use to!int. It may get inlined in release code, but think of the debug overhead it would generate. The current way is great as it is, cast() for straightforward unsafe casting and to!(T)() for safe casting. This is exactly what makes D attractive to me, the choice between safe and unsafe alternatives.grauzone wrote:What about cast!int could _not_ be done as a function?Andrei Alexandrescu wrote:What about cast(int) or cast(string) and whatnot then? You'd have cast!A(B) for classes and cast(int) for values, that would be backwards. Jeremiedowns wrote:When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly.Andrei Alexandrescu wrote:Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive.downs wrote:Unions, and LOTS of static ifs. :)With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?What would the implementation look like? AndreiAndrei
Sep 24 2009
downs wrote:Jeremie Pelletier wrote:Compile with -debug -unittest -g and you get no inlines whatsoever, even const values aren't inlined, when I run such an executable in windbg the code cursor actually goes to the declaration of enums and other constants. A lot of casts are just type reinterpretations, with a few semantics behind float to int conversions. I wouldn't give away the convenience of cast() to force everything through to!(T)(). I use cast() for most cases where I don't need anything special, and to!(T)() when I need some specific semantics. It also makes such cases much easier to notice when reading code.downs wrote:What debug overhead? With current casts, all the logic is in the compiler - where you can't get at it. Moving it into the library can only make this better. There is nothing about cast that I can see that requires dedicated compiler assistance. Furthermore, consider it a testcase - if a trivial function like that isn't inlined, _something_ is wrong :)Jeremie Pelletier wrote:I don't want to call into functions for simple value casts. If I want safe casts I use to!int. It may get inlined in release code, but think of the debug overhead it would generate. The current way is great as it is, cast() for straightforward unsafe casting and to!(T)() for safe casting. This is exactly what makes D attractive to me, the choice between safe and unsafe alternatives.grauzone wrote:What about cast!int could _not_ be done as a function?Andrei Alexandrescu wrote:What about cast(int) or cast(string) and whatnot then? You'd have cast!A(B) for classes and cast(int) for values, that would be backwards. Jeremiedowns wrote:When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly.Andrei Alexandrescu wrote:Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive.downs wrote:Unions, and LOTS of static ifs. :)With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?What would the implementation look like? AndreiAndrei
Sep 24 2009
Jeremie Pelletier wrote:downs wrote:Good argument. Thanks.Jeremie Pelletier wrote:Compile with -debug -unittest -g and you get no inlines whatsoever, even const values aren't inlined, when I run such an executable in windbg the code cursor actually goes to the declaration of enums and other constants. A lot of casts are just type reinterpretations, with a few semantics behind float to int conversions. I wouldn't give away the convenience of cast() to force everything through to!(T)(). I use cast() for most cases where I don't need anything special, and to!(T)() when I need some specific semantics. It also makes such cases much easier to notice when reading code.downs wrote:What debug overhead? With current casts, all the logic is in the compiler - where you can't get at it. Moving it into the library can only make this better. There is nothing about cast that I can see that requires dedicated compiler assistance. Furthermore, consider it a testcase - if a trivial function like that isn't inlined, _something_ is wrong :)Jeremie Pelletier wrote:I don't want to call into functions for simple value casts. If I want safe casts I use to!int. It may get inlined in release code, but think of the debug overhead it would generate. The current way is great as it is, cast() for straightforward unsafe casting and to!(T)() for safe casting. This is exactly what makes D attractive to me, the choice between safe and unsafe alternatives.grauzone wrote:What about cast!int could _not_ be done as a function?Andrei Alexandrescu wrote:What about cast(int) or cast(string) and whatnot then? You'd have cast!A(B) for classes and cast(int) for values, that would be backwards. Jeremiedowns wrote:When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly.Andrei Alexandrescu wrote:Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive.downs wrote:Unions, and LOTS of static ifs. :)With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?What would the implementation look like? AndreiAndrei
Sep 24 2009
On Thu, 24 Sep 2009 12:35:22 -0400, downs <default_357-line yahoo.de> wrote:With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?What is the benefit? Does it allow anything that isn't possible today (aside from using cast as a member, which I find not that worthy)? What I'd much rather have is directed casts, even if they are supported by the compiler, such as the casting features of C++ (i.e. const_cast and static_cast). I actually prefer the compiler to handle the casting versus templates to cut down on template instantiation bloat. -Steve
Sep 24 2009
Thu, 24 Sep 2009 13:47:21 -0400, Steven Schveighoffer thusly wrote:I actually prefer the compiler to handle the casting versus templates to cut down on template instantiation bloat.I wonder how D scales to 100 MLOC programs as the template instantiations can be troublesome already in < 1000 LOC programs.
Sep 24 2009
language_fan wrote:Thu, 24 Sep 2009 13:47:21 -0400, Steven Schveighoffer thusly wrote:We write templates in < 1000 LOC programs to avoid having to write 100 MLOC :) Also, let me categorically state: if you're writing 100MLOC programs, you're doing it horribly, horribly wrong. No conceivable program possibly requires that much logic.I actually prefer the compiler to handle the casting versus templates to cut down on template instantiation bloat.I wonder how D scales to 100 MLOC programs as the template instantiations can be troublesome already in < 1000 LOC programs.
Sep 24 2009
Thu, 24 Sep 2009 21:13:48 +0200, downs thusly wrote:language_fan wrote:I agree, usually there is *something* wrong with your program if it gets that large. I personally do not consider programs of that size very reliable. But the thing is, you probably know that people fear template instantiations. Not only can they cause really weird linking bugs, the more templates you have, the larger the executables get. Also as dmd does not use garbage collection (yet?) during compilation, the instantiations can easily kill the compilation process. Sometimes templates are abused to do what macros were supposed to by used for. I can imagine that templates can cause problems much sooner, you do not even need 1 MLOC of code to do that. Apparently D will never get a powerful macro system since the focus is on other features and templates seem to work just fine on the small scale.Thu, 24 Sep 2009 13:47:21 -0400, Steven Schveighoffer thusly wrote:We write templates in < 1000 LOC programs to avoid having to write 100 MLOC :) Also, let me categorically state: if you're writing 100MLOC programs, you're doing it horribly, horribly wrong. No conceivable program possibly requires that much logic.I actually prefer the compiler to handle the casting versus templates to cut down on template instantiation bloat.I wonder how D scales to 100 MLOC programs as the template instantiations can be troublesome already in < 1000 LOC programs.
Sep 24 2009
language_fan wrote:Thu, 24 Sep 2009 21:13:48 +0200, downs thusly wrote:That's not the reason. A bit of history: A macro system was planned for D2, and 'macro' was made a reserved word. But in discussions at the end of the first D conference, I demonstrated that the combination of CTFE + string mixins, even in D1, was dramatically more powerful than the proposed macros. It became clear that we didn't have a macro design that was anywhere near powerful enough, and macros were postponed to D3. We don't know how they should work. By all means make a proposal.language_fan wrote:I agree, usually there is *something* wrong with your program if it gets that large. I personally do not consider programs of that size very reliable. But the thing is, you probably know that people fear template instantiations. Not only can they cause really weird linking bugs, the more templates you have, the larger the executables get. Also as dmd does not use garbage collection (yet?) during compilation, the instantiations can easily kill the compilation process. Sometimes templates are abused to do what macros were supposed to by used for. I can imagine that templates can cause problems much sooner, you do not even need 1 MLOC of code to do that. Apparently D will never get a powerful macro system since the focus is on other features and templates seem to work just fine on the small scale.Thu, 24 Sep 2009 13:47:21 -0400, Steven Schveighoffer thusly wrote:We write templates in < 1000 LOC programs to avoid having to write 100 MLOC :) Also, let me categorically state: if you're writing 100MLOC programs, you're doing it horribly, horribly wrong. No conceivable program possibly requires that much logic.I actually prefer the compiler to handle the casting versus templates to cut down on template instantiation bloat.I wonder how D scales to 100 MLOC programs as the template instantiations can be troublesome already in < 1000 LOC programs.
Sep 25 2009
On Fri, 25 Sep 2009 03:29:21 -0400, Don <nospam nospam.com> wrote: [snip]A bit of history: A macro system was planned for D2, and 'macro' was made a reserved word. But in discussions at the end of the first D conference, I demonstrated that the combination of CTFE + string mixins, even in D1, was dramatically more powerful than the proposed macros. It became clear that we didn't have a macro design that was anywhere near powerful enough, and macros were postponed to D3. We don't know how they should work. By all means make a proposal.About the only thing I find lacking today is the ability to do zero weight expression templates. I think fleshing out the alias keyword might do the trick (i.e. alias tuples + alias function parameters) but I haven't though it all through.
Sep 25 2009
On 25/09/2009 18:32, Robert Jacques wrote:On Fri, 25 Sep 2009 03:29:21 -0400, Don <nospam nospam.com> wrote: [snip]My preferred design, which I can't imagine implemented in the near future, would be something in these lines: (disclaimer: heavily influenced by Nemerle) 1. macro definitions are separate from regular code. Macros are compiled into libs that are loaded by the compiler: something like: dmd --load-macro=my_macro.dll mysource.d (can be implemented as DDLs for portability) 2. macros contain regular D code and can use facilities from the stdlib to manipulate their input (examples will follow) 3. macros can either be called from regular code with function call syntax or by using an attribute system to specify hook points. e.g. int result = max_macro(50, 90); // transformed to: "int result = 90;" [macro(params)] // some imaginary attribute/annotations syntax class Class { .... } examples of macro definitions: a) CTFE replacement: macro max(int a, int b) { return (a > b) ? a : b; } b) operate on the current AST node: /// stdlib provided utilities to work with the AST import Compiler.AST; import Compiler.parser; macro (AST input) { // input is set by compiler to the current AST sub-tree return some_ast_transform(input); // can call regular functions to implement macros } c) compile-time vs. run-time : macro () { Stdout("Compile time").newline; //printed at compile-time return AST("Stdout(\"Run time\").newline;"); //printed at run-time } The Compiler package above provides facilities for the programmer to directly manipulate the AST in a standard way with API calls instead of string manipulations.A bit of history: A macro system was planned for D2, and 'macro' was made a reserved word. But in discussions at the end of the first D conference, I demonstrated that the combination of CTFE + string mixins, even in D1, was dramatically more powerful than the proposed macros. It became clear that we didn't have a macro design that was anywhere near powerful enough, and macros were postponed to D3. We don't know how they should work. By all means make a proposal.About the only thing I find lacking today is the ability to do zero weight expression templates. I think fleshing out the alias keyword might do the trick (i.e. alias tuples + alias function parameters) but I haven't though it all through.
Sep 26 2009
On Fri, Sep 25, 2009 at 09:29:21AM +0200, Don wrote:I demonstrated that the combination of CTFE + string mixins, even in D1, was dramatically more powerful than the proposed macros. It became clear that we didn't have a macro design that was anywhere near powerful enough, and macros were postponed to D3. We don't know how they should work. By all means make a proposal.I was thinking of a simple one for D2 a while back, but canceled my post since it is basically just sugar for what it does now. But, on the other hand, that is a bit simpler to implement, so let me throw it out. I propose that a macro (in D2; I don't know about a more elegant D3 design) is merely a CTFE function that is mixed in, and takes symbols as strings. Let me give an example: ==== macro max(int a, int b) { return a ~ " > " ~ b ~ " ? " ~ a ~ " : " ~ b; } void main() { auto num1 = 10; auto num2 = 20; auto result = max(num1, num2); } ==== This would be the same as: ==== string max(string a, string b) { return a ~ " > " ~ b ~ " ? " ~ a ~ " : " ~ b; } void main() { auto num1 = 10; auto num2 = 20; auto result = mixin(max("num1", "num2")); } =============== So: a) A macro function always returns a string, which is mixed in at the point where you used it b) Its arguments are actually strings. (I don't know if I'm happy with what I did in the above example, using int when they are actually string, but having some type checking seems more sane than actually going all string. All string feels too C preprocessor like.) c) All the arguments are the name of the variable as a string. It basically just tosses quotes around whatever you literally wrote on the line when you used it. (So passing a string literal would actually send "\"what you wrote\"" to the macro.) This doesn't do anything we can't already do with the language, but I think it looks a little prettier, which might make the functions a bit easier for the user. Though it would still be the same for the lib writer, of course. -- Adam D. Ruppe http://arsdnet.net
Sep 25 2009
Adam D. Ruppe:macro max(int a, int b) { return a ~ " > " ~ b ~ " ? " ~ a ~ " : " ~ b; }In std.metastrings there's Format that allows to use a basic form of string templating, that I find a little more readable than many string concats: return a ~ " > " ~ b ~ " ? " ~ a ~ " : " ~ b; ==> Format!("return %s > %s ? %s : %s;", a, b, a, b); Or safer: Format!("return %d > %d ? %d : %d;", a, b, a, b); Or more readable, something like: return "{a} > {b} ? {a} : {b};" % (a, b, a, b); Bye, bearophile
Sep 25 2009
Adam D. Ruppe wrote:On Fri, Sep 25, 2009 at 09:29:21AM +0200, Don wrote:I agree, for a user that'd give you all the syntax sugar you'd hope for from a macro. You haven't said what happens with arguments which are expressions rather than symbols, though, and that's the interesting bit. I'd propose it just does a .stringof on them. Basically the same as what my BLADE library did manually. It'd actually be interesting to see how much ugliness is left after doing that. Further refinement of macro proposals might be aimed at removing whatever hackiness is left.I demonstrated that the combination of CTFE + string mixins, even in D1, was dramatically more powerful than the proposed macros. It became clear that we didn't have a macro design that was anywhere near powerful enough, and macros were postponed to D3. We don't know how they should work. By all means make a proposal.I was thinking of a simple one for D2 a while back, but canceled my post since it is basically just sugar for what it does now. But, on the other hand, that is a bit simpler to implement, so let me throw it out. I propose that a macro (in D2; I don't know about a more elegant D3 design) is merely a CTFE function that is mixed in, and takes symbols as strings. Let me give an example: ==== macro max(int a, int b) { return a ~ " > " ~ b ~ " ? " ~ a ~ " : " ~ b; } void main() { auto num1 = 10; auto num2 = 20; auto result = max(num1, num2); } ==== This would be the same as: ==== string max(string a, string b) { return a ~ " > " ~ b ~ " ? " ~ a ~ " : " ~ b; } void main() { auto num1 = 10; auto num2 = 20; auto result = mixin(max("num1", "num2")); } =============== So: a) A macro function always returns a string, which is mixed in at the point where you used it b) Its arguments are actually strings. (I don't know if I'm happy with what I did in the above example, using int when they are actually string, but having some type checking seems more sane than actually going all string. All string feels too C preprocessor like.) c) All the arguments are the name of the variable as a string. It basically just tosses quotes around whatever you literally wrote on the line when you used it. (So passing a string literal would actually send "\"what you wrote\"" to the macro.) This doesn't do anything we can't already do with the language, but I think it looks a little prettier, which might make the functions a bit easier for the user. Though it would still be the same for the lib writer, of course.
Sep 29 2009
Fri, 25 Sep 2009 15:35:11 -0400, Adam D. Ruppe wrote:==== macro max(int a, int b) { return a ~ " > " ~ b ~ " ? " ~ a ~ " : " ~ b; } void main() { auto num1 = 10; auto num2 = 20; auto result = max(num1, num2); } ====While I like and support the idea, I think that hijacking the "macro" keyword now will make it very hard to re-design later. It would be much better to reuse the "mixin" keyword for this since it's exactly what's happening: defining a function for mixing in: mixin max(int a, int b) {...} It could be problematic from the grammar perspective though.
Oct 03 2009
On Sat, Oct 3, 2009 at 9:22 PM, Sergey Gromov <snake.scaly gmail.com> wrote= :While I like and support the idea, I think that hijacking the "macro" keyword now will make it very hard to re-design later. =A0It would be muc=hbetter to reuse the "mixin" keyword for this since it's exactly what's happening: defining a function for mixing in: mixin max(int a, int b) {...} It could be problematic from the grammar perspective though.Newp. 'mixin' could be followed by one of four things: - '(', it's a string mixin. - 'ident' '!', it's a template mixin. - 'ident' ';' it's also a template mixin. - 'ident' '(', it's a mixin declaration. Not tough. But then you're really overloading the keyword by using it for three very different purposes.
Oct 03 2009
Sat, 3 Oct 2009 21:33:37 -0400, Jarrett Billingsley wrote:On Sat, Oct 3, 2009 at 9:22 PM, Sergey Gromov <snake.scaly gmail.com> wrote:I cannot see how this is "very different" from what it does currently. I'm declaring a function intended specifically for mixing in. That's what you usually do. I'm just moving the "mixin" keyword from every single function invocation to its declaration, reducing the unnecessary typing and ugliness. I can see a problem with this approach though, that something that looks lke a function call can be actually a mixin with full access to the container function scope. Explicit mixins are, well, explicit in this respect.While I like and support the idea, I think that hijacking the "macro" keyword now will make it very hard to re-design later. It would be much better to reuse the "mixin" keyword for this since it's exactly what's happening: defining a function for mixing in: mixin max(int a, int b) {...} It could be problematic from the grammar perspective though.Newp. 'mixin' could be followed by one of four things: - '(', it's a string mixin. - 'ident' '!', it's a template mixin. - 'ident' ';' it's also a template mixin. - 'ident' '(', it's a mixin declaration. Not tough. But then you're really overloading the keyword by using it for three very different purposes.
Oct 04 2009
language_fan wrote:Thu, 24 Sep 2009 13:47:21 -0400, Steven Schveighoffer thusly wrote:It scales to a few hundred kLoC if you don't abuse templates (too much) and sacrifice your firstborn to OPTLINK. I don't know what's further, perhaps a hecatomb would do. On a more serious note, the number of template instantiations will probably be more of the logarithmic kind with respect to LoC count. Unless you do everything in a generic way. But writing this sort of code is a major PITA and often a waste of time. -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenodeI actually prefer the compiler to handle the casting versus templates to cut down on template instantiation bloat.I wonder how D scales to 100 MLOC programs as the template instantiations can be troublesome already in < 1000 LOC programs.
Sep 24 2009
On 24/09/2009 19:35, downs wrote:With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?vote++; casts and especially implicit casts are evil. The programmer should always prefer calling a conversion function instead of relying on casts. for example, for FP -> integer conversion the user may need to change the rounding/truncation behavior.
Sep 24 2009