Re: [Haskell-cafe] Efficient temporary file storage??
On 1/24/12 5:51 PM, Vincent Hanquez wrote: On 01/24/2012 07:33 AM, Gregory Crosswhite wrote: On 1/24/12 9:43 AM, Felipe Almeida Lessa wrote: Use cereal [1], usually it's fast and easy enough. Out of curiosity, is binary no longer the recommended standard for such things? binary got only an interface for processing lazy bytestring. cereal is able to do strict and lazy bytestring and got a partial interface like attoparsec (which is required to do proper network/io processing). Fortunately it's very simple to convert between the two, since the actual serialization API is really close. Features-wise, in my view, cereal is a superset of binary. the only thing missing that i've noticed is that you can't tell how many bytes you have processed with cereal. Fair enough, it's just that I had gotten the impression that for some time the binary package was considered by the community to the community to be the standard way of serialization/deserialization values. Is this no longer the case? Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Efficient temporary file storage??
On 1/24/12 9:43 AM, Felipe Almeida Lessa wrote: Use cereal [1], usually it's fast and easy enough. Out of curiosity, is binary no longer the recommended standard for such things? Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Why were unfailable patterns removed and fail added to Monad?
Today I learned (tldr; TIL) that the fail in the Monad class was added as a hack to deal with the consequences of the decision to remove unfailable patterns from the language. I will attempt to describe the story as I have picked it up from reading around, but please feel free to correct me on the details. :-) An unfailable pattern (which is a generalization of an irrefutable pattern) is a pattern which can never fail (excluding the possibility of _|_), such as let (x,y) = pair Before fail was a method of the Monad class, using refutable patterns in a monad required the type to be an instance of MonadZero (that is, MonadPlus without the plus), so that for example do Just x - m required that the monad be an instance of MonadZero. If you avoided such patterns, your Monad did not have to have this instance, so that for example do (x,y) - pair would not require MonadZero because the pattern is unfailable. To me this seems like a lovely way of handling the whole matter, and much improved over the incredibly ugly wart of having a fail method in the Monad class. In fact, I think I remember people on this list and in other forums occasionally bringing something like this approach up as a way of getting rid of the fail wart. So my question is, why did we go to all of the trouble to transition away from the MonadZero approach to the current system to begin with? What was so bad about unfailable patterns that it was decided to remove them and in doing so replace MonadZero with a mandatory fail method in Monad? I mean, this *is* Haskell, so my safest assumption is that smart people were involved in making this decision and therefore the reasons much have been really good (or at least, seemed good given the information at the time). :-) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why were unfailable patterns removed and fail added to Monad?
On 01/20/12 13:23, Edward Z. Yang wrote: In Haskell 1.4 g would not be in MonadZero because (a,b) is unfailable (it can't fail to match). But the Haskell 1.4 story is unattractive becuase a) we have to introduce the (new) concept of unfailable b) if you add an extra constructor to a single-constructor type then pattern matches on the original constructor suddenly become failable (b) is a real killer: suppose that you want to add a new constructor and fix all of the places where you assumed there was only one constructor. The compiler needs to emit warnings in this case, and not silently transform these into failable patterns handled by MonadZero... Okay, great, that explains two things that had not been clear to me: first, that the notion of unfailable was not removed from the language so much as not added in the first place, and second, that if unfailable *had* been added to the language then this would have created the serious risk that adding a new constructor to a type could change the meaning of your code by changing formerly irrefutable pattern matches into potential sources of mzeros. Thanks! Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why were unfailable patterns removed and fail added to Monad?
On 01/20/12 14:52, Michael Snoyman wrote: Essentially, I would want: SomeConstr args - someAction to be interpreted as: temp - someAction case temp of SomeConstr args - I completely agree; perhaps what we really want though is something more akin to a language extension --- say, DisableMonadFailForRefutablePatterns? Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to catch all exceptions that could be caught?
On 01/12/12 13:03, Magicloud Magiclouds wrote: Hi, With Prelude.catch, I could write catch () $ \_ - return Nothing. But with Control.Exception.catch, I must specify a type for the _. What should I do? Use SomeException for the type, as it is the base of the exception hierarchy. (Although Haskell does not have classes in the OOP sense and therefore does not have a built-in means of expressing subtype relations, it emulates this in a somewhat awkward manner for exceptions.) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to catch all exceptions that could be caught?
On 01/12/12 16:49, Ivan Lazar Miljenovic wrote: But it is usually recommended that you *don't* do this, as it even captures Ctrl-c invocations: Is that true in all threads, or just in the main thread? Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to catch all exceptions that could be caught?
On 01/12/12 17:07, Simon Hengel wrote: I think there are situation when it is justified to catch almost all exceptions. And people do that a lot, which often leads to ctrl-c not properly working (e.g. we had this in HUnit before 1.2.4.2). Indeed, and in fact this situation is a very natural occurrence whenever you are writing code that takes an arbitrary IO action, executes it, and then returns either the result or the exception that it threw. The code that I last used for this took advantage of catchJust and looked roughly like the following: execute :: IO a → IO (Either SomeException a) execute action = catchJust (\e → case fromException e of {Just (_ :: AsyncException) → Nothing; _ → Just e}) (Right $ action) (return . Left) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to catch all exceptions that could be caught?
On 01/12/12 17:23, Gregory Crosswhite wrote: Indeed, and in fact this situation is a very natural occurrence whenever you are writing code that takes an arbitrary IO action, executes it, and then returns either the result or the exception that it threw. The code that I last used for this took advantage of catchJust and looked roughly like the following: execute :: IO a → IO (Either SomeException a) execute action = catchJust (\e → case fromException e of {Just (_ :: AsyncException) → Nothing; _ → Just e}) (Right $ action) (return . Left) Cheers, Greg Ugh, I have no idea why the spacing got eaten; it was meant to look like: execute :: IO a - IO (Either SomeException a) execute action = catchJust (\e - case fromException e of Just (_ :: AsyncException) - Nothing; _ - Just e ) (Right $ action) (return . Left) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to catch all exceptions that could be caught?
On 01/12/12 16:58, Magicloud Magiclouds wrote: Yes, that is a problem. But consider my PS in original mail, I have no idea what exception should I catch. Where could I get that information? In my experience, exceptions fall into three categories. First, when performing IO, some functions throw an exception instead of returning an error code, as is the case for many of the functions in System.IO; however, in these cases the exceptions that can be thrown are clearly documented. Second, when a bug in your code has caused it to reach a point where it can no longer proceed, such as when there is a deadlock, when there is an infinite loop, when you violated a precondition of a pure function by for example calling head on an empty list, etc.; in such cases it is very unlikely that you would even want to catch and gracefully recover from them, so an exception specification would not help you very much anyway. Third, when you are running someone else's code and you want to be able to catch any exceptions it throws so that you can handle the error reporting yourself; in this case the only thing that you care about is whether the exception is an AsyncException or not, since if it is an AsyncException then you should almost certainly should just let it propagate up the call stack rather than dealing with it yourself. Incidentally, in all of these cases catching *all* exceptions is a bad idea unless you really know what you are doing for the reasons that others here have pointed out, so I apologize for misleading you with that suggestion. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] strict, lazy, non-strict, eager
On Dec 24, 2011, at 6:22 PM, Tony Morris wrote: Wait what? I find it intriguing, helpful, provocative and potentially helpful toward the common goal of helping others. I am interested in further commentary. I'm not scared and you shouldn't be either. Asking honest questions is imminently reasonable; accusing others of being incompetent hypocrites --- especially when you go to great length to make it clear that this is *exactly* what you are doing --- is not. The former is helpful, but the latter is poisonous. Yves's point is that doing the latter risks scaring people away. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] strict, lazy, non-strict, eager
On Dec 24, 2011, at 6:47 PM, Murray Campbell wrote: It's too late to avoid success at all costs but please don't banish our precious pedantry! Scare on! Please don't misunderstand, I have absolutely no problems at all with people arguing voraciously and pedantically over ideas, as long as they are doing so respectfully, impersonally, politely and open-mindedly. In fact, like you I welcome such discourse, and the fact that this list provides such a nice environment for it is part of the reason why I like it so much. :-) (See, for example, the argument that I started a few days ago over whether some/many belong in Alternative a few days ago.) Having said that, there is no small difference between Hey everyone! I have been thinking about something for a while, and I have an idea with which many of you will most likely strongly disagree. Here it is, and I welcome your feedback on it! and You all have long been maintaining a cognitive dissonance that in some cases turns into plain hypocrisy, and the only reason I hadn't complained about it until now was because I have been waiting for unmistakable evidence, a smoking gun, a red hand so caught that you cannot explain away. Here it is. Now people, could you please make up your mind already? It has been more than 13 years. The former invites open discussion in a friendly and positive environment, whereas the latter at best turns people off from wanting to respond positively, and at worst provokes angry responses that further poison the well. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Interruptible threads with IO loops
On Dec 21, 2011, at 6:52 PM, Fedor Gogolev wrote: Hello. I'm trying to get some threads that I can stop and get last values that was computed (and that values are IO values, in fact). Here is my first approach: [...] tick :: Int - IO Int tick v = return $ v + 1 [...] The problem is that it looks a little messy and what's worse it leaks memory. So I'm wondering if there is a better approach to do so or some fix to memory leak. I don't have any tips for cleaning up the code off the top of my head, but I suspect that the memory leak is coming from the fact that the expression (v+1) is not being forced, which means that each iteration of the loop is constructing a new thunk with a reference to the old thunk resulting in a data structure that is growing in memory usage over time. In this case the fix is easy: just replace return in tick with evaluate from Control.Exception, since evaluate guarantees in this case that the expression will be evaluated before being returned. (Caveat: What I said about evaluate will be true for numeric expressions, but for non-trivial data structures evaluate only ensures that the expression is evaluated to something called weak-head normal form, which essentially means that it will only evaluate enough of the expression to figure out what the outermost constructor of the datatype is; it just so happens that for numeric expressions the outermost data constructor is enough to give you the numeric value.) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
On Dec 20, 2011, at 11:18 PM, Heinrich Apfelmus wrote: Tillmann Rendel wrote: Hi, Robert Clausecker wrote: Image you would create your own language with a paradigm similar to Haskell or have to chance to change Haskell without the need to keep any compatibility. What stuff would you add to your language, what stuff would you remove and what problems would you solve completely different? I would try to improve the language's support for the embedding of domain-specific embedded languages (aka. combinator libraries). Such embedding requires the integration of a domain-specific language's syntax, static semantics and dynamic semantics. Some (more or less far fetched) ideas about these three areas follow. I think this is a very good point. The things I would like to see: * Better syntax for observable sharing. Doaitse Swierstra proposed a grammer construct that is basically a let statement where the binder names can be observed. I'm not entirely sure whether that is the most general or sufficient syntax, but something along these lines. * Meta-programming / partial evaluation. When designing a DSL, it is often the case that you know how to write an optimizing compiler for your DSL because it's usually a first-order language. However, trying to squeeze that into GHC rules is hopeless. Having some way of compiling code at run-time would solve that. Examples: ** Conal Elliott's image description language Pan ** Henning Thielemann's synthesizer-llvm I am not disagreeing with anything that you have said here, but in a way it seems like the problem is more fundamental than all of these things since metaprogramming and type-programming in Haskell is not first-class, so it really isn't a language that is designed for DSLs even though people get a surprisingly long way abusing it for this purpose. :-) Really what we need is a language built from the ground up for this purpose, such as Lisp, but without the parts of Lisp that cause us to use Haskell instead. :-) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
On Dec 22, 2011, at 12:25 PM, Alexander Solla wrote: It is not limiting to make distinctions that capture real differences. An overly broad generalization limits what can be proved. Can we prove that every vehicle with wheels has a motor? Of course not -- bicycles exist. Can we prove every car has a motor? Yes we can. Throwing bottoms into the collection of values is like throwing bicycles into the collection of cars. We can say /less/ about the collection than we could before, /because/ the collection is more general. Sure, throwing bottom into the set of values means that we can no longer prove as many nice properties about them. However, since bottom *does* exist in this set since functions cannot be guaranteed to terminate, the properties that we do prove will have more relevance. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
On Dec 22, 2011, at 12:40 PM, Alexander Solla wrote: fst _|_ = _|_ This expression is basically non-sense. This is only nonsense because you refuse to accept that there are valid formalisms other than your own that contain _|_ as a perfectly valid entity. :-) Should we accept straight-forwardly ill-typed expressions like: data Strict a = Strict !a fst (Strict [1..]) just because the argument is strictly a bottom? Bottom inhabits every type, but only vacuously. No, each type has its own value for _|_, and your example demonstrates why this makes more sense than making all _|_'s be equivalent. Things like seq, unsafeCoerce, and the like, are defined as (functions into) bottom in GHC.Prim, and the real semantic-changing magic they perform is done behind the scenes. It cannot be expressed as Haskell in the same Haskell context it is used. So assuming you mean something like: fst (seq [1..] (1,2)) I must respond that you are using one of these magical keywords which change Haskell's semantics. They should be avoided. So... now you want to throw out seq so that we no longer have a way to force the evaluation of values, and the motivation for this is because when we throw out _|_ then we no longer have a formal way to describe the semantics of seq? Refusing to use bottom in our semantics doesn't make life better by forcing us to stay within a total fragment of the language, it actually makes life harder by removing from us a useful tool for knowing *how* to stay within a total fragment of the language. I am collapsing the semantics for distinct bottoms into a single bottom and noting that it has no interpretation as a Haskell value. I agree that if you collapse all of the distinct bottoms then you get a mess, but since whenever we are talking about semantics in the Haskell community we give each type has its own _|_ it is an incredibly moot point; it's like saying that the problem with cars is that if you remove all of their wheels then they have a lot of trouble getting anywhere at all. :-) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
On Dec 20, 2011, at 8:05 PM, Tillmann Rendel wrote: Hi, Robert Clausecker wrote: Image you would create your own language with a paradigm similar to Haskell or have to chance to change Haskell without the need to keep any compatibility. What stuff would you add to your language, what stuff would you remove and what problems would you solve completely different? I would try to improve the language's support for the embedding of domain-specific embedded languages (aka. combinator libraries). Such embedding requires the integration of a domain-specific language's syntax, static semantics and dynamic semantics. Some (more or less far fetched) ideas about these three areas follow. To support better syntax for embedded languages, provide more rebindable syntax à la do-notation. For example, (if c then t else e) currently desugars to (case c of False - e; True - t). But it could also desugar to (if' c t e) where if' is a method of a type class. For (c : Bool), the standard library would provide an instance of this type class, but for other condition types, third-party libraries could provide it. Alternatively, if-then-else could even desugar to whatever if' is in scope. A similar idea is currently applied to Scala in the scala-virtualized project. A large part of the language should be virtualized this way, including pattern matching, lambda expressions, maybe even type or class declarations. To support better static semantics for embedded languages, provide better type-level computation, including some form of closed-world reasoning (for example, backtracking or closed pattern matching) and a reification of names at the type level, so that type-level computations can reason about the binding structures of expressions-level code. Note that I am interested in the static structure of terms, not their dynamic behavior, so this is different from dependent types. With Haskell being a fine general-purpose programming language, and even having a good foreign language interface, there is already plenty of support for the specification of dynamic semantics. Nevertheless, for domain-specific embedded compilers, it would possibly be nice to access a Haskell compiler at runtime, to compile snippets of Haskell code and dynamically link them into the currently running program. So in other words, you would like Haskell to simultaneously become more like Lisp and more like Agda? :-) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
On Dec 20, 2011, at 8:30 PM, Jesse Schalken wrote: On Tue, Dec 20, 2011 at 8:46 PM, Ben Lippmeier b...@ouroborus.net wrote: On 20/12/2011, at 6:06 PM, Roman Cheplyaka wrote: In denotational semantics, every well-formed term in the language must have a value. So, what is a value of fix id? There isn't one! Bottoms will be the null pointers of the 2010's, you watch. This ×1000. Errors go in an error monad. Including all possible manifestations of infinite loops? Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
On Dec 20, 2011, at 8:40 PM, Jesse Schalken wrote: If you think a value might not reduce, return an error in an error monad. Okay, I'm completely convinced! Now all that we have to do is to solve the halting problem to make your solution work... :-) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
On Dec 20, 2011, at 8:38 PM, Ben Lippmeier wrote: Some would say that non-termination is a computational effect, and I can argue either way depending on the day of the week. *shrug* I figure that whether you call _|_ a value is like whether you accept the Axiom of Choice: it is a situational decision that depends on what you are trying to learn more about. Of course, the history books show that monads were invented *after* it was decided that Haskell would be a lazy language. Talk about selection bias. True, but I am not quite sure how that is relevant to _|_... Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
On Dec 20, 2011, at 9:18 PM, Jesse Schalken wrote: Why do you have to solve the halting problem? You have to solve the halting problem if you want to replace every place where _|_ could occur with an Error monad (or something similar), because _|_ includes occasions when functions will never terminate. Consider integer division by 0. [...] This is all I was talking about. But imagine there was an occasion where you *knew* that the divisor was never zero --- say, because the divisor was constructed to be a natural number. Now there is no point in running in the Error monad because there will never such a runtime error; in fact, it is not clear what you would even *do* with a Left value anyway, short of terminating the program and printing and error, which is what would have happened anyway. Furthermore, it is easy to imagine circumstances where you have now forced your entire program to run in the Error monad, which makes everything incredibly inconvenient with no benefit at all. This is the problem with arguments against partial functions; they don't solve any problems at all except in the case where you have untrusted data in which case you should be using a different function or manually checking it anyway, and they add a lot of wasted overhead. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
On Dec 20, 2011, at 11:21 PM, Jesse Schalken wrote: On Tue, Dec 20, 2011 at 10:43 PM, Gregory Crosswhite gcrosswh...@gmail.com wrote: On Dec 20, 2011, at 9:18 PM, Jesse Schalken wrote: Why do you have to solve the halting problem? You have to solve the halting problem if you want to replace every place where _|_ could occur with an Error monad (or something similar), because _|_ includes occasions when functions will never terminate. I think we're talking about different things. By bottom I mean the function explicitly returns error ... or undefined. In those cases, it should go in an error monad instead. In cases where there is an infinite loop, the function doesn't return anything because it never finishes, and indeed this separate problem will never be solved while remaining Turing complete because it is the halting problem. Then honestly you should choose a different term because I am pretty certain that my use of the term bottom is the commonly accepted one which (among other places) appears in denotation semantics. Consider integer division by 0. [...] This is all I was talking about. But imagine there was an occasion where you *knew* that the divisor was never zero --- say, because the divisor was constructed to be a natural number. Then use a separate type for natural numbers excluding 0. Then you can define a total integer division function on it (although the return value may be zero and so needs a different type). That would certainly be a lovely idea *if* we were programming in Agda, but I was under the assumption that this conversation was about Haskell. :-) Now there is no point in running in the Error monad because there will never such a runtime error; in fact, it is not clear what you would even *do* with a Left value anyway, short of terminating the program and printing and error, which is what would have happened anyway. What you do with a Left value is up to you - that's the point, you now have a choice. Yes, but it is a pointless choice because if you had any reason to believe that your value was an invalid input to a function you would have checked it by now or used an alternative non-partial function that did run in an Error monad for that specific purpose. In fact, the value might not even be being handled by you, in which case someone else now has a choice. Handling of the error is done in the same place as handling of the result, no IO needed. Yes, but all that the user of your library knows at this point is that there is a bug somewhere in your library that violated an invariant. Nearly all of the time there is no way to recover from this in a useful way and so all the user will end up doing in response to your Left value is to abort anyway. The point is your program shouldn't be able to make assumptions about values without proving them with types. I agree but, again, we aren't talking about Agda here, we are talking about Haskell. :-) The whole term untrusted data baffles me. How often can you actually trust your data? All the time! For example, if I create a counter that starts at 1, only increase it, and give nobody else access to it, then I can be as certain as it is possible to be can be that it is not 0. Also, there are occasionally times when I essentially check that a Maybe value is Just in one part of the code, and then in another part of the code need to extract the value from the Just; in such cases there is no point in using method *other* than simply fromJust to extract the value. (Of course, it would be better to have condensed all of this into a single case statement in the first place, but sometimes --- say, when interfacing with others' libraries --- this ends up not being an available option.) When you send your software out into the wild, what assumptions can you make about its input? None, which is why in that case you need to test your input in that case. Also I would like to think this wasted overhead can be optimised away at some stage of compilation, or somehow removed without the programmer needing to think about it. I was thinking in terms of overhead from the coder's point of view, not from the compiler's point of view. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
On Dec 21, 2011, at 2:14 PM, scooter@gmail.com wrote: I'd suggest, in addition to the symbols, renaming some of the fundamental types and concepts, like Monad. I would violently agree that Monad is the correct term, but try to communicate with a commodity software developer sometime (or a government acquisition professional). RWH goes a long way to explaining the concepts, as do the countless Web pages dedicated to explaining the monad concept. I super-agree with you on this point; just because something is modeled by a particular mathematical structure doesn't mean that it should be named *after* that structure unless said structure is a commonly known one. In a programming language names should be chosen to maximize clarity, and the term Monad conveys absolutely no sense of what it is to anyone who isn't already well-versed in category theory. I would go further and say that there is a problem in a lot of the documentation surrounding such concepts as Monads which is that they start with a mathematical definition --- i.e., a type with a return and bind method --- and then proceed from there, which obfuscates what Monads are all about. It would be much better of a typical tutorial instead started by describing what problem exists that they solve. Haskell is a great language with solid mathematical underpinnings. I'm a big fan of it. But, adoption is the key to success; need to make the ordinary easy to understand unless the community wants to be relegated to Scala status. Honest question here: what exactly do you mean by being relegated to Scala status? Scala seems pretty alive and kicking to me, with the added bonus that it runs on the JVM which gives it an advantage in many respects over Haskell. Is there something I am mising? :-) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
On Dec 21, 2011, at 2:24 PM, Alexander Solla wrote: I would rather have an incomplete semantic, and have all the incomplete parts collapsed into something we call bottom. We can then be smart and stay within a total fragment of the language (where bottom is guaranteed to not occur). But part of the whole point of including bottom in our semantics in the first place is *exactly* to *enable* us to be smart enough to know when we are staying within a total fragment of the language. For example, including bottom in our semantics allows us to make and prove statements like fst (42,_|_) = 42 and fst _|_ = _|_ That is, as long a you know that the pair is total and that the first element is total, calling fst on it is also total regardless of whether the second value is total. Refusing to use bottom in our semantics doesn't make life better by forcing us to stay within a total fragment of the language, it actually makes life harder by removing from us a useful tool for knowing *how* to stay within a total fragment of the language. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
On Dec 21, 2011, at 8:52 AM, Jesse Schalken wrote: I don't have experience with proof assistants, but maybe my answer to this thread can be summed up as giving Haskell that kind of capability. ;) Okay, then suffice it to say that most of what you said *is* implemented in real languages like Coq and Agda so you should check them out. :-) Unfortunately there are two hurdles one faces when using these languages: first, it is often very cumbersome to actually prove all of the invariants you want to prove to make your code total, and second, there is not yet a nice way of doing I/O actions and/or interfacing with external libraries written in other languages. However, until we have solved the problems that make working entirely in dependently-typed languages a pain, we will need to stick with languages with weaker type systems like Haskell, which means that we can't get around _|_ since we cannot encode all of our invariants into the type system. Incidentally, I would highly recommend learning more about Coq and Agda. There is a great textbook to start from available here: http://adam.chlipala.net/cpdt/ It is valuable because it is not Coq-specific but rather is a good general introduction to, exactly as the title promises, certified programming with dependent types. You should also really check out Agda; the main difference between it and Coq is the language in which proofs are written. To make a long story short, in Coq proofs are often easier to write because they use a specialized language for that purpose but this often makes them a bit of a black box, whereas in Agda the proofs are fully explicit which makes them much more transparent but also more verbose and often harder to write. Unfortunately the documentation for Agda tends to be sparse and split over several kinds of documents (such as theses, papers, etc.) so isn't an obvious guide for me to recommend to you, but if you look around you should find enough information to get you started. The home page is http://wiki.portal.chalmers.se/agda/pmwiki.php For me part of the most exciting part was reading through the Agda standard libraries, which you can download from http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Libraries.StandardLibrary Just reading through their code is enlightening because it shows you just how much power is available from dependent types; the standard library also covers a lot more than Coq's does. Unfortunately it also showcases one of the limitations of Agda, which is things can often get cryptic and arcane very quickly, especially since Agda makes you work with universes explicitly (Coq handles them implicitly) which adds another layer of complexity. :-) (FYI, the universes are a hierarchy such that values are at the bottom, types of values one rung up, types of types two rungs up, types of types of types three rungs up, etc. Haskell is limited in only having a three-level hierarchy, with values, types, and kinds.) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] If you'd design a Haskell-like language, what would you do different?
On Dec 20, 2011, at 5:20 AM, Robert Clausecker wrote: What stuff would you add to your language Gratuitous use of parentheses. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Dec 19, 2011, at 12:39 PM, Brandon Allbery wrote: On Sun, Dec 18, 2011 at 20:42, Richard O'Keefe o...@cs.otago.ac.nz wrote: No. Not by a country mile. It's better than non-existent. It's better than misleading. But it's not even on the same *continent* as adequate. +1 So what do you all think about my own suggestion for the documentation? The following is the same as what I've posted before, but with some tweaks such as swapping the last two paragraphs. The Monoid instance for Maybe has the property that, for all x and y, (Just x) wins when combined (on either side) with Nothing values, and when (Just x) is combined with (Just y) then the result is (Just (x `mappend` y)). Note that the behavior of the Monoid instance of Maybe is *different* from the behavior of the MonadPlus and Alternative instance of Maybe. For the latter two typeclasses, the behavior is that when (Just x) is combined with (Just y) the x and y values themselves are not combined but rather y is discarded so (Just x) simply wins; put another way, for all x and z, we have that (Just x) `mappend` z is *always* equal to (Just x), regardless of whether z is equal to Nothing or whether it is equal to (Just y) for some y. For this reason, unlike the instance for Monoid, the instances for these MonadPlus and Alternative place no additional constraints on the type lifted into Maybe. Incidentally, for the more mathematically inclined, you may think of this as being equivalent to the standard practice of turning an arbitrary semigroup into a monoid by simply adding a new element to the semigroup to serve as the identity element, where in this case the identity element is the Nothing value of Maybe; unfortunately, since the base libraries do not come with a Semigroup typeclass, this process is expressed in code as lifting from the Monoid typeclass. I welcome any feedback that you all have to offer. If some iteration of the above is considered an improvement, then I would be happy to submit a patch using whatever process someone is kind enough to point me towards. :-) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Dec 19, 2011, at 1:03 PM, Alexander Solla wrote: The incidental comment is significantly more clear than an English description. That is only true for someone who has already seen a sentence like that one before and so can immediately pick up what it is getting at. :-) In particular, if one has never heard of a semigroup then the sentence is not very helpful. I would rather see commutative diagrams (or what amounts to the same, usage examples) that describe the behavior than a plain English description. I find it amusing that anyone would consider commutative diagram to be the same thing as usage examples for anyone other than a mathematician. :-) Nonetheless, I see your point that examples may be clearer than English, so how about: This instance satisfies the property that, for all x any y: (1) Nothing `mappend` Nothing = Nothing (2) Just x `mappend` Nothing = Just x (3) Nothing `mappend` Just y = Just y (4) Just x `mappend` Just y = Just (x `mappend` y) (Warning: Note that rule (4) for this instance is different from the case of the MonadPlus/Alternative instances where the Just y value is discarded so that Just x `mplus` Just y = Just x | Just y = Just x.) Formally, this instance performs the standard procedure of turning an arbitrary semigroup into a monoid by simply adding a new element to the semigroup to serve as the identity element, where in this case the identity element is the Nothing value of Maybe; unfortunately, since the base libraries do not come with a Semigroup typeclass, this process is expressed in code as lifting from the Monoid typeclass. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Dec 19, 2011, at 1:01 PM, Richard O'Keefe wrote: On 19/12/2011, at 3:44 PM, Gregory Crosswhite wrote: So what do you all think about my own suggestion for the documentation? It is an improvement. Documentation for a library module needs to start by telling people what it is for. For a particular function, someone needs to know very quickly is this what I am looking for? is this the kind of thing I _should_ have been looking for? I agree, though really much of that kind of information should be in the Monoid typeclass rather than in the Maybe instance in particular. The point is not that your proposed documentation doesn't say that, but it doesn't say that the MonadPlus reading is a *LEGITIMATE* way to view Maybe as a Monoid, which happens not to have been the one chosen; also that this possibility that the Monoid instance you WANT might not be the one you GET is to me the first thing you need to understand about it. Yes, there is a blanket warning about this, but it specifically mentions Num. Whenever it is possible for a reasonable person to want a Monoid instance and get one that is not the instance s/he wanted, it's worth highlighting in the docs. I understand what you are getting at here, but the reason why think that the word warning needs to appear somewhere is to get users' attention long enough to let them know that this instance might break their expectations since it is inconsistent with MonadPlus and Alternative. Nonetheless, I agree that it is a good idea to let users know that the alternative behavior might be the most useful one in their own case, so how about the following (including changes listed in an earlier e-mail), which I will call Version 5: This instance satisfies the property that, for all x any y: (1) Nothing `mappend` Nothing = Nothing (2) Just x `mappend` Nothing = Just x (3) Nothing `mappend` Just y = Just y (4) Just x `mappend` Just y = Just (x `mappend` y) Put in formal terms, this instance performs the standard procedure of turning an arbitrary semigroup into a monoid by simply adding a new element to the semigroup to serve as the identity element, where in this case the identity element is the Nothing value of Maybe; unfortunately, since the base libraries do not come with a Semigroup typeclass, this process is expressed in code as lifting from the Monoid typeclass. CAVEAT: Note that rule (4) here is different from the case of the MonadPlus/Alternative instances where the Just y value is discarded so that Just x `mplus` Just y = Just x | Just y = Just x; if this is alternative behavior is what you were looking for, then try those typeclasses instead. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Dec 19, 2011, at 1:01 PM, Richard O'Keefe wrote: Documentation for a library module needs to start by telling people what it is for. For a particular function, someone needs to know very quickly is this what I am looking for? is this the kind of thing I _should_ have been looking for? As I said before, some of this information really belongs in the Monoid typeclass itself, so here is my attempt at adding more information in this vein to the Monoid typeclass: The Monoid typeclass provides a standard interface for specifying how pairs of values of a given type can be combined to form new values of that type, as well well as an identity value for that type that when combined with any value x produces x. The Monoid class typically appears in higher-order functions that produce a list of values that need to be summarized into a single result, such as in Data.Foldable.foldMap function or the Writer monad. Formally, an instance of Monoid provides a binary associative operator with an identity element; to do this one must specify (at a minimum) the methods mempty and mappend such that they obey following properties: (*) mempty is the identity: mempty `mappend` x = x `mappend` mempty = x (*) mappend is associative: x `mappend` (y `mappend` z) = (x `mappend` y) `mappend` z Although not strictly necessary, for reasons of performance the Monoid typeclass also includes the method mconcat which combines all the elements in a list, i.e. it is a method which obeys the property (*) mconcat = foldr mappend mempty The above is the default definition of mconcat if no other is supplied, but for some times users may wish to override it when it can be performed more efficiently. Regardless, the minimal complete definition for an instance of the Monoid typeclass is mempty and mappend. For many types there are multiple equally sensible ways to combine pairs of values; for example, for the Int type one could use either addition or multiplication. In such cases where there is no single natural way to combine values, we often (though not always) define newtype wrappers for these types so that we can make it explicit which operation we are using. In the case of the Int type, for example, we define the Sum and Product newtypes and make these instances of Monoid using the corresponding mathematical operator. This additional information unfortunately makes the documentation more verbose, but the hope was to try to explain as much as possible the whys and whens of the Monoid class (to a non-mathematician audience) in addition to the whats, since as you point out often the most important part of the documentation is where it explains why something exists and when you would need it. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Dec 19, 2011, at 3:49 PM, Richard O'Keefe wrote: On 19/12/2011, at 5:46 PM, Gregory Crosswhite wrote: [improved Monoid documentation] Thank you. :-) I would go so far as to point out that mappend is a generalisation of Data.List.sum, Data.List.product, Data.List.and, and Data.List.or, where the initial value and combining rule are implied by the type. Inspired by the idea behind your suggestion, I modified the documentation as follows: The Monoid typeclass provides a standard interface for specifying how pairs of values of a given type can be combined to form new values of that type, as well as an identity value for that type that when combined with any value x produces x. The Monoid class typically appears in higher-order functions that produce a list of values that need to be summarized into a single result, such as in Data.Foldable.foldMap function or the Writer monad. Formally, an instance of Monoid provides a binary associative operator with an identity element; to do this one must specify (at a minimum) the methods mempty and mappend such that they obey following properties: (*) mempty is the identity: mempty `mappend` x = x `mappend` mempty = x (*) mappend is associative: x `mappend` (y `mappend` z) = (x `mappend` y) `mappend` z Note that this structure is very generic; it includes addition with the identity element 0 (i.e. mappend = (+), mempty = 0), multiplication with the identity element 1 (i.e. mappend = (*), mempty = 1), list concatenation with the identity element [] (i.e. mappend = (++), mempty = []), logical and with the identity element True (i.e., mappend = (), mempty = True), logical or with the identity element False (i.e., mappend = (||), mempty = False), etc. Unfortunately, sometimes this very generality results in there being multiple equally sensible ways to define a Monoid instance for a type. For example, for numeric values addition and multiplication work equally well, and for boolean values logical and and logical or work equally well. In such cases, it is a good idea to define newtype wrappers for these types so that we can make it explicit which operation we are using. In the case of the Int type, for example, we define the Sum and Product newtypes and make these instances of Monoid using the corresponding mathematical operator; see also Any, All, First, and Last for other examples of this. Although not strictly necessary, for reasons of performance the Monoid typeclass also includes the method mconcat which combines all the elements in a list, i.e. it is a method which obeys the property (*) mconcat = foldr mappend mempty The above is the default definition of mconcat if no other is supplied, but for some times users may wish to override it when it can be performed more efficiently. Regardless, the minimal complete definition for an instance of the Monoid typeclass is mempty and mappend. This additional information unfortunately makes the documentation more verbose, One man's more verbose is another man's less cryptic. Don't get me wrong, I completely agree with you that adding more words for the sake of making a subject less cryptic is a net win. :-) There are two dangers that lurk, however. First, there needs to be lots of that makes it easy for people to skim through and pick out the specific information that they want to find out about, and in particular the information that is most important/most urgently needed needs to be placed first so that it is the first thing that reader sees. Second, if you take too long to explain a point then you risk having your reader get fatigued so that all that effort you put in to make things clear just ends up getting going in one eye and out the other. :-) I really don't like the emphasis on Num, as if it was a bizarre feature of Num that there's more than one Monoid reading for it. This is a *common* property of data types. For example, Sets can be seen as monoids with empty and union; and Sets with a universe can also be seen as monoids with universe and intersection. In the revised version above, added Booleans as another example. The more I think about it, the less idea I have _what_ to expect for _any_ instance of Monoid. This is an inherent weakness of typeclasses, and why languages like Agda use record systems where instance declarations are records that you can either pass in explicitly or import explicitly to use implicitly within a particular scope. I think, though, that for many types, though, there really is a sort of most intuitive/most natural Monoid operation. For lists and sequences, for example, I think that the most intuitive operation is concatenation, rather than say taking the intersection of the elements of the two arguments. Likewise when you are accumulating over a bunch of sets
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Dec 19, 2011, at 4:45 PM, Gregory Crosswhite wrote: First, there needs to be lots of [STRUCTURE] that makes it easy for people to skim through and pick out the specific information that they want to find out about [...] Grr! I have no idea why that word got dropped out, since it was kinda important... writing too many words at once puts my brain in a fog. :-) Also, just to clarify I don't necessarily mean structure as in explicit headlines so much as any kind of structure --- including implicit structure from paragraph breaks and careful choice of presentation and ordering --- that makes it easy to pick up on how a text is broken into logical parts, what each part is roughly about, and how the parts are related. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Dec 17, 2011, at 12:35 PM, Matthew Farkas-Dyck wrote: (1) If we do (4), then the documentation ought to be adequate as-is. I see your point that if we do (4) then some and many are no longer problematic for Maybe and [], and thus we don't need warnings for those types. However, nonetheless we will *still* need *big warnings* *for the sake of others who write Alternative instances* for new types to make sure that these instances do not fall into the same trap as Maybe and []. That is, we want to let future authors of instances know about the conditions under which they will need to write their own versions of some and maybe in order to make sure that these methods have sensible behavior. In addition to this, we also really need some additional documentation explaining what the point of some and many are, since few people have any clue about them. :-) Finally, if we adopt (4) then we will need to change the documentation to remove least from least solutions of the equations since the phrase will no longer be correct. Better still, we could replace the phrase entirely with something like least *converging* solutions of the equations. (*) Cheers, Greg (*) P.S: Dear people who are better at this kind of technical language than I: I am fully aware of the fact that the phrase least converging solutions of the equations [...] is sloppy wording at best and absolutely wrong at worst, but hopefully you should at least understand what I am *trying* to get at. Thus, I would welcome either your feedback on what it is that I am supposed to be thinking and saying, or an explanation about why the idea I am trying to conceive and convey is so intrinsically poorly formed that I am best off just giving up on it. ;-)___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Alternative versus Monoid
On Dec 17, 2011, at 1:26 AM, Yves Parès wrote: 1) What about the First type? Do we {-# DEPRECATE #-} it? Personnaly, I'm in favor of following the same logic than Int: Int itself is not a monoid. You have to be specific: it's either Sum or Mult. It should be the same for Maybe: we remove its instance of Monoid, and we only use First and Last. +1 for this idea, because it follows the principle of least surprise. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Alternative versus Monoid
On Dec 17, 2011, at 1:26 AM, Yves Parès wrote: 1) What about the First type? Do we {-# DEPRECATE #-} it? Personnaly, I'm in favor of following the same logic than Int: Int itself is not a monoid. You have to be specific: it's either Sum or Mult. It should be the same for Maybe: we remove its instance of Monoid, and we only use First and Last. +1 for this idea, because it follows the principle of least surprise. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Alternative versus Monoid
On Dec 17, 2011, at 12:51 PM, Matthew Farkas-Dyck wrote: By my reason, the instance (Monoid a = Monoid (Maybe a)) is appropriate, since we have another class for inner-type-agnostic choice -- Alternative! (and MonadPlus, but that's essentially the same, and would be if (Functor m = Applicative m = Monad m), as it ought). Yes, but the problem here is that having different behavior for Alternative, MonadPlus, and Monoid instances is inherently confusing, in the sense that this would almost certainly surprise someone who wasn't already aware of the difference between the instances. Regardless, even if we keep the current behavior, we *really* *really* need to improve the documentation for the Monoid instance of Maybe. Currently it reads: Lift a semigroup into Maybe forming a Monoid according to http://en.wikipedia.org/wiki/Monoid: Any semigroup S may be turned into a monoid simply by adjoining an element e not in S and defining e*e = eand e*s = s = s*e for all s S. Since there is no Semigroup typeclass providing just mappend, we use Monoid instead. Now, I just happened to have recently spent time studying the properties of Semigroups and Monoids, so this explanation made perfect sense to me and was a beautiful way of explaining what is going on. A typical user, however --- which would have included me roughly one month ago :-) --- would have looked at this and just seen goobledegook which reinforced their perception that Haskell is first and foremost a playground for mathematicians. It would be much, much better for the documentation to be something like this: The Monoid instance for Maybe has the property that, for all x and y, (Just x) wins when combined (on either side) with Nothing values, and when (Just x) is combined with (Just y) then the result is (Just (x `mappend` y)). For the more mathematically inclined, you may think of this as being equivalent to the standard practice of turning an arbitrary semigroup into a monoid by simply adding a new element to the semigroup to serve as the identity element, where in this case the identity element is the Nothing value of Maybe; unfortunately, since the base libraries do not come with a Semigroup typeclass, this process is expressed in code as lifting from the Monoid typeclass. NOTE THAT the behavior of the Monoid instance of Maybe is DIFFERENT from the behavior of the MonadPlus and Alternative instance of Maybe. For the latter two typeclasses, the behavior is that when (Just x) is combined with (Just y) the x and y values themselves are not combined but rather y is discarded so (Just x) simply wins; put another way, for all x and z, we have that (Just x) `mappend` z is *always* equal to (Just x), regardless of whether z is equal to Nothing or whether it is equal to (Just y) for some y. For this reason, unlike the instance for Monoid, the instances for these MonadPlus and Alternative place no additional constraints on the type lifted into Maybe. Incidentally, would people be interested in me sending a patch to update the documentation to be more along these lines? (After applying your feedback, of course!) If so, could you point me to where I could learn about the process for doing so? Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Alternative versus Monoid
On Dec 17, 2011, at 2:57 PM, Gregory Crosswhite wrote: +1 for this idea, because it follows the principle of least surprise. Sorry about the double-post! I was foolish enough not only to use unsafePerformIO to send my e-mail, but to forgot to mark the sending routine with NOINLINE pragma. As a result, the sending action was sparked and run twice by the runtime environment. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type checker for haskell-src-exts (was: Typechecking Using GHC API)
On Dec 17, 2011, at 9:58 AM, Thomas Schilling wrote: Wll... I've gotten a little bit of a different perspective on this since working at a company with very high code quality standards (at least for new code). There is practically no observable code review happening. I'm sure Dimitrios and Simon PJ review most of each other's code every now and then, but overall there is very little code review happening (and no formal, recorded code review whatsoever). Cleaning up the GHC code base is a huge task -- it uses lots of dirty tricks (global variables, hash tables, unique generation is non-deterministic, ...) which often complicate efforts tremendously (I tried). The lack of a unit tests doesn't help (just rewriting code so that it can be tested would help quite a bit). So in other words, would it be helpful it we recruited GHC janitors? That is, similar to how we have the Trac which gives people bug reports to pick out and work on, would it make sense to have a Trac or some other process which gives people chunks of code to clean up and/or make easier to test? (I am of course inspired in suggesting this by the Linux kernel janitors, though it doesn't look like the project has survived, and maybe that portends ill for trying to do the same for GHC...) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] [Alternative] summary of my understanding so far
Hey everyone! First of all, it sounds like we all agree that the documentation for Alternative needs to be improved; that alone would clear a lot of the confusion up. I think that a fairly convincing case has also been made that removing many/some from the typeclass doesn't help too much since they are generically defined in terms of the other methods. Put another way, arguing that removing many/some makes Alternative more safe would be like arguing that removing forever from the definition of Monad (assuming it were currently a method rather than a function) made Monad more safe. (On the other hand, it might be nice if many/some were not featured so prominently above other functions/combinators in the module.) As a corollary to the above paragraph, if the many/some methods *were* moved to a subclass --- call it, Parser --- then essentially this subclass would be redundant. Nonetheless, such a subclass could still be useful because it supplies more information to the user about how the type behaves. That is, while any user of an instance of Alternative can always theoretically use something like many/some, in practice a user might want to add the Parser constraint to their type just to get an extra guarantee that many/some not only exist but are well-behaved. Although many/some cause infinite loops for the current instance of Maybe and [], forever also causes loops for (return (undefined)) for any Monad. Thus, even in the likely event that we decide to keep many/some in Alternative, it still makes sense to have Alternative instances for Maybe and [], despite the fact that they don't play well with many/some for non-empty values. In fact, if anything the existence of the Maybe and [] instances provides a strong reason *to* have the many/some methods inside Alternative, precisely because it gives us a customization point that allows us to make many and some provide well-defined answers for all values of these types. To quote Ross Paterson's proposals: instance Alternative Maybe where ... some Nothing = Nothing some (Just x) = Just (repeat x) many Nothing = Just [] many (Just x) = Just (repeat x) instance Alternative [] where ... some [] = [] some (x:xs) = repeat (repeat x) many [] = [[]] many (x:xs) = repeat (repeat x) The only price that we pay for these instances is that, while some and many are still solutions of • some v = (:) $ v * many v • many v = some v | pure [] they no longer the *least* solutions of these equations. In my opinion this is a relatively small price to pay since they nonetheless *are* solutions to these questions, and they have the nice property that they converge sensibly. In fact, in a sense they are the least solutions to the equations that out of all the solutions that converge, though I don't know enough about the theory involved to use the proper technical terminology to express what I really mean, or even if what I just wrote was true. :-) Anyway, as the above discussion illustrates, the existence of pure types that are instances of Alternative actually *adds* to the case of keeping some and maybe in Alternative. So in conclusion: 1) Documentation really needs to be improved 2) some/many cannot be physically separated from Alternative, but there *might* be an advantage to creating a subclass for them anyway purely for the sake of conveying more information about a type to users 3) Maybe and [] are sensible instances of Alternative, even if many/some often enters an infinite loop. 4) It is possible to provide special instance of many/some that satisfy the equations of many/some, with the slight disadvantage that these solutions are no longer the least solutions. Based on all of this, at this moment in time it seems to me that the most sensible way forward is to fix the documentation, tweak the definition of Alternative to no longer require the least solutions of the equations, and then to adopt the new instances for Maybe and []. Thoughts? Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] change some/many semantics
On Dec 15, 2011, at 5:40 PM, Antoine Latter wrote: I said 'combinators', not 'instances'. Oh! Okay, that was my bad then. A lot of popular parsers combinators can be written exclusively from (|) and empty, but make little sense for List and Maybe, and may not even function properly. The 'trifecta' package includes a nice reference: http://hackage.haskell.org/packages/archive/trifecta/0.49.1/doc/html/Text-Trifecta-Parser-Combinators.html See 'skipSome' through 'chainr1' - I wouldn't be surprised if most of these lead to the same infinite loop behavior for Maybe as the stock 'many' and 'some' in base. These sorts of functions are what Alternative is for. Okay, I see better now what you mean. Thank you. But then, if so much code based on Alternative makes little sense for List and Maybe, then maybe this should be a signal they we should remove their instance from Alternative? After all, we already have the Monad typeclass which gives them essentially the same functionality. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] change some/many semantics
On Dec 15, 2011, at 6:19 PM, Gregory Crosswhite wrote: After all, we already have the Monad typeclass which gives them essentially the same functionality. Make that the *Monoid* typeclass. :-) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Alternative versus Monoid
Hey everyone, First, thank you all for this great discussion! I unfortunately have been home due to health concerns which gets really boring after a while, so being able to participate in such a fun intellectual exercise like has really been making my day. :-D Sorry that this has resulted in such a flood of commentary on the list! Antoine Latter has pointed out to me that (using my own words here) essentially entire parser libraries are built around the assumption that many and some are sensibly defined the way that they are, and that as a result much of their functionality simply doesn't make sense for Maybe and []. So maybe the best approach to take really is to remove the instance for Maybe and [] from Alternative. After all, some and many simply are not well-behaved for them, and if you are using Alternative you are expecting them to be well-behaved. Now, on the other hand, one might argue: but Maybe and [] have well-defined functions for empty and |, so since some and many are defined in terms of these operations, shouldn't that make Maybe and [] natural instances of Alternative anyway? And *this* is where Haskell separates its way from other languages. In others language we may very well just say, Well, good point, why not make them instances of Alternative, and simply not worry about the fact that some and many don't behave well --- just don't use them like that! But in Haskell we don't do things this way. When we make something be an instance of a typeclass, we want that to *mean* something. In the case of Alternative, we want, among other things, for it to mean that our type has sensible meanings for some and many --- and if Maybe and [] simply do not meet this criteria, then THEN THEY DESERVE TO BE CAST OUT! I know, I know, I can hear you all shouting: This is blasphemy! This is madness! Madness? This... IS HASKELL! But on a more serious note, it turns out that we *already* have a typeclass that does everything that Alternative does but without the some and many baggage: it's called Monoid! So we can already get all of the features that we need (and most likely have been using anyway) by using the Monoid instances for Maybe and [] and just forgetting about the existence of Alternative entirely. So at the end of the day... what is the point of even making Maybe and [] instances of Alternative? Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] change some/many semantics
On Dec 15, 2011, at 9:31 PM, malcolm.wallace wrote: I do not regard that as a change in their semantics - it is perfectly allowed already Indeed, the instances of some/many that I write are already lazily-unfolding, wherever possible. It all depends simply on whether your instance of Applicative is lazy or strict. That makes sense. So the problem is not with Alternative but with Maybe: specifically, the problem is that there is no way to write a fully lazy instance of Applicative for Maybe since both arguments have to be reduced to WHNF before we can determine the WHNF of the result of applying ($), and this is why some/many cannot return lazily generated lists of results. Put another way, the problem with Maybe computations is that if there is a failure at any point in the computation than *the entire computation fails*, and this means that you can't lazily generate a list of results using some/many because you can't tell whether your computation was a success or a failure until the entire infinite computation has been run; the only solution to this problem is, as others have suggested, to build domain-specific knowledge about Maybe into the some/many methods of Alternative instance, which I think is one of the good solutions that has been brought up in this discussion. :-) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] some/many narrative
On Dec 16, 2011, at 3:34 AM, Bryan O'Sullivan wrote: This is both confusing and incorrect. It's entirely possible for an action in the Maybe type to fail. Okay, so inserting the phrases that either fail eventually or and that succeed forever if they do not immediately fail so that that the documentation reads: -- [Warning]: This is only defined for actions that either fail immediately or that eventually fail -- after being performed repeatedly, such as parsing. For pure values such -- as 'Maybe' that succeed forever if they do not immediately fail, this will cause an infinite loop. makes the situation more clear. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Alternative versus Monoid
On Dec 16, 2011, at 3:59 AM, Carl Howells wrote: Monoid and Alternative are not the same. There is a very important difference between them: class Alternative f where (|) :: f a - f a - f a ... class Monoid a where mappend :: a - a - a ... The equivalent to Alternative is MonadPlus, not Monoid. The kinds matter. In Alternative, you are guaranteed that the type that f is applied to cannot affect the semantics of (|). I understand that one needs to worry about kinds in general, but in this particular case such a subtlety is non-issue because you would always be defining Monad for a particular type. That is to say, given an alternative f, the instance of Monoid would be instance Monoid (f a) where { ... } where in the above a is an arbitrary type variable. To give you a more concrete example, the following code compiles and runs, producing the output [1,2,3,4,5,6] import Data.Monoid newtype L a = L [a] deriving (Show,Eq) instance Monoid (L a) where mempty = L [] mappend (L x) (L y) = L (x ++ y) main = putStrLn . show $ (L [1,2,3]) `mappend` (L [4,5,6]) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Splitting off many/some from Alternative
On Dec 14, 2011, at 4:40 PM, Ivan Lazar Miljenovic wrote: [...] Apart from some basic combinators in Control.Monad or the definitions of monad transformers, how much of what you write in do-blocks is applicable to some generic Monad instance as opposed to a specific Monad? Well, if my *only* constraint on a type is that it be an instance of Monad, then *all* of the code written in do-blocks will be applicable to a generic Monad instance. That's the whole point. :-) Furthermore, you make it sound like this generic case scenario is incredibly rare, but in fact it is very common: it occurs whenever someone writes a monadic transformer, which happens all the time. Imagine what writing monadic transformers would be like if you couldn't always trust that, say, (=) was a well-defined operation? Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Splitting off many/some from Alternative
On Dec 15, 2011, at 3:37 AM, Bryan O'Sullivan wrote: But that's precisely what the Alternative class is already for! If you are writing an Alternative instance at all, then you are asserting that it must be possible and reasonable to replicate the existing behaviour of some and many. So... in other words, the Maybe and [] instances are wrong, and in an idea world would be removed? As I thought I stated before, I would be perfectly okay with that. The fact that those functions are currently methods of the class is completely irrelevant, and perhaps this is a source of your confusion. They can be - and used to be - implemented as normal functions with Alternative class constraints, then at some point someone moved them into the class itself, solely to allow implementors to write faster versions. Hmm, that's a fair point that I hadn't considered, namely that some and many can always be defined in terms of the other methods so moving them out of the typeclass doesn't make them inaccessible. Thus, splitting them off into a subclass if Alternative would in some sense just be a formality; nonetheless, I think that it would be a useful formality because it would make explicit when these two methods are actually useful. Those who have more efficient versions for some/many can write them manually, and those who don't could just add a line instance Parsive T (or whatever) and be done with it. I think we should take any further discussion off-list. Your messages from last night betray a deep misunderstanding that I'm not sure everyone else needs to sit through :-) I know that you meant no offense, but your remark was essentially just a nicer version of Clearly you simply don't know what you are talking about, so shut up and go away so that those of us who *do* know what we are talking about can be left alone, which comes across as really condescending and offensive. Also, frankly, I haven't seen much of a sign that the community itself has some kind of deep understanding of some/many that I lack. People have been giving me different answers to my question, many of which are not consistent with each other, and some of which seem not to be consistent with themselves. Regarding what to do about Alternative, I have been getting a whole range of answers, including: do nothing but add more documentation, split some/many off from Alternative into a separate subclass, remove instances from Alternative got Maybe and [], etc. So it's not as if there is this obvious and complete picture of what Alternative is or should be about that is available to nearly everyone here but me, an part of the reasons why I have been pushing so hard here is to see if we can work towards a consensus of some kind on this issue. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Splitting off many/some from Alternative
On Dec 15, 2011, at 12:03 PM, Ross Paterson wrote: The current definition says that some and many should be the least solutions of the equations some v = (:) $ v * many v many v = some v | pure [] We could relax that to just requiring that they satisfy these equations (which I think is what John wants). In that case there would be another possible definition for Maybe: some Nothing = Nothing some (Just x) = Just (repeat x) many Nothing = Just [] many (Just x) = Just (repeat x) That is a really good idea! In fact, this behavior was exactly what my intuition had at first suggested to me that these methods should do. But the part that still confuses me is: why are these not considered the least solutions of the equations? Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Splitting off many/some from Alternative
On Dec 15, 2011, at 12:36 PM, Antoine Latter wrote: Although I'm still not sure why I would be using these operations in maybe or list. You probably wouldn't use these operations directly on Maybe or List, but the whole point is that when you are using a typeclass you have cannot assume that you know what they underlying type is. If your algorithm needs to make use of many and some, then as long as the type is an instance of Alternative then you know that you can do this regardless of what the type actually is. If certain types break your algorithm, then the constraint on the type being Alternative is clearly insufficient. I wish that I had a more concrete example of how this could happen in practice off the top of my head --- say, when writing something like an alternative stack transformer (analogous to a monad stack transformer). Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Splitting off many/some from Alternative
On Dec 15, 2011, at 12:52 PM, Brandon Allbery wrote: These statements are not mutually logically consistent, and leave me wondering if Applicative and/or Alternative have been fully thought out. Oh, that particular question is *super*-easy to answer: based on what I've been reading, they *weren't* fully thought out. ;-) It would seem that they were tacked onto the base libraries because people had learned from experience (mostly while writing parser libraries, in the case of Alternative) that they were sufficiently useful in a general setting that doing this made sense at the time. (I am exaggerating a little but that's the general idea.) Mind you, this was not meant to be a criticism at all --- design is an iterative process where at each step you make the best decision that you can based on the available information, hopefully setting yourself up so that at the next step you can make an even better decision. :-) What we seem to be learning now is simply that things that may have seemed obvious years ago are not as obvious now as they had seemed to be at the time. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] [Alternative] some/many narrative
Okay, so how about the following as a user narrative for some and many? many v = repeatedly execute the action v and save each obtained result until v fails; at that point, *succeed* and return a list with all of the results that had been collected some v = like many v, but if v does not succeed even once then *fail* instead of return the empty list Note: If v *never* fails, then at best many/some will return infinite lists, and at worst they will repeat your action forever. Cheers, Greg P.S.: And yes, I know that many of you will complain that these definitions are not mathematically precise or what not, but it is important to be able to build up narratives at a sufficiently high level that they explain the essentials of what is going on for the benefit of users who are unfamiliar with the precise mathematical language used to precisely define their semantics.___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] [Alternative] change some/many semantics
Hey everyone, This is even more out there than my previous posts, but the following just occurred to me: is it absolutely necessary that some/many have produced the entire list of results before returning? Couldn't we change their semantics so that the list of results is computed and/or extracted lazily? For example, if this were the case, then we would have that (some (Just 1)) returns an infinite list rather than running in an infinite loop (even without defining a special case some implementation), which is exactly what my intuition would expect. Of course, this is not a simple change at all because it would have to be done in such a way as to respect the ordering of actions --- that is, we can't have each action executed only when the corresponding element of the list demanded is forced, or else actions would undesirably interleave. For example, in a parser when we use many v we expect everything matching v to be consumed by the time many v returns, but if instead many v only consumed as much of the input as we demanded from its result list then we might see a chunk of input matching v in another part of our parser despite having assumed we'd gotten rid of it, which would cause our parser to be broken. Nonetheless, if there were some way that we could use magic fairy dust to have the results returned by some and many be lazily generated lists, then this might solve many of the problems that come up with them performing infinite loops in cases where it seems like they shouldn't. :-) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] change some/many semantics
On Dec 15, 2011, at 2:13 PM, Antoine Latter wrote: Isn't this what Ross previously suggested? I think his suggested instance methods for Maybe return the elements of the lists incrementally. Yes and no. Yes, his excellent suggestion is one of my favorite ideas for what we should do with Alternative that I have seen so far and was the inspiration for my proposal, but no it is not the same idea at all. Whereas his suggestion keeps the types and generic definitions of some and many the way that they are but overrides them manually to work for types such as Maybe, my proposal is that we instead change the types and generic definitions of some and many themselves so that they automatically do the right thing for the Maybe and List types. To justify my idea in a different way, it seems to me that somehow some and many somehow aren't lazy enough, because if they *were* lazy enough then we wouldn't have to hack into them for some types (Maybe and List) in order to get them to generate the infinite lazy lists that we were expecting. Again, though, this is all crazy talk, and the only way to bring my epic vision into creation might be through abundant use of magic fairy dust. :-) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] change some/many semantics
On Dec 15, 2011, at 3:36 PM, Antoine Latter wrote: That's the interesting thing about type-classes like Alternative and Functor - they mean very little, and are used in widely varying contexts. So... your point is that in the Haskell community we don't tend to care about whether our types, typeclasses, typeclass instances, etc. make any sense at all? Heck, Control.Monad.void has the type signature Functor f a = f a - f () - how many functors is that operator sensible for? All of them. I can't conceive of a single case where this would result in an undefined operation; can you? Furthermore when people write code using monadic combinators they toss out results all the time so this kind of function makes perfect sense. There are a lot of combinators you can build from (|) and empty that go terribly wrong for Maybe and List but are still quite useful. Yes, you *could* do that, but the whole point is that you shouldn't. Typeclasses generally come with informal laws that must be obeyed. If your instance does not obey those laws, then it should not be an instance. Incidentally, exactly what use cases do you have in mind? Even the operators at hand ('many' and 'some') are partial in parsing, but I'm not prepared to throw them out. Okay, I must confess that this straw man has been causing my patience to get a little thing. *Nobody* here is saying that many and some should be thrown out, since there are clearly many contexts where they are very useful. The *most* that has been suggested is that they should be moved into a subclass in order to make it explicit when they are sensible, and that is *hardly* banning them. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] some/many narrative
On Dec 15, 2011, at 4:29 PM, Chris Wong wrote: Okay, so how about the following as a user narrative for some and many? ... I was in the middle of writing my own version of Applicative when I stumbled on this intense debate. Here's what I wrote for the documentation: class (Applicative f, Monoid f) = Alternative f where -- | Keep repeating the action (consuming its values) until it fails, and then return the values consumed. -- -- [Warning]: This is only defined for actions that eventually fail -- after being performed repeatedly, such as parsing. For pure values such -- as 'Maybe', this will cause an infinite loop. some :: f a - f [a] some v = ... -- | Similar to 'many', but if no values are consumed it returns 'empty' instead of @f []@. -- -- [Warning]: This is only defined for actions that eventually fail -- after being performed repeatedly, such as parsing. For pure values such -- as 'Maybe', this will cause an infinite loop. many :: f a - f [a] many v = ... Warnings are repeated for emphasis :) I think that merely putting up documentation along these lines would be a huge improvement, though it should also contain the formal definitions from the old documentation in it somewhere as well. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Splitting off many/some from Alternative
On Dec 13, 2011, at 3:06 AM, Bryan O'Sullivan wrote: There is absolutely no implication of consuming anything in the definitions of many or some. This is how they happen to behave when used in the context of some parsing libraries, but that's all. If many or some always go into an infinite loop for some Alternative instance, then I suspect that the instance itself is either broken or shouldn't exist. Yes of course, so I suppose my point was that when I thought about them in this way their purpose made sense for the first time. :-) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Splitting off many/some from Alternative
On Dec 13, 2011, at 5:09 AM, Bryan O'Sullivan wrote: Correct. And your example of some (Just 1) inflooping was not a counterargument, but rather an illustration that perhaps some people (and I'm not trying to imply you here, don't worry) don't understand what some and many are supposed to do. But if you can't determine whether you can use certain methods of a typeclass without first knowing more about what type you are working with, then that breaks the abstraction since you can no longer treat a typeclass as a promise that given set of methods can be applied to a type. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Splitting off many/some from Alternative
On Dec 13, 2011, at 5:09 AM, Bryan O'Sullivan wrote: Correct. And your example of some (Just 1) inflooping was not a counterargument, but rather an illustration that perhaps some people (and I'm not trying to imply you here, don't worry) don't understand what some and many are supposed to do. But does it really make sense to have class methods with the property that they are undefined on all but a special value of a type? It seems extremely silly to me to keep these two methods in the class and to get around this problem by adding documentation that essentially says, Don't use these methods because they are not actually defined in general. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Splitting off many/some from Alternative
On Dec 14, 2011, at 8:38 AM, Thomas Schilling wrote: On 12 December 2011 22:39, Antoine Latter aslat...@gmail.com wrote: But now they look as if they are of equal importance with the other class methods, which is not really true. Maybe, but something like this is best fixed by improving documentation, not by shuffling things around and needlessly breaking APIs. I also agree that if an Alternative instance doesn't make sense it should be removed. The current documentation is indeed very terse indeed. In particular it needs a section on the pitfalls that users are likely to run into (like infinite loops). It seems that if we go down this route, though, then what we really need is a big, bold warning at the top of the Alternative class saying something like, Do *not* implement this class for your type unless you *really* know what you are doing, which will probably only true if you are writing a parser. If you fail to heed this advice, then many and some will almost assuredly be broken for your type, which will cause code using it to have infinite loops. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Splitting off many/some from Alternative
On Dec 13, 2011, at 3:32 AM, Bryan O'Sullivan wrote: Don't be silly. The purpose of some and many is to be used with combinators that are expected to fail sometimes. If you use them with combinators that always succeed, of course you're going to get an infinite loop. Yes, but how can someone using a typeclass *know* whether a type has values that will always succeed? Apparently the confusion here lies with the fact that the documentation for some and many are too terse for their behaviour to be easily understood. That's a whole different category of problem than ban them!. Nobody has been calling for them to be banned at all --- or at least, I haven't, and I am the one who has started the thread. :-) What we (if I may be so bold as to use the royal we here :-) ) would like would be for these methods to be moved into a separate class. This way users of the classes will know whether their type has well-defined instance for some and many or not. Or, alternatively, we could add documentation making it clear that one should *only* make a type be an instance of Applicative *if* all values of that type will eventually fail in combination, thus ensuring that some and many will always be well defined. Thus, in particular, Maybe would no longer be a well-formed instance of this type, though we might decide to keep it around anyway in order to avoid breaking old code. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Linear types using kinds?
Hey everyone! So, I was on LtU reading about F* http://lambda-the-ultimate.org/node/4318 and an idea just occurred to me which *must* have occurred to someone smarter than me, so I would love your feedback on the following question: Could Haskell be extended to support linear/affine types (in order to have, for example, more efficient resource management) by extending the kind system to include such types? Or, even if the answer were yes, does the use of monads and higher-order types (like those used in runST function for the ST monad) make linear/affine types completely redundant in Haskell. Thanks a lot! Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Splitting off many/some from Alternative
Hey everyone, I am sure that it is too late to do more than idly speculate about this, but could we split the some/many methods out from Alternative? They simply don't make sense except in a subset of possible Alternatives --- in most cases they just result in an infinite loop. That is to say, it is not just that they are extraneous functionality, but most of the time they are *impossible* functionality to even implement! In a way, it is a lie to be including them in Alternative since people making use of the class might incorrectly (but quite reasonably!) assume that any type that is an instance of Alternative *has* a well-defined some and many method, when this is actually the exception rather than the rule. It is only recently that I have been able to grok what some and many are even about (I think), and they seem to only make sense in cases where executing the Alternative action results in a portion of some input being consumed or not consumed. some v means consume at least one v and return the list of items consumed or fail, and many v means consume zero or more v and return the list of items consumed or the empty list of none are consume. It thus makes sense for there to be some subclass of Alternative called something like Consumptive that contains these methods. The majority of Alternative instances would no longer have these methods, and again that would actually be an improvement since in such cases some/many were unworkable and did nothing but cause infinite loops anyway. Normally it would be unthinkable to even consider such a change to the base libraries, but I suspect that there are not more than a couple of packages out there that make active use of the some/many instances of Alternative; it is really only parser packages that need some/many, and users most likely use the versions included with the packages themselves rather than the Alternative version. Could we verify that this is the case, and if so split them away? I thought I heard a trick whereby people were able to grep all the source on Hackage, but I can't remember what it was. :-) Just a thought. :-) Thanks, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Built-in LLVM exception handling
Purely out of curiosity, would it be more efficient for GHC to use the new built-in exception handling instructions in LLVM? http://blog.llvm.org/2011/11/llvm-30-exception-handling-redesign.html Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Hackage feature request: E-mail author when a package breaks
Hey everyone, I have uploaded a number of small packages to Hackage that I no longer actively use so that I don't find out immediately when a new version of GHC has broken them. Since Hackage is going to the trouble of finding out when a package no longer builds anyway, could it have a feature where when a working package breaks with a new version of GHC the author is automatically e-mailed? This would make me (and probably others) a lot more likely to notice and proactively fix broken packages. (Heck, I wouldn't even necessarily mind being nagged about it from time to time. :-) ) Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] MonadPlus versus Alternative
Hey everyone, What is the difference between MonadPlus and Alternative? In my mind, it would make sense for the difference to be that the former provides and semantics (i.e., x `mplus` y means do both x and y) whereas the latter provides or semantics (i.e., x | y means do x or y but not both). However, when I look at the instances defined for List I see that it is exactly the same as MonadPlus. So is there any difference between the interpretation of MonadPlus and Alternative, or is the only difference between them that the former applies to Monad whereas the latter applies to Applicative? Also, along similar lines, why does MonadPlus exist when it is essentially just a special case of Monoid? (That is, any MonadPlus instance could be equivalently cast as a Monoid instance.) Thanks! Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] The Typeable class is changing
On 7/11/11 11:18 AM, Yitzchak Gale wrote: The standard way to create a Typeable instance is just to derive it. If you do that, you will not be affected by this change. This is only the standard way if one is willing to sacrifice Haskell98 or Haskell2010 compatibility by using the non-standard DeriveDataTypeable extension. But it seems that many packages create Typeable instances by explicitly using mkTyCon. If your package does this, it will eventually break, after a deprecation period. I have done this in at least one of my packages (type-level-natural-number) because I wanted to keep my library compatible with Haskell2010 rather than relying on GHC-specific extensions. To be clear, I think that the new Typeable is an improvement and don't mind migrating my package to use it, I just get the sense after reading the linked exchange that those discussing this have just assumed that the standard way to use Typeable *should be* to use deriving Typeable and are missing what I suspect is a major reason why people avoid using it, which is to reduce dependence on GHC-specific extensions. Again, this not a complaint or an objection at all, I'm just sharing my own thoughts on the matter. :-) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Lazy Evaluation in Monads
On 5/31/11 12:49 PM, Scott Lawrence wrote: I was under the impression that operations performed in monads (in this case, the IO monad) were lazy. Whether they are lazy or not depends entirely on the definition of the monad. For example, if you look up the ST and State monads you will find that they come in strict and lazy flavors. As a general rule, operations in the IO monad are strict except for very special cases which are explicitly labeled as such, e.g. unsafeInterleaveIO, lazyIO, etc. FYI, in GHC the definition of IO is at http://www.haskell.org/ghc/docs/7.0.3/html/libraries/ghc-prim-0.2.0.0/src/GHC-Types.html#IO You can tell it is strict because the result of the map is an unboxed tuple, which is strict (at least, if I understand correctly :-) ). If you are curious, State# and RealWorld are defined here: http://www.haskell.org/ghc/docs/7.0.3/html/libraries/ghc-prim-0.2.0.0/src/GHC-Prim.html#State. State# and RealWorld do not contain data constructors because they are not intended to contain data but rather to parametrize types --- that is to say, you can think of IO as being a special case of the strict ST transformer which uses a special type tag to keep different ST threads separate (even though this type is never instantiated), and in the case of IO the state tag is RealWorld. So in short, monads need not be strict but often are, and in particular IO is designed to be strict because it is essentially just a special case of the strict ST monad. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Erlang's module discussion
On 5/28/11 10:11 AM, Alex Rozenshteyn wrote: Since no-one has yet mentioned it, and I think it might be relevant, http://types.bu.edu/seminar-modularity/first-class-modules-for-haskell.pdf I haven't read it with any degree of understanding, but I don't think it's tractable to remove modules from haskell, nor desirable. Aww... I read that paper and got really excited thinking, Wow! I didn't realize that people were working on that; I wonder when I'll get to play with it!, and then I saw the paper was written for a seminar that took place in 2002, so I guess the idea just didn't pan out... Would anyone involved in the matter want be so kind as to fill me in on how that particular story ended (i.e., why everyone gave up it)? Thanks! Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Maybe Int] sans Nothings
On 5/23/11 9:20 AM, michael rice wrote: What's the best way to end up with a list composed of only the Just values, no Nothings? Try catMaybes in Data.Maybe. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Maybe Int] sans Nothings
On 5/23/11 9:29 AM, Max Bolingbroke wrote: On 23 May 2011 17:20, michael rice nowg...@yahoo.com mailto:nowg...@yahoo.com wrote: What's the best way to end up with a list composed of only the Just values, no Nothings? http://haskell.org/hoogle/?hoogle=%3A%3A+%5BMaybe+a%5D+-%3E+%5Ba%5D Data.Maybe.catMaybes is what you want :-) Cheers, Max On 5/23/11 9:25 AM, Malcolm Wallace wrote: On 23 May 2011, at 17:20, michael rice wrote: What's the best way to end up with a list composed of only the Just values, no Nothings? Go to haskell.org/hoogle Type in [Maybe a] - [a] Click on first result. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe On 5/23/11 9:25 AM, Gregory Crosswhite wrote: On 5/23/11 9:20 AM, michael rice wrote: What's the best way to end up with a list composed of only the Just values, no Nothings? Try catMaybes in Data.Maybe. Cheers, Greg GO TEAM HASKELL!!! Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Maybe Int] sans Nothings
On 05/23/2011 12:08 PM, Brent Yorgey wrote: Just a minor quibble: note that filter (not . isNothing) is slightly preferable since it does not introduce a frivolous equality constraint on the type wrapped by the Maybe. Or even better, filter isJust :-) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] *GROUP HUG*
Hey everyone, Okay, this will sound silly, but I ventured into the Scala mailing list recently and asked an ignorant question on it, and I was shocked when people reacted not by enlightening me but by jumping on me and reacting with hostility. I bring this up not to badmouth the Scala community (they are apparently going through growing pains and will hopefully mature with time!) but just because it made me appreciate just how awesome you guys are, so I just feel the need to publicly express my admiration and thank to everyone on this list for having fostered such an incredibly professional, fanatically nonhostile, and generally pleasant place to talk about Haskell!!! *GROUP HUG* Okay, I'm done now. :-) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Status of Haskell + Mac + GUIs graphics
On 5/20/11 8:35 AM, Jeremy O'Donoghue wrote: I would like to suggest, quite seriously, that the Haskell community try to come to a consensus about supporting a single Haskell GUI, with a view to distribution in the HP. Obviously my vote is for wxHaskell, but I'm quite prepared to loose the vote. Reason is that I think we need to concentrate some effort on getting one GUI binding to 'production' status, and I don't believe that on the current basis we will ever do this. From my perspective, only GtkHS and wxHaskell look like serious candidates with at least some history and maturity behind them. If you are going to rule out Qt, then the only good cross-platform option remaining is wx since Gtk is not fully native on OSX but instead uses X11 which results in an inferior user experience, and it would be a bad idea to have that be the standard that everyone associates with applications written in Haskell. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Using cmake with haskell
On 5/14/11 1:25 PM, Maciej Marcin Piechotka wrote: (to mention one which is often neglected - parallel build). While I do appreciate you stepping in to defend autotools (if for no other reason then because someone has to so that the discussion is balanced :-) ), I think that you are wrong to say that autotools is unusual in getting the idea of parallel builds right, since in my experience the opposite is the case: most systems support parallel builds --- such as SCons, CMake, I think waf, etc. --- with Cabal being an outlier here. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Using cmake with haskell
What on earth are you doing that mixes Haskell, C++, Scala, and Python? I am very intrigued by the very idea of such a project. :-) I have to confess that don't care for waf myself because I had unpleasant experiences using it which stemmed in part from its design which I also didn't like. For example, if you don't get the proper complex incantations correct then it will simply fail silently without giving you any hint as to what you might have gotten wrong, even for the most basic of tasks! Also, the last time I looked into waf in depth a couple of years ago the basic task model was designed around a language like C++ where there is a build phase and then a link phase and everything within a phase can be built in any order, so to compile something like Haskell code you need to essentially put every file in its own phase, but the scheduler they used for phases was not optimized at all precisely because they were assuming a C++-like model where there were only a couple of phases; they could have changed this since then, though. But anyway, I am always willing to keep an open mind about tools if someone convinces me that my current negative impressions about them is wrong or outdated, so if you got waf to build a project with all four of those languages then that does definitely give it extra points in my book. :-) Cheers, Greg On 5/14/11 6:12 PM, Nathan Howell wrote: Waf supports parallel builds and works with GHC without too much trouble. I use it in a mixed Haskell, C++, Scala and Python build. If there is interest I could conceivably clean up the ghc waf tool and release it. On Sat, May 14, 2011 at 5:32 PM, Gregory Crosswhite gcr...@phys.washington.edu mailto:gcr...@phys.washington.edu wrote: On 5/14/11 1:25 PM, Maciej Marcin Piechotka wrote: (to mention one which is often neglected - parallel build). While I do appreciate you stepping in to defend autotools (if for no other reason then because someone has to so that the discussion is balanced :-) ), I think that you are wrong to say that autotools is unusual in getting the idea of parallel builds right, since in my experience the opposite is the case: most systems support parallel builds --- such as SCons, CMake, I think waf, etc. --- with Cabal being an outlier here. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org mailto:Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Using cmake with haskell
On 5/11/11 3:11 PM, Bryan O'Sullivan wrote: It's a fairly terrible piece of software. My experience is that it is the only cross-platform build system I have used to date that hasn't made my eyes bleed, though I only use it for C/C++/Fortran. I suppose that counts as a personal testimonial in favor of it. Put another way: it is definitely the worst of all build systems --- except for all the rest. :-) Also, my most recent experience with Cabal is that it is a serious PITA if you want to do any non-trivial cross-language stuff with it, since essentially its only support for non-Haskell stuff is its hard-coded support for C/C++. It is true that you can add hooks to do arbitrary stuff, but at that point you are basically bolting your own build system on top of it and have to start from scratch --- or worse, *autotools* (SHUDDER!) At one point I was working on my own build system Blueprint that was a generalized build system where GHC was just one specific tool within the system, but although I got it working just fine, at some point implementing all of the of the crazy stuff that is needed for proper GHC package support burned me out so I stopped short of finishing it since it's not like I didn't have other things to do with my time. :-) You might ask why I didn't just use the Cabal libraries to help myself out, and while I was able to get some use out of them unfortunately most the functionality in the Cabal libraries is simply not designed to be used by third parties. (For the curious, the sources are available at www.github.com/gcross/blueprint; look at the *blueprint* branch, not the *master* branch which was a first attempt that has been superseded by a complete rewrite.) So anyway, what it comes down to in my experience is 1) Cabal is a tool that can only be used to build Haskell packages with some supporting C/C++ code thrown in and 2) Cabal is currently the only tool that can realistically be used to properly build and install Haskell packages due to the great complexity involved with getting all the details right Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Proving correctness
On 2/11/11 1:25 PM, Luke Palmer wrote: I would like to see a language that allowed optional verification, but that is a hard balance to make because of the interaction of non-termination and the evaluation that needs to happen when verifying a proof. I believe that ATS (short for Advanced Type System) allows this. Although I haven't actually programmed in it, I read through the documentation and it looks to me like it is a fully dependently-typed language that allows you prove as little or as much about your program as you like. http://www.ats-lang.org/ Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type System vs Test Driven Development
On 1/12/11 5:05 AM, Ketil Malde wrote: Of course, ideally you should design your types so that all possible values are meaningful:-) Sadly we cannot all program in Agda. :-) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [darcs-users] Darcs failure
On 12/24/10 4:08 PM, Andrew Coppin wrote: Gotta love the way that this is THE MOST COMMON USE CASE for kill, and yet kill itself doesn't support doing this. The problem with killing processes by name is that names aren't unique, so you might unintentionally end up killing other processes that share the same name. If you want to kill all processes with a given name, then you can use the killall command, which explicitly indicates that you are willing to kill everything with that name. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] IO, sequence, lazyness, takeWhile
Take a look at the monad-loops package. Cheers, Greg On 12/13/2010 06:15 AM, Jacek Generowicz wrote: -- Is it possible to rewrite code written in this style untilQuit = do text - getLine report text if text == quit then return () else untilQuit -- in a style using higher order functions for abstract iteration? For -- example, something along these lines: untilQuit' = (fmap (takeWhile (/= quit))) (sequence $ map (= report) (repeat getLine)) -- The latter version shows the report, but it doesn't stop at the -- appropriate place, so I'm guessing that I'm being bitten by my -- ignorance about the interaction of actions and lazyness. -- For completeness, here's a definition of report report text = do putStrLn $ You wrote ++ text return text ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Wondering if this could be done.
On 11/21/10 10:48 PM, Magicloud Magiclouds wrote: Hi, For example, I have a data A defined. Then I want to add (+) and (-) operators to it, as a sugar (compared to addA/minusA). But * or other stuff defined in class Num is meanless to A. So I just do: (+) :: A - A - A (+) a b = A (elem1 a + elem1 b) (elem2 a + elem2 b) -- I got errors here, for the (+) is ambiguous. So, just wondering, does this way work in Haskell? One solution to this problem is to use slightly modified operators, such as .+. and .-., or anything else that crosses your fancy and is accepted by the compiler. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Impredicative Types
Hey everyone! I haven't had a chance to try out GHC 7 myself, but I saw in the documentation that Impredicative Types are still supported. Is this true? I thought that they were on their way out because they overcomplicated type checking; has this plan been changed? Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Impredicative Types
Awesome, thank you. :-) One more question out of pure curiosity, if you have the time: What is allowing you to keep them in? I thought that the problem was that they made a mess that touched every party of the type checker rather than being centralized in one place. Was there a trick you discovered that now allows you to support them without creating such a mess? Cheers, Greg On 11/19/10 11:45 AM, Simon Peyton-Jones wrote: Yes, impredicative types are still in, but in a simpler form than before, along the lines of QML http://research.microsoft.com/en-us/um/people/crusso/qml/ I have been too busy with getting the new type checker working to describe or document it. Notably, I have not yet added syntax for QML's rigid type annotations, which leads to a loss of expressive power. too much to do! Bottom line: if you are interested in impredicative polymorphism, let me know. A good way to do so would be to register your interest on http://hackage.haskell.org/trac/ghc/ticket/4295 Just add your email address to the cc list, *and* write a comment giving an example of how you are using impredicative poly, and pointing to any further info. That'll help motivate me to do the remaining work! Thanks Simon | -Original Message- | From: haskell-cafe-boun...@haskell.org [mailto:haskell-cafe-boun...@haskell.org] | On Behalf Of Gregory Crosswhite | Sent: 19 November 2010 19:23 | To: Haskell Cafe | Subject: [Haskell-cafe] Impredicative Types | | Hey everyone! I haven't had a chance to try out GHC 7 myself, but I saw | in the documentation that Impredicative Types are still supported. Is | this true? I thought that they were on their way out because they | overcomplicated type checking; has this plan been changed? | | Cheers, | Greg | ___ | Haskell-Cafe mailing list | Haskell-Cafe@haskell.org | http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Impredicative Types
On 11/19/10 12:22 PM, Andrew Coppin wrote: Use the Force I tried, but I'm not yet strong enough in the Force to read citations with my eyes closed. :-( (PS: Thanks for pointing me to the paper, Simon!) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Serialization of (a - b) and IO a
On 11/11/10 12:07 PM, C. McCann wrote: To retain sanity, either types that can be serialized must be marked explicitly (perhaps in the context, similar to having a Data.Typeable constraint) to indicate potential non-parametric shenanigans You mean, like Data.Binary? Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to put a string into Data.Binary.Put
On 11/6/10 6:38 AM, C K Kashyap wrote: Thanks a lot Gregory and Daniel, I think I'll go with the mapM_ (putWord8 . fromIntegral . ord) approach. If your string has any chance of containing Unicode characters then you will want to use the encode function in the module Codec.Binary.UTF8.String in the package utf8-string, so that the code becomes mapM_ putWord8 . encode Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is Curry alive?
On 11/02/2010 08:37 PM, wren ng thornton wrote: Indeed. If your program requires unification or constraint solving then logic programming or constraint programming[1] is the way to go. Would you be kind enough to give me or point me towards a good example of such a case? I've been trying to understand what the point of logic languages is for a while now, but whenever I look at them I have trouble seeing what exactly it is they offer that solves some problems better/more easily than functional languages. Thanks! Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Haskell is a scripting language inspired by Python.
On 11/04/2010 03:30 PM, Lennart Augustsson wrote: KRC, Miranda, and LML all predate Haskell and have list comprehensions. Just because those languages predate Haskell and have list comprehensions doesn't mean that they still couldn't have gotten the idea from Haskel!. After all, I fully anticipate us using the Haskell language in the near future to build a time machine that will allow us to beam some of our insights back to influence earlier programming languages. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is Curry alive?
On 11/04/2010 03:06 PM, Dan Doel wrote: Implementing type inference can be very easy in a logic language, because most of the work in a non-logic language is implementing unification: http://muaddibspace.blogspot.com/2008/01/type-inference-for-simply-typed- lambda.html 3 lines of Prolog to infer types for the simply typed lambda calculus with meta-variables (not counting the operator fixity declarations). I've written something similar in Haskell, and it's more like 80 lines of real code, a lot of which is implementing things that are simply part of Prolog's computation model. -- Dan Cool! Thank you very much; that is exactly the kind of thing I was looking for. :-) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What is simplest extension language to implement?
I haven't ever used it myself, but I've heard good things about Lua, which was designed to be an embedded scripting language for applications: http://www.lua.org/ If you believe the Programming Language Shootout (http://shootout.alioth.debian.org/) it is pretty fast for a dynamic interpreted language, though JavaScript is much faster since the latter has more companies piling work into making it fast. Cheers, Greg On 11/1/10 11:04 PM, Permjacov Evgeniy wrote: Let us think, that we need some scripting language for our pure haskell project and configure-compile-run is not a way. In such a case a reasonably simple, yet standartized and wide known language should be implemented. What such language may be? R(4/5/6)RS ? EcmaScript ? Some other ? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is Curry alive?
On 11/2/10 8:37 PM, wren ng thornton wrote: Though I would suggest you look at the LogicT library instead of using actual lists... Also, you may be interested in reading the LogicT paper[2] or this paper[3] about search combinators in Haskell. Both offer a number of optimizations you should be aware of. I considered it, but wasn't there discussion recently about how LogicT is a lot slower than the list monad? Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Is Curry alive?
Hey everyone, This is a little off-topic, but I just ran into a problem which might benefit from being attacked by a logic language, so I've been looking for a good one to try out --- and hopefully one that has a very efficient implementation since I want to iterate through billions and possibly trillions of nondeterministically generated solutions. I was thinking about using Curry, but it looks to me like the language is dead and hasn't seen much activity for a few years. Does anyone know about whether there is still much going on over there? Or, alternatively, do you have any suggestions regarding other logic language/implementations I should check out? I've also been looking at Prolog but I am having trouble seeing whether I can process N non-deterministic solutions in O(1) space (rather than first generating a O(N) size list), and I checked out Mercury but the documentation for it is a bit sparse. Thanks! Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is Curry alive?
On 11/01/2010 06:19 PM, Richard O'Keefe wrote: On 2/11/2010, at 1:27 PM, Gregory Crosswhite wrote: Hey everyone, This is a little off-topic, but I just ran into a problem which might benefit from being attacked by a logic language, Why not describe the problem? My goal is to exhaustively search through a space in order to categorize all of the elements in that space. This space is combinatorial, so I am looking for a good domain specific language for letting me break up the space into a bunch of generators which can be combined combinatorically to generate the list of elements in the space. What makes the generators non-trivial is that I am choosing them carefully in order to eliminate many symmetries of the problem that effectively result in equivalent/redundant elements of the search space, and a consequence of this is that some generators depend on the results of other generators. The combinatorics of the problem are such that there are about a billion elements in the space if I try tackling a small version of my problem, and a trillion if I try tackling a slightly larger version of my problem. (More background: The elements in this space are choices of quantum measurement operators which are used to implement a quantum error-correcting code, and I am interested in knowing if the code is good or not. My goal is to systematically search through all codes with a small (= 5-6) number of qubits in order to be able to classify all of the possible of error-correcting codes one can implement using that many qubits.) It is worth mentioning that the function I am applying to these elements to compute the desired properties is very fast. I have had benchmarks showing the ability for this function to scan through up to ~ 500,000 elements a second (It helps that it is written in C++ :-) ). Actually, the more that I think about my problem the more that I'm thinking I should just stick with the List monad. This gives me a way to create generators that can rely on the results of other generators and put them all together using the List monad, taking advantage of Haskell's laziness to iterate in O(1) space. Which does raise the question: when is it better to use a logic programming language instead of the list monad? so I've been looking for a good one to try out --- and hopefully one that has a very efficient implementation since I want to iterate through billions and possibly trillions of nondeterministically generated solutions. I think about the practical success of Model Checking, and wonder whether it might be better NOT to iterate through so many. What exactly do you mean by Model Checking? Anyway, there might be more clever ways to eliminate possibilities from my space (other than the ones I have already) but the advantage of having a computer search all of it is that it can scan through all of the millions and even billions of possibilities in a stupid brute-force fashion in less time than it takes for me to come up with a clever way to analyze the space using theoretical analysis. :-) I've also been looking at Prolog but I am having trouble seeing whether I can process N non-deterministic solutions in O(1) space (rather than first generating a O(N) size list), The point of backtracking search is that you need only space for the current candidate solution, not for all solutions visited so far. So much so that the Iterative Deepening family of search algorithms cheerfully *revisit* graph nodes in order to save time over all. Yes, exactly, but my point is that in Prolog I am having trouble figuring out if there is a way to iterate over all of the solutions generated non-deterministically in O(1) space because all of the library functions which run an accumulator over a generated set of results seem to operate by first generating the full list and then accumulating over it which takes O(n) space, which is wasteful since as you point out it should only take O(1) space to do this. However, it is also possible that I misunderstand the semantics of how Prolog works and so things which look like O(n) to me are actually O(1) --- similar to laziness in Haskell. and I checked out Mercury but the documentation for it is a bit sparse. Packl The Mercury documentation I downloaded in March comes to 773 pages. faq.pdf 6 pages library.pdf 470 pages reference_manual.pdf150 pages transition_guide.pdf 10 pages (Mercury for Prolog programmers) user_guide.pdf 137 pages Packing the tutorial into a single HTML file gives another 19 pages. Ralph Beckett's tutorial adds another 53 pages of PDF. So that's 845 pages all up. sparse? a bit sparse? Yes, because although there is a tutorial with the trivial stuff, and a references for people who already know what they are doing, there is not much intermediate-level documentation for someone who understands the basic ideas behind the language
Re: [Haskell-cafe] who's in charge?
Also, this is a complete aside but what the heck. :-) Has anyone else been driven crazy by the way that Java code and libraries are documented? It seems like whenever I try to figure out how to use a piece of Java code, the functionality is spread out over a huge collection of classes and methods so that it is impossible to figure out where things actually happen and how the code is supposed to be used. Am I correct to perceive this as a general trend in Java, or is it just the projects that I looked at and/or my lack of experience in how Java sources and libraries are organize? Cheers, Greg On 10/28/10 9:53 PM, aditya siram wrote: I understand your frustration at not having free tested libs ready-to-go, Java/any-other-mainstream-language programmers tend to expect this and usually get it. If a lack of libs is a dealbreaker for you and you want to use a functional programming language with some of Haskell's advantages (like immutability, lazy data structures and STM) I encourage you to check out Clojure [1] a nicely designed Lisp. It is tightly integrated in to the JVM and you have access to all the Java libs you want. -deech [1] http://clojure.org/ 2010/10/27 Günther Schmidt gue.schm...@web.de mailto:gue.schm...@web.de Hi Malcolm, well if I would like to point out that, for instance, Haskell exists for a lot more than 10 years now, and that, while the language per se rocks, and there are cool tools (cabal) and libraries (list, Set, Map), there still isn't even a mail client library, I wonder whom to escalate this to, and who is going to do something about it. I understand some parties wish to avoid success at all costs, while others, commercial users, benefit from the edge haskell gives them already and which probably can help themselves in case of, again, for instance a missing mail client library. And then there is the ones like me, which also want to benefit from the edge Haskell gives them over users of other languages and want to develop Real World Apps and who cannot easily help themselves in case of a missing mail client library. So while there are many aspects of the future of haskell, who effectively is it that steers the boat? Günther ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org mailto:Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monads and Functions sequence and sequence_
The expression sequence [a,b,c,...] is roughly equivalent to do r_a - a r_b - b r_c - c ... return [r_a,r_b,r_c,...] The expression sequence_ [a,b,c,...] is roughly equivalent to do a b c ... return () Does that help? Cheers, Greg On 10/29/10 10:07 PM, Mark Spezzano wrote: Hi, Can somebody please explain exactly how the monad functions sequence and sequence_ are meant to work? I have almost every Haskell textbook, but there's surprisingly little information in them about the two functions. From what I can gather, sequence and sequence_ behave differently depending on the types of the Monads that they are processing. Is this correct? Some concrete examples would be really helpful. Even references to some research papers that explain the rationale behind these (and all the other..?) monad functions would be great. Thanks in advance, Mark Spezzano ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Edit Hackage
On 10/28/10 12:34 PM, Andrew Coppin wrote: More specifically, I copied the Cabal description from another package and then updated all the fields. Except that I forgot to update one. And now I have a package which I've erroneously placed in completely the wrong category. I am glad to hear that I am not the only one who has done this. :-) I second the notion that it would nice to be able to tweak the meta-data of a package after uploading it. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] who's in charge?
Or if you want to keep the advantages of a powerful type system, you can use Scala. Cheers, Greg On 10/28/10 9:53 PM, aditya siram wrote: I understand your frustration at not having free tested libs ready-to-go, Java/any-other-mainstream-language programmers tend to expect this and usually get it. If a lack of libs is a dealbreaker for you and you want to use a functional programming language with some of Haskell's advantages (like immutability, lazy data structures and STM) I encourage you to check out Clojure [1] a nicely designed Lisp. It is tightly integrated in to the JVM and you have access to all the Java libs you want. -deech [1] http://clojure.org/ 2010/10/27 Günther Schmidt gue.schm...@web.de mailto:gue.schm...@web.de Hi Malcolm, well if I would like to point out that, for instance, Haskell exists for a lot more than 10 years now, and that, while the language per se rocks, and there are cool tools (cabal) and libraries (list, Set, Map), there still isn't even a mail client library, I wonder whom to escalate this to, and who is going to do something about it. I understand some parties wish to avoid success at all costs, while others, commercial users, benefit from the edge haskell gives them already and which probably can help themselves in case of, again, for instance a missing mail client library. And then there is the ones like me, which also want to benefit from the edge Haskell gives them over users of other languages and want to develop Real World Apps and who cannot easily help themselves in case of a missing mail client library. So while there are many aspects of the future of haskell, who effectively is it that steers the boat? Günther ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org mailto:Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] concurrency vs. I/O in GHC
On 10/23/10 7:54 AM, John Lato wrote: On Fri, Oct 22, 2010 at 6:16 PM, Bulat Ziganshin bulat.zigans...@gmail.com mailto:bulat.zigans...@gmail.com wrote: Hello John, Monday, October 18, 2010, 8:15:42 PM, you wrote: If anyone is listening, I would very much like for there to be a mechanism by which external functions can be called unsafe-ly, but without blocking all other Haskell threads. I have code that does this: +RTS -N2 This doesn't work, which was why the OP asked in the first place. When a thread calls an unsafe foreign function, it blocks everything until that function returns. Is that true? The last time we discussed this in Haskell Cafe the conclusion I drew from the discussion was that unsafe foreign functions block the current thread but not any other thread. Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] concurrency vs. I/O in GHC
On 10/23/10 12:57 PM, Claude Heiland-Allen wrote: On 23/10/10 17:42, Gregory Crosswhite wrote: On 10/23/10 7:54 AM, John Lato wrote: On Fri, Oct 22, 2010 at 6:16 PM, Bulat Ziganshin This doesn't work, which was why the OP asked in the first place. When a thread calls an unsafe foreign function, it blocks everything until that function returns. Is that true? The last time we discussed this in Haskell Cafe the conclusion I drew from the discussion was that unsafe foreign functions block the current thread but not any other thread. The conclusion I drew was that unsafe foreign functions block the current capability (OS thread) and any threads (Haskell forkIO etc) currently scheduled on that capability, but other capabilities and threads continue executing as normal. Yes, that is what I really meant to say; thank you for using the correct words. :-) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Template Haskell: onward and upward
Since you are proposing creating an abstract type TExp that can't be created manually in contrast to Exp, I have a question that might simply be a reflection of ignorance on my part on how TH works now. As far as I can tell by looking through the documentation, when I want to create an identifier with a computed name I have to build up the AST manually rather than by using quoters since there is no way to splice an identifier name into a quoter. Does this mean that it will not be possible to construct a TExp with a computed identifier name, since one can only use the quoter syntax and not manual construction? Thanks, Greg On 10/18/10 3:02 PM, Simon Peyton-Jones wrote: Folks Following lots of feedback from users, especially at ICFP, I've evolved some proposals for Template Haskell, that should make it both more expressive, and more secure. http://hackage.haskell.org/trac/ghc/blog/Template%20Haskell%20Proposal Do let me know what you think. Discussion by email is fine (cc me if it's on Haskell-cafe), or comments direct on the Trac. (None of this will be in GHC 7.0; it's a proposed plan for post-release improvements.) Thanks Simon ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe