Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
July 29, 2004 Templates and Generic Programming | ||||
---|---|---|---|---|
| ||||
#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. |
July 29, 2004 Re: Templates and Generic Programming | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sha Chancellor | "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? |
July 30, 2004 Re: Templates and Generic Programming | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | 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? |
July 30, 2004 Re: Templates and Generic Programming | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | 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 |
July 30, 2004 Re: Templates and Generic Programming | ||||
---|---|---|---|---|
| ||||
Posted in reply to James Widman | "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. |
July 30, 2004 Re: Templates and Generic Programming | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | "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 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. 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. |
July 30, 2004 Re: Templates and Generic Programming | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | 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 > 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. > > 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 |
July 30, 2004 Re: Templates and Generic Programming | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | "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 > > 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. > > > > 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. |
Copyright © 1999-2021 by the D Language Foundation