
Steve Horne
There's a proposal at the moment to add support for TDNR to Haskell - to leverage "the power of the dot" (e.g. for
intellisense).http://hackage.haskell.org/trac/haskell- prime/wiki/TypeDirectedNameResolution
I approve of the goal, ...
Steve, I think that proposal has been rather superseeded by http://hackage.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields, which draws on TDNR. But SORF is best seen as an evolving design space, with precise details yet to be clarified/agreed. I've put my own variation into the ring: http://www.haskell.org/pipermail/glasgow-haskell-users/2011- December/021298.html -- which seems to have fallen into a black hole :-( One of the aspects of TDNR that wasn't so popular was that its type-directed resolution was very similar to instance resolution, but subtly and confusingly different. I guess we have to be very careful about the dot. It seems to be in a very 'crowded' syntax space, so if we implement the wrong way, we could end up shutting the door with the keys left inside. SPJ's observations about how the dot works in other languages are all good points. He's arguing that the dot should behave in a familiar way. I'm most used to it in SQL as table.column, but I guess for most programmers it's object.method. Haskell is already encumbered by Module.name, and g . f (function composition with spaces round the dot). I like the part in OverloadedRecordFields (and TDNR) re user-defined 'virtual' fields. (fullName being a concatenation of the datatype fields firstName and lastName, area being a calculation over a Shape datatype.) But the point about those being virtual is that they're not first-class fields: you can't update through them. SPJ got 'stuck' at that point. My proposal was that restricting the dot to field selection wasted too much of the design space. Instead dot should be merely syntactic sugar for reverse function application. That is: whatever.funcmethod ==> (funcmethod whatever) (Note no spaces around the dot. This is syntactically distinct from qualified names because the name to the left of the dot begins lower-case.) Then funcmethod can be a 'real' field selector, or a virtual field or a class method or some other function completely. So to get to name resolution: since dot is (reverse) function application, we can use all the usual Haskell type inference/instance selection 'for free'. Either/both `whatever' and `funcmethod' could be arguments passed through from a distant call, which turned out to be a record type and field selector (not recognisable as such from its name). So we'd get polymorphic record and field selection 'for free'. I'd also like to be able to mix the dot with qualified names: A.b.(C.D.e.f).G.h ==> (G.h ((f C.D.e) A.b)) The syntax rule is: an upper-case name to the left of the dot means this is a qualified name, and binds most tightly. lower-case to the left means reverse- function applic. Of course you can use parentheses to group differently. (Re a one-sided dot I have no intuitions. TDNR includes some options for partial application/sections, SORF some more. They seem to me what Wirth would call 'rococo'. If dot is to be merely function application, it hardly seems worth worrying about.) How do we get field names to be suitable funcmethods for dot applying to records? And how do we support field update? ==> Subjects for a different post. There's also an elephant in the room I haven't talked about: TDNR started with what happens inside an IDE when you type `x.' and all the possible methods (or fields) for x pop up. This follows the philosophy in OO of focus on the object -> look for the action. (Same thinking as right-click in GUI's. Contrast old-style 'green screen' applications where you went down a menu tree first (action), then looked for your object.) If the dot is merely function application, then what follows the dot could be 'anything' (including very generic functions like show or return). I plain don't know if IDE's can be smart enough to spot that what's to the left of the dot is a datatype and offer its fields, or get from its type to its instances to their methods. (Actually, under my proposal, datatype to fields is exactly datatype to Has instance.) (How) could it tell what are more-specific or more- generic methods?
My basic idea is stolen from Bertrand Meyer (Object-Oriented Software Construction, second edition). Basically, a class *is* both a module and a type. ...
1) Are you sure that C++ classes/instances/methods are comparable enough to Haskell's? This is a very confusing area of terminology for object-oriented cp. functional languages. 2) Have you looked at GHC 7.4.1 innovations around classes-as-types and Constraint kinds?