December 20, 2009
Hello Yigal,

> On 18/12/2009 22:09, BCS wrote:
> 
>> Hello Yigal,
>> 
>>> On 18/12/2009 02:49, Tim Matthews wrote:
>>> 
>>>> In a reddit reply: "The concept of templates in D is exactly the
>>>> same as in C++. There are minor technical differences, syntactic
>>>> differences, but it is essentially the same thing. I think that's
>>>> understandable since Digital Mars had a C++ compiler."
>>>> 
>>>> http://www.reddit.com/r/programming/comments/af511/ada_programming_
>>>> ge nerics/c0hcb04?context=3
>>>> 
>>>> I have never touched ada but I doubt it is really has that much
>>>> that can't be done in D. I thought most (if not all) the problems
>>>> with C++ were absent in D as this summary of the most common ones
>>>> points out
>>>> http://www.digitalmars.com/d/2.0/templates-revisited.html.
>>>> 
>>>> Your thoughts?
>>>> 
>>> I don't know Ada but I do agree with that reddit reply about c++ and
>>> D
>>> templates. D provides a better implementation of the exact same
>>> design,
>>> so it does fix many minor issues (implementation bugs). An example
>>> of
>>> this is the foo<bar<Class>> construct that doesn't work because of
>>> the
>>> ">>" operator.
>>> However, using the same design obviously doesn't solve any of the
>>> deeper
>>> design problems and this design has many of those. An example of
>>> that
>>> is
>>> that templates are compiled as part of the client code. This forces
>>> a
>>> library writer to provide the source code (which might not be
>>> acceptable
>>> in commercial circumstances) but even more frustrating is the fact
>>> that
>>> template compilation bugs will also happen at the client.
>>> There's a whole range of designs for this and related issues and IMO
>>> the C++ design is by far the worst of them all. not to mention the
>>> fact that it isn't an orthogonal design (like many other "features"
>>> in
>>> c++). I'd much prefer a true generics design to be separated from
>>> compile-time execution of code with e.g. CTFE or AST macros, or
>>> other
>>> designs.
>> If D were to switch to true generics, I for one would immediately
>> start looking for ways to force it all back into compile time. I
>> think that this would amount to massive use of CTFE and string
>> mixins.
>> 
>> One of the things I *like* about template is that it does everything
>> at compile time.
>> 
>> That said, I wouldn't be bothered by optional generics or some kind
>> of compiled template where a lib writer can ship a binary object (JVM
>> code?) that does the template instantiation at compile time without
>> the text source. (The first I'd rarely use and the second would just
>> be an obfuscation tool, but then from that standpoint all compilers
>> are)
>> 
> you are confused - the term "generics" refers to writing code that is
> parametrized by type(s).

I've never looked into them in detail but I think I'm taking about the same idea as you are.

To be clear, the aspect of generics that I dislike is the part that has them use the exact same code for all cases. The aspect of true templates that I like is that the template gets specialized for the type very early in the compile process. That name lookup is done after the type is know. That code gen happens after all (or at least most) of the things that make it a template are gone. That the resulting code can take full advantage of all the details of the actual type the template is instantiated on rather than being limited to merely the things they are true of everything it could be used with. And that ALL of that is over and done (including all possible template related errors) with befor runtime time.

That is the aspect of generics vs template that I care about. The actual implementation doesn't bother me a bit. Heck, if you can get all of that in something that gives you the bits of generics you want, I'd be happy

> it has nothing to do with JVM or the specific
> Java implementation of this idea. Java's implementation is irrelevant
> to our discussion since it's broken by design in order to accommodate
> backward compatibility.

I actually have no clue how the Java generics work and for what I'm proposing, using a JVM would be purely an implementation detail. In fact it is very likely that Java generics would NOT be used anywhere in the system


What I was proposing is that when someone wants to ship a template lib without the source, they would compile it into a JVM file that the compiler would load. This file WOULD NOT be put right into the final binary but rather be loaded by the compiler and used by the compiler to instantiate a template. Whatever functions from the file that the compiler calls would take the place of the code in the compiler that normally instantiates a template; that is, function would generate an AST or IL blob that would get passed to the backend.

Note, using the JVM for this is an implementation detail. You could just as easily use Linux shared objects, DLLs, DDl, .NET assemblies, JavaScript, Python, Lua, perl, LISP, or BF. The point is that rather than ship template source, you ship a program that, when run, does the instantiation of the template. What form this program is shipped in as a minor detail as far as I'm concerned.

> generics != Java generics !!!
> 
> Generics are also orthogonal to meta-programming.
> 

Yes they are orthogonal. However the same is less true with regards to the aspects of templates that I want. For example, without some bits of meta-programing, you can't do most of what I want and with a really good meta-programing system, you wouldn't need any template specific features at all except as sugar. 

> please also see my reply to dsimcha.
> 


December 20, 2009
Hello bearophile,

> [...] you will end in D3 with templates + macros +
> language conventions that tell to not use templates when macros can be
> used.

There is nothing new in that. Even when you have other tools, you can still make every problem look like a nail, and it's an even worse idea than when you only have a hammer.


December 20, 2009
Hello Yigal,

> On 18/12/2009 17:34, dsimcha wrote:
> 
>> I think variadics, static if and alias parameters qualify more as a
>> "better design" than fixing "minor issues".
>> 
> actually they qualify as - "even worse design". duplicating the syntax
> like that is butt ugly.
> 

I for one think that it's a better design than C++ has. (Given that 99% of what they do, C++ was never designed to do at all, you'd be hard pressed to come up with a worse design without trying to.)

If you can come up with an even better design for compile time stuff, I'd be interested.

>the conflation of user-code and library code.

Could you elaborate on this?

> 
>>> but even more frustrating is the fact that
>>> template compilation bugs will also happen at the client.

Jumping back a bit; which client? The one with the compiler or the end user?

If the first; removing this puts major limits on what can be done because you can't do anything unless you be sure it will work with the open set of types that could be instanceiated, including ones you don't know about yet. I know some system like c# requiter you to define what you will do to a type at the top and then enforce that. IMHO this is a non-solution. Without be to silly I think I could come up with a library that would requiter a solution to the halting problem in order to check that the template code can't generate and error with the given constants and that a given type fits the constraints, both without actuality instanceate the template for the type.

If the second; nether D nor C++ have to worry about that.

> .Net generics for example work by creating an instantiation for each
> value type (same as c++ templates) and one instantiation for all
> reference types since at the binary level all reference types are
> simply
> addresses.

I don't know how it does it but there has to be more to it in C# because they allow you to do thing to the objects that Object doesn't support. For that to happen, the objects have to be wrapped or tagged or something so that the generics code can make "foo.MyFunction()" work for different types. If I has to guess, I'd guess it's done via a vtable either as a "magic" interface or as a fat pointer.

Oh, and if the above is garbage because C# can't access totally independent methods from a generic, then right there is my next argument against generics.


December 20, 2009
Yigal Chripun wrote:

> On 19/12/2009 01:31, Lutger wrote:
>> Yigal Chripun wrote:
>>
>>> On 18/12/2009 02:49, Tim Matthews wrote:
>>>> In a reddit reply: "The concept of templates in D is exactly the same as in C++. There are minor technical differences, syntactic differences, but it is essentially the same thing. I think that's understandable since Digital Mars had a C++ compiler."
>>>>
>>>>
>> 
http://www.reddit.com/r/programming/comments/af511/ada_programming_generics/c0hcb04?context=3
>>>>
>>>>
>>>> I have never touched ada but I doubt it is really has that much that can't be done in D. I thought most (if not all) the problems with C++ were absent in D as this summary of the most common ones points out http://www.digitalmars.com/d/2.0/templates-revisited.html.
>>>>
>>>> Your thoughts?
>>>
>>> I don't know Ada but I do agree with that reddit reply about c++ and D
>>> templates. D provides a better implementation of the exact same design,
>>> so it does fix many minor issues (implementation bugs). An example of
>>> this is the foo<bar<Class>>  construct that doesn't work because of the
>>> ">>" operator.
>>> However, using the same design obviously doesn't solve any of the deeper
>>> design problems and this design has many of those. An example of that is
>>> that templates are compiled as part of the client code. This forces a
>>> library writer to provide the source code (which might not be acceptable
>>> in commercial circumstances) but even more frustrating is the fact that
>>> template compilation bugs will also happen at the client.
>>
>> Well yes, but the .NET design restrict the generic type to a specific named interface in order to do type checking. You may find this a good design choice, but others find it far more frustrating because this is exactly what allows for a bit more flexibility in a statically typed world. So it is not exactly a problem but rather a trade-off imho.
> 
> The .Net implementation isn't perfect of course and has a few issues that should be resolved, one of these is the problem with using operators. requiring interfaces by itself isn't the problem though. The only drawback in this case is verbosity which isn't really a big deal for this.

The drawback is not verbosity but lack of structural typing. Suppose some library has code that can be parametrized by IFoo and I have another library with a type that implements IBar, which satisfies IFoo but not explicitly so. Then what? Unless I have totally misunderstood .NET generics, I have to create some proxy object for IBar that implements IFoo just to satisfy the strong type checking of .NET generics. You could make the argument that this 'inconvenience' is a good thing, but I do think it is a bit more of a drawback than just increased verbosity.
December 20, 2009
"Lutger" <lutger.blijdestijn@gmail.com> wrote in message news:hgl440$tlo$1@digitalmars.com...
> Yigal Chripun wrote:
>>
>> The .Net implementation isn't perfect of course and has a few issues that should be resolved, one of these is the problem with using operators. requiring interfaces by itself isn't the problem though. The only drawback in this case is verbosity which isn't really a big deal for this.
>
> The drawback is not verbosity but lack of structural typing. Suppose some
> library has code that can be parametrized by IFoo and I have another
> library
> with a type that implements IBar, which satisfies IFoo but not explicitly
> so. Then what? Unless I have totally misunderstood .NET generics, I have
> to
> create some proxy object for IBar that implements IFoo just to satisfy the
> strong type checking of .NET generics. You could make the argument that
> this
> 'inconvenience' is a good thing, but I do think it is a bit more of a
> drawback than just increased verbosity.

It sounds like you're talking about duck typing?


December 20, 2009
Nick Sabalausky wrote:

> "Lutger" <lutger.blijdestijn@gmail.com> wrote in message news:hgl440$tlo$1@digitalmars.com...
>> Yigal Chripun wrote:
>>>
>>> The .Net implementation isn't perfect of course and has a few issues that should be resolved, one of these is the problem with using operators. requiring interfaces by itself isn't the problem though. The only drawback in this case is verbosity which isn't really a big deal for this.
>>
>> The drawback is not verbosity but lack of structural typing. Suppose some
>> library has code that can be parametrized by IFoo and I have another
>> library
>> with a type that implements IBar, which satisfies IFoo but not explicitly
>> so. Then what? Unless I have totally misunderstood .NET generics, I have
>> to
>> create some proxy object for IBar that implements IFoo just to satisfy
>> the strong type checking of .NET generics. You could make the argument
>> that this
>> 'inconvenience' is a good thing, but I do think it is a bit more of a
>> drawback than just increased verbosity.
> 
> It sounds like you're talking about duck typing?
> 
> 

I'm not sure, I don't think so. From what I understand, duck typing is supposed to be dynamic, while structural and nominative typing are part of a static type system. I meant the non-nominative kind of typing, whatever it is.

fwiw, this is what wikipedia says:

"Duck typing is similar to but distinct from structural typing. Structural typing is a static typing system that determines type compatibility and equivalence by a type's structure, whereas duck typing is dynamic and determines type compatibility by only that part of a type's structure that is accessed during run time."

http://en.wikipedia.org/wiki/Duck_typing#Structural_type_systems
December 20, 2009
Sun, 20 Dec 2009 18:53:56 +0100, Lutger wrote:

> I'm not sure, I don't think so. From what I understand, duck typing is supposed to be dynamic, while structural and nominative typing are part of a static type system. I meant the non-nominative kind of typing, whatever it is.
> 
> fwiw, this is what wikipedia says:
> 
> "Duck typing is similar to but distinct from structural typing. Structural typing is a static typing system that determines type compatibility and equivalence by a type's structure, whereas duck typing is dynamic and determines type compatibility by only that part of a type's structure that is accessed during run time."
> 
> http://en.wikipedia.org/wiki/Duck_typing#Structural_type_systems

You don't need a named interfaces in structural type system. Only the members of the data type have any meaning.
December 20, 2009
Hello Lutger,

> Yigal Chripun wrote:
> 
>> The .Net implementation isn't perfect of course and has a few issues
>> that should be resolved, one of these is the problem with using
>> operators. requiring interfaces by itself isn't the problem though.
>> The only drawback in this case is verbosity which isn't really a big
>> deal for this.
>> 
> The drawback is not verbosity but lack of structural typing. Suppose
> some  library has code that can be parametrized by IFoo and I have
> another library with a type that implements IBar, which satisfies IFoo
> but not explicitly so.

Fully compile-time duck typeing. Thats the one of the things I must demand be kept.


December 21, 2009
Lutger Wrote:

> Yigal Chripun wrote:
> 
> > On 19/12/2009 01:31, Lutger wrote:
> >> Yigal Chripun wrote:
> >>
> >>> On 18/12/2009 02:49, Tim Matthews wrote:
> >>>> In a reddit reply: "The concept of templates in D is exactly the same as in C++. There are minor technical differences, syntactic differences, but it is essentially the same thing. I think that's understandable since Digital Mars had a C++ compiler."
> >>>>
> >>>>
> >> 
> http://www.reddit.com/r/programming/comments/af511/ada_programming_generics/c0hcb04?context=3
> >>>>
> >>>>
> >>>> I have never touched ada but I doubt it is really has that much that can't be done in D. I thought most (if not all) the problems with C++ were absent in D as this summary of the most common ones points out http://www.digitalmars.com/d/2.0/templates-revisited.html.
> >>>>
> >>>> Your thoughts?
> >>>
> >>> I don't know Ada but I do agree with that reddit reply about c++ and D
> >>> templates. D provides a better implementation of the exact same design,
> >>> so it does fix many minor issues (implementation bugs). An example of
> >>> this is the foo<bar<Class>>  construct that doesn't work because of the
> >>> ">>" operator.
> >>> However, using the same design obviously doesn't solve any of the deeper
> >>> design problems and this design has many of those. An example of that is
> >>> that templates are compiled as part of the client code. This forces a
> >>> library writer to provide the source code (which might not be acceptable
> >>> in commercial circumstances) but even more frustrating is the fact that
> >>> template compilation bugs will also happen at the client.
> >>
> >> Well yes, but the .NET design restrict the generic type to a specific named interface in order to do type checking. You may find this a good design choice, but others find it far more frustrating because this is exactly what allows for a bit more flexibility in a statically typed world. So it is not exactly a problem but rather a trade-off imho.
> > 
> > The .Net implementation isn't perfect of course and has a few issues that should be resolved, one of these is the problem with using operators. requiring interfaces by itself isn't the problem though. The only drawback in this case is verbosity which isn't really a big deal for this.
> 
> The drawback is not verbosity but lack of structural typing. Suppose some library has code that can be parametrized by IFoo and I have another library with a type that implements IBar, which satisfies IFoo but not explicitly so. Then what? Unless I have totally misunderstood .NET generics, I have to create some proxy object for IBar that implements IFoo just to satisfy the strong type checking of .NET generics. You could make the argument that this 'inconvenience' is a good thing, but I do think it is a bit more of a drawback than just increased verbosity.

The way I see it we have three options:

assume we have these definitions:
interface I {...}
class Foo : I {...}
class Bar {...} // structurally compatible to I

template tp (I) {...}

1) .Net nominative typing:
tp!(Foo) // OK
tp!(Bar) //not OK

2) structural typing (similllar to Go?)
tp!(Foo) // OK
tp!(Bar) // also OK

3) C++ style templates where the compatibility check is against the *body* of the template.

of the three above I think option 3 is the worst design and option 2 is my favorite design. I think that in reality you'll almost always want to define such an interface and I really can't think of any useful use cases for an unrestricted template parameter as in C++.

If you think of templates as functions the compiler executes, the difference between the last two options is that option 2 is staticly typed vs. option 3 which is dynamicaly typed. We all use D because we like static typing and there's no reasone to not extend this to compile-time as well.
December 21, 2009
Lutger wrote:
> Nick Sabalausky wrote:
> 
>> "Lutger" <lutger.blijdestijn@gmail.com> wrote in message
>> news:hgl440$tlo$1@digitalmars.com...
>>> Yigal Chripun wrote:
>>>> The .Net implementation isn't perfect of course and has a few issues
>>>> that should be resolved, one of these is the problem with using
>>>> operators. requiring interfaces by itself isn't the problem though. The
>>>> only drawback in this case is verbosity which isn't really a big deal
>>>> for this.
>>> The drawback is not verbosity but lack of structural typing. Suppose some
>>> library has code that can be parametrized by IFoo and I have another
>>> library
>>> with a type that implements IBar, which satisfies IFoo but not explicitly
>>> so. Then what? Unless I have totally misunderstood .NET generics, I have
>>> to
>>> create some proxy object for IBar that implements IFoo just to satisfy
>>> the strong type checking of .NET generics. You could make the argument
>>> that this
>>> 'inconvenience' is a good thing, but I do think it is a bit more of a
>>> drawback than just increased verbosity.
>> It sounds like you're talking about duck typing?
>>
>>
> 
> I'm not sure, I don't think so. From what I understand, duck typing is supposed to be dynamic, while structural and nominative typing are part of a  static type system. I meant the non-nominative kind of typing, whatever it is.
> 
> fwiw, this is what wikipedia says:
> 
> "Duck typing is similar to but distinct from structural typing. Structural typing is a static typing system that determines type compatibility and equivalence by a type's structure, whereas duck typing is dynamic and determines type compatibility by only that part of a type's structure that is accessed during run time." 
> 
> http://en.wikipedia.org/wiki/Duck_typing#Structural_type_systems

That Wikipedia page doesn't any make sense to me. Is that *really* what duck typing is? If so, it's a complete misnomer. Because it's totally different to "if it looks like a duck, quacks like a duck, etc".
If it looks like a duck now, but *didn't* look like a duck three minutes ago, you can be pretty sure it's NOT a duck!

Whereas what it calls "structural typing" follows the duck rule perfectly. There is no reasoning on that page as to why duck typing is restricted to dynamic languages.

There's far too much ideology in that page, it ought to get flagged as inappropriate. Eg this line near the top:

"Users of statically typed languages new to dynamically typed languages are usually tempted to .."