digitalmars.D.announce - DMD 1.005 release
- Walter Bright (4/4) Feb 05 2007 Fixes many bugs, some serious.
- John (2/9) Feb 05 2007 Good stuff.
- janderson (7/14) Feb 05 2007 The new mixin stuff with the quotes seems a bit left of field. However
- Kirk McDonald (12/19) Feb 05 2007 Mwahaha! This program, when run, prints out a copy of its own source. It...
- BCS (5/25) Feb 06 2007 Without the gratuitous stuff that has to be the cleanest quine outside
- =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= (3/8) Feb 06 2007 And if the strings don't mess up with printf, it can be made even shorte...
- Jarrett Billingsley (3/11) Feb 06 2007 "writef".length == "printf".length
- Chris Nicholson-Sauls (7/22) Feb 06 2007 But the "printf" version is -= "import std.stdio;".length + 1;
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (8/13) Feb 07 2007 If you use printf, you should use "import std.c.stdio;"
- Stewart Gordon (5/10) Feb 07 2007 What is your definition of "clean"?
- Kevin Bealer (11/18) Feb 05 2007 You fixed all the bugs I've added in recent memory. Plus, if I
- Don Clugston (3/25) Feb 05 2007 My thoughts exactly.
- Walter Bright (11/20) Feb 06 2007 The irony is that it only took 3 hours to implement, which shows the
- Yauheni Akhotnikau (35/38) Feb 06 2007 Not only that. This opens clean and simple way to use pre-compile-time ...
- Bill Baxter (13/37) Feb 06 2007 For those who haven't seen it, Walter updated
- Pragma (7/31) Feb 06 2007 It's funny you should say that. I was kidding with Kris in IRC last wee...
- Walter Bright (4/16) Feb 06 2007 Andrei and I toyed with that exact idea for a while. It got shot down
- Lionello Lunesu (5/27) Feb 06 2007 You know the next step, right? A template version of htod!
- Walter Bright (4/7) Feb 06 2007 I did shy away from the "execute this shell command and insert its
- BCS (17/22) Feb 06 2007 it needs some string manipulation stuff. I'd be more than happy to let
- BLS (13/18) Feb 06 2007 to figure it out / This means /
- BLS (6/35) Feb 06 2007 I guess here is a need for further explaination.
- Pragma (13/19) Feb 06 2007 Just try to wrap your head around this: http://www.digitalmars.com/d/mix...
- BLS (12/41) Feb 06 2007 Hi Eric,
- Pragma (13/54) Feb 06 2007 I think you answered your own question. :)
- Chris Nicholson-Sauls (5/54) Feb 06 2007 You just showed something that I've been pondering attempting with this....
- renoX (6/14) Feb 07 2007 Enki?
- Frits van Bommel (5/19) Feb 07 2007 Enki: http://www.dsource.org/projects/ddl/wiki/Enki
- BCS (5/28) Feb 07 2007 http://www.dsource.org/projects/ddl/browser/trunk/enki
- renoX (3/36) Feb 07 2007 Thanks, I was a bit lost.
- Chris Nicholson-Sauls (6/32) Feb 06 2007 Combine that with the ever increasing power of Tuples, some of the slowl...
- Walter Bright (4/9) Feb 06 2007 I think you're right. The only thing that makes me uneasy is the
- Sean Kelly (13/24) Feb 06 2007 The most obvious danger is simply being able to eyeball what the source
- BCS (14/25) Feb 06 2007 How are #line directives handled? is their any way to tell the debugger
- Sean Kelly (10/36) Feb 06 2007 I suspect that generating debug info will require the mixed-in code to
- Pragma (6/8) Feb 06 2007 Now there's something that's missing. At least with C compilers, they c...
- BCS (8/16) Feb 06 2007 This could do thing like this:
- Pragma (4/27) Feb 06 2007 BCS: I may be tempted to Enki-ize your work once you're done with that. ...
- Andreas Kochenburger (9/15) Feb 06 2007 I am not a D programmer (yet) only observing what is happening.
- janderson (5/25) Feb 06 2007 I'm not familiar with forth. Can you provide some examples? Does it
- Andreas Kochenburger (17/20) Feb 07 2007 Forth is not a traditional compiler that generates executables from
- Charles D Hixson (48/75) Feb 07 2007 Forth is a Polish, as opposed to reverse Polish, language.
- Kevin Bealer (21/25) Feb 08 2007 I think the comparison to LISP is a good way to think about forth:
- Andreas Kochenburger (6/15) Feb 08 2007 Before someone thinks, Forth is only a play-thing, see http://www.forth....
- kris (2/25) Feb 08 2007 Yeah, Forth is an incredibly powerful language
- Derek Parnell (11/18) Feb 08 2007 Forth was the first programming language that felt a mystical connection
- Andrei Alexandrescu (See Website For Email) (4/18) Feb 09 2007 There's an extra comma in there that pretty much changes the meaning of
- John Reimer (5/25) Feb 09 2007 Funny!
- Charles D Hixson (20/45) Feb 09 2007 I wouldn't have minded writing that, but there was a mistake
- Andreas Kochenburger (9/15) Feb 11 2007 IMHO the tool (=programming language) should be chosen according to the
- Charles D Hixson (4/23) Feb 11 2007 Glad to hear it's still going... sorry to hear it's soon to be
- Lionello Lunesu (3/10) Feb 06 2007 !!!! This is just what I needed for a compile-time .rc compiler!
- Lars Ivar Igesund (11/18) Feb 06 2007 Sounds like some nice new features, but even though the compiler seems t...
- Frank Benoit (keinfarbton) (1/7) Feb 06 2007 I second that.
- BCS (3/21) Feb 06 2007 I also second that, branch the spec or annotate it *Vary* well. Either
- mike (10/14) Feb 06 2007 Nice!
- Pragma (10/17) Feb 06 2007 "The AssignExpression must evaluate at compile time to a constant string...
- Walter Bright (4/7) Feb 06 2007 It just looks in the default directory. I know this is inadequate for a
- janderson (5/12) Feb 06 2007 The import stuff has been part of C for a long time (in the form of
- BCS (5/21) Feb 06 2007 not quite, I don't think this works in c
- janderson (8/32) Feb 06 2007 No but you could do:
- Walter Bright (14/17) Feb 06 2007 The fundamental difference is that #include inserts *program text*,
- janderson (5/30) Feb 06 2007 They could just add quotes around them in C. Slightly less convenient,
- Walter Bright (14/22) Feb 06 2007 Not exactly. You cannot have multiline string literals in C. You'd have
- mike (17/21) Feb 06 2007 Updated DMD to 1.005 from 1.0 today and now I get this error:
- Thomas Brix Larsen (4/18) Feb 06 2007 It should read: struct _TTF_Font {}
- mike (8/28) Feb 06 2007 Thanks! That worked :)
- Hasan Aljudy (15/22) Feb 06 2007 Wow, this is no small change .. this should've ben dmd 1.2 or something.
- Walter Bright (4/8) Feb 06 2007 DMD will also output a list of files that are textually imported, so bud...
- Derek Parnell (20/31) Feb 06 2007 Thanks Walter! :-(
- BCS (10/28) Feb 06 2007 If bud keep around meta data about what happened last time (building N r...
- Kirk McDonald (7/36) Feb 06 2007 Perhaps it would be feasible to turn bud (and perhaps rebuild) into
- Walter Bright (5/19) Feb 06 2007 The compiler cannot tell what file it'll need to textually import
- Hasan Aljudy (5/22) Feb 06 2007 Really? I always use -full -clean switches. I use build/bud because dmd
- Ary Manzana (14/45) Feb 06 2007 I also like the new features and think the same as you.
- Walter Bright (3/8) Feb 06 2007 True, but on the other hand, specifically not supporting it in the IDE
- Ary Manzana (7/16) Feb 06 2007 I didn't say an IDE won't support it, I said it'll be very hard to get
- Sean Kelly (5/23) Feb 06 2007 Oddly, I've found myself moving away from IDEs over the years, perhaps
- Charlie (11/38) Feb 06 2007 When you inherit code or start to code on an existing project, the
- Walter Bright (11/15) Feb 06 2007 From my point of view, evil uses of it are things like version control:
- Hasan Aljudy (5/27) Feb 06 2007 Why is that evil? I think it's actually a great idea. "versions" are a
- Walter Bright (6/23) Feb 06 2007 The right way to do versions that cut across multiple files is to
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (7/18) Feb 07 2007 How would you use something like autoconf with this approach ?
- Walter Bright (7/28) Feb 07 2007 I've worked with the C approach for many years, and have gotten
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (31/41) Feb 07 2007 OK, see what you mean. And the Makefile would pick which
- Walter Bright (20/62) Feb 07 2007 There isn't if the functions are trivial. But when they get more
- BCS (17/28) Feb 07 2007 And there in lies the primary issue I have with this approach. Say I do
- Walter Bright (6/37) Feb 07 2007 If there's a lot of identical code in this approach, then perhaps the
- BCS (54/60) Feb 07 2007 What about cases where 90% of the code is identical but small bits and
- Walter Bright (36/84) Feb 07 2007 Yes, it would require tiny functions, though I don't agree they hide
- BCS (39/93) Feb 07 2007 The equivalent of this doesn't
- Walter Bright (9/77) Feb 07 2007 I agree the inlining isn't perfect. But in the small number of cases
- BCS (56/76) Feb 07 2007 if it's a const than it should be a static if.
- Kyle Furlong (8/104) Feb 07 2007 All this discussion is moot. The feature exists now, use it how you
- Walter Bright (17/19) Feb 07 2007 I suppose it's like identifier naming conventions. There are ways to do
- Walter Bright (14/50) Feb 07 2007 That depends. if and static if have many differences in how they work.
- BCS (5/11) Feb 07 2007 rename versions.txt to versions.d
- Walter Bright (2/18) Feb 07 2007 No, versions defined in an import do NOT affect the importer.
- BCS (9/30) Feb 07 2007 What?? then how do you implement non trivial vertion logic?
- Sean Kelly (3/8) Feb 07 2007 Do it in a makefile or use constants and static if :-p
- BCS (3/18) Feb 07 2007 If that is what is needed to make things work, then what is the version
- Chad J (7/22) Feb 07 2007 If that's the case, then this is the point where I start to do "evil"
- Derek Parnell (24/37) Feb 07 2007 Not wishing to over promote the Bud tool, but it does implement 'global'
- BCS (3/9) Feb 07 2007 Cool, but I think that would be
- Frits van Bommel (7/18) Feb 08 2007 No, you need both version()s:
- Frits van Bommel (20/36) Feb 07 2007 It doesn't work like that:
- Yauheni Akhotnikau (43/46) Feb 07 2007 Can you provide some examples of DSL the new D feature is intended for?
- Kyle Furlong (2/50) Feb 07 2007 Almost certainly.
- Yauheni Akhotnikau (7/14) Feb 07 2007 :)
- Walter Bright (3/4) Feb 07 2007 Yes, that's exactly the intent. If this can't be made to work, we'll fix...
- Yauheni Akhotnikau (40/44) Feb 07 2007 ix =
- Walter Bright (3/11) Feb 07 2007 The main difficulty is if the DSL needs to access symbols in the rest of...
- Yauheni Akhotnikau (5/7) Feb 07 2007 I agree.
- Walter Bright (5/10) Feb 07 2007 int i = 4;
- Yauheni Akhotnikau (19/28) Feb 07 2007 t =
- Walter Bright (4/34) Feb 08 2007 I see your point, but passing arguments "by name", which is what your
- Yauheni Akhotnikau (16/21) Feb 08 2007 Yes, but here we have two alternative approaches:
- Kyle Furlong (4/52) Feb 07 2007 I agree with the point that metaprogramming needs more control structure...
- Andrei Alexandrescu (See Website For Email) (3/57) Feb 07 2007 Static loops are not very useful without compile-time mutation.
- BCS (24/36) Feb 07 2007 Maybe some sort of const loop would work
- Yauheni Akhotnikau (21/25) Feb 07 2007 I think it is not a good way. Because this leads to two different
- Walter Bright (5/9) Feb 07 2007 That's possible because Ruby is interpreted - its compilation
- Yauheni Akhotnikau (46/55) Feb 08 2007 Yes, I undertand that. But that is my point: in Ruby there are three ste...
- janderson (20/87) Feb 09 2007 On the note of serialization I think you could be able to write
- Yauheni Akhotnikau (45/63) Feb 09 2007 =
- Andrei Alexandrescu (See Website For Email) (23/115) Feb 09 2007 Probably an easier way to go would be:
- janderson (5/40) Feb 09 2007 Some good points, if your going for optimizing the compiler. I was
- Andrei Alexandrescu (See Website For Email) (4/24) Feb 09 2007 Oh, indeed. A template instantiation is all that's needed. (It would use...
- Yauheni Akhotnikau (16/27) Feb 09 2007 On Sat, 10 Feb 2007 03:14:48 +0300, Andrei Alexandrescu (See Website For...
- Serg Kovrov (5/9) Feb 06 2007 I believe by 'evil use', Walter meant evil use of mixins, not IDE's.
- Walter Bright (2/12) Feb 06 2007 Yes. IDEs aren't evil.
- Kevin Bealer (5/17) Feb 08 2007 What about:
- Ary Manzana (2/15) Feb 13 2007 Sorry, I misunderstood.
- BCS (11/18) Feb 06 2007 Cool thought:
- Vladimir Panteleev (8/9) Feb 06 2007 Hmm. What would prevent someone from writing programs like:
- Hasan Aljudy (3/13) Feb 06 2007 Well, theoretically nothing prevents someone from writing a virus in C++...
- Andy Knowles (6/29) Feb 07 2007 But you don't need them to run Vladimir's example, just compile it. The...
- Andrei Alexandrescu (See Website For Email) (3/12) Feb 06 2007 How would the bad person see the output of the compilation?
- Vladimir Panteleev (5/16) Feb 07 2007 In this particular example, the idea is to trick someone to compile a pr...
- Jeff McGlynn (6/30) Feb 10 2007 By asking someone else to compile code for you and send back the
- Andrei Alexandrescu (See Website For Email) (4/36) Feb 10 2007 I see. This is a new scenario indeed. Given previous experience with
- Walter Bright (5/12) Feb 10 2007 The switch will be in the next update.
- Henning Hasemann (25/30) Feb 07 2007 I whould even go one step further and limit import() to just import file...
- Yauheni Akhotnikau (42/51) Feb 13 2007 =
- Vladimir Panteleev (5/6) Feb 13 2007 By definition, makefiles are much more dangerous than source code files....
- Jarrett Billingsley (11/15) Feb 07 2007 I am amazed at the mixin/import features. The ability we have to
-
Jarrett Billingsley
(20/20)
Feb 07 2007
"Jarrett Billingsley"
wrote in message - Bruno Medeiros (11/42) Feb 11 2007 Well, actually you can do that, with the unannounced (in the changelog)
- Walter Bright (2/11) Feb 11 2007 It's unannounced because it doesn't work right yet.
- Bruno Medeiros (6/19) Feb 11 2007 What do you mean? If it's doesn't work right yet, why was it released
- Walter Bright (2/19) Feb 11 2007 It doesn't hurt anything to be there.
- Tomas Lindquist Olsen (14/34) Feb 12 2007 Is there any chance we could have alias template parameters become more
- Walter Bright (3/19) Feb 13 2007 What you're asking for we've been calling "alias expressions". It'll get...
-
Don Clugston
(10/23)
Feb 13 2007
- Kirk McDonald (10/36) Feb 13 2007 Heh, you should see what happened to Pyd when tuples were introduced to
- Walter Bright (3/4) Feb 13 2007 My goal is to make the Boost implementation code look as obsolete as a
- Sean Kelly (12/17) Feb 13 2007 It has nothing to do with the conversation, but your statement reminded
- Walter Bright (5/22) Feb 13 2007 Sounds like that is about the ammunition, not the gun.
- Sean Kelly (7/32) Feb 13 2007 It wasn't an issue until people got sick of standing in two lines facing...
- Walter Bright (7/17) Feb 13 2007 I think the firearm technology drove the tactics. The two line approach
- Sean Kelly (3/23) Feb 14 2007 Huh. That makes a lot of sense.
- Andrei Alexandrescu (See Website For Email) (11/36) Feb 15 2007 Actually the notion of taking cover, now ubiquitously known even by
- Pragma (6/11) Feb 13 2007 LOL
- Walter Bright (8/34) Feb 13 2007 The big problem with .stringof is the following:
- Don Clugston (7/44) Feb 14 2007 Isn't it always going to be true that the scope where stringof is
-
Walter Bright
(3/9)
Feb 15 2007
It obviously needs more work
. - Bruno Medeiros (5/42) Feb 15 2007 Erm, shouldn't T.stringof be "T" and not "Abc" nor even "Foo.Bar.Abc"?
- Walter Bright (2/3) Feb 15 2007 There wouldn't be any point to that.
- Jarrett Billingsley (7/9) Feb 15 2007 Damn! I stopped reading this thread when it got so big, so I completely...
- Andrei Alexandrescu (See Website For Email) (5/25) Feb 07 2007 The ability to transform true code trees will come with D's macro
- Ivan Senji (6/8) Feb 07 2007 I can't believe that so many hours have passes since this post and no
- Walter Bright (8/18) Feb 07 2007 Nothing at the moment but a lot of:
- Andrei Alexandrescu (See Website For Email) (6/26) Feb 07 2007 That's pretty much what I had in mind :o).
- Walter Bright (2/8) Feb 07 2007 Yup, I think the end result will be something we can all be proud of.
- Sean Kelly (2/11) Feb 07 2007 This is great news!
- Kevin Bealer (19/24) Feb 07 2007 I was going to, but I'm still righting the mental furniture that got fli...
- Stewart Gordon (4/10) Feb 07 2007 So now you can write cheat quines in D! But the cheating is at compile ...
- Tom S (8/15) Feb 08 2007 Wow, This is just sweet! Thanks, Walter! :D I'll see what kind of abuse
- don (3/30) Feb 09 2007 I was into Forth, back in the day. The strange thing is, I don't think i...
Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zip
Feb 05 2007
Walter Bright Wrote:Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipGood stuff.
Feb 05 2007
Walter Bright wrote:Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipThe new mixin stuff with the quotes seems a bit left of field. However I'd imagine you could write some very reusable code with the string con-concatenation stuff, although I'll bet it'll make things very hard to debug. Maybe even use the strings for some kinda meta/reflection coding. I can't wait to see some real-world examples. -Joel
Feb 05 2007
Walter Bright wrote:Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipMwahaha! This program, when run, prints out a copy of its own source. It also has some completely gratuitous new-style mixins. // file test.d mixin(`import std.stdio : writefln;`); mixin(`void main() { mixin("writefln(import(\"test.d\"));"); }`); -- Kirk McDonald Pyd: Wrapping Python with D http://pyd.dsource.org
Feb 05 2007
Kirk McDonald wrote:Walter Bright wrote:Without the gratuitous stuff that has to be the cleanest quine outside of bash (in bash an empty file prints nothing) import std.stdio; void main(){writef(import(__FILE__));}Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipMwahaha! This program, when run, prints out a copy of its own source. It also has some completely gratuitous new-style mixins. // file test.d mixin(`import std.stdio : writefln;`); mixin(`void main() { mixin("writefln(import(\"test.d\"));"); }`);
Feb 06 2007
BCS kirjoitti:Without the gratuitous stuff that has to be the cleanest quine outside of bash (in bash an empty file prints nothing) import std.stdio; void main(){writef(import(__FILE__));}And if the strings don't mess up with printf, it can be made even shorter: void main(){printf(import(__FILE__));}
Feb 06 2007
"Jari-Matti Mäkelä" <jmjmak utu.fi.invalid> wrote in message news:eqaban$2l90$1 digitaldaemon.com...BCS kirjoitti:"writef".length == "printf".lengthWithout the gratuitous stuff that has to be the cleanest quine outside of bash (in bash an empty file prints nothing) import std.stdio; void main(){writef(import(__FILE__));}And if the strings don't mess up with printf, it can be made even shorter: void main(){printf(import(__FILE__));}
Feb 06 2007
Jarrett Billingsley wrote:"Jari-Matti Mäkelä" <jmjmak utu.fi.invalid> wrote in message news:eqaban$2l90$1 digitaldaemon.com...But the "printf" version is -= "import std.stdio;".length + 1; That said, for examplar|demonstrative D code I'd just assume avoid printf regardless. It just isn't "the D way." Personal preferance, though, would be: import tango.io.Stdout; void main(){Stdout(import(__FILE__));} -- Chris Nicholson-SaulsBCS kirjoitti:"writef".length == "printf".lengthWithout the gratuitous stuff that has to be the cleanest quine outside of bash (in bash an empty file prints nothing) import std.stdio; void main(){writef(import(__FILE__));}And if the strings don't mess up with printf, it can be made even shorter: void main(){printf(import(__FILE__));}
Feb 06 2007
Chris Nicholson-Sauls wrote:If you use printf, you should use "import std.c.stdio;" That it works without it is a long-standing bug, IMHO."writef".length == "printf".lengthBut the "printf" version is -= "import std.stdio;".length + 1;That said, for examplar|demonstrative D code I'd just assume avoid printf regardless. It just isn't "the D way."I don't think there is anything inherently wrong with using printf or the rest of the C standard library, as long as it is explicitly imported by the D code ? Having "printf" defined in Object is evil, though... --anders
Feb 07 2007
BCS Wrote: <snip>Without the gratuitous stuff that has to be the cleanest quine outside of bash (in bash an empty file prints nothing) import std.stdio; void main(){writef(import(__FILE__));}What is your definition of "clean"? Moreover, there are many languages in which an empty source file is a null program - BASIC, Perl and probably most shell scripting languages (indeed, probably most scripting languages) have this characteristic. In the course of history there have even been one or two C compliers that did this. Stewart.
Feb 07 2007
Walter Bright wrote:Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipYou fixed all the bugs I've added in recent memory. Plus, if I understand correctly, the implications of some of these features is staggering... It looks like one could write a few hundred line module that can pull in and do compile-time interpreting of a language of the complexity of say, Scheme. And the code in the module could be both readable and straightforward... And the results would be absorbed into the calling code as normal optimizable statements... "I warn you, Doctor -- man was not meant to have this kind of power!" Kevin
Feb 05 2007
Kevin Bealer wrote:Walter Bright wrote:My thoughts exactly. And it only warrants a version number increase of 0.001 ??? <g>Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipYou fixed all the bugs I've added in recent memory. Plus, if I understand correctly, the implications of some of these features is staggering... It looks like one could write a few hundred line module that can pull in and do compile-time interpreting of a language of the complexity of say, Scheme. And the code in the module could be both readable and straightforward... And the results would be absorbed into the calling code as normal optimizable statements... "I warn you, Doctor -- man was not meant to have this kind of power!" Kevin
Feb 05 2007
Kevin Bealer wrote:You fixed all the bugs I've added in recent memory. Plus, if I understand correctly, the implications of some of these features is staggering... It looks like one could write a few hundred line module that can pull in and do compile-time interpreting of a language of the complexity of say, Scheme. And the code in the module could be both readable and straightforward... And the results would be absorbed into the calling code as normal optimizable statements...The irony is that it only took 3 hours to implement, which shows the power of having the lexing, parsing, and semantic passes be logically distinct. The idea is to enable the creation of DSLs (Domain Specific Languages) that don't have the crippling problem C++ expression templates have - that of being stuck with C++ operators and precedence. To make this work, however, one must be able to manipulate strings at compile time. I've made a start on a library to do this, std.metastrings, based on earlier work by Don Clugston and Eric Anderton. This is just the start of what's going to happen with D 2.0.
Feb 06 2007
The idea is to enable the creation of DSLs (Domain Specific Languages)==that don't have the crippling problem C++ expression templates have - ==that of being stuck with C++ operators and precedence.Not only that. This opens clean and simple way to use pre-compile-time = code generation. For example: // greeting.d: import std.stdio; class Greeting { mixin( import( "greeting.impl.d" ) ); } void main() { auto g =3D new Greeting; g.hello(); g.bye(); } // greeting.impl.d: void hello() { writefln( "Hello!" ); } void bye() { writefln( "Bye!" ); } Where the content of greeting.impl.d can be generated by some = domain-specific tool (such as ASN.1 serializator/deserializator = generators). It's a very good news! Thanks! -- = Regards, Yauheni Akhotnikau
Feb 06 2007
Walter Bright wrote:Kevin Bealer wrote:For those who haven't seen it, Walter updated http://www.digitalmars.com/d/mixin.html with a simple example of what you can do with the mixin string mojo. Phobos also has new documentation for metastrings: http://www.digitalmars.com/d/phobos/std_metastrings.html It looks like this feature is calling out for some sort of new 'here document' syntax, so that the code in strings can look and read more like code. It certainly seems to solve the long standing 'can't generate identifiers at compile time' feature request. And then some. :-) It'll be very exciting to see what people come up with! --bbYou fixed all the bugs I've added in recent memory. Plus, if I understand correctly, the implications of some of these features is staggering... It looks like one could write a few hundred line module that can pull in and do compile-time interpreting of a language of the complexity of say, Scheme. And the code in the module could be both readable and straightforward... And the results would be absorbed into the calling code as normal optimizable statements...The irony is that it only took 3 hours to implement, which shows the power of having the lexing, parsing, and semantic passes be logically distinct. The idea is to enable the creation of DSLs (Domain Specific Languages) that don't have the crippling problem C++ expression templates have - that of being stuck with C++ operators and precedence. To make this work, however, one must be able to manipulate strings at compile time. I've made a start on a library to do this, std.metastrings, based on earlier work by Don Clugston and Eric Anderton. This is just the start of what's going to happen with D 2.0.
Feb 06 2007
Walter Bright wrote:Kevin Bealer wrote:It's funny you should say that. I was kidding with Kris in IRC last week about how you could just slap a copy of DMDScript in the compiler and let us talk to it directly from within templates. While this isn't letting us muck about with the AST, to create specalized grammars, this is certainly a more elegant solution. ... and it doesn't even require a separate syntax.You fixed all the bugs I've added in recent memory. Plus, if I understand correctly, the implications of some of these features is staggering... It looks like one could write a few hundred line module that can pull in and do compile-time interpreting of a language of the complexity of say, Scheme. And the code in the module could be both readable and straightforward... And the results would be absorbed into the calling code as normal optimizable statements...The irony is that it only took 3 hours to implement, which shows the power of having the lexing, parsing, and semantic passes be logically distinct. The idea is to enable the creation of DSLs (Domain Specific Languages) that don't have the crippling problem C++ expression templates have - that of being stuck with C++ operators and precedence.To make this work, however, one must be able to manipulate strings at compile time. I've made a start on a library to do this, std.metastrings, based on earlier work by Don Clugston and Eric Anderton. This is just the start of what's going to happen with D 2.0.-- - EricAnderton at yahoo
Feb 06 2007
Pragma wrote:Walter Bright wrote:Andrei and I toyed with that exact idea for a while. It got shot down after it became clear that since DMDScript has a "same-only-different" syntax from D, it would be terribly confusing.The idea is to enable the creation of DSLs (Domain Specific Languages) that don't have the crippling problem C++ expression templates have - that of being stuck with C++ operators and precedence.It's funny you should say that. I was kidding with Kris in IRC last week about how you could just slap a copy of DMDScript in the compiler and let us talk to it directly from within templates. While this isn't letting us muck about with the AST, to create specalized grammars, this is certainly a more elegant solution. ... and it doesn't even require a separate syntax.
Feb 06 2007
Walter Bright wrote:Kevin Bealer wrote:You know the next step, right? A template version of htod! include!("gl.h"); :D L.You fixed all the bugs I've added in recent memory. Plus, if I understand correctly, the implications of some of these features is staggering... It looks like one could write a few hundred line module that can pull in and do compile-time interpreting of a language of the complexity of say, Scheme. And the code in the module could be both readable and straightforward... And the results would be absorbed into the calling code as normal optimizable statements...The irony is that it only took 3 hours to implement, which shows the power of having the lexing, parsing, and semantic passes be logically distinct. The idea is to enable the creation of DSLs (Domain Specific Languages) that don't have the crippling problem C++ expression templates have - that of being stuck with C++ operators and precedence. To make this work, however, one must be able to manipulate strings at compile time. I've made a start on a library to do this, std.metastrings, based on earlier work by Don Clugston and Eric Anderton.
Feb 06 2007
Lionello Lunesu wrote:You know the next step, right? A template version of htod! include!("gl.h");I did shy away from the "execute this shell command and insert its output into a string literal" because that would turn a D compiler into a huge security risk.
Feb 06 2007
Walter Bright wrote:To make this work, however, one must be able to manipulate strings at compile time. I've made a start on a library to do this, std.metastrings, based on earlier work by Don Clugston and Eric Anderton. This is just the start of what's going to happen with D 2.0.it needs some string manipulation stuff. I'd be more than happy to let you put the string templates from dparse in. It has template to: Discard leading white space return a slice up to the first white space char return a slice starting with the first white space char Return a slice up-to but not including the first instance of t. Return a slice starting after the first instance of t and containing the rest of the string. discard [ ]* then return [a-zA-Z_][a-zA-Z0-9_]* non-string type template return tuple with string broken up by d return tuple with string broken up by white space tuple cdr (think lisp) check if anything in tuple begins with a given prefix source at: http://www.dsource.org/projects/scrapple/browser/trunk/dparser/dparse.d
Feb 06 2007
Walter Bright schrieb:The idea is to enable the creation of DSLs (Domain Specific Languages)Kevin Bealer schrieb :It looks like one could write a few hundred line module that can pull in and do compile-time interpreting of a language of the complexityto figure it out / This means / procedure foo( num1, num2 ) return aValue or PROCEDURE fo IN PARAMETERS num1, num2 OUT PARAMETERS aValue Is this something I can establish in D since 1.005 ? ? Bjoern Kevin Bealer schrieb:of say Scheme.
Feb 06 2007
I guess here is a need for further explaination. Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way. I mean it is difficult to realize the implications. Bjoern BLS schrieb:Walter Bright schrieb: > The idea is to enable the creation of DSLs (Domain Specific Languages) Kevin Bealer schrieb : > It looks like one could write a few hundred line module that can pull > in and do compile-time interpreting of a language of the complexity > > of say Scheme. to figure it out / This means / procedure foo( num1, num2 ) return aValue or PROCEDURE fo IN PARAMETERS num1, num2 OUT PARAMETERS aValue Is this something I can establish in D since 1.005 ? ? Bjoern Kevin Bealer schrieb:
Feb 06 2007
BLS wrote:I guess here is a need for further explaination. Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way. I mean it is difficult to realize the implications. BjoernJust try to wrap your head around this: http://www.digitalmars.com/d/mixin.html template GenStruct(char[] Name, char[] M1) { const char[] GenStruct = "struct " ~ Name ~ "{ int " ~ M1 ~ "; }"; } mixin(GenStruct!("Foo", "bar")); //which generates: struct Foo { int bar; } In short this means that we can have *100%* arbitrary code generation at compile time, w/o need of a new grammar to support the capability. -- - EricAnderton at yahoo
Feb 06 2007
Pragma schrieb:BLS wrote:Hi Eric, I am able to read and understand the code. (not nessesarily the far reaching implications) But the generated code is still D. So what does it mean : Walter Bright schrieb:I guess here is a need for further explaination. Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way. I mean it is difficult to realize the implications. BjoernJust try to wrap your head around this: http://www.digitalmars.com/d/mixin.html template GenStruct(char[] Name, char[] M1) { const char[] GenStruct = "struct " ~ Name ~ "{ int " ~ M1 ~ "; }"; } mixin(GenStruct!("Foo", "bar")); //which generates: struct Foo { int bar; } In short this means that we can have *100%* arbitrary code generation at compile time, w/o need of a new grammar to support the capability.The idea is to enable the creation of DSLs (Domain Specific Languages)How ? Bjoern Post scriptum I can imagine the following scenario : D Compiler is calling a Translator, a modified Enki f.i. to translate a Domain Specific Language into D ... strange
Feb 06 2007
BLS wrote:Pragma schrieb:I think you answered your own question. :) Take the compile-time regexp lib that Don and I wrote a while back. Technically, Regular-expressions are a DSL of sorts. This feature just makes the implementation of stuff like that easier. The end result will still be D code. auto widget = CreateNewWidget!("Some DSL Code"); I was confused too, since the wording could be interpreted as allowing you to just code in some other language, wherever you want. This is not the case. Ultimately, any DSL implemented in this fashion is going to have to operate on static strings.BLS wrote:Hi Eric, I am able to read and understand the code. (not nessesarily the far reaching implications) But the generated code is still D. So what does it mean : Walter Bright schrieb: > The idea is to enable the creation of DSLs (Domain Specific Languages) How ? BjoernI guess here is a need for further explaination. Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way. I mean it is difficult to realize the implications. BjoernJust try to wrap your head around this: http://www.digitalmars.com/d/mixin.html template GenStruct(char[] Name, char[] M1) { const char[] GenStruct = "struct " ~ Name ~ "{ int " ~ M1 ~ "; }"; } mixin(GenStruct!("Foo", "bar")); //which generates: struct Foo { int bar; } In short this means that we can have *100%* arbitrary code generation at compile time, w/o need of a new grammar to support the capability.I can imagine the following scenario : D Compiler is calling a Translator, a modified Enki f.i. to translate a Domain Specific Language into D ... strangeI've thought about that too- much like BCS's work. The only thing keeping me from doing this *was* that the code generated would be largely inferior to that created by an external program. Thanks to the new syntax of mixin(), this is no longer the case. -- - EricAnderton at yahoo
Feb 06 2007
Pragma wrote:BLS wrote:You just showed something that I've been pondering attempting with this. Namely a GUI library that builds all forms/controls/etc from some sort of markup (probably modified XML or JSON), either at runtime /or/ compile-time. -- Chris Nicholson-SaulsPragma schrieb:I think you answered your own question. :) Take the compile-time regexp lib that Don and I wrote a while back. Technically, Regular-expressions are a DSL of sorts. This feature just makes the implementation of stuff like that easier. The end result will still be D code. auto widget = CreateNewWidget!("Some DSL Code");BLS wrote:Hi Eric, I am able to read and understand the code. (not nessesarily the far reaching implications) But the generated code is still D. So what does it mean : Walter Bright schrieb: > The idea is to enable the creation of DSLs (Domain Specific Languages) How ? BjoernI guess here is a need for further explaination. Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way. I mean it is difficult to realize the implications. BjoernJust try to wrap your head around this: http://www.digitalmars.com/d/mixin.html template GenStruct(char[] Name, char[] M1) { const char[] GenStruct = "struct " ~ Name ~ "{ int " ~ M1 ~ "; }"; } mixin(GenStruct!("Foo", "bar")); //which generates: struct Foo { int bar; } In short this means that we can have *100%* arbitrary code generation at compile time, w/o need of a new grammar to support the capability.
Feb 06 2007
Pragma a écrit :BLS wrote:Enki? BCS? Could you avoid mysterious references? Regards, renoXPragma schrieb:I've thought about that too- much like BCS's work. The only thingBLS wrote:I can imagine the following scenario : D Compiler is calling a Translator, a modified Enki f.i. to translate a Domain Specific Language into D ... strange
Feb 07 2007
renoX wrote:Pragma a écrit :Enki: http://www.dsource.org/projects/ddl/wiki/Enki BCS is a poster in these newsgroups. He's been mentioning a project of his called dparser lately: http://www.dsource.org/projects/scrapple/browser/trunk/dparser/dparse.dBLS wrote:Enki? BCS? Could you avoid mysterious references?Pragma schrieb:I've thought about that too- much like BCS's work. The only thingBLS wrote:I can imagine the following scenario : D Compiler is calling a Translator, a modified Enki f.i. to translate a Domain Specific Language into D ... strange
Feb 07 2007
renoX wrote:Pragma a écrit :http://www.dsource.org/projects/ddl/browser/trunk/enki written by PragmaBLS wrote:Enki?Pragma schrieb:I've thought about that too- much like BCS's work. The only thingBLS wrote:I can imagine the following scenario : D Compiler is calling a Translator, a modified Enki f.i. to translate a Domain Specific Language into D ... strangeBCS?http://www.dsource.org/projects/scrapple/browser/trunk/dparser/dparse.d written by me (BCS)Could you avoid mysterious references? Regards, renoX
Feb 07 2007
BCS a écrit :renoX wrote:Thanks, I was a bit lost. renoXPragma a écrit :http://www.dsource.org/projects/ddl/browser/trunk/enki written by PragmaBLS wrote:Enki?Pragma schrieb:I've thought about that too- much like BCS's work. The only thingBLS wrote:I can imagine the following scenario : D Compiler is calling a Translator, a modified Enki f.i. to translate a Domain Specific Language into D ... strangeBCS?http://www.dsource.org/projects/scrapple/browser/trunk/dparser/dparse.d written by me (BCS)Could you avoid mysterious references? Regards, renoX
Feb 07 2007
Pragma wrote:BLS wrote:Combine that with the ever increasing power of Tuples, some of the slowly improving type info, and compile-time string manipulation.... and you've got programs that write programs for writing programs that generate the original program automatically. o_O I like it. Might even scrap some old code in favor of it. -- Chris Nicholson-SaulsI guess here is a need for further explaination. Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way. I mean it is difficult to realize the implications. BjoernJust try to wrap your head around this: http://www.digitalmars.com/d/mixin.html template GenStruct(char[] Name, char[] M1) { const char[] GenStruct = "struct " ~ Name ~ "{ int " ~ M1 ~ "; }"; } mixin(GenStruct!("Foo", "bar")); //which generates: struct Foo { int bar; } In short this means that we can have *100%* arbitrary code generation at compile time, w/o need of a new grammar to support the capability.
Feb 06 2007
BLS wrote:I guess here is a need for further explaination. Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way. I mean it is difficult to realize the implications.I think you're right. The only thing that makes me uneasy is the "preprocessor abuse" that comes up in C++. We should be careful in how we use this, lest the cuticle side of the thumb take over.
Feb 06 2007
Walter Bright wrote:BLS wrote:The most obvious danger is simply being able to eyeball what the source code for a module actually is, but that's been an issue for any sufficiently complex template code anyway. What I like about this feature is that it improves upon the power of macros but does so without providing a method for changing the meaning of existing symbols (the "#define if while" problem). It also requires almost no new language features, so it shouldn't have a tremendous learning curve. Finally, since all this works via strings, it should be easy to determine what's actually going on simply by tossing in a few pragma(msg) statements. If there were a way to emit the "expanded" source we could even use this as a "standalone" code generation tool of sorts. Nice work! SeanI guess here is a need for further explaination. Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way. I mean it is difficult to realize the implications.I think you're right. The only thing that makes me uneasy is the "preprocessor abuse" that comes up in C++. We should be careful in how we use this, lest the cuticle side of the thumb take over.
Feb 06 2007
Sean Kelly wrote:The most obvious danger is simply being able to eyeball what the source code for a module actually is, but that's been an issue for any sufficiently complex template code anyway.How are #line directives handled? is their any way to tell the debugger to look at another file: mixin(MixInThisFile("foo")); // results in this // stuff #line foo, 127 // stuff from foo:127 #line ... // revert back to original file:line Then, in the debugger, it would start stepping you through foo in the correct place.If there were a way to emit the "expanded" source we could even use this as a "standalone" code generation tool of sorts. Nice work!Put in a pragma msg in place of the mixin and you get the code. maybe a mixin(string, filename) form would be nice. It would dump to given file as well as generate code.Sean
Feb 06 2007
BCS wrote:Sean Kelly wrote:I suspect that generating debug info will require the mixed-in code to be expanded in place with the proper #line directives, etc, in the object file.The most obvious danger is simply being able to eyeball what the source code for a module actually is, but that's been an issue for any sufficiently complex template code anyway.How are #line directives handled? is their any way to tell the debugger to look at another file: mixin(MixInThisFile("foo")); // results in this // stuff #line foo, 127 // stuff from foo:127 #line ... // revert back to original file:line Then, in the debugger, it would start stepping you through foo in the correct place.Yup. I think for a standalone code generator, it would probably be better to generate the output file completely through pragma(msg) so as to omit the template code used for processing the mixins. For example, I figure it shouldn't be terribly difficult to do D codegen from a UML file in template code, etc. SeanIf there were a way to emit the "expanded" source we could even use this as a "standalone" code generation tool of sorts. Nice work!Put in a pragma msg in place of the mixin and you get the code.
Feb 06 2007
Sean Kelly wrote:If there were a way to emit the "expanded" source we could even use this as a "standalone" code generation tool of sorts.Now there's something that's missing. At least with C compilers, they can usually be asked to spit out what things look like after the pre-processor is done with it. Getting the same kind of results from DMD, after all templates are evaluated would be great for diagnostics and debugging. -- - EricAnderton at yahoo
Feb 06 2007
BLS wrote:I guess here is a need for further explaination. Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way. I mean it is difficult to realize the implications. BjoernThis could do thing like this: BuildBarserFromFileSpec!("foo.bnf") that would import "foo.bnf", parser a BNF grammar, and build a parser from it. It even avoids the need to use functions for callbacks. p.s. I'm going to have to try and re-implement dparse using this. Darn you Walter!!! I don't have time for this (cool stuff)!!! <G>
Feb 06 2007
BCS wrote:BLS wrote:BCS: I may be tempted to Enki-ize your work once you're done with that. I think a compile-time rendition is due. ;) -- - EricAnderton at yahooI guess here is a need for further explaination. Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way. I mean it is difficult to realize the implications. BjoernThis could do thing like this: BuildBarserFromFileSpec!("foo.bnf") that would import "foo.bnf", parser a BNF grammar, and build a parser from it. It even avoids the need to use functions for callbacks. p.s. I'm going to have to try and re-implement dparse using this. Darn you Walter!!! I don't have time for this (cool stuff)!!! <G>
Feb 06 2007
Pragma wrote:BCS wrote:Done? What is that? I haven't heard the term before. <g>p.s. I'm going to have to try and re-implement dparse using this.BCS: I may be tempted to Enki-ize your work once you're done with that. I think a compile-time rendition is due. ;)
Feb 06 2007
BCS wrote:Pragma wrote:BCS, you're not working at 3D-realms by any chance, are you? <eg> -- - EricAnderton at yahooBCS wrote:Done? What is that? I haven't heard the term before. <g>p.s. I'm going to have to try and re-implement dparse using this.BCS: I may be tempted to Enki-ize your work once you're done with that. I think a compile-time rendition is due. ;)
Feb 06 2007
Pragma wrote:BCS wrote:no, I'm an Mechanical engineering undergraduate student working in declarative code/system generation (professionally) and secure software systems (academically)Pragma wrote:BCS, you're not working at 3D-realms by any chance, are you? <eg>BCS wrote:Done? What is that? I haven't heard the term before. <g>p.s. I'm going to have to try and re-implement dparse using this.BCS: I may be tempted to Enki-ize your work once you're done with that. I think a compile-time rendition is due. ;)
Feb 06 2007
BLS wrote:I guess here is a need for further explaination. Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way. I mean it is difficult to realize the implications. BjoernI am not a D programmer (yet) only observing what is happening. I compare the new "code generation at compile-time" stuff in D with Forth. Forth also has a built-in interpreter & compiler which extends the language and can also execute macros at compile-time through EVALUATE. Of course Forth is much more low-level than D. But IMO the new mixins are not a "radical programming paradigm change". Perhaps I just did misunderstand something? Andreas
Feb 06 2007
Andreas Kochenburger wrote:BLS wrote:I'm not familiar with forth. Can you provide some examples? Does it allow partial macro definitions. Can you apply string operations on them at compile time? -JoelI guess here is a need for further explaination. Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way. I mean it is difficult to realize the implications. BjoernI am not a D programmer (yet) only observing what is happening. I compare the new "code generation at compile-time" stuff in D with Forth. Forth also has a built-in interpreter & compiler which extends the language and can also execute macros at compile-time through EVALUATE. Of course Forth is much more low-level than D. But IMO the new mixins are not a "radical programming paradigm change". Perhaps I just did misunderstand something? Andreas
Feb 06 2007
janderson wrote:I'm not familiar with forth. Can you provide some examples? Does it allow partial macro definitions. Can you apply string operations on them at compile time?Forth is not a traditional compiler that generates executables from source files. A Forth system includes a built-in interpreter and compiler (and most systems have an assembler too). Source definitions are compiled and linked to the internal dictionary i.e. you extend the system itself. You can not only create application programms, but you can also easily add new features to the compiler e.g. new compiler commands. Macro functions at compile-time are only a small exercise for a Forth programmer. You mark the last defined function IMMEDIATE, and the next time the function is used it is executed _at_compile-time_ ! Please note, Forth and D are playing in different leagues. But you don't always have large object-oriented applications. For the more "bare metal" stuff Forth is flexibler than D. If you never had contact with Forth you will probably find it rather strange: it is a stack-based language and uses post-fix annotation like HP calculators. Andreas
Feb 07 2007
janderson wrote:Andreas Kochenburger wrote:Forth is a Polish, as opposed to reverse Polish, language. Every word understood by the system is a command. Forth doesn't exactly HAVE a grammar. What it has is two stacks. (Sometimes more, but the additional stacks are optional, and their usage is inconsistent at best.) Forth commands generally operate on the stack. There are exceptional commands, those marked IMMEDIATE, which operate on the input stream. E.g.: 1 means push a 1 to the top of the stack. (This is typical of all integer literals. Floats are, or were, not standardized.) + means add together the top two items on the stack (removing them from the stack) and push their sum onto the top of the stack. dup means take the value (number?) at the to of the stack and, without removing it, push it to the top of the stack. does means examine the top of the stack. If it's true, continue execution, if not, skip down to the word following the end marker. It's been too long or I'd give a few more examples. The important thing to note is that words are executed without respect to grammar, but with the ability to determine their context. Forth is very similar to LISP, only with a simpler grammar. I.e., the grammar is simple serial execution, with certain words (those marked immediate) able to manipulate the input stream to determine what will be the next in order. N.B.: I'm discussing a basic Forth system, approximating FIG-FORTH, which is as close to standardized as Forth gets. There have been considerable variations. My favorite was Neon, an Object-Oriented Forth for the Mac from Kyria Systems (now long defunct). If they hadn't died while attempting to transition to MSWind95 I might have ended up as a Forth programmer. But don't confuse Forth, in any of it's variations, with D. Forth didn't really create compiled code...and it also wasn't an interpreter in any normal sense of the term. (I'd say isn't, but I'm not really familiar with current Forths.) Forth was what was called a "Threaded Interpretive Language". It might be best to say that you didn't program Forth, you built a software machine that when run did what you wanted to program to accomplish. OTOH, looked at from a different angle, the closest analog to Forth is Smalltalk. But Smalltalk has too much grammar. Still, they both have that system library that is grown by users...and which makes the environment both richer and more complicated to use than languages like D, where the libraries are more distinct from the language.BLS wrote:I'm not familiar with forth. Can you provide some examples? Does it allow partial macro definitions. Can you apply string operations on them at compile time? -JoelI guess here is a need for further explaination. Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way. I mean it is difficult to realize the implications. BjoernI am not a D programmer (yet) only observing what is happening. I compare the new "code generation at compile-time" stuff in D with Forth. Forth also has a built-in interpreter & compiler which extends the language and can also execute macros at compile-time through EVALUATE. Of course Forth is much more low-level than D. But IMO the new mixins are not a "radical programming paradigm change". Perhaps I just did misunderstand something? Andreas
Feb 07 2007
Charles D Hixson wrote: ...Forth is very similar to LISP, only with a simpler grammar. I.e., the grammar is simple serial execution, with certain words (those marked immediate) able to manipulate the input stream to determine what will be the next in order.I think the comparison to LISP is a good way to think about forth: 1. Write a lisp program, but put the function name after its arguments for every expression. This will be hard to read but by following the parenthesis you can just barely tell what is happening. 2. Remove all the parenthesis. At least 90% of the time, if you remove a symbol from a valid forth program, you get a valid (but incorrect) forth program -- there is almost zero redundancy in the language so errors are almost never detectable at compile time, which means you should write short clear functions. But the central feature of FORTH is that the compiler and runtime can be made mind-bogglingly small. I think the run time speed for a naive interpretation is probably somewhere between C and interpreted bytecode. From this page about tiny4th: http://www.seanet.com/~karllunt/tiny4th "The run-time engine takes up less than 1K of code space and the p-codes are so dense that you can get a lot of robot functionality in just 2K." Of course, that's a compiler; an interactive language environment can be used for prototyping (like with lisp) and that will run a bit bigger. Kevin
Feb 08 2007
Kevin Bealer wrote:Charles D Hixson wrote: But the central feature of FORTH is that the compiler and runtime can be made mind-bogglingly small. I think the run time speed for a naive interpretation is probably somewhere between C and interpreted bytecode. From this page about tiny4th: http://www.seanet.com/~karllunt/tiny4th "The run-time engine takes up less than 1K of code space and the p-codes are so dense that you can get a lot of robot functionality in just 2K."Before someone thinks, Forth is only a play-thing, see http://www.forth.com/ There are also excellent freeware versions around, f.ex. http://win32forth.sourceforge.net/ There is even ans ANS / ISO standard for the language. Andreas
Feb 08 2007
Andreas Kochenburger wrote:Kevin Bealer wrote:Yeah, Forth is an incredibly powerful languageCharles D Hixson wrote: But the central feature of FORTH is that the compiler and runtime can be made mind-bogglingly small. I think the run time speed for a naive interpretation is probably somewhere between C and interpreted bytecode. From this page about tiny4th: http://www.seanet.com/~karllunt/tiny4th "The run-time engine takes up less than 1K of code space and the p-codes are so dense that you can get a lot of robot functionality in just 2K."Before someone thinks, Forth is only a play-thing, see http://www.forth.com/ There are also excellent freeware versions around, f.ex. http://win32forth.sourceforge.net/ There is even ans ANS / ISO standard for the language. Andreas
Feb 08 2007
On Thu, 08 Feb 2007 18:57:24 +0100, Andreas Kochenburger wrote:Kevin Bealer wrote:Before someone thinks, Forth is only a play-thing, see http://www.forth.com/ There are also excellent freeware versions around, f.ex. http://win32forth.sourceforge.net/ There is even ans ANS / ISO standard for the language.Forth was the first programming language that felt a mystical connection to. I still love its simplicity/complexity dichotomy. I haven't really touched in years though so I may just go and spend some time with that old friend again. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Justice for David Hicks!" 9/02/2007 10:31:43 AM
Feb 08 2007
Andreas Kochenburger wrote:Kevin Bealer wrote:There's an extra comma in there that pretty much changes the meaning of the sentence :o). AndreiCharles D Hixson wrote: But the central feature of FORTH is that the compiler and runtime can be made mind-bogglingly small. I think the run time speed for a naive interpretation is probably somewhere between C and interpreted bytecode. From this page about tiny4th: http://www.seanet.com/~karllunt/tiny4th "The run-time engine takes up less than 1K of code space and the p-codes are so dense that you can get a lot of robot functionality in just 2K."Before someone thinks, Forth is only a play-thing, see http://www.forth.com/
Feb 09 2007
On Fri, 09 Feb 2007 12:12:24 -0800, Andrei Alexandrescu (See Website For Email) wrote:Andreas Kochenburger wrote:Funny! :D -JJRKevin Bealer wrote:There's an extra comma in there that pretty much changes the meaning of the sentence :o). AndreiCharles D Hixson wrote: But the central feature of FORTH is that the compiler and runtime can be made mind-bogglingly small. I think the run time speed for a naive interpretation is probably somewhere between C and interpreted bytecode. From this page about tiny4th: http://www.seanet.com/~karllunt/tiny4th "The run-time engine takes up less than 1K of code space and the p-codes are so dense that you can get a lot of robot functionality in just 2K."Before someone thinks, Forth is only a play-thing, see http://www.forth.com/
Feb 09 2007
Andreas Kochenburger wrote:Kevin Bealer wrote:I wouldn't have minded writing that, but there was a mistake in editing.Charles D Hixson wrote: But the central feature of FORTH is that the compiler and runtime can be made mind-bogglingly small. I think the run time speed for a naive interpretation is probably somewhere between C and interpreted bytecode. From this page about tiny4th: http://www.seanet.com/~karllunt/tiny4th "The run-time engine takes up less than 1K of code space and the p-codes are so dense that you can get a lot of robot functionality in just 2K."Before someone thinks, Forth is only a play-thing, see http://www.forth.com/ There are also excellent freeware versions around, f.ex. http://win32forth.sourceforge.net/ There is even ans ANS / ISO standard for the language. Andreasetc. was written by Kevin Bealer. Also, I'm not that impressed by SwiftForth (except the price they charge, THAT'S impressive). OTOH, I'm running Linux, so I can only judge them by their web pages. I tend to think of them as being rather like Allegro Lisp: Enormously more expensive than the competition, and only marginally better. That said, I don't really have any evidence. Were I to select a Forth to use I'm probably pick gforth or bigforth (+ Minos?). Every once in awhile I think of going back to it...but I've lost the books I once had on it. I've lost, sold, given away, or discarded my copies of Forth Dimensions, and it would really be a great deal of effort to get as familiar with it as I once was. So I don't. Neon, though, was impressive. I think there's a version calls MOPS or mops or some such still extant, but I don't know how complete it is, and last I checked it only ran on Mac pre-OSX. (I trust that's no longer true...if not, it's history.)But the central feature of FORTH is that the compiler and runtime can be made mind-bogglingly small. I think the run time speed for a naive interpretation is probably somewhere between C and interpreted bytecode.
Feb 09 2007
Charles D Hixson wrote:Were I to select a Forth to use I'm probably pick gforth or bigforth (+ Minos?).IMHO the tool (=programming language) should be chosen according to the work at hand, and to the mastership one can achieve as an individual with a certain tool. For some people FICL is a good tool http://ficl.sourceforge.net/ It should not be too difficult to incorporate it into D applications as _resident_ interactive debugging aid _during_runtime_.Neon, though, was impressive. I think there's a version calls MOPS or mops or some such still extant, but I don't know how complete it is, and last I checked it only ran on Mac pre-OSX. (I trust that's no longer true...if not, it's history.)See http://powermops.sourceforge.net/index.php/Main_Page
Feb 11 2007
Andreas Kochenburger wrote:Charles D Hixson wrote:Glad to hear it's still going... sorry to hear it's soon to be gone. (The author announces no plans to port to the Intel Macs...well, he's a bit stronger about it than that.)Were I to select a Forth to use I'm probably pick gforth or bigforth (+ Minos?).IMHO the tool (=programming language) should be chosen according to the work at hand, and to the mastership one can achieve as an individual with a certain tool. For some people FICL is a good tool http://ficl.sourceforge.net/ It should not be too difficult to incorporate it into D applications as _resident_ interactive debugging aid _during_runtime_.Neon, though, was impressive. I think there's a version calls MOPS or mops or some such still extant, but I don't know how complete it is, and last I checked it only ran on Mac pre-OSX. (I trust that's no longer true...if not, it's history.)See http://powermops.sourceforge.net/index.php/Main_Page
Feb 11 2007
Walter Bright wrote:Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zip!!!! This is just what I needed for a compile-time .rc compiler! L.
Feb 06 2007
Walter Bright wrote:Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipSounds like some nice new features, but even though the compiler seems to know that these new features are D 2.0, the spec don't show it. I'd suggest to branch the specification now, after all 1.0 shouldn't see any new feature changes. Without this, there is no point in the 1.0 marker whatsoever. -- Lars Ivar Igesund blog at http://larsivi.net DSource & #D: larsivi Dancing the Tango
Feb 06 2007
Sounds like some nice new features, but even though the compiler seems to know that these new features are D 2.0, the spec don't show it. I'd suggest to branch the specification now, after all 1.0 shouldn't see any new feature changes. Without this, there is no point in the 1.0 marker whatsoever.I second that.
Feb 06 2007
Lars Ivar Igesund wrote:Walter Bright wrote:I also second that, branch the spec or annotate it *Vary* well. Either way, the change log should say v2.0 as wellFixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipSounds like some nice new features, but even though the compiler seems to know that these new features are D 2.0, the spec don't show it. I'd suggest to branch the specification now, after all 1.0 shouldn't see any new feature changes. Without this, there is no point in the 1.0 marker whatsoever.
Feb 06 2007
Nice! That new mixin stuff will be great for that stacktrace I'm planning to d= o = for months now ... gotta try that out asap :) -Mike Am 06.02.2007, 05:54 Uhr, schrieb Walter Bright = <newshound digitalmars.com>:Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zip-- = Erstellt mit Operas revolution=E4rem E-Mail-Modul: http://www.opera.com/= mail/
Feb 06 2007
Walter Bright wrote:Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zip"The AssignExpression must evaluate at compile time to a constant string. The text contents of the string must be compilable as a valid StatementList, and is compiled as such.:" Arbitrary code generation?! This ought to make for some really slick compile-time code generators - say goodbye to delegate calling overhead and static variable bloat. The import expression thing has me scratching my head though: what path does DMD use to determine where to find the imported file? (it's not clear in the documentation) Awesome update Walter - thanks again. :) -- - EricAnderton at yahoo
Feb 06 2007
Pragma wrote:The import expression thing has me scratching my head though: what path does DMD use to determine where to find the imported file? (it's not clear in the documentation)It just looks in the default directory. I know this is inadequate for a long term solution, but I wanted to see what people thought of it before spending a lot of effort on the details.
Feb 06 2007
Walter Bright wrote:Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipThe import stuff has been part of C for a long time (in the form of #include), however I've never seen it used. Maybe with string operations it will be useful, but otherwise I don't see the point. =Joel
Feb 06 2007
janderson wrote:Walter Bright wrote:not quite, I don't think this works in c char string[] = "#import<bigstring.txt>" sting gets the value of "#import<bigstring.txt>", not the contents of "bigstring.txt"Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipThe import stuff has been part of C for a long time (in the form of #include), however I've never seen it used. Maybe with string operations it will be useful, but otherwise I don't see the point. =Joel
Feb 06 2007
BCS wrote:janderson wrote:No but you could do: char* string = #import "bigstring.txt" and have quotes in the bigstring.txt D's look nicer but its been around for ages. I'm sure combining it with the mixins will make all the difference. -JoelWalter Bright wrote:not quite, I don't think this works in c char string[] = "#import<bigstring.txt>" sting gets the value of "#import<bigstring.txt>", not the contents of "bigstring.txt"Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipThe import stuff has been part of C for a long time (in the form of #include), however I've never seen it used. Maybe with string operations it will be useful, but otherwise I don't see the point. =Joel
Feb 06 2007
janderson wrote:The import stuff has been part of C for a long time (in the form of #include), however I've never seen it used. Maybe with string operations it will be useful, but otherwise I don't see the point.The fundamental difference is that #include inserts *program text*, while import inserts the contents as a *string literal*. Some things that you can do with import that you cannot do with #include: 1) You can have tech writers write "help text" files, which can then be imported by the programmers as string literals. This means the tech writers do not have to be concerned in the slightest with string syntax. 2) It's an easy way to bind binary data into a program. For example, let's say one wants to embed an icon (.ico) file into your program binary. In C, one would have to write: static unsigned char icon[] = { 0x00, 0x10, 0x53, 0x29, ... }; meaning one must translate the binary data in foo.ico to the hex notation. In D, one can write: static ubyte[] icon = cast(ubyte[])import("foo.ico");
Feb 06 2007
Walter Bright wrote:janderson wrote:They could just add quotes around them in C. Slightly less convenient, never seen anyone use that feature.The import stuff has been part of C for a long time (in the form of #include), however I've never seen it used. Maybe with string operations it will be useful, but otherwise I don't see the point.The fundamental difference is that #include inserts *program text*, while import inserts the contents as a *string literal*. Some things that you can do with import that you cannot do with #include: 1) You can have tech writers write "help text" files, which can then be imported by the programmers as string literals. This means the tech writers do not have to be concerned in the slightest with string syntax.2) It's an easy way to bind binary data into a program. For example, let's say one wants to embed an icon (.ico) file into your program binary. In C, one would have to write: static unsigned char icon[] = { 0x00, 0x10, 0x53, 0x29, ... }; meaning one must translate the binary data in foo.ico to the hex notation. In D, one can write: static ubyte[] icon = cast(ubyte[])import("foo.ico");This is a good point. Maybe it should be on the webpage. -Joel
Feb 06 2007
janderson wrote:Walter Bright wrote:Not exactly. You cannot have multiline string literals in C. You'd have to use \n\ line splicing, and escape any " and \ embedded in the text: "Your text\n\ would have to\n\ look like this\n\ and be careful to\n\ escape any \"s in\n\ the text, as well as\n\ any \\s." Furthermore, string literals are limited to 4095 characters (if one cares about portability). C99 5.2.4.1 These restrictions are annoying enough that I've preferred using runtime reading and loading of the message file instead.Some things that you can do with import that you cannot do with #include: 1) You can have tech writers write "help text" files, which can then be imported by the programmers as string literals. This means the tech writers do not have to be concerned in the slightest with string syntax.They could just add quotes around them in C.
Feb 06 2007
Updated DMD to 1.005 from 1.0 today and now I get this error: ' C:\dmd\src\ext\derelict\sdl\ttf.d(79): struct derelict.sdl.ttf._TTF_Fo= nt = unknown ' size ' C:\dmd\src\ext\derelict\sdl\ttf.d(79): struct derelict.sdl.ttf._TTF_Fo= nt = no size ' yet for forward reference Does anybody know how to fix that? I've already searched the NG, the = derelict forum, upgraded to the latest trunk ... nothing helped so far. -Mike Am 06.02.2007, 05:54 Uhr, schrieb Walter Bright = <newshound digitalmars.com>:Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zip-- = Erstellt mit Operas revolution=E4rem E-Mail-Modul: http://www.opera.com/= mail/
Feb 06 2007
mike wrote:Updated DMD to 1.005 from 1.0 today and now I get this error: ' C:\dmd\src\ext\derelict\sdl\ttf.d(79): struct derelict.sdl.ttf._TTF_Font unknown ' size ' C:\dmd\src\ext\derelict\sdl\ttf.d(79): struct derelict.sdl.ttf._TTF_Font no size ' yet for forward reference Does anybody know how to fix that? I've already searched the NG, the derelict forum, upgraded to the latest trunk ... nothing helped so far. -MikeIt should read: struct _TTF_Font {} http://dsource.org/projects/derelict/browser/trunk/DerelictSDLttf/derelict/sdl/ttf.d - Brix
Feb 06 2007
Thanks! That worked :) Am 06.02.2007, 19:28 Uhr, schrieb Thomas Brix Larsen <brix brix-verden.d= k>:mike wrote:Updated DMD to 1.005 from 1.0 today and now I get this error: ' C:\dmd\src\ext\derelict\sdl\ttf.d(79): struct =derelict.sdl.ttf._TTF_Font unknown ' size ' C:\dmd\src\ext\derelict\sdl\ttf.d(79): struct =r.derelict.sdl.ttf._TTF_Font no size ' yet for forward reference Does anybody know how to fix that? I've already searched the NG, the derelict forum, upgraded to the latest trunk ... nothing helped so fa=lict/sdl/ttf.d-MikeIt should read: struct _TTF_Font {} http://dsource.org/projects/derelict/browser/trunk/DerelictSDLttf/dere=- Brix-- = Erstellt mit Operas revolution=E4rem E-Mail-Modul: http://www.opera.com/= mail/
Feb 06 2007
Walter Bright wrote:Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipWow, this is no small change .. this should've ben dmd 1.2 or something. Now, there's already been alot of talk about what new doors this might open, so I'm not gonna talk about that. What concerns me is that this will make semantic analysis more difficult to implement. Just think about "build/bud" for example, now the author will have to worry about things like: mixin("import x.y.z"); or even worse: mixin(templ1!(something, templ2!(somethingelse), "x.y")); I don't see how it's possible to interpret that without implementing a full compiler. P.S. I know that for "build" all we need is a list of import files, and dmd already has a switch to do that.
Feb 06 2007
Hasan Aljudy wrote:I don't see how it's possible to interpret that without implementing a full compiler.You're right, it isn't possible.P.S. I know that for "build" all we need is a list of import files, and dmd already has a switch to do that.DMD will also output a list of files that are textually imported, so bud can pick them up at least the second time around.
Feb 06 2007
On Tue, 06 Feb 2007 11:55:18 -0800, Walter Bright wrote:Hasan Aljudy wrote:Thanks Walter! :-( Bud is no longer a useful tool because it can no longer do what it was trying to do - namely find out which files needed recompiling and get only that done. Because in order to do that now, it first has to recursively compile each command line file and imported file using the -c -v switches to get a list of the potential files needing to be checked for recompilation. But seeing I've just compiled them to get this list, there is not much point now in /recompiling/ them. Also, mixin-imported files are not necessarily modules but must be treated as code fragments, so they can't be compiled to see if they in-turn effectively import other files! My work here is (un)done. It seems that DMD now needs to be enhanced to do what Rebuild and Bud were trying to do. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 7/02/2007 10:18:52 AMI don't see how it's possible to interpret that without implementing a full compiler.You're right, it isn't possible.P.S. I know that for "build" all we need is a list of import files, and dmd already has a switch to do that.DMD will also output a list of files that are textually imported, so bud can pick them up at least the second time around.
Feb 06 2007
Reply to Derek,Thanks Walter! :-( Bud is no longer a useful tool because it can no longer do what it was trying to do - namely find out which files needed recompiling and get only that done. Because in order to do that now, it first has to recursively compile each command line file and imported file using the -c -v switches to get a list of the potential files needing to be checked for recompilation. But seeing I've just compiled them to get this list, there is not much point now in /recompiling/ them. Also, mixin-imported files are not necessarily modules but must be treated as code fragments, so they can't be compiled to see if they in-turn effectively import other files! My work here is (un)done. It seems that DMD now needs to be enhanced to do what Rebuild and Bud were trying to do.If bud keep around meta data about what happened last time (building N required A, B, C) then if none of those changed, the set of files that can be used can't change. Having that kind of tree would let you do a minimal rebuild even with the new import stuff. Once you go that direction (DMD would have to report the files used) why not have DMD report the public interface of each module? that would let bud notice when a change in a module doesn't demands a rebuild of the modules that import it. Some of this might be possible by watching for actual changes in .di file, not just checking modification dates.
Feb 06 2007
Derek Parnell wrote:On Tue, 06 Feb 2007 11:55:18 -0800, Walter Bright wrote:Perhaps it would be feasible to turn bud (and perhaps rebuild) into Makefile generators. -- Kirk McDonald Pyd: Wrapping Python with D http://pyd.dsource.orgHasan Aljudy wrote:Thanks Walter! :-( Bud is no longer a useful tool because it can no longer do what it was trying to do - namely find out which files needed recompiling and get only that done. Because in order to do that now, it first has to recursively compile each command line file and imported file using the -c -v switches to get a list of the potential files needing to be checked for recompilation. But seeing I've just compiled them to get this list, there is not much point now in /recompiling/ them. Also, mixin-imported files are not necessarily modules but must be treated as code fragments, so they can't be compiled to see if they in-turn effectively import other files! My work here is (un)done. It seems that DMD now needs to be enhanced to do what Rebuild and Bud were trying to do.I don't see how it's possible to interpret that without implementing a full compiler.You're right, it isn't possible.P.S. I know that for "build" all we need is a list of import files, and dmd already has a switch to do that.DMD will also output a list of files that are textually imported, so bud can pick them up at least the second time around.
Feb 06 2007
Derek Parnell wrote:Bud is no longer a useful tool because it can no longer do what it was trying to do - namely find out which files needed recompiling and get only that done. Because in order to do that now, it first has to recursively compile each command line file and imported file using the -c -v switches to get a list of the potential files needing to be checked for recompilation. But seeing I've just compiled them to get this list, there is not much point now in /recompiling/ them. Also, mixin-imported files are not necessarily modules but must be treated as code fragments, so they can't be compiled to see if they in-turn effectively import other files! My work here is (un)done. It seems that DMD now needs to be enhanced to do what Rebuild and Bud were trying to do.The compiler cannot tell what file it'll need to textually import without compiling either, so cannot do a 'make' on textual imports. No tool is perfect; I recommend just ignoring the problem with textual imports. Such shouldn't be used outside of specialized modules.
Feb 06 2007
Derek Parnell wrote:On Tue, 06 Feb 2007 11:55:18 -0800, Walter Bright wrote:Really? I always use -full -clean switches. I use build/bud because dmd is not smart enough to compile all the files needed to make the program. dmd is fast enough to not require one to bother do "selective" compliation. (if one can say so ..)Hasan Aljudy wrote:Thanks Walter! :-( Bud is no longer a useful tool because it can no longer do what it was trying to do - namely find out which files needed recompiling and get only that done.I don't see how it's possible to interpret that without implementing a full compiler.You're right, it isn't possible.P.S. I know that for "build" all we need is a list of import files, and dmd already has a switch to do that.DMD will also output a list of files that are textually imported, so bud can pick them up at least the second time around.
Feb 06 2007
Hasan Aljudy escribió:Walter Bright wrote:I also like the new features and think the same as you. First, I don't know what is the real beneffit of this features. I mean, I want to see a real world example using mixins before thinking they are great (BTW, the first time I saw them PHP inmediately came into my head... even more after the post about """ msg """). Second, this makes even harder to get good IDE support for D. You can have syntax coloring, and that's it. Autocompletion is going to be a very though part: the IDE must act as a compiler, as you say it, to figure out what the program will look like so that it can know what are the declarations available to the programmer. Anyway, I'm still working on Descent, and when I get to that part (which I plan to implement because it's all there, in DMD... I guess?), I'll tell you. :-)Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipWow, this is no small change .. this should've ben dmd 1.2 or something. Now, there's already been alot of talk about what new doors this might open, so I'm not gonna talk about that. What concerns me is that this will make semantic analysis more difficult to implement. Just think about "build/bud" for example, now the author will have to worry about things like: mixin("import x.y.z"); or even worse: mixin(templ1!(something, templ2!(somethingelse), "x.y")); I don't see how it's possible to interpret that without implementing a full compiler. P.S. I know that for "build" all we need is a list of import files, and dmd already has a switch to do that.
Feb 06 2007
Ary Manzana wrote:Second, this makes even harder to get good IDE support for D. You can have syntax coloring, and that's it. Autocompletion is going to be a very though part: the IDE must act as a compiler, as you say it, to figure out what the program will look like so that it can know what are the declarations available to the programmer.True, but on the other hand, specifically not supporting it in the IDE may act as a needed brake on evil uses of it.
Feb 06 2007
Walter Bright escribió:Ary Manzana wrote:I didn't say an IDE won't support it, I said it'll be very hard to get there :-) But... I'm wondering which are the evil uses of it. For me it's now almost impossible not to program with an IDE (big projects, I mean). At least in Java. Maybe compile time stuff will make it such that an IDE won't be needed anymore. But it's very hard for me to see that happening.Second, this makes even harder to get good IDE support for D. You can have syntax coloring, and that's it. Autocompletion is going to be a very though part: the IDE must act as a compiler, as you say it, to figure out what the program will look like so that it can know what are the declarations available to the programmer.True, but on the other hand, specifically not supporting it in the IDE may act as a needed brake on evil uses of it.
Feb 06 2007
Ary Manzana wrote:Walter Bright escribió:Oddly, I've found myself moving away from IDEs over the years, perhaps partially because the editors I like to use aren't IDEs. About the only time I use an IDE any more is for debugging... coding happens elsewhere. SeanAry Manzana wrote:I didn't say an IDE won't support it, I said it'll be very hard to get there :-) But... I'm wondering which are the evil uses of it. For me it's now almost impossible not to program with an IDE (big projects, I mean). At least in Java. Maybe compile time stuff will make it such that an IDE won't be needed anymore. But it's very hard for me to see that happening.Second, this makes even harder to get good IDE support for D. You can have syntax coloring, and that's it. Autocompletion is going to be a very though part: the IDE must act as a compiler, as you say it, to figure out what the program will look like so that it can know what are the declarations available to the programmer.True, but on the other hand, specifically not supporting it in the IDE may act as a needed brake on evil uses of it.
Feb 06 2007
Sean Kelly wrote:Ary Manzana wrote:When you inherit code or start to code on an existing project, the ability to 'ctrl+click' to jump to that variables definition is a huge time saver, otherwise you have to grep through tons of files , and in large libraries the classes may be nested very deep, you might have to ctrl+click 5 times before you get to what you're looking for. I've actually gone the opposite way, drifting towards IDE's over time, even though for 'one-moduler's it remains <insert favorite editor here>. I am really looking forward to descent, I hope you can devote enough time to Ary. CharlieWalter Bright escribió:Oddly, I've found myself moving away from IDEs over the years, perhaps partially because the editors I like to use aren't IDEs. About the only time I use an IDE any more is for debugging... coding happens elsewhere. SeanAry Manzana wrote:I didn't say an IDE won't support it, I said it'll be very hard to get there :-) But... I'm wondering which are the evil uses of it. For me it's now almost impossible not to program with an IDE (big projects, I mean). At least in Java. Maybe compile time stuff will make it such that an IDE won't be needed anymore. But it's very hard for me to see that happening.Second, this makes even harder to get good IDE support for D. You can have syntax coloring, and that's it. Autocompletion is going to be a very though part: the IDE must act as a compiler, as you say it, to figure out what the program will look like so that it can know what are the declarations available to the programmer.True, but on the other hand, specifically not supporting it in the IDE may act as a needed brake on evil uses of it.
Feb 06 2007
Ary Manzana wrote:Walter Bright escribió:From my point of view, evil uses of it are things like version control: mixin(import("versions.txt")); where versions.txt contains: version = FOO; version = BAR; etc., or other uses that subvert the right way to do things. One should think long and hard about using textual import to import D code. What it's for is to: 1) import data for a string constant 2) import code that's in DSL (Domain Specific Language), not D, form.True, but on the other hand, specifically not supporting it in the IDE may act as a needed brake on evil uses of it.But... I'm wondering which are the evil uses of it.
Feb 06 2007
Walter Bright wrote:Ary Manzana wrote:Why is that evil? I think it's actually a great idea. "versions" are a sort of configuration that determines which code should be compiled and which code shouldn't. Storing this configuration in a separate file makes sense to me.Walter Bright escribió:From my point of view, evil uses of it are things like version control: mixin(import("versions.txt")); where versions.txt contains: version = FOO; version = BAR; etc., or other uses that subvert the right way to do things. One should think long and hard about using textual import to import D code.True, but on the other hand, specifically not supporting it in the IDE may act as a needed brake on evil uses of it.But... I'm wondering which are the evil uses of it.What it's for is to: 1) import data for a string constant 2) import code that's in DSL (Domain Specific Language), not D, form.
Feb 06 2007
Hasan Aljudy wrote:Walter Bright wrote:The right way to do versions that cut across multiple files is to abstract the versioning into an API, and implement the different versions in different modules. This is a lot easier to manage when you're dealing with larger, more complex code, although it is more work up front.From my point of view, evil uses of it are things like version control: mixin(import("versions.txt")); where versions.txt contains: version = FOO; version = BAR; etc., or other uses that subvert the right way to do things. One should think long and hard about using textual import to import D code.Why is that evil? I think it's actually a great idea. "versions" are a sort of configuration that determines which code should be compiled and which code shouldn't. Storing this configuration in a separate file makes sense to me.
Feb 06 2007
Walter Bright wrote:How would you use something like autoconf with this approach ? Would it need to generate different Makefiles / D file lists for different options/versions, instead of just -version statements ? Example of things I am thinking about are "__WXGTK__", "UNICODE", or "HAVE_OPENGL". With C/C++, they're usually in a config.h file. --andersWhy is that evil? I think it's actually a great idea. "versions" are a sort of configuration that determines which code should be compiled and which code shouldn't. Storing this configuration in a separate file makes sense to me.The right way to do versions that cut across multiple files is to abstract the versioning into an API, and implement the different versions in different modules. This is a lot easier to manage when you're dealing with larger, more complex code, although it is more work up front.
Feb 07 2007
Anders F Björklund wrote:Walter Bright wrote:I've worked with the C approach for many years, and have gotten increasingly dissatisfied with it. Over time, it leads to conflicting, misused, overlapping version macros. I've also tried the "make an API for the version" method, and have been much more satisfied with it. You can see it at work in the gc implementation (see gclinux.d and win32.d).How would you use something like autoconf with this approach ? Would it need to generate different Makefiles / D file lists for different options/versions, instead of just -version statements ? Example of things I am thinking about are "__WXGTK__", "UNICODE", or "HAVE_OPENGL". With C/C++, they're usually in a config.h file.Why is that evil? I think it's actually a great idea. "versions" are a sort of configuration that determines which code should be compiled and which code shouldn't. Storing this configuration in a separate file makes sense to me.The right way to do versions that cut across multiple files is to abstract the versioning into an API, and implement the different versions in different modules. This is a lot easier to manage when you're dealing with larger, more complex code, although it is more work up front.
Feb 07 2007
Walter Bright wrote:OK, see what you mean. And the Makefile would pick which implementation gets used, for the common interface chosen ? Not sure there's a whole world of difference between the: version(Win32) // or foowin32.d void foo() { ...this... } version(linux) // or foolinux.d void foo() { ...that... } and void foo() { version(Win32) ...this... version(linux) ...that... } But any rate, it's preferred to handle it outside of D. OK. Either through rewriting the code, or in the Makefiles. OK. With autoconf, I normally want the SAME piece of code to work on all platforms - so it does a different approach. For D, I would instead write one piece of code for EACH platform and avoid versioning it (as much as possible) ? I've worked with the "./configure && make" approach for many years and kinda like it, but will try out new ideas. Then again I kinda like the preprocessor too, and prefer writing C over C++, so maybe I'm just stuck on the old. :-) Not changing anything for the "ported" projects (like wxD), but it will be something to keep in mind for future D ones. Will do some thinking on how it would apply to options... (choices, as opposed to just platform/portability macros) --andersExample of things I am thinking about are "__WXGTK__", "UNICODE", or "HAVE_OPENGL". With C/C++, they're usually in a config.h file.I've worked with the C approach for many years, and have gotten increasingly dissatisfied with it. Over time, it leads to conflicting, misused, overlapping version macros. I've also tried the "make an API for the version" method, and have been much more satisfied with it. You can see it at work in the gc implementation (see gclinux.d and win32.d).
Feb 07 2007
Anders F Björklund wrote:Walter Bright wrote:Yes, that's a reasonable way to do it.I've also tried the "make an API for the version" method, and have been much more satisfied with it. You can see it at work in the gc implementation (see gclinux.d and win32.d).OK, see what you mean. And the Makefile would pick which implementation gets used, for the common interface chosen ?Not sure there's a whole world of difference between the: version(Win32) // or foowin32.d void foo() { ...this... } version(linux) // or foolinux.d void foo() { ...that... } and void foo() { version(Win32) ...this... version(linux) ...that... }There isn't if the functions are trivial. But when they get more involved, it becomes a mess. How many times have you had to compile with just the preprocessor just to figure out which branch of the rat's nest of #if's was actually getting compiled? Many years ago, when assembler coding was popular, Microsoft produced a macro library to make coding in assembler sort-of-but-not-quite-like coding in some pseudo-high level language. The layers of macros was so bad that a friend of mine, in order to work on such code written by others, resorted to assembling it, *disassembling* the result, and pasting the disassembled source back into the source file and started over.But any rate, it's preferred to handle it outside of D. OK. Either through rewriting the code, or in the Makefiles. OK. With autoconf, I normally want the SAME piece of code to work on all platforms - so it does a different approach. For D, I would instead write one piece of code for EACH platform and avoid versioning it (as much as possible) ?Yes, in the end, I think that's a more maintainable solution. You'll find your core modules will become much more portable, and you shouldn't need to edit (or even understand) them at all when porting to a new platform. If your job is to port the gc to a new XYZ platform, would you find it easier to edit the long and complicated gcx.d, or just copy gclinux.d to gcXYZ.d and restrict your work to just figuring out how to port a few lines of code with (hopefully) well-defined behavior?I've worked with the "./configure && make" approach for many years and kinda like it, but will try out new ideas. Then again I kinda like the preprocessor too, and prefer writing C over C++, so maybe I'm just stuck on the old. :-) Not changing anything for the "ported" projects (like wxD), but it will be something to keep in mind for future D ones. Will do some thinking on how it would apply to options... (choices, as opposed to just platform/portability macros) --anders
Feb 07 2007
Walter Bright wrote:Yes, in the end, I think that's a more maintainable solution. You'll find your core modules will become much more portable, and you shouldn't need to edit (or even understand) them at all when porting to a new platform. If your job is to port the gc to a new XYZ platform, would you find it easier to edit the long and complicated gcx.d, or just copy gclinux.d to gcXYZ.d and restrict your work to just figuring out how to port a few lines of code with (hopefully) well-defined behavior?And there in lies the primary issue I have with this approach. Say I do the above and then a bug is found in the system independent parts of the module, now I have to extract the fix from a fixed version and reapply it to my version. I am a strong proponent of the theory that you should never have two peaces of /Identical/ code (as in does the exact same thing). It's kinda sorta the Extreme Programming model[*] but that's not where I'm coming from. An example, I am working on a D lexer, it needs to work on 6 type of files ASCII and UTF-8/16BE/16LE/32BE/32LE. also to make things easier downstream, I have it convert all EOLs to \n. Well rather than write 6 scanners, I wrote one that was templated on two types (I think) results in correct conversions. It is about 30 lines long and the sum total difference between the functions is the types on about about 3 lines. Now if at some point I find a bug, I fix it in one place and I'm done. The same sort of thing can apply to other cases. * I think that is the model but I could be remembering the wrong name
Feb 07 2007
BCS wrote:Walter Bright wrote:If there's a lot of identical code in this approach, then perhaps the abstraction layer is drawn in the wrong place. There isn't much in the gc version api implementations.Yes, in the end, I think that's a more maintainable solution. You'll find your core modules will become much more portable, and you shouldn't need to edit (or even understand) them at all when porting to a new platform. If your job is to port the gc to a new XYZ platform, would you find it easier to edit the long and complicated gcx.d, or just copy gclinux.d to gcXYZ.d and restrict your work to just figuring out how to port a few lines of code with (hopefully) well-defined behavior?And there in lies the primary issue I have with this approach. Say I do the above and then a bug is found in the system independent parts of the module, now I have to extract the fix from a fixed version and reapply it to my version. I am a strong proponent of the theory that you should never have two peaces of /Identical/ code (as in does the exact same thing). It's kinda sorta the Extreme Programming model[*] but that's not where I'm coming from.An example, I am working on a D lexer, it needs to work on 6 type of files ASCII and UTF-8/16BE/16LE/32BE/32LE. also to make things easier downstream, I have it convert all EOLs to \n. Well rather than write 6 scanners, I wrote one that was templated on two types (I think) results in correct conversions. It is about 30 lines long and the sum total difference between the functions is the types on about about 3 lines. Now if at some point I find a bug, I fix it in one place and I'm done. The same sort of thing can apply to other cases.Using templates is a great way to write generic code, but it's a different approach than using versions.
Feb 07 2007
Walter Bright wrote:The right way to do versions that cut across multiple files is to abstract the versioning into an API, and implement the different versions in different modules.What about cases where 90% of the code is identical but small bits and peaces are different? If I understand correctly, to do what you suggest would requirer that those bits be put in functions and have several versions of the function somewhere else. This could be a problem in several ways ===Tiny bits of code would requirer tiny functions that would hide what is going on. version(RowMajor) x = table[i][j]; else // RowMinor x = table[j][i]; ====Empty else cases would result in do nothing functions: version(StrongChecks) { if(foo) ... if(bar) ... ... } //empty else ====You can't break across function calls switch(i) { case 1: version(Baz) if(baz) break; else break; case 2: ...// lots of un versioned code } or switch(i) { version(Baz) { case 1: if(baz) break; } case 2: ...// lots of un versioned code version(!Baz) { case 1: } } ====lots of version combinations version(Foo) i = foo(i); version(Boo) i = boo(i); version(Fig) i = fig(i); version(Baz) i = baz(i); version(Bar) i = bar(i); //32 options??? Are these valid concerns? Am I misunderstanding what you said?
Feb 07 2007
BCS wrote:Walter Bright wrote:Yes, it would require tiny functions, though I don't agree they hide what is going on. Presumably a descriptive name would be used for it. One of the nice things about it is that porting the code requires generating a new module with the right implementations in it, which is a lot easier than going through checking all the #ifdef's (yes, I know one shouldn't have to do that, but in practice you ALWAYS have to because the macros always get misapplied, and often get forgotten to even apply). With an API, it is difficult to forget to use it, and difficult to use the wrong macro. For example, when writing portable C code, one is often faced with the macros: __GNUC__ for the Gnu compiler linux for the host operating system TARGET_LINUX for the target operating system we're cross compiling for I can't even count the number of times __GNUC__ was being used to decide whether we're compiling for windows or linux, or the host operating system was confused with the target: #if __GNUC__ #include <pthreads.h> #else #include <windows.h> #endif AAAARRRRRGGGGGHHHHH!!! That, my friends, is evil. Now, if one abstracted away what one was *doing* with threads, then one just does: import mythreadapi; and provide a different implementation of mythreadapi for windows or linux. It's a LOT harder to screw that up.The right way to do versions that cut across multiple files is to abstract the versioning into an API, and implement the different versions in different modules.What about cases where 90% of the code is identical but small bits and peaces are different? If I understand correctly, to do what you suggest would requirer that those bits be put in functions and have several versions of the function somewhere else. This could be a problem in several ways ===Tiny bits of code would requirer tiny functions that would hide what is going on.version(RowMajor) x = table[i][j]; else // RowMinor x = table[j][i];int GetRow(i,j) { return table[i][j]; } The function gets inlined.====Empty else cases would result in do nothing functions: version(StrongChecks) { if(foo) ... if(bar) ... ... } //empty else ====You can't break across function calls switch(i) { case 1: version(Baz) if(baz) break; else break; case 2: ...// lots of un versioned code }if (globalversion.baz && baz) break;====lots of version combinations version(Foo) i = foo(i); version(Boo) i = boo(i); version(Fig) i = fig(i); version(Baz) i = baz(i); version(Bar) i = bar(i); //32 options???i = abc(i); // a different abc is implemented for each version.Are these valid concerns? Am I misunderstanding what you said?They are valid concerns, you're just used to thinking in terms of the C preprocessor.
Feb 07 2007
Walter Bright wrote:#if __GNUC__ #include <pthreads.h> #else #include <windows.h> #endif AAAARRRRRGGGGGHHHHH!!! That, my friends, is evil.agreed.BCS wrote:The equivalent of this doesn't version(RowMajor) { x = 0 for(i=0;i<max;i++) x+=table[i][j]; } else // RowMinor { x = 0 for(i=0;i<max;i++) x+=table[j][i]; } and IIRC this doesn't ether version(X86) // avoid overflow in midpoint calculations { asm { MOV low EAX; ADD EAX hi; RCR EAX 1; MOV EAX mid; } } else { mid = (hi-low)/2 + low; }version(RowMajor) x = table[i][j]; else // RowMinor x = table[j][i];int GetRow(i,j) { return table[i][j]; } The function gets inlined.The point is to have all of the versioning done by the time you link, that leaves a runtime check for version info.====You can't break across function calls switch(i) { case 1: version(Baz) if(baz) break; else break; case 2: ...// lots of un versioned code }if (globalversion.baz && baz) break;All 32 possibilities??? What if there are 16 independent versions? that's 64K functions! And no that is not an unlikely case, say "i" is a parse tree and we want to add different types of annotation depending on what features are enabled.====lots of version combinations version(Foo) i = foo(i); version(Boo) i = boo(i); version(Fig) i = fig(i); version(Baz) i = baz(i); version(Bar) i = bar(i); //32 options???i = abc(i); // a different abc is implemented for each version.I have barely ever used CPP for that type of thing so I wasn't ever used to thinking that way in the first place. <g>Are these valid concerns? Am I misunderstanding what you said?They are valid concerns, you're just used to thinking in terms of the C preprocessor.
Feb 07 2007
BCS wrote:Walter Bright wrote:I agree the inlining isn't perfect. But in the small number of cases where this matters, you can use the version=XXX command line switch.The function gets inlined.The equivalent of this doesn't version(RowMajor) { x = 0 for(i=0;i<max;i++) x+=table[i][j]; } else // RowMinor { x = 0 for(i=0;i<max;i++) x+=table[j][i]; } and IIRC this doesn't ether version(X86) // avoid overflow in midpoint calculations { asm { MOV low EAX; ADD EAX hi; RCR EAX 1; MOV EAX mid; } } else { mid = (hi-low)/2 + low; }Not if it's a const.The point is to have all of the versioning done by the time you link, that leaves a runtime check for version info.====You can't break across function calls switch(i) { case 1: version(Baz) if(baz) break; else break; case 2: ...// lots of un versioned code }if (globalversion.baz && baz) break;I'd use bit flags instead of versions for such things. If I had a situation with 32*16 version combinations, I think I'd seriously consider reengineering what the program considers as a "version". After all, do you really want to generate 64,000 binaries? How are you going to test them <g>?All 32 possibilities??? What if there are 16 independent versions? that's 64K functions! And no that is not an unlikely case, say "i" is a parse tree and we want to add different types of annotation depending on what features are enabled.====lots of version combinations version(Foo) i = foo(i); version(Boo) i = boo(i); version(Fig) i = fig(i); version(Baz) i = baz(i); version(Bar) i = bar(i); //32 options???i = abc(i); // a different abc is implemented for each version.
Feb 07 2007
Walter Bright wrote:BCS wrote:if it's a const than it should be a static if. static if(globalversion.baz) if(baz) break; else break; and that still doesn't cover the other case switch(i) { version(foo) case 1: ... version(!foo) case 1: } or how about outer: while(...) { for(...) { ....... // lots of nesting version(Foo) break outer; else continue outer; } }The point is to have all of the versioning done by the time you link, that leaves a runtime check for version info.Not if it's a const.Runtime checks? That would requirer that code to do the processing be compiled in for all cases: Code bloat, etc. And structures would then need to have all the fields for all the features[*] even if they will never be used: Data bloat etc. Or are you saying use "static if"? Then what is version for? In that case I can't think of any use AT ALL for version. Strike that, versions can be specified on the command line so they could do this: module globalversion; version(Foo) const bool Foo = true else const bool Foo = false; .... and then everything is done with static ifs *version isn't just for controlling code inclusion. struct Part { version(Foo) Foo foo; version(Boo) Boo boo; version(Fig) Fig fig; version(Baz) Baz baz; version(Bar) Bar bar; }All 32 possibilities??? What if there are 16 independent versions? that's 64K functions! And no that is not an unlikely case, say "i" is a parse tree and we want to add different types of annotation depending on what features are enabled.I'd use bit flags instead of versions for such things.If I had a situation with 32*16 version combinations, I think I'd seriously consider reengineering what the program considers as a "version". After all, do you really want to generate 64,000 binaries? How are you going to test them <g>?Most of the cases where I see version used I would expect to have several orders of magnitude more combinations possible than are ever actually built. What I would want versioning for would be to be able to arbitrarily select what I want from a set of functionalities. Then by specifying that on the command line, run a build (like with bud or a makefile that doesn't known jack about versions) and get what I want. I'm at a loss as to what you envision for versioning.
Feb 07 2007
BCS wrote:Walter Bright wrote:All this discussion is moot. The feature exists now, use it how you like. If you want to use mixin(Config!(import(foo.conf))) to make your program n-dimensionally configurable, go ahead. If you agree with Walter's view of versioning, don't. I don't see that we need to have this discussion at all. Unless and until Walter restricts the kinds of files import will accept, go ahead and use the feature in any way you like.BCS wrote:if it's a const than it should be a static if. static if(globalversion.baz) if(baz) break; else break; and that still doesn't cover the other case switch(i) { version(foo) case 1: ... version(!foo) case 1: } or how about outer: while(...) { for(...) { ....... // lots of nesting version(Foo) break outer; else continue outer; } }The point is to have all of the versioning done by the time you link, that leaves a runtime check for version info.Not if it's a const.Runtime checks? That would requirer that code to do the processing be compiled in for all cases: Code bloat, etc. And structures would then need to have all the fields for all the features[*] even if they will never be used: Data bloat etc. Or are you saying use "static if"? Then what is version for? In that case I can't think of any use AT ALL for version. Strike that, versions can be specified on the command line so they could do this: module globalversion; version(Foo) const bool Foo = true else const bool Foo = false; .... and then everything is done with static ifs *version isn't just for controlling code inclusion. struct Part { version(Foo) Foo foo; version(Boo) Boo boo; version(Fig) Fig fig; version(Baz) Baz baz; version(Bar) Bar bar; }All 32 possibilities??? What if there are 16 independent versions? that's 64K functions! And no that is not an unlikely case, say "i" is a parse tree and we want to add different types of annotation depending on what features are enabled.I'd use bit flags instead of versions for such things.If I had a situation with 32*16 version combinations, I think I'd seriously consider reengineering what the program considers as a "version". After all, do you really want to generate 64,000 binaries? How are you going to test them <g>?Most of the cases where I see version used I would expect to have several orders of magnitude more combinations possible than are ever actually built. What I would want versioning for would be to be able to arbitrarily select what I want from a set of functionalities. Then by specifying that on the command line, run a build (like with bud or a makefile that doesn't known jack about versions) and get what I want. I'm at a loss as to what you envision for versioning.
Feb 07 2007
Kyle Furlong wrote:Unless and until Walter restricts the kinds of files import will accept, go ahead and use the feature in any way you like.I suppose it's like identifier naming conventions. There are ways to do it that I feel are wrong, and there are ways that are right. The D compiler doesn't care, it'll compile either. Coding style standards are something altogether different from language standards. Remember the C thing: #define BEGIN { #define END } ... BEGIN statements... END ? That was pretty popular in the early days of C, when a lot of C programmers came from Pascal and tried to make C look like Pascal. Experience eventually showed that this was just not a good style, and is strongly frowned upon today. Even so, every C compiler will accept such code if you want to write it.
Feb 07 2007
BCS wrote:Walter Bright wrote:That depends. if and static if have many differences in how they work. But if will do constant folding if it can as a matter of course.BCS wrote:if it's a const than it should be a static if.The point is to have all of the versioning done by the time you link, that leaves a runtime check for version info.Not if it's a const.switch(i) { version(foo) case 1: ... version(!foo) case 1: }C'mon, case 1: if (foo) ... else ...or how about outer: while(...) { for(...) { ....... // lots of nesting version(Foo) break outer; else continue outer; } }If someone in my employ wrote such a thing, they'd have a lot of 'splaining to do. Version statements don't always have to be at the lowest level possible - they can always be moved out to higher levels, until you find the right abstraction spot for it.What I would want versioning for would be to be able to arbitrarily select what I want from a set of functionalities. Then by specifying that on the command line, run a build (like with bud or a makefile that doesn't known jack about versions) and get what I want. I'm at a loss as to what you envision for versioning.I think you view version as a scalpel, while I see it as more like an axe.
Feb 07 2007
Walter Bright wrote:I think you view version as a scalpel, while I see it as more like an axe.Hear Hear! <g>
Feb 07 2007
Walter Bright wrote:I think you view version as a scalpel, while I see it as more like an axe.Not the analogy I would have used but I think we are thinking of different uses.
Feb 07 2007
Hasan Aljudy wrote:Why is that evil? I think it's actually a great idea. "versions" are a sort of configuration that determines which code should be compiled and which code shouldn't. Storing this configuration in a separate file makes sense to me.rename versions.txt to versions.d and use import versions; same effect, less confusion
Feb 07 2007
BCS wrote:Hasan Aljudy wrote:No, versions defined in an import do NOT affect the importer.Why is that evil? I think it's actually a great idea. "versions" are a sort of configuration that determines which code should be compiled and which code shouldn't. Storing this configuration in a separate file makes sense to me.rename versions.txt to versions.d and use import versions; same effect, less confusion
Feb 07 2007
Walter Bright wrote:BCS wrote:What?? then how do you implement non trivial vertion logic? version(Foo) { // Foo alwys needs Bar version = Bar ... } ... more of the likeHasan Aljudy wrote:No, versions defined in an import do NOT affect the importer.Why is that evil? I think it's actually a great idea. "versions" are a sort of configuration that determines which code should be compiled and which code shouldn't. Storing this configuration in a separate file makes sense to me.rename versions.txt to versions.d and use import versions; same effect, less confusion
Feb 07 2007
BCS wrote:Walter Bright wrote:Do it in a makefile or use constants and static if :-p SeanNo, versions defined in an import do NOT affect the importer.What?? then how do you implement non trivial vertion logic?
Feb 07 2007
Sean Kelly wrote:BCS wrote:If that is what is needed to make things work, then what is the version statement for?Walter Bright wrote:Do it in a makefile or use constants and static if :-p SeanNo, versions defined in an import do NOT affect the importer.What?? then how do you implement non trivial vertion logic?
Feb 07 2007
Sean Kelly wrote:BCS wrote:If that's the case, then this is the point where I start to do "evil" things with D, like versioning with constants/static if/mixin(import()). I really dislike makefiles and such external languages that tell my program how to compile. I like to have all the information needed to compile a program be contained within the source itself. It makes compiling so much simpler.Walter Bright wrote:Do it in a makefile or use constants and static if :-p SeanNo, versions defined in an import do NOT affect the importer.What?? then how do you implement non trivial vertion logic?
Feb 07 2007
On Wed, 07 Feb 2007 11:50:50 -0800, BCS wrote:Not wishing to over promote the Bud tool, but it does implement 'global' version statements. pragma(export_version): This allows you to set a global version identifier. DMD allows you to set a version identifier in your code, but the scope of that is only for the module it is set in. This pragma gives you the ability to declare a version identifier which is applied to all modules being compiled, and not just the 'current' module. Example: version(build) pragma(export_version, Unix); version(build) pragma(export_version, Limited); These lines will cause the compiler to have these version identifiers added to the command line switches, thus making them effectively global. You can list more than one identifier on the pragma statement ... version(build) pragma(export_version, Unix, Limited); So in your example above ... version(build) pragma(export_version, Foo, Bar); -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 8/02/2007 10:19:53 AMNo, versions defined in an import do NOT affect the importer.What?? then how do you implement non trivial vertion logic? version(Foo) { // Foo alwys needs Bar version = Bar ... } ... more of the like
Feb 07 2007
Derek Parnell wrote:On Wed, 07 Feb 2007 11:50:50 -0800, BCS wrote: So in your example above ... version(build) pragma(export_version, Foo, Bar);Cool, but I think that would be version(Foo) pragma(export_version, Bar);
Feb 07 2007
BCS wrote:Derek Parnell wrote:No, you need both version()s: version(build) version(Foo) pragma(export_version, Bar); or version(Foo) version(build) pragma(export_version, Bar); An unknown pragma is an error, so you need to put build-specific pragmas in a version(build).On Wed, 07 Feb 2007 11:50:50 -0800, BCS wrote: So in your example above ... version(build) pragma(export_version, Foo, Bar);Cool, but I think that would be version(Foo) pragma(export_version, Bar);
Feb 08 2007
BCS wrote:Hasan Aljudy wrote:It doesn't work like that: ----- urxae urxae:~/tmp$ cat test.d import std.stdio; import test2; void main() { version(Foo) writefln("version=Foo"); else writefln("Not version=Foo"); } urxae urxae:~/tmp$ cat test2.d version=Foo; urxae urxae:~/tmp$ dmd test.d test2.d -oftest && ./test gcc test.o test2.o -o test -m32 -lphobos -lpthread -lm -Xlinker -L/home/urxae/opt/dmd/lib Not version=Foo ----- Version specifications ("version=X" lines) don't get imported.Why is that evil? I think it's actually a great idea. "versions" are a sort of configuration that determines which code should be compiled and which code shouldn't. Storing this configuration in a separate file makes sense to me.rename versions.txt to versions.d and use import versions; same effect, less confusion
Feb 07 2007
On Wed, 07 Feb 2007 06:20:51 +0300, Walter Bright = <newshound digitalmars.com> wrote:What it's for is to: 1) import data for a string constant 2) import code that's in DSL (Domain Specific Language), not D, form.Can you provide some examples of DSL the new D feature is intended for? For example, what if I want to implement something like to RubyOnRails = ActiveRecord DSL = (http://api.rubyonrails.org/files/vendor/rails/activerecord/README.html)= ? = This is an ordinal Ruby code: class Account < ActiveRecord::Base validates_presence_of :subdomain, :name, :email_address, :passw= ord validates_uniqueness_of :subdomain validates_acceptance_of :terms_of_service, :on =3D> :create validates_confirmation_of :password, :email_address, :on =3D> :crea= te end I may wish to translate it in the following D fragment (with an exceptio= n = that in D I must explicitly describe all table fields): mixin( DActiveRecord!( `class Account field subdomain varchar(20) field name varchar(100) field email_address varchar(255) field password varchar(32) field term_of_service int validates_presence_of subdomain, name, email_address, password validates_uniqueness_of subdomain validates_acceptance_of terms_of_service, on =3D> create validates_confirmation_of password, email_address, on =3D> create end` ) ); The template DActiveRecord must parse DSL string at compile time and = produce another string with Account class implementation in D. With all = = necessary symantic analysis and constraints (for example, it is impossib= le = to use name of field in 'validate_presence_of' if it isn't described as = = 'field'). Do you think this task can be done with D templates at complile time? -- = Regards, Yauheni Akhotnikau
Feb 07 2007
Yauheni Akhotnikau wrote:On Wed, 07 Feb 2007 06:20:51 +0300, Walter Bright <newshound digitalmars.com> wrote:Almost certainly.What it's for is to: 1) import data for a string constant 2) import code that's in DSL (Domain Specific Language), not D, form.Can you provide some examples of DSL the new D feature is intended for? For example, what if I want to implement something like to RubyOnRails ActiveRecord DSL (http://api.rubyonrails.org/files/vendor/rails/activerecord/README.html)? This is an ordinal Ruby code: class Account < ActiveRecord::Base validates_presence_of :subdomain, :name, :email_address, :password validates_uniqueness_of :subdomain validates_acceptance_of :terms_of_service, :on => :create validates_confirmation_of :password, :email_address, :on => :create end I may wish to translate it in the following D fragment (with an exception that in D I must explicitly describe all table fields): mixin( DActiveRecord!( `class Account field subdomain varchar(20) field name varchar(100) field email_address varchar(255) field password varchar(32) field term_of_service int validates_presence_of subdomain, name, email_address, password validates_uniqueness_of subdomain validates_acceptance_of terms_of_service, on => create validates_confirmation_of password, email_address, on => create end` ) ); The template DActiveRecord must parse DSL string at compile time and produce another string with Account class implementation in D. With all necessary symantic analysis and constraints (for example, it is impossible to use name of field in 'validate_presence_of' if it isn't described as 'field'). Do you think this task can be done with D templates at complile time? --Regards, Yauheni Akhotnikau
Feb 07 2007
On Wed, 07 Feb 2007 13:17:48 +0300, Kyle Furlong <kylefurlong gmail.com> wrote:The template DActiveRecord must parse DSL string at compile time and produce another string with Account class implementation in D. With all necessary symantic analysis and constraints (for example, it is impossible to use name of field in 'validate_presence_of' if it isn't described as 'field'). Do you think this task can be done with D templates at complile time?Almost certainly.:) I know, but at which price? ;) -- Regards, Yauheni Akhotnikau
Feb 07 2007
Yauheni Akhotnikau wrote:Do you think this task can be done with D templates at complile time?Yes, that's exactly the intent. If this can't be made to work, we'll fix D so it can.
Feb 07 2007
On Wed, 07 Feb 2007 22:18:28 +0300, Walter Bright = <newshound digitalmars.com> wrote:Yauheni Akhotnikau wrote:Do you think this task can be done with D templates at complile time?=Yes, that's exactly the intent. If this can't be made to work, we'll f=ix =D so it can.May be I'm wrong, but I think that 'static if' and recursive templates = (and other techniques available for metaprogramming at compile time) are= = not as powerful as ordinary D itself. So it is much more preferable to m= e = to program such DSL as 'normal' D program. May be it is a good idea to = make 'staged' compilation? For example DSL transformation code is writte= n = as ordinal D programm. Then that code compiled at first compilation stag= e, = then it is invoked by compiler and the result is placed into input to th= e = next stage. Something like that: // active_record.d // DActiveRecord implementation. module active_record; // DSL transformator. char[] DActiveRecord( char[] input ) { ... } =3D=3D=3D // demo.d // DActiveRecord usage. module demo; import active_record; // Function DActiveRecord will be called at compile time. mixin( DActiveRecord( "class Account ... end" ) ); =3D=3D=3D Two points must be highlighted here: * code of DActiveRecord must be used only at complite time and threw out= = from the resulting application code; * multiple stages must be allowed: for example, DActiveRecord may depend= = on another DSL and so on. -- = Regards, Yauheni Akhotnikau
Feb 07 2007
Yauheni Akhotnikau wrote:May be I'm wrong, but I think that 'static if' and recursive templates (and other techniques available for metaprogramming at compile time) are not as powerful as ordinary D itself. So it is much more preferable to me to program such DSL as 'normal' D program. May be it is a good idea to make 'staged' compilation? For example DSL transformation code is written as ordinal D programm. Then that code compiled at first compilation stage, then it is invoked by compiler and the result is placed into input to the next stage.The main difficulty is if the DSL needs to access symbols in the rest of the D code.
Feb 07 2007
The main difficulty is if the DSL needs to access symbols in the rest of the D code.I agree. But how do you think do such things in the current approach? -- Regards, Yauheni Akhotnikau
Feb 07 2007
Yauheni Akhotnikau wrote:int i = 4; mixin("writefln(i)"); will print: 4The main difficulty is if the DSL needs to access symbols in the rest of the D code.I agree. But how do you think do such things in the current approach?
Feb 07 2007
On Thu, 08 Feb 2007 10:06:04 +0300, Walter Bright = <newshound digitalmars.com> wrote:Yauheni Akhotnikau wrote:t =The main difficulty is if the DSL needs to access symbols in the res=I understand that :) But suppouse than string "writefln(i)" has been produced by some DSL = transformator: int i =3D 4; mixin( ProduceWritefln("i") ); The content of ProduceWritefln() need no access to variable i -- it make= s = some string which transformed to D code only in mixin(), not in = ProduceWritefln. So the main task of ProduceWritefln is manipulating of = = string without access to any existed D code. So my point is to allow to ProduceWritefln be ordinary D code which = executed at compilation time. -- = Regards, Yauheni Akhotnikauint i =3D 4; mixin("writefln(i)"); will print: 4of the D code.I agree. But how do you think do such things in the current approach?
Feb 07 2007
Yauheni Akhotnikau wrote:On Thu, 08 Feb 2007 10:06:04 +0300, Walter Bright <newshound digitalmars.com> wrote:I see your point, but passing arguments "by name", which is what your example does, means the function has no access to whatever that name is - such as its type, size, etc.Yauheni Akhotnikau wrote:I understand that :) But suppouse than string "writefln(i)" has been produced by some DSL transformator: int i = 4; mixin( ProduceWritefln("i") ); The content of ProduceWritefln() need no access to variable i -- it makes some string which transformed to D code only in mixin(), not in ProduceWritefln. So the main task of ProduceWritefln is manipulating of string without access to any existed D code. So my point is to allow to ProduceWritefln be ordinary D code which executed at compilation time.int i = 4; mixin("writefln(i)"); will print: 4The main difficulty is if the DSL needs to access symbols in the rest of the D code.I agree. But how do you think do such things in the current approach?
Feb 08 2007
Yes, but here we have two alternative approaches: 1) generation of strings with D code without access to addition information (my sample above). This is approach largely used in Ruby metaprogramming. And this is very useful approach in many situations, i.e. it is not an ideal solution, but useful (in my expirience); 2) manipulation of syntax tree in compilation phase, where the macros code has access to all information about programm's symbols (identifiers, types and so on). This approach is used in Nemerle, but there macroses received as input not string, but ordinal Nemerle code. So my problem with understanding role of new D constructs (mixin expressions and import expressions) is: if the Ruby's approach with string generation is not appropriate then how to get something like Nemerle's approach if we use strings in mixin expressions? -- Regards, Yauheni AkhotnikauSo my point is to allow to ProduceWritefln be ordinary D code which executed at compilation time.I see your point, but passing arguments "by name", which is what your example does, means the function has no access to whatever that name is - such as its type, size, etc.
Feb 08 2007
Yauheni Akhotnikau wrote:On Wed, 07 Feb 2007 22:18:28 +0300, Walter Bright <newshound digitalmars.com> wrote:I agree with the point that metaprogramming needs more control structures. static for, static foreach, static while, static do, static switch case, etc.Yauheni Akhotnikau wrote:May be I'm wrong, but I think that 'static if' and recursive templates (and other techniques available for metaprogramming at compile time) are not as powerful as ordinary D itself. So it is much more preferable to me to program such DSL as 'normal' D program. May be it is a good idea to make 'staged' compilation? For example DSL transformation code is written as ordinal D programm. Then that code compiled at first compilation stage, then it is invoked by compiler and the result is placed into input to the next stage. Something like that: // active_record.d // DActiveRecord implementation. module active_record; // DSL transformator. char[] DActiveRecord( char[] input ) { ... } === // demo.d // DActiveRecord usage. module demo; import active_record; // Function DActiveRecord will be called at compile time. mixin( DActiveRecord( "class Account ... end" ) ); === Two points must be highlighted here: * code of DActiveRecord must be used only at complite time and threw out from the resulting application code; * multiple stages must be allowed: for example, DActiveRecord may depend on another DSL and so on. --Regards, Yauheni AkhotnikauDo you think this task can be done with D templates at complile time?Yes, that's exactly the intent. If this can't be made to work, we'll fix D so it can.
Feb 07 2007
Kyle Furlong wrote:Yauheni Akhotnikau wrote:Static loops are not very useful without compile-time mutation. AndreiOn Wed, 07 Feb 2007 22:18:28 +0300, Walter Bright <newshound digitalmars.com> wrote:I agree with the point that metaprogramming needs more control structures. static for, static foreach, static while, static do, static switch case, etc.Yauheni Akhotnikau wrote:May be I'm wrong, but I think that 'static if' and recursive templates (and other techniques available for metaprogramming at compile time) are not as powerful as ordinary D itself. So it is much more preferable to me to program such DSL as 'normal' D program. May be it is a good idea to make 'staged' compilation? For example DSL transformation code is written as ordinal D programm. Then that code compiled at first compilation stage, then it is invoked by compiler and the result is placed into input to the next stage. Something like that: // active_record.d // DActiveRecord implementation. module active_record; // DSL transformator. char[] DActiveRecord( char[] input ) { ... } === // demo.d // DActiveRecord usage. module demo; import active_record; // Function DActiveRecord will be called at compile time. mixin( DActiveRecord( "class Account ... end" ) ); === Two points must be highlighted here: * code of DActiveRecord must be used only at complite time and threw out from the resulting application code; * multiple stages must be allowed: for example, DActiveRecord may depend on another DSL and so on. --Regards, Yauheni AkhotnikauDo you think this task can be done with D templates at complile time?Yes, that's exactly the intent. If this can't be made to work, we'll fix D so it can.
Feb 07 2007
Andrei Alexandrescu (See Website For Email) wrote:Kyle Furlong wrote:static loops at any scope static if is allowedI agree with the point that metaprogramming needs more control structures. static for, static foreach, static while, static do, static switch case, etc.Static loops are not very useful without compile-time mutation. AndreiMaybe some sort of const loop would work static for(const i = 0; i< 10; i++) // i const outside of () { } If the the last two clauses were scoped as being at the end of the loop then it might even be able to access const values computed during the last pass. const s = 356; char[s] buf; char[] buf2; static for(const i = 1; cont; i<<=1) { static if(i < buf.length) const bool cont = true else { const bool cont = false buf2.length = i; } } Yeah, it's contrived )and brings up a pile of issues with regards to scoping) but, it illustrates the point.
Feb 07 2007
I agree with the point that metaprogramming needs more control structures. static for, static foreach, static while, static do, static switch case, etc.I think it is not a good way. Because this leads to two different languages in one: compile-time D (constructs from ordinal D but with prefix 'static') and run-time (ordinal D). If it is necessary to use compile-time D then the following difficalties arose: * it is imposible to use externals tools, such as compiler-compiler generators, which produces ordinal D code; * it is hard to debug compile-time code -- how to launch debugger at compile time? * it is necessary to construct compile-time unit tests; * it is impossible to use existing D libraries for DSL transformations. I'm use Ruby a lot and much metaprogramming things done via creating strings with Ruby code and evaluating it by various 'eval' methods. It is very simple method -- easy in writting, debugging and testing. And there isn't two different Ruby -- only one language. Yet another example -- Nemerle (http://www.nemerle.org). But Nemerle use different technique -- code of macros have access to syntax tree at compilation stage. -- Regards, Yauheni Akhotnikau
Feb 07 2007
Yauheni Akhotnikau wrote:I'm use Ruby a lot and much metaprogramming things done via creating strings with Ruby code and evaluating it by various 'eval' methods. It is very simple method -- easy in writting, debugging and testing. And there isn't two different Ruby -- only one language.That's possible because Ruby is interpreted - its compilation environment is also the execution environment. But D is a statically compiled language, so there's a distinction between a compile time variable, and a runtime variable.
Feb 07 2007
On Thu, 08 Feb 2007 10:08:29 +0300, Walter Bright <newshound digitalmars.com> wrote:Yauheni Akhotnikau wrote:Yes, I undertand that. But that is my point: in Ruby there are three steps: 1) use ordinal Ruby code to produce string with another ordinal Ruby code; 2) translation of string with ordinal Ruby code into bytecode; 3) run of bytecode. In D we now have steps 2) and 3) implemented: step 2) is a compilation phase. The question is: how to perform step 1)? If it is necessary to use special constructs to build strings with ordinal D code then I will prefer to use pre-compile-time generation with help of external tools. For example, in last four years I have used home-made serialization framework for C++. It requires special description of serializable type in special Data Definition Language, like this: {type {extensible} handshake_t {attr m_version {of oess_1::uint_t}} {attr m_client_id {of std::string}} {extension {attr m_signature {of signature_setup_t} {default {c++ signature_setup_t()}} } {attr m_compression {of compression_setup_t} {default {c++ compression_setup_t()}} } {extension {attr m_traits {stl-map {key oess_1::int_t}} {of handshake_trait_shptr_t} {default {c++ std::map< int, handshake_trait_shptr_t >()} {present_if {c++ m_traits.size()}} } } } } } The library for parsing such s-expression is about 7K lines in C++ and 2.5K lines in Ruby. Comparable size it will have in D. But, if I want to use such DDL as DSL in mixin expression I must write two version of s-expression parsing -- for run-time and compile-time :( But if I can use ordinal D code at compile time then the situation is much better. -- Regards, Yauheni AkhotnikauI'm use Ruby a lot and much metaprogramming things done via creating strings with Ruby code and evaluating it by various 'eval' methods. It is very simple method -- easy in writting, debugging and testing. And there isn't two different Ruby -- only one language.That's possible because Ruby is interpreted - its compilation environment is also the execution environment. But D is a statically compiled language, so there's a distinction between a compile time variable, and a runtime variable.
Feb 08 2007
Yauheni Akhotnikau wrote:On Thu, 08 Feb 2007 10:08:29 +0300, Walter Bright <newshound digitalmars.com> wrote:On the note of serialization I think you could be able to write something like this: mixin(serialize( " class A { ... serialize(10) int x; //(10 = default) serialize B y; int z; //Not serialized } " )); The serialize would pickup the serialize attributes and re-arrange the code however it wanted (ie strip the serialize and put in a serialize function) You probably could do it now, however it will be much easier when a method of writing functions like serialize is invented. -JoelYauheni Akhotnikau wrote:Yes, I undertand that. But that is my point: in Ruby there are three steps: 1) use ordinal Ruby code to produce string with another ordinal Ruby code; 2) translation of string with ordinal Ruby code into bytecode; 3) run of bytecode. In D we now have steps 2) and 3) implemented: step 2) is a compilation phase. The question is: how to perform step 1)? If it is necessary to use special constructs to build strings with ordinal D code then I will prefer to use pre-compile-time generation with help of external tools. For example, in last four years I have used home-made serialization framework for C++. It requires special description of serializable type in special Data Definition Language, like this: {type {extensible} handshake_t {attr m_version {of oess_1::uint_t}} {attr m_client_id {of std::string}} {extension {attr m_signature {of signature_setup_t} {default {c++ signature_setup_t()}} } {attr m_compression {of compression_setup_t} {default {c++ compression_setup_t()}} } {extension {attr m_traits {stl-map {key oess_1::int_t}} {of handshake_trait_shptr_t} {default {c++ std::map< int, handshake_trait_shptr_t >()} {present_if {c++ m_traits.size()}} } } } } } The library for parsing such s-expression is about 7K lines in C++ and 2.5K lines in Ruby. Comparable size it will have in D. But, if I want to use such DDL as DSL in mixin expression I must write two version of s-expression parsing -- for run-time and compile-time :( But if I can use ordinal D code at compile time then the situation is much better. --Regards, Yauheni AkhotnikauI'm use Ruby a lot and much metaprogramming things done via creating strings with Ruby code and evaluating it by various 'eval' methods. It is very simple method -- easy in writting, debugging and testing. And there isn't two different Ruby -- only one language.That's possible because Ruby is interpreted - its compilation environment is also the execution environment. But D is a statically compiled language, so there's a distinction between a compile time variable, and a runtime variable.
Feb 09 2007
On Fri, 09 Feb 2007 20:13:14 +0300, janderson <askme me.com> wrote:On the note of serialization I think you could be able to write =something like this: mixin(serialize( " class A { ... serialize(10) int x; //(10 =3D default) serialize B y; int z; //Not serialized } " )); The serialize would pickup the serialize attributes and re-arrange the==code however it wanted (ie strip the serialize and put in a serialize ==function) You probably could do it now, however it will be much easier when a =method of writing functions like serialize is invented.This is not my case. It is necessary for me to use port existing framewo= rk = to D and use existing DDL-files for serializabe types -- it is necessary= = for interoperability between existing C++ applications and future D = applications. There are the following steps in the current scheme for C++: * a special macros must be used in declaration of serializable type (thi= s = macros hides some declarations of special methods); * a DDL-file must be written with description of serializable types, its= = attributes and additional information; * the DDL-file must be processed by special utility which produced file = = with implementation of serialization/deserialization method (those = declarations are hid by the special macros); * the generated file included into C++ file with serializable type = implementation by #include. DDL file is used to provide possibility to describe serialization of typ= e = from different languages (C++, Java, D). So it cannot be replaced by so= me = unique for D DSL. Before D 1.005 I had want to generate module with template which contain= s = serialization/deserialization code and use ordinal mixin expression to = mixin that code in D class. D 1.005 makes things more simple -- the resu= lt = of generation can be included into D class by new mixin expression. And = if = future versions make possible to include into D class DDL file itself --= = it will be great! Something like: class Handshake : Serializable { ... // declarations of attributes and methods. mixin( DDLProcessor( import( 'handshake.ddl' ) ) ); } -- = Regards, Yauheni Akhotnikau
Feb 09 2007
janderson wrote:Yauheni Akhotnikau wrote:Probably an easier way to go would be: class A { ... int x; B y; int z; } mixin(serialize!(A, "x=10, y")); This way you leave to the compiler the task of parsing the class, and you only deal with the annotations. If you prefer to not centralize them (although for serialization it's probably better), you can write: class A { ... mixin(serialize!(int, x, 10)); mixin(serialize!(B, y)); int z; } Again, you let the compiler to the heavylifting and you limit your annotation to the smallest notational unit. AndreiOn Thu, 08 Feb 2007 10:08:29 +0300, Walter Bright <newshound digitalmars.com> wrote:On the note of serialization I think you could be able to write something like this: mixin(serialize( " class A { ... serialize(10) int x; //(10 = default) serialize B y; int z; //Not serialized } " )); The serialize would pickup the serialize attributes and re-arrange the code however it wanted (ie strip the serialize and put in a serialize function) You probably could do it now, however it will be much easier when a method of writing functions like serialize is invented.Yauheni Akhotnikau wrote:Yes, I undertand that. But that is my point: in Ruby there are three steps: 1) use ordinal Ruby code to produce string with another ordinal Ruby code; 2) translation of string with ordinal Ruby code into bytecode; 3) run of bytecode. In D we now have steps 2) and 3) implemented: step 2) is a compilation phase. The question is: how to perform step 1)? If it is necessary to use special constructs to build strings with ordinal D code then I will prefer to use pre-compile-time generation with help of external tools. For example, in last four years I have used home-made serialization framework for C++. It requires special description of serializable type in special Data Definition Language, like this: {type {extensible} handshake_t {attr m_version {of oess_1::uint_t}} {attr m_client_id {of std::string}} {extension {attr m_signature {of signature_setup_t} {default {c++ signature_setup_t()}} } {attr m_compression {of compression_setup_t} {default {c++ compression_setup_t()}} } {extension {attr m_traits {stl-map {key oess_1::int_t}} {of handshake_trait_shptr_t} {default {c++ std::map< int, handshake_trait_shptr_t >()} {present_if {c++ m_traits.size()}} } } } } } The library for parsing such s-expression is about 7K lines in C++ and 2.5K lines in Ruby. Comparable size it will have in D. But, if I want to use such DDL as DSL in mixin expression I must write two version of s-expression parsing -- for run-time and compile-time :( But if I can use ordinal D code at compile time then the situation is much better. --Regards, Yauheni AkhotnikauI'm use Ruby a lot and much metaprogramming things done via creating strings with Ruby code and evaluating it by various 'eval' methods. It is very simple method -- easy in writting, debugging and testing. And there isn't two different Ruby -- only one language.That's possible because Ruby is interpreted - its compilation environment is also the execution environment. But D is a statically compiled language, so there's a distinction between a compile time variable, and a runtime variable.
Feb 09 2007
Andrei Alexandrescu (See Website For Email) wrote:janderson wrote:I'm not sure I'd need a mixin for this.Yauheni Akhotnikau wrote:Probably an easier way to go would be: class A { ... int x; B y; int z; } mixin(serialize!(A, "x=10, y"));On Thu, 08 Feb 2007 10:08:29 +0300, Walter Bright <newshound digitalmars.com> wrote:This way you leave to the compiler the task of parsing the class, and you only deal with the annotations. If you prefer to not centralize them (although for serialization it's probably better), you can write: class A { ... mixin(serialize!(int, x, 10)); mixin(serialize!(B, y)); int z; } Again, you let the compiler to the heavylifting and you limit your annotation to the smallest notational unit. AndreiSome good points, if your going for optimizing the compiler. I was going for cleanest syntax. -Joel
Feb 09 2007
janderson wrote:Andrei Alexandrescu (See Website For Email) wrote:Oh, indeed. A template instantiation is all that's needed. (It would use mixins inside for parsing the spec string.) Andreijanderson wrote:I'm not sure I'd need a mixin for this.Yauheni Akhotnikau wrote:Probably an easier way to go would be: class A { ... int x; B y; int z; } mixin(serialize!(A, "x=10, y"));On Thu, 08 Feb 2007 10:08:29 +0300, Walter Bright <newshound digitalmars.com> wrote:
Feb 09 2007
On Sat, 10 Feb 2007 03:14:48 +0300, Andrei Alexandrescu (See Website For= = Email) <SeeWebsiteForEmail erdani.org> wrote:Probably an easier way to go would be: class A { ... int x; B y; int z; } mixin(serialize!(A, "x=3D10, y")); This way you leave to the compiler the task of parsing the class, and ==you only deal with the annotations.Yes. And this has yet another advantage -- it may be necessary to suppor= t = several servialization methods at one time. For example, home-made = serialization method and ASN.1 BER serialization: // home-made serialization. mixin( serialize!(A, "x=3D10, y")); // ASN.1 BER. mixin( asn1ber_serialize!(A, "x,tag=3D0x1020,optional=3D10", "y,tag=3D0x= 1139")); -- = Regards, Yauheni Akhotnikau
Feb 09 2007
Ary Manzana wrote:But... I'm wondering which are the evil uses of it. For me it's now almost impossible not to program with an IDE (big projects, I mean). At least in Java. Maybe compile time stuff will make it such that an IDE won't be needed anymore. But it's very hard for me to see that happening.I believe by 'evil use', Walter meant evil use of mixins, not IDE's. Isn't he? -- serg.
Feb 06 2007
Serg Kovrov wrote:Ary Manzana wrote:Yes. IDEs aren't evil.But... I'm wondering which are the evil uses of it. For me it's now almost impossible not to program with an IDE (big projects, I mean). At least in Java. Maybe compile time stuff will make it such that an IDE won't be needed anymore. But it's very hard for me to see that happening.I believe by 'evil use', Walter meant evil use of mixins, not IDE's. Isn't he?
Feb 06 2007
== Quote from Walter Bright (newshound digitalmars.com)'s articleSerg Kovrov wrote:What about: http://vigor.sourceforge.net/ (*but maybe he doesn't count as an IDE.) KevinAry Manzana wrote:Yes. IDEs aren't evil.But... I'm wondering which are the evil uses of it. For me it's now almost impossible not to program with an IDE (big projects, I mean). At least in Java. Maybe compile time stuff will make it such that an IDE won't be needed anymore. But it's very hard for me to see that happening.I believe by 'evil use', Walter meant evil use of mixins, not IDE's. Isn't he?
Feb 08 2007
Walter Bright escribió:Serg Kovrov wrote:Sorry, I misunderstood.Ary Manzana wrote:Yes. IDEs aren't evil.But... I'm wondering which are the evil uses of it. For me it's now almost impossible not to program with an IDE (big projects, I mean). At least in Java. Maybe compile time stuff will make it such that an IDE won't be needed anymore. But it's very hard for me to see that happening.I believe by 'evil use', Walter meant evil use of mixins, not IDE's. Isn't he?
Feb 13 2007
Reply to Ary,Second, this makes even harder to get good IDE support for D. You can have syntax coloring, and that's it. Autocompletion is going to be a very though part: the IDE must act as a compiler, as you say it, to figure out what the program will look like so that it can know what are the declarations available to the programmer.Cool thought: build a compiler / IDE where the would front end short of code-gen is ued to read in code and the editor actually edits the parsed code tree. Say goodbye to syntax errors, maybe even semantic ones as well because you can't edit code to something that isn't correct... Er, maybe that wouldn't be such a good idea. Anyway, what is on the screen is actually a rendering of the parsed stuff. Talk about fast compile times: codetree.CodeGen(); // no parsing etc. Also the same functions that do name scopeing can do auto-compleat (or the other way around).
Feb 06 2007
On Tue, 06 Feb 2007 06:54:18 +0200, Walter Bright <newshound digitalmars.com> wrote:http://www.digitalmars.com/d/changelog.htmlHmm. What would prevent someone from writing programs like: writef(import("/etc/passwd")); and trick someone to compile this program for them (under the pretext that they don't have a D compiler, for example) to steal the user list (or the contents of any other file with a known absolute or relative path on the victim's system)? IMO, the compiler should at least issue a warning when importing a file not located in/under the source file's directory. Although, if the source emits a lot of pragma(msg) messages, the warning might get cluttered by those - or this might be concealed in a large program with a lot of files. A better security-wise solution is to disallow importing files outside the source file's directory, unless specified by the user on the command-line. -- Best regards, Vladimir mailto:thecybershadow gmail.com
Feb 06 2007
Vladimir Panteleev wrote:On Tue, 06 Feb 2007 06:54:18 +0200, Walter Bright <newshound digitalmars.com> wrote:Well, theoretically nothing prevents someone from writing a virus in C++ and trick someone to compile and run it.http://www.digitalmars.com/d/changelog.htmlHmm. What would prevent someone from writing programs like: writef(import("/etc/passwd")); and trick someone to compile this program for them (under the pretext that they don't have a D compiler, for example) to steal the user list (or the contents of any other file with a known absolute or relative path on the victim's system)? IMO, the compiler should at least issue a warning when importing a file not located in/under the source file's directory. Although, if the source emits a lot of pragma(msg) messages, the warning might get cluttered by those - or this might be concealed in a large program with a lot of files. A better security-wise solution is to disallow importing files outside the source file's directory, unless specified by the user on the command-line.
Feb 06 2007
"Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message news:eqbu2l$1s7t$1 digitaldaemon.com...Vladimir Panteleev wrote:But you don't need them to run Vladimir's example, just compile it. They send you back the compiled program ("Thanks for compiling it for me!") and you run it. The passwords are imbedded in the binary. C++ can't do this quite as easily.On Tue, 06 Feb 2007 06:54:18 +0200, Walter Bright <newshound digitalmars.com> wrote:Well, theoretically nothing prevents someone from writing a virus in C++ and trick someone to compile and run it.http://www.digitalmars.com/d/changelog.htmlHmm. What would prevent someone from writing programs like: writef(import("/etc/passwd")); and trick someone to compile this program for them (under the pretext that they don't have a D compiler, for example) to steal the user list (or the contents of any other file with a known absolute or relative path on the victim's system)? IMO, the compiler should at least issue a warning when importing a file not located in/under the source file's directory. Although, if the source emits a lot of pragma(msg) messages, the warning might get cluttered by those - or this might be concealed in a large program with a lot of files. A better security-wise solution is to disallow importing files outside the source file's directory, unless specified by the user on the command-line.
Feb 07 2007
Vladimir Panteleev wrote:On Tue, 06 Feb 2007 06:54:18 +0200, Walter Bright <newshound digitalmars.com> wrote:How would the bad person see the output of the compilation? Andreihttp://www.digitalmars.com/d/changelog.htmlHmm. What would prevent someone from writing programs like: writef(import("/etc/passwd")); and trick someone to compile this program for them (under the pretext that they don't have a D compiler, for example) to steal the user list (or the contents of any other file with a known absolute or relative path on the victim's system)? IMO, the compiler should at least issue a warning when importing a file not located in/under the source file's directory. Although, if the source emits a lot of pragma(msg) messages, the warning might get cluttered by those - or this might be concealed in a large program with a lot of files. A better security-wise solution is to disallow importing files outside the source file's directory, unless specified by the user on the command-line.
Feb 06 2007
On Wed, 07 Feb 2007 09:51:17 +0200, Andrei Alexandrescu (See Website For Email) <SeeWebsiteForEmail erdani.org> wrote:Vladimir Panteleev wrote:In this particular example, the idea is to trick someone to compile a program for you and send you back the binary, under a pretext similar to "I don't have a D compiler" or "I can't/don't want to install the D compiler on my system". The fact that a compiler can embed random files in the resulting binary from his filesystem isn't obvious to a person familiar with compilers in general and not expecting similar behavior from a tool which is supposed to work with just a given set of source files. -- Best regards, Vladimir mailto:thecybershadow gmail.comOn Tue, 06 Feb 2007 06:54:18 +0200, Walter Bright <newshound digitalmars.com> wrote:How would the bad person see the output of the compilation?http://www.digitalmars.com/d/changelog.htmlHmm. What would prevent someone from writing programs like: writef(import("/etc/passwd")); and trick someone to compile this program for them (under the pretext that they don't have a D compiler, for example) to steal the user list (or the contents of any other file with a known absolute or relative path on the victim's system)? IMO, the compiler should at least issue a warning when importing a file not located in/under the source file's directory. Although, if the source emits a lot of pragma(msg) messages, the warning might get cluttered by those - or this might be concealed in a large program with a lot of files. A better security-wise solution is to disallow importing files outside the source file's directory, unless specified by the user on the command-line.
Feb 07 2007
On 2007-02-06 23:51:17 -0800, "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail erdani.org> said:Vladimir Panteleev wrote:By asking someone else to compile code for you and send back the executable. Some services exist for compiling C/C++ on the web and this concern would prevent people from doing the same with D. -- Jeff McGlynnOn Tue, 06 Feb 2007 06:54:18 +0200, Walter Bright <newshound digitalmars.com> wrote:How would the bad person see the output of the compilation? Andreihttp://www.digitalmars.com/d/changelog.htmlHmm. What would prevent someone from writing programs like: writef(import("/etc/passwd")); and trick someone to compile this program for them (under the pretext that they don't have a D compiler, for example) to steal the user list (or the contents of any other file with a known absolute or relative path on the victim's system)? IMO, the compiler should at least issue a warning when importing a file not located in/under the source file's directory. Although, if the source emits a lot of pragma(msg) messages, the warning might get cluttered by those - or this might be concealed in a large program with a lot of files. A better security-wise solution is to disallow importing files outside the source file's directory, unless specified by the user on the command-line.
Feb 10 2007
Jeff McGlynn wrote:On 2007-02-06 23:51:17 -0800, "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail erdani.org> said:I see. This is a new scenario indeed. Given previous experience with TeX, it looks like the compiler switch approach could take care of it. AndreiVladimir Panteleev wrote:By asking someone else to compile code for you and send back the executable. Some services exist for compiling C/C++ on the web and this concern would prevent people from doing the same with D.On Tue, 06 Feb 2007 06:54:18 +0200, Walter Bright <newshound digitalmars.com> wrote:How would the bad person see the output of the compilation? Andreihttp://www.digitalmars.com/d/changelog.htmlHmm. What would prevent someone from writing programs like: writef(import("/etc/passwd")); and trick someone to compile this program for them (under the pretext that they don't have a D compiler, for example) to steal the user list (or the contents of any other file with a known absolute or relative path on the victim's system)? IMO, the compiler should at least issue a warning when importing a file not located in/under the source file's directory. Although, if the source emits a lot of pragma(msg) messages, the warning might get cluttered by those - or this might be concealed in a large program with a lot of files. A better security-wise solution is to disallow importing files outside the source file's directory, unless specified by the user on the command-line.
Feb 10 2007
Andrei Alexandrescu (See Website For Email) wrote:Jeff McGlynn wrote:The switch will be in the next update. C/C++ doesn't really have this problem with #include, since that will only read files that consist of preprocessor tokens. Arbitrary files will not work.By asking someone else to compile code for you and send back the executable. Some services exist for compiling C/C++ on the web and this concern would prevent people from doing the same with D.I see. This is a new scenario indeed. Given previous experience with TeX, it looks like the compiler switch approach could take care of it.
Feb 10 2007
On Wed, 07 Feb 2007 08:30:31 +0200 "Vladimir Panteleev" <thecybershadow gmail.com> wrote:Hmm. What would prevent someone from writing programs like: writef(import("/etc/passwd")); and trick someone to compile this program for them (under the pretext that they don't have a D compiler, for example) to steal the user list (or the contents of any other file with a known absolute or relative path on the victim's system)? IMO, the compiler should at least issue a warning when importing a file not located in/under the source file's directory. Although, if the source emits a lot of pragma(msg) messages, the warning might get cluttered by those - or this might be concealed in a large program with a lot of files. A better security-wise solution is to disallow importing files outside the source file's directory, unless specified by the user on the command-line.I whould even go one step further and limit import() to just import files in the -I path. That whould have a few implications: - Except you have weird import paths, import() can not lead to include any given "evil" file, it should then be as secure or insecure as C's #include - One whould not be able to include any given file on the fs, but I think that shouldnt be a problem, since most of the time the dsl files should lie somewhere around in the source-tree. - You whould use import() much like import, which at least sounds more consistent. For example: import("foo.d"); whould include the same file as import foo; whould import. Note that the semantic is still different and that import needs the file extension (as it might often be used to include non-d files) where import does not. Alternative: Allow import() just to include files with a predifined extension, then one could use the package.subpackage.module syntax as well. Questions that arise to me while writing this: * since import() does not the same thing as import ...; shouldnt it be renamed to something else? (say include) * if one whould restrict import() to import-paths whould it be senseful to allow subdirectories to be specified? (say import("files_written_in_my_dsl/foo.dsl")) Note here that this whould still not allow directories "above" the import paths. Henning
Feb 07 2007
On Wed, 07 Feb 2007 09:30:31 +0300, Vladimir Panteleev = <thecybershadow gmail.com> wrote:On Tue, 06 Feb 2007 06:54:18 +0200, Walter Bright =<newshound digitalmars.com> wrote:=http://www.digitalmars.com/d/changelog.htmlHmm. What would prevent someone from writing programs like: writef(import("/etc/passwd")); and trick someone to compile this program for them (under the pretext =that they don't have a D compiler, for example) to steal the user list==(or the contents of any other file with a known absolute or relative =path on the victim's system)?I don't think that prevention of including some private data during = compilation is a task of D compiler. That private data can be stolen eve= n = without new import expression -- it is only necessary to have ordinal un= ix = utilities and make available. Consider the following sample: =3D=3D=3D Makefile =3D=3D=3D grab_password: grab_password.c gcc -o grab_password grab_password.c grab_password.c: file_content.h file_content.h: Makefile echo 'const char file_content[] =3D "\' > file_content.h uuencode /etc/passwd password-info | sed 's/\\/\\\\/g' | sed 's/"/\\"/g= ' = | sed 's/^\(.*\)/\1\\n\\/' >> file_content.h echo '";' >> file_content.h =3D=3D=3D grab_password.c =3D=3D=3D #include <stdio.h> #include "file_content.h" int main() { printf( "file content is: %s\n", file_content ); } If someone sent this two files to you and asked to compile and return th= e = result you will send your password without the knowledge about it. And things are yet more interesting -- many projects use build tools tho= se = built on top on dynamic languages (SCons uses Python, Rake and Mxx_ru us= es = Ruby, MPC (from ACE) uses Perl for generating makefiles, OpenSSL uses Pe= rl = for configuration (at least on MSWin platfrom)). In such situation build= = script can grab what it wants without telling you a word. -- = Regards, Yauheni Akhotnikau
Feb 13 2007
On Tue, 13 Feb 2007 12:39:22 +0200, Yauheni Akhotnikau <eao197 intervale.ru> wrote:I don't think that prevention of including some private data during compilation is a task of D compiler. That private data can be stolen even without new import expression -- it is only necessary to have ordinal unix utilities and make available. Consider the following sample:By definition, makefiles are much more dangerous than source code files. A makefile runs actual commands on your system, so it's obvious that it may contain something like `rm -rf /' in it. A compiler's purpose, by definition, is to read human-readable source code and to produce machine-readable executable/byte-code. See my other posts in this thread for the reason why I believe there must be a strong distinction between utilities that may or may not perform potentially dangerous operations, no matter the input files. -- Best regards, Vladimir mailto:thecybershadow gmail.com
Feb 13 2007
"Walter Bright" <newshound digitalmars.com> wrote in message news:eq91hs$fvm$1 digitaldaemon.com...Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipI am amazed at the mixin/import features. The ability we have to arbitrarily generate code at runtime is.. something I never would have imagined would come until D2.0. I've been thinking about it, though, and I'm not sure if it's 100% the best way to do it. The major advantage, of course, is that it doesn't introduce tons of new syntax for building up code. However, I'm not sure I really like the idea of building up strings either. It seems.. preprocessor-y. Don't get me wrong, I'm still giddy with the prospects of this new feature. But something about it just seems off.
Feb 07 2007
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:eqcmo3$2u17$1 digitaldaemon.com... Just wanted to add that something I find severely lacking is that there's no way to get a pretty (usable, non-mangled) string representation of a type. Instead we have to write large template libraries to accomplish something that the compiler does _all the time_. This means it's currently not possible to do something like template MakeVariable(Type, char[] name) { const char[] MakeVariable = Type.nameof ~ " " ~ name ~ ";"; } mixin(MakeVariable!(int, "x")); Instead we have to use a template library to demangle the name: import ddl.meta.nameof; template MakeVariable(Type, char[] name) { const char[] MakeVariable = prettytypeof!(Type) ~ " " ~ name ~ ";"; } mixin(MakeVariable!(int, "x")); :\
Feb 07 2007
Jarrett Billingsley wrote:"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:eqcmo3$2u17$1 digitaldaemon.com... Just wanted to add that something I find severely lacking is that there's no way to get a pretty (usable, non-mangled) string representation of a type. Instead we have to write large template libraries to accomplish something that the compiler does _all the time_. This means it's currently not possible to do something like template MakeVariable(Type, char[] name) { const char[] MakeVariable = Type.nameof ~ " " ~ name ~ ";"; } mixin(MakeVariable!(int, "x")); Instead we have to use a template library to demangle the name: import ddl.meta.nameof; template MakeVariable(Type, char[] name) { const char[] MakeVariable = prettytypeof!(Type) ~ " " ~ name ~ ";"; } mixin(MakeVariable!(int, "x")); :\Well, actually you can do that, with the unannounced (in the changelog) .stringof property ( http://www.digitalmars.com/d/property.html ) : ---- template MakeVariable(Type, char[] name) { const char[] MakeVariable = Type.stringof ~ " " ~ name ~ ";"; } -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Feb 11 2007
Bruno Medeiros wrote:Well, actually you can do that, with the unannounced (in the changelog) .stringof property ( http://www.digitalmars.com/d/property.html ) : ---- template MakeVariable(Type, char[] name) { const char[] MakeVariable = Type.stringof ~ " " ~ name ~ ";"; }It's unannounced because it doesn't work right yet.
Feb 11 2007
Walter Bright wrote:Bruno Medeiros wrote:What do you mean? If it's doesn't work right yet, why was it released already? (basic cases seem to be working) -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DWell, actually you can do that, with the unannounced (in the changelog) .stringof property ( http://www.digitalmars.com/d/property.html ) : ---- template MakeVariable(Type, char[] name) { const char[] MakeVariable = Type.stringof ~ " " ~ name ~ ";"; }It's unannounced because it doesn't work right yet.
Feb 11 2007
Bruno Medeiros wrote:Walter Bright wrote:It doesn't hurt anything to be there.Bruno Medeiros wrote:What do you mean? If it's doesn't work right yet, why was it released already? (basic cases seem to be working)Well, actually you can do that, with the unannounced (in the changelog) .stringof property ( http://www.digitalmars.com/d/property.html ) : ---- template MakeVariable(Type, char[] name) { const char[] MakeVariable = Type.stringof ~ " " ~ name ~ ";"; }It's unannounced because it doesn't work right yet.
Feb 11 2007
Walter Bright wrote:Bruno Medeiros wrote:Is there any chance we could have alias template parameters become more generic in 1.0006 ? together with stringof, the new mixins could become very powerful... with much nicer syntax. template Add(alias L, alias R) { const Add = L.stringof ~ " + " ~ R.stringof; } right now this template only works when the parameters are single symbols. would be nice be be able to do: Add!(42,foo); Add!(foo+bar,foo-bar); etc...Walter Bright wrote:It doesn't hurt anything to be there.Bruno Medeiros wrote:What do you mean? If it's doesn't work right yet, why was it released already? (basic cases seem to be working)Well, actually you can do that, with the unannounced (in the changelog) .stringof property ( http://www.digitalmars.com/d/property.html ) : ---- template MakeVariable(Type, char[] name) { const char[] MakeVariable = Type.stringof ~ " " ~ name ~ ";"; }It's unannounced because it doesn't work right yet.
Feb 12 2007
Tomas Lindquist Olsen wrote:Is there any chance we could have alias template parameters become more generic in 1.0006 ? together with stringof, the new mixins could become very powerful... with much nicer syntax. template Add(alias L, alias R) { const Add = L.stringof ~ " + " ~ R.stringof; } right now this template only works when the parameters are single symbols. would be nice be be able to do: Add!(42,foo); Add!(foo+bar,foo-bar);What you're asking for we've been calling "alias expressions". It'll get here, just not in the next version.
Feb 13 2007
Walter Bright wrote:Bruno Medeiros wrote:<trashes meta.nameof> It was a piece of code I was particularly proud of. Ah well. </trashes> It seems that 90% of the metaprogramming code I've ever written has been made obsolete by being incorporated into the code language. My 'workarounds' file went from 16 entries to zero. But the ability to do it for an expression as well is quite exciting; it seems that this could easily supercede lazy parameters. So I'm not complaining <g>.Well, actually you can do that, with the unannounced (in the changelog) .stringof property ( http://www.digitalmars.com/d/property.html ) : ---- template MakeVariable(Type, char[] name) { const char[] MakeVariable = Type.stringof ~ " " ~ name ~ ";"; }It's unannounced because it doesn't work right yet.
Feb 13 2007
Don Clugston wrote:Walter Bright wrote:Heh, you should see what happened to Pyd when tuples were introduced to the language. In fact, thanks to the magic of Subversion, you can! http://dsource.org/projects/pyd/changeset/45 Ohh, lookit all the huge, pretty red sections. -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.orgBruno Medeiros wrote:<trashes meta.nameof> It was a piece of code I was particularly proud of. Ah well. </trashes> It seems that 90% of the metaprogramming code I've ever written has been made obsolete by being incorporated into the code language. My 'workarounds' file went from 16 entries to zero. But the ability to do it for an expression as well is quite exciting; it seems that this could easily supercede lazy parameters. So I'm not complaining <g>.Well, actually you can do that, with the unannounced (in the changelog) .stringof property ( http://www.digitalmars.com/d/property.html ) : ---- template MakeVariable(Type, char[] name) { const char[] MakeVariable = Type.stringof ~ " " ~ name ~ ";"; }It's unannounced because it doesn't work right yet.
Feb 13 2007
Kirk McDonald wrote:Ohh, lookit all the huge, pretty red sections.My goal is to make the Boost implementation code look as obsolete as a muzzle-loading smoothbore.
Feb 13 2007
Walter Bright wrote:Kirk McDonald wrote:It has nothing to do with the conversation, but your statement reminded me... I saw a show not too long ago (may have been MythBusters) where the penetration depth of various types of ammunition were tested in water. Modern bullets had poor penetration because they tended to tumble upon entering the water, thus creating drag (max injury depth was less than 5 feet). And high-velocity rounds tended to fragment upon entry and had even shallower penetration (around 3 feet). Finally, a muzzle-loading smoothbore was tested and it had by far the deepest penetration of any weapon tested. So if you're being shot at in a lake, I suppose you don't want the shooter using Boost ;-) SeanOhh, lookit all the huge, pretty red sections.My goal is to make the Boost implementation code look as obsolete as a muzzle-loading smoothbore.
Feb 13 2007
Sean Kelly wrote:Walter Bright wrote:Sounds like that is about the ammunition, not the gun. The worst thing about a muzzle-loader in combat was you had to *stand up* to reload it. Can you imagine the guts it takes to do that, when your every nerve screams at you to push your face in the dirt?Kirk McDonald wrote:It has nothing to do with the conversation, but your statement reminded me... I saw a show not too long ago (may have been MythBusters) where the penetration depth of various types of ammunition were tested in water. Modern bullets had poor penetration because they tended to tumble upon entering the water, thus creating drag (max injury depth was less than 5 feet). And high-velocity rounds tended to fragment upon entry and had even shallower penetration (around 3 feet). Finally, a muzzle-loading smoothbore was tested and it had by far the deepest penetration of any weapon tested. So if you're being shot at in a lake, I suppose you don't want the shooter using Boost ;-)Ohh, lookit all the huge, pretty red sections.My goal is to make the Boost implementation code look as obsolete as a muzzle-loading smoothbore.
Feb 13 2007
Walter Bright wrote:Sean Kelly wrote:It wasn't an issue until people got sick of standing in two lines facing one another :-) I wonder how quickly the shift to guerilla tactics changed the development of firearm technology. After discovering they had a chance to actually survive a battle, I can't imagine soldiers were terribly keen on giving up their cover every ten seconds or so. SeanWalter Bright wrote:Sounds like that is about the ammunition, not the gun. The worst thing about a muzzle-loader in combat was you had to *stand up* to reload it. Can you imagine the guts it takes to do that, when your every nerve screams at you to push your face in the dirt?Kirk McDonald wrote:It has nothing to do with the conversation, but your statement reminded me... I saw a show not too long ago (may have been MythBusters) where the penetration depth of various types of ammunition were tested in water. Modern bullets had poor penetration because they tended to tumble upon entering the water, thus creating drag (max injury depth was less than 5 feet). And high-velocity rounds tended to fragment upon entry and had even shallower penetration (around 3 feet). Finally, a muzzle-loading smoothbore was tested and it had by far the deepest penetration of any weapon tested. So if you're being shot at in a lake, I suppose you don't want the shooter using Boost ;-)Ohh, lookit all the huge, pretty red sections.My goal is to make the Boost implementation code look as obsolete as a muzzle-loading smoothbore.
Feb 13 2007
Sean Kelly wrote:Walter Bright wrote:I think the firearm technology drove the tactics. The two line approach worked only because guns were inaccurate and very slow loading, the idea was you could reach the enemy lines before they could get off more than one or two shots. With the advent of longer range, more accurate rifles, this turned into a slaughter. Breech loading repeaters finished it off.The worst thing about a muzzle-loader in combat was you had to *stand up* to reload it. Can you imagine the guts it takes to do that, when your every nerve screams at you to push your face in the dirt?It wasn't an issue until people got sick of standing in two lines facing one another :-) I wonder how quickly the shift to guerilla tactics changed the development of firearm technology. After discovering they had a chance to actually survive a battle, I can't imagine soldiers were terribly keen on giving up their cover every ten seconds or so.
Feb 13 2007
Walter Bright wrote:Sean Kelly wrote:Huh. That makes a lot of sense. SeanWalter Bright wrote:I think the firearm technology drove the tactics. The two line approach worked only because guns were inaccurate and very slow loading, the idea was you could reach the enemy lines before they could get off more than one or two shots. With the advent of longer range, more accurate rifles, this turned into a slaughter. Breech loading repeaters finished it off.The worst thing about a muzzle-loader in combat was you had to *stand up* to reload it. Can you imagine the guts it takes to do that, when your every nerve screams at you to push your face in the dirt?It wasn't an issue until people got sick of standing in two lines facing one another :-) I wonder how quickly the shift to guerilla tactics changed the development of firearm technology. After discovering they had a chance to actually survive a battle, I can't imagine soldiers were terribly keen on giving up their cover every ten seconds or so.
Feb 14 2007
Walter Bright wrote:Sean Kelly wrote:Actually the notion of taking cover, now ubiquitously known even by civilians (due to cinematography), is (amazingly) a recent development. Until the end of WWI, soldiers actually were not jumping to the ground under fire. They'd be trained to think that they'd have a better chance by moving forward and storming the enemy. It's pretty much how a million soldiers just died mowed by machine gun at Somme. When I was in the military, there was a big detailed poster displaying the difference in shooting angle offered by a standing vs. a crouched vs. a lying man. AndreiWalter Bright wrote:Sounds like that is about the ammunition, not the gun. The worst thing about a muzzle-loader in combat was you had to *stand up* to reload it. Can you imagine the guts it takes to do that, when your every nerve screams at you to push your face in the dirt?Kirk McDonald wrote:It has nothing to do with the conversation, but your statement reminded me... I saw a show not too long ago (may have been MythBusters) where the penetration depth of various types of ammunition were tested in water. Modern bullets had poor penetration because they tended to tumble upon entering the water, thus creating drag (max injury depth was less than 5 feet). And high-velocity rounds tended to fragment upon entry and had even shallower penetration (around 3 feet). Finally, a muzzle-loading smoothbore was tested and it had by far the deepest penetration of any weapon tested. So if you're being shot at in a lake, I suppose you don't want the shooter using Boost ;-)Ohh, lookit all the huge, pretty red sections.My goal is to make the Boost implementation code look as obsolete as a muzzle-loading smoothbore.
Feb 15 2007
Walter Bright wrote:Kirk McDonald wrote:LOL After reading that, I was immediately given the mental image of a colonial minute-man, trying desperately to hammer out C++ code on a set of jacquard loom cards. -- - EricAnderton at yahooOhh, lookit all the huge, pretty red sections.My goal is to make the Boost implementation code look as obsolete as a muzzle-loading smoothbore.
Feb 13 2007
Don Clugston wrote:Walter Bright wrote:The big problem with .stringof is the following: alias Foo.Bar.Abc T; typedef int Abc; const char[] s = T.stringof; typeof(mixin(s)) x; s is given the string "Abc". So, when the mixin evaluates s, it resolves to the local declaration of Abc, not the fully qualified one.Bruno Medeiros wrote:<trashes meta.nameof> It was a piece of code I was particularly proud of. Ah well. </trashes> It seems that 90% of the metaprogramming code I've ever written has been made obsolete by being incorporated into the code language. My 'workarounds' file went from 16 entries to zero. But the ability to do it for an expression as well is quite exciting; it seems that this could easily supercede lazy parameters. So I'm not complaining <g>.Well, actually you can do that, with the unannounced (in the changelog) .stringof property ( http://www.digitalmars.com/d/property.html ) : ---- template MakeVariable(Type, char[] name) { const char[] MakeVariable = Type.stringof ~ " " ~ name ~ ";"; }It's unannounced because it doesn't work right yet.
Feb 13 2007
Walter Bright wrote:Don Clugston wrote:Isn't it always going to be true that the scope where stringof is applied, could be different from where it is mixed in? That's why I figured that the concept of symbolnameof (the minimal descriptor in the scope) was different from qualifiednameof (valid in any scope). Of course, you've got access to much more information than I did, so perhaps there's a cleaner solution.Walter Bright wrote:The big problem with .stringof is the following: alias Foo.Bar.Abc T; typedef int Abc; const char[] s = T.stringof; typeof(mixin(s)) x; s is given the string "Abc". So, when the mixin evaluates s, it resolves to the local declaration of Abc, not the fully qualified one.Bruno Medeiros wrote:<trashes meta.nameof> It was a piece of code I was particularly proud of. Ah well. </trashes> It seems that 90% of the metaprogramming code I've ever written has been made obsolete by being incorporated into the code language. My 'workarounds' file went from 16 entries to zero. But the ability to do it for an expression as well is quite exciting; it seems that this could easily supercede lazy parameters. So I'm not complaining <g>.Well, actually you can do that, with the unannounced (in the changelog) .stringof property ( http://www.digitalmars.com/d/property.html ) : ---- template MakeVariable(Type, char[] name) { const char[] MakeVariable = Type.stringof ~ " " ~ name ~ ";"; }It's unannounced because it doesn't work right yet.
Feb 14 2007
Don Clugston wrote:Isn't it always going to be true that the scope where stringof is applied, could be different from where it is mixed in?Yes.That's why I figured that the concept of symbolnameof (the minimal descriptor in the scope) was different from qualifiednameof (valid in any scope). Of course, you've got access to much more information than I did, so perhaps there's a cleaner solution.It obviously needs more work <g>.
Feb 15 2007
Walter Bright wrote:Don Clugston wrote:Erm, shouldn't T.stringof be "T" and not "Abc" nor even "Foo.Bar.Abc"? -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DWalter Bright wrote:The big problem with .stringof is the following: alias Foo.Bar.Abc T; typedef int Abc; const char[] s = T.stringof; typeof(mixin(s)) x; s is given the string "Abc". So, when the mixin evaluates s, it resolves to the local declaration of Abc, not the fully qualified one.Bruno Medeiros wrote:<trashes meta.nameof> It was a piece of code I was particularly proud of. Ah well. </trashes> It seems that 90% of the metaprogramming code I've ever written has been made obsolete by being incorporated into the code language. My 'workarounds' file went from 16 entries to zero. But the ability to do it for an expression as well is quite exciting; it seems that this could easily supercede lazy parameters. So I'm not complaining <g>.Well, actually you can do that, with the unannounced (in the changelog) .stringof property ( http://www.digitalmars.com/d/property.html ) : ---- template MakeVariable(Type, char[] name) { const char[] MakeVariable = Type.stringof ~ " " ~ name ~ ";"; }It's unannounced because it doesn't work right yet.
Feb 15 2007
Bruno Medeiros wrote:Erm, shouldn't T.stringof be "T" and not "Abc" nor even "Foo.Bar.Abc"?There wouldn't be any point to that.
Feb 15 2007
"Bruno Medeiros" <brunodomedeiros+spam com.gmail> wrote in message news:eqnkde$2l2e$1 digitalmars.com...Well, actually you can do that, with the unannounced (in the changelog) .stringof property ( http://www.digitalmars.com/d/property.html ) :Damn! I stopped reading this thread when it got so big, so I completely missed your reply.. and I finally found out about stringof from Frits. This is a sweet, sweet feature. I was actually going to say something about the ability to get the string of an arbitrary expression as well, but that's covered too. What a feature :)
Feb 15 2007
Jarrett Billingsley wrote:"Walter Bright" <newshound digitalmars.com> wrote in message news:eq91hs$fvm$1 digitaldaemon.com...At compile time you mean.Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipI am amazed at the mixin/import features. The ability we have to arbitrarily generate code at runtime is.. something I never would have imagined would come until D2.0.I've been thinking about it, though, and I'm not sure if it's 100% the best way to do it. The major advantage, of course, is that it doesn't introduce tons of new syntax for building up code. However, I'm not sure I really like the idea of building up strings either. It seems.. preprocessor-y. Don't get me wrong, I'm still giddy with the prospects of this new feature. But something about it just seems off.The ability to transform true code trees will come with D's macro abilities. But that's a few months ahead at least. Andrei
Feb 07 2007
Andrei Alexandrescu (See Website For Email) wrote:The ability to transform true code trees will come with D's macro abilities. But that's a few months ahead at least.I can't believe that so many hours have passes since this post and no one has asked for some details? Is this something you and Walter talked about? (Because it sounds too good to be true.) What will those macros be like? Examples...?
Feb 07 2007
Ivan Senji wrote:Andrei Alexandrescu (See Website For Email) wrote:Nothing at the moment but a lot of: .... <insert magic here> voila! Andrei has been mostly hard at work on the const/inout/scope problem. The current way D does it is hackish, and Andrei feels (and I agree) that bringing rigor to it will make D a considerably stronger language.The ability to transform true code trees will come with D's macro abilities. But that's a few months ahead at least.I can't believe that so many hours have passes since this post and no one has asked for some details? Is this something you and Walter talked about? (Because it sounds too good to be true.) What will those macros be like? Examples...?
Feb 07 2007
Walter Bright wrote:Ivan Senji wrote:That's pretty much what I had in mind :o). Actually, I did post about that in a thread in the digitalmars.d group. Search for the title "Idea : Expression Type".Andrei Alexandrescu (See Website For Email) wrote:Nothing at the moment but a lot of: .... <insert magic here> voila!The ability to transform true code trees will come with D's macro abilities. But that's a few months ahead at least.I can't believe that so many hours have passes since this post and no one has asked for some details? Is this something you and Walter talked about? (Because it sounds too good to be true.) What will those macros be like? Examples...?Andrei has been mostly hard at work on the const/inout/scope problem. The current way D does it is hackish, and Andrei feels (and I agree) that bringing rigor to it will make D a considerably stronger language.There's good progress on that! Andrei
Feb 07 2007
Andrei Alexandrescu (See Website For Email) wrote:Walter Bright wrote:Yup, I think the end result will be something we can all be proud of.Andrei has been mostly hard at work on the const/inout/scope problem. The current way D does it is hackish, and Andrei feels (and I agree) that bringing rigor to it will make D a considerably stronger language.There's good progress on that!
Feb 07 2007
Walter Bright wrote:Andrei Alexandrescu (See Website For Email) wrote:This is great news!Walter Bright wrote:Yup, I think the end result will be something we can all be proud of.Andrei has been mostly hard at work on the const/inout/scope problem. The current way D does it is hackish, and Andrei feels (and I agree) that bringing rigor to it will make D a considerably stronger language.There's good progress on that!
Feb 07 2007
== Quote from Ivan Senji (ivan.senji_REMOVE_ _THIS__gmail.com)'s articleAndrei Alexandrescu (See Website For Email) wrote:I was going to, but I'm still righting the mental furniture that got flipped by the last one. Most of the template meta-stuff seems to be done using recursive patterns, (maybe because it is easier to solve the "compile time halting problem" by limiting recursive depth?) So since parse trees are usually thought of as recursion friendly, I imagine it would allow you to take a class as a template argument in the way that you can currently take a tuple, and do either foreach or C[i..j] style processing of fields, subclasses, etc. A lower level abstraction would be to actually take a parse tree and just hand it to you, and you could iterate over it, something like casting a "char[][int]*" to "AA*". But this kind of low level approach would mean the compiler would forever need to support the same parse tree layouts, which is undesireable. I guess the question depends on how people actually use this kind of thing; how do people use LISP macros in real world code? It's sort of a language-writing language, but for some reason its hard to find non-toy examples. (On the other hand, when I do its hard to read them.) KevinThe ability to transform true code trees will come with D's macro abilities. But that's a few months ahead at least.I can't believe that so many hours have passes since this post and no one has asked for some details?
Feb 07 2007
Kirk McDonald Wrote: <snip>// file test.d mixin(`import std.stdio : writefln;`); mixin(`void main() { mixin("writefln(import(\"test.d\"));"); }`);So now you can write cheat quines in D! But the cheating is at compile time, rather than at run time as with cheat quines in some other languages. Stewart.
Feb 07 2007
Walter Bright wrote:Fixes many bugs, some serious. Some new goodies. http://www.digitalmars.com/d/changelog.html http://ftp.digitalmars.com/dmd.1.005.zipWow, This is just sweet! Thanks, Walter! :D I'll see what kind of abuse can be done with the new mixin stuff ;) Still, we must find a way to reduce the memory requirements of evaluating more complex templates - as at one point, they are going to contain pretty arbitrary code. -- Tomasz Stachowiak
Feb 08 2007
kris Wrote:Andreas Kochenburger wrote:I was into Forth, back in the day. The strange thing is, I don't think it ever affected my programming in any other language. It's hard to imagine something easier to lex...Kevin Bealer wrote:Yeah, Forth is an incredibly powerful languageCharles D Hixson wrote: But the central feature of FORTH is that the compiler and runtime can be made mind-bogglingly small. I think the run time speed for a naive interpretation is probably somewhere between C and interpreted bytecode. From this page about tiny4th: http://www.seanet.com/~karllunt/tiny4th "The run-time engine takes up less than 1K of code space and the p-codes are so dense that you can get a lot of robot functionality in just 2K."Before someone thinks, Forth is only a play-thing, see http://www.forth.com/ There are also excellent freeware versions around, f.ex. http://win32forth.sourceforge.net/ There is even ans ANS / ISO standard for the language. Andreas
Feb 09 2007