tag:blogger.com,1999:blog-71535146555538758102024-03-23T15:26:30.235+01:00Monadic Headachesmain = putStrLn $ b :: Programming t => IO Blog tCristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.comBlogger23125tag:blogger.com,1999:blog-7153514655553875810.post-46023586527350608242008-05-09T16:46:00.001+02:002008-05-09T17:00:37.267+02:00Javascript syntax highlighting for Haskell codeLots of time passed since my last post. I've been busy but this week I got sick and had some time to hack a bit.<br /><br />As I said in my last post, I was sick of Blogger's way of indenting my Haskell code. I was on the verge to move to wordpress.com, which provides seamless support for the excellent <a href="http://code.google.com/p/syntaxhighlighter/">syntaxhighlighter</a>. Too bad, syntaxhighlighter doesn't provide Haskell support out-of-the-box.<br /><br />Hence, I decided to write <a href="http://cristiano.paris.googlepages.com/shBrushHaskell.js">one</a> myself. Go get it! Then, follow <a href="http://developertips.blogspot.com/2007/08/syntaxhighlighter-on-blogger.html">these instructions</a> to get it to work with Blogger.<br /><br />Here's an example of what it can do:<br /><br /><pre name="code" class="hs"><br />{-dfhc: by jAS 000807-}<br /><br />module Import (importOne) where<br /><br />import IO<br />import PackedString(PackedString,packString,unpackPS)<br />import Flags<br />import OsOnly(fixImportNames,isPrelude)<br />import Extra<br />import Syntax(Module,ImpDecl,Type,Decls,Decl,FixId,InfixClass(..),Simple,<br /> Context,Constr)<br />import Lex(Lex)<br />import TokenId(TokenId(..),tPrelude,rpsPrelude,extractV)<br />import ParseCore(Parser(..),ParseBad(..),ParseError(..),ParseGood(..),<br /> ParseResult(..),parseit)<br />import ParseI<br />import Lexical(PosToken(..),PosTokenPre(..),LexState(..),lexical)<br />import State<br />import Error<br />import IExtract<br />import ImportState(ImportState,putModid2IS)<br />import IntState(dummyIntState)<br />import PPSyntax(ppModule,ppDecl,ppDecls,ppImpDecls,ppInterface,ppFun,ppClassCodes)<br /><br />#if !defined(__HASKELL98__)<br />#define ioError fail<br />#endif<br /><br />openImport:: Flags -> PackedString -> IO (String,String,String)<br />openImport flags mrps =<br /> catch<br /> (do<br /> (fstr,finput) <- readFirst filenames<br /> if sImport flags<br /> then hPutStr stderr<br /> ("Importing module "++mstr++" from "++fstr++".\n")<br /> else return ()<br /> return (mstr,fstr,finput))<br /> (\err -> ioError (userError (can'tOpenStr mstr filenames err)))<br /> where<br /> isUnix = sUnix flags<br /> preludes = sPreludes flags<br /> includes = sIncludes flags ++ preludes<br /> mstr = (reverse . unpackPS) mrps<br /> filenames =<br /> fixImportNames isUnix mstr<br /> (if isPrelude mstr then preludes else includes)<br /><br />readFirst:: [String] -> IO (String,String)<br />readFirst [] = hPutStr stderr "Fail no filenames, probably no -I or -P" >> exit<br />readFirst [x] = do<br /> finput <- readFile x<br /> return (x,finput)<br /></pre><br /><br />Of course, you can help improve it! While waiting for me to setup a page for this (which could take foerever), patches and comments are very welcomed!Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com5tag:blogger.com,1999:blog-7153514655553875810.post-38866524914307584302008-01-31T22:35:00.001+01:002008-01-31T22:35:50.838+01:00Sick of BloggerAnd yes! I'm sick of Blogger... going to change that really soon...Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com2tag:blogger.com,1999:blog-7153514655553875810.post-86549602540340958312008-01-31T21:12:00.004+01:002008-05-09T16:45:53.649+02:00More on Python 2.5's generatorsThe implementation I <a href="http://monadicheadaches.blogspot.com/2008/01/python-25s-iterators-in-haskell-sort-of.html">proposed</a> is actually flawed. No sooner than I wrote it, I noticed that the value returned after a send call doesn't depend on the value passed to send itself.<br /><br />Why? Let me explain the situation. First, let's call the "sender" the function calling send, and "recipient" the function calling the yield.<br /><br />The recipient's yield call is:<br /><br /><pre name="code" class="hs:nocontrols:nogutter"><br />y <- yield x<br /></pre><br /><br />Conversely, the sender's call is:<br /><br /><pre name="code" class="hs:nocontrols:nogutter"><br />x <- send y<br /></pre><br /><br />Can you see the point? x depends only on what happened in the receiver's past, so it can't depend on y, which is actually in the receiver's future. The same happens to the sender. So:<br /><br /><pre name="code" class="hs:nocontrols"><br />bar = do x <- yield 1<br /> yield $ x+5<br /><br />foo = do y1 <- send 1999<br /> y2 <- send 100<br /> return [y1,y2] </listing><br /></pre><br /><br />returns [1,2004]. That's not the way a Python 2.5's iterator works. Actually, such an iterator can't work at all!<br /><br />If you can't believe this, try and run the equivalent piece of code in a Python 2.5 interpreter:<br /><br /><pre name="code" class="py:nocontrols"><br />def bar():<br /> x = (yield 1)<br /> yield x+5<br /><br />def foo():<br /> it = bar()<br /><br /> y1 = it.send(1999)<br /> y2 = it.send(100)<br /><br /> return [y1,y2]<br /></pre><br /><br />You'll get the following error:<br /><br /><listing><br />TypeError: can't send non-None value to a just-started generator<br /></listing><br /><br />That simply means that you can't call send() if haven't previously called next(). That's exactly the same reason why my implementation was wrong: the semantics of send() says that the value returned by it must depend on the value passed to it. But, in the first yield() this semantics can't be fulfilled because the value passed to the yield depends only on the past in which, for the first call, can't include the value passed to send().<br /><br />On subsequent calls, how can Python assure the semantics of send()? The answer is both easy and surprising: the value returned by send() depends on the next yield(), for which that value is actually in its past!<br /><br />The solution I come up with is rewriting the send function and writing a next in this way:<br /><br /><pre name="code" class="hs:nocontrols"><br />next = do (RP (y,_)) <- get<br /> return y<br /><br />send x = do (RP (_,f)) <- get<br /> let rp@(RP (y',f')) = f x<br /> put rp<br /> return y'<br /></pre><br /><br />Now it works as expected. Notice that, surprisingly, the semantics of send/next depends only on send and next implementation: the yield function is completely apart from it.Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com5tag:blogger.com,1999:blog-7153514655553875810.post-36577231670100557042008-01-31T13:44:00.000+01:002008-01-31T14:09:05.773+01:00Python 2.5's iterators in Haskell (sort of)<blockquote><strong>DISCLAIMER</strong>! The code I present here is likely to be far from perfect and in fact I ask for comments from the community, specifically on how to get rid of the "RecPair" user data type.</blockquote><br />Is it possible to mimic Python 2.5's iterators in Haskell? If you don't<br />know what iterators are (or you're used to 2.4's ones), have a look to <a href="http://docs.python.org/whatsnew/pep-342.html">PEP343</a>.<br />By and large, iterators are Python's way to surrogate continuations, which<br />represent a more general concept usually found in FP languages.<br /><br />Basically, I want to be able to write something like:<br /><br /><listing><br />bar = do y <- yield 1<br /> yield (y+2)<br /></listing><br /><br />and have bar return immediately the argument in a yield call to the caller. Yet, the caller should look like:<br /><br /><listing><br />foo k = do x <- send undefined -- this will be ignored<br /> y <- send k<br /> return $ [x,y]<br /></listing><br /><br />First two considerations:<br /><br /><ul><br /><li>It natural to use the Cont monad when implementing the yield function.</li><br /><li>As two successive calls to send may have different outcomes, some sort of state must be involved. For the basic implementation we resort to State monad.</li><br /></ul><br /><br />When trying to solve the puzzle, I stumbled upon a beautiful and straightforward <a href="http://www.haskell.org/pipermail/haskell/2005-April/015684.html">implementation</a> of Python 2.4's iterators by David Menendez. The problem of extending his approach to 2.5 iterators turned out to be a bit more difficult. First, I'll show you the code:<br /><br /><listing><br />module Main where<br /><br />import Control.Monad.Cont<br />import Control.Monad.State<br /><br />data RecPair a b = Nil RP (b,a -> RecPair a b)<br /><br />yield x = Cont $ \k -> RP (x,k)<br /><br />send x = do (RP (y,f)) <- get<br /> put $ f x<br /> return y<br /><br />runYield it cl = evalState cl $ runCont it $ \_ -> Nil<br /></listing><br /><br />Let's discuss the yield funtion's implementation. First, as we're working<br />in the Cont monad, we must return a Cont value which is basically a<br />function taking a continuation (what to do next) and build a pair (x,k).<br /><br />x is the value passed to the yield function and then returned to the<br />caller.<br /><br />What about k? In my mind, k is a function taking an argument (the<br />receiving variable of a '<-' statement in a do-block) and returning another pair (x',k'), which is the result of the next small step of the Cont computation, till the next yield call. In this way, a computation can't go on after a yield statement until you feed it with a value through a send call, which is the semantics of iterators. Naively, at start I wrote: yield x = Cont $ \k -> (x,k)<br /><br />But ghc promptly issued the following error:<br /><br /><listing><br />Occurs check: cannot construct the infinite type t = a -> (t1,t)<br /></listing><br /><br />What's going on? Let's try and do some type analysis:<br /><br /><ol><br /><li>The type of "\k -> (x,k)" is "t -> (b,t)" which is perfectly right, as long as "x" is in the scope of that definition and is of type "b".</li><br /><li>But, the argument of "Cont" must have type "(a -> r) -> r".</li><br /><li>Let's do the bindings: "t = a -> r" and "r = (b,t)".</li><br /><li>Substituting the latter in the former we obtain "t = a -> (b,t)".</li><br /></ol><br /><br />This equation is clearly impossible to solve (no types exist to make the<br />equation true) and the Haskell's type system did his job.<br /><br />How to escape the problem? The real point here is that the above type<br />equation can be expanded infinitely. There must be a way to stop the<br />expansion. What if "r" would be masked by an opaque type?<br /><br />Enter RecPair. We turn the above equation into:<br /><br /><listing><br />t = a -> RecPair a b<br /></listing><br /><br />which is perfectly solvable provided there are instances of the type<br />"RecPair a b". In the above snippet you can find a convenient definition of<br />RecPair which is suitable to our goal. There are other, like:<br /><br /><listing><br />data RecPair a b = Nil RP (a -> (b,RecPair a b))<br /></listing><br /><br />which turns out to be less elegant when you modify yield and send<br />accordingly.<br /><br />The other part of the code is just plain Haskell code. Notice that solution<br />I proposed doesn't mimic completely Python 2.5's iterators: for example,<br />send can't deal with more than one iterator at the time due to the use of the State monad.<br /><br />But these are only technicalities which can be easily overcome, for instance,<br />using the IO Monad and a couple of IORef here and there.Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com96tag:blogger.com,1999:blog-7153514655553875810.post-76221616400794842332008-01-29T17:47:00.000+01:002008-01-29T18:27:02.278+01:00syb-with-class 0.4 for HAppSWhile I was trying to compile HAppS, I needed version 0.4 the syb-with-class package, which is not in the HackageDB (yet, I hope). I had to grab it from:<br /><br /><span style="font-family:courier new;">darcs get http://happs.org/HAppS/syb-with-class</span><br /><br />Hope this will help anyone trying to compile HAppS.Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com1tag:blogger.com,1999:blog-7153514655553875810.post-14174699580074730602008-01-21T20:06:00.000+01:002008-01-29T15:08:18.379+01:00Xmonad side bye side KDEAs you may know, I <a href="http://monadicheadaches.blogspot.com/2007/10/bye-bye-ubuntu.html">recently</a> switched to ArchLinux... those guys are doing an excellent work and, after some months, I got completely addicted to that <a href="http://kdemod.ath.cx/about.html">kdemod</a> thing... I missed Xmonad though, which jumped from 0.2 to 0.5 in the meanwhile and I badly wanted to give it a try and test out the new features...<br /><br />What to do? Well, it's indeed possible to run xmonad and kde side-by-side on the same PC. You could fire up a new Xserver on a different display but switching between them may not be fast enough.<br /><br />Instead, my solution relies on Xnest, an X server running in a window of another X server.<br /><br />Here's the command line I use:<br /><br /><span style="font-family:courier new;">kstart --desktop 2 --fullscreen -- xinit ~/.xinitrc.xmonad -- /usr/bin/Xnest :10 -geometry 1600x1200 -ac</span><br /><br />where .xinit.xmond simply contains:<br /><br />/usr/bin/xmonad<br /><br />The command will open a new full-screen Xnest window, with no window decoration, on virtual desktop number 2. Now, you can use the usual shortcuts to switch between virtual desktops to go back and forth KDE and Xmonad.<br /><br />Best of the two worlds!<br /><br />UPDATE! Too bad, cut&paste doesn't work between Xnset and the real X server beneath. Any hints?Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com0tag:blogger.com,1999:blog-7153514655553875810.post-34104485093907598862007-12-05T16:54:00.000+01:002007-12-06T20:10:21.033+01:00More on Point-Free Programming StyleI discovered that programming in Point-Free Style can be addictive! Today, I wrote two perverse functions using PFS before discovering I had spent almost two hours just two add two lines to my code!!!<br /><br />Here's the one of the two:<br /><br /><span style="font-size:85%;"><span style="font-family:courier new;">foo = uncurry (.) . (map . second . drop . length &&& (filter . (flip $ flip isPrefixOf . snd)))</span></span><br /><br />Sorry if it didn't fit in your screen. I used the name <span style="font-family:courier new;">foo</span> purposedly: can you imagine what this function does?<br /><br />If you can't come up with a solution in less than 1 minute, the above code is a failure as it means nothing to you (i.e. its meaning is not apparent).<br /><br />Try with the following version:<br /><br /><span style="font-family:courier new;">foo p [] = []</span><br /><span style="font-family:courier new;">foo p ( (k,l):os ) | p `isPrefixOf` l = (k,take (length p) l) : foo p os</span><br /><span style="font-family:courier new;"> </span><span style="font-family:courier new;">| otherwise = foo p os</span><br /><br />Sorry for the bad layout.<br /><br />It took two hours to me to figure out how and where to put all those . and $ in the first version but it was fun, just like winning a game.<br /><br />On the other hand, I wrote the second version as I was writing this post. I think the reason why I write PFS code much much slower lies both in my lack of knowledge of PFS programming and my way of reasoning about programs.<br /><br />Nevertheless, PFS is appealing to me because I'm used to write shell scripts to automate things on the systems I manage: PFS is all about composing and piping functions, mostly like you compose and pipe shell programs.<br /><br />I wonder if I'll be able to guess the meaning of the PFS functions I wrote after some months: we'll see.<br /><br />As a side note, I noticed that the following pattern is coming up rather often when coding in FPS:<br /><br /><span style="font-family: courier new;">goo = uncurry g . (foo &&& bar)</span><br /><br />which means:<br /><br /><span style="font-family: courier new;">goo i = foo i `g` bar i</span><br /><br />So, I wonder whether the following combinator would help to making FPS code more readable:<br /><br /><span style="font-family: courier new;">f `interspersedBy` g = uncurry g . f</span><br /><br />So, the above snippet would become:<br /><br /><span style="font-family: courier new;">goo = (foo &&& bar) `interspersedBy` g</span>Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com3tag:blogger.com,1999:blog-7153514655553875810.post-32267592819107211472007-12-04T21:55:00.000+01:002007-12-05T09:38:53.678+01:00Arrows first encounter<strong>UPDATE</strong>: My post appeared on Reddit's programming feed. Thank you! Also, my post's title should've been "Point-free programming style first encounter", but I'm too lazy to change it ^_^<br /><br />I was really busy lately so no post around for a while. Surprisingly, I wasn't busy wrinting code but actually thinking about the problem: this is feasible in Haskell as the code is more concise and the typing system keeps you from doing stupid design mistakes (or at least make them appear earlier than in other programming language).<br /><br />Now, done with the ritual Haskell-awe prologue, here my post for today.<br /><br />Lately, I've been working to a program manipulating objects which turned out to be monomials, which I represented as a pair of (Double,[Int]), i.e.:<br /><br />(4.0,[1,2,-1,-2]) -> 4.0 x(1,1) x(2,2) x(3,-1) x(4,-2)<br /><br />where x(i,j) are unknowns indexed by a pair. Since I assume that the first component of the unknowns' pairs will be the sequence 1,2,3,... I only need to specify the second component. I know, it's kinda weird, but it has to do with my domain problem which is related to finite difference operators for PDE.<br /><br />Now I want to define a "product" operator which works like this:<br /><br />(k,[b,c,d]) * (h,[e,f,g]) = (k*h,[a+e, c+f, d+g])<br /><br />I can define this like follows:<br /><br />prod (k,ll) (h,rl) = (k*h, zipWith (+) ll rl)<br /><br />This is perfectly correct and good as it's very expressive.<br /><br />Now, I want to apply the same function monadically to list arguments, i.e.:<br /><br />prod :: [(Double,[Int])] -> [(Double,[(Double,[Int])] -> [(Double,[Int])]<br /><br />To do this, I'll use liftM2 which take a function of two arguments and applies it to every pair formed taking an element from the first list and an element from the second. So:<br /><br />prodM = liftM2 prod<br /><br />But I'll never use prod by itself, so let's put this in a lambda abstraction and rename prodM to prod:<br /><br />prod = liftM2 $ \(k,ll) (h,rl) -> (k*h, zipWith (+) ll rl)<br /><br />Again, this is correct but my Haskell soul is becoming more strict and such a formulation sounds bad to me (I could've felt perfectly right with some month ago). I don't like lambdas when used this way, I see as an intrusive element in the perfect world of function combinators/operators (and liftM2 is such a combinator). More, I had to specify that prod requires two tuples while it'd be neat if the compiler could infere this automatically: I see this as code replication issue.<br /><br />The solution to this dilemma is using point-free style programming. I'll abuse arrow combinators a bit. Specifically, there's the (***) operator which takes two function f and g and applies them to a tuple:<br /><br />(f *** g) (a,b) = (f a, g b)<br /><br />What if I need to combine two tuples using two separate binary operators? I.e.:<br /><br />(f ***' g) (a,b) (c,d) = (f a c, g b d)<br /><br />Arrows module doesn't provides such a combinator but we could build one. First, if we combine f and g using (***), we get a pair of two functions as f and g are partially evaluated. What we need now is to interpose (***) between these two functions. How to do this? Simple, we just need to uncurry (***). So, now:<br /><br />(f ***' g) = uncurry (***) . (f *** g)<br /><br />and we're done as f ***' g returns a function taking two tuples and apply f and g separately to each component. This is good as we can rewrite prod as:<br /><br />prod = liftM2 $ uncurry (***) . ((*) *** (zipWith (+)))<br /><br />which is essentially a smart combination of functions. Notice that no arguments of prod has been specified: this is where point-free programming style really lies. Changing the way prod is written will change the type of its arguments, in single place, without requiring you to rewrite them in two places (i.e. the argument list).Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com0tag:blogger.com,1999:blog-7153514655553875810.post-59654072614350242922007-11-14T21:22:00.000+01:002007-11-14T22:23:15.156+01:00Random numbers (where it all started)At first, Haskell seemed a reasonable language... until Monads appeared! Until then, purity was a clear plus of Haskell but... what about a random number generator (RNG)?<br /><br />A pure function is deterministic: it depends only on its inputs and, as computers are deterministic as well, its output must be the same given the same input data.<br /><br />Conversely, an RNG function (at least as it's known in the imperative world) must be non-deterministic and return a different outcome whenever it's called (without arguments).<br /><br />So, how to code an RNG function in Haskell? Enter Monads.<br /><br />Haskell can't give up on purity, so the solution is simple: instead of returning a value, an RNG function returns a <span style="font-style: italic;">computation</span>.<br /><br />A <span style="font-style: italic;">computation</span> is like a machine with some pipes going in. By itself, the machine doesn't do anything. But, if you <span style="font-style: italic;">run</span> it, providing fuel through the pipes, it will eventually produce something.<br /><br />The machine is pure, while the fuel is impurity (or side-effects). The fuel comes from the environment under which the machine is run.<br /><br />So, an RNG function is actually a machine which, when run under the special enviroment of the IO Monad, provides a number. More, you can build a special RNG machine (i.e. write an RNG computation) producing an infinite list of random numbers: just fill in sufficient fuel until more random numbers are needed!<br /><br />In this way, Haskell let's you stay on the pure side when building the computation, letting you do all sort of things a computer theorist would do to a program (applying transformations, proving properties...), and getting you dirty when running your computation.<br /><br />Sometimes it's hard to catch up with the meaning of Monads at first because the first Monad you encounter is the IO Monad, which is implicitly run by the Haskell run-time environment. So, you lose the concept that a Monad computation must be run to produce something useful.<br /><br />For instance, the State Monad has <span style="font-family: courier new;">runState</span> function. But, as I said in one of my previous post, IO has its own run function: <span style="font-family: courier new;">unsafePerformIO</span>, from Foreign module.<br /><br />So, let's see how to build an RNG computation:<br /><br /><span style="font-family: courier new;">randomList r = do g <- getStdGen</span><br /><span style="font-family: courier new;"> return $ randomRs r g</span><br /><br /><span style="font-family: courier new;">randomList</span> takes a pair representing a range of numbers and return a computation that, when run, provides an infinite list of numbers. Indeed, <span style="font-family: courier new;">randomList</span>'s type is:<br /><br /><span style="font-family: courier new;">Num a => (a,a) -> IO [a]</span><br /><br />Specifically, when you state:<br /><br /><span style="font-family: courier new;">g <- getStdGen</span><br /><br />you are saying something like: "<span style="font-family: courier new;">g</span> is a pipe. When you run this computation, please provide a <span style="font-family: courier new;">StdGen</span> value here". <span style="font-family: arial;">randomRs</span> is a plain pure function taking a <span style="font-family: courier new;">StdGen</span> (which is basically a seed with a <span style="font-family: courier new;">next</span> function iterated to provide an infinite list of random number from it) and the range to which random numbers must be belong to.<br /><br />How do we run this machine? Simple: put unsafePerformIO in front of it.<br /><br /><span style="font-family: courier new;">randomList r = unsafePerformIO $</span><br /><span style="font-family: courier new;"> do g <- getStdGen</span><br /><span style="font-family: courier new;"> return $ randomRs r g</span><br /><br />Now <span style="font-family: courier new;">randomList</span> produces an infinite list of random numbers because it'll run the computation inside it.<br /><br />But, beware! <span style="font-family: courier new;">randomList</span> is now and impure function masked as a pure function. Haskell could tricked by this masking and make the wrong thing misled by the purity assumption.<br /><br />So, I promised myself not to write another Monad tutorial, but I did, at last!Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com3tag:blogger.com,1999:blog-7153514655553875810.post-34463488859936381182007-11-07T19:40:00.000+01:002007-11-07T19:45:52.126+01:00Again a post about Haskell performancesI've found an interesting <a href="http://augustss.blogspot.com/2007/11/benchmarking-ray-tracing-haskell-vs.html">article</a> describing how to make an Haskell program run as fast as the OCaml version, which is often regarded as the workhorse among FP languages. Three points grabbed my attention the most:<br /><ol><li>ghc 6.8 seems to boost the performances of Haskell programs: in some cases the benchmarks show programs run twice as faster as those compiled with ghc 6.6.</li><li>Faster Haskell programs are written similarly to OCaml version.</li><li>OCamls versions are no longer than their Haskell versions.</li></ol>Something to think about!Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com0tag:blogger.com,1999:blog-7153514655553875810.post-45762174327696389942007-11-05T19:18:00.000+01:002007-11-05T19:20:53.451+01:00"Making Haskell programs faster and smaller"I've just found this <a href="http://users.aber.ac.uk/afc/stricthaskell.html">article</a> through a nice <a href="http://calculist.blogspot.com/">blog</a> about programming languages. Haven't read it yet, but surely something to put apart!Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com0tag:blogger.com,1999:blog-7153514655553875810.post-81515216740035019332007-11-02T08:53:00.000+01:002007-11-02T08:55:18.704+01:00Oh... my god ^_^From reddit:<br /><br /><a href="http://reddit.com/goto?rss=true&id=t3_5zmgd" target="_blank">How many Java programmers does it take to round up to a power of two?</a>Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com1tag:blogger.com,1999:blog-7153514655553875810.post-88429530541752719792007-10-31T21:58:00.000+01:002007-12-05T09:33:20.398+01:00The typical Haskell programmer's customsWhen learning a new programming language, it's very important to learn the best practices arising from the community. For example, in Java you learn pretty soon to name your stuff in CamelCase: you'll make your code more readable by others and, at the same time, you're likely to avoid the mistakes others did before.<br /><br />Haskell is no different and I found a good <a href="http://www.serpentine.com/blog/2007/05/14/norvigs-spell-checker-and-idiomatic-haskell/">article</a> by Bryan O’Sullivan, somewhat related to this.Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com0tag:blogger.com,1999:blog-7153514655553875810.post-6566028310236942007-10-25T12:12:00.000+02:002007-10-25T12:33:10.365+02:00Bye bye, UbuntuA couple of years ago, I started using a new and (at that time) unknown GNU/Linux dsitribution. It was called Ubuntu Warty 4.10. The things I liked in that distro were the hardware detection module and the fact it stemmed from Debian, which I always wanted to give a try.<br /><br />Two days ago, I decided to upgrade my system (a Feisty Fawn) to the latest version, Gutsy Gibbon.<br /><br />The upgrade process died at 60%, more or less, due to a problem in the nvidia-driver install script which managed to give up after seeing a diversion from the base package (ah! total functions!).<br /><br />Now, I have a half-upgraded system and I can't finish the upgrade as apt-get says everything is current, and have xorg doing all sort of funny things, the Gnome applets not working anymore, mplayer segfaulting... I even filed a <a href="http://ubuntuforums.org/showthread.php?t=587020&highlight=cristiano+paris">help request</a> in the Ubuntu forums, like any other newbie out there, but got nothing in return: perhaps the community has become so large that a rather common help request now pass unobserved...<br /><br />So, time to change. It happened in the past and is likely going to happen again in the future: I switched from Slackware to Red Hat to Slackaware to Gentoo to Ubuntu. Now it's time for <a href="http://www.archlinux.org/">ArchLinux</a>. I've been using it for a while now, on a VMWare VM and, apart from being quite satisfied, I'm impressed as well.<br /><br />pacman works like a charm: simple and effective. Everything gets configured neatly and almost everything worked out of the box.<br /><br />Of course, this means that I'll have to configure my devices and xorg myself, insted of relying on some Ubuntuish automatic tool. But, at least, I'd know what's going on.<br /><br />So, bye bye Ubuntu. Welcome ArchLinux.Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com2tag:blogger.com,1999:blog-7153514655553875810.post-78765058416611559772007-10-22T15:32:00.001+02:002007-10-23T10:41:50.575+02:00Is Haskell really expressive?My idea of an <em>expressive</em> program is one whose meaning (or at least the meaning of its functions when taken apart) is <em>kind of </em>intuitive.<br /><br />Haskell is often remarkably pointed out as an expressive language. Nevertheless, I'd say that a language is simply a weapon in the hand of the developer and that expressiveness mostly depend solely on him.<br /><br />Indeed, consider the following Haskell piece of code:<br /><br /><span style="font-family:courier new;">cartesian = (foldl (liftM2 $ flip (:)) [[]]).(map (\n -> [0..n-1]))</span><br /><br />Apart from its name, would you tell that this function evaluates a multiple cartesian product? Actually you need to have an intermediate knowledge of Haskell and its libraries to catch the meaning of this function:<br /><ul><li>You should know that <span style="font-family:courier new;">foldl</span> is like a generic "summation"</li><li>You should know that <span style="font-family:courier new;">liftM2</span> will lift a function taking two arguments into a Monad (the List Monad actually).</li><li>You should know that semantics of the List Monad has to do with non-determinism, i.e. passing two lists to a lifted function will result in applying that function to each and every pair built from them.</li></ul><p>Writing programs this way is really concise but I sometimes feel like it's not really intuitive. My understanding of Haskell programs improves everyday and lots of Haskell snippets I've read in the past are now less obscure. But I think my most importat breakthrough in understanding the language will happen when I'm able to make the above snippet's meaning apparent even for the almost occasional (and non-Haskell) programmer.</p>Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com5tag:blogger.com,1999:blog-7153514655553875810.post-91173717421226834562007-10-22T12:05:00.001+02:002007-10-22T12:07:11.557+02:00Haskell concurrencyHere's an <a href="http://mult.ifario.us/articles/2007/10/21/tuppence-tour-of-haskell-concurrency-constructs">article</a> introducing Haskell concurrency constructs for the two paradigms out there: message passing (à-la Erlang) and shared-memory (the rest of us).Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com0tag:blogger.com,1999:blog-7153514655553875810.post-85447431425330551952007-10-16T11:37:00.001+02:002007-10-16T11:39:52.430+02:00Algebraic rules for GHCAs I'm still experimenting with Haskell, I'm not into Haskell code optimization yet.<br /><br />Anyhow, I think the intermediate ghc user might find the following document interesting:<br /><br /><a href="http://www.haskell.org/haskellwiki/Playing_by_the_rules">Playing by the rules</a><br /><br />It sort of explains how to get advantage of the equational-like form of Haskell programs to teach ghc simple rules to optimize an Haskell program.Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com0tag:blogger.com,1999:blog-7153514655553875810.post-61719266895892654442007-10-15T15:48:00.001+02:002007-10-15T15:51:38.065+02:00BoilerplatesAn interesting application of generic programming and data structures:<br /><br /><a href="http://www.defmacro.org/ramblings/haskell-web.html">Haskell and Web Applications</a><br /><br />Here is the documentation about <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Generics-Basics.html">Data.Generics.Basics</a> which is useful to understand what the above article is all about.Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com0tag:blogger.com,1999:blog-7153514655553875810.post-4020315982447379682007-10-09T22:32:00.000+02:002007-10-09T22:34:07.501+02:00HAppShttp://bluebones.net/2007/09/simple-haskell-web-programming-with-happs/Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com0tag:blogger.com,1999:blog-7153514655553875810.post-1573957372542670772007-10-09T21:37:00.000+02:002007-10-09T21:38:17.919+02:00Control.Monad.Fix: recursive lambda abstractionshttp://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad-Fix.htmlCristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com0tag:blogger.com,1999:blog-7153514655553875810.post-71054621436936856632007-10-09T11:49:00.000+02:002007-10-09T11:52:13.657+02:00CleverCSS<a href="http://sandbox.pocoo.org/clevercss-hs/">http://sandbox.pocoo.org/clevercss-hs/</a>Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com0tag:blogger.com,1999:blog-7153514655553875810.post-7263863089361491522007-10-08T19:57:00.000+02:002007-10-08T20:57:48.465+02:00Tracing your code... the dirty way!<span style="font-weight: bold;">Problem</span>: you want to trace your Haskell program but you're scared that touching anything might thrash your type hackery.<br /><br /><span style="font-weight: bold;">Solution</span>: Use <span style="font-family:courier new;">Debug.Trace.trace</span> wherever you want to print something on the console:<br /><br /><span style="font-style: italic;">Before</span>: <span style="font-family:courier new;">map f (x:xs) = (f x):(map f xs)</span><br /><span style="font-style: italic;">After</span>: <span style="font-family:courier new;">map f (x:xs) = trace "Here I am" $ (f x):(map f xs)</span><br /><br /><span style="font-weight: bold;">Explanation</span>: I was trying to understand how <a href="http://happs.org/">HAppS</a> worked and I really missed the possibility to put a harmless print statemente here and there in the code just to get the feeling of what was happening in the behinds, as I'd do in an imperative language like python.<br /><br />The problem is that we have to deal with Haskell purity so if you want to print something in a Haskell program, you have to do it inside the <span style="font-family:courier new;">IO</span> Monad.<br /><br />So far so good, but IO is not available everytime you need it... at least not the "official" one. In fact Haskell allows you to enter the IO Monad anytime you need it and perform an IO action straight away using the <span style="font-family:courier new;">unsafePerformIO</span> function.<br /><br />"Unsafe" means that you use it at your own risk, since you're doing something impure in a pure environment. Of course, <span style="font-family:courier new;">trace</span> has nothing to do with the real meaning of the traced funcion, so it's perfectly safe to use it that way.<br /><br />I spent almost an hour to figure out how to do this, so I hope this trick will save you time.Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com0tag:blogger.com,1999:blog-7153514655553875810.post-3342476056803120012007-10-08T19:46:00.000+02:002007-10-09T11:36:17.899+02:00A new programming blogI start this new blog for the following purposes:<br /><ul><li>I'm learning new programming paradigms. Actually, I'm focusing on <a href="http://www.haskell.org/">Haskell</a> but I take a peek to other langs from time to time, like Lisp, Erlang and so on. Having a blog is a great way to get support from the community (provided I write interesting posts) and have a place to store my findings so I can look them up when needed.<br /></li><li>A place to post things I find on the web and worth mentioning.</li><li>I don't know yet, but I'll add something in lazy-haskelish way as soon as I find it.</li></ul>Let's get started.Cristiano Parishttp://www.blogger.com/profile/16571894970486579772noreply@blogger.com0