Thread overview | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 07, 2013 My first email to Walter, ever | ||||
---|---|---|---|---|
| ||||
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
>
|
July 07, 2013 Re: My first email to Walter, ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 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? :) |
July 07, 2013 Re: My first email to Walter, ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Am Sat, 06 Jul 2013 20:02:16 -0700 schrieb Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>: > > * The venerable typeof check > > * 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. check > > * 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. 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 |
July 07, 2013 Re: My first email to Walter, ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 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?
|
July 07, 2013 Re: My first email to Walter, ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Sunday, 7 July 2013 at 03:03:03 UTC, Andrei Alexandrescu wrote:
> On 4/26/04 6:54 PM, Andrei Alexandrescu wrote:
>> 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
>> [...].
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.
|
July 07, 2013 Re: My first email to Walter, ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Alexander | 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:
>> 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?
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.
|
July 07, 2013 Re: My first email to Walter, ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Alexander | 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 |
July 07, 2013 Re: My first email to Walter, ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Alexander | 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
|
July 07, 2013 Re: My first email to Walter, ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Alexander | 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. |
July 07, 2013 Re: My first email to Walter, ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Sunday, 7 July 2013 at 13:20:14 UTC, Timon Gehr wrote:
> 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
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?
|
Copyright © 1999-2021 by the D Language Foundation