digitalmars.D - Templates and Generic Programming
- Sha Chancellor <schancel pacific.net> Jul 29 2004
- "Matthew" <admin stlsoft.dot.dot.dot.dot.org> Jul 29 2004
- James Widman <james jwidman.com> Jul 29 2004
- "Matthew" <admin stlsoft.dot.dot.dot.dot.org> Jul 29 2004
- Derek Parnell <derek psych.ward> Jul 29 2004
- "Matthew" <admin stlsoft.dot.dot.dot.dot.org> Jul 29 2004
- Derek Parnell <derek psych.ward> Jul 29 2004
- "Matthew" <admin stlsoft.dot.dot.dot.dot.org> Jul 29 2004
#import std.c.stdio;
#class Foo(T) {
# alias T baseType;
# /* ... */
#}
#int main( char[][] args )
#{
# Foo!(int) f = new Foo!(int); //Redundant
#
# f.baseType s = 10; //Why Doesn't this work?!
# //This allows you to declare variables that are related to f
# // without somehow already knowing F's template types.
#
# Foo!(int).baseType t = 10; //Why does only this work???
# // This works fine if you know F is has a template type of int.
# // Unfortunately I don't know of a way to find s's
# // template types at runtime if you don't already know it.
#
#
#
# // The compiler it seems should know what T is,
# // why can't it make the previous declaration work?
#
# return 0;
#}
For generic programming, as Matthew mentioned earlier. There should be
a way to deduce base types. There's no good generic way to do this
besides aliases. What should we do:
Foo!(int,char,float) f = new Foo!(int,char,float) (BTW, wtf do we need
to specify this stuff twice? Should be implicit if you leave it off...)
template_type( f, 0 ) = int?
template_type( f, 1 ) = char?
template_type( f, 2 ) = float?
This seems klunky. Rather specifying aliases in the classes for the
ones you'd need seems like a better solution... If only it worked.
Jul 29 2004
"Sha Chancellor" <schancel pacific.net> wrote in message news:schancel-0DEA5D.10244529072004 digitalmars.com...#import std.c.stdio; #class Foo(T) { # alias T baseType; # /* ... */ #} #int main( char[][] args ) #{ # Foo!(int) f = new Foo!(int); //Redundant # # f.baseType s = 10; //Why Doesn't this work?! # //This allows you to declare variables that are related to f # // without somehow already knowing F's template types. # # Foo!(int).baseType t = 10; //Why does only this work??? # // This works fine if you know F is has a template type of int. # // Unfortunately I don't know of a way to find s's # // template types at runtime if you don't already know it. # # # # // The compiler it seems should know what T is, # // why can't it make the previous declaration work? # # return 0; #} For generic programming, as Matthew mentioned earlier. There should be a way to deduce base types. There's no good generic way to do this besides aliases. What should we do: Foo!(int,char,float) f = new Foo!(int,char,float) (BTW, wtf do we need to specify this stuff twice? Should be implicit if you leave it off...) template_type( f, 0 ) = int? template_type( f, 1 ) = char? template_type( f, 2 ) = float? This seems klunky. Rather specifying aliases in the classes for the ones you'd need seems like a better solution... If only it worked.
As we've begged for for a long time, we need an autotype (or similar keyword), e.g. autotype f = new Foo!(int,char,float); rather than Foo!(int,char,float) f = new Foo!(int,char,float) I can't see that this would be terribly hard to do, since the compiler already knows the type returned, so this could be a moderate step with minimum effort. Much easier than implicit instantiation, eh Walter?
Jul 29 2004
In article <cec1ml$1tlt$2 digitaldaemon.com>, "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote:As we've begged for for a long time, we need an autotype (or similar keyword), e.g. autotype f = new Foo!(int,char,float); rather than Foo!(int,char,float) f = new Foo!(int,char,float)
How about: Foo!(int,char,float) f = new(); Foo!(int,char,float)[] f = new[5]; ...with the assumption that if 'new' is followed immediately by '(', '[', or ';', then it's just as if we saw: Foo!(int,char,float) f = new typeof(f)(/* args to this() */); Would that throw a big monkey wrench in the parser?
Jul 29 2004
"James Widman" <james jwidman.com> wrote in message news:james-B2BBCF.20133029072004 digitalmars.com...In article <cec1ml$1tlt$2 digitaldaemon.com>, "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote:As we've begged for for a long time, we need an autotype (or similar keyword), e.g. autotype f = new Foo!(int,char,float); rather than Foo!(int,char,float) f = new Foo!(int,char,float)
How about: Foo!(int,char,float) f = new(); Foo!(int,char,float)[] f = new[5]; ...with the assumption that if 'new' is followed immediately by '(', '[', or ';', then it's just as if we saw: Foo!(int,char,float) f = new typeof(f)(/* args to this() */); Would that throw a big monkey wrench in the parser?
It'd throw a huge wrench in DTL. You'd be writing very, very, very long types.
Jul 29 2004
On Fri, 30 Jul 2004 09:29:47 +1000, Matthew wrote:"Sha Chancellor" <schancel pacific.net> wrote in message news:schancel-0DEA5D.10244529072004 digitalmars.com...#import std.c.stdio; #class Foo(T) { # alias T baseType; # /* ... */ #} #int main( char[][] args ) #{ # Foo!(int) f = new Foo!(int); //Redundant # # f.baseType s = 10; //Why Doesn't this work?! # //This allows you to declare variables that are related to f # // without somehow already knowing F's template types. # # Foo!(int).baseType t = 10; //Why does only this work??? # // This works fine if you know F is has a template type of int. # // Unfortunately I don't know of a way to find s's # // template types at runtime if you don't already know it. # # # # // The compiler it seems should know what T is, # // why can't it make the previous declaration work? # # return 0; #} For generic programming, as Matthew mentioned earlier. There should be a way to deduce base types. There's no good generic way to do this besides aliases. What should we do: Foo!(int,char,float) f = new Foo!(int,char,float) (BTW, wtf do we need to specify this stuff twice? Should be implicit if you leave it off...) template_type( f, 0 ) = int? template_type( f, 1 ) = char? template_type( f, 2 ) = float? This seems klunky. Rather specifying aliases in the classes for the ones you'd need seems like a better solution... If only it worked.
As we've begged for for a long time, we need an autotype (or similar keyword), e.g. autotype f = new Foo!(int,char,float); rather than Foo!(int,char,float) f = new Foo!(int,char,float) I can't see that this would be terribly hard to do, since the compiler already knows the type returned, so this could be a moderate step with minimum effort. Much easier than implicit instantiation, eh Walter?
How about something like ... new Foo!(int,char,float) f; as a complete statement. class Bar{} new Bar b; new int i; seems easy to understand and write. The 'new' creates a newly initialized instance of the 'type'. Classes are created on the heap and everything else on the stack. Thus it would be redundant for intrinsic types and structs but shouldn't be a issue if used. -- Derek Melbourne, Australia 30/Jul/04 10:34:39 AM
Jul 29 2004
"Derek Parnell" <derek psych.ward> wrote in message news:cec5bd$1v91$1 digitaldaemon.com...On Fri, 30 Jul 2004 09:29:47 +1000, Matthew wrote:"Sha Chancellor" <schancel pacific.net> wrote in message news:schancel-0DEA5D.10244529072004 digitalmars.com...#import std.c.stdio; #class Foo(T) { # alias T baseType; # /* ... */ #} #int main( char[][] args ) #{ # Foo!(int) f = new Foo!(int); //Redundant # # f.baseType s = 10; //Why Doesn't this work?! # //This allows you to declare variables that are related to f # // without somehow already knowing F's template types. # # Foo!(int).baseType t = 10; //Why does only this work??? # // This works fine if you know F is has a template type of int. # // Unfortunately I don't know of a way to find s's # // template types at runtime if you don't already know it. # # # # // The compiler it seems should know what T is, # // why can't it make the previous declaration work? # # return 0; #} For generic programming, as Matthew mentioned earlier. There should be a way to deduce base types. There's no good generic way to do this besides aliases. What should we do: Foo!(int,char,float) f = new Foo!(int,char,float) (BTW, wtf do we need to specify this stuff twice? Should be implicit if you leave it off...) template_type( f, 0 ) = int? template_type( f, 1 ) = char? template_type( f, 2 ) = float? This seems klunky. Rather specifying aliases in the classes for the ones you'd need seems like a better solution... If only it worked.
As we've begged for for a long time, we need an autotype (or similar keyword), e.g. autotype f = new Foo!(int,char,float); rather than Foo!(int,char,float) f = new Foo!(int,char,float) I can't see that this would be terribly hard to do, since the compiler already knows the type returned, so this
a moderate step with minimum effort. Much easier than implicit instantiation, eh Walter?
How about something like ... new Foo!(int,char,float) f; as a complete statement. class Bar{} new Bar b; new int i; seems easy to understand and write. The 'new' creates a newly initialized instance of the 'type'. Classes are created on the heap and everything else on the stack. Thus it would be redundant for intrinsic types and structs but shouldn't be a issue if used.
But that's missing the point. The ideal is to not have to worry about the specific type of a function return, and simply to write your code in accordance to that type's expected operations. It's kind of a typeless programming, with compile-time type checking. (Cake & eating it, if you will.) A good example of this would be where one might apply a transformation operation to a selected element from a container, ie. template someFunc(X) { void someFunc(. . . { autotype x = cont.select(IsOdd).collect!(X).max(); If cont contains ints, but the X functor transforms to some other type, we can still manipulate the instance x of that "other type", without knowing its precise type. All we know is that it will fulfil the intended operations we subject it to, and because the compiler knows the return type from "cont.select(IsOdd).collect!(X).max();" it can ensure that it will.
Jul 29 2004
On Fri, 30 Jul 2004 12:02:14 +1000, Matthew wrote:"Derek Parnell" <derek psych.ward> wrote in message news:cec5bd$1v91$1 digitaldaemon.com...On Fri, 30 Jul 2004 09:29:47 +1000, Matthew wrote:"Sha Chancellor" <schancel pacific.net> wrote in message news:schancel-0DEA5D.10244529072004 digitalmars.com...#import std.c.stdio; #class Foo(T) { # alias T baseType; # /* ... */ #} #int main( char[][] args ) #{ # Foo!(int) f = new Foo!(int); //Redundant # # f.baseType s = 10; //Why Doesn't this work?! # //This allows you to declare variables that are related to f # // without somehow already knowing F's template types. # # Foo!(int).baseType t = 10; //Why does only this work??? # // This works fine if you know F is has a template type of int. # // Unfortunately I don't know of a way to find s's # // template types at runtime if you don't already know it. # # # # // The compiler it seems should know what T is, # // why can't it make the previous declaration work? # # return 0; #} For generic programming, as Matthew mentioned earlier. There should be a way to deduce base types. There's no good generic way to do this besides aliases. What should we do: Foo!(int,char,float) f = new Foo!(int,char,float) (BTW, wtf do we need to specify this stuff twice? Should be implicit if you leave it off...) template_type( f, 0 ) = int? template_type( f, 1 ) = char? template_type( f, 2 ) = float? This seems klunky. Rather specifying aliases in the classes for the ones you'd need seems like a better solution... If only it worked.
As we've begged for for a long time, we need an autotype (or similar keyword), e.g. autotype f = new Foo!(int,char,float); rather than Foo!(int,char,float) f = new Foo!(int,char,float) I can't see that this would be terribly hard to do, since the compiler already knows the type returned, so this
a moderate step with minimum effort. Much easier than implicit instantiation, eh Walter?
How about something like ... new Foo!(int,char,float) f; as a complete statement. class Bar{} new Bar b; new int i; seems easy to understand and write. The 'new' creates a newly initialized instance of the 'type'. Classes are created on the heap and everything else on the stack. Thus it would be redundant for intrinsic types and structs but shouldn't be a issue if used.
But that's missing the point.
That maybe true. However, I was replying to the point raised above, and I requote .. " As we've begged for for a long time, we need an autotype (or similar keyword), e.g. autotype f = new Foo!(int,char,float); rather than Foo!(int,char,float) f = new Foo!(int,char,float) " This seemed to be dealing with the declaration of variables and not function execution. My mistake.The ideal is to not have to worry about the specific type of a function return, and simply to write your code in accordance to that type's expected operations. It's kind of a typeless programming, with compile-time type checking. (Cake & eating it, if you will.)
So in general, are you saying ... The generic *syntax* form of variable declaration is <datatype> <identifier> ['=' <initialization>] ';' and if the <datatype> is "autotype" then the compiler will use the datatype of the <initialization> expression? This is a useful idea. I'm not saying otherwise. Yep, sounds okay to me. It could mean a serious rethink of how the current compiler is written, as it may now have to defer decisions until the <initialization> datatype is known (ie, the function might be forward-referenced). -- Derek Melbourne, Australia 30/Jul/04 12:05:20 PM
Jul 29 2004
"Derek Parnell" <derek psych.ward> wrote in message news:cecbjb$21ho$1 digitaldaemon.com...On Fri, 30 Jul 2004 12:02:14 +1000, Matthew wrote:"Derek Parnell" <derek psych.ward> wrote in message news:cec5bd$1v91$1 digitaldaemon.com...On Fri, 30 Jul 2004 09:29:47 +1000, Matthew wrote:"Sha Chancellor" <schancel pacific.net> wrote in message news:schancel-0DEA5D.10244529072004 digitalmars.com...#import std.c.stdio; #class Foo(T) { # alias T baseType; # /* ... */ #} #int main( char[][] args ) #{ # Foo!(int) f = new Foo!(int); //Redundant # # f.baseType s = 10; //Why Doesn't this work?! # //This allows you to declare variables that are related to f # // without somehow already knowing F's template types. # # Foo!(int).baseType t = 10; //Why does only this work??? # // This works fine if you know F is has a template type of int. # // Unfortunately I don't know of a way to find s's # // template types at runtime if you don't already know it. # # # # // The compiler it seems should know what T is, # // why can't it make the previous declaration work? # # return 0; #} For generic programming, as Matthew mentioned earlier. There should be a way to deduce base types. There's no good generic way to do this besides aliases. What should we do: Foo!(int,char,float) f = new Foo!(int,char,float) (BTW, wtf do we need to specify this stuff twice? Should be implicit if you leave it off...) template_type( f, 0 ) = int? template_type( f, 1 ) = char? template_type( f, 2 ) = float? This seems klunky. Rather specifying aliases in the classes for the ones you'd need seems like a better solution... If only it worked.
As we've begged for for a long time, we need an autotype (or similar keyword), e.g. autotype f = new Foo!(int,char,float); rather than Foo!(int,char,float) f = new Foo!(int,char,float) I can't see that this would be terribly hard to do, since the compiler already knows the type returned, so this
a moderate step with minimum effort. Much easier than implicit instantiation, eh Walter?
How about something like ... new Foo!(int,char,float) f; as a complete statement. class Bar{} new Bar b; new int i; seems easy to understand and write. The 'new' creates a newly initialized instance of the 'type'. Classes are created on the heap and everything else on the stack. Thus it would be redundant for intrinsic types and structs but shouldn't be a issue if used.
But that's missing the point.
That maybe true. However, I was replying to the point raised above, and I requote .. " As we've begged for for a long time, we need an autotype (or similar keyword), e.g. autotype f = new Foo!(int,char,float); rather than Foo!(int,char,float) f = new Foo!(int,char,float) " This seemed to be dealing with the declaration of variables and not function execution. My mistake.
No, it was mine for not being clear enough.The ideal is to not have to worry about the specific type of a function return, and simply to write your code in accordance to that type's expected operations. It's kind of a typeless programming, with compile-time type checking. (Cake & eating it, if you will.)
So in general, are you saying ... The generic *syntax* form of variable declaration is <datatype> <identifier> ['=' <initialization>] ';' and if the <datatype> is "autotype" then the compiler will use the datatype of the <initialization> expression? This is a useful idea. I'm not saying otherwise. Yep, sounds okay to me. It could mean a serious rethink of how the current compiler is written, as it may now have to defer decisions until the <initialization> datatype is known (ie, the function might be forward-referenced).
Not sure. I wouldn't think it'd be that serious, since the type of <initialisation> *is* already known at that time. Dunno, really. That's Walter's area.
Jul 29 2004









"Matthew" <admin stlsoft.dot.dot.dot.dot.org> 