Re: [Haskell-cafe] What Haskell Records Need
Evan Laforge wrote: I consider that a strength of the lens approach. If I say 'set (a.b.c.d) 42 record', 'a', 'b' etc. don't have to be record fields, I can swap them out for other lenses later on. I can also easily precompose, e.g. 'setThis = a . b; setThat = b . c' and encourage people to use the composed ones (or require via export lists). This corresponds to asking in that it introduces a point of abstraction where I can change all access / modification in one place, or a module can retain control by only exporting the composed version. The same is true with SEC functions: personsSalary' :: (Salary - Salary) - Person - Person personsSalary' = job' . salary' Here I've created a new updater that is composed of 2 that are generated for me (from the examples given in the original email). I can export whichever of these functions I like, generated or otherwise, and keep as much abstraction as I like! The nice part about the SEC functions is that they compose as regular functions. Lenses are super powerful in that they form a category. Unfortunately using categories other than functions feels a tad unwieldy because you have to hide something from prelude and then import Category. (A bit like exceptions, currently). If you like the look of set with lenses, you could define a helper function to use with SEC updaters. set :: ((b - a) - c) - a - c set sec = sec . const --and then use it like so: setPersonsSalary :: Salary - Person - Person setPersonsSalary salary = set personsSalary' salary With it you can use an updater as a setter. I'd like to reiterate one of finer points of the original proposal. The compiler could disallow using old-style update syntax for fields whose SEC update function is not in scope, giving us fine-grained control over access and update. On the other hand we currently have to create new functions to achieve this (exporting the getter means exporting the ability to update [using update syntax] as well, currently). And now back to lenses: it is really convenient how lenses let you compose the getter and setter together. I don't recall too many cases where having the getter and setter and modifier all in one place was terribly useful. Could anyone give me an example? But again, where that is useful, a lens can be created from a getter and a SEC updater. Thoughts? --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What Haskell Records Need
Richard O'Keefe Said: Ouch! And that's not even very deeply nested. Imagine 4 or 5 levels deep. It really makes Haskell feel clunky next to `a.b.c.d = val` that you see in other languages. I was taught that this kind of thing violates the Law of Demeter and that an object should not be mutating the parts of an acquaintance's parts, but should ask the acquaintance to do so. I'd say that a.b.c.d = val is at the very least a sign that some encapsulation did not happen. Absolutely! But in Haskell how do you do the asking? I guess that's what I'm proposing is a built in way of doing just that! I'm shooting for as-easy-as the built in getters. Erik Hesselink said: Isn't this exactly the problem solved by all the lens packages? Yes it is. I think the existence of these packages along with all the proposals to change records is an indication that something is missing from the language as a whole. What I'm proposing is that the language give you something that is lightweight and easy to use to address this issue. You can still use lenses on top of all of this. makeLens myField myField' If I remember correctly, one of the problems with lenses is that they cannot support polymorphic updates (updates which change a type variable of the data). SEC functions, on the other hand support polymorphic updates. --Jonathan On Thu, Aug 2, 2012 at 4:48 AM, Andrew Butterfield andrew.butterfi...@scss.tcd.ie wrote: Ah yes - the joy of Haskell It so easy to roll your own, rather than search to find someone else's (better/more elegant) solution... :-) On 2 Aug 2012, at 11:41, Erik Hesselink wrote: On Thu, Aug 2, 2012 at 12:30 PM, Andrew Butterfield andrew.butterfi...@scss.tcd.ie wrote: On 2 Aug 2012, at 09:25, Erik Hesselink wrote: Isn't this exactly the problem solved by all the lens packages? Current popular ones are fclabels [0] and data-lens [1]. [0] http://hackage.haskell.org/package/fclabels [1] http://hackage.haskell.org/package/data-lens Not sure what all of these do, but I have a simple solution I use in my work: They do exactly that. They create 'lenses' which are getters/setters/modifiers combined, and allow you to compose these to get/set/modify deep inside nested data types. Look at the examples in the fclabels documentation [2] for more details. [2] http://hackage.haskell.org/packages/archive/fclabels/1.1.4/doc/html/Data-Label.html Andrew Butterfield Tel: +353-1-896-2517 Fax: +353-1-677-2204 Lero@TCD, Head of Foundations Methods Research Group Director of Teaching and Learning - Undergraduate, School of Computer Science and Statistics, Room G.39, O'Reilly Institute, Trinity College, University of Dublin http://www.scss.tcd.ie/Andrew.Butterfield/ ___ 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
[Haskell-cafe] What Haskell Records Need
Greetings, tl;dr - What Haskell Records need are semantic editor combinators for free. I know this is yet another Record proposal among many, but none of them out there strike me as being exactly what I want in Haskell. Take the following types from a contrived example. type Salary = Integer data Job = Job { title :: String , salary :: Salary } data Person = Person { name :: String , job :: Job } Since I've used record syntax, I get getter/accessor functions (title, salary, name, job) for free. Now suppose I want to create an aggregate getter function: return the salary of a given person. Piece of cake, it's just function composition getSalary :: Person - Salary getSalary = salary . job Done! Now suppose I want to write a setter/mutator function for the same nested field setSalaryMessy :: Salary - Person - Person setSalaryMessy newSalary person = person { job = (job person) { salary = newSalary } } Ouch! And that's not even very deeply nested. Imagine 4 or 5 levels deep. It really makes Haskell feel clunky next to `a.b.c.d = val` that you see in other languages. Of course immutability means that the semantics of Haskell are quite different (we're creating new values here, not updating old ones) but it's still common to model change using these kinds of updates. What if along with the free getters that the compiler generates when we use record syntax, we also got semantic editor combinator (SEC) functions[0] that could be used as follows? setSalary newSalary = job' $ salary' (const newSalary) giveRaise amount = job' $ salary' (+amount) givePercentRaise percent = job' $ salary' (*(1+percent)) For each field x, the compiler generates a function x' (the tic is mnemonic for change). These little functions aren't hard to write, but they're classic boilerplate. job' :: (Job - Job) - Person - Person job' f person = person {job = f $ job person} salary' :: (Salary - Salary) - Job - Job salary' f job = job { salary = f $ salary job} These type of utility functions are a dream when working with any reference type or State Monad. modify $ givePercentRaise 0.25 The compiler could also generate polymorphic SEC functions for polymorphic fields. Further, the compiler could disallow using old-style update syntax for fields whose SEC update function is not in scope, giving us fine-grained control over access and update. On the other hand we currently have to create new functions to achieve this (exporting the getter means exporting the ability to update as well, currently). Of course this doesn't address the namespacing issues with records, but it is likely nicely orthogonal to other proposals which do. Also note that there's a package on hackage [1] that will generate SEC functions using TH. It's nice, but I prefer the style of field names used above for updaters (field' vs editField). Let me know what you think. I'll write up an official proposal if there's a bit of general interest around this. Thanks for reading, --Jonathan [0] - http://conal.net/blog/posts/semantic-editor-combinators [1] - http://hackage.haskell.org/packages/archive/sec/0.0.1/doc/html/Data-SemanticEditors.html ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Best way to build a GHC backend?
Thanks for all the Info, Brent! I wasn't aware of many of those projects. I agree that contributing to an existing project is a better idea than doing something new. I suppose I was hoping there would be an official GHC JavaScript backend so that it would be clear which of the efforts to contribute to (and use). -J Arthur On Mon, Jul 9, 2012 at 8:38 AM, Brent Yorgey byor...@seas.upenn.edu wrote: On Sun, Jul 08, 2012 at 09:21:08AM -0600, Jonathan Geddes wrote: I agree that the Raison d'être for a .NET or JVM backend is interop. Perhaps that's not worth the effort of an entirely new backend. JavaScript is a different beast, however. I said before: From my point of view, languages that cannot run on one of the 3 aforementioned platforms will become irrelevant. (with the exception of C, of course). I'll take that one step further and say that for web applications it is becoming increasingly difficult to justify using a language that WILL NOT run both client and server. JavaScript (with NodeJS), Clojure (with ClojureScript), and Dart are just a few examples. I really believe that with a solid JavaScript backend, Haskell would be an ideal web application language. Am I alone in that belief? What can I do to get the ball rolling on that? I should point out that the ball already IS rolling -- ranging from EDSLs that compile to JavaScript [1,2] to macro systems [3] to more serious full-featured efforts [4,5]. There's even a wiki page listing all these and more [6]. The yesod developers share your view that Haskell would benefit from some sort of JavaScript backend; see [7] as well as the ensuing discussion on Reddit [8]. See also Elm [9], which compiles to HTML+CSS+JavaScript and has some Haskell integration [10]. Rather than trying to start yet another effort, what about contributing to one of these ongoing ones? -Brent [1] http://www.ittc.ku.edu/csdlblog/?p=88 [2] http://www.ittc.ku.edu/csdl/fpg/node/125 [3] http://www.haskell.org/haskellwiki/JMacro [4] http://uu-computerscience.github.com/uhc-js/ [5] https://github.com/ghcjs/ghcjs [6] http://www.haskell.org/haskellwiki/The_JavaScript_Problem [7] http://www.yesodweb.com/blog/2012/04/client-side [8] http://www.reddit.com/r/haskell/comments/sm72n/client_side_yesod_an_frpinspired_approach/ [9] http://elm-lang.org/ [10] http://www.reddit.com/r/haskell/comments/uugne/announcing_elm_02_haskell_integration_yesod/ ___ 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] Best way to build a GHC backend?
I agree that the Raison d'être for a .NET or JVM backend is interop. Perhaps that's not worth the effort of an entirely new backend. JavaScript is a different beast, however. I said before: From my point of view, languages that cannot run on one of the 3 aforementioned platforms will become irrelevant. (with the exception of C, of course). I'll take that one step further and say that for web applications it is becoming increasingly difficult to justify using a language that WILL NOT run both client and server. JavaScript (with NodeJS), Clojure (with ClojureScript), and Dart are just a few examples. I really believe that with a solid JavaScript backend, Haskell would be an ideal web application language. Am I alone in that belief? What can I do to get the ball rolling on that? --J Arthur ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Best way to build a GHC backend?
Venerable Haskell Hackers, I love Haskell and think it should run everywhere. Now supposing I would like to build another backend for GHC, perhaps for Java Bytecode, .Net CIL, or JavaScript, What would be the best way to approach that? I can think of a few options: 1. Produce External Core with -fext-core and compile that with a completely separate compiler 2. Use the GHC apis to build a compiler that reuses a load of GHC's code, but has it's own backend 3. Add a new backend directly into GHC Any other options? While I'm on the subject, why has Haskell not been ported to the likes of the JVM, .NET CLR, or JavaScript? Are Haskell's non-strict semantics just too different from the semantics of these other platforms? SPJ is known for saying that Haskell's plan for world domination is support for many parallelism/concurrency idioms. I believe running on many platforms is just as important. From my point of view, languages that cannot run on one of the 3 aforementioned platforms will become irrelevant. (with the exception of C, of course). Thoughts? --J Arthur ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ghci session slows down over time.
Thanks for the responses. I am using GHC 7.4.1 an Ubuntu. Shutting down and restarting ghci is my current workaround. I was hoping for something a bit less disruptive. :kickoffGC or something like that. --J Arthur On Mon, Jun 25, 2012 at 6:54 AM, Ketil Malde ke...@malde.org wrote: Jonathan Geddes geddes.jonat...@gmail.com writes: Is this a known issue? More importantly, is there a known workaround? My experience is that ghci (typically run as an inferior Emacs process) often retains a lot of memory. Thus, I occasionally kill and restart it. (Not sure if that counts as a workaround :-) -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ghci session slows down over time.
Haskell Cafe, I'm seeing crazy amounts of slowdown in a ghci session after just a few executions of :r (reload). Using :set +r (revert top-level bindings) doesn't seem to help. Is it possible that the dynamically-loaded object code is not being garbage collected? Is this a known issue? More importantly, is there a known workaround? Thanks, --J Arthur ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Martin Odersky on What's wrong with Monads
Cafe, I was watching a panel on languages[0] recently and Martin Odersky (the creator of Scala) said something about Monads: What's wrong with Monads is that if you go into a Monad you have to change your whole syntax from scratch. Every single line of your program changes if you get it in or out of a Monad. They're not polymorphic so it's really the old days of Pascal. A monomorphic type system that says 'well that's all I do' ... there's no way to abstract over things. [0, 53:45] Thoughts? --J Arthur [0] - http://css.dzone.com/articles/you-can-write-large-programs ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How do people still not understand what FP is about? What are we doing wrong?
I believe you are observing and commiserating over what Paul Graham famously refers to as the blub paradox[0]. Here is the problem from my perspective. It is a bootstrapping problem: you have to think FP is good to invest the time to learn it, but you have to invest a lot of time to learn it before you think it's good. This may be why FP has found a place in academia--loads of smart people who want to learn for the shear joy of learning. In my experience, it is often useful to provide a person with another motive to learn FP. If you can get them to learn anything at all, you can hope to get the bootstrapping process going. For example, one friend of mine really enjoys a good debate, but he really couldn't argue with me when it came to FP and so he went off to learn it. Now we argue about Haskell vs Scala for much more time than is productive, but he is sold on FP. In another case a junior programmer asked me how he could be more productive and I told him to learn FP. Anyway, I don't think things are not as bleak as you might think. See, for example [1]'s headline for the month of June. While not exactly scientific, it is encouraging. [0] - http://www.paulgraham.com/avg.html [1] - http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html -J Arthur On Mon, Jun 18, 2012 at 1:59 PM, Ben Kolera ben.kol...@gmail.com wrote: Saw this float by in twitter, and it made me a bit sad. Obviously this is still a large misunderstanding of FP in the larger programming community and it make me wonder what we FP enthusiasts are doing wrong to not get the message out to people. Programming languages that require random senseless voodoo to get an effect are awesome. Let's make programming hard through poor design. [1] The sad thing about this is that the inverse of this has more truth to it; that languages that allow people to intersperse side effects anywhere in their computation without thought are flawed by design and allow programmers to do stupid things that hinder the composability, thread safety and ability to reason of/about their code. Has anyone had any experience / success with convincing people that the senseless voodoo is actually a boon rather than a bane? Is it even worth trying to convince people so set in their ways? ( Sorry if this is even too off-topic for the cafe. Just needed a place to vent my frustration at this. ) Cheers, Ben [1] https://twitter.com/cwestin63/status/214793627170390018 ___ 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] Requesting Feedback: I Love Haskell, but can't find a place to use it
Thanks for the responses, everyone. J. W. wrote: have you considered your head as such a place that should be easy to find. even just for specifying things, Haskell is tremendously useful. even if you don't write programs, but just their types. you can express your software design that way, and have it formally verified (by the compiler's type checker). Yes! And in fact this is exactly how I use Haskell now (aside from little scripts and such). It has had a HUGE effect on the way I write software. There have been a number of times that a colleague has asked what a strange comment was in my Java[Script] code. When I tell them that the funny looking one-liner is the Haskell equivalent of the following 30+ Java[Script] lines, they are incredulous, to say the least. But taking that beautiful Haskell one-liner and manually transcribing it into an imperative language feels like being a human compiler. My favorite example of this was the use of the power set in JavaScript: //powerSet = filterM (const [True, False]) and then a few dozen JavaScript lines it compiled down to via the human compiler. --J Arthur On Thu, May 31, 2012 at 8:41 AM, Ivan Perez ivanperezdoming...@gmail.comwrote: On 31 May 2012 01:30, Jonathan Geddes geddes.jonat...@gmail.com wrote: I love Haskell. It is my absolute favorite language. But I have a very hard time finding places where I can actually use it! This has been bugging me for years and, like you, I think we ought to lean towards web-pages and mobile devices. Yesod has been a tremendous push forward in this direction but, as you already stated, the browser and android devices remain mostly unexplored in Haskell. Here's my bit: - There's a port of ghc for iphone. - There's frege (http://code.google.com/p/frege/), a non-strict, pure, functional programming language in the spirit of Haskell. - I've been working as a freelance developer for some time now. I focus on desktop apps in Haskell. I can't say I'm overwhelmed by the amount of offers (speaking of which, if anyone needs a freelance haskell developer,... ahem), but this area will not be clinically dead as long as we cannot use web applications knowing (99% sure) that the owner of the website cannot use our personal information for any purpose other than giving us our service. There's only two kinds of clients here, though: those that explicitly want Haskell, and those than don't care about the programming language. Otherwise, you'll have to sell Haskell and, personally, I'm not that good a salesman (10% success, tops). - I've also ported Haskell designs to other programming languages (with small adaptations). I only found this cost-effective because the code in Haskell was not going to be thrown away. Good luck. Please, let us know what you find. Cheers, Ivan. I had hoped that compiling Haskell to C with -fvia-C (or would it be just -C?) would allow Haskell to run in new, uncharted territory such as Android (with NDK), IOS, Google's NaCl, etc. But today I learned that GHC's C backend has been deprecated! Is it more difficult than I am imagining to get Haskell to work in these environments? Is it simply a matter of low interest in this kind of work? Or something more fundamental? Am I missing something? I'm hoping that the Haskell-JavaScript efforts will mature enough to make Haskell viable for client-side web apps. (I think the first sign of this will be a self-hosting Haskell-JavaScript compiler.) I use Haskell for Server-Side code with various web frameworks, but over the years more and more of the app logic is moved into client-side JavaScript, leaving the server-side code as little more than a simple validation and security layer over the database and other services. Haskell doesn't have any trouble with this, of course, but it's not exactly a role where it can shine. (Of course this is not true of ALL server-side code, just the kind of apps I have been writing.) So anyway I'd like to request feedback: where can I use Haskell besides simple CLI utilities, dull server code, or project Euler problems? Even if it's just to contribute to getting Haskell in the environments mentioned above, any feedback is welcome! Thanks for reading, --J Arthur ___ 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
[Haskell-cafe] Most Important GHC extensions to learn/use?
Haskell Hackers, I'm pretty comfortable with all of Haskell 98 (and 2010, really). But I've always sort of avoided extensions. I realize that this is a bit silly and if I want to continue learning, it probably means delving into the extensions. Which ones are the most important to know from a practical point of view? And which ones from a {Language,Category,Math}-theoretical point of view? (Any other interesting/important points of view I'm missing? :D ) As always, thanks for the feedback. Cheers, --J Arthur ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Most Important GHC extensions to learn/use?
Thanks, Wren, I really appreciate the detailed response! Though I am surprised that Template Haskell isn't on your list. From the little I know of TH it seems like all of the interesting generic/generative stuff is done with TH. Do the other extensions subsume the need for TH, or is it just not terribly interesting? --J Arthur On Thu, May 31, 2012 at 10:29 PM, wren ng thornton w...@freegeek.orgwrote: On 5/31/12 7:15 PM, Jonathan Geddes wrote: Haskell Hackers, I'm pretty comfortable with all of Haskell 98 (and 2010, really). But I've always sort of avoided extensions. I realize that this is a bit silly and if I want to continue learning, it probably means delving into the extensions. Which ones are the most important to know from a practical point of view? And which ones from a {Language,Category,Math}-** theoretical point of view? (Any other interesting/important points of view I'm missing? :D ) There are a bunch which are mostly just syntax changes. The important ones are: ForeignFunctionInterface (aka FFI) Not technically part of H98, though it was a quick addition. It is part of H2010, so it's not really an extension anymore. ScopedTypeVariables This one's really easy, and in the cases where you want it you really really want it. KindSignatures This one's simple, and it helps expose you to the idea of kinds, which is helpful for what's to come. TypeOperators This one's trivial, but it makes things a bit prettier. FlexibleContexts, FlexibleInstances These are essential for actually using MPTCs (described below). IMO they should be enabled automatically whenever MPTCs are on. And there are also a bunch of ones about extending the deriving mechanic to work with new classes or with newtypes. Then there are the ones that actually change the language in a significant way. I'd say the critical ones to learn are: RankNTypes (or Rank2Types if you're squeamish) This is used in lots of nice tricks like list fusion. Learning list fusion is a good place for the H98 veteran to explore next, since it's easy to pick up and has many applications outside of just doing list fusion. Also, it's been around forever and isn't going anywhere anytime soon. MultiParamTypeClasses (aka MPTCs) This has been around forever, and is considered standard Haskell by most people, even though it hasn't made it into the Report yet (due the the fundeps vs TFs issue). FunctionalDependencies (aka fundeps) This is helpful for making certain MPTCs usable without too many type signatures. Also, it's good for understanding the fundeps vs TFs issue. Also, this one has been around forever, and although it's fallen into disfavor it is still indispensable due to limitations in TFs. TypeFamilies (aka TFs) These are really nifty and they're all the rage these days. In a formal sense they're equivalent to fundeps, but in practice they're weaker than fundeps. GADTs These are really nifty and they're all the rage these days. Though beware, GADTs are a rabbit hole leading off to the world of dependent types. You should be aware of the basic ideas here, though don't worry too much about the theory (unless you want to spend a lot of time worrying about the theory). -- Live well, ~wren __**_ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/**mailman/listinfo/haskell-cafehttp://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] Requesting Feedback: I Love Haskell, but can't find a place to use it
I love Haskell. It is my absolute favorite language. But I have a very hard time finding places where I can actually use it! I had hoped that compiling Haskell to C with -fvia-C (or would it be just -C?) would allow Haskell to run in new, uncharted territory such as Android (with NDK), IOS, Google's NaCl, etc. But today I learned that GHC's C backend has been deprecated! Is it more difficult than I am imagining to get Haskell to work in these environments? Is it simply a matter of low interest in this kind of work? Or something more fundamental? Am I missing something? I'm hoping that the Haskell-JavaScript efforts will mature enough to make Haskell viable for client-side web apps. (I think the first sign of this will be a self-hosting Haskell-JavaScript compiler.) I use Haskell for Server-Side code with various web frameworks, but over the years more and more of the app logic is moved into client-side JavaScript, leaving the server-side code as little more than a simple validation and security layer over the database and other services. Haskell doesn't have any trouble with this, of course, but it's not exactly a role where it can shine. (Of course this is not true of ALL server-side code, just the kind of apps I have been writing.) So anyway I'd like to request feedback: where can I use Haskell besides simple CLI utilities, dull server code, or project Euler problems? Even if it's just to contribute to getting Haskell in the environments mentioned above, any feedback is welcome! Thanks for reading, --J Arthur ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Some thoughts on Type-Directed Name Resolution
modifyConfig :: (Config - a) - (a - a) - Config - Config modifyConfig fr fv a = a { fr = fv (fr a) I like this Idea. The only problem I see is this: if I'm trying to write code that is very generic and abstract, how does the compiler know if the update a { fr = 5 } is targeting a field fr of the record a, or a variable fr, which is in scope and points to a first-class field. The difference depends on the record in question, so the code would work differently depending on the context. I would think it would have to be something like a { :fr = 5 } or something else syntactically distinct from current record update syntax. With this and a few more conveniences on record syntax, lenses could go away. For example, I'd love to see a lambda update syntax. For example instead of: setName n r = r {name = n} we'd write setName n = \{name = n} I'd also like to see an Update field by syntax. Instead of addMr r = r { name = Mr. ++ (name r) } we'd write addMr r = r { name = (Mr. ++) } or combining the previous 2: addMr = \{name=(Mr. ++)} feels very terse and Haskelly to me. Regards, --J Arthur ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Get a variable's type in quasiquote
Cafe, I'm playing around with Template Haskell, specifically QuasiQuotes and I've run into something that I hope is not an inherent limitation in TH. Specifically I want to get the type of a variable whose name is used in a QuasiQuote. The code generated by the QQ should depend on the type of the variables that are to be antiquoted. For example let a = True in [qq | a |] should result in different code being generated by the qq than let a = 42 in [qq | a |] because the type of variable a is different. So far I've tried simple reification, but quote = do let varname = someVariableKnownToExist info - reify $ mkName str ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Get a variable's type in quasiquote
Oops I didn't get to finish... accidentally sent. Here's the completed version: I'm playing around with Template Haskell, specifically QuasiQuotes and I've run into something that I hope is not an inherent limitation in TH.Specifically I want to get the type of a variable whose name is used in a QuasiQuote. The code generated by the QQ should depend on the type of the variables that are to be antiquoted. For example let a = True in [qq | a |] should result in different code being generated by the qq than let a = 42 in [qq | a |] because the type of variable a is different. So far I've tried simple reification quote str = do let varname = someVariableKnownToExist info - reify $ mkName str ... but this results in `someVariableKnownToExists' is not in scope at a reify any thoughts? --J Arthur ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type System vs Test Driven Development
Cafe, In every language I program in, I try to be as disciplined as possible and use Test-Driven Development. That is, every language except Haskell. There are a few great benefits that come from having a comprehensive test suite with your application: 1. Refactoring is safer/easier 2. You have higher confidence in your code 3. You have a sort of 'beacon' to show where code breakage occurs Admittedly, I don't believe there is any magical benefit that comes from writing your tests before your code. But I find that when I don't write tests first, it is incredibly hard to go back and write them for 'completed' code. But as mentioned, I don't write unit tests in Haskell. Here's why not. When I write Haskell code, I write functions (and monadic actions) that are either a) so trivial that writing any kind of unit/property test seems silly, or are b) composed of other trivial functions using equally-trivial combinators. So, am I missing the benefits of TDD in my Haskell code? Is the refactoring I do in Haskell less safe? I don't think so. I would assert that there is no such thing as refactoring with the style of Haskell I described: the code is already super-factored, so any code reorganization would be better described as recomposition. When recomposing a program, its incredibly rare for the type system to miss an introduced error, in my experience. Am I less confidence in my Haskell code? On the contrary. In general, I feel more confident in Haskell code WITHOUT unit tests than code in other languages WITH unit tests! Finally, am I missing the error beacon when things break? Again I feel like the type system has got me covered here. One of the things that immediately appealed to me about Haskell is that the strong type system gives the feeling of writing code against a solid test base. The irony is that the type system (specifically the IO monad) force you to structure code that would be very easy to test because logic code is generally separated from IO code. I explained these thoughts to a fellow programmer who is not familiar with Haskell and his response was essentially that any language that discourages you from writing unit tests is a very poor language. He (mis)quoted: compilation [is] the weakest form of unit testing [0]. I vehemently disagreed, stating that invariants embedded in the type system are stronger than any other form of assuring correctness I know of. I know that much of my code could benefit from a property test or two on the more complex parts, but other than that I can't think that unit testing will improve my Haskell code/programming practice. Am I putting too much faith in the type system? [0] http://blog.jayfields.com/2008/02/static-typing-considered-harmful.html ___ 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
The Haskell type system is simply not rich enough to guarantee everything you might need. That's true, and after giving this a bit more thought, I realized it's not JUST the type system that I'm talking about here. There are a few other features that make it hard for me to want to use unit/property tests. For example, say (for the sake of simplicity and familiarity) that I'm writing the foldl function. If I were writing this function in any other language, this would be my process: first I'd write a test to check that foldl returns the original accumulator when the list is empty. Then I would write code until the test passed. Then I would move on to the next property of foldl and write a test for it. Rinse repeat. But in Haskell, I would just write the code: foldl _ acc [] = acc The function is obviously correct for my (missing) test. So I move on to the next parts of the function: foldl _ acc [] = acc foldl f acc (x:xs) = foldl f (f acc x) xs and this is equally obviously correct. I can't think of a test that would increase my confidence in this code. I might drop into the ghci repl to manually test it once, but not a full unit test. I said that writing Haskell code feels like writing code against a solid test base. But I think there's more to it than this. Writing Haskell code feels like writing unit tests and letting the machine generate the actual code from those tests. Declarative code for the win. Despite all this, I suspect that since Haskell is at a higher level of abstraction than other languages, the tests in Haskell must be at a correspondingly higher level than the tests in other languages. I can see that such tests would give great benefits to the development process. I am convinced that I should try to write such tests. But I still think that Haskell makes a huge class of tests unnecessary. Haskell has some awesome testing tool, and I highly recommend getting acquainted with them. I will certainly take your advice here. Like I said, I use TDD in other languages but mysteriously don't feel its absence in Haskell. I probably need to get into better habits. --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Template Haskell a Permanent solution?
On Tue, Dec 28, 2010 at 8:17 AM, Tillmann Rendel ren...@mathematik.uni-marburg.de wrote: This seems simple enough to me, so it looks as if your use case is already supported as a library on top of the more general API. This is exactly what I was looking for, and much simpler than my previous experiences with quasiQuoters. In the original post I said, It may very well be that I am simply not experienced enough with TH to fully appreciate and embrace it. More and more I am thinking this is the case. I'll have to give TH a more thorough look. BTW, in addition to the resources already given, can anyone suggest materials for my aforementioned more thorough look? Thanks again for the responses. --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Template Haskell a Permanent solution?
On Mon, Dec 27, 2010 at 12:44 AM, Henning Thielemann lemm...@henning-thielemann.de wrote: I think it would be enough, if the compiler could be told to unfold an expression like parse text in a domain specific language at compile time. I'm afraid I have to disagree with you here. Being able to specify that the string should be parsed at compile time is only half of the equation in my mind. The other half is the clean syntax for multi-line strings. Haskell already has great syntax for specifying data in a declarative manner. Especially in contrast with ie Java/C++. Even as good as the dynamic languages ie JavaScript/Python/Ruby. When you add the ability to specify data in ANY syntax you can parse, Haskell is clearly the best. But the complexity of TH detracts from the elegance of this greatly in my opinion. And wrapping your data in string syntax, multi-line or otherwise, detracts from the elegance as well. A syntax has to be less painful or more convenient or more readable/maintainable than literal list/record syntax before it is useful. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Template Haskell a Permanent solution?
On Mon, Dec 27, 2010 at 1:14 AM, Stephen Tetley stephen.tet...@gmail.com wrote: By this are you meaning to add quasiquoting to the language Haskell or the Glasgow Haskell, taking it out of the domain of Template Haskell? I believe that all new features should start as extensions and as an extension, these things could coexist with TH. I just can't see TH becoming standard. I think something much simpler that accomplishes the common uses of TH is more likely to make it into Haskell' 20[1-2]x. --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Template Haskell a Permanent solution?
Thanks, everyone, for the responses. I don't understand why the library/extension duality is a problem. I don't think it is a _problem_ it just feels strange to me. Maybe I'm misunderstanding, is it possible to use TH without using the library components? Shouldn't specialized features be defined in terms of general features? Absolutely, but usually don't you use the specialized features over general ones where you can? For example, I don't often (if ever) use the general feature of the goto statement in C. Instead I use conditionals, loops, and functions. I don't often write explicitly recursive functions in Haskell, rather I use map, filter, fold, etc. whenever the structure of the recursion allows. How does this differ from the current QuasiQuotes extension? From what I can tell, all you need to achieve this with TH is to automatically derive a Language.Haskell.TH.Lift instance for JsonObject, i.e. a function lift :: JsonObject - Q Exp such that the expression will evaluate to the original JsonObject. A QuasiQuoter like the one you describe can then be created by QuasiQuoter { parseExp = lift . json }. Right, it's not a lot of extra work. But it's enough that in most cases, I stick with constructing records or using other built-in syntax. Should both approaches be supported directly, or should we sacrifice the generality of the current quoters for the simplicity of the ones you suggest? No, I don't think TH should be sacrificed. I just think more specific (and more simple) features might be nice in place of some of TH's specific uses. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Template Haskell a Permanent solution?
Cafe, First let me say that Template Haskell is very powerful and a lot of great work has been done in this area. It fills in a number of holes in Haskell's feature set. But TH gives me the same feeling as other language features that have been described as bolted on. Also, TH is both library and built-in syntax (via an extension) which feels strange to me. Finally, It's very complicated to do some simple things. I see TH used most for the following tasks: #1 Parse a string at compile-time so that a custom syntax for representing data can be used. At the extreme, this data might even be an EDSL. #2 Provide instances automatically. I would propose that more specialized features be implemented to accomplish these tasks. To start, I'll throw out some ideas that provide these capabilities. For TH use #1, compile-time parsing of arbitrary strings, I think it would be nice for quasiquote semantics to be modified so that code like json :: String - JsonObject json = ... data = [ json | { name : Jonathan , favorite language: Haskell } |] causes the function json to be called at compile time with a string argument of{\name\ : \Jonathan\\n , \favorite language\: \Haskell\\n }. The whole expression being then replaced with the result of the function application. What I like about this is that defining quasiquoters is trivial. They're just functions of the form String - a. Many such quasiquoters already exist and would be ready for use! I imagine certain rules would apply, ie a quasiquoter must be defined prior to use and in a separate module, etc. For TH use #2, automatic instances, I would propose a way of declaring that a class can be automatically derived, and therefore added to the set [Eq, Ord, Show, Read, ... , etc]. This is the set of classes that can be put in the deriving clause of a type declaration. I don't know exactly what the syntax for this would look like, but I imagine it would look a bit like the various current implementations of automatic instances in TH. Again, TH is very powerful, and fills in a number of holes in Haskell's feature set. But it leaves me wondering if these holes should not be filled in by other, more specialized features, leaving TH to continue to find other holes to fill. I'm wondering if others see TH as a permanent solution, or if you agree with me that some of TH's most common usages should have more specialized features dedicated to them. It may very well be that I am simply not experienced enough with TH to fully appreciate and embrace it. By the way, did I miss any uses of TH as common as the ones I mentioned? --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Do we need Monad fail (or MonadFail)?
I'd love for the compiler to give an error (or maybe just a warning) in the case that I have a pattern match in a monad that just blows up (throws an exception) on a pattern match failure. Currently there's no way to know the behavior of failed pattern match failures without looking at the instance for the current monad. And what if you're writing monad agnostic (higher-order polymorphism?) code? If there were a MonadFail class, you could explicitly codify that you expect a monad to NOT crash your program in the case of a pattern match. For example: someFunction :: (MonadState m, MonadFail m) = a - m a someFunction arg = do [x,y,z] - action arg return z Of course one of the laws for MonadFail would be that fail never throws an exception. The compiler couldn't exactly enforce it, but we're used to expecting sane instances that obey laws. I think IO would be the exception (no pun intended) to this and be an instance of MonadFail, but just throw an exception on fail. Since you can only catch exceptions in the IO monad, this sounds reasonable to me. --Jonathan On Tue, Dec 21, 2010 at 2:49 AM, John Smith volderm...@hotmail.com wrote: Monads seem to use fail in one of three ways: -Regular monads leave it at the default definition of error -MonadPlus sometimes redefines it to mzero -IO redefines it to failIO Are there any other definitions of fail? If not, does the special case of IO really need a class-level definition, or could there be another way of dealing with failed pattern matches? ___ 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] Do we need Monad fail (or MonadFail)?
I'd be really interested in learning the rationale behind those changes. I'm sure it wasn't done for capricious or arbitrary reasons, but I can't help but see it as a step back. --Jonathan Geddes (sent from android mobile) On Dec 21, 2010 8:47 AM, Lauri Alanko l...@iki.fi wrote: On Tue, Dec 21, 2010 at 08:31:08AM -0700, Jonathan Geddes wrote: I'd love for the compiler to give... You will be interested to know that everything you ask for already was in Haskell ages ago: http://www.cs.auckland.ac.nz/references/haskell/haskell-report-1.4-html/exps.html#do-expressions They decided to get rid of it in Haskell 98, for reasons that someone else can probably explain. Lauri ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org ... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell, Step by Step, Tutorial, Developing a Whole Application
I agree with the feeling that Haskell tutorials feel like they are bottom-up. But I think there's a reason for this: In my experience, at least, Haskell applications are built bottom-up. Functional programming languages strive for composability. In Haskell you have very clean, clear ways of composing functions, Monads, and even composing them with each other. In OOP languages, the glue that you have for composing objects is more objects. This can be a much less elegant way to build applications bottom-up, and so bottom up applications feel sloppy and hacked together. In an OOP app, you need to start with some kind of scaffolding, such as mvc or the like, so that as you compose your objects, they start to take the shape of a well-structured application. In functional programming, that composability is much more flexible, so you don't need to worry as much about coding yourself into a poorly structured app. After all, mvc is all about separation of concerns which comes naturally if you keep as much as possible outside of the IO monad. When I'm coding in Haskell, I like to think in the paradigm of creating a domain specific language. I'm not writing my program for the first 90% of development, I'm actually working on the DSL that will be used to create my app. Finally, i switch from functional programming to imperative, procedural programming in the IO monad (or some custom Monad) to write the actual code. The end result is a flexible, maintainable program in very few lines of code and then some very general, reusable library code supporting it. I didn't address the actual question, instead I tried to speak to how I got around the problem. Hope my $0.02 helps. --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Haskell] Functor = Applicative = Monad
Fail can't just be removed. That would just break too much code. For example, I find myself writing code like the following: [a,b,c] - Just someList in place of let [a,b,c] = someList so that pattern match failure is lifted into the maybe monad (as long as I'm already in the maybe monad). I would like to see a MonadFail class, with one method 'fail', such that it is a compile-time error to try 'failable' pattern matches in a monad that is not an instance of MonadFail. --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] $ do?
Quick question: Why do I need the $ in the following bits of code? main = withSocketsDo $ do --do something with sockets foo = fromMaybe 0 $ do --do something in the maybe monad I don't see (after admittedly only a minute or so thinking about it) where any grammar ambiguities would be if 'do' had an implicit $ in front of it: foo = fromMaybe 0 do --do something in maybe Though now that I've written it down, that is hard for me to visually parse at a glance. I'm still curious though. --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] typeclass namespace rational?
cafe, Data Constructors and Type Constructors don't share the same namespace. You see code like the following all the time: data MyRecord = MyRecord {...} This is possible because Data Constructors are used in different parts of the code than Type Constructors so there's never any ambiguity. Type Classes, on the other hand, share the same namespace as Type Constructors. You can't define this: class String s where ... instance String String where ... instance String ByteString where ... instance String Text where ... Not that I'm running out of valid haskell identifiers or anything :P, I'm just wondering: what's the rationale behind keeping Type Classes and Type Constructors in the same namespace? I can't think of any ambiguity there would be if they each had their own namespace. And In some cases it would be convenient to be able to define both a concrete representation and an abstract one with the same name as in the String class example above. --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: typeclass namespace rational?
2 seconds after sending I realized the issue is in module exports: Module String where (String(..)) is that exporting some concrete ADT with all of its constructors or an abstract type class with all of its methods? Its too bad that Classes and ADTs overlap in export syntax and as such must share a namespace. I would much prefer Module String where (class String(..), data String(..), someOtherFunction) which I think is easier for the reader anyway. --Jonathan On Mon, Nov 15, 2010 at 8:31 PM, Jonathan Geddes geddes.jonat...@gmail.com wrote: cafe, Data Constructors and Type Constructors don't share the same namespace. You see code like the following all the time: data MyRecord = MyRecord {...} This is possible because Data Constructors are used in different parts of the code than Type Constructors so there's never any ambiguity. Type Classes, on the other hand, share the same namespace as Type Constructors. You can't define this: class String s where ... instance String String where ... instance String ByteString where ... instance String Text where ... Not that I'm running out of valid haskell identifiers or anything :P, I'm just wondering: what's the rationale behind keeping Type Classes and Type Constructors in the same namespace? I can't think of any ambiguity there would be if they each had their own namespace. And In some cases it would be convenient to be able to define both a concrete representation and an abstract one with the same name as in the String class example above. --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Better Records was Re: [Haskell-cafe] Type Directed Name Resolution
Records do leave quite a bit to be desired. But does anybody actually have a concrete alternative proposal yet? A few months ago I proposed a couple of extensions [1] on -cafe. The jist of it is in the following: someUpdate :: MyRecord - MyRecord someUpdate myRecord = myRecord { field1 = f $ field1 myRecord , field2 = g $ field2 myRecord , field3 = h $ filed3 myRecord } becomes someUpdate :: MyRecord - MyRecord someUpdate = \{field1 = f, field2 = g, field3 = h} The two syntax changes here are: 1. '=' remains as assignment in record updates, but = is added and means 'field is transformed by', and 2. \{...} is a first-class lambda update. It's made possible by the 1 since with 1 you no longer need to reference the entire record anywhere in the update Consider what this would do for nested updates: UpdateTripleInner :: (Inner-Inner) - MyTriplyNestedRecord - MyTriplyNestedRecord UpdateTripleInner f = \{inner1 = \{inner2 = \{inner3 = f }}} I cringe to imagine what the equivalent is in current Haskell syntax. Anyone want to try it? Not me! These extensions, admittedly, don't do anything for the namespacing problem, which might be a bigger issue than awkward updates. I submit that it's a different and somewhat unrelated issue, though I'd love to see something that addresses both (all?) of the issues! --Jonathan Geddes [1] http://www.mail-archive.com/haskell-cafe@haskell.org/msg81509.html On Fri, Nov 12, 2010 at 1:29 PM, Andrew Coppin andrewcop...@btinternet.com wrote: On 11/11/2010 11:48 PM, John Lask wrote: again quoting http://research.microsoft.com/en-us/um/people/simonpj/Haskell/records.html Haskell lacks a serious record system. (The existing mechanism for named fields in data types was always seen as a stop-gap measure.) isn't it about time this changed? Records do leave quite a bit to be desired. But does anybody actually have a concrete alternative proposal yet? Personally I'm not really keen on TDNR; I'd prefer records that aren't so inconvenient. But I have no idea how to design that. ___ 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] Re: Haskell is a scripting language inspired by Python.
Regardless of which languages got which features for which other languages, Haskell is surely NOT a scripting language inspired by python... Also, it was my understanding that Python got list comprehensions straight from Haskell. Unless, of course, some of the pre-Haskells also had this feature. Haskell: [f x | x - xs, x = 15] Python: [f(x) for x in xs if x = 15] The Python version reads the way I would speak the Haskell one if I were reading code aloud, though I might say such that rather than for --Jonathan Geddes On Thu, Nov 4, 2010 at 6:05 AM, Stephen Tetley stephen.tet...@gmail.com wrote: On 4 November 2010 12:03, Stephen Tetley stephen.tet...@gmail.com wrote: Python is approximately as old as Python and most likely got indentation from ABC. Apologies that should read - as old as Haskell Obviously IDSWIM - (I _don't_ say what I mean). ___ 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
[Haskell-cafe] Haskell is a scripting language inspired by Python.
This is off topic (almost regardless of the topic), but It gave me a laugh. Hope you all enjoy it, too. I was telling a friend about the power and elegance of Haskell. When I mentioned that it has influenced many other programming languages, including his favorite language (Python) he retorted by saying that I was mistaken and it was, in fact, the other way around: Python inspired Haskell. The following link was his source of information (or FUD, as the case may be). http://www.datarecoverylabs.com/ultimate-computer-language-guide.html It's called The *Ultimate* Computer Language Guide, and it's on the internets, so it must be correct, right? --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Re: Lambda-case / lambda-if
I can honestly say that I haven't felt much pain from the status quo regarding this. Most of the time my code is structured so that case statements don't appear in do blocks. When they do, I don't see it as a big issue. The special case for operator - is a bigger wart on haskell syntax than this, imo. I would vote in favor of keeping the language simple. I do like the idea of generalizing lambda functions to include multiple cases, however. On the other hand, I almost never use lambdas now since named functions yield better self-documenting code. --jonathan On Oct 8, 2010 8:09 AM, Peter Wortmann sc...@leeds.ac.uk wrote: On Fri, 2010-10-08 at 01:13 +0300, Lauri Alanko wrote: Your general rule doesn't subsume your ... Yes, that's what I meant. Thanks for describing it properly. On Fri, 2010-10-08 at 05:41 -0700, Nicolas Pouillard wrote: Imagine find this code: do s1 ... This is roughly what I meant with abused: Where C is very complex, it might become non-obvious where exactly the monad actions are supposed to happen. Hence such traps when refactoring. Also of note: Just moving sub-expressions around isn't something that is guaranteed to be save. Introducing new names and using them in s2 would be problematic, for example: do map (\x - (- putStrLn x)) [a, b] Obviously can't be made to work. You might have to check for this - or maybe even disallow the shorthand inside lamdbas and lets. Might be less satisfying to have such special cases, but it is still a good bit more general than what is available right now. Greetings, Peter Wortmann ___ Haskell-Cafe mailing list haskell-c...@haskell.org... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Question on monad transformers stack
Arnaud, You might also consider writing monad-agnostic code: code that doesn't know which monad it is executing in. For example: class (Monad g) = MonadGit g where gitOp1 :: gitOp2 :: instance MonadGit Git where gitOp1 = ... gitOp2 = ... ... intance MonadGit DebugGit where gitOp1 = ... gitOp2 = ... otherGitOp :: (MonadGit g) = a - b - g a otherGitOp = gitOp1 . gitOp2 . otherF . etc In other words, you create a typeclass that (at least) two different monads will implement. One which runs the code normally, while the other performs the debug actions that you described. Then your debug flag becomes a choice of which monad to begin execution in. Note that this can be a bit cumbersome (but I don't think impossible) if the debug flag has to be changed at runtime. Hope this helps, --Jonathan On Tue, Sep 28, 2010 at 12:56 AM, Arnaud Bailly arnaud.oq...@gmail.com wrote: Hello Cafe, I have the following type which represents some action using Git newtype (Monad m) = Git m a = Git { runGit :: ErrorT String (StateT Environment m) a } deriving (Monad, MonadState Environment, MonadError String) and the following typeclass whose purpose is to abstract away the details of executing commands in the OS, with an obvious IO instance, and to ease testing of commands effects: -- | A monad for simple execution of a process within the class (MonadError e m) = MonadExec e m where debug :: String - m () exec :: String - [String] - m String -- ^Do not really execute commande but output the command string and arguments passed exec' :: String - [String] - m String exec' proc args = return $ program proc args The type environment is : data Environment = Env { debugMode :: Bool, baseDirectory :: FilePath, maven :: FilePath, git :: FilePath, p4 :: FilePath, javaHome :: FilePath} deriving (Eq, Show, Read) This follows the monad stack pattern presented in RWH and in Don Stewart's presentation on scripting with haskell. Actually, what I am trying to achieve is to be able to write my own scripts in Haskell. What I would like to do is to be able to wrap each Git action occuring in a MonadExec instance into a call to debug according to the status of the debugMode flag in environment, in order to prevent the need of explicit calls to debug. Something like the -v flag in bash... I can imagine being able to do this using 2 different ways: - add a constraint on Git monad and write explicitly return and = to use debug - push the environment or part of it inside the MonadExec, for example as a Reader. What is the best (i.e. most economical) way of doing this? Thanks for your advices. Arnaud Bailly ___ 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
[Haskell-cafe] Inverse of HaskellDB
Cafe, HaskellDB takes a database schema and produces Haskell data structures (plus some other query-related stuff for its EDSL query language). What I'm looking for is the inverse of this functionality. I want to create tables based on a Haskell data structure with a few simple rules. These rules include: if a field is not of the form `Maybe a' then it can't be nullable in the database. If a field is not a primitive (in the database) then it is actually stored in another table and a reference id is stored in the table. Tables are produced recursively, unless they already exist, etc. The HaskellDB approach is great for interfacing with existing tables, but in my case I already have data structures and now I would like a quick way to create tables to persist them. Does such a thing exist? If not, would you find it useful? I may take this up as a side project if it does not already exist and others would find it useful. Thanks, --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Inverse of HaskellDB
Versioning is a tricky problem regardless of how you are creating tables. And that isn't the problem I was aiming to tackle; the problem I was aiming to tackle is a bit more narrow than that: I have a record and now I need a table to stick it in. By the way, how does HaskellDB handle versioning? --Jonathan On Sat, Sep 25, 2010 at 1:57 PM, Antoine Latter aslat...@gmail.com wrote: That sounds pretty awesome to me. Have you given any thought as to how you want to approach versioning? Maybe I'm asking a silly question - I have very little real world experience with relation databases and how to version schemas. Antoine On Sep 25, 2010 2:31 PM, Jonathan Geddes geddes.jonat...@gmail.com wrote: Cafe, HaskellDB takes a database schema and produces Haskell data structures (plus some other query-related stuff for its EDSL query language). What I'm looking for is the inverse of this functionality. I want to create tables based on a Haskell data structure with a few simple rules. These rules include: if a field is not of the form `Maybe a' then it can't be nullable in the database. If a field is not a primitive (in the database) then it is actually stored in another table and a reference id is stored in the table. Tables are produced recursively, unless they already exist, etc. The HaskellDB approach is great for interfacing with existing tables, but in my case I already have data structures and now I would like a quick way to create tables to persist them. Does such a thing exist? If not, would you find it useful? I may take this up as a side project if it does not already exist and others would find it useful. Thanks, --Jonathan ___ 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] Inverse of HaskellDB
Have you given any thought as to how you want to approach versioning? After giving this some more thought, I realized: 1) One of the best practices (even though I despise the term) of versioning schema is to include a script with the code which checks for each change to the tables, and makes the change if it is needed [1]. Each time you check out new code, you run the script to ensure that the code you are working with matches the tables you are working with. 2) A system that generates tables from Haskell types could also be made to check if a given table faithfully represents a given Haskell record type. It could then make any changes to the table so that it _does_ faithfully represent the record type. 3) In this way, your Haskell records ARE your table update script, just (like most Haskell code) incredibly terse. Your usual code repository will track when and by whom changes are made to the record. Of course, there are some issues with this, but I think it could be made to work well. Hibernate does this, more or less, for Java classes. That might be a good place to look for ideas. Good point. I'll start there. [1] http://www.codeproject.com/KB/database/DatabaseSchemaVersioning.aspx --Jonathan On Sat, Sep 25, 2010 at 3:45 PM, Rogan Creswick cresw...@gmail.com wrote: On Sat, Sep 25, 2010 at 12:31 PM, Jonathan Geddes geddes.jonat...@gmail.com wrote: Does such a thing exist? If not, would you find it useful? I may take this up as a side project if it does not already exist and others would find it useful. I've been looking for something along these lines too. Hibernate does this, more or less, for Java classes. That might be a good place to look for ideas. --Rogan Thanks, --Jonathan ___ 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] record update
Wow, I had no idea there were so many record packages! This indicates a couple things to me: a) Haskell is very flexible. b) I'm not the only one who things the built-in record system isn't perfect. Digging a bit deeper, it looks like some of the record-related ghc extensions might also be useful, such as record punning and field disambiguation. Since these are already extensions, they're more likely to make it into Haskell 20XX. Are these considered to be the solution to current record syntax problems? With these extensions, couldn't I write the following? someUpdate :: MyRecord - MyRecord someUpdate myRecord@(MyRecord{..}) = let { field1 = f field1 , field2 = g field2 , field3 = h filed3 } in myRecord{..} ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] record update
I know that record updates is a topic that has become a bit of a dead horse, but here I go anyway: I find that most of the record updates I read and write take the form someUpdate :: MyRecord - MyRecord someUpdate myRecord = myRecord { field1 = f $ field1 myRecord , field2 = g $ field2 myRecord , field3 = h $ filed3 myRecord } I find myself wishing I could write something more like someUpdate :: MyRecord - MyRecord someUpdate myRecord = myRecord { field1 = f , field2 = g , field3 = h } with equivalent semantics. Here = reads is transformed by. Operator = could still be used for assignment as in current record updates. The best part about such an extension, in my opinion, is that it would open the door for anonymous lambda record updates. Something like: someUpdate :: MyRecord - MyRecord someUpdate = \{field1 = f, field2 = g, field3 = h} again, with the same semantics. This becomes possible because you no longer need to refer to the record within the {} part of the update. This would be useful, for example, in the State monad. We could write: someStateTransform :: State MyRecord () someStateTransform = do modify $ \{field1 = (++!)} ... where currently we see code like someStateTransform :: State MyRecord () someStateTransform = do modify $ \record-record{field1 = (++!) $ field1 record} ... which repeats the record name 3 times and the field name twice. The repetition just feels out of place next to all the other terse, readable Haskell code in the program. So what do my fellow haskellers think? Is this idea worth writing up a proposal for? Alternatively, can you offer me some advice on writing code in Haskell 2010 that avoids the ugly, repetitive style of record update? --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] record update
On Sat, Sep 11, 2010 at 11:53 AM, Henning Thielemann schlepp...@henning-thielemann.de wrote: Jonathan Geddes schrieb: I know that record updates is a topic that has become a bit of a dead horse, but here I go anyway: I find that most of the record updates I read and write take the form someUpdate :: MyRecord - MyRecord someUpdate myRecord = myRecord { field1 = f $ field1 myRecord , field2 = g $ field2 myRecord , field3 = h $ filed3 myRecord } I find myself wishing I could write something more like someUpdate :: MyRecord - MyRecord someUpdate myRecord = myRecord { field1 = f , field2 = g , field3 = h } data-accessor and similar packages may become your friends. data-accessor allows you to write: someUpdate = (field1 ^: f) . (field2 ^: g) . (field3 ^: h) data-accessor is a pretty cool package, but if I understand correctly, your fields are not the same as the straight functions you get from defining a record, and cant' be used as regular functions. So you have to create these Data.Accessor.Accessors. Is defining accessors really any better than just writing update functions like the following? updateField1 :: (Field1Type - Field1Type) - MyRecord - MyRecord updateField1 f x = x{field1 = f $ field1 x} someUpdate = (updateField1 f) . j(updateField2 g) . (updateField3 h) I understand that there is a package data-accessor-template for generating accessors, but couldn't you use TH for generating updater functions as well? It seems like something as fundamental as record update should have a clean, build-in syntax. Or am I thinking too imperatively? --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Socket not released
You need to close the parent's socket in the child fork, as well as the parent - if it's inherited by the child, it's held open there, even if the parent closes it. Thanks! That did the trick. I did so by adding close_fds = True to the CreateProcess record. However the documentation of System.Process says that this only works on Windows if std_in, std_out, and std_err are all set to Inherit. This is not the case in my program so it will not work on any nodes that run on Windows. What is the workaround for doing this kind of thing in Windows? Also since the file descriptor of the socket appears to be inherited by the child process, can I just start using it rather than closing it in both the parent and child and then creating a new one? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Socket not released
Only a guess, but I predict that it will work for your purposes, since you're not concerned about what happens to std_in et al. I actually am concerned about what happens to std_in. The parent process serializes a bit of state and passes it to the child via the child's std_in. There's probably a better way to do such a thing, but it works for now. That statement in the documentation is ambiguous, so if it isn't convenient to just test for this, you need someone to clarify what doesn't work means. I will wait to test this when (and if) I have to put a node on a Windows box. Sure! At least from a POSIX perspective, and it would be surprising if a Haskell implementation failed to preserve that. If only I knew for sure that all nodes would remain in the POSIX world. I appreciate the help. --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Haskell in Industry
Yes. I find that out of 10 people I train, only about 2 pick it up and run with it. I'm starting to believe you are either wired for functional programming, or you're not. Couldn't agree more. This is the usual conclusion I arrive at when I find myself wondering why so many very intelligent people reject FP when it's obviously (to my and my FP-wired brain) superior. --Jonathan Geddes ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Socket not released
Cafe, I'm writing a network application that uses static configuration a la xmonad and yi. When the app receives a certain command it recompiles its source, closes the socket it is using and runs its newly compiled predecessor as a new process. The problem I'm having is that the port that the parent process was using is not available to the child process. Even though the parent process has terminated, the port is unusable until the child process also terminates. Can anyone give me a clue about what's going on here? I'm using Network and System.Process modules and ruining on Ubuntu linux. I'm using the sClose function to close the socket. Thanks for any tips. --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Socket not released
Thank you for your response Are you certain of this part? The usual problem with this kind of program is that the system holds the socket open for a minute or so in case there are any packets in flight for the connection (the lower level network protocols not being 100% reliable). I'm not certain, but here's what I'm seeing. The process tries n times to acquire the socket, pausing for a second or so between attempts. While running a child process I will run a fresh process so that the two processes are competing for the socket, but neither of them are getting it. In half a dozen such test cases the fresh process grabs the socket on the very next attempt after the child process is interrupted. But if I interrupt the fresh process, the child process continues to fail to acquire the socket. And the workaround is to set SO_REUSEADDR before binding the port; in Haskell, setSocketOption socket ReuseAddr 1 I'm using the Network Module which sets ReuseAddr, according to its documentation. --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Suggestions For An Intro To Monads Talk.
On Fri, Aug 6, 2010 at 9:17 AM, aditya siram aditya.si...@gmail.com wrote: Upon further reflection I realized that my audience is more pragmatic than theoretical. Instead of emphasizing how monads are constructed and the monad laws I think I want to dive right into the most common and useful monads. From my vantage point they are (in no particular order) : Reader, Writer, State, IO, ST, STM, Parsec (have I missed any?) and of course the transformer versions. I am debating whether or not to add [] to the bunch. If your audience is indeed a pragmatic lot then they will not be interested in the same things as a more theoretical crowd (obviously). So they might not be interested in Monads at all. You've got your work cut out for you! With that said, I would suggest starting with the advantages of purity. I would guess that 95% of bugs in imperative code are related to some erroneous state. Pure code, on the other hand is immune to this huge class of bugs. Sometimes state is useful or even necessary (stateful computations, IO, in-place algorithms, etc), so you really can't forgo state entirely. The cool thing about Monads is they allow us to have our cake and eat it too! We can model stateful computations in pure code. You might also mention the separation of pure and impure code and how this helps us to reason about a program. I'm still a little iffy on why the monad concept isn't used in other languages. From where I sit it seems as though monads really let you play with the order of evaluation - just because one statement is executed after another doesn't mean they are executed in that order. I think other languages don't make this easy. My guess would be that other languages have much less commitment to purity. You don't need Monads in other languages because state is implicit, everything is in the IO monad, in a sense. While Monads are still an excellent abstraction in other languages they're often more awkward than just using implicit state/IO/whatever operations. Haskell has some sweet built-in syntax for monads. Also related to advantages of purity: http://www.haskell.org/haskellwiki/Why_Haskell_just_works I think this approach (stating benefits of purity and maybe laziness) would be more interesting to a pragmatic crowd. Just a guess though. Good luck with your presentation! --Jonathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe