December 21, 2009
Don, el 21 de diciembre a las 09:20 me escribiste:
> >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 .."

I think Wikipedia talks about what the meaning of the term is commonly used, maybe duck typing is not too accurate, but I think most people use the term for dynamically typed languages. I don't think people differentiate between what Wikipedia defines as duck typing and structural typing, though, I think people usually say duck typing to both.

Anyway, if you *really* think Wikipedia is wrong, you can fix it or at
least mention it in the discussion page[1], that's what Wikipedia is all
about :)
http://en.wikipedia.org/wiki/Talk:Duck_typing

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
... los cuales son susceptibles a una creciente variedad de ataques previsibles,
tales como desbordamiento del tampón, falsificación de parámetros, ...
	-- Stealth - ISS LLC - Seguridad de IT
December 21, 2009
Don Wrote:

> yigal chripun wrote:
> > Don Wrote:
> >>> 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++.
> >> You forgot option 4:
> >>
> >> 4) D2 constrained templates, where the condition is checked inside the template constraint.
> >>
> >> This is more powerful than option 2, because:
> >>
> >> (1) there are cases where you want MORE constraints than simply an
> >> interface; and (2) only a subset of constraints can be expressed as an
> >> interface.
> >> Also a minor point: (3) interfaces don't work for built-in types.
> >>
> >> Better still would be to make it impossible to compile a template which made use of a feature not provided through a constraint.
> >>
> > 
> > I wouldn't give that a sepoarate option number, IMO this is a variation on option2. regarding your notes:
> > when you can express the same concept in both ways, using an interface is esier to read & understand IMO. What about having a combination of the two designs? you define an interface and allow optionally defining additional constraints _on_the_interface_ instead of the template.
> > I think this complies with your points (1) and (2) and is better since you don't need to repeat the constraints at the call site (each template that uses that type needs to repeat the constraint).
> 
> I don't think interfaces are flexible enough for that.
> EG, how do you express that the type I must have a template function
> void baz!(X)(X x) ?
> There's more to a type, than just a list of the virtual functions which
> it supports.

I agree that interfaces don't support this ATM. That's why i suggested to add constraints to them.
e.g.
Interface I if isFoo!(I) {...}  // one possible syntax
other approaches could be :
1) add non-virtual functions to interfaces (Andrei once suggested this)
2) add more meta-data with annotations
etc..

> 
> > even if you factor out the checks into a separate "isFoo" template you still need to add to each template declaration "if isFoo!(T)" which really should be done by the compiler instead.
> > 
> > regarding point(3) - this is orthogonal IMO. Ideally I'd like to see this distinction between builtin type and user defined one removed. int should be treated in the same manner as a user defined struct.
> > 
> > I completely agree about not compiling templates that use features not defined by constraints. This is in fact the main point I was trying to make in this thread.
> 
> The problem is, I'm not sure that it's feasible in general. At least, it's not obvious how to do it.
> 
December 21, 2009
Don wrote:
> The problem is, I'm not sure that it's feasible in general. At least, it's not obvious how to do it.

C++0x Concepts tried to do it in a limited form, and it got so complicated nobody could figure out how it was supposed to work and it capsized and sank.

I don't think it's possible in the more general sense.
December 21, 2009
On 20/12/2009 03:11, BCS wrote:
> 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.
>
>

What you're talking about in the above is meta-programing. Doing meta-programing a-la c++ templates is IMO like trying to use square wheels, it is just wrong.

To answer your questions:
D already has better designed tools for this and they keep improving. Don is doing an excellent job in fixing CTFE.
I think D needs to go beyond just constant-folding (CTFE) and allow to run any function at compile-time in the same manner it's done in Nemerle (multi-stage compilation).

This is orthogonal to generics. the limitations you see in C# are *not* limitations of its generics but rather of the meta-programing facilities.
December 21, 2009
On 21/12/2009 19:53, Walter Bright wrote:
> Don wrote:
>> The problem is, I'm not sure that it's feasible in general. At least,
>> it's not obvious how to do it.
>
> C++0x Concepts tried to do it in a limited form, and it got so
> complicated nobody could figure out how it was supposed to work and it
> capsized and sank.
>
> I don't think it's possible in the more general sense.

The C++0x Concepts tried to add two more levels to the type system:
template <typename T> ...
The T parameter would belong to a Concept "type", and they also added Concept maps whice are like concept Interfaces. Add to the mix backward compatibility (as always is the case in C++) and of course you'll get a huge complicated mess of special cases that no-one can comprehend.

But that doesn't mean the idea itself isn't valid. Perhaps a different language with different goals in mind can provide a much simpler non convoluted implementation and semantics for the same idea?
You've shown in the past that you're willing to break backward compatibility in the name of progress and experiment with new ideas. You can make decisions that the C++ committee will never approve.

Doesn't that mean that this is at least worth a shot?
December 21, 2009
"retard" <re@tard.com.invalid> wrote in message news:hgnlug$452$1@digitalmars.com...
> Mon, 21 Dec 2009 04:05:01 -0700, Rainer Deyke wrote:
>
>> yigal chripun wrote:
>>> Rainer Deyke Wrote:
>>>> I prefer to think of option 2 as explicitly typed while option 3 uses type inference.  Type inference is a good thing.
>>
>>> You might prefer that but it's incorrect.
>>
>> It's not incorrect, it's another way of looking at the same thing. Structural type inference and
>
>> compile-time dynamic typing are the same
>> thing.
>
> Now that's a funny term.. you see
>
> dynamic = runtime
> static = compile-time
>
> "compile type dynamic X" is a paradox. And so is "runtime static X"
>

That's not a paradox, that's a contradiction. ;)

("That's no paradox, that's my wife!" [canned laughter])


December 21, 2009
On 2009-12-18 17:07:57 -0800, bearophile <bearophileHUGS@lycos.com> said:

> Yigal Chripun:
> 
>> .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. C++ can't do this since it has no separation between
>> "structs" and "classes".
>> there is no casting involved since the full type info is stored.
>> so a Foo<Bar> will be typed as Foo<Bar> at the binary level as well and
>> you can use APIs to query this at runtime.
> 
> In D structs and classes are distinct enough, but they currently produce duplicated templated code, this may be fixed:
> 
> void foo(T)(T o) {
>     printf("foo: %d\n", o.y);
> }
> 
> class A { int x = 1; }
> class B : A { int y = 2; }
> class C : A { int y = 3; }
> 
> void main() {
>     B b = new B();
>     C c = new C();
>     foo(b);
>     foo(c);
> }
> 
> /*
> DMD1:
> 
> _D4temp17__T3fooTC4temp1BZ3fooFC4temp1BZv   comdat
>         push    EAX
>         mov ECX,offset FLAT:_D4temp1C6__vtblZ[018h]
>         push    dword ptr 0Ch[EAX]
>         push    ECX
>         call    near ptr _printf
>         add ESP,8
>         pop EAX
>         ret
> 
> _D4temp17__T3fooTC4temp1CZ3fooFC4temp1CZv   comdat
>         push    EAX
>         mov ECX,offset FLAT:_D4temp1C6__vtblZ[018h]
>         push    dword ptr 0Ch[EAX]
>         push    ECX
>         call    near ptr _printf
>         add ESP,8
>         pop EAX
>         ret
> 
> 
> LDC:
> 
> _D13testtemplates27__T3fooTC13testtemplates1BZ3fooFC13testtemplates1BZv:
>     subl    $12, %esp
>     movl    12(%eax), %eax
>     movl    %eax, 4(%esp)
>     movl    $.str3, (%esp)
>     call    printf
>     addl    $12, %esp
>     ret
> 
> _D13testtemplates27__T3fooTC13testtemplates1CZ3fooFC13testtemplates1CZv:
>     subl    $12, %esp
>     movl    12(%eax), %eax
>     movl    %eax, 4(%esp)
>     movl    $.str3, (%esp)
>     call    printf
>     addl    $12, %esp
>     ret
> */
> 
> Bye,
> bearophile

This isn't a bug.   This is how it is template code is supposed to work.   However, there does seem to be one problem in the output you're giving.

LDC should not be producing different name mangling than DMD!   This is part of the D ABI last I checked, so as to avoid all the problems C++ has associated with libraries from different compilers not playing nice.

-S



December 21, 2009
Hello Yigal,

> On 20/12/2009 03:11, BCS wrote:
> 
>> 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.
>> 

[reordered a bit]

> This is orthogonal to generics. the limitations you see in C# are
> *not* limitations of its generics but rather of the meta-programing
> facilities.
> 

I that case, I don't give a rat's A** about generics. Do whatever you want as long as you don't mess with my meta-programming stuff.

> What you're talking about in the above is meta-programing. Doing
> meta-programing a-la c++ templates is IMO like trying to use square
> wheels, it is just wrong.
> 
> To answer your questions:
> D already has better designed tools for this and they keep improving.
> Don is doing an excellent job in fixing CTFE.
> I think D needs to go beyond just constant-folding (CTFE) and allow to
> run any function at compile-time in the same manner it's done in
> Nemerle
> (multi-stage compilation).

Personally I see CTFE as a hack for about half of the use cases I'm interested in. The vast bulk of the meta-programming that I care about amounts to compile time code generation. For that, CTFE falls into one of two uses; data processing to convert user input into something that can be (somehow) converted into code and mixin(CTFE()).

For the first I think we are in agreement, the more CTFE can do the better. For the second, I think it's a total abomination in all but a few tiny use cases. 


December 21, 2009
S:
>This isn't a bug.   This is how it is template code is supposed to work.<

It's not a bug, but a smarter compiler can try to reduce binary size conflating parts of asm code that are equal, to reduce the size of the resulting binary. It's a way to reduce one of the disadvantages of C++/D-style templates.

Bye,
bearophile
December 22, 2009
Yigal Chripun wrote:
> But that doesn't mean the idea itself isn't valid. Perhaps a different language with different goals in mind can provide a much simpler non convoluted implementation and semantics for the same idea?
> You've shown in the past that you're willing to break backward compatibility in the name of progress and experiment with new ideas. You can make decisions that the C++ committee will never approve.
> 
> Doesn't that mean that this is at least worth a shot?

I believe that D's template constraint feature fills the bill, it does everything Concepts purported to do, and more, in a simple and easily explained manner, except check the template body against the constraint.

The latter is, in my not-so-humble opinion, a desirable feature but its desirability is overwhelmed by the payment in complexity and constrictions on the Concepts necessary to make it work.