> First of all, how Haskell type classes and Ocaml functors are
> implemented, under the hood, are records of closures.  This is not a
> new idea.  Hell, if you want old school, records of function pointers
> aren't uncommon in C either.  Now get off my lawn.

If you actually read the post (or the slides), you'll notice that this
is slightly more than records of functions, and for more reasons than
just "it doesn't solve the problem in Haskell".  Specifically, if you
want open recursion with statically typed records of functions, you're
going to very quickly find yourself wading through a dense forest of
existential types, higher kinds, and (if you're very unlucky)
recursive types.  See also: TAPL.

This problem is solved by making the self pointer primitive, and thus
avoiding the need to pass it as a parameter.  And no, Haskell's
typeclasses can't do this.  Nor can OCaml's functors, or even C
structs of function pointers (not without casting).  Though, given the
fact that neither typeclasses nor functors exhibit subtyping in any
serious way, I'm not sure why you brought them up.

> The problem isn't implementation, the problem is typing subtypes.  If
> you're not doing subtyping, you're not doing OO.  "Duck types" are
> just implicitly generated supertypes- so even in duck typed languages
> like Ruby and Python you're still doing subtyping.  Changing objects
> to structures doesn't change the need for subtyping- and subtypes are
> just a royal frimping pest to type.

Yes.  That doesn't mean it's impossible, nor does it mean that all
forms of subtyping are created equal.  Nominal subtyping is a majorly
complex system.  It seems intuitive because it's easy to write from an
end code point of view, but as soon as you dig into the formalisms you
will see that structural subtyping is actually somewhat simpler to
represent.  Given the strong correlation between type formalisms and
the raw semantics of a type checker, it's not unreasonable to suspect
that this might be reflected in the way the language behaves in
practice.

> Robert, you've heard this, but for those playing along at home- one of
> the big problems with subtyping is co/contra-variance.  Say you've got
> two types, A and B, and B is a subtype of A.  That means all B's are
> A's, but not all A's are B's.  Under what circumstances can an
> array/list/vector/container of A's be used as a container of B's, and
> vice versa?  The answer is- it depends upon what you're doing with the
> array.  If you're only taking things out of the container, a container
> of B's can be used as a container of A's- but a container of A's can
> not be used as a container of B's.  Likewise, if you're putting things
> into the container, a container of A's can be used as a container of
> B's, but not vice versa.

Co- and contravariance aren't that crazy.  Granted, checking
contravariance in conjunction with nominal subtyping and multiple
inheritance is undecidable in the general case, but our languages omit
two of those three qualifications.

To date, I haven't seen a problem with variance.  Granted, that may
very well be a lack of imagination on my part, but it's still worth
mentioning.  I would need to see a compelling example that variance is
actually *necessary* in this type system.  I already have an example
in my slides which shows that path dependence, existentials and higher-
kinds are not.

> If you're willing to ditch subtyping, then yes, the problem becomes
> easy to solve.

Not sure what you're saying here.  This doesn't really relate to
anything we put forward.

Daniel

-- 
You received this message because you are subscribed to the Google Groups "JVM 
Languages" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/jvm-languages?hl=en.

Reply via email to