<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>My Other Pants &#187; functional</title>
	<atom:link href="http://myotherpants.com/tag/functional/feed/" rel="self" type="application/rss+xml" />
	<link>http://myotherpants.com</link>
	<description>I left it in my other pants</description>
	<lastBuildDate>Tue, 24 Jan 2012 18:11:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Unsoliceted Code Review &#8211; Haskell Chat Server Edition</title>
		<link>http://myotherpants.com/2011/10/unsoliceted-code-review-haskell-chat-server-edition/</link>
		<comments>http://myotherpants.com/2011/10/unsoliceted-code-review-haskell-chat-server-edition/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 14:20:16 +0000</pubDate>
		<dc:creator>Ball</dc:creator>
				<category><![CDATA[work safe]]></category>
		<category><![CDATA[codereview]]></category>
		<category><![CDATA[functional]]></category>
		<category><![CDATA[haskell]]></category>

		<guid isPermaLink="false">http://myotherpants.com/?p=278</guid>
		<description><![CDATA[Our most recent Sep book club has been The Passionate Programmer. One of the things mentioned was taking some third party code and reviewing it. This is not a new idea. Many people has said the best way to understand the code you write is to understand the good and bad of code written by [...]]]></description>
			<content:encoded><![CDATA[<p>Our most recent <a href="http://www.sep.com/">Sep</a> book club has been <a href="http://pragprog.com/book/cfcar2/the-passionate-programmer"><i>The Passionate Programmer</i></a>.  One of the things mentioned was taking some third party code and reviewing it.</p>
<p>This is not a new idea.  Many people has said the best way to understand the code you write is to understand the good and bad of code written by other people.  In addition, reading code in a language you are learning exposes you to functions you might not understand as well as idioms you don&#8217;t understand.  We had an idea of meeting occasionally over lunch and tackling some code.  Here&#8217;s kinda what I&#8217;m thinking that would look like.  Please comment and let me know if there&#8217;s something else I&#8217;m missing.</p>
<p>With that in mind, I found an article on the <a href="http://www.haskell.org/haskellwiki/">Haskell Wiki</a> where they <a href="http://www.haskell.org/haskellwiki/Implement_a_chat_server">implement a chat server in Haskell</a>.</p>
<p>I&#8217;m only posting the code review for the final version.  Technically, the final version and my changes to make it compile.  There are more about that in the comments.  I added my initials, BJB, to the comments I made and if I had to look up an API, I provided a link to where I learned about it.</p>
<p>This chat server has a couple of interesting features.  It uses lightweight threading to handle multiple incoming and outgoing IO.  It uses channels to communicate across these threads.  The forking calls are also used to create separate &#8220;loops of control&#8221; for each IO channel being handled.</p>
<p>Below are the comments I&#8217;ve added to the program.</p>
<p><span id="more-278"></span></p>
<pre name="code" class="Haskell">
-- Socket based network library
-- http://www.haskell.org/ghc/docs/6.10.4/html/libraries/network/Network-Socket.html
import Network.Socket
-- System io calls.  Posix based
-- http://lambda.haskell.org/hp-tmp/docs/2011.2.0.0/ghc-doc/libraries/haskell2010-1.0.0.0/System-IO.html
import System.IO
-- for exceptions
-- http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html
import Control.Exception
-- concurrent primitives
-- http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent.html
import Control.Concurrent
-- concurrent channels
-- http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent-Chan.html
import Control.Concurrent.Chan
-- http://www.haskell.org/ghc/docs/latest/html/libararies/base/Control-Monad.html
import Control.Monad
-- http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.4.0.0/Control-Monad-Fix.html
import Control.Monad.Fix (fix)

-- BJB - our message type will be an id and a string message to be passed to all
--     - channels not on that Id
type Msg = (Int, String)

-- BJB - The main function is run as an IO Monad
main :: IO ()
main = do
    -- BJB Create a new channel for the server side communication
    chan <- newChan
    -- create socket
    -- BJB - The socket is of type AF_INET http://en.wikipedia.org/wiki/AF_INET
    --       The socket type is Stream, which means they are connected, ie failure on
    --       on party breaks both connections
    sock <- socket AF_INET Stream 0
    -- make socket immediately reusable - eases debuggin
    -- BJB - Socket option SO_REUSEADDR
    --       http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=%2Fapis%2Fssocko.htm
    setSocketOption sock ReuseAddr 1
    -- listen on TCP port 4242
    -- BJB - could be written as `bindSocket sock $ SockAddrInet 4242 iNADDR_ANY`
    --       iNADDR_ANY is the ipv4 wildcard.  4242 is the port
    --       this takes the socket and binds it to the network interface
    bindSocket sock (SockAddrInet 4242 iNADDR_ANY)
    -- listen on TCP port 4242
    -- BJB - could be written as `bindSocket sock $ SockAddrInet 4242 iNADDR_ANY`
    --       iNADDR_ANY is the ipv4 wildcard.  4242 is the port
    --       this takes the socket and binds it to the network
    listen sock 2
    -- BJB - recursive sink to pull data off the first chanel
    --     - this is to prevent the channel from filling it's
    --     - buffer without removing any data
    --     - See below for more information about fix and how it works
    forkIO $ fix $ \loop -> do
        (_, msg) <- readChan chan
        loop
    -- BJB - Passing the channel to the loop with an id
    mainLoop sock chan 0

-- handles all incoming connections
-- since it performs IO, it too must operate in the IO monad
mainLoop :: Socket -> Chan Msg -> Int -> IO ()
mainLoop sock chan nr = do
    -- accept on connection and handle it
    -- BJB - http://en.wikipedia.org/wiki/Berkeley_sockets#accept.28.29
    --       waits for a connection to a client
    --       a connection is a (Socket, SockAddr)
    conn <- accept sock
    -- BJB - passes the connection to the handler function
    --     - type of forkIO is IO() -> IO ThreadId
    --     - it's a lightweight thread
    --     - not for use if there are system threads excpected by the
    --     - underlying libraries
    --     - pass the channel to the socket handlers
    forkIO (runConn conn chan nr)
    -- BJB - loops back to accept the next connection
    --     - increment the connection id
    --     - the $! operator is defined as
    --     - f $! x = x `seq` f x
    --     - seq forces evaluation of a function, this increments
    --     - the connection id explicitly before the recursive call is made
    mainLoop sock chan $! nr+1

-- BJB Need to constrain the error handler used below to only receive an IOException
-- Will try to find out why later
errorHandler :: IOException -> IO()
-- BJB - the return () or return unit/void means do nothing
errorHandler _ = return ()

-- sends a message to the incomming socket
runConn :: (Socket, SockAddr) -> Chan Msg -> Int -> IO ()
runConn (sock, _) chan nr = do
    -- BJB - define a helper to broadcast a mesage to the channel
    --     - note: it closes over the channel
    let broadcast msg = writeChan chan (nr, msg)
    -- BJB - socketToHandle converts a network socket to a handle
    --     - a read / write handle
    hdl <- socketToHandle sock ReadWriteMode
    -- BJB - set to nobuffer, no need to flush
    hSetBuffering hdl NoBuffering
    -- BJB - As the user for their name
    hPutStrLn hdl "Hi, what's your name?"
    -- BJB - Store the user name
    name <- liftM init (hGetLine hdl)
    -- BJB - Tell everyone the user entered.
    --     - the ++ operator concats two lists efficientlyd
    broadcast ("--> " ++ name ++ " entered.")
    -- BJB - welcome the user on their socket
    hPutStrLn hdl ("Welcome, " ++ name ++ "!")
    -- BJB - duplicate the chanel
    --     - chan' is used to read
    --     - chan is used to write
    chan' <- dupChan chan
    -- fork off thread for reading fro the duplicate channel
    -- BJB - fix turns a lamba (taking a function as an arg and calling that at the end)
    --     -  into a loop
    --     - fix f = f (fix f)
    --     - http://en.wikibooks.org/wiki/Haskell/Fix_and_recursion
    --     - remember forkIO's threadId so we can work on it later
    reader <- forkIO $ fix $ \loop -> do
        (nr', line) <- readChan chan'
        -- BJB - if the message comes from a channel that isn't mine,
        --     - send it over the socket, otherwise skip it
        when (nr /= nr') $ hPutStrLn hdl line
        loop
    -- BJB - right now, this won't even compile
    --     - I suspect it isn't compiling because it's looking for an exception,
    --     - but one isn't present
    --     - handle is of type handle::Exception e => (e -> IO a) -> IO a -> IO a
    --     - the (e -> IO a) is an exception handler
    --     - However, the compiler wants it to be tightented down to only (IOException -> IO a)
    --     - this is done by using the errorHandler defined above as opposed to the
    --     - lambda from the original article
    handle errorHandler $fix $ \loop -> do
        -- BJB - http://en.wikibooks.org/wiki/Haskell/Monad_transformers#liftM
        --     - liftM turns init into a monad to take the line from the socket
        --     - init is used to kill the \n character
        line <- liftM init (hGetLine hdl)
        case line of
         -- BJB - quit if needed
         "quit" -> hPutStrLn hdl "Bye!"
         -- BJB - otherwise broadcast
         _      -> do
                   broadcast (name ++ ": " ++ line)
                   loop
    -- BJB - close the reader thread.
    --     - this isn't a problem because the previous line will not get here
    --     - until the writer chanel is closed from the 'quit' command
    killThread reader
    -- BJB - Let the room know this user left
    broadcast ("<-- " ++ name ++ " left.")
    -- BJB - close the socket/handle
    hClose hdl
</pre>
]]></content:encoded>
			<wfw:commentRss>http://myotherpants.com/2011/10/unsoliceted-code-review-haskell-chat-server-edition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Just passing through</title>
		<link>http://myotherpants.com/2009/11/just-passing-through/</link>
		<comments>http://myotherpants.com/2009/11/just-passing-through/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 23:30:57 +0000</pubDate>
		<dc:creator>Ball</dc:creator>
				<category><![CDATA[work safe]]></category>
		<category><![CDATA[functional]]></category>

		<guid isPermaLink="false">http://myotherpants.com/?p=182</guid>
		<description><![CDATA[Continuation Passing Style is a functional pattern where all work that can&#8217;t be passed into a tail recursive function call is passed in as an additional argument via a closure or anonymous function, delaying execution. What got me confused for years on this was the explanation, almost like a mantra, &#8220;A continuation is like a [...]]]></description>
			<content:encoded><![CDATA[<p>Continuation Passing Style is a functional pattern where all work that can&#8217;t be passed into a tail recursive function call is passed in as an additional argument via a closure or anonymous function, delaying execution.</p>
<p>What got me confused for years on this was the explanation, almost like a mantra, &#8220;A continuation is like a callback.&#8221; I don&#8217;t use callbacks much and I believe that phrase is actually expressing a different pattern, simple first-class functions.  So what do I think a continuation is?  It is a promise to get to it later, after a tail call.  I do agree with the literature that it turns the function inside out.  <a href="http://my.safaribooksonline.com/9781590598504/stack_as_a_resource_colon_tail_calls_and">And Don Syme&#8217;s reasoning that you&#8217;re trading heap to avoid spending stack.</a></p>
<p>I know you hate <a href="http://en.wikipedia.org/wiki/Fibonacci_number">fibonacci</a>, but it&#8217;s simple to explain.  Here it is in all it&#8217;s glory.</p>
<p><script src="http://gist.github.com/235454.js"></script></p>
<p>You note, however, that since the results of two recursive calls need to be stored, we can&#8217;t dump the stackframe and tail optimize the call, right?  We could pass around two accumulators, essentially mimicking the imperative for-loop solution to the problem</p>
<p><script src="http://gist.github.com/235456.js"></script></p>
<p>This works because the Fibonacci sequence is just that, a sequence.  It can also be represented by a tree, and that&#8217;s what&#8217;s causing it to be a problem for recursion in the first place.  We are still left with, &#8220;How do I process a tree without risking a blown stack?&#8221;  That&#8217;s what Continuation Passing hopes to solve by using a continuation (read: anonymous function) that wraps our core functionality in a heap object so we don&#8217;t call down one leve.  I&#8217;m not making this clear, so I&#8217;ll show this in pictures.</p>
<div id="attachment_185" class="wp-caption aligncenter" style="width: 310px"><a href="http://myotherpants.com/wp-content/uploads/2009/11/cps_one.png"><img src="http://myotherpants.com/wp-content/uploads/2009/11/cps_one-300x69.png" alt="Continutation Passing Style, step one." title="cps_one" width="300" height="69" class="size-medium wp-image-185" /></a><p class="wp-caption-text">Step One: We're abstracting the problem to it's simplest form</p></div>
<div id="attachment_187" class="wp-caption aligncenter" style="width: 147px"><a href="http://myotherpants.com/wp-content/uploads/2009/11/cps_two.png"><img src="http://myotherpants.com/wp-content/uploads/2009/11/cps_two.png" alt="Step Two: We&#039;re making a promise to do something later" title="cps_two" width="137" height="96" class="size-full wp-image-187" /></a><p class="wp-caption-text">Step Two: We're making a promise to do something later</p></div>
<div id="attachment_186" class="wp-caption aligncenter" style="width: 310px"><a href="http://myotherpants.com/wp-content/uploads/2009/11/cps_three.png"><img src="http://myotherpants.com/wp-content/uploads/2009/11/cps_three-300x79.png" alt="Step Three: We&#039;re expanding the first abstraction" title="cps_three" width="300" height="79" class="size-medium wp-image-186" /></a><p class="wp-caption-text">Step Three: We're expanding the first abstraction</p></div>
<div id="attachment_184" class="wp-caption aligncenter" style="width: 310px"><a href="http://myotherpants.com/wp-content/uploads/2009/11/cps__four.png"><img src="http://myotherpants.com/wp-content/uploads/2009/11/cps__four-300x101.png" alt="Step Four: We&#039;re expanding the second abstraction" title="cps__four" width="300" height="101" class="size-medium wp-image-184" /></a><p class="wp-caption-text">Step Four: We're expanding the second abstraction</p></div>
<p>Step Five:  Fill in the base-cases for both our promise, and the function.<br />
<script src="http://gist.github.com/235497.js"></script></p>
<p>And now for the punchline.  Why do I care?  This goes back to the  <a href="http://xp123.com/xplor/xp0201/">spreadsheet challenge</a> <a href="http://myotherpants.com/2009/10/state-makes-it-easy/">I talked about earlier</a>.  I was evaluating my abstract tree and noticed a lot of code that looked like: <code>| Sum(a,b) -> eval a + eval b</code> and I knew it wasn&#8217;t going to scale past <a href="http://github.com/Ball/Spreadsheet-Challenge">my toy problem</a>.  I had a few tests, so I branched it with Git and tried replacing it with a tail recursive version.  I know a spreadsheet doesn&#8217;t need that, but it really didn&#8217;t add any complexity once I figured out what it was actually doing.  Just thought I&#8217;d share.</p>
]]></content:encoded>
			<wfw:commentRss>http://myotherpants.com/2009/11/just-passing-through/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

