Jump to page: 1 2
Thread overview
template functions
Feb 23, 2004
Sean Kelly
Feb 23, 2004
Sam McCall
Feb 23, 2004
C
Feb 23, 2004
Sean Kelly
Feb 23, 2004
Sam McCall
Feb 23, 2004
Ben Hinkle
Feb 23, 2004
Sean Kelly
Feb 23, 2004
Ben Hinkle
Feb 23, 2004
Ben Hinkle
Feb 23, 2004
Sam McCall
Feb 23, 2004
Ben Hinkle
Feb 23, 2004
Sam McCall
Feb 23, 2004
Sean Kelly
Feb 23, 2004
Sam McCall
Feb 23, 2004
Matthew
February 23, 2004
One feature of D I haven't completely adjusted to is the need to explicitly specify each parameter of template methods.  Would it be too complicated to allow template parameter discovery somewhat similar to how it works in C++?

template foo( Ty ) {
    int foo( Ty val ) {
        return 1;
    }
}

int main() {
    int i = foo!(int)( 1 ); // A: current
    int j = foo!( 'c' ); // B: optional?
}

I'd like to be able to do something like in B.  The obvious catch is that more complex templates involving classes and the like could make such discovery difficult to impossible.  Comments?


Sean

February 23, 2004
Sean Kelly wrote:
> template foo( Ty ) {
>     int foo( Ty val ) {
>         return 1;
>     }
> }
> 
> int main() {
>     int i = foo!(int)( 1 ); // A: current
>     int j = foo!( 'c' ); // B: optional?
> }
Maybe foo('c') would even be easier to parse. (Having a template foo and a function foo is a symbol conflict anyways).

> I'd like to be able to do something like in B.  The obvious catch is that more complex templates involving classes and the like could make such discovery difficult to impossible.  Comments?
I'd be happy with limited discovery, as I posted about earlier (every type parameter must be the type of at least one parameter, no non-trivial overloading), in every other case you'd have to specify manually. This isn't ideal but it's so much better than what we've got now, and seems to be relatively simple to implement.
Sam
February 23, 2004
> I'd be happy with limited discovery, as I posted about earlier (every type parameter must be the type of at least one parameter, no non-trivial overloading)

That sounds good to me, though I really don't know what the fuss is about on having to specify type .  Sure its nice ( type deduction ) but are you really all that lazy ? :P

C


On Mon, 23 Feb 2004 13:53:52 +1300, Sam McCall <tunah.d@tunah.net> wrote:

> Sean Kelly wrote:
>> template foo( Ty ) {
>>     int foo( Ty val ) {
>>         return 1;
>>     }
>> }
>>
>> int main() {
>>     int i = foo!(int)( 1 ); // A: current
>>     int j = foo!( 'c' ); // B: optional?
>> }
> Maybe foo('c') would even be easier to parse. (Having a template foo and a function foo is a symbol conflict anyways).
>
>> I'd like to be able to do something like in B.  The obvious catch is that more complex templates involving classes and the like could make such discovery difficult to impossible.  Comments?
> I'd be happy with limited discovery, as I posted about earlier (every type parameter must be the type of at least one parameter, no non-trivial overloading), in every other case you'd have to specify manually. This isn't ideal but it's so much better than what we've got now, and seems to be relatively simple to implement.
> Sam



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
February 23, 2004
C wrote:
>
>> I'd be happy with limited discovery, as I posted about earlier (every type parameter must be the type of at least one parameter, no non-trivial overloading)
> 
> That sounds good to me, though I really don't know what the fuss is about on having to specify type .  Sure its nice ( type deduction ) but are you really all that lazy ? :P

Perhaps it's a hold-over from C++, but I like having a unified calling convention for functions.  Also, there are times when template parameters might be non-obvious to the caller, though I'll grant that in D this could be solved via nested templates.  But I'm undecided about whether I'd like this in D, as the template declaration method is quite different from that in C++.

I just thought of a way around explicit type specification.  Referring to my original example, this is a working substitute for B:

char c = 'c';
int j = foo!( typeof( c ) )( c );

This is ovbiously more verbose, but it does help avoid maintenance problems regarding explicitly specified types.  I'll have to think some more about whether type discovery might allow for something that is difficult to accomplish without it.  For some reason I thought I'd come up with an example but if I did it currently escapes me.


Sean

February 23, 2004
>> That sounds good to me, though I really don't know what the fuss is about on having to specify type .  Sure its nice ( type deduction ) but are you really all that lazy ? :P
Collection!(Object) foo;
Collection!(String) bar;

foo.addAll!(MyCollection!(String))(bar);
versus
foo.addAll(bar);

Personally find the first one moderately unwritable and perfectly unreadable ;)

> char c = 'c';
> int j = foo!( typeof( c ) )( c );
> 
> This is ovbiously more verbose, but it does help avoid maintenance problems regarding explicitly specified types.
Yes, but it's ugly, you have to remember which variable corresponds to which type argument, which the compiler already knows about. If something mechanical like this can do the job, why should you actually have to type it?
Sam
February 23, 2004
It's not a question of sloth. It's about whether, and how easily, one can write generic code.

> I'd be happy with limited discovery, as I posted about earlier (every type parameter must be the type of at least one parameter, no non-trivial overloading)

That sounds good to me, though I really don't know what the fuss is about on having to specify type .  Sure its nice ( type deduction ) but are you really all that lazy ? :P

C


On Mon, 23 Feb 2004 13:53:52 +1300, Sam McCall <tunah.d@tunah.net> wrote:

> Sean Kelly wrote:
>> template foo( Ty ) {
>>     int foo( Ty val ) {
>>         return 1;
>>     }
>> }
>>
>> int main() {
>>     int i = foo!(int)( 1 ); // A: current
>>     int j = foo!( 'c' ); // B: optional?
>> }
> Maybe foo('c') would even be easier to parse. (Having a template foo and
> a function foo is a symbol conflict anyways).
>
>> I'd like to be able to do something like in B.  The obvious catch is that more complex templates involving classes and the like could make such discovery difficult to impossible.  Comments?
> I'd be happy with limited discovery, as I posted about earlier (every
> type parameter must be the type of at least one parameter, no
> non-trivial overloading), in every other case you'd have to specify
> manually. This isn't ideal but it's so much better than what we've got
> now, and seems to be relatively simple to implement.
> Sam



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/


February 23, 2004
"Sam McCall" <tunah.d@tunah.net> wrote in message news:c1bqrm$2fvv$1@digitaldaemon.com...
> >> That sounds good to me, though I really don't know what the fuss is about on having to specify type .  Sure its nice ( type deduction ) but are you really all that lazy ? :P
> Collection!(Object) foo;
> Collection!(String) bar;
>
> foo.addAll!(MyCollection!(String))(bar);
> versus
> foo.addAll(bar);
>
> Personally find the first one moderately unwritable and perfectly unreadable ;)
>

My first try to investigate this was to use:
  class Collection(T:Object) {
    void addAll(Collection!(Object) x) {}
  }
and then hope that Collection!(String) could be implicitly cast to
Collection!(Object) but it failed to compile the addAll declaration.
This looks to me like a bug in class template syntax.
So my second attempt was
  interface Collection {
    void addAll(Collection x);
  }
  class LinkedList(T): Collection {
    void addAll(Collection x){}
  }
and this worked fine when called with
  Collection foo = new LinkedList!(String);
  Collection bar = new LinkedList!(String);
  foo.addAll(bar);
So my first guess is that templates might not be the right way to do what
you want to do. That doesn't mean there isn't a problem with templates
but I'm not sure this is a great example.

> > char c = 'c';
> > int j = foo!( typeof( c ) )( c );
> >
> > This is ovbiously more verbose, but it does help avoid maintenance problems regarding explicitly specified types.
> Yes, but it's ugly, you have to remember which variable corresponds to
> which type argument, which the compiler already knows about. If
> something mechanical like this can do the job, why should you actually
> have to type it?
> Sam


February 23, 2004
Ben Hinkle wrote:
>
> So my first guess is that templates might not be the right way to do what
> you want to do. That doesn't mean there isn't a problem with templates
> but I'm not sure this is a great example.

I think it's more an example of how the syntax can get complicated rather than being an example of something you'd probably want to do very often.


Sean

February 23, 2004
"Sean Kelly" <sean@ffwd.cx> wrote in message news:c1derl$2bif$1@digitaldaemon.com...
> Ben Hinkle wrote:
> >
> > So my first guess is that templates might not be the right way to do
what
> > you want to do. That doesn't mean there isn't a problem with templates but I'm not sure this is a great example.
>
> I think it's more an example of how the syntax can get complicated rather than being an example of something you'd probably want to do very often.

Over lunch I realized the reason for not using a straightforward interface
is that it loses the contained type T. So I think his example is actually a
good one for any generic, efficient add method from one container
type to another. If you start making assumptions about the source
or destination types then my posted code would be ok - but it wouldn't
work well for the general case.

>
>
> Sean
>


February 23, 2004
"Sean Kelly" <sean@ffwd.cx> wrote in message news:c1derl$2bif$1@digitaldaemon.com...
> Ben Hinkle wrote:
> >
> > So my first guess is that templates might not be the right way to do
what
> > you want to do. That doesn't mean there isn't a problem with templates but I'm not sure this is a great example.
>
> I think it's more an example of how the syntax can get complicated rather than being an example of something you'd probably want to do very often.
>
>
> Sean
>

Take Two. Collections are just waay to much fun to putter around with :-)
Here's an example that results in calls that look like
  TmixCollectionTypes!(Object,String).addAll(foo,bar);
when you want to copy from one contained type to another.
More details:

interface Collection(T) { // a cheesy Collection
  T getItem();
  void addItem(T x);
}

template TmixCollectionTypes(S,T) {
  void addAll(Collection!(S) x, Collection!(T) y) {
    x.addItem(y.getItem()); // you get the idea...
  }
}

class LinkedList(T): Collection!(T) { // a cheesy list
  T getItem() { return item; }
  void addItem(T x) { item=x; }
  T item;
}

class String {}

int main(char[][] argv)
{
Collection!(Object) foo = new LinkedList!(Object);
Collection!(String) bar = new LinkedList!(String);
TmixCollectionTypes!(Object,String).addAll(foo,bar);
return 0;
}


« First   ‹ Prev
1 2