Re: Holes in GHC
Hi Sorry to pile in late... On 13 Feb 2012, at 09:09, Thijs Alkemade wrote: > On Sun, Feb 12, 2012 at 2:55 PM, Andres Löh > wrote: >> Hi Thijs. >> >> Sorry if this has been discussed before. >> >> In my opinion, the main advantage of Agda goals is not that the type >> of the hole itself is shown, but that you get information about all >> the locally defined identifiers and their types in the context of the >> hole. [..] > Thanks for your feedback. Showing everything in scope that matches or > can match the type of a hole is certainly something I am interested > in, but I'm afraid it's out of the scope of this project. That's not quite what Andres said, although it would also be a useful piece of functionality. If I might plug a bit of kit I knocked together recently, if you cabal install shplit (see also https://personal.cis.strath.ac.uk/~conor/pub/shplit/ ) you'll get the beginnings of an editor-assistant which just works as a stdin->stdout transducer. I've been able to wire it into emacs quite neatly and gedit more clunkily. I'm told vi should be no problem. Shplit turns foo :: [x] -> [x] foo xs{-?-} = into foo :: [x] -> [x] foo [] = foo (x : xs) = by (i) snarfing the datatype declarations from your file (no import chasing yet) and adding them to a standard collection, (ii) figuring out the type of the pattern variables given the type signature provided. Shplit is still very dumb and makes no use of ghc's typechecker: shplit's typechecker could be used just as easily to mark up pattern variables with their types, as to do case analysis. It is rather tempting to push further and make the thing label holes with their types. Sometimes, the adoption of primitive technology is a spur to design. If one adopts the transducer model, the question then arises "in what format might we insert this data into the file?". In the case of typed holes, we can go with types in comments, or (with careful use of ScopedTypeVariables) we can really attach them in a way that would get checked. I think it could be quite a lot of fun to build a helpful tool, splitting cases, supplying type information, perhaps even offering a menu of possible ways to build a term. I think the transducer method is a relatively cheap (* major caveat ahead) and editor-neutral way to go about it. If you fix a text format for the markup (i.e., for requests to and responses from the transducer-collaborator), at worst it's usable just by running the thing on the buffer, but with more programmable editors, you can easily make more convenient triggers for the requests, and you can parse the responses (e.g. generating tooltips or lifting out a list of options as a contextual menu). The adoption of the transducer model effectively separates the choice of information and functionality from the design of the user interface, which has certainly helped me to get on and do something. The caveat is that transducers require not just parsing source code but the ability to reconstruct it, slightly modified. Currently, she and shplit have very selective, primitive technology for doing this. Parsing-for-transduction is surely worth a proper think. All the best Conor ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: ANNOUNCE: GHC 7.4.1 Release Candidate 1
On 22 Dec 2011, at 16:08, Sean Leather wrote: I've built it from source (ghc-7.4.0.20111219-src.tar.bz2) on Leopard. I'd be happy to contribute my build if somebody tells me what to do. I had a crack at this and got quite warm, literally and metaphorically. But, no, I didn't quite get there. And yes, it's some sort of libraries issue. Here's the barf... make -r --no-print-directory -f ghc.mk phase=final all "inplace/bin/ghc-stage1" -fPIC -dynamic -H32m -O-package-name integer-gmp-0.4.0.0 -hide-all-packages -i -ilibraries/integer-gmp/. - ilibraries/integer-gmp/dist-install/build -ilibraries/integer-gmp/dist- install/build/autogen -Ilibraries/integer-gmp/dist-install/build - Ilibraries/integer-gmp/dist-install/build/autogen -Ilibraries/integer- gmp/.-optP-include -optPlibraries/integer-gmp/dist-install/build/ autogen/cabal_macros.h -package ghc-prim-0.2.0.0 -package-name integer-gmp -XHaskell98 -XCPP -XMagicHash -XUnboxedTuples - XNoImplicitPrelude -XForeignFunctionInterface -XUnliftedFFITypes -O2 - no-user-package-conf -rtsopts -odir libraries/integer-gmp/dist- install/build -hidir libraries/integer-gmp/dist-install/build -stubdir libraries/integer-gmp/dist-install/build -hisuf dyn_hi -osuf dyn_o - hcsuf dyn_hc libraries/integer-gmp/dist-install/build/GHC/ Integer.dyn_o libraries/integer-gmp/dist-install/build/GHC/Integer/GMP/ Internals.dyn_o libraries/integer-gmp/dist-install/build/GHC/Integer/ GMP/Prim.dyn_o libraries/integer-gmp/dist-install/build/GHC/Integer/ Logarithms.dyn_o libraries/integer-gmp/dist-install/build/GHC/Integer/ Logarithms/Internals.dyn_o libraries/integer-gmp/dist-install/build/ GHC/Integer/Type.dyn_o libraries/integer-gmp/dist-install/build/cbits/ gmp-wrappers.dyn_o libraries/integer-gmp/dist-install/build/cbits/ cbits.dyn_o libraries/integer-gmp/gmp/objs/*.o -shared -dynamic - dynload deploy -dylib-install-name /usr/local/lib/ghc-7.4.0.20111219/ `basename "libraries/integer-gmp/dist-install/build/libHSinteger- gmp-0.4.0.0-ghc7.4.0.20111219.dylib" | sed 's/^libHS//;s/[-]ghc.*//'`/ `basename "libraries/integer-gmp/dist-install/build/libHSinteger- gmp-0.4.0.0-ghc7.4.0.20111219.dylib"` -no-auto-link-packages -o libraries/integer-gmp/dist-install/build/libHSinteger-gmp-0.4.0.0- ghc7.4.0.20111219.dylib ld: duplicate symbol ___gmpz_abs in libraries/integer-gmp/gmp/objs/ add.o and libraries/integer-gmp/gmp/objs/abs.o collect2: ld returned 1 exit status make[1]: *** [libraries/integer-gmp/dist-install/build/libHSinteger- gmp-0.4.0.0-ghc7.4.0.20111219.dylib] Error 1 make: *** [all] Error 2 ...which makes me wonder just what I need to delete. This sort of issue is beyond my ken, but I'm willing to learn. I also have no especial attachment to Leopard. Clues appreciated Conor ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: ANNOUNCE: GHC 7.4.1 Release Candidate 1
On 22 Dec 2011, at 16:08, Sean Leather wrote: I've built it from source (ghc-7.4.0.20111219-src.tar.bz2) on Leopard. I'd be happy to contribute my build if somebody tells me what to do. I hope somebody who knows does just that. Meanwhile, that sounds good to try for myself. My flat's a bit on the chilly side... Cheers Conor ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: ANNOUNCE: GHC 7.4.1 Release Candidate 1
Hi On 21 Dec 2011, at 22:41, Johan Tibell wrote: Built a bunch of packages using the 64-bit compiler on OS X Lion. Works fine. I'm a bit of a numpty when it comes to this sort of thing. I tried to install this version ghc-7.4.0.20111219-i386-apple-darwin.tar.bz2 under Leopard, and got this far bash-3.2$ sudo ./configure Password: checking for path to top of build tree... dyld: unknown required load command 0x8022 configure: error: cannot determine current directory I don't really know what this means. I'm kind of expecting that I have *no chance* of getting this to work on Leopard and should pop out for some other big cat. Is it worth trying harder just now, or should I lose the spots? Cheers Conor ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Superclass defaults
On 2 Sep 2011, at 18:19, Jonas Almström Duregård wrote: I agree. Option 2 FTW :) The recent discussion concerns whether option 2 should eventually be shifted to option 1. Everyone seems to agree that option 2 should be used initially. A similar warning should perhaps indicate that a "hiding" clause has nothing to hide, as Jonas suggests. I'm in favour of Option 2 now and Option 1 later, where "later" has non-disruptiveness criteria attached. A bit like being in favour of the pound now and the euro later. As I've mentioned in another message just now, even Option 2 entails some disruption, when you make one old class a new superclass-with- default of another (e.g. Functor for Monad): if old code makes M a Functor in a later module than its Monad instance, that Functor M instance comes too late to pre-empt the default and is rejected as a duplicate. All the best Conor Regards, Jonas On 2 September 2011 18:55, Simon Peyton-Jones wrote: Too many words! I'm losing track. What I'm proposing is Option 2 under "The design of the opt-out mechanism" on http://hackage.haskell.org/trac/ghc/wiki/DefaultSuperclassInstances I believe that meets everyone's goals: * A warning encourages you to fix the client code * But you can turn it off, and it's not fatal. Does anyone advocate something else? Simon | -Original Message- | From: glasgow-haskell-users-boun...@haskell.org [mailto:glasgow-haskell-users- | boun...@haskell.org] On Behalf Of Jonas Almström Duregård | Sent: 02 September 2011 16:50 | To: Conor McBride | Cc: GHC users | Subject: Re: Superclass defaults | | > The question then comes down to whether that warning should ever be | > strengthened to an error. | | Indeed. | | > I agree that such a scenario is possible. The present situation gives | > no choice but to do things badly, but things often get done badly the | > first time around anyway. Perhaps I'm just grumpy, but I think we | > should aim to make bad practice erroneous where practicable. Once | > the mistake is no longer forced upon us, it becomes a mistake that | > deserves its penalty in labour. Silent pre-emption is bad practice and | > code which relies on it should be fixed: it's not good to misconstrue | > an instance declaration because you don't know which instance | > declarations are somewhere else. Nonmonotonic reasoning is always a | > bit scary. | > | > From a library design perspective, we should certainly try to get these | > hierarchical choices right when we add classes. I accept that it should | > be cheap to fix mistakes (especially when the mistake is lack of | > foresight. Sticking with the warning rather than the error reduces the | > price of this particular legacy fix at the cost of tolerating misleading | > code. I agree that the balance of this trade-off is with the warning, | > for the moment, but I expect it to shift over time towards the error. | > But if it's clear what the issue is, then we can at least keep it under | > review. | | I agree. Making bad practice erroneous is good, but its not really the | bad practice that raises the error here. You have no serious problems | until you try to change your bad design to a good one. Like you say it | should be cheap to fix mistakes. | | >> Will there be a solution to this dilemma that I have missed? Should | >> the client code be allowed opt-out from the superclass preemptively | >> before it is given a default? Won't that cause a similar perplexity? | > | > I don't know what you mean by this. Perhaps you could expand on it? | | What I'm trying to ask is if you can write compatible code that will | work across gradual changes of the compiler and the libraries. | | Suppose we have library with class C. In a newer version of the | library we add an intrinsic superclass S. Also suppose the compiler | implements option 1. Now the users of the library want to write code | that uses both C and S, and that's compatible with both the new and | the old library. From what I can tell there are three situations that | needs to be covered: | | 1) Old compiler - Old library | Here we need to specify both instances, and we cant hide the default S | instance because its not supported by the compiler. This also applies | for other situations where the client must use Haskell 2010 compatible | code. | | 2) New compiler - Old library | Here we also need to specify both instances. | | 3) New compiler - New library | We can either write both instances and hide the default or we can just | write an instance for C. | | Clearly code that covers situation 1 will never be compatible with situation 3. | | The question I was asking was if we are allowed to hide the default | instance of S in situation 2. In t
Re: Superclass defaults
Hi On 2 Sep 2011, at 16:34, Brandon Allbery wrote: I hope I am misunderstanding this I wrote: I agree that such a scenario is possible. The present situation gives no choice but to do things badly, but things often get done badly the first time around anyway. Perhaps I'm just grumpy, but I think we should aim to make bad practice erroneous where practicable. Once the mistake is no longer forced upon us, it becomes a mistake that deserves its penalty in labour. Silent pre-emption is bad practice and with the response: So, when the whole point is that an unfortunate design years ago can't be reasonably fixed without rewriting massive amounts of code, the only correct answer is to rewrite massive amounts of code? I'm not sure what you're asking here. Of course we should compare the pain of the treatment with that of the symptoms. Especially when the original proposal was put forward *specifically to avoid* rewriting massive amounts of code? Which original proposal? How does it avoid rewriting code? Yes, we'd love a perfect world. We don't have one. That's the *point*. Recall that Option 2 resolves the duplicate superclass instances in favour of an explicit prior instance, but issues a warning (which should offer the data to choose between explicit resolutions). That deals with a chunk of the legacy scenario (although it doesn't handle the situation where some M is made a Monad in one module and made Applicative in a later module, which is possible (common, even?) because Applicative is not currently a superclass of Monad). If we make one existing class a superclass of another existing class, some disruption is inevitable: we can try to minimize that disruption, but we can't eliminate it entirely. For another example, if some F is made Applicative and Traversable in the same module, which default Functor instance pre-empts the other? We should question whether the disruption of even Option 2/3 makes it worth adding default superclass instances at all. Maybe, depressingly, we've reached the can't-fix-it stage. It would be good to get some data. It's also worth considering tools to support migration, using the diagnostics generated by warnings. If it is worth adding default superclass instances, Option 2 looks like a crucial disruption-minimizing expedience, while we have a legacy of newly extraneous instances to deal with. As far as "an unfortunate design years ago" is concerned, we should be careful to minimize the amount of rewriting required. If that minimum is still too much, we'd better not go there. I'm in favour of moving to Option 1 eventually, as somehow the better choice for code comprehension. But I can see reasons to resist the changeover: * too much unmigrated code still relying on pre-emption under Option 2; * new instances of the old problem (an existing S is suddenly made a superclass of an existing C, with a default S instance for C) come into being, The former is a real risk, but hopefully with a finite lifespan. It would be too costly to switch from a warning to an error while too much code relies on the deprecated practice. Please don't imagine I'm in favour of that. The latter, however, requires us to be a bit dim in a way which was certainly not in evidence when most of the current motivating examples arose. In the legacy code (Monad-Applicative-Functor, Traversable-Foldable-Functor), we've had to choose between two bad options, but the candidate superclass-with-default-implementation has usually been evident. I'm sure we're capable of being that dim. I'm also sure we're capable of screwing up by writing an instance and assuming we get the default superclass instance we expect, without noticing that someone else's chunk of the codebase pre-empts it. I'd be troubled if someone knackered my applicative- style use of Monad [] by adding a zipping Applicative [], or even an instance which appeared to have the same functionality but also did some sneaky unsafePerformIO badness. That's an example of the risk we take by allowing pre-emption. We have to balance the risk of going back and resolving duplicates with the risk of bugs caused by code meaning less than it says. So, are default superclass instances just too disruptive? All the best Conor PS We'd love a perfect world. We don't have one. That's why we change things. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Superclass defaults
Hi On 2 Sep 2011, at 10:55, Jonas Almström Duregård wrote: On 31 August 2011 12:22, Conor McBride wrote: I become perplexed very easily. I think we should warn whenever silent pre-emption (rather than explicit) hiding is used to suppress a default instance, because it is bad --- it makes the meaning of an instance declaration rather more context dependent. Perhaps a design principle should be that to understand an instance declaration, you need only know (in addition) the tower of class declaration s above it: it is subtle and worrying to make the meaning of one instance declaration depend on the presence or absence of others. Those are all good arguments, and you've convinced me that always warning is better. The question then comes down to whether that warning should ever be strengthened to an error. First of all, I think the design goal is quite clear: "a class C can be re-factored into a class C with a superclass S, without disturbing any clients". Requiring client C to opt-out from the default implementation of S is a clear violation of the design goal. So I disagree that option 1 can be compatible with the design goal, but like you say the design goal might be at fault. Design goal 1 does not explicitly distinguish the scenarios where S is pre-existing or being introduced afresh. If the former, it's inaccurate to describe what's happening as refactoring C, for S is experiencing some fall-out, too. We should clearly seek more precision, one way or another. Also, if I understand you correctly, you say the current situation is exceptional, and suggest option 2 as a temporary solution to it. You seem convinced that these kind of situations will not appear in the future, but I'm not as optimistic about that. Even when superclass defaults are implemented, people will occasionally implement classes without realizing that there is a suitable intrinsic superclass (or add the superclass but not the default instance). People will start using the new class and give separate instances for the superclass, and eventually someone will point out that the there should be a default instance for the superclass. Now if option 1 is implemented, the library maintainers will be reluctant to add the superclass instance because it will break a lot of client code. I agree that such a scenario is possible. The present situation gives no choice but to do things badly, but things often get done badly the first time around anyway. Perhaps I'm just grumpy, but I think we should aim to make bad practice erroneous where practicable. Once the mistake is no longer forced upon us, it becomes a mistake that deserves its penalty in labour. Silent pre-emption is bad practice and code which relies on it should be fixed: it's not good to misconstrue an instance declaration because you don't know which instance declarations are somewhere else. Nonmonotonic reasoning is always a bit scary. From a library design perspective, we should certainly try to get these hierarchical choices right when we add classes. I accept that it should be cheap to fix mistakes (especially when the mistake is lack of foresight. Sticking with the warning rather than the error reduces the price of this particular legacy fix at the cost of tolerating misleading code. I agree that the balance of this trade-off is with the warning, for the moment, but I expect it to shift over time towards the error. But if it's clear what the issue is, then we can at least keep it under review. Will there be a solution to this dilemma that I have missed? Should the client code be allowed opt-out from the superclass preemptively before it is given a default? Won't that cause a similar perplexity? I don't know what you mean by this. Perhaps you could expand on it? All the best Conor ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Superclass defaults
Hi Sorry to be late again...I'm trying to have what's laughably described as a holiday, but it seems more like the common cold to me. On 31 Aug 2011, at 08:52, Jonas Almström Duregård wrote: | > There seems to be a lot of support for Option 3... but what about Option 2 (ie pre-empt but give a warning)? At least in the short term, I think Option 2 is a good compromise. It's true that when I started using default superclass instances (which SHE supports) in the Epigram codebase, the first thing I had to do was delete a bunch of dull default instance stacks. That was fun, but it wasn't nothing. I think option 2 sounds very good. Possibly with the exception of only warning when the manual instance is in another module, since you will never experience the "perplexity" described in option 3 if you have written the instance yourself. I become perplexed very easily. I think we should warn whenever silent pre-emption (rather than explicit) hiding is used to suppress a default instance, because it is bad --- it makes the meaning of an instance declaration rather more context dependent. Perhaps a design principle should be that to understand an instance declaration, you need only know (in addition) the tower of class declaration s above it: it is subtle and worrying to make the meaning of one instance declaration depend on the presence or absence of others. Arguably, option 1 does not conflict with design goal 1. Design goal 1 supports a methodology for refining a class into a hierarchy without creating the need for stacks of default instances or breaking code. If the new superclass is a brand new thing without legacy instances, there's no problem. If we'd had this mechanism in place, Functor would always have been made a superclass of Monad, Applicative would have been easily inserted, and we wouldn't have the stacks of manually added default instances to worry about. The main problem with Option 1 is in dealing with the legacy of classes which currently require a stack of default instances, creating a hierarchy from parts which already exist. Option 1 would create a bunch of instance conflicts and thus demand changes to code. Design goal 1 isn't very explicit (sorry!) about this distinction between introducing new classes as superclasses and building hierarchies from legacy classes, but it was the former I intended. I always expected the latter to cause trouble. If it is also a design goal to minimize damage with respect to the current unfortunate situation, then Option 1 is problematic. Whatever we might wish, we are where we are. We should be pragmatic. I think we should set Option 1 as the direction of travel, but go with Option 2 for the moment. We should make sure that the warnings generated by Option 2 are sufficiently informative that it is easy to track down the conflicts and resolve them explicitly, for Option 1 compliance. Does this sound plausible? Conor ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Superclass defaults
[resend to GHC users, now I've subscribed!] Hi Simon On 15 Aug 2011, at 11:36, Simon Peyton-Jones wrote: | Nice. But will it be happening soon, or not? And how soon is | soon? Not soon enough to be useful for this mappend question. But, concerning proposed extensions to GHC about class aliases/ superclass defaults etc, the truth is that the biggest reason for inertia here at GHC HQ is not so much the implementation effort (athough that is always an issue). Rather, it's uncertainty about (a) Is there a reasonably large group of users who really want such a change? Or is it just "nice to have"? (b) What is the "right" design? (c) Does it pay its way? (ie do the programming benefits justify the cost in terms of both language complexity and ongoing maintenance burden of one more feature to bear in mind when changing anything) If you care about the issue, maybe you can help resolve the above questions. In particular, to give concrete evidence for (b), working out some case studies would be a Good Thing. The examples given in other proposals using the extension proposed here would be one starting point. I can't speak for "typical" users, but I can relay my own experience. I added this feature to SHE last time there was an outbreak of Functor/Applicative/Monad, just to focus a bit of concrete thought on the matter. Hacking on Epigram the other day, I finally got annoyed enough (with dumb extra instances) to use it, so I wired in default superclass instances Functor for Applicative, Applicative for Monad Functor for Traversable, Foldable for Traversable Alternative for MonadPlus and then went on the rampage! Nothing broke. I got rid of a lot of cruft. I did make essential use of hiding instance Functor for structures which were both Applicative and Traversable. I cut tens of lines for the cost of one or two hidings. If someone felt able to act as moderator for the discussion, willing to summarise conclusions, open questions, and so on, on the wiki page, that would be enormously helpful. I'm up for that role, if that's appropriate. I am in too many inner loops. But I *am* willing to contemplate such an extension -- it has the same flavour as default methods themselves, which are a very useful part of H98. One thing that's really noticeable and sad about the status quo is that we can't refine the structure of a bunch of related classes without breaking established interfaces. I guess an interesting question might be what progress is effectively being blocked by our current inability to engineer around this problem. What are we stuck with just now? This is a recurring issue, at least as far as mailing list heat is concerned, but it would be good to have more evidence of substantial impact. The Monoid vs Semigroup issue is a case in point, perhaps. Folks, what do you think? Cheers Conor PS Are there any other default superclass instances for standard classes that SHE could usefully bake in? Sadly, we can't purge redundant methods from standard classes just yet, but we can at least get rid of boilerplate instances. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users