<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Reflections on leaving Haskell</title>
	<atom:link href="http://www.alsonkemp.com/haskell/reflections-on-leaving-haskell/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.alsonkemp.com/haskell/reflections-on-leaving-haskell/</link>
	<description>Hackfoofery</description>
	<lastBuildDate>Wed, 23 Feb 2011 00:34:59 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>By: How do you maintain type-safety in web applications? &#124; Alson Kemp</title>
		<link>http://www.alsonkemp.com/haskell/reflections-on-leaving-haskell/comment-page-1/#comment-436</link>
		<dc:creator>How do you maintain type-safety in web applications? &#124; Alson Kemp</dc:creator>
		<pubDate>Fri, 19 Mar 2010 00:02:37 +0000</pubDate>
		<guid isPermaLink="false">http://www.alsonkemp.com/?p=335#comment-436</guid>
		<description>&lt;p&gt;[...] Curt and I were discussing over in my last post, I am bothered by the lack of type-safety in MVC web frameworks.  In most MVC frameworks, [...]&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>[...] Curt and I were discussing over in my last post, I am bothered by the lack of type-safety in MVC web frameworks.  In most MVC frameworks, [...]</p>]]></content:encoded>
	</item>
	<item>
		<title>By: alson</title>
		<link>http://www.alsonkemp.com/haskell/reflections-on-leaving-haskell/comment-page-1/#comment-432</link>
		<dc:creator>alson</dc:creator>
		<pubDate>Tue, 16 Mar 2010 15:20:30 +0000</pubDate>
		<guid isPermaLink="false">http://www.alsonkemp.com/?p=335#comment-432</guid>
		<description>&lt;p&gt;David,&lt;/p&gt;

&lt;p&gt;Agreed.  UTs certainly seem to straighten out my IO grumpiness, but they aren&#039;t a panacea.  Monads are still necessary but can be restricted in their application.  See here:&lt;/p&gt;

&lt;p&gt;http://lambda-the-ultimate.org/node/1180&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>David,</p>

<p>Agreed.  UTs certainly seem to straighten out my IO grumpiness, but they aren&#8217;t a panacea.  Monads are still necessary but can be restricted in their application.  See here:</p>

<p><a href="http://lambda-the-ultimate.org/node/1180" rel="nofollow">http://lambda-the-ultimate.org/node/1180</a></p>]]></content:encoded>
	</item>
	<item>
		<title>By: David</title>
		<link>http://www.alsonkemp.com/haskell/reflections-on-leaving-haskell/comment-page-1/#comment-431</link>
		<dc:creator>David</dc:creator>
		<pubDate>Tue, 16 Mar 2010 14:27:44 +0000</pubDate>
		<guid isPermaLink="false">http://www.alsonkemp.com/?p=335#comment-431</guid>
		<description>&lt;p&gt;I am surprised to see that Clean has not been mentioned, since it is often compared to Haskell. There are some problems with it, for example that it is proprietary, with a smaller user base and has less libraries.&lt;/p&gt;

&lt;p&gt;However, uniqueness typing really kicks the IO monad&#039;s butt IMHO, while also being useful for destructive updates. See http://en.wikipedia.org/wiki/Uniqueness_type&lt;/p&gt;

&lt;p&gt;I wish uniqueness typing would enter a language that feels more presently alive than Clean.&lt;/p&gt;

&lt;p&gt;Regarding Clojure, it seems to me that it does not really matter if it handles multi-cores well if it is 10 times (often more) slower than C. Haskell is nice that way.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I am surprised to see that Clean has not been mentioned, since it is often compared to Haskell. There are some problems with it, for example that it is proprietary, with a smaller user base and has less libraries.</p>

<p>However, uniqueness typing really kicks the IO monad&#8217;s butt IMHO, while also being useful for destructive updates. See <a href="http://en.wikipedia.org/wiki/Uniqueness_type" rel="nofollow">http://en.wikipedia.org/wiki/Uniqueness_type</a></p>

<p>I wish uniqueness typing would enter a language that feels more presently alive than Clean.</p>

<p>Regarding Clojure, it seems to me that it does not really matter if it handles multi-cores well if it is 10 times (often more) slower than C. Haskell is nice that way.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Curt Sampson</title>
		<link>http://www.alsonkemp.com/haskell/reflections-on-leaving-haskell/comment-page-1/#comment-430</link>
		<dc:creator>Curt Sampson</dc:creator>
		<pubDate>Mon, 15 Mar 2010 18:00:52 +0000</pubDate>
		<guid isPermaLink="false">http://www.alsonkemp.com/?p=335#comment-430</guid>
		<description>&lt;p&gt;Sorry, I misinterpreted you somewhat about the &quot;standard practice&quot; thing.       Still, contemplating things further, I think I still disagree with you.&lt;/p&gt;

&lt;p&gt;You mention that there are &quot;a number of successful libraries for Haskell that   are derivative of those in other languages.&quot; Do you have some examples? Looking through them myself, the &quot;ported libraries&quot; that have a very similar interface  to the original tend to have interfaces that are either fairly trivial (zlib)   or don&#039;t feel very Haskell-ish (various POSIX library ports). The ones that do  feel Haskellish tend to have fairly major changes to the interface to make them so (eprocess, regex-base).&lt;/p&gt;

&lt;p&gt;It doesn&#039;t really make sense, by the way, to ask if your adaptation of Rails    was or was not to my liking, since the source material is so much not to my     liking. I think that Rails goes about a lot of things in a very wrong way. What little I&#039;ve seen of Django, for example, seemed a lot nicer. I&#039;d love to show   you QWeb, but unfortunately it&#039;s proprietary and I no longer own the product.&lt;/p&gt;

&lt;p&gt;I think we&#039;re in agreement about the use of IO if you no longer feel you&#039;re     always &quot;doing something wrong&quot; when it gets used heavily. As I mentioned, I&#039;ve  got areas of my program a thousand lines in size that are all in IO, though     you&#039;d hardly know it to look at it, and it certainly doesn&#039;t &lt;em&gt;feel&lt;/em&gt; like you&#039;re working in IO.&lt;/p&gt;

&lt;p&gt;As for feeling more productive in Ruby, as I do for certain things as well, I   suspect that there are two things that bring this about. The first is that      there are some areas where Haskell doesn&#039;t yet have the comfortable syntax and  libraries needed for certain types of things, mainly in string matching and     manipulation and system areas (think of things like the Dir[...] construct in   Ruby). Those will probably come if someone sits down to work on them seriously. The other is that, especially due to the lack of refactoring tools, Haskell     isn&#039;t well suited to certain types of prototyping (or prototyping-like          programming) where so long as the program is 20% correct, you&#039;re happy to       ignore all the broken parts. Haskell really tends to push you to handle all     cases rather than just the common one, and especially if you&#039;re writing         something like a one-off script this can be far more work than necessary.       Still, this isn&#039;t always the case; one example I can think of involved a filter to colour the text passing through it based on certain rules, where after a     couple of hours of struggling with it in Ruby I switch to Haskell and had a     much more correct version running in about 30 minutes.&lt;/p&gt;

&lt;p&gt;For stuff that really does need to handle all possible cases correctly, though, Haskell is a godsend. I wouldn&#039;t even want to contemplate trying to write my    current trading system in a non-ML-based language.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Sorry, I misinterpreted you somewhat about the &#8220;standard practice&#8221; thing.       Still, contemplating things further, I think I still disagree with you.</p>

<p>You mention that there are &#8220;a number of successful libraries for Haskell that   are derivative of those in other languages.&#8221; Do you have some examples? Looking through them myself, the &#8220;ported libraries&#8221; that have a very similar interface  to the original tend to have interfaces that are either fairly trivial (zlib)   or don&#8217;t feel very Haskell-ish (various POSIX library ports). The ones that do  feel Haskellish tend to have fairly major changes to the interface to make them so (eprocess, regex-base).</p>

<p>It doesn&#8217;t really make sense, by the way, to ask if your adaptation of Rails    was or was not to my liking, since the source material is so much not to my     liking. I think that Rails goes about a lot of things in a very wrong way. What little I&#8217;ve seen of Django, for example, seemed a lot nicer. I&#8217;d love to show   you QWeb, but unfortunately it&#8217;s proprietary and I no longer own the product.</p>

<p>I think we&#8217;re in agreement about the use of IO if you no longer feel you&#8217;re     always &#8220;doing something wrong&#8221; when it gets used heavily. As I mentioned, I&#8217;ve  got areas of my program a thousand lines in size that are all in IO, though     you&#8217;d hardly know it to look at it, and it certainly doesn&#8217;t <em>feel</em> like you&#8217;re working in IO.</p>

<p>As for feeling more productive in Ruby, as I do for certain things as well, I   suspect that there are two things that bring this about. The first is that      there are some areas where Haskell doesn&#8217;t yet have the comfortable syntax and  libraries needed for certain types of things, mainly in string matching and     manipulation and system areas (think of things like the Dir[...] construct in   Ruby). Those will probably come if someone sits down to work on them seriously. The other is that, especially due to the lack of refactoring tools, Haskell     isn&#8217;t well suited to certain types of prototyping (or prototyping-like          programming) where so long as the program is 20% correct, you&#8217;re happy to       ignore all the broken parts. Haskell really tends to push you to handle all     cases rather than just the common one, and especially if you&#8217;re writing         something like a one-off script this can be far more work than necessary.       Still, this isn&#8217;t always the case; one example I can think of involved a filter to colour the text passing through it based on certain rules, where after a     couple of hours of struggling with it in Ruby I switch to Haskell and had a     much more correct version running in about 30 minutes.</p>

<p>For stuff that really does need to handle all possible cases correctly, though, Haskell is a godsend. I wouldn&#8217;t even want to contemplate trying to write my    current trading system in a non-ML-based language.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: alson</title>
		<link>http://www.alsonkemp.com/haskell/reflections-on-leaving-haskell/comment-page-1/#comment-427</link>
		<dc:creator>alson</dc:creator>
		<pubDate>Mon, 15 Mar 2010 01:33:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.alsonkemp.com/?p=335#comment-427</guid>
		<description>&lt;p&gt;Curt,&lt;/p&gt;

&lt;p&gt;I&#039;m a little confused.  Reading through my previous message, I don&#039;t really see myself as saying anything you suggest I said...&lt;/p&gt;

&lt;p&gt;I didn&#039;t say that porting Rails is a standard exercise.  I said that it&#039;s a standard exercise to bring favored practices from other languages to new languages.  There are a number of successful libraries for Haskell that are derivative of those in other languages.  Naturally, the exercise includes adapting the material to the new environment and I assume what you&#039;re saying is that my adaptation was not to your liking.&lt;/p&gt;

&lt;p&gt;I&#039;m not dogmatic about IO and I don&#039;t consider IO to be offensive.  In Haskell, IO is treated very specially, so I felt as though I was doing something wrong when I was special-casing all of my functions for IO.  In nearly every other language, IO is not distinguished from non-IO so everyone does it blindly.&lt;/p&gt;

&lt;p&gt;Productivity: again, I&#039;m not sure where I said anything about the productivity of the code.  I said that &lt;em&gt;I&lt;/em&gt; was more productive in Ruby than in Haskell.  It bums me to admit that, but it is what it is.  I can build fairly robust systems quickly and easily in Ruby or Rails; I struggle with relatively basic stuff in Haskell (and comments here suggest that others do, too).&lt;/p&gt;

&lt;p&gt;I also didn&#039;t say that I&#039;d &quot;never been bitten by sloppy IO&quot;; I&#039;m sure that I have been. I said that I couldn&#039;t remember a time when I&#039;d been bitten.  To me, that suggests that I&#039;m working on problems which don&#039;t have the issue that Haskell solves...&lt;/p&gt;

&lt;p&gt;MVC: agreed.  The term is used very loosely in the web world... but, just as frustratingly as Ruby, the structure seems to make me fairly productive...  I&#039;ve definitely seen Rails projects abuse it and produce an incomprehensible app.&lt;/p&gt;

&lt;p&gt;QWeb: I&#039;ve been thinking more about how to solve this C-V impedance match issue.  Would love to see how you did it with QWeb.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Curt,</p>

<p>I&#8217;m a little confused.  Reading through my previous message, I don&#8217;t really see myself as saying anything you suggest I said&#8230;</p>

<p>I didn&#8217;t say that porting Rails is a standard exercise.  I said that it&#8217;s a standard exercise to bring favored practices from other languages to new languages.  There are a number of successful libraries for Haskell that are derivative of those in other languages.  Naturally, the exercise includes adapting the material to the new environment and I assume what you&#8217;re saying is that my adaptation was not to your liking.</p>

<p>I&#8217;m not dogmatic about IO and I don&#8217;t consider IO to be offensive.  In Haskell, IO is treated very specially, so I felt as though I was doing something wrong when I was special-casing all of my functions for IO.  In nearly every other language, IO is not distinguished from non-IO so everyone does it blindly.</p>

<p>Productivity: again, I&#8217;m not sure where I said anything about the productivity of the code.  I said that <em>I</em> was more productive in Ruby than in Haskell.  It bums me to admit that, but it is what it is.  I can build fairly robust systems quickly and easily in Ruby or Rails; I struggle with relatively basic stuff in Haskell (and comments here suggest that others do, too).</p>

<p>I also didn&#8217;t say that I&#8217;d &#8220;never been bitten by sloppy IO&#8221;; I&#8217;m sure that I have been. I said that I couldn&#8217;t remember a time when I&#8217;d been bitten.  To me, that suggests that I&#8217;m working on problems which don&#8217;t have the issue that Haskell solves&#8230;</p>

<p>MVC: agreed.  The term is used very loosely in the web world&#8230; but, just as frustratingly as Ruby, the structure seems to make me fairly productive&#8230;  I&#8217;ve definitely seen Rails projects abuse it and produce an incomprehensible app.</p>

<p>QWeb: I&#8217;ve been thinking more about how to solve this C-V impedance match issue.  Would love to see how you did it with QWeb.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Curt Sampson</title>
		<link>http://www.alsonkemp.com/haskell/reflections-on-leaving-haskell/comment-page-1/#comment-426</link>
		<dc:creator>Curt Sampson</dc:creator>
		<pubDate>Mon, 15 Mar 2010 00:43:02 +0000</pubDate>
		<guid isPermaLink="false">http://www.alsonkemp.com/?p=335#comment-426</guid>
		<description>&lt;p&gt;I don&#039;t buy your argument about porting Rails being a &quot;standard exercise.&quot; Porti
ng an imperative program into an OO language, but still writing it in an imperat
ive style, doesn&#039;t make sense; why should doing the moral equivalant from a lang
auge without compile-time type-checking to one with make any more sense?&lt;/p&gt;

&lt;p&gt;That said, if you want to do it, it&#039;s not as hard as you make it out to be. Rather than using all those separate data types in your environment, just create a big dictionary mapping String names to a type that&#039;s an enumeration of all your different kinds of values, and your type &quot;problems&quot; will disappear just the way they do in Ruby. It&#039;s even easy to do automated conversions in your accessors, e.
g., given &quot;data Value = StringValue String &#124; IntValue Int&quot;, the getInt function
can return the Int in the IntValue case, or read the String to an Int in the Str
ingValue case.&lt;/p&gt;

&lt;p&gt;If you consider this offensive, you have to ask yourself why it&#039;s not offensive when you do what is morally the same thing in Ruby.&lt;/p&gt;

&lt;p&gt;With IO, it&#039;s the same. I seem to hear you saying that &quot;f s = putStrLn s :: IO ()&quot; is offensive, but &quot;def f(s); puts(s); end&quot; is not. What about &quot;f s = putStrLn s&quot;, without the type signature, then? All three of those have the same type sig
nature. How is the Ruby one &quot;more productive&quot; than either of the Haskell ones?&lt;/p&gt;

&lt;p&gt;I think here you&#039;ve just got the handle on the wrong end. Haskell is no more str
ict about the use of IO than any other languge: it&#039;s only more strict about &lt;em&gt;dec
laring&lt;/em&gt; the use of IO. You&#039;re perfectly free to put every function you write int
o the IO monad, if you like, just as you always do in any other language.&lt;/p&gt;

&lt;p&gt;Further, when you say you&#039;ve &quot;never been bitten by sloppy IO,&quot; you&#039;ve missed the whole point, unless you really meant that a variable (often a global) being set to a different value than you expected was &quot;sloppy IO&quot;. All this monad stuff is really all about control of access to state. That&#039;s why program designs that re
ly on lots of global state being accessable everywhere (such as Rails assumes, if you really analyze it) hurt to build in Haskell.&lt;/p&gt;

&lt;p&gt;As to your controller and view type safety issue: yes, you&#039;re absolutely correct there. In fact, what you&#039;ve stumbled on is an indication of the true problem, which is that the MVC design is not a good match to HTTP&#039;s request/response design. (Consider, for example, how in Rails you&#039;d implement a &quot;view&quot; without a &quot;controller.&quot; You can&#039;t.) &quot;Controllers&quot; and &quot;views&quot; are actually inextricably linked in systems like Rails, and artifically separated for no good reason. (I&#039;m reckoning that someone thought MVC sounded like a cool idea and wanted to apply it somewhere.)&lt;/p&gt;

&lt;p&gt;Rails &quot;solves&quot; the problem by sweeping it under the rug. Haskell, uncomfortably enough, forces you to admit that the problem is there. The solution, of course, is to dump the MVC model, avoid the impedence mismatch, and use the command/response model that matches the way HTTP works.&lt;/p&gt;

&lt;p&gt;I&#039;ve in fact tested this approach in Ruby, and the QWeb framework I designed tur
ned out to produce servlets rather less complex than those in Rails; a simple He
llo World servlet that returns the result of a database query for example is a h
alf-dozen lines of code in a single file, including all &quot;routing&quot; information, whereas in Rails that&#039;s spread across three different files and possibly has thin
gs encoded in the source file names and locations themselves. (Determining just what URLs a large Rails application responds to is a nightmare.)&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I don&#8217;t buy your argument about porting Rails being a &#8220;standard exercise.&#8221; Porti
ng an imperative program into an OO language, but still writing it in an imperat
ive style, doesn&#8217;t make sense; why should doing the moral equivalant from a lang
auge without compile-time type-checking to one with make any more sense?</p>

<p>That said, if you want to do it, it&#8217;s not as hard as you make it out to be. Rather than using all those separate data types in your environment, just create a big dictionary mapping String names to a type that&#8217;s an enumeration of all your different kinds of values, and your type &#8220;problems&#8221; will disappear just the way they do in Ruby. It&#8217;s even easy to do automated conversions in your accessors, e.
g., given &#8220;data Value = StringValue String | IntValue Int&#8221;, the getInt function
can return the Int in the IntValue case, or read the String to an Int in the Str
ingValue case.</p>

<p>If you consider this offensive, you have to ask yourself why it&#8217;s not offensive when you do what is morally the same thing in Ruby.</p>

<p>With IO, it&#8217;s the same. I seem to hear you saying that &#8220;f s = putStrLn s :: IO ()&#8221; is offensive, but &#8220;def f(s); puts(s); end&#8221; is not. What about &#8220;f s = putStrLn s&#8221;, without the type signature, then? All three of those have the same type sig
nature. How is the Ruby one &#8220;more productive&#8221; than either of the Haskell ones?</p>

<p>I think here you&#8217;ve just got the handle on the wrong end. Haskell is no more str
ict about the use of IO than any other languge: it&#8217;s only more strict about <em>dec
laring</em> the use of IO. You&#8217;re perfectly free to put every function you write int
o the IO monad, if you like, just as you always do in any other language.</p>

<p>Further, when you say you&#8217;ve &#8220;never been bitten by sloppy IO,&#8221; you&#8217;ve missed the whole point, unless you really meant that a variable (often a global) being set to a different value than you expected was &#8220;sloppy IO&#8221;. All this monad stuff is really all about control of access to state. That&#8217;s why program designs that re
ly on lots of global state being accessable everywhere (such as Rails assumes, if you really analyze it) hurt to build in Haskell.</p>

<p>As to your controller and view type safety issue: yes, you&#8217;re absolutely correct there. In fact, what you&#8217;ve stumbled on is an indication of the true problem, which is that the MVC design is not a good match to HTTP&#8217;s request/response design. (Consider, for example, how in Rails you&#8217;d implement a &#8220;view&#8221; without a &#8220;controller.&#8221; You can&#8217;t.) &#8220;Controllers&#8221; and &#8220;views&#8221; are actually inextricably linked in systems like Rails, and artifically separated for no good reason. (I&#8217;m reckoning that someone thought MVC sounded like a cool idea and wanted to apply it somewhere.)</p>

<p>Rails &#8220;solves&#8221; the problem by sweeping it under the rug. Haskell, uncomfortably enough, forces you to admit that the problem is there. The solution, of course, is to dump the MVC model, avoid the impedence mismatch, and use the command/response model that matches the way HTTP works.</p>

<p>I&#8217;ve in fact tested this approach in Ruby, and the QWeb framework I designed tur
ned out to produce servlets rather less complex than those in Rails; a simple He
llo World servlet that returns the result of a database query for example is a h
alf-dozen lines of code in a single file, including all &#8220;routing&#8221; information, whereas in Rails that&#8217;s spread across three different files and possibly has thin
gs encoded in the source file names and locations themselves. (Determining just what URLs a large Rails application responds to is a nightmare.)</p>]]></content:encoded>
	</item>
	<item>
		<title>By: alson</title>
		<link>http://www.alsonkemp.com/haskell/reflections-on-leaving-haskell/comment-page-1/#comment-425</link>
		<dc:creator>alson</dc:creator>
		<pubDate>Sun, 14 Mar 2010 18:18:35 +0000</pubDate>
		<guid isPermaLink="false">http://www.alsonkemp.com/?p=335#comment-425</guid>
		<description>&lt;p&gt;Curt,&lt;/p&gt;

&lt;p&gt;Fantastic comment.  Taking it bits at a time:&lt;/p&gt;

&lt;p&gt;Rails: I like it; you don&#039;t.  Fair enough.&lt;/p&gt;

&lt;p&gt;Porting Rails to Haskell: it&#039;s a fairly standard exercise to bring favored practices from other languages/disciplines into new languages, so, while I agree with the &quot;square peg - round hole&quot; assessment of the project, it&#039;s not unreasonable to undertake the project.  Especially when the project looks like an opportunity to web together a number of libraries into a more useful framework... except when the project then founders because its requirements and the libraries&#039; construction/monads all conflict.&lt;/p&gt;

&lt;p&gt;IO: I really like Haskell&#039;s explicit usage of IO and I buy that not being careful with IO can get me into trouble... but I don&#039;t think that I&#039;m deluding myself if I choose to move to a language that is less strict about the usage of IO.  In fact, I&#039;m acting rationally: I&#039;m more productive across a range of problems and I can&#039;t really think of a time when I&#039;ve been bitten by sloppy IO.  (At which point someone will claim that I don&#039;t know Haskell well enough or haven&#039;t worked on large enough projects or something...)&lt;/p&gt;

&lt;p&gt;Rails makes maintaining type-safety hard/impossible: amen, sister!  This is more than a problem for just Rails, though.  See ViewState in ASP.NET MVC.  I&#039;m really interested in this problem.  The MVC-ish pattern used in Rails and in ASP.NET seems to force type-UNsafety at the transition from Controller to View.  I hate it, but I&#039;m not sure how to fix it especially given that the MVC-ish structure seems to force type-UNsafety at the Controller-View intersection.  I held my nose and duplicated ASP.NET MVC&#039;s ViewState.&lt;/p&gt;

&lt;p&gt;Also, I&#039;m sold on creating a number of different environment types.  Multiple types would make the program more clear in return for minimally increased complexity.  ServerEnvironment, WorkerEnvironment, RequestEnvironment&lt;/p&gt;

&lt;p&gt;Monads: Agreed.  If I recall correctly, the problem I got into with Monads was that various libraries had their own monads and composing them together rarely worked, so I wound up incrementally backing down to just IO and then got everything working.  But I didn&#039;t like that solution and was frustrated by having to do so.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Curt,</p>

<p>Fantastic comment.  Taking it bits at a time:</p>

<p>Rails: I like it; you don&#8217;t.  Fair enough.</p>

<p>Porting Rails to Haskell: it&#8217;s a fairly standard exercise to bring favored practices from other languages/disciplines into new languages, so, while I agree with the &#8220;square peg &#8211; round hole&#8221; assessment of the project, it&#8217;s not unreasonable to undertake the project.  Especially when the project looks like an opportunity to web together a number of libraries into a more useful framework&#8230; except when the project then founders because its requirements and the libraries&#8217; construction/monads all conflict.</p>

<p>IO: I really like Haskell&#8217;s explicit usage of IO and I buy that not being careful with IO can get me into trouble&#8230; but I don&#8217;t think that I&#8217;m deluding myself if I choose to move to a language that is less strict about the usage of IO.  In fact, I&#8217;m acting rationally: I&#8217;m more productive across a range of problems and I can&#8217;t really think of a time when I&#8217;ve been bitten by sloppy IO.  (At which point someone will claim that I don&#8217;t know Haskell well enough or haven&#8217;t worked on large enough projects or something&#8230;)</p>

<p>Rails makes maintaining type-safety hard/impossible: amen, sister!  This is more than a problem for just Rails, though.  See ViewState in ASP.NET MVC.  I&#8217;m really interested in this problem.  The MVC-ish pattern used in Rails and in ASP.NET seems to force type-UNsafety at the transition from Controller to View.  I hate it, but I&#8217;m not sure how to fix it especially given that the MVC-ish structure seems to force type-UNsafety at the Controller-View intersection.  I held my nose and duplicated ASP.NET MVC&#8217;s ViewState.</p>

<p>Also, I&#8217;m sold on creating a number of different environment types.  Multiple types would make the program more clear in return for minimally increased complexity.  ServerEnvironment, WorkerEnvironment, RequestEnvironment</p>

<p>Monads: Agreed.  If I recall correctly, the problem I got into with Monads was that various libraries had their own monads and composing them together rarely worked, so I wound up incrementally backing down to just IO and then got everything working.  But I didn&#8217;t like that solution and was frustrated by having to do so.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Curt Sampson</title>
		<link>http://www.alsonkemp.com/haskell/reflections-on-leaving-haskell/comment-page-1/#comment-424</link>
		<dc:creator>Curt Sampson</dc:creator>
		<pubDate>Sun, 14 Mar 2010 10:03:30 +0000</pubDate>
		<guid isPermaLink="false">http://www.alsonkemp.com/?p=335#comment-424</guid>
		<description>&lt;p&gt;Speaking as someone who&#039;s written a web framework (massive deficiencies in Rails drove me to write my own in Ruby), and admittedly only having had a brief look at Turbinado, I feel that you&#039;ve made a few decisions that made things more difficult than they needed to be, especially given that you&#039;re doing this in Haskell.&lt;/p&gt;

&lt;p&gt;First, trying to model your system Rails is a bad idea. Not only is Rails more complex than it needs to be, but the overall design is really unsuited for a system with any sort of type discipline. With Rails, pretty much everything is accessible and can be changed anywhere.&lt;/p&gt;

&lt;p&gt;Second, yes, you really did want to split Environment into a few entirely separate types. Right now you&#039;ve got a system where, for example, a function that loads static configuration information (such as your CodeStore) is typed as taking a Maybe Request, and something that operates on a Request is not only typed as taking a Mabybe Request but is also typed as being able to modify your CodeStore. Even starting with the Java Servlet API would have cleaned up a lot of this; you&#039;ll note that Java API is fairly clear about what can and can&#039;t be modified as a ServletRequest and ServletResponse go through the processing chain, though both those classes have parts that can be modified.&lt;/p&gt;

&lt;p&gt;As a (stripped down) example of what you did and should have done, rather than having something like an &quot;Environment (Maybe CodeStore) (Maybe MimeTypes) (Maybe (HTTP.Request String))&quot; you really wanted an &quot;Environment CodeStore MimeTypes&quot;, &quot;Request Environment (HTTP.Request String)&quot;, and &quot;typedef Servelet = Request -&gt; Response -&gt; Response&quot; to indicate that a request cannot exist without a CodeStore etc., a response can be built up through stages, and neither the envirionment nor the original request can be modified by any Servlet (or whatever you care to call your service functions).&lt;/p&gt;

&lt;p&gt;Request Environment (HTTP.Request String)&quot;. That would show that a Request can&#039;t be handled without a CodeStore and a MimeTypes, nor can it modify the CodeStore and MimeTypes&lt;/p&gt;

&lt;p&gt;Third, it appears that you were designing a system, like Rails, where a a request handler (or Servlet, or whatever) can do pretty much anything on the system that any arbitrary program running as the web server user can do. If you really want to go that way, as you saw, the request handling code has to run in the IO monad. For programs of this nature you just need to accept that, rather than getting all uptight about it; even with that you can still end up with a fair amount of pure code, and have fairly good isolation of functions that do impure stuff. 
Looking at your list of Things You Could Do Without:&lt;/p&gt;

&lt;p&gt;Regarding your subclassing complaint, how one fixes any particular situation is heavily dependent on the exact details of the situation itself, so I can&#039;t provide much advice here, except to say that usually a fairly clean design can be found. Type classes and composition are your basic tools here. I gave a small example of one direction you might take things above, but no doubt it&#039;s wrong in the details for the particular idea of how you want your web server to work.&lt;/p&gt;

&lt;p&gt;Regarding monads, I love them myself, but you do have to find some way to really learn to understand them, both from the inside (writing your own) and the outside (good ways to use the interfaces they can present). You&#039;re right that monad transformers can get clunky quickly, which is why I don&#039;t use them all that much: when they do start to get clunky, I find that to be an indication that you should be writing your own custom monad rather than using a transformer stack. The key thing about monads is that they provide a powerful way of dividing up the total state of your program into discrete chunks, and knowing what functions modify what state. I think many Haskell programmers working on real-world applications concentrate too much on trying to make everything pure, and not enough on using state all over the place because it&#039;s convenient, but typing things so that, while you&#039;ve got lots of functions that deal with state, most of them deal with a very limited amount of state. STM is a good example of this sort of use: you know exactly what functions do and don&#039;t touch TVars and so on, and atomically is what drags a composition of these into the world of IO.&lt;/p&gt;

&lt;p&gt;Regarding IO, as I mentioned above, some sorts of programs just want to have a lot of functions in IO because they do a lot of &quot;real-world&quot; work. If you can&#039;t figure out how to bring more stuff out of IO, don&#039;t get too unhappy becuse you&#039;re still ahead of the game. Remember that switching away from Haskell means putting &lt;em&gt;every&lt;/em&gt; function into IO; if that doesn&#039;t make you even more unhappy, you&#039;re just deluding yourself.&lt;/p&gt;

&lt;p&gt;I&#039;m not clear from your example on what the issue with simpleFunction is. If you write it as &quot;otherFunction s &gt;&gt;= putStrLn&quot; it feels fairly functional to me when I remember that this is basically sugar where we&#039;re just passing a World state between the functions in a clever way. Playing a bit with the State monad and expanding the &quot;do&quot; syntactic sugar and then doing some by-hand evaluation of what&#039;s really going on may make this more clear.&lt;/p&gt;

&lt;p&gt;Let me give you one example of something where, even though IO is involved, things end up looking pretty clean. I&#039;ve got a custom monad within my trading system called OrderGen which handles state for one particular loop of the order (as in orders I send to the exchange) generator. It&#039;s typed as &quot;newtype OrderGen a = OrderGen { run :: State -&gt; IO (a,State) }&quot;, and so you can see that anything running in that monad can do IO. However, it&#039;s quite clear to me when exactly I&#039;m doing something in IO because I need to do an explicit liftIO to do that. As it turns out, in something just over a thousand lines of code in that part of the system, I call liftIO exactly nine times in only six out of well over a hundred functions. It&#039;s quite easy for me to find and review all of these cases and convince myself that this whole subsystem is only reading from and updating a very limited set of MVars and Channels, and also in one case doing a threadDelay. Try that with a thousand lines of code in any other language!&lt;/p&gt;

&lt;p&gt;cjs@cynic.net&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Speaking as someone who&#8217;s written a web framework (massive deficiencies in Rails drove me to write my own in Ruby), and admittedly only having had a brief look at Turbinado, I feel that you&#8217;ve made a few decisions that made things more difficult than they needed to be, especially given that you&#8217;re doing this in Haskell.</p>

<p>First, trying to model your system Rails is a bad idea. Not only is Rails more complex than it needs to be, but the overall design is really unsuited for a system with any sort of type discipline. With Rails, pretty much everything is accessible and can be changed anywhere.</p>

<p>Second, yes, you really did want to split Environment into a few entirely separate types. Right now you&#8217;ve got a system where, for example, a function that loads static configuration information (such as your CodeStore) is typed as taking a Maybe Request, and something that operates on a Request is not only typed as taking a Mabybe Request but is also typed as being able to modify your CodeStore. Even starting with the Java Servlet API would have cleaned up a lot of this; you&#8217;ll note that Java API is fairly clear about what can and can&#8217;t be modified as a ServletRequest and ServletResponse go through the processing chain, though both those classes have parts that can be modified.</p>

<p>As a (stripped down) example of what you did and should have done, rather than having something like an &#8220;Environment (Maybe CodeStore) (Maybe MimeTypes) (Maybe (HTTP.Request String))&#8221; you really wanted an &#8220;Environment CodeStore MimeTypes&#8221;, &#8220;Request Environment (HTTP.Request String)&#8221;, and &#8220;typedef Servelet = Request -&gt; Response -&gt; Response&#8221; to indicate that a request cannot exist without a CodeStore etc., a response can be built up through stages, and neither the envirionment nor the original request can be modified by any Servlet (or whatever you care to call your service functions).</p>

<p>Request Environment (HTTP.Request String)&#8221;. That would show that a Request can&#8217;t be handled without a CodeStore and a MimeTypes, nor can it modify the CodeStore and MimeTypes</p>

<p>Third, it appears that you were designing a system, like Rails, where a a request handler (or Servlet, or whatever) can do pretty much anything on the system that any arbitrary program running as the web server user can do. If you really want to go that way, as you saw, the request handling code has to run in the IO monad. For programs of this nature you just need to accept that, rather than getting all uptight about it; even with that you can still end up with a fair amount of pure code, and have fairly good isolation of functions that do impure stuff. 
Looking at your list of Things You Could Do Without:</p>

<p>Regarding your subclassing complaint, how one fixes any particular situation is heavily dependent on the exact details of the situation itself, so I can&#8217;t provide much advice here, except to say that usually a fairly clean design can be found. Type classes and composition are your basic tools here. I gave a small example of one direction you might take things above, but no doubt it&#8217;s wrong in the details for the particular idea of how you want your web server to work.</p>

<p>Regarding monads, I love them myself, but you do have to find some way to really learn to understand them, both from the inside (writing your own) and the outside (good ways to use the interfaces they can present). You&#8217;re right that monad transformers can get clunky quickly, which is why I don&#8217;t use them all that much: when they do start to get clunky, I find that to be an indication that you should be writing your own custom monad rather than using a transformer stack. The key thing about monads is that they provide a powerful way of dividing up the total state of your program into discrete chunks, and knowing what functions modify what state. I think many Haskell programmers working on real-world applications concentrate too much on trying to make everything pure, and not enough on using state all over the place because it&#8217;s convenient, but typing things so that, while you&#8217;ve got lots of functions that deal with state, most of them deal with a very limited amount of state. STM is a good example of this sort of use: you know exactly what functions do and don&#8217;t touch TVars and so on, and atomically is what drags a composition of these into the world of IO.</p>

<p>Regarding IO, as I mentioned above, some sorts of programs just want to have a lot of functions in IO because they do a lot of &#8220;real-world&#8221; work. If you can&#8217;t figure out how to bring more stuff out of IO, don&#8217;t get too unhappy becuse you&#8217;re still ahead of the game. Remember that switching away from Haskell means putting <em>every</em> function into IO; if that doesn&#8217;t make you even more unhappy, you&#8217;re just deluding yourself.</p>

<p>I&#8217;m not clear from your example on what the issue with simpleFunction is. If you write it as &#8220;otherFunction s &gt;&gt;= putStrLn&#8221; it feels fairly functional to me when I remember that this is basically sugar where we&#8217;re just passing a World state between the functions in a clever way. Playing a bit with the State monad and expanding the &#8220;do&#8221; syntactic sugar and then doing some by-hand evaluation of what&#8217;s really going on may make this more clear.</p>

<p>Let me give you one example of something where, even though IO is involved, things end up looking pretty clean. I&#8217;ve got a custom monad within my trading system called OrderGen which handles state for one particular loop of the order (as in orders I send to the exchange) generator. It&#8217;s typed as &#8220;newtype OrderGen a = OrderGen { run :: State -&gt; IO (a,State) }&#8221;, and so you can see that anything running in that monad can do IO. However, it&#8217;s quite clear to me when exactly I&#8217;m doing something in IO because I need to do an explicit liftIO to do that. As it turns out, in something just over a thousand lines of code in that part of the system, I call liftIO exactly nine times in only six out of well over a hundred functions. It&#8217;s quite easy for me to find and review all of these cases and convince myself that this whole subsystem is only reading from and updating a very limited set of MVars and Channels, and also in one case doing a threadDelay. Try that with a thousand lines of code in any other language!</p>

<p><a href="mailto:cjs@cynic.net">cjs@cynic.net</a></p>]]></content:encoded>
	</item>
	<item>
		<title>By: Gour</title>
		<link>http://www.alsonkemp.com/haskell/reflections-on-leaving-haskell/comment-page-1/#comment-422</link>
		<dc:creator>Gour</dc:creator>
		<pubDate>Sun, 14 Mar 2010 07:17:27 +0000</pubDate>
		<guid isPermaLink="false">http://www.alsonkemp.com/?p=335#comment-422</guid>
		<description>&lt;p&gt;@Alson:&lt;/p&gt;

&lt;blockquote&gt;
I still think that Turbinado is a great bit of code (down!, ego, down!), but it is very much a port of Rails to Haskell and doesn’t really feel like functional programming. I’m not entirely happy with some of the design decisions, but I’m very happy with the simplicity of developing web apps in Turbinado.
&lt;/blockquote&gt;

&lt;p&gt;Yeah, it could be, but, unfortunately, I never really tried it, hoping to see some more docs.&lt;/p&gt;

&lt;p&gt;I&#039;m also sad that nobody jumped in to help fixing design which finally brought you to the end. :-(&lt;/p&gt;

&lt;blockquote&gt;
The various Haskell web libraries have always struck me as a bit complicated, more like PHP web libraries than web frameworks.
&lt;/blockquote&gt;

&lt;p&gt;I confess that I still do not understand Yesod, but, at least, it has prospects to get proper back-end, to run on non-VPS (FCGI,SCGI etc.). Happs is also too complicated and non-practical for my use-case.&lt;/p&gt;

&lt;p&gt;It would be great to get one common &amp; decent web-framework for Haskell. (I just posted to web-devel list about it. You&#039;re are free to join. ;) )&lt;/p&gt;

&lt;p&gt;Sincerely,
Gour&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>@Alson:</p>

<blockquote>
I still think that Turbinado is a great bit of code (down!, ego, down!), but it is very much a port of Rails to Haskell and doesn’t really feel like functional programming. I’m not entirely happy with some of the design decisions, but I’m very happy with the simplicity of developing web apps in Turbinado.
</blockquote>

<p>Yeah, it could be, but, unfortunately, I never really tried it, hoping to see some more docs.</p>

<p>I&#8217;m also sad that nobody jumped in to help fixing design which finally brought you to the end. <img src='http://www.alsonkemp.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </p>

<blockquote>
The various Haskell web libraries have always struck me as a bit complicated, more like PHP web libraries than web frameworks.
</blockquote>

<p>I confess that I still do not understand Yesod, but, at least, it has prospects to get proper back-end, to run on non-VPS (FCGI,SCGI etc.). Happs is also too complicated and non-practical for my use-case.</p>

<p>It would be great to get one common &amp; decent web-framework for Haskell. (I just posted to web-devel list about it. You&#8217;re are free to join. <img src='http://www.alsonkemp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )</p>

<p>Sincerely,
Gour</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Jake McArthur</title>
		<link>http://www.alsonkemp.com/haskell/reflections-on-leaving-haskell/comment-page-1/#comment-420</link>
		<dc:creator>Jake McArthur</dc:creator>
		<pubDate>Sun, 14 Mar 2010 05:27:09 +0000</pubDate>
		<guid isPermaLink="false">http://www.alsonkemp.com/?p=335#comment-420</guid>
		<description>&lt;p&gt;&quot;Putting aside Turbinado’s Environment type, how do you grow a heterogeneous collection in Haskell?&quot;&lt;/p&gt;

&lt;p&gt;I&#039;d say the problem is not that it&#039;s difficult to do but that you wish to do it. This is just not how I believe Haskell should be used, generally. It&#039;s much nicer to work with small, composable parts which are simply not aware of each other. A design of this kind tend to avoid monstrosities like heterogeneous collections.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>&#8220;Putting aside Turbinado’s Environment type, how do you grow a heterogeneous collection in Haskell?&#8221;</p>

<p>I&#8217;d say the problem is not that it&#8217;s difficult to do but that you wish to do it. This is just not how I believe Haskell should be used, generally. It&#8217;s much nicer to work with small, composable parts which are simply not aware of each other. A design of this kind tend to avoid monstrosities like heterogeneous collections.</p>]]></content:encoded>
	</item>
</channel>
</rss>

