The madness of implicit parameters: cured?

Ben Rudiak-Gould benrg@dark.darkweb.com
Sun, 3 Aug 2003 16:29:43 -0700 (PDT)


I just noticed something interesting. Consider

    f #name = g where g #name = "hello"

This apparently has type (#name :: a) -> (#name :: b) -> String. Should
the two #names be merged? Clearly not, because ordinary positional
parameters never get merged, and named parameters are supposed to be the
same except that they're referred to by name. Then the following should be
legal:

    f { #name = 1 } { #name = 2 }

So when named parameters have different names their relative order doesn't
matter, but when they have the same name it certainly does!

But this is actually a simplification, not a complication, because it
means that the distinction between positional and named parameters is a
chimera. Positional parameters behave just like named parameters having a
special out-of-band name, so ordinary abstraction and application can be
treated as sugar for named abstraction and application.

That's not quite the whole story, though:

    f #name #name = #name

Is this (#name :: a) -> (#name :: b) -> a, or
(#name :: a) -> (#name :: b) -> b, or an error? This problem crops up
because my notation for abstracting named parameters involves punning
(which I hadn't noticed before): It uses the same identifier in the
interface and the implementation. The proper notation would be something
like this:

    f { #name = x } { #name = y } = y

On the other hand, auto-lifted parameters with the same name clearly
should be merged. This is another way in which they differ from ordinary
named parameters, and suggests that they should indeed go in the
(unordered) type context, while ordinary named parameters clearly
shouldn't.

I don't think this is actually a problem with my proposal, but it worries
me a bit because it suggests that the semantics of named parameters aren't
quite as obvious as I previously thought.


-- Ben