Andreas said:
Not sure how the "wrong" relates to the quoted paragraph, but I guess
you mean my conjecture that you cannot dispatch on return types with
dynamic typing.
Interesting example, thanks for showing it. I'm not fluent enough in
Lisp to understand how this actually works but it does not seem to be
extensible in a compositional way (you have to insert all type cases by
hand).
No, at least not in the default method for from-string-expansion I have
shown above. That method only covers the default cases, and needs to
distinguish different ways how Common Lisp handles pre-defined types.
What you would need to do for your own types is to write your own
specialized versions of from-string-expansion:
(defmethod from-string-expansion ((to-type (eql 'foo)) string)
`(somehow-convert-string-to-foo ,string))
You don't need to modify the method given above. (You need to write
conversion routines for your own types in any language.)
And does the resolution work transitively? I.e. if I write some
complex function f using fromString somewhere, performing arbitrary
calculations on its return value of type t, and returning something of a
type containing t, is all this code parametric in t such that I can call
f expecting arbitrary result types? All this would be automatic in Haskell.
It should be possible in principle. The macro shown above is expanded at
compile-time (this is 100% correct, but sufficiently correct for the
sake of our discussion). The &environment keyword captures the lexical
environment that is current at macro expansion time.
VARIABLE-INFORMATION looks up type information about a variable in that
environment, before the code is actually translated into its final form.
The original idea for such environment objects was that you could not
only look up standardized information about entities of the compilation
environment, but that you can also stuff in your own information. So in
principle, it should be possible to use this as a basis for a type
inferencing mechanism.
The downside of all this is that ANSI Common Lisp doesn't define the
needed functions to do all this. It defines such environment objects
only in very rudimentary ways that are actually not powerful enough.
CLtL2 had this stuff, but apparently it had some glitches that are hard
to get right, and it was decided to leave this stuff out of the ANSI
standard.
There are Common Lisp implementations that implement this functionality
to a certain degree, and apparently Duane Rettig of Franz Inc. is
currently working on an implementation that has sorted out the edge
cases. They seem to consider making this available as open source.
It's probably possible to do similar things with the ANSI-defined
DEFINE-COMPILER-MACRO, or with proprietary extensions like DEFTRANSFORM
in LispWorks.
Also note that your transcript shows that your approach indeed requires
*explicit* type annotations, while you would rarely need them when doing
the same thing in a language like Haskell.
I think it should be possible in principle to add type inferencing to
Common Lisp as a sophisticated macro package, even without proper
environment objects.
It would probably take serious effort to implement such a beast, and it
would be difficult to solve interferences with "third-party" Lisp code,
but at least you would not need to change the base compiler to add this.
Anyway, your code is complicated enough to make my point that the static
type system gives you similar expressiveness with less fuss.
Yes, you're right. If you would want/need static type checking by
default, it wouldn't make much sense to do this in a dynamically typed
language that treats static type checking as an exceptional case. And
vice versa.
Pascal