Re: [Haskell-cafe] Re: Proposal: TypeDirectedNameResolution
On Tue, Jul 28, 2009 at 10:05:29AM -0700, Ryan Ingram wrote: On Tue, Jul 28, 2009 at 1:41 AM, Heinrich Apfelmusapfel...@quantentunnel.de wrote: While I do agree that qualified names are annoying at times, I think that type directed name disambiguation is a Pandora's box. I see where you are going, but I'm not sure I agree. Let me give an example from another language with this kind of resolution: C++. From a purely practical point of view, function overloading in C++ does what I want almost all the time. And when it doesn't do what I want, it's always been immediately obvious, and it's a sign that my design is flawed. I would be careful about assuming aspects of C++ will translate to haskell at the type system level, The reason is that in C++, all type information flows in one direction, for instance. int foo(...) { ... int x = bar(z,y); ... } all of the types of everything passed to bar and what it returns (x,y, and z) are fully specified at every call site, so 'name overloading' is a simple matter of finding the best match. however in haskell this isn't the case. 'bar' may affect the types used in 'foo'. there is two way type information passing in haskell. This radically changes the landscape for what is possible in the two type systems. John -- John Meacham - ⑆repetae.net⑆john⑈ - http://notanumber.net/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Proposal: TypeDirectedNameResolution
Henning Thielemann wrote: Heinrich Apfelmus schrieb: Note that there are alternative solution for this particular problem. For instance, a version of qualified with different semantics will do; something like this import Data.List import sometimes qualified Data.Map as Map Isn't that quite the same as import Data.Map as Map ? Not quite. The intended difference is that ambiguous names default to the module that imports them unqualified. I.e. import Data.List import sometimes qualified Data.Map as Map map -- Data.List.map or Data.Map.map ? will silently default to Data.List.map . But you risk breaking packages when new qualifiers are added to imported modules. Yeah, that's kinda unavoidable if you don't want to qualify so many names. Regards, apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Proposal: TypeDirectedNameResolution
Heinrich Apfelmus schrieb: Sure, overloading is useful. But to avoid headache in a polymorphic language, I'd prefer a principled approach to it. Hence, I'm convinced that there should be only one mechanism for overloading in Haskell; which is type classes at the moment. It appears that type direction name disambiguation can be implemented with (automatically generated) type classes? When thinking about how to make Haskell familiar to SQL programmers I also thought that a Haskell compiler might automatically generate a type class and according instances, such that an identifier like 'field' can be used for all record types that have a field with name 'field'. I'm sure Template Haskell programmers can achieve this already with todays GHC. In the meantime I'm happy with writing qualifications, type signatures and so on. I don't know why people like to avoid them at all costs. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Proposal: TypeDirectedNameResolution
Heinrich Apfelmus schrieb: Note that there are alternative solution for this particular problem. For instance, a version of qualified with different semantics will do; something like this import Data.List import sometimes qualified Data.Map as Map Isn't that quite the same as import Data.Map as Map ? But you risk breaking packages when new qualifiers are added to imported modules. foo :: Map k a -- accepted with out qualifier 'Map' -- because it's unambiguous bar m = map show m -- defaults to Data.List.map , -- 'Map' prefix would be need in -- cases of ambiguity The idea being that names only need to be qualified when they are ambiguous, which Map and ByteString are not. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Proposal: TypeDirectedNameResolution
Ryan Ingram wrote: Heinrich wrote: While I do agree that qualified names are annoying at times, I think that type directed name disambiguation is a Pandora's box. I see where you are going, but I'm not sure I agree. Let me give an example from another language with this kind of resolution: C++. From a purely practical point of view, function overloading in C++ does what I want almost all the time. And when it doesn't do what I want, it's always been immediately obvious, and it's a sign that my design is flawed. But those cases where it does what I want have been incredibly useful. Sure, overloading is useful. But to avoid headache in a polymorphic language, I'd prefer a principled approach to it. Hence, I'm convinced that there should be only one mechanism for overloading in Haskell; which is type classes at the moment. It appears that type direction name disambiguation can be implemented with (automatically generated) type classes? Something like this class Function_lookup t where lookup :: t instance Function_lookup (k - [(k,a)] - Maybe a) where lookup = ... instance Function_lookup (k - Map k a - Maybe a) where lookup = ... For each ambiguous function, the compiler creates a type class and corresponding instances and type inference will sort out the rest (or throw a type error). Regards, apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Proposal: TypeDirectedNameResolution
Ketil Malde wrote: Cale Gibbard writes: There was a great related idea on #haskell the other day: Make explicit qualification unnecessary whenever there is a *unique* choice of module qualifications from those imported which would make the expression typecheck. My favorite annoyance is repeated import lines for each library just to be able to use some unique identifiers unqualified, e.g.: import qualified Data.ByteString as B import Data.ByteString (ByteString) import qualified Data.Map as M import Data.Map (Map) and so on. I'm all for it, if for no other reason, then just to get rid of this. Note that there are alternative solution for this particular problem. For instance, a version of qualified with different semantics will do; something like this import Data.List import sometimes qualified Data.Map as Map foo :: Map k a -- accepted with out qualifier 'Map' -- because it's unambiguous bar m = map show m -- defaults to Data.List.map , -- 'Map' prefix would be need in -- cases of ambiguity The idea being that names only need to be qualified when they are ambiguous, which Map and ByteString are not. Regards, apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Proposal: TypeDirectedNameResolution
Jason Dagit da...@codersbase.com wrote: My biggest fear is that of usability. If I understand you correctly, then as you change module imports you change the meaning of the code in potentially non-obvious ways. So this isn't too different than using unqualified imports and flipping between two modules that export the same function. Except that as you increase the 'automatic'ness of it, it has the potential to trip up people. My biggest fear is seeing it actually implemented as a language switch, resulting in chaotic inferance behaviour as soon as imports change. I think the Right Place to do this is on the editor/ide level: Help the programmer to use the right function by scanning through types, leave the display uncluttered (but make precise information about what function is referenced easily available) and save the source code fully qualified. Source code is not only made for human consumption but also as fodder for batch processes, re-compilation with other compilers etc, so we shouldn't put anything into it that can break way too easily, be it because type inferance changes in subtle ways or some library merely happens to export an additional function. Thus is the way of Malbolge, be ye warned, ye who construeth isomorphic brainb0rkz0rage. | Book 4 - Coding | | Thus spake the master programmer: | | ``A well-written program is its own heaven; a poorly-written program | is its own hell.'' | [...] | A program should follow the `Law of Least Astonishment'. What is this | law? It is simply that the program should always respond to the user | in the way that astonishes him least. | | A program, no matter how complex, should act as a single unit. The | program should be directed by the logic within rather than by outward | appearances. | | If the program fails in these requirements, it will be in a state of | disorder and confusion. The only way to correct this is to rewrite | the program. | [...] etc. pp. qed. -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Proposal: TypeDirectedNameResolution
Cale Gibbard wrote: There was a great related idea on #haskell the other day: Make explicit qualification unnecessary whenever there is a *unique* choice of module qualifications from those imported which would make the expression typecheck. Ambiguities would still need to be qualified, but I feel that this would eliminate 99% of all ugly qualified names from code. It would be especially good in the case of infix operators, which as far as I know, nobody actually enjoys qualifying explicitly. [...] What do people think of this idea? Personally, it really annoys me whenever I'm forced to give explicit module qualifications, and I think this would really help. It would also subsume the DisambiguateRecordFields extension rather handily. While I do agree that qualified names are annoying at times, I think that type directed name disambiguation is a Pandora's box. Furthermore, we already have a mechanism for type based disambiguation, namely good old type classes. For instance, the qualifications required when importing Data.Map are actually a sign that we are lacking proper container type classes à la Edison. There are other possible language extension that may make qualification easier, Pascal's with statement comes to mind. http://freepascal.decenturl.com/with-statement-pascal In Haskell, this would work something like this: histogram xs = with Data.Map foldl' f empty xs where f m x = case lookup m x where Just k - insertWith x (+1) m Nothing - insert x 1 m In the scope of with , ambiguous qualifications default to Data.Map . Regards, apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Proposal: TypeDirectedNameResolution
There are other possible language extension that may make qualification easier, Pascal's with statement comes to mind. http://freepascal.decenturl.com/with-statement-pascal In Haskell, this would work something like this: histogram xs = with Data.Map foldl' f empty xs where f m x = case lookup m x where Just k - insertWith x (+1) m I like both that and TDNR. It would be cool that at least one of them gets accepted in Haskell prime. David. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Proposal: TypeDirectedNameResolution
On Tue, Jul 28, 2009 at 1:41 AM, Heinrich Apfelmusapfel...@quantentunnel.de wrote: While I do agree that qualified names are annoying at times, I think that type directed name disambiguation is a Pandora's box. I see where you are going, but I'm not sure I agree. Let me give an example from another language with this kind of resolution: C++. From a purely practical point of view, function overloading in C++ does what I want almost all the time. And when it doesn't do what I want, it's always been immediately obvious, and it's a sign that my design is flawed. But those cases where it does what I want have been incredibly useful. Furthermore, we already have a mechanism for type based disambiguation, namely good old type classes. For instance, the qualifications required when importing Data.Map are actually a sign that we are lacking proper container type classes à la Edison. Perhaps. I think containers is a great example of why you want TDNR. Many containers have *almost* the same interface, but not quite. After all, if the interface was the same, you would just find the most efficient container for that interface and call it a day. So unless you want to go the direction of putting every single container-related function in its own typeclass, I don't think you'll be able to come up with one container interface to rule them all. To be fair, I'm not against the idea of putting each function in its own typeclass. For work along these lines, see the many better numeric hierarchy attempts. But I'd also need support for class aliases or something similar so that defining common subsets of those classes would work easily. Along those lines, what about being able to elide class names when they can be unambiguously determined from the functions defined? instance _ [] where fmap = map pure x = [x] fs * xs = [ f x | f - fs, x - xs ] return x = [x] m = f = concatMap f m This would define Functor, Applicative, and Monad for []. -- ryan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Proposal: TypeDirectedNameResolution
Ryan == Ryan Ingram ryani.s...@gmail.com writes: Ryan Along those lines, what about being able to elide class Ryan names when they can be unambiguously determined from the Ryan functions defined? Ryan instance _ [] where fmap = map pure x = [x] fs * xs = [ f Ryan x | f - fs, x - xs ] return x = [x] m = f = concatMap f Ryan m Ryan This would define Functor, Applicative, and Monad for []. What happens if I define a class Foo with a method named fmap? If this were in scope then Functor would no longer be defined for []. Could this situation cause a problem? -- Colin Adams Preston Lancashire ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Proposal: TypeDirectedNameResolution
On Jul 29, 2009, at 5:05 AM, Ryan Ingram wrote: I see where you are going, but I'm not sure I agree. Let me give an example from another language with this kind of resolution: C++. Right. That settles it: TDNR is a bad idea. Half fun and full earnest. I'm a fan of overloading as done in Ada, but the way C++ does it has always struck me as a mix of under-useful and over-complex, and my experience with it in practice has not been that marvellous. (C++ has far too many types that are _sort of_ compatible, but only sort of.) Interestingly, I've found that when I've thought I've wanted overloading in Haskell, what I've _really_ wanted is typeclasses, because they give me - far more confidence that my code is correct - far more _leverage_; typeful programming is amazing. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Proposal: TypeDirectedNameResolution
On Tuesday 28 July 2009 8:27:53 pm Richard O'Keefe wrote: Right. That settles it: TDNR is a bad idea. Half fun and full earnest. I'm a fan of overloading as done in Ada, but the way C++ does it has always struck me as a mix of under-useful and over-complex, and my experience with it in practice has not been that marvellous. (C++ has far too many types that are _sort of_ compatible, but only sort of.) Amusingly enough, one of the major items going into C++0x was concepts, which are an effort to add type class-alike restrictions to C++'s current completely ad-hoc overloading. They were only recently dropped due to disagreements about certain details (I think I read that people couldn't agree whether programmers should be forced to declare the analogue of class instances, or whether the compiler should figure it out, but I haven't paid close attention, so that may be inaccurate). -- Dan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe