Jump to page: 1 24  
Page
Thread overview
Why D needs implicit instantion or an autotype keyword
Jul 18, 2004
Matthew
Jul 18, 2004
Ivan Senji
Jul 18, 2004
Matthias Becker
Jul 18, 2004
Matthew Wilson
Jul 18, 2004
Bent Rasmussen
Jul 18, 2004
Norbert Nemec
Jul 18, 2004
Bent Rasmussen
Jul 20, 2004
Norbert Nemec
Jul 20, 2004
Bent Rasmussen
Jul 20, 2004
Andy Friesen
Jul 18, 2004
Andy Friesen
Jul 19, 2004
Bent Rasmussen
Jul 20, 2004
Norbert Nemec
Jul 19, 2004
Russ Lewis
Jul 19, 2004
Andy Friesen
Jul 20, 2004
Matthias Becker
Multimethods
Jul 20, 2004
nail
Jul 20, 2004
Sean Kelly
Jul 21, 2004
Matthias Becker
Jul 21, 2004
Sean Kelly
Jul 21, 2004
Russ Lewis
Jul 21, 2004
nail
Jul 21, 2004
Matthias Becker
Jul 21, 2004
nail
Jul 22, 2004
Matthias Becker
Jul 23, 2004
Sean Kelly
Jul 23, 2004
Matthias Becker
Jul 23, 2004
Sha Chancellor
Jul 23, 2004
Sean Kelly
Jul 23, 2004
Sha Chancellor
Jul 23, 2004
Sean Kelly
Jul 23, 2004
Sha Chancellor
Jul 23, 2004
Sean Kelly
Jul 21, 2004
Andy Friesen
MultimethodDelegate (was: Re: Multimethods) - multimethod.d
Jul 21, 2004
pragma
Jul 21, 2004
pragma
Jul 28, 2004
Bent Rasmussen
July 18, 2004
Ok, some of you may have followed a recent post describing composition of filtering operations on DTL containers, e.g.


    foreach(X x;
cont.select!(SomePredicate).collect(SomeTxFunction).select(SomeDelegate))
    {
      . . .
    }

Although the compiler currently eats my machine when trying to compile this, I'm pretty confident that it can be achieved soon without much hassles. This all works reasonably neatly because all <range> objects (those returned by transformations on containers or other <ranges>) support foreach. So far so good.

There'll also be support for getting a specific item out of container/range, via
methods like max(), min_if(), find_first(), as in:

    Person m =
cont.select!(SomePredicate).collect(SomeTxFunction).max(SomeDelegate)

That's also quite straightforward.

However, here's the rub. If you want to get hold of a range and save it for later processing, you need to know its type. The problem is that its type can be something incredibly complex.

Consider the following fictional case, where we're filtering the contents of a List of Person

container:                                                  List!(Person)
results of select() (with delegate IsMan):
MatchedNotionalRange!(_ListUtil!(Person).ListRange, DelegatePredicate!(bool
delegate(in Person value), Person))

Now that's just the one level. Imagine what it looks like when we're composing another filter on top of the results of select()!

In C++ one can obviate such things by writing working template functions. Since C++ supports implicit instantiation, the worker function can deduce such horrendous mouthfuls for us. Of course, this is not always appropriate, but it does help a lot.

Since D is not going to have implicit instantiation, I suggest that we *must* have the autotype keyword, which will be akin to the semantics proposed for auto in C++ 0.x. That is to say, the type is deduced, at compile time - it's no variant type! - from the initialising expression, so:

    bool IsOdd(Number n);
    Number Square(Number n);

    autotype r = cont.select!(IsOdd).collect(Square)

    . . .

    for(; r.open; r.advance())
    {
        writeln("Number: ", r.current);
    }

AFAIUI, there's no major conceptual difficulty in doing this, since the compiler already knows the type of the initialising expression. The only area of uncertainty is that we might lose the polymorphic nature of the type, but I'd say that if you know what type it should be, then you don't need autotype. Kind of axiomatic, but maybe I've missed something

Thoughts, everyone? Walter?!?




July 18, 2004
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cddhd8$275p$2@digitaldaemon.com...
> Ok, some of you may have followed a recent post describing composition of filtering operations on DTL containers, e.g.
>
>
>     foreach(X x;
> cont.select!(SomePredicate).collect(SomeTxFunction).select(SomeDelegate))
>     {
>       . . .
>     }
>
> Although the compiler currently eats my machine when trying to compile
this, I'm
> pretty confident that it can be achieved soon without much hassles. This
all
> works reasonably neatly because all <range> objects (those returned by transformations on containers or other <ranges>) support foreach. So far
so good.
>
> There'll also be support for getting a specific item out of
container/range, via
> methods like max(), min_if(), find_first(), as in:
>
>     Person m =
> cont.select!(SomePredicate).collect(SomeTxFunction).max(SomeDelegate)
>
> That's also quite straightforward.
>
> However, here's the rub. If you want to get hold of a range and save it
for later
> processing, you need to know its type. The problem is that its type can be something incredibly complex.
>
> Consider the following fictional case, where we're filtering the contents
of a
> List of Person
>
> container:                                                  List!(Person)
> results of select() (with delegate IsMan):
> MatchedNotionalRange!(_ListUtil!(Person).ListRange,
DelegatePredicate!(bool
> delegate(in Person value), Person))
>
> Now that's just the one level. Imagine what it looks like when we're
composing
> another filter on top of the results of select()!
>
> In C++ one can obviate such things by writing working template functions.
Since
> C++ supports implicit instantiation, the worker function can deduce such horrendous mouthfuls for us. Of course, this is not always appropriate,
but it
> does help a lot.
>
> Since D is not going to have implicit instantiation, I suggest that we
*must*
> have the autotype keyword, which will be akin to the semantics proposed
for auto
> in C++ 0.x. That is to say, the type is deduced, at compile time - it's no variant type! - from the initialising expression, so:
>
>     bool IsOdd(Number n);
>     Number Square(Number n);
>
>     autotype r = cont.select!(IsOdd).collect(Square)
>
>     . . .
>
>     for(; r.open; r.advance())
>     {
>         writeln("Number: ", r.current);
>     }
>
> AFAIUI, there's no major conceptual difficulty in doing this, since the
compiler
> already knows the type of the initialising expression. The only area of uncertainty is that we might lose the polymorphic nature of the type, but
I'd say
> that if you know what type it should be, then you don't need autotype.
Kind of
> axiomatic, but maybe I've missed something
>
> Thoughts, everyone? Walter?!?

I like it! I also liked that proposal for C++, so why not for D? :)



July 18, 2004
>Thoughts, everyone? Walter?!?

Well, I proposed this some time ago, got only good response, but Walter didn't answer.

If you look at Walters style you can understand this. He declares all variables on top of his functions, like Pascal coders do or C programmers before 1999.

Anyway, I don't like the name autotype. In C++0x auto is used so they don't have to introduce a new keyword. But auto is already used in D (well it is in C++, too, but with another meaning, that can't conflict in the situations, where you need the new auto).

Other languages use let, var or val for this. Why don't we use one of these words?


-- Matthias Becker


July 18, 2004
"Matthias Becker" <Matthias_member@pathlink.com> wrote in message news:cddv6v$2bi8$1@digitaldaemon.com...
> >Thoughts, everyone? Walter?!?
>
> Well, I proposed this some time ago, got only good response, but Walter
didn't
> answer.
>
> If you look at Walters style you can understand this. He declares all
variables
> on top of his functions, like Pascal coders do or C programmers before
1999.
>
> Anyway, I don't like the name autotype. In C++0x auto is used so they
don't have
> to introduce a new keyword. But auto is already used in D (well it is in
C++,
> too, but with another meaning, that can't conflict in the situations,
where you
> need the new auto).
>
> Other languages use let, var or val for this. Why don't we use one of
these
> words?

I don't really care about the name, although I don't like let and val, and I assume var will be reserved for a built-in variant type in the future.



July 18, 2004
You are talking about two connected but distinct issues here: implicit instantiation and automatic type deduction for local variables.

The first is dearly needed for template metaprogramming, and especially for expression templates. It is far more than just a convenience issue. A nested expression of moderate complexity, will usually have a type of nested templates of the same depth. Furthermore: the exact type of the expression may not even be easy to deduct, but it may follow from some lengthy compile-time computation.

With types of local variables, the situation is similar. Of course, you could in principle always deduct them and give them explicitly, but for a non-trivial meta-program, this deduction may be arbitrarily complicated. The compiler, of course, can always deduct it (that's why it is called compile-time-computation).

B.t.w: autotypes for local variables have proven rather convenient in Sather as well. There is no meta-programming possibility, so it really is just a matter of convenience, but still, you quickly get addicted to it...




Matthew wrote:

> Ok, some of you may have followed a recent post describing composition of filtering operations on DTL containers, e.g.
> 
> 
>     foreach(X x;
> cont.select!(SomePredicate).collect(SomeTxFunction).select(SomeDelegate))
>     {
>       . . .
>     }
> 
> Although the compiler currently eats my machine when trying to compile this, I'm pretty confident that it can be achieved soon without much hassles. This all works reasonably neatly because all <range> objects (those returned by transformations on containers or other <ranges>) support foreach. So far so good.
> 
> There'll also be support for getting a specific item out of
> container/range, via methods like max(), min_if(), find_first(), as in:
> 
>     Person m =
> cont.select!(SomePredicate).collect(SomeTxFunction).max(SomeDelegate)
> 
> That's also quite straightforward.
> 
> However, here's the rub. If you want to get hold of a range and save it for later processing, you need to know its type. The problem is that its type can be something incredibly complex.
> 
> Consider the following fictional case, where we're filtering the contents of a List of Person
> 
> container:                                                  List!(Person)
> results of select() (with delegate IsMan):
> MatchedNotionalRange!(_ListUtil!(Person).ListRange,
> DelegatePredicate!(bool delegate(in Person value), Person))
> 
> Now that's just the one level. Imagine what it looks like when we're composing another filter on top of the results of select()!
> 
> In C++ one can obviate such things by writing working template functions. Since C++ supports implicit instantiation, the worker function can deduce such horrendous mouthfuls for us. Of course, this is not always appropriate, but it does help a lot.
> 
> Since D is not going to have implicit instantiation, I suggest that we *must* have the autotype keyword, which will be akin to the semantics proposed for auto in C++ 0.x. That is to say, the type is deduced, at compile time - it's no variant type! - from the initialising expression, so:
> 
>     bool IsOdd(Number n);
>     Number Square(Number n);
> 
>     autotype r = cont.select!(IsOdd).collect(Square)
> 
>     . . .
> 
>     for(; r.open; r.advance())
>     {
>         writeln("Number: ", r.current);
>     }
> 
> AFAIUI, there's no major conceptual difficulty in doing this, since the compiler already knows the type of the initialising expression. The only area of uncertainty is that we might lose the polymorphic nature of the type, but I'd say that if you know what type it should be, then you don't need autotype. Kind of axiomatic, but maybe I've missed something
> 
> Thoughts, everyone? Walter?!?

July 18, 2004
Matthew wrote:
> Since D is not going to have implicit instantiation, I suggest that we *must*
> have the autotype keyword, which will be akin to the semantics proposed for auto
> in C++ 0.x. That is to say, the type is deduced, at compile time - it's no
> variant type! - from the initialising expression, so:
> 
> Thoughts, everyone? Walter?!?

It even looks (to my feeble brain, at least) easy to implement:

	autotype r = expr;
	// equivalent to:
	typeof(expr) r = expr;

 -- andy
July 18, 2004
> I don't really care about the name, although I don't like let and val, and
I
> assume var will be reserved for a built-in variant type in the future.

I like "val", it reminds me of ML.


July 18, 2004
> B.t.w: autotypes for local variables have proven rather convenient in
Sather
> as well. There is no meta-programming possibility, so it really is just a matter of convenience, but still, you quickly get addicted to it...

It sure would be sweet to have both in 2.0. I like it even before I've tried it. :-)

val t, i;
...
t = s[5 .. 25];
i = index(s,"abc");

begone bloat


July 19, 2004
"Andy Friesen" <andy@ikagames.com> escribió en el mensaje
news:cde51k$2dpc$1@digitaldaemon.com
| Matthew wrote:
|| Since D is not going to have implicit instantiation, I suggest that we
*must*
|| have the autotype keyword, which will be akin to the semantics proposed
for auto
|| in C++ 0.x. That is to say, the type is deduced, at compile time - it's
no
|| variant type! - from the initialising expression, so:
||
|| Thoughts, everyone? Walter?!?
|

I don't really care about the name, but I do like the idea.

| It even looks (to my feeble brain, at least) easy to implement:
|
| autotype r = expr;
| // equivalent to:
| typeof(expr) r = expr;
|
|   -- andy

What if "expr" is really complex (like that really long expression that Matthew posted before) and the compiler can't directly determine what it's type is? Wouldn't it mean evaluating it twice? Of course, if it just can't happen, then just tell me so, I just wanna be sure.

-----------------------
Carlos Santander Bernal


July 19, 2004
> What if "expr" is really complex (like that really long expression that Matthew posted before) and the compiler can't directly determine what it's type is? Wouldn't it mean evaluating it twice? Of course, if it just can't happen, then just tell me so, I just wanna be sure.

I can't imagine. To test this write

    type value = expr;

where typeof(expr) is incompatible with type, and expr is an arbitrarily
complex expression.

It should be clear that since the compiler can catch type mismatches between the type of value and the type of expr, it must know the type of expr and hence be able to deduce the type of a val/autotype.

I can imagine implicit template instantiation complex to implement though. But then either it can deduce the types or it can't, in which case compilation fails.


« First   ‹ Prev
1 2 3 4