2010/11/11 Gábor Lehel <illiss...@gmail.com>: > I agree with the people who want to decouple the dot-syntax from TDNR > itself. To quote myself from the publicly-editable wiki page: > > "This might be a really dumb question, but is there any reason TDNR > needs to be tied to a new syntax for function application? It seems > strange to me to have one syntax for left-to-right function > application without TDNR, and then another for right-to-left > application with it. I would much rather gain TDNR for the existing > syntax, and then maybe introduce the dot operator as a separate option > if people want it, which I don't. The reason I don't is that (.) as > composition and ($) already work in one direction, which is the same > direction (`foo . bar . baz $ bla` and `foo $ bar $ baz $ bla` are > interchangeable), and while in a vacuum I might even prefer the > opposite direction which (.)-as-application uses, it is much more > important to be consistent. We have a vast body of functions already > written and designed to be convenient with the existing direction: > functions are generally of the form `f :: (what to do) -> (what to do > it with) -> (result)`, which lends itself well to partial > application/currying and chaining in the existing direction, but not > the other one. (Object oriented languages which use the dot operator > indeed also use the reverse order for their methods, with the object > first and the action second.) Also, reading expressions where > different parts work in different directions is very confusing. The > one major exception which works in the other direction is monadic > bind, (>>=), which I think was a (minor) mistake, and indeed I > frequently end up using (=<<) instead. Anyway, executive summary: TDNR > yea, dot operator nay." > > Some further thoughts. > > I would have TDNR apply only in cases where: > - The functions are all imported from different modules (so you can't > define overlapping names within the same module); > - All of the functions have an explicit type signature; > - The ambiguity can be resolved by looking at the type of the first > (taking currying into account, only) parameter of each function and, > looking at the type constructors from the outside in, comparing only > type constructors which are concrete types, rather than type variables > (with or without constraints). E.g.: > -- f :: Int -> [...] and f :: Char -> [...] could be resolved; > -- f :: Foo Int -> [...] and f :: Foo Char -> [...] could be resolved; > -- f :: Foo a -> [...] and f :: Bar b -> [...] could be resolved; > -- f :: Num a => a -> [...] and f :: IsString b => b -> [...] could > *not* be resolved (even if it is known that the argument type doesn't > satisfy both constraints); > -- f :: a Int -> [...] and f :: b Char -> [...] could *not* be > resolved (though I'm less sure about this one). > -- Going by the above, neither Foo nor Bar can be type functions. > -- With more than two functions, each possible pair has to meet the > conditions.
I forgot to mention: some kind of similar criteria should probably apply to the function where 'f' is used (again going by the above examples) and/or its argument as well. E.g. it should not be possible to define "g a = f a" and have f be resolved by TDNR when g is used (even if all of the in-scope functions with the name 'f' meet the previous criteria), because TDNR is not duck typing. > > I don't have any well-articulated arguments to support this idea, yet; > it mainly just "feels right". My intuition for TDNR is that it has no > connection to semantics, and it is not intended as a means of defining > an interface: it is merely a syntactic convenience. If you want to > define an interface, use a type class. TDNR would be a convenience for > the case where you have imported multiple modules using a function of > the same name with obviously different types (whether the functions do > similar or different things is beside the point). Comparing to C++ > (though it's unlikely to help my case to mention that language here, > but whatever), I feel that type classes : TDNR :: virtual functions : > static overloading. > > And, in any case, as a language extension nobody would be forced to > use it if they don't like it. (I personally would find it very > useful). I think the fact that language extensions need to meet (much) > lesser criteria than changes to the language standard itself is > plainly evidenced by the existence of IncoherentInstances, which > nobody in their right mind would ever consider standardizing (or, for > that matter, ever enabling). > > > On Wed, Nov 10, 2010 at 10:59 AM, John Smith <volderm...@hotmail.com> wrote: >> Type-directed name resolution, as originally proposed for Haskell', has now >> been proposed for GHC. Obvious benefits of this are that conflicting >> function names from imported modules can be used without qualification >> (verbose) or pseudo-Hungarian renaming (verbose, and requires that you >> control the source, and perform the same renaming in all dependencies). This >> is important for both readability and programming in the large, particularly >> where records are concerned, as the duplicate name problem cannot be >> alleviated with typeclasses, and it is often desirable to have the same >> field names for many records in the same module. >> >> http://hackage.haskell.org/trac/ghc/ticket/4479 >> http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > > > -- > Work is punishment for failing to procrastinate effectively. > -- Work is punishment for failing to procrastinate effectively. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe