digitalmars.D.announce - My first email to Walter, ever
- Andrei Alexandrescu (6/53) Jul 06 2013 While doing some unrelated research I stumbled upon my very first email
- Andrej Mitrovic (2/4) Jul 07 2013 That's a cool teaser, but how did the discussion continue? :)
- Walter Bright (4/8) Jul 07 2013 Generally along these lines:
- Joseph Rushton Wakeling (2/7) Jul 08 2013 What happened when Toto pulled back the curtain? :-)
- Marco Leise (14/28) Jul 07 2013 check
- Peter Alexander (34/39) Jul 07 2013 :-(
- John Colvin (4/44) Jul 07 2013 So what you're effectively asking for is for templates to be
- Timon Gehr (3/8) Jul 07 2013 Almost there indeed.
- Peter Alexander (12/24) Jul 07 2013 Hmmm.... I was thinking about encoding/decoding types, but it
- Artur Skawina (12/42) Jul 07 2013 template allSatisfy(alias F, T...) {
- Nick Sabalausky (10/24) Jul 07 2013 It'd be even nicer when/if this becomes possible (I *think* I remember
- Andrej Mitrovic (17/25) Jul 07 2013 Also why not be able to write this (yes I know we can use Filter!()
- QAston (5/45) Jul 07 2013 Static foreach would help, at least in my case:
- Kagamin (3/21) Jul 08 2013 It's deplhi-style
- Xinok (5/15) Jul 07 2013 You may hold a different opinion today, and my opinion is
- deadalnix (2/10) Jul 07 2013 hoooooooo :P
While doing some unrelated research I stumbled upon my very first email to Walter, dated April 26, 2004. I liked to see from today's perspective where a great collaboration and friendship have started. I thought others would also enjoy to see it, so I'm sharing it with Walter's approval and a few minor edits. On 4/26/04 6:54 PM, Andrei Alexandrescu wrote:[Walter: I'm going to be ruthless. Put your bulletproof vest on.] Hi Walter, this is Andrei, we met at SD in Santa Clara. I was bitching to myself and then together with a friend (e-meet [...]) about how hard it is to do metaprogramming in C++. He mentioned D is much better at it, and we browsed the online documentation for D's templates (http://www.digitalmars.com/d/template.html), which we noticed (apologies if I am wrong) is not much more more than a cleaned-syntax version of C++'s templates, which in turn are [...]. That sucks. So I said I'd give you the highest order bits of what I think what a better language for metaprogramming ought to be like. In spite of my ruthlessness, please accept this as a statement of hope that you'd be willing to think about this and do something about it. A metalanguage should bear the same programming style as the base language that it serves. I think that's only fair: the programmer learns one syntax and set of semantics (e.g. conditionals, iterations, objects...), and applies it as transparently as it gets to both metaprogramming and regular programming. C++ has a rich mixed-mode language for straight programming, and a half-assed (or should I say quarter-assed) functional language for metaprogramming. You carried this schism in D, while just cleaning the corners. Terrible. If you have conditionals, iteration, functions, and objects in D's straight programming support, you should have conditionals, iteration, functions, and objects in D's metalanguage. (I'm not asking for things like virtuals, exceptions, contracts, and other higher-order stuff on grounds that metaprograms are usually smaller and aren't subjected to as many scale issues as regular programs are.) Those should be combined with introspection primitives, such as: * The venerable typeof * For a class, enumerate all of its members, and figure out their attributes (protection level, static or not, type...) * For a module/namespace, enumerate all of its symbols and figure out their attributes. * For a function, figure out its return type and the type of each of its formal arguments. * Figure out if a certain function exists (that should be easy if you have the tools above). That will be useful to decide, for example, if an iterator supports random access. * And if you really want to go meta, define metacode that can take an AST node as a parameter and can visit the AST and figure out what each node is. That would allow things such as loop fusion and other advanced stuff. But for now, let's leave those aside. Does anything make sense so far? :o) Andrei
Jul 06 2013
On 7/7/13, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:While doing some unrelated research I stumbled upon my very first email to Walter, dated April 26, 2004.That's a cool teaser, but how did the discussion continue? :)
Jul 07 2013
On 7/7/2013 5:09 AM, Andrej Mitrovic wrote:On 7/7/13, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Generally along these lines: "And you, Scarecrow, have the effrontery to ask for a brain, you billowing bale of bovine fodder!"While doing some unrelated research I stumbled upon my very first email to Walter, dated April 26, 2004.That's a cool teaser, but how did the discussion continue? :)
Jul 07 2013
On Sunday, 7 July 2013 at 22:03:17 UTC, Walter Bright wrote:On 7/7/2013 5:09 AM, Andrej Mitrovic wrote:What happened when Toto pulled back the curtain? :-)That's a cool teaser, but how did the discussion continue? :)Generally along these lines: "And you, Scarecrow, have the effrontery to ask for a brain, you billowing bale of bovine fodder!"
Jul 08 2013
Am Sat, 06 Jul 2013 20:02:16 -0700 schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:check* The venerable typeofcheck* For a class, enumerate all of its members, and figure out their attributes (protection level, static or not, type...)check* For a module/namespace, enumerate all of its symbols and figure out their attributes.check* For a function, figure out its return type and the type of each of its formal arguments.check* Figure out if a certain function exists (that should be easy if you have the tools above). That will be useful to decide, for example, if an iterator supports random access.che... oh _that_ topic. I think you have done some really good team work there. And I may add Walter's good intuition to make the front end reusable for GDC and LDC. Btw, you didn't want to start a new discussion about AST manipulation through the back door, did you? ;) -- Marco* And if you really want to go meta, define metacode that can take an AST node as a parameter and can visit the AST and figure out what each node is. That would allow things such as loop fusion and other advanced stuff. But for now, let's leave those aside.
Jul 07 2013
On Sunday, 7 July 2013 at 03:03:03 UTC, Andrei Alexandrescu wrote:Terrible. If you have conditionals, iteration, functions, and objects in D's straight programming support, you should have conditionals, iteration, functions, and objects in D's metalanguage.:-( template allSatisfy(alias F, T...) { static if (T.length == 0) { enum allSatisfy = true; } else static if (T.length == 1) { enum allSatisfy = F!(T[0]); } else { enum allSatisfy = allSatisfy!(F, T[ 0 .. $/2]) && allSatisfy!(F, T[$/2 .. $ ]); } } Still looks like half-assed functional programming to me. Where's the iteration? Why can't I write this? template allSatisfy(alias F, T...) { foreach(t; T) if (!F!(t)) return false; return true; } (Those are rhetorical questions btw, before anyone links me to a D tutorial). We're almost there with CTFE, but CTFE can only run functions that could run at runtime. In a crazy world where types were first class objects, stuff like this would be feasible. Or perhaps we just need a compile-time metalanguage that allows things like this to be run with CTFE?
Jul 07 2013
On Sunday, 7 July 2013 at 12:27:02 UTC, Peter Alexander wrote:On Sunday, 7 July 2013 at 03:03:03 UTC, Andrei Alexandrescu wrote:So what you're effectively asking for is for templates to be compile-time functions where types are first class variables. I would love that.Terrible. If you have conditionals, iteration, functions, and objects in D's straight programming support, you should have conditionals, iteration, functions, and objects in D's metalanguage.:-( template allSatisfy(alias F, T...) { static if (T.length == 0) { enum allSatisfy = true; } else static if (T.length == 1) { enum allSatisfy = F!(T[0]); } else { enum allSatisfy = allSatisfy!(F, T[ 0 .. $/2]) && allSatisfy!(F, T[$/2 .. $ ]); } } Still looks like half-assed functional programming to me. Where's the iteration? Why can't I write this? template allSatisfy(alias F, T...) { foreach(t; T) if (!F!(t)) return false; return true; } (Those are rhetorical questions btw, before anyone links me to a D tutorial). We're almost there with CTFE, but CTFE can only run functions that could run at runtime. In a crazy world where types were first class objects, stuff like this would be feasible. Or perhaps we just need a compile-time metalanguage that allows things like this to be run with CTFE?
Jul 07 2013
On 07/07/2013 02:27 PM, Peter Alexander wrote:... We're almost there with CTFE, but CTFE can only run functions that could run at runtime. In a crazy world where types were first class objects, stuff like this would be feasible. Or perhaps we just need a compile-time metalanguage that allows things like this to be run with CTFE?Almost there indeed. http://d.puremagic.com/issues/show_bug.cgi?id=9945
Jul 07 2013
On Sunday, 7 July 2013 at 13:20:14 UTC, Timon Gehr wrote:On 07/07/2013 02:27 PM, Peter Alexander wrote:Hmmm.... I was thinking about encoding/decoding types, but it doesn't help with template instantiations. You still need a separate compile time language. bool allSatisfy(alias F)(TypeInfo[] typeIds) { foreach(t; typeIds) if (!F!(__traits(typeFromId, t))) <---- How do you do this step? return false; return true; } Or am I missing something?... We're almost there with CTFE, but CTFE can only run functions that could run at runtime. In a crazy world where types were first class objects, stuff like this would be feasible. Or perhaps we just need a compile-time metalanguage that allows things like this to be run with CTFE?Almost there indeed. http://d.puremagic.com/issues/show_bug.cgi?id=9945
Jul 07 2013
On 07/07/13 14:27, Peter Alexander wrote:template allSatisfy(alias F, T...) { static if (T.length == 0) { enum allSatisfy = true; } else static if (T.length == 1) { enum allSatisfy = F!(T[0]); } else { enum allSatisfy = allSatisfy!(F, T[ 0 .. $/2]) && allSatisfy!(F, T[$/2 .. $ ]); } } Still looks like half-assed functional programming to me. Where's the iteration? Why can't I write this? template allSatisfy(alias F, T...) { foreach(t; T) if (!F!(t)) return false; return true; } (Those are rhetorical questions btw, before anyone links me to a D tutorial).template allSatisfy(alias F, T...) { enum allSatisfy = { foreach (E; T) if (!F!E) return false; return true; }(); } // And no, it isn't perfect. But not /that/ much is missing. // It's the more complex cases that would benefit from more meta features. artur
Jul 07 2013
On Sun, 07 Jul 2013 15:23:03 +0200 Artur Skawina <art.08.09 gmail.com> wrote:template allSatisfy(alias F, T...) { enum allSatisfy = { foreach (E; T) if (!F!E) return false; return true; }(); } // And no, it isn't perfect. But not /that/ much is missing. // It's the more complex cases that would benefit from more meta features.It'd be even nicer when/if this becomes possible (I *think* I remember Walter saying it was planned...): enum allSatisfy(alias F, T...) = { foreach (E; T) if (!F!E) return false; return true; }();
Jul 07 2013
On 7/7/13, Peter Alexander <peter.alexander.au gmail.com> wrote:Still looks like half-assed functional programming to me.Yep I agree.Where's the iteration? Why can't I write this? template allSatisfy(alias F, T...) { foreach(t; T) if (!F!(t)) return false; return true; }Also why not be able to write this (yes I know we can use Filter!() but this is just an example): template GetIntegrals(Types...) { foreach (T; Types) { static if (isIntegral!T) GetIntegrals ~= T; // GetIntegrals becomes a typetuple } } This beats the whole recursive template madness which we always have to write (again there's the D language, and the "template" language, just like in C++) Maybe it would even speed things up not having to recursively instantiate the template many times.
Jul 07 2013
On Sunday, 7 July 2013 at 12:27:02 UTC, Peter Alexander wrote:On Sunday, 7 July 2013 at 03:03:03 UTC, Andrei Alexandrescu wrote:Static foreach would help, at least in my case: http://forum.dlang.org/post/ebvrirxozwllqjbffwzh forum.dlang.org Sadly, there are more important issues (shared libs, 83 PRs in dmd) so this will probably have to wait for better times.Terrible. If you have conditionals, iteration, functions, and objects in D's straight programming support, you should have conditionals, iteration, functions, and objects in D's metalanguage.:-( template allSatisfy(alias F, T...) { static if (T.length == 0) { enum allSatisfy = true; } else static if (T.length == 1) { enum allSatisfy = F!(T[0]); } else { enum allSatisfy = allSatisfy!(F, T[ 0 .. $/2]) && allSatisfy!(F, T[$/2 .. $ ]); } } Still looks like half-assed functional programming to me. Where's the iteration? Why can't I write this? template allSatisfy(alias F, T...) { foreach(t; T) if (!F!(t)) return false; return true; } (Those are rhetorical questions btw, before anyone links me to a D tutorial). We're almost there with CTFE, but CTFE can only run functions that could run at runtime. In a crazy world where types were first class objects, stuff like this would be feasible. Or perhaps we just need a compile-time metalanguage that allows things like this to be run with CTFE?
Jul 07 2013
On Sunday, 7 July 2013 at 12:27:02 UTC, Peter Alexander wrote::-( template allSatisfy(alias F, T...) { static if (T.length == 0) { enum allSatisfy = true; } else static if (T.length == 1) { enum allSatisfy = F!(T[0]); } else { enum allSatisfy = allSatisfy!(F, T[ 0 .. $/2]) && allSatisfy!(F, T[$/2 .. $ ]); } }It's deplhi-style http://www.freepascal.org/docs-html/ref/refse77.html#x155-16500014.3
Jul 08 2013
On Sunday, 7 July 2013 at 03:03:03 UTC, Andrei Alexandrescu wrote:On 4/26/04 6:54 PM, Andrei Alexandrescu wrote:You may hold a different opinion today, and my opinion is worthless this point. But my two cents, I think (1) static-if and (2) making templates independent of classes and functions were both huge steps forward.I was bitching to myself and then together with a friend (e-meet [...]) about how hard it is to do metaprogramming in C++. He mentioned D is much better at it, and we browsed the online documentation for D's templates (http://www.digitalmars.com/d/template.html), which we noticed (apologies if I am wrong) is not much more more than a cleaned-syntax version of C++'s templates, which in turn are [...].
Jul 07 2013
On Sunday, 7 July 2013 at 03:03:03 UTC, Andrei Alexandrescu wrote:hoooooooo :P* And if you really want to go meta, define metacode that can take an AST node as a parameter and can visit the AST and figure out what each node is. That would allow things such as loop fusion and other advanced stuff. But for now, let's leave those aside.
Jul 07 2013