<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-34271990</id><updated>2011-11-28T01:01:03.913+01:00</updated><category term='linux'/><category term='jira'/><category term='eclipse'/><category term='java'/><category term='XP'/><category term='programming'/><title type='text'>try { } catch blog</title><subtitle type='html'>shared notes on programming, and some codesnippets</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>47</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-34271990.post-5403652783931345347</id><published>2011-02-19T01:53:00.000+01:00</published><updated>2011-02-19T01:54:33.051+01:00</updated><title type='text'>ErlyMock 3.0.0  Created!</title><content type='html'>&lt;a href="http://erlymock-site.sourceforge.net/index.html"&gt;ErlyMock home&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-5403652783931345347?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/5403652783931345347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=5403652783931345347' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/5403652783931345347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/5403652783931345347'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2011/02/erlymock-300-created.html' title='ErlyMock 3.0.0  Created!'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-8484868601377705893</id><published>2011-02-06T07:43:00.001+01:00</published><updated>2011-02-19T01:57:25.632+01:00</updated><title type='text'>New Erlymock Release</title><content type='html'>&lt;b&gt;The project has evolved and can be found here: &lt;a href="http://erlymock-site.sourceforge.net/"&gt;ErlyMock&lt;/a&gt;&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-8484868601377705893?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/8484868601377705893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=8484868601377705893' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/8484868601377705893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/8484868601377705893'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2011/02/new-erlymock-release.html' title='New Erlymock Release'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-579185206024168129</id><published>2010-11-07T19:12:00.002+01:00</published><updated>2010-11-07T20:12:49.800+01:00</updated><title type='text'>Age</title><content type='html'>Sadly, I will never be as young as I am right now. Luckily, I will neither be any older than I am in the present moment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-579185206024168129?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/579185206024168129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=579185206024168129' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/579185206024168129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/579185206024168129'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2010/11/age.html' title='Age'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-6934266859560376024</id><published>2010-08-01T16:41:00.017+02:00</published><updated>2010-09-12T13:56:02.680+02:00</updated><title type='text'>My minimalistic xinitrc, xmonad.hs and xmobarrc</title><content type='html'>put this in ~/.xinitrc&lt;br /&gt;&lt;span class="Apple-style-span"  &gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ck-launch-session&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;# start trayer to contain apps like nm-applet&lt;/div&gt;&lt;div&gt;trayer --edge top --align right --SetDockType true --SetPartialStrut true --expand true --width 5 --transparent true --tint 0x191970 --height 12 &amp;amp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;kmix &amp;amp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;# some cool effects&lt;/div&gt;&lt;div&gt;xcompmgr -c -f -F &amp;amp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;# Set the background color&lt;/div&gt;&lt;div&gt;hsetroot -tile /home/sven/Wallpapers/abstract-bluelights-1280x800-.jpg&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;xset b 100 0 0&lt;/div&gt;&lt;div&gt;xset r rate 190 90&lt;/div&gt;&lt;div&gt;dbus-launch --exit-with-session xmonad&lt;/div&gt;&lt;div style="font-size: 13px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;div&gt;&lt;br /&gt;put this in ~/.xmonad/xmonad.hs&lt;br /&gt;&lt;pre&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; &lt;font color=Green&gt;&lt;u&gt;qualified&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;StackSet &lt;font color=Green&gt;&lt;u&gt;as&lt;/u&gt;&lt;/font&gt; W&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;ManageHook&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Hooks&lt;font color=Cyan&gt;.&lt;/font&gt;ManageHelpers&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Hooks&lt;font color=Cyan&gt;.&lt;/font&gt;DynamicLog&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Hooks&lt;font color=Cyan&gt;.&lt;/font&gt;ManageDocks&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Hooks&lt;font color=Cyan&gt;.&lt;/font&gt;FadeInactive()&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Hooks&lt;font color=Cyan&gt;.&lt;/font&gt;SetWMName&lt;font color=Cyan&gt;(&lt;/font&gt;setWMName&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Layout&lt;font color=Cyan&gt;.&lt;/font&gt;NoBorders&lt;font color=Cyan&gt;(&lt;/font&gt;smartBorders&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Layout&lt;font color=Cyan&gt;.&lt;/font&gt;Tabbed&lt;font color=Cyan&gt;(&lt;/font&gt;tabbed&lt;font color=Cyan&gt;,&lt;/font&gt; shrinkText&lt;font color=Cyan&gt;,&lt;/font&gt; defaultTheme&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Layout&lt;font color=Cyan&gt;.&lt;/font&gt;LayoutHints&lt;font color=Cyan&gt;(&lt;/font&gt;layoutHints&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Layout&lt;font color=Cyan&gt;.&lt;/font&gt;LayoutModifier&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Util&lt;font color=Cyan&gt;.&lt;/font&gt;Run&lt;font color=Cyan&gt;(&lt;/font&gt;spawnPipe&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Util&lt;font color=Cyan&gt;.&lt;/font&gt;EZConfig&lt;font color=Cyan&gt;(&lt;/font&gt;additionalKeys&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; System&lt;font color=Cyan&gt;.&lt;/font&gt;IO&lt;br /&gt;&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Prompt&lt;font color=Cyan&gt;(&lt;/font&gt;defaultXPConfig&lt;font color=Cyan&gt;,&lt;/font&gt; autoComplete&lt;font color=Cyan&gt;,&lt;/font&gt; XPPosition&lt;font color=Cyan&gt;(&lt;/font&gt;Bottom&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; position&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Prompt&lt;font color=Cyan&gt;.&lt;/font&gt;RunOrRaise&lt;font color=Cyan&gt;(&lt;/font&gt;runOrRaisePrompt&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Actions&lt;font color=Cyan&gt;.&lt;/font&gt;WindowGo&lt;font color=Cyan&gt;(&lt;/font&gt;runOrRaiseNext&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Actions&lt;font color=Cyan&gt;.&lt;/font&gt;UpdatePointer()&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Prompt&lt;font color=Cyan&gt;.&lt;/font&gt;Man&lt;font color=Cyan&gt;(&lt;/font&gt;manPrompt&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Prompt&lt;font color=Cyan&gt;.&lt;/font&gt;Window&lt;font color=Cyan&gt;(&lt;/font&gt;windowPromptGoto&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;font color=Green&gt;&lt;u&gt;import&lt;/u&gt;&lt;/font&gt; XMonad&lt;font color=Cyan&gt;.&lt;/font&gt;Util&lt;font color=Cyan&gt;.&lt;/font&gt;Themes()&lt;br /&gt;&lt;br /&gt;&lt;font color=Blue&gt;main&lt;/font&gt; &lt;font color=Red&gt;=&lt;/font&gt; &lt;font color=Green&gt;&lt;u&gt;do&lt;/u&gt;&lt;/font&gt;&lt;br /&gt;  mobar &lt;font color=Red&gt;&amp;lt;-&lt;/font&gt; spawnPipe &lt;font color=Magenta&gt;"/usr/bin/xmobar ~/.xmonad/xmobarrc"&lt;/font&gt; &lt;br /&gt;  xmonad &lt;font color=Cyan&gt;$&lt;/font&gt; defaultConfig &lt;font color=Cyan&gt;{&lt;/font&gt; manageHook &lt;font color=Red&gt;=&lt;/font&gt; manageDocks &lt;font color=Cyan&gt;&amp;lt;+&amp;gt;&lt;/font&gt; customManageHooks &lt;font color=Cyan&gt;&amp;lt;+&amp;gt;&lt;/font&gt; manageHook defaultConfig&lt;br /&gt;                         &lt;font color=Cyan&gt;,&lt;/font&gt; layoutHook &lt;font color=Red&gt;=&lt;/font&gt; avoidStruts sheyllLayouts&lt;br /&gt;                         &lt;font color=Cyan&gt;,&lt;/font&gt; modMask &lt;font color=Red&gt;=&lt;/font&gt; windowsKey &lt;font color=Blue&gt;&lt;i&gt;-- rebind ALT modifier key to WIN&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                         &lt;font color=Cyan&gt;,&lt;/font&gt; logHook &lt;font color=Red&gt;=&lt;/font&gt; myLogHook mobar&lt;br /&gt;                         &lt;font color=Cyan&gt;,&lt;/font&gt; terminal &lt;font color=Red&gt;=&lt;/font&gt; &lt;font color=Magenta&gt;"konsole"&lt;/font&gt;&lt;br /&gt;                         &lt;font color=Cyan&gt;,&lt;/font&gt; startupHook &lt;font color=Red&gt;=&lt;/font&gt; setWMName &lt;font color=Magenta&gt;"LG3D"&lt;/font&gt;&lt;br /&gt;                         &lt;font color=Cyan&gt;}&lt;/font&gt; &lt;font color=Cyan&gt;`additionalKeys`&lt;/font&gt; sheyllShortCuts&lt;br /&gt;      &lt;font color=Green&gt;&lt;u&gt;where&lt;/u&gt;&lt;/font&gt; myLogHook mobar &lt;font color=Red&gt;=&lt;/font&gt; dynamicLogWithPP sjanssenPP  &lt;font color=Cyan&gt;{&lt;/font&gt; ppOutput &lt;font color=Red&gt;=&lt;/font&gt; hPutStrLn mobar&lt;br /&gt;                                                     &lt;font color=Cyan&gt;}&lt;/font&gt;       &lt;br /&gt;&lt;br /&gt;&lt;font color=Blue&gt;customManageHooks&lt;/font&gt; &lt;font color=Red&gt;=&lt;/font&gt; composeAll &lt;font color=Red&gt;[&lt;/font&gt; className &lt;font color=Cyan&gt;=?&lt;/font&gt; &lt;font color=Magenta&gt;"ioUrbanTerror"&lt;/font&gt; &lt;font color=Cyan&gt;--&amp;gt;&lt;/font&gt; doFullFloat&lt;br /&gt;                               &lt;font color=Cyan&gt;,&lt;/font&gt; className &lt;font color=Cyan&gt;=?&lt;/font&gt; &lt;font color=Magenta&gt;"XConsole"&lt;/font&gt;      &lt;font color=Cyan&gt;--&amp;gt;&lt;/font&gt; doFloat&lt;br /&gt;                               &lt;font color=Cyan&gt;,&lt;/font&gt; className &lt;font color=Cyan&gt;=?&lt;/font&gt; &lt;font color=Magenta&gt;"Kcalc"&lt;/font&gt;         &lt;font color=Cyan&gt;--&amp;gt;&lt;/font&gt; doFloat&lt;br /&gt;                               &lt;font color=Cyan&gt;,&lt;/font&gt; className &lt;font color=Cyan&gt;=?&lt;/font&gt; &lt;font color=Magenta&gt;"Pidgin"&lt;/font&gt;        &lt;font color=Cyan&gt;--&amp;gt;&lt;/font&gt; doFloat&lt;br /&gt;                               &lt;font color=Cyan&gt;,&lt;/font&gt; className &lt;font color=Cyan&gt;=?&lt;/font&gt; &lt;font color=Magenta&gt;"Kmix"&lt;/font&gt;          &lt;font color=Cyan&gt;--&amp;gt;&lt;/font&gt; doFloat&lt;font color=Red&gt;]&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color=Blue&gt;windowsKey&lt;/font&gt; &lt;font color=Red&gt;=&lt;/font&gt; mod4Mask&lt;br /&gt;&lt;br /&gt;&lt;font color=Blue&gt;sheyllLayouts&lt;/font&gt; &lt;font color=Red&gt;=&lt;/font&gt; smartBorders &lt;font color=Cyan&gt;$&lt;/font&gt; &lt;br /&gt;                 tabbed shrinkText defaultTheme&lt;br /&gt;                &lt;font color=Cyan&gt;|||&lt;/font&gt; layoutHints &lt;font color=Cyan&gt;(&lt;/font&gt;layoutHook defaultConfig&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color=Blue&gt;sheyllShortCuts&lt;/font&gt; &lt;font color=Red&gt;=&lt;/font&gt; &lt;font color=Red&gt;[&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; xK_p&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; runOrRaisePrompt defaultXPConfig&lt;br /&gt;                                           &lt;font color=Cyan&gt;{&lt;/font&gt; position &lt;font color=Red&gt;=&lt;/font&gt; Bottom&lt;br /&gt;                                           &lt;font color=Cyan&gt;,&lt;/font&gt; autoComplete &lt;font color=Red&gt;=&lt;/font&gt; Just &lt;font color=Magenta&gt;500000&lt;/font&gt; &lt;font color=Cyan&gt;}&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Blue&gt;&lt;i&gt;-- important apps&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; xK_Return&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; runOrRaiseNext &lt;font color=Magenta&gt;"konsole"&lt;/font&gt;&lt;br /&gt;                                           &lt;font color=Cyan&gt;(&lt;/font&gt;className &lt;font color=Cyan&gt;=?&lt;/font&gt; &lt;font color=Magenta&gt;"Konsole"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; xK_f&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; runOrRaiseNext &lt;font color=Magenta&gt;"google-chrome"&lt;/font&gt;&lt;br /&gt;                                           &lt;font color=Cyan&gt;(&lt;/font&gt;className &lt;font color=Cyan&gt;=?&lt;/font&gt; &lt;font color=Magenta&gt;"Google-chrome"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey &lt;font color=Cyan&gt;.|.&lt;/font&gt; shiftMask&lt;font color=Cyan&gt;,&lt;/font&gt; xK_f&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; spawn &lt;font color=Magenta&gt;"google-chrome"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                    &lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; xK_a&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; runOrRaiseNext &lt;font color=Magenta&gt;"emacs"&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;className &lt;font color=Cyan&gt;=?&lt;/font&gt;&lt;br /&gt;                                                                     &lt;font color=Magenta&gt;"Emacs"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey &lt;font color=Cyan&gt;.|.&lt;/font&gt; shiftMask&lt;font color=Cyan&gt;,&lt;/font&gt; xK_a&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; spawn &lt;font color=Magenta&gt;"emacs"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                    &lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; xK_d&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; runOrRaiseNext &lt;font color=Magenta&gt;"dolphin"&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;className&lt;br /&gt;                                                                                     &lt;font color=Cyan&gt;=?&lt;/font&gt; &lt;font color=Magenta&gt;"Dolphin"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey &lt;font color=Cyan&gt;.|.&lt;/font&gt; shiftMask&lt;font color=Cyan&gt;,&lt;/font&gt; xK_d&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; spawn &lt;font color=Magenta&gt;"dolphin"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                    &lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; xK_End&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; kill&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                    &lt;br /&gt;                  &lt;font color=Blue&gt;&lt;i&gt;-- eclipse IDE&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; xK_x&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; runOrRaiseNext &lt;font color=Magenta&gt;"eclipse"&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;className &lt;font color=Cyan&gt;=?&lt;/font&gt;&lt;br /&gt;                                                                     &lt;font color=Magenta&gt;"Eclipse"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey &lt;font color=Cyan&gt;.|.&lt;/font&gt; shiftMask&lt;font color=Cyan&gt;,&lt;/font&gt; xK_x&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; spawn &lt;font color=Magenta&gt;"eclipse"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                    &lt;br /&gt;&lt;br /&gt;                  &lt;font color=Blue&gt;&lt;i&gt;-- launch a mail programm&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; xK_m &lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; runOrRaiseNext &lt;font color=Magenta&gt;"kmail"&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;className &lt;font color=Cyan&gt;=?&lt;/font&gt; &lt;font color=Magenta&gt;"Kmail"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;                  &lt;font color=Blue&gt;&lt;i&gt;-- switch kb to de&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; xK_BackSpace&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; spawn &lt;font color=Magenta&gt;"setxkbmap de"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;                  &lt;font color=Blue&gt;&lt;i&gt;-- switch kb to us&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey &lt;font color=Cyan&gt;.|.&lt;/font&gt; shiftMask&lt;font color=Cyan&gt;,&lt;/font&gt; xK_BackSpace&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; spawn &lt;font color=Magenta&gt;"setxkbmap us"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;                  &lt;font color=Blue&gt;&lt;i&gt;-- launch pidgin&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; xK_i &lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; runOrRaiseNext &lt;font color=Magenta&gt;"pidgin"&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;className &lt;font color=Cyan&gt;=?&lt;/font&gt; &lt;font color=Magenta&gt;"Pidgin"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;                  &lt;font color=Blue&gt;&lt;i&gt;-- sound &amp;amp; media&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; xK_v&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; runOrRaiseNext &lt;font color=Magenta&gt;"rhythmbox"&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;className&lt;br /&gt;                                                                        &lt;font color=Cyan&gt;=?&lt;/font&gt; &lt;font color=Magenta&gt;"Rhythmbox"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                    &lt;br /&gt;                  &lt;font color=Blue&gt;&lt;i&gt;-- put system into hibernate mode&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey &lt;font color=Cyan&gt;.|.&lt;/font&gt; shiftMask &lt;font color=Cyan&gt;.|.&lt;/font&gt; controlMask&lt;font color=Cyan&gt;,&lt;/font&gt; xK_r&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; spawn &lt;font color=Magenta&gt;"sudo reboot"&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                    &lt;br /&gt;                    &lt;br /&gt;                  &lt;font color=Blue&gt;&lt;i&gt;-- Toggle docks gaps&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey &lt;font color=Cyan&gt;,&lt;/font&gt; xK_b&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; sendMessage ToggleStruts&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;                  &lt;font color=Blue&gt;&lt;i&gt;-- prompt, runOrRaise&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey &lt;font color=Cyan&gt;.|.&lt;/font&gt; controlMask&lt;font color=Cyan&gt;,&lt;/font&gt; xK_x&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; runOrRaisePrompt&lt;br /&gt;                                                       defaultXPConfig&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; xK_F1&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; manPrompt defaultXPConfig&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                    &lt;br /&gt;                  &lt;font color=Blue&gt;&lt;i&gt;-- finding windows&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; xK_g &lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; windowPromptGoto&lt;br /&gt;                                        defaultXPConfig &lt;font color=Cyan&gt;{&lt;/font&gt; autoComplete &lt;font color=Red&gt;=&lt;/font&gt; Just &lt;font color=Magenta&gt;500000&lt;/font&gt; &lt;font color=Cyan&gt;}&lt;/font&gt; &lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                  &lt;font color=Red&gt;]&lt;/font&gt;&lt;br /&gt;                    &lt;font color=Cyan&gt;++&lt;/font&gt;&lt;br /&gt;                    &lt;font color=Blue&gt;&lt;i&gt;-- mod-{w,e,r}, Switch to physical/Xinerama screens 1, 2, or 3&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                    &lt;font color=Blue&gt;&lt;i&gt;-- mod-shift-{w,e,r}, Move client to screen 1, 2, or 3&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                    &lt;font color=Blue&gt;&lt;i&gt;--&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;                    &lt;font color=Red&gt;[&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;m &lt;font color=Cyan&gt;.|.&lt;/font&gt; windowsKey&lt;font color=Cyan&gt;,&lt;/font&gt; key&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; screenWorkspace sc &lt;font color=Cyan&gt;&amp;gt;&amp;gt;=&lt;/font&gt; flip whenJust &lt;font color=Cyan&gt;(&lt;/font&gt;windows &lt;font color=Cyan&gt;.&lt;/font&gt; f&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;br /&gt;                         &lt;font color=Red&gt;|&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;key&lt;font color=Cyan&gt;,&lt;/font&gt; sc&lt;font color=Cyan&gt;)&lt;/font&gt; &lt;font color=Red&gt;&amp;lt;-&lt;/font&gt; zip &lt;font color=Red&gt;[&lt;/font&gt;xK_e&lt;font color=Cyan&gt;,&lt;/font&gt; xK_w&lt;font color=Cyan&gt;,&lt;/font&gt; xK_r&lt;font color=Red&gt;]&lt;/font&gt; &lt;font color=Red&gt;[&lt;/font&gt;&lt;font color=Magenta&gt;0&lt;/font&gt;&lt;font color=Red&gt;..&lt;/font&gt;&lt;font color=Red&gt;]&lt;/font&gt;&lt;br /&gt;                    &lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;f&lt;font color=Cyan&gt;,&lt;/font&gt; m&lt;font color=Cyan&gt;)&lt;/font&gt; &lt;font color=Red&gt;&amp;lt;-&lt;/font&gt; &lt;font color=Red&gt;[&lt;/font&gt;&lt;font color=Cyan&gt;(&lt;/font&gt;W&lt;font color=Cyan&gt;.&lt;/font&gt;view&lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Magenta&gt;0&lt;/font&gt;&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Cyan&gt;,&lt;/font&gt; &lt;font color=Cyan&gt;(&lt;/font&gt;W&lt;font color=Cyan&gt;.&lt;/font&gt;shift&lt;font color=Cyan&gt;,&lt;/font&gt; shiftMask&lt;font color=Cyan&gt;)&lt;/font&gt;&lt;font color=Red&gt;]&lt;/font&gt;&lt;font color=Red&gt;]&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;place this in ~/.xmonad/xmobarrc:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Config { font = "-*-Fixed-Bold-R-Normal-*-13-*-*-*-*-*-*-*"&lt;br /&gt;, bgColor = "black"&lt;br /&gt;, fgColor = "grey"&lt;br /&gt;, position = TopW L 95&lt;br /&gt;, lowerOnStart = True&lt;br /&gt;, commands = [ Run Memory ["-t","Mem: %"] 10&lt;br /&gt;, Run Swap [] 10&lt;br /&gt;, Run Battery ["-t","Batt: "] 10&lt;br /&gt;, Run Thermal "THRM" [] 10&lt;br /&gt;, Run Network "eth0" ["-L","0","-H","32","--normal","green","--high","red"] 10&lt;br /&gt;, Run Memory ["-t","Mem: &lt;usedratio&gt;%"] 10&lt;br /&gt;, Run MultiCpu ["-t", "CPU: &lt;total&gt;","-L","3","-H","50","--normal","green","--high","red"] 10&lt;br /&gt;, Run Date "%a %b %_d %Y %H:%M:%S" "date" 10&lt;br /&gt;, Run StdinReader&lt;br /&gt;]&lt;br /&gt;, sepChar = "%"&lt;br /&gt;, alignSep = "}{"&lt;br /&gt;, template = "%StdinReader%} {%multicpu% &lt;fc=#444444&gt;&lt;&lt;&lt;/fc&gt; %memory% &lt;fc=#444444&gt;&lt;&lt;&lt;/fc&gt; %swap% &lt;fc=#444444&gt;&lt;&lt;&lt;/fc&gt; %eth0% &lt;fc=#444444&gt;&lt;&lt;&lt;/fc&gt; %date%"&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-6934266859560376024?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/6934266859560376024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=6934266859560376024' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/6934266859560376024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/6934266859560376024'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2010/08/my-xmonadhs-and-xmobarrc.html' title='My minimalistic xinitrc, xmonad.hs and xmobarrc'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-2551854641397071127</id><published>2010-05-13T13:36:00.017+02:00</published><updated>2010-05-13T20:17:46.885+02:00</updated><title type='text'>Installing GHC 6.12.2 on Red Hat Entrprise Linux 5.4 (i386)</title><content type='html'>Haskell, a general-purpose, purely functional programming language, has become more and more interesting for me, it allows me to write maintainable code, with acceptable performance even for tasks like analyzing large log files. I recently discovered how easy it is to write programs interacting with a unix like environment. It also very easy to write networking code. Haskell offers great opportunities for TDD and SDD through HUnit and QuickCheck, which - together with the pure and strong static type system of the language itself - enable trust in program correctness, which is vital for many commercial applications, or applications exposed to increased security requirements.&lt;br /&gt;&lt;br /&gt;In order to leverage the outstandingly great features of Haskell, one has to have that beast running on a stable, proven and hence archaic and outdated operating system. Even if one is not a firm believer in magical awesomeness of &lt;em&gt;Enterprise&lt;/em&gt; labels on top of ridiculously obsolete tools(like gcc 4.1 and glibc 2.5), the server landscape might require to use a specific Linux distribution, because of proprietary drivers for specialized hardware components, in this post I will assume that this Linux distro is Red Hat Entrprise Linux 5.4 and explain the cumbersome installation of the latest and greatest Haskell compiler. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Step 0: Preparing the build environment&lt;/h2&gt;&lt;br /&gt;As a non-commercial 100% binary compatible replacement for RHEL with only the proprietary art work replaced &lt;b&gt;Cent OS&lt;/b&gt; should be used. I installed Cent OS 5.4 i386 without any GNOME or KDE and with bridge networking in a Virtual Box with on an Arch Linux host.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Step 1: Installing GHC 6.8.3&lt;/h2&gt;&lt;br /&gt;Because the generic &lt;b&gt;binary&lt;/b&gt; linux distribution of GHC 6.12.2 depends on at least the 2.7 version of glibc, and RHEL 5.4 only provides glibc 2.5, it is necessary to build it from the sources. Strangely the GHC source distribution needs an existing GHC to compile it: in order to compile GHC 6.12.2 from source we need to have a GHC already installed. The latest GHC version with a generic linux binray distribution compatible with glibc 2.5 is GHC 6.8.3.&lt;br /&gt;  &lt;br /&gt;These are the required commands(execute as root) to install GHC 6.8.3 into &lt;tt&gt;/usr/local&lt;/tt&gt;:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[root@noname ~]# wget http://haskell.org/ghc/dist/6.8.3/ghc-6.8.3-i386-unknown-linux.tar.bz2&lt;br /&gt;[root@noname ~]# tar xvfj ghc-6.8.3-i386-unknown-linux.tar.bz2&lt;br /&gt;[root@noname ~]# cd ghc-6.8.3&lt;br /&gt;[root@noname ghc-6.8.3]# ./configure&lt;br /&gt;[root@noname ghc-6.8.3]# make install&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Try running &lt;tt&gt;ghci&lt;/tt&gt;, the interactive Haskell REPL, it should start and welcome its user with a warm...&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[root@noname ~]# ghci&lt;br /&gt;GHCi, version 6.8.3: http://www.haskell.org/ghc/  :? for help&lt;br /&gt;Loading package base ... linking ... done.&lt;br /&gt;Prelude&gt; &lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt; Step 2: Building GHC-6.12.2&lt;/h2&gt;&lt;br /&gt;GHC 6.12.2 can now be built from source using the GHC 6.8.3 from the previous build...&lt;br /&gt;&lt;code&gt;&lt;br /&gt;wget http://haskell.org/ghc/dist/6.12.2/ghc-6.12.2-src.tar.bz2&lt;br /&gt;tar xfvj ghc-6.12.2-src.tar.bz2&lt;br /&gt;cd ghc-6.12.2&lt;br /&gt;./configure&lt;br /&gt;make&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;b&gt;STOP&lt;/b&gt; do not &lt;tt&gt;make install&lt;/tt&gt; just yet. Before, move your &lt;tt&gt;/usr/local/&lt;/tt&gt; to &lt;tt&gt;/usr/local.ghc683&lt;/tt&gt; in order to get a clean&lt;br /&gt;install of GHC 6.12 in &lt;tt&gt;/usr/local&lt;/tt&gt; with &lt;tt&gt;make install&lt;/tt&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Harvest the result of your hard work&lt;/h2&gt;&lt;br /&gt;Now would be an excellent moment to save a snapshot of your &lt;tt&gt;/usr/local&lt;/tt&gt; directory. &lt;br /&gt;If I knew where I would even upload an archived version of mine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-2551854641397071127?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/2551854641397071127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=2551854641397071127' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/2551854641397071127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/2551854641397071127'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2010/05/installing-haskell-prime-on-cent-os-54.html' title='Installing GHC 6.12.2 on Red Hat Entrprise Linux 5.4 (i386)'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-7709301975337438184</id><published>2010-05-09T10:11:00.002+02:00</published><updated>2010-09-02T18:34:29.735+02:00</updated><title type='text'>haskell stuff in my .emacs</title><content type='html'>&lt;pre&gt;This does not include the ghc-mod configuration.&lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;;; haskell section:&lt;br /&gt;(load "/usr/share/emacs/site-lisp/haskell-mode/haskell-site-file.el")&lt;br /&gt;(require 'inf-haskell)&lt;br /&gt;(autoload 'turn-on-haskell-doc-mode "haskell-doc" nil t)&lt;br /&gt;(add-hook 'haskell-mode-hook 'heyllStd)&lt;br /&gt;(add-hook 'haskell-mode-hook 'turn-on-haskell-font-lock)&lt;br /&gt;(add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)&lt;br /&gt;(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)&lt;br /&gt;(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)&lt;br /&gt;(add-hook 'haskell-mode-hook 'turn-on-haskell-ghci)&lt;br /&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-7709301975337438184?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/7709301975337438184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=7709301975337438184' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7709301975337438184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7709301975337438184'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2010/05/haskell-stuff-in-my-emacs.html' title='haskell stuff in my .emacs'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-1877631213172525807</id><published>2009-10-19T19:13:00.007+02:00</published><updated>2009-10-27T09:25:30.431+01:00</updated><title type='text'>Regular Expression Cheat Sheet YEAHH!!</title><content type='html'>&lt;span style="font-weight: bold;"&gt;...NOT!&lt;/span&gt; There seems to be no good regex escaping cheat-sheet, that is easy to find.&lt;br /&gt;I was so tired of remebering when to escape what in grep, awk, sed and emacs, that I asked google for help. The result of my search was not very satisfying :(&lt;br /&gt;&lt;br /&gt;So I started this blogpost as the location for gathering all diffrent escaping styles that I find during my daily work.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;sed&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;\(\)&lt;/li&gt;&lt;li&gt;\+&lt;/li&gt;&lt;li&gt;*&lt;/li&gt;&lt;li&gt;.&lt;/li&gt;&lt;li&gt;\/ (backslash must be escaped, even if not used as seperator cahracter)&lt;/li&gt;&lt;li&gt;\|&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;grep&lt;/span&gt;&lt;br /&gt;Like sed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-1877631213172525807?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/1877631213172525807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=1877631213172525807' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/1877631213172525807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/1877631213172525807'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2009/10/regular-expression-cheat-sheet-yeahh.html' title='Regular Expression Cheat Sheet YEAHH!!'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-7804824328150980063</id><published>2009-07-07T20:30:00.002+02:00</published><updated>2009-07-07T20:34:09.150+02:00</updated><title type='text'>I know this isn't twitter but...</title><content type='html'>What do they say about a Job?&lt;br /&gt;&lt;br /&gt;0. Create it.&lt;br /&gt;&lt;br /&gt;- if that doesn't work -&lt;br /&gt;1. Love it.&lt;br /&gt;&lt;br /&gt;- if that doesn't work -&lt;br /&gt;2. Change it.&lt;br /&gt;&lt;br /&gt;- if that doesn't work - &lt;br /&gt;3. Leave it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-7804824328150980063?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/7804824328150980063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=7804824328150980063' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7804824328150980063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7804824328150980063'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2009/07/i-know-this-isnt-twitter-but.html' title='I know this isn&apos;t twitter but...'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-3443738303572252029</id><published>2009-06-09T01:27:00.003+02:00</published><updated>2009-06-09T01:45:28.420+02:00</updated><title type='text'>it</title><content type='html'>it&lt;br /&gt;&lt;br /&gt;syllables stroke hidden performances, relentlessly&lt;br /&gt;while she is singing&lt;br /&gt;with his song she - flowers and shines in a shower&lt;br /&gt;half through and yet stuck &lt;br /&gt;off by an occurence - hesitating&lt;br /&gt;&lt;br /&gt;wandering through grayness colorfull her tears&lt;br /&gt;hidden permitted to beast &lt;br /&gt;breaks old and new and she will see&lt;br /&gt;he is falling unforgottenly muted&lt;br /&gt;&lt;br /&gt;blended by invisable light not so pure&lt;br /&gt;not shining - hesitate!&lt;br /&gt;clicked links to the past before her metamorphoses&lt;br /&gt;cuting moments of pain and pity&lt;br /&gt;&lt;br /&gt;grayness wandering colorfull through his tears&lt;br /&gt;stainless trees fallen in the way&lt;br /&gt;running in a direction and the other &lt;br /&gt;where will we go from here?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-3443738303572252029?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/3443738303572252029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=3443738303572252029' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/3443738303572252029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/3443738303572252029'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2009/06/it.html' title='it'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-7586205739442402792</id><published>2009-06-09T01:15:00.002+02:00</published><updated>2009-06-09T01:16:00.416+02:00</updated><title type='text'>I was there...</title><content type='html'>&lt;a href="http://www.youtube.com/watch?v=PDFrEZ8hqOA"&gt;http://www.youtube.com/watch?v=PDFrEZ8hqOA&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-7586205739442402792?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/7586205739442402792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=7586205739442402792' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7586205739442402792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7586205739442402792'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2009/06/i-was-there.html' title='I was there...'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-7781895302650790755</id><published>2009-04-15T00:33:00.005+02:00</published><updated>2009-04-15T00:40:51.100+02:00</updated><title type='text'>New project started: tabloid</title><content type='html'>&lt;a href="http://code.google.com/p/tabloid/"&gt;link&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-7781895302650790755?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/7781895302650790755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=7781895302650790755' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7781895302650790755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7781895302650790755'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2009/04/new-project-started-tabloid.html' title='New project started: tabloid'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-173182929999970761</id><published>2009-02-25T20:11:00.010+01:00</published><updated>2011-02-19T01:56:21.460+01:00</updated><title type='text'>Erlang mock - erlymock</title><content type='html'>&lt;h1&gt;NOTE THIS POST IS OUTDATED!&lt;/h1&gt;&lt;br /&gt;&lt;b&gt;The project has evolved and can be found here: &lt;a href="http://erlymock-site.sourceforge.net/"&gt;ErlyMock&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Some features&lt;/h1&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Easy to use&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Design based on easymock&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Works together with otp: can be used even if the clut is called from another process, by invoking mock:verify_after_last_call(Mock,optional: timeout)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;custom return functions&lt;/li&gt;&lt;br /&gt;&lt;li&gt;predefined return functions for returning values, receiving message, throwing exceptions, etc..&lt;/li&gt;&lt;br /&gt;&lt;li&gt;erlymock automatically purges all modules that were mocked, after verify()&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Custom argument matchers:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;%% Orderchecking types: in_order, out_of_order, stub;  &lt;br /&gt;%% Answering: {return, ...}|{error, ...}|{throw, ...}|{exit, ...}|{rec_msg, Pid}|{function, Fun(Args) -&gt; RetVal}&lt;br /&gt;expect(Mock, Type, Module, Function, Arguments, Answer = {AT, _}) when AT==return;AT==error;AT==throw;AT==exit;AT==rec_msg;AT==function -&gt;&lt;br /&gt;    call(Mock, {expect, Type, Module, Function, length(Arguments), {Arguments, Answer}}).&lt;br /&gt;&lt;br /&gt;%% this version of expect is suited for useing custom argument matchers&lt;br /&gt;expect(Mock, Type, Module, Fun, Arity, MatcherFun, Function) -&gt;&lt;br /&gt;    call(Mock, {expect, Type, Module, Fun, Arity, {custom, MatcherFun, Function}}).&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;multiple module per mock&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;basic usage&lt;/h1&gt;&lt;br /&gt;&lt;br /&gt;in a typicall unit test you will mock certain dependencies. In order to be able to mock function call in the erlang environment you need hot code swapping to&lt;br /&gt;replace the actual implementations with mock functions that look exactly like their orignals to the outside, but that talk to a mock control process,&lt;br /&gt;that you control in order to assert, that functions are called in the correct order and with corrent parameters.&lt;br /&gt;Mocking a process is easier as you can always create a mock process that you smuggle into the code under test.&lt;br /&gt;With erlymock however, you can do both at ease.&lt;br /&gt;&lt;br /&gt;The general skeleton of unit test looks like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;xxx_test() -&gt;&lt;br /&gt; M = mock:new(),&lt;br /&gt; ...&lt;br /&gt; mock:strict(M, ModulToMock, FunctionToMock, ArgumentLiteralList, AnswerDefinition)&lt;br /&gt; ...&lt;br /&gt; mock:replay(M)&lt;br /&gt; ...&lt;br /&gt;  do the actual testing&lt;br /&gt; ...&lt;br /&gt; mock:verify(M)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Please refer to the easymock for java documentation to understand the basic principles behind this.&lt;br /&gt;Restrictions&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;       &lt;li&gt; Do not mock system modules.&lt;/li&gt;&lt;br /&gt;       &lt;li&gt; at the moment only whole modules can be replaced, it is not possible(nor desirable in most cases) to mix original module code and generated mock code&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;API&lt;/h1&gt;&lt;br /&gt;&lt;br /&gt;There are only eight public function calls, of wich only 5 are neede for most tasks. They are:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;new() -&gt; Mock&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;use this to create a new instance of a mock process that is in programming phase&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;expect(Mock, OrderCheckingType, Module, Function, Arguments, Answer)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;expect has the following options:&lt;br /&gt;Orderchecking types:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt; &lt;li&gt; in_order all calles flaged in_order must be called in the order recorded, an out of order or stub call will not effect the order of stub call. in_order calls have the highest priorite, they are always check before out of order calls or stub calls. That allows for intermixing of calls to the same functions from all three classes. However if possible in_order calls will be matched before oo and stub calls. All in_order call must occur in the correct order.&lt;br /&gt; &lt;/li&gt;&lt;li&gt; out_of_order the main diffrences to in_order calls is that these calls may come in any order, but they must still all be made&lt;br /&gt; &lt;/li&gt;&lt;li&gt; stub stub calls are not checked at all, stub calls are usefull for providing fixtures, think of it as comfort noise for the class under test.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h2&gt;Answering:&lt;/h2&gt;&lt;br /&gt;The last parameter of the expect function defines the answer. It is tuple where the first element is one of the following described atoms,&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt; {return, Value} allows you to just specify a value that will be returned from the function call&lt;/li&gt;&lt;br /&gt;  &lt;li&gt; {error, Reason} specifies that a certain error will be thrown with erlang:error(Reason)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt; {throw, What} will make the function throw an exception when called&lt;/li&gt;&lt;br /&gt;  &lt;li&gt; exit this will cause the function to call exit when invoked&lt;/li&gt;&lt;br /&gt;  &lt;li&gt; {rec_msg,...} this will caus teh function to make a receive, receiving any message and sending it to a pid&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;{function, F} when the function is invoked, a user defined function can be passed as parameter. The function will be called with the arguments of the mock invocation in an array&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt; Convenience functions &lt;/h2&gt;&lt;br /&gt;A variant of expect is suited for using custom argument matchers:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;expect(Mock, Type, Module, Fun, Arity, MatcherFun, Function)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A short cut for &lt;pre&gt;expect(.., in_order, ..)&lt;/pre&gt; is:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;strict(Mock, M,F,Args, Answer)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A short cut for &lt;pre&gt;expect(.., out_of_order, ..)&lt;/pre&gt; is:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;o_o(Mock, M,F,Args, Answer)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A short cut for &lt;pre&gt;expect(.., stub, ..)&lt;/pre&gt; is:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;stub(Mock, M,F,Args, Answer)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;After the programming phase call this to switch to the replay phase:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;replay(Mock)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;After the verification phase use this to verify that all expected invocations occured:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;verify(Mock)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Example code&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;These are the unit tests for erlymock, they have a certain documentory value...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-module(testtest).&lt;br /&gt;-compile(export_all).&lt;br /&gt;&lt;br /&gt;suite() -&gt;&lt;br /&gt;  test0(),&lt;br /&gt;  test0a(),&lt;br /&gt;  test0b(),&lt;br /&gt;  test0c(),&lt;br /&gt;  test0d(),&lt;br /&gt;  test0e(),&lt;br /&gt;  test1(),&lt;br /&gt;  test2(),&lt;br /&gt;  test3(),&lt;br /&gt;  test3a(),&lt;br /&gt;  test3b(),&lt;br /&gt;  test4(),&lt;br /&gt;  test4a(),&lt;br /&gt;  test5(),&lt;br /&gt;  test6(),&lt;br /&gt;  test6a(),&lt;br /&gt;  test7(),&lt;br /&gt;  test7a(),&lt;br /&gt;  io:format("~n~nfinished without unexpected errors! error reports may be ignored!!~n~n~n").&lt;br /&gt;&lt;br /&gt;test0() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule1, mockme1, [1,2], {return, ok}),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule1, mockme2, [2,3], {return, ok}),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule2, mockme2, [3,2], {return, ok}),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule2, mockme1, [1,2], {return, ok}),&lt;br /&gt;&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;&lt;br /&gt;  testmodule1:mockme1(1,2),&lt;br /&gt;  testmodule1:mockme2(2,3),&lt;br /&gt;  testmodule2:mockme2(3,2),&lt;br /&gt;  testmodule2:mockme1(1,2),&lt;br /&gt;&lt;br /&gt;  mock:verify(Mock).&lt;br /&gt;&lt;br /&gt;test0a() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule1, mockme1, [1,2], {return, ok}),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule1, mockme2, [2,3], {return, ok}),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule2, mockme2, [3,2], {return, ok}),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule2, mockme1, [1,2], {return, ok}),&lt;br /&gt;&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;&lt;br /&gt;  testmodule1:mockme1(1,2),&lt;br /&gt;  testmodule1:mockme2(2,3),&lt;br /&gt;  {'EXIT',_} = (catch testmodule2:mockme1(1,2)).&lt;br /&gt;&lt;br /&gt;test0b() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule1, mockme1, [1,2], {return, ok}),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule1, mockme2, [2,3], {return, ok}),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule2, mockme2, [3,2], {return, ok}),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule2, mockme1, [1,2], {return, ok}),&lt;br /&gt;&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;&lt;br /&gt;  testmodule1:mockme1(1,2),&lt;br /&gt;  testmodule1:mockme2(2,3),&lt;br /&gt;  testmodule2:mockme2(3,2),&lt;br /&gt;&lt;br /&gt;  {error, _} = mock:verify(Mock).&lt;br /&gt;&lt;br /&gt;test0c() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:strict(Mock, testmodule1, mockme1, [1,2], {return, ok}),&lt;br /&gt;  mock:o_o   (Mock, testmodule1, mockme2, [2,3], {return, ok}),&lt;br /&gt;  mock:strict(Mock, testmodule2, mockme2, [3,2], {return, ok}),&lt;br /&gt;  mock:o_o   (Mock, testmodule2, mockme1, [1,2], {return, ok}),&lt;br /&gt;&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;&lt;br /&gt;  testmodule1:mockme1(1,2),&lt;br /&gt;  testmodule2:mockme2(3,2),&lt;br /&gt;  testmodule2:mockme1(1,2),&lt;br /&gt;  testmodule1:mockme2(2,3),&lt;br /&gt;&lt;br /&gt;  mock:verify(Mock).&lt;br /&gt;&lt;br /&gt;test0d() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:strict(Mock, testmodule1, mockme1, [1,2], {return, ok}),&lt;br /&gt;  mock:o_o   (Mock, testmodule1, mockme2, [2,3], {return, ok}),&lt;br /&gt;  mock:strict(Mock, testmodule2, mockme2, [3,2], {return, ok}),&lt;br /&gt;  mock:o_o   (Mock, testmodule2, mockme1, [1,2], {return, ok}),&lt;br /&gt;&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;&lt;br /&gt;  testmodule1:mockme1(1,2),&lt;br /&gt;  testmodule2:mockme2(3,2),&lt;br /&gt;  testmodule2:mockme1(1,2),&lt;br /&gt;&lt;br /&gt;  {error, _} = mock:verify(Mock).&lt;br /&gt;&lt;br /&gt;test0e() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:strict(Mock, testmodule1, mockme1, [1,2], {return, ok}),&lt;br /&gt;  mock:o_o   (Mock, testmodule1, mockme2, [2,3], {return, ok}),&lt;br /&gt;  mock:strict(Mock, testmodule2, mockme2, [3,2], {return, ok}),&lt;br /&gt;  mock:o_o   (Mock, testmodule2, mockme1, [1,2], {return, ok}),&lt;br /&gt;&lt;br /&gt;  mock:stub  (Mock, testmodule3, mockme, [666], {return, ok}),&lt;br /&gt;  mock:stub  (Mock, testmodule3, mockme, [777], {return, ok}),&lt;br /&gt;  mock:stub  (Mock, testmodule3, mockme, [888], {return, ok}),&lt;br /&gt;  mock:stub  (Mock, testmodule3, mockme, [999], {return, ok}),&lt;br /&gt;&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;&lt;br /&gt;  ok = testmodule1:mockme1(1,2),&lt;br /&gt;  ok = testmodule2:mockme2(3,2),&lt;br /&gt;  ok = testmodule3:mockme(777),&lt;br /&gt;  ok = testmodule2:mockme1(1,2),&lt;br /&gt;  ok = testmodule3:mockme(777),&lt;br /&gt;  ok = testmodule3:mockme(888),&lt;br /&gt;  ok = testmodule1:mockme2(2,3),&lt;br /&gt;  ok = testmodule3:mockme(777),&lt;br /&gt;&lt;br /&gt;  mock:verify(Mock).&lt;br /&gt;&lt;br /&gt;test1() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;  mock:verify(Mock).&lt;br /&gt;&lt;br /&gt;%error expected&lt;br /&gt;test2() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:strict(Mock, testmodule, mockme, [1,2],{return, ok}),&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;  {error, _} = mock:verify(Mock).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;test3() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:strict(Mock, testmodule2, mockme1, [666], {error, end_of_times}),&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;  try testmodule2:mockme1(666) of&lt;br /&gt; _ -&gt;&lt;br /&gt;      exit(error_expected)&lt;br /&gt;  catch&lt;br /&gt; error:end_of_times -&gt;&lt;br /&gt;     ok&lt;br /&gt;  end.  &lt;br /&gt;&lt;br /&gt;test3a() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:o_o(Mock, testmodule2, mockme1, [666], {throw, end_of_times}),&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;  try testmodule2:mockme1(666) of&lt;br /&gt; _ -&gt;&lt;br /&gt;      exit(error_expected)&lt;br /&gt;  catch&lt;br /&gt; throw:end_of_times -&gt;&lt;br /&gt;     ok&lt;br /&gt;  end.  &lt;br /&gt;&lt;br /&gt;test3b() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:strict(Mock, testmodule2, mockme1, [666], {exit, end_of_times}),&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;  try testmodule2:mockme1(666) of&lt;br /&gt; _ -&gt;&lt;br /&gt;      exit(error_expected)&lt;br /&gt;  catch&lt;br /&gt; exit:end_of_times -&gt;&lt;br /&gt;     ok&lt;br /&gt;  end.  &lt;br /&gt;&lt;br /&gt;test4() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  {error,_} = mock:verify(Mock).&lt;br /&gt;&lt;br /&gt;test4a() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  {'EXIT',_} = (catch mock:strict(Mock, testmodule1, mockme1, [1,2], {hier_steht_was_falsches, xxx})).&lt;br /&gt;&lt;br /&gt;test5() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:strict(Mock, testmodule1, mockme1, [1,2], {rec_msg, self()}),&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;  TestPid = spawn(testmodule1,mockme1,[1,2]),&lt;br /&gt;  TestPid ! test,&lt;br /&gt;  receive&lt;br /&gt; test -&gt;&lt;br /&gt;     ok,&lt;br /&gt;     mock:verify(Mock)&lt;br /&gt;  after 1000 -&gt;&lt;br /&gt;     error&lt;br /&gt;  end.&lt;br /&gt;&lt;br /&gt;test6() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:o_o(Mock, testmodule1, mockme1, [1,2], {function, fun(X,Y) -&gt;&lt;br /&gt;            X + Y&lt;br /&gt;           end}),&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;  R = testmodule1:mockme1(1,2),&lt;br /&gt;  mock:verify(Mock),&lt;br /&gt;  3 = R.&lt;br /&gt;&lt;br /&gt;test6a() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:stub(Mock, testmodule1, mockme1, [1,2], {function, fun(_,_) -&gt;&lt;br /&gt;            erlang:error(test)&lt;br /&gt;           end}),&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;  {'EXIT',_} = (catch testmodule1:mockme1(1,2)),&lt;br /&gt;  mock:verify(Mock).&lt;br /&gt;&lt;br /&gt;test7() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule1, mockme1, 1,&lt;br /&gt;  fun([{qXYZ, D, B, A}]) when A &gt;= B andalso B &gt;= D -&gt;&lt;br /&gt;   true&lt;br /&gt;  end,&lt;br /&gt;  {function, fun({qXYZ, D, B, A}) -&gt;&lt;br /&gt;   [B,D|A]&lt;br /&gt;  end}&lt;br /&gt;        ),&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;  L = testmodule1:mockme1({qXYZ, 1,2,3}),&lt;br /&gt;  mock:verify(Mock),&lt;br /&gt;  [2,1|3] = L.&lt;br /&gt;&lt;br /&gt;test7a() -&gt;&lt;br /&gt;  Mock = mock:new(),&lt;br /&gt;  mock:expect(Mock, in_order, testmodule1, mockme1, 1,&lt;br /&gt;  %% hier fehlen die obligatorischen Klammern&lt;br /&gt;  fun({qXYZ, D, B, A}) when A &gt;= B andalso B &gt;= D -&gt;&lt;br /&gt;   true&lt;br /&gt;  end,&lt;br /&gt;  {function, fun({qXYZ, D, B, A}) -&gt;&lt;br /&gt;   [B,D|A]&lt;br /&gt;  end}&lt;br /&gt;        ),&lt;br /&gt;  mock:replay(Mock),&lt;br /&gt;  {'EXIT',_}= (catch testmodule1:mockme1({qXYZ, 1,2,3})).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Most important: erlymock source code&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Contents of file mock.erl:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-module(mock).&lt;br /&gt;-export([await/1,await/2,signal_fun/2,new/0, expect/7, expect/6, strict/6, strict/5, o_o/5, stub/5, replay/1, verify/1, verify_after_last_call/1, verify_after_last_call/2, invocation_event/1]).&lt;br /&gt;&lt;br /&gt;-author('Sven Heyll').&lt;br /&gt;-version(2).&lt;br /&gt;&lt;br /&gt;%% use this to create a new instance of a mock process that is in programming phase&lt;br /&gt;new() -&gt;&lt;br /&gt;    Mock = spawn_link(fun() -&gt; program_mock([],[],[]) end),&lt;br /&gt;    error_logger:info_msg("mock ~w: created~n", [Mock]),&lt;br /&gt;    Mock.&lt;br /&gt;&lt;br /&gt;%% expect has the following options:&lt;br /&gt;%% Orderchecking types: in_order, out_of_order, stub;  &lt;br /&gt;%% Answering: {return, ...}|{error, ...}|{throw, ...}|{exit, ...}|{rec_msg, Pid}|{function, Fun(Args)} -&gt; RetVal}|{function1, Fun(ArgList)}&lt;br /&gt;expect(Mock, Type, Module, Function, Arguments, Answer = {AT, _}) when is_list(Arguments), AT==return;AT==error;AT==throw;AT==exit;AT==rec_msg;AT==function;AT==function1 -&gt;&lt;br /&gt;    call(Mock, {expect, Type, Module, Function, length(Arguments), {Arguments, Answer}}).&lt;br /&gt;&lt;br /&gt;%% this version of expect is suited for useing custom argument matchers&lt;br /&gt;expect(Mock, Type, Module, Fun, Arity, MatcherFun, Answer) when is_integer(Arity), is_function(MatcherFun)-&gt;&lt;br /&gt;    call(Mock, {expect, Type, Module, Fun, Arity, {custom, MatcherFun, Answer}}).&lt;br /&gt;    &lt;br /&gt;%% this is a short cut for expect(.., in_order, ..)&lt;br /&gt;strict(Mock, M,F,Arity, Fun, Answer) when is_integer(Arity)-&gt;&lt;br /&gt;    expect(Mock, in_order, M, F, Arity, Fun, Answer).&lt;br /&gt;&lt;br /&gt;%% this is a short cut for expect(.., in_order, ..)&lt;br /&gt;strict(Mock, M,F,Args, Answer) -&gt;&lt;br /&gt;    expect(Mock, in_order, M, F, Args, Answer).&lt;br /&gt;&lt;br /&gt;%% this is a short cut for expect(.., in_order, ..)&lt;br /&gt;o_o(Mock, M,F,Args, Answer) -&gt;&lt;br /&gt;    expect(Mock, out_of_order, M, F, Args, Answer).&lt;br /&gt;&lt;br /&gt;%% this is a short cut for expect(.., in_order, ..)&lt;br /&gt;stub(Mock, M,F,Args, Answer) when is_list(Args)-&gt;&lt;br /&gt;    expect(Mock, stub, M, F, Args, Answer);&lt;br /&gt;&lt;br /&gt;%% this is a short cut for expect(.., in_order, ..)&lt;br /&gt;stub(Mock, M,F,Arity, Answer) when is_integer(Arity) -&gt;&lt;br /&gt;    expect(Mock, stub, M, F, Arity, fun(_) -&gt; true end, Answer).&lt;br /&gt;&lt;br /&gt;%% after the programming phase call this to switch to the replay phase&lt;br /&gt;replay(Mock) -&gt;&lt;br /&gt;    call(Mock, replay).&lt;br /&gt;&lt;br /&gt;%% after the verification phase use this to verify that all expected invocations occured&lt;br /&gt;verify(Mock) -&gt;    &lt;br /&gt;    verify_after_last_call(Mock, 0).&lt;br /&gt;&lt;br /&gt;%% after the verification phase use this to verify that all expected invocations occured&lt;br /&gt;verify_after_last_call(Mock) -&gt;&lt;br /&gt;    verify_after_last_call(Mock, 1500).&lt;br /&gt;verify_after_last_call(Mock, TimeOut) -&gt;&lt;br /&gt;    catch(await(invocation_list_empty, TimeOut)),&lt;br /&gt;    call(Mock, verify),&lt;br /&gt;    await(cleanup_finished),&lt;br /&gt;    error_logger:info_msg("mock ~p: verify finished~n~n~n", [Mock]).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&lt;br /&gt;%% utility functions for dealing with mock code called from a new process.&lt;br /&gt;&lt;br /&gt;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&lt;br /&gt;%% this will create an answering function that captures the current pid and&lt;br /&gt;%% sends an atom to that pid, make sure to use await(atom()) to block until that&lt;br /&gt;%% message is sent &lt;br /&gt;signal_fun(Atom, RetVal) -&gt;&lt;br /&gt;    SelfP = self(),&lt;br /&gt;    {function1, fun(_) -&gt; &lt;br /&gt;   signal(SelfP, Atom),&lt;br /&gt;   RetVal&lt;br /&gt;  end}.&lt;br /&gt;&lt;br /&gt;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    &lt;br /&gt;%% internal signal function that send a message in "signal" protocol format to&lt;br /&gt;%% some "await(...)"&lt;br /&gt;signal(Pid, Atom) -&gt;&lt;br /&gt;    error_logger:info_msg("signalling ~p from  ~p to ~p~n", [Atom, self(), Pid]),&lt;br /&gt;    Pid ! {mock_signal, Atom}.&lt;br /&gt;    &lt;br /&gt;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&lt;br /&gt;%% this block the current process until signal(SameAtom) from another process is&lt;br /&gt;%% invoked&lt;br /&gt;await(Atom) when is_atom(Atom) -&gt;&lt;br /&gt;    await(Atom, 2000).&lt;br /&gt;&lt;br /&gt;await(Atom,To) when is_atom(Atom)-&gt;       &lt;br /&gt;    error_logger:info_msg("now awaiting ~p in process ~p~n", [Atom, self()]),&lt;br /&gt;    receive&lt;br /&gt; {mock_signal, Atom} -&gt;&lt;br /&gt;     error_logger:info_msg("await succeeded: ~p~n", [Atom])&lt;br /&gt;    after To -&gt;&lt;br /&gt;     fail({timeout, await, Atom})&lt;br /&gt;    end.&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&lt;br /&gt;&lt;br /&gt;fail(Pid, Reason) -&gt;&lt;br /&gt;    error_logger:info_msg("mock ~w: failed: ~w~n",[self(), Reason]),&lt;br /&gt;    Pid ! {error, Reason}.&lt;br /&gt;&lt;br /&gt;fail(Reason) -&gt;&lt;br /&gt;    error_logger:info_msg("mock ~w: failed: ~w~n",[self(), Reason]),&lt;br /&gt;    throw({mock_failure, Reason}).&lt;br /&gt;&lt;br /&gt;success(Pid) -&gt;&lt;br /&gt;    Pid ! {response, ok},&lt;br /&gt;    success().&lt;br /&gt;&lt;br /&gt;success() -&gt;&lt;br /&gt;    error_logger:info_msg("mock ~w: successfully finished.~n",[self()]),&lt;br /&gt;    test_passed.    &lt;br /&gt;&lt;br /&gt;call(Name, Request) -&gt;&lt;br /&gt;    Name ! {self(), Request},&lt;br /&gt;    receive&lt;br /&gt; {error, Reason} -&gt;&lt;br /&gt;     throw({mock_failure, Reason});&lt;br /&gt; {response, Response} -&gt;&lt;br /&gt;     Response&lt;br /&gt;    end.&lt;br /&gt;&lt;br /&gt;filter_fun(_, _, _, {Arguments, _}) -&gt;    &lt;br /&gt;    fun(Args) -&gt;&lt;br /&gt;     Args == Arguments&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;filter_fun(_, _, _, {custom, Matcher, _}) -&gt;&lt;br /&gt;    Matcher.&lt;br /&gt;&lt;br /&gt;answer_fun({_, Answer}) -&gt;    &lt;br /&gt;    Answer;&lt;br /&gt;&lt;br /&gt;answer_fun({custom, _, Answer}) -&gt;&lt;br /&gt;    Answer.&lt;br /&gt;&lt;br /&gt;module_header_abstract_form(Mod) -&gt;&lt;br /&gt;    [{attribute,0,module,Mod}, &lt;br /&gt;    {attribute,0,compile,[export_all]}].&lt;br /&gt;&lt;br /&gt;fundef_to_abstract_meta_form(Self, Mod, FunName, Arity) -&gt;&lt;br /&gt;    Line = 1,&lt;br /&gt;    Params = [{var, Line, list_to_atom("A" ++ integer_to_list(I))} || I &lt;- seq(1,Arity)],&lt;br /&gt;    {function, Line, FunName, Arity,&lt;br /&gt;     [{clause, Line, &lt;br /&gt;       Params, [], &lt;br /&gt;       [{call, Line, &lt;br /&gt;  {remote, Line, {atom, Line, mock}, {atom, Line, invocation_event}}, &lt;br /&gt;  [{tuple, Line, &lt;br /&gt;    [{string,Line, Self}, {atom, Line, Mod}, {atom,Line, FunName}, {integer, Line, Arity},&lt;br /&gt;     lists:foldr(&lt;br /&gt;       fun(E,R) -&gt;&lt;br /&gt;        {cons, Line, E, R}&lt;br /&gt;       end, &lt;br /&gt;       {nil, Line}, &lt;br /&gt;       Params)]}]}]}]}.&lt;br /&gt;&lt;br /&gt;compile_and_load_abstract_form(AbsForm) -&gt;&lt;br /&gt;    CompRes = compile:forms(AbsForm),&lt;br /&gt;    {ok, Mod, Code} = CompRes,&lt;br /&gt;    code:purge(Mod),&lt;br /&gt;    code:delete(Mod),&lt;br /&gt;    {module, _} = load_module(Mod, Code).&lt;br /&gt;&lt;br /&gt;extract_module_set(Combined) -&gt;&lt;br /&gt;    sets:from_list(lists:map(fun([{M,_,_}|_]) -&gt; M end, Combined)).&lt;br /&gt;&lt;br /&gt;program_mock(InOrder, OutOfOrder, Stub) -&gt;&lt;br /&gt;    receive &lt;br /&gt; {From, {expect, Type, Mod, Fun, Arity, Arg}} -&gt;&lt;br /&gt;     FunDef = [{Mod, Fun, Arity} | {filter_fun(Mod,Fun,Arity,Arg), answer_fun(Arg)}],&lt;br /&gt;     From ! {response, ok},&lt;br /&gt;     case Type of &lt;br /&gt;  in_order -&gt;&lt;br /&gt;      program_mock([FunDef | InOrder], OutOfOrder, Stub);&lt;br /&gt;  out_of_order -&gt;&lt;br /&gt;      program_mock(InOrder, [FunDef | OutOfOrder], Stub);&lt;br /&gt;  stub -&gt;&lt;br /&gt;      program_mock(InOrder, OutOfOrder, [FunDef | Stub])&lt;br /&gt;     end;&lt;br /&gt;&lt;br /&gt; {From, replay}  -&gt;&lt;br /&gt;     Self = pid_to_list(self()),&lt;br /&gt;      Combined = InOrder ++ OutOfOrder ++ Stub,&lt;br /&gt;      ModuleSet = extract_module_set(Combined),&lt;br /&gt;      sets:fold( fun (Mod, _) -&gt;&lt;br /&gt;          FunsOfModSet = sets:from_list(&lt;br /&gt;      lists:foldl(&lt;br /&gt;        fun([{M,F,A}|_], Acc) -&gt; &lt;br /&gt;         if Mod == M -&gt; [{F,A}|Acc];           &lt;br /&gt;            true -&gt; Acc&lt;br /&gt;         end&lt;br /&gt;        end, [], Combined)),&lt;br /&gt;          HeaderForm = module_header_abstract_form(Mod),&lt;br /&gt;          FunctionForms = sets:fold(&lt;br /&gt;       fun({F,A},FFAcc) -&gt; &lt;br /&gt;        [fundef_to_abstract_meta_form(Self, Mod, F, A)|FFAcc]&lt;br /&gt;       end,&lt;br /&gt;       [],&lt;br /&gt;       FunsOfModSet),&lt;br /&gt;          CLRes = compile_and_load_abstract_form(HeaderForm ++ FunctionForms),&lt;br /&gt;          error_logger:info_msg("mock ~w: created and loaded mock code ~w~n",[self(),CLRes])&lt;br /&gt;         end,&lt;br /&gt;         [],&lt;br /&gt;         ModuleSet),&lt;br /&gt;       From ! {response, ok},&lt;br /&gt;     %% spawn a cleanup process that will call the uninstall fun&lt;br /&gt;     auto_cleanup(fun() -&gt;&lt;br /&gt;     uninstall(ModuleSet),&lt;br /&gt;     signal(From, cleanup_finished)&lt;br /&gt;    end),&lt;br /&gt;      record_invocations(lists:reverse(InOrder), &lt;br /&gt;          OutOfOrder, &lt;br /&gt;          Stub,&lt;br /&gt;          fun() -&gt; &lt;br /&gt;           signal(From, invocation_list_empty) &lt;br /&gt;          end&lt;br /&gt;         );&lt;br /&gt; {From, What} -&gt;     &lt;br /&gt;     fail(From, {invalid_state, What})&lt;br /&gt;    end.&lt;br /&gt; &lt;br /&gt;record_invocations([], [], Stub, EmptyFun) when is_function(EmptyFun) -&gt;&lt;br /&gt;    EmptyFun(),&lt;br /&gt;    record_invocations([], [], Stub, undefined);&lt;br /&gt;record_invocations(InOrder, OutOfOrder, Stub, EF) -&gt;&lt;br /&gt;    %% wait for all incoming invocations, expect every invocation and crash if the invocation was not correct&lt;br /&gt;    receive&lt;br /&gt; Invocation = {ProcUnderTestPid, Mod, Fun, Arity, Args} -&gt;&lt;br /&gt;     InvMatcher = fun ([{M,F,A}|{Pred,_}]) -&gt;&lt;br /&gt;     {M,F,A} == {Mod, Fun, Arity} andalso Pred(Args)&lt;br /&gt;    end,&lt;br /&gt;     try &lt;br /&gt;  case InOrder of&lt;br /&gt;      [Test| _] -&gt;  InvMatcher(Test);&lt;br /&gt;      [] -&gt; false&lt;br /&gt;  end&lt;br /&gt;  of&lt;br /&gt;  true -&gt;       &lt;br /&gt;      [[_|{_,Function}]| IOR] = InOrder,&lt;br /&gt;      ProcUnderTestPid ! {mock_process_gaurd__, Function},&lt;br /&gt;      record_invocations(IOR, OutOfOrder, Stub, EF);&lt;br /&gt;&lt;br /&gt;  false -&gt; &lt;br /&gt;      case lists:splitwith(InvMatcher, OutOfOrder) of&lt;br /&gt;   {[OOODef|Rest1],Rest2} -&gt;&lt;br /&gt;       [_|{_,Function}] = OOODef,        &lt;br /&gt;       ProcUnderTestPid ! {mock_process_gaurd__, Function},&lt;br /&gt;       record_invocations(InOrder, Rest1 ++ Rest2, Stub, EF);&lt;br /&gt;&lt;br /&gt;   {[], _} -&gt;&lt;br /&gt;       case lists:filter(InvMatcher, Stub) of&lt;br /&gt;    [StubDef|_] -&gt;&lt;br /&gt;        [_|{_,Function}] = StubDef,        &lt;br /&gt;        ProcUnderTestPid ! {mock_process_gaurd__, Function},&lt;br /&gt;        record_invocations(InOrder, OutOfOrder, Stub, EF);&lt;br /&gt;&lt;br /&gt;    _ -&gt;&lt;br /&gt;        EF(),&lt;br /&gt;        Reason = {unexpected_invocation, Invocation},&lt;br /&gt;        ProcUnderTestPid ! {mock_process_gaurd__, {error, Reason}},&lt;br /&gt;        fail(Reason)&lt;br /&gt;       end&lt;br /&gt;      end&lt;br /&gt;     catch&lt;br /&gt;  ET:EX -&gt; &lt;br /&gt;      Reason = {matching_function_is_incorrent, Invocation, {ET, EX}},&lt;br /&gt;      ProcUnderTestPid ! {mock_process_gaurd__, {error, Reason}},&lt;br /&gt;      EF(),&lt;br /&gt;      fail(Reason)&lt;br /&gt;     end; &lt;br /&gt;&lt;br /&gt; {From, verify} -&gt;&lt;br /&gt;     case {InOrder,OutOfOrder} of&lt;br /&gt;  {[],[]} -&gt; &lt;br /&gt;      success(From);&lt;br /&gt;  MissingRest -&gt;&lt;br /&gt;      fail(From,{expected_invocations_missing, MissingRest})&lt;br /&gt;     end;&lt;br /&gt;&lt;br /&gt; {From, What} -&gt;&lt;br /&gt;     EF(),&lt;br /&gt;     fail(From, {invalid_state, What})&lt;br /&gt;&lt;br /&gt;    end.&lt;br /&gt;&lt;br /&gt;invocation_event({MockPidStr, Mod, Fun, Arity, Args}) -&gt;&lt;br /&gt;    MockPid = list_to_pid(MockPidStr),&lt;br /&gt;    error_logger:info_msg("mock ~w: invocation: ~w:~w/~w ~w~n",[MockPid, Mod, Fun, Arity, Args]),&lt;br /&gt;    MockPid ! {self(), Mod, Fun, Arity, Args},&lt;br /&gt;    receive&lt;br /&gt; {mock_process_gaurd__, {return, Answer}} -&gt; &lt;br /&gt;     Answer;&lt;br /&gt; {mock_process_gaurd__, {error, E}} -&gt;&lt;br /&gt;     erlang:error(E);&lt;br /&gt; {mock_process_gaurd__, {throw, E}} -&gt;&lt;br /&gt;     throw(E);&lt;br /&gt; {mock_process_gaurd__, {exit, R}} -&gt;&lt;br /&gt;     exit(R);&lt;br /&gt; {mock_process_gaurd__, {function, F}} -&gt;&lt;br /&gt;     error_logger:info_msg("mock ~w: invoking answerer~n",[MockPid]),     &lt;br /&gt;     R = apply(F,Args),&lt;br /&gt;     error_logger:info_msg("mock ~w: answerer returned: ~w~n",[MockPid,R]),&lt;br /&gt;     R;&lt;br /&gt; {mock_process_gaurd__, {function1, F}} -&gt;&lt;br /&gt;     error_logger:info_msg("mock ~w: invoking answerer~n",[MockPid]),     &lt;br /&gt;     R = F(Args),&lt;br /&gt;     error_logger:info_msg("mock ~w: answerer returned: ~w~n",[MockPid,R]),&lt;br /&gt;     R;&lt;br /&gt; {mock_process_gaurd__, {rec_msg, P}} -&gt;&lt;br /&gt;     error_logger:info_msg("mock ~w: receiving message for ~w~n",[MockPid,P]),     &lt;br /&gt;     Msg = receive &lt;br /&gt;        M -&gt;&lt;br /&gt;     P ! M&lt;br /&gt;    end,&lt;br /&gt;     error_logger:info_msg("mock ~w: message ~w delivered to ~w~n",[MockPid,Msg,P])    &lt;br /&gt;    end.&lt;br /&gt;&lt;br /&gt;seq(A, E) when A &gt; E -&gt; [];&lt;br /&gt;seq(A, E) -&gt; lists:seq(A,E).&lt;br /&gt;    &lt;br /&gt;uninstall(ModuleSet) -&gt;&lt;br /&gt;    lists:map(fun(Mod) -&gt;&lt;br /&gt;        error_logger:info_msg("Deleting and purging module ~p~n", [Mod]),&lt;br /&gt;        code:purge(Mod),&lt;br /&gt;        code:delete(Mod)&lt;br /&gt;       end, sets:to_list(ModuleSet)).&lt;br /&gt;&lt;br /&gt;auto_cleanup(CleanupFun) -&gt;    &lt;br /&gt;    spawn_link(fun() -&gt;&lt;br /&gt;         erlang:process_flag(trap_exit, true),&lt;br /&gt;         error_logger:info_msg("auto cleanup handler ~p waiting for the end...~n", [self()]),&lt;br /&gt;         receive&lt;br /&gt;      Msg = {'EXIT', _From, _Reason} -&gt;&lt;br /&gt;          error_logger:info_msg("auto cleanup handler ~p receive exit message ~p.~n", [self(), Msg]),&lt;br /&gt;          CleanupFun();&lt;br /&gt;      _Ather -&gt; &lt;br /&gt;          error_logger:info_msg("auto cleanup handler ~p received unexpected message  ~p.~n", [self(), _Ather])&lt;br /&gt;         end&lt;br /&gt;        end).          &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-173182929999970761?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/173182929999970761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=173182929999970761' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/173182929999970761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/173182929999970761'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2009/02/erlang-mock-erlymock.html' title='Erlang mock - erlymock'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-6682605922066611142</id><published>2008-11-30T18:45:00.008+01:00</published><updated>2008-11-30T19:08:23.188+01:00</updated><title type='text'>my personal profiling guide</title><content type='html'>This is suited for functional programming.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Blind optimizations: just say NO.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. Write some unit tests that ensure your code stays correct.&lt;br /&gt;2. DO NOT ASSUME ANY KNOWLEDGE ON WHAT SHOULD BE OPTIMIZED- but try to "see"&lt;br /&gt;   possible bottlenecks.&lt;br /&gt;3. Write a the smallest possible program that uses the code to optimize, such that&lt;br /&gt;   the program exhibits the functionality that seems to be the bottleneck(s).&lt;br /&gt;   Design this program to run for a few seconds without user interaction.&lt;br /&gt;4. Use a decent profiler to profile a complete run of this program&lt;br /&gt;5. Optimize the bad code in this order&lt;br /&gt;    - estimate the complexity of the code around hotspots&lt;br /&gt;    - try diffrent data structures and algorithms&lt;br /&gt;      - try to involve background knowledge&lt;br /&gt;      - try to combine several functions into one&lt;br /&gt;      - records should fit into the cache of the target platform&lt;br /&gt;    - add more strictness(dangerous)&lt;br /&gt;    - move common subexpressions or constant subexpressions to a higher scope(generalisation of precalculation)&lt;br /&gt;    - use more efficient primitives(do I really need an arbitrary precission floating point)&lt;br /&gt;&lt;br /&gt;Following the steps from above I was able to optimize two new programms each by a factor of about 50(!).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-6682605922066611142?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/6682605922066611142/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=6682605922066611142' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/6682605922066611142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/6682605922066611142'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/11/my-personal-profiling-guide.html' title='my personal profiling guide'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-2463930315780830229</id><published>2008-09-15T07:18:00.003+02:00</published><updated>2008-09-15T07:34:18.629+02:00</updated><title type='text'>ArrowLoop - finally seeing the light at the end of a long tunnel</title><content type='html'>Today I achieved something I long lusted to acheive, I made the step from fix to loop.&lt;br /&gt;Basically by going from the applicative order Y combinator:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;(define (y f)&lt;br /&gt;  ((lambda (ff) &lt;br /&gt;     (lambda (xx)&lt;br /&gt;       (f (ff ff) xx)))&lt;br /&gt;   (lambda (ff) &lt;br /&gt;     (lambda (xx) &lt;br /&gt;       (f (ff ff) xx)))))&lt;br /&gt;&lt;br /&gt;(define (fak f n)&lt;br /&gt;  (if (= 0 n)&lt;br /&gt;      1&lt;br /&gt;      (* (f (- n 1)) n)))&lt;br /&gt;&lt;br /&gt;((y fak) 5)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;to writing the same in lazy haskell:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;y f = f $ y f&lt;br /&gt;&lt;br /&gt;fak r 0 = 1&lt;br /&gt;fak r n = n * r (n - 1)&lt;br /&gt;&lt;br /&gt;-- ghci&gt; y fak 5  ----&gt; 120&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;someone told me that &lt;br /&gt;&lt;pre&gt; fix = y &lt;/pre&gt;&lt;br /&gt;and that fix and loop are closely related.&lt;br /&gt;I found an aspiring &lt;a href="http://onthebalcony.wordpress.com/2007/02/19/my-evolution-as-a-haskell-programmer/"&gt;blogpost&lt;/a&gt; and thought it would be fun to&lt;br /&gt;do the fibonacci recursion instead of the simple factorial.&lt;br /&gt;&lt;br /&gt;That resulted in:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;data SF a b = SF {runSF :: [a] -&gt; [b]}&lt;br /&gt;&lt;br /&gt;instance Arrow SF where&lt;br /&gt;    arr f = SF (map f)&lt;br /&gt;    (SF f) &gt;&gt;&gt; (SF g) = SF (f &gt;&gt;&gt; g)&lt;br /&gt;    first (SF f) = SF $ unzip &gt;&gt;&gt; (first f) &gt;&gt;&gt; zip'&lt;br /&gt;&lt;br /&gt;instance ArrowLoop SF where&lt;br /&gt;    loop (SF f) = SF (\ins -&gt; &lt;br /&gt;                  let (outs, rs) = (zip' &gt;&gt;&gt; f &gt;&gt;&gt; unzip) (ins, lazy rs)&lt;br /&gt;                  in outs)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;lazy ~(z:zs) = z : lazy zs&lt;br /&gt;zip' = uncurry zip&lt;br /&gt;delay n = SF (n:)&lt;br /&gt;&lt;br /&gt;{-&lt;br /&gt;  &lt;br /&gt;   The Fibonacci device&lt;br /&gt;        1             2           3             4 &lt;br /&gt;&lt;br /&gt;   o----x    ,-&gt;(delay b)-.                ,--&gt;(id)-------&gt;o&lt;br /&gt;             |            |=&gt;(uncurry (+))-|&lt;br /&gt;   o---------'---(id)-----'                `--&gt;(delay a)--&gt;o&lt;br /&gt;&lt;br /&gt; (the first input is merely a clock source...)                 &lt;br /&gt;&lt;br /&gt; with the loop around:&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;-}&lt;br /&gt;fib n = take n (runSF (loop (fib' 0 1)) [1,1..])&lt;br /&gt;fib' :: (Num a) =&gt; a -&gt; a -&gt; SF (a, a) (a, a)&lt;br /&gt;fib' a b = arr snd  &gt;&gt;&gt; -- 1 &lt;br /&gt;           (delay b &amp;&amp;&amp; arr id) &gt;&gt;&gt;  -- 2&lt;br /&gt;           arr (uncurry (+)) &gt;&gt;&gt;  -- 3&lt;br /&gt;           (arr id &amp;&amp;&amp; delay a) -- 4&lt;br /&gt;&lt;br /&gt;{-&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   The experimental  Fibonacci device&lt;br /&gt;                   1             2                        3                4 &lt;br /&gt;   o-------------------------------------------.                   ,------(id)-----&gt;o&lt;br /&gt;             ,-&gt;(delay b)-.                    |===&gt; (uncurry (*))-|&lt;br /&gt;             |            |=&gt;(uncurry (+))-----'                   `---&gt;(delay a)--&gt;o&lt;br /&gt;   o---------'---(id)-----'                                    &lt;br /&gt;                  &lt;br /&gt;&lt;br /&gt;-}&lt;br /&gt;fibex' :: (Num a) =&gt; a -&gt; a -&gt; SF (a, a) (a, a)&lt;br /&gt;fibex' a b = (second &lt;br /&gt;            ((delay b &amp;&amp;&amp; arr id) &gt;&gt;&gt;  -- 1&lt;br /&gt;                                  arr (uncurry (+))))  -- 2&lt;br /&gt;           &gt;&gt;&gt;&lt;br /&gt;           (arr (uncurry (*))) &gt;&gt;&gt; -- 3&lt;br /&gt;                   ((arr id) &amp;&amp;&amp; (delay a)) -- 4&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;fibex n = take n (runSF (loop (fib' 0 1)) [1..])&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That was/is really fun. I like haskell.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-2463930315780830229?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/2463930315780830229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=2463930315780830229' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/2463930315780830229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/2463930315780830229'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/09/arrowloop-finally-seeing-light-at-end.html' title='ArrowLoop - finally seeing the light at the end of a long tunnel'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-2863439363449093425</id><published>2008-08-08T01:39:00.007+02:00</published><updated>2008-08-08T02:42:16.144+02:00</updated><title type='text'>Got Religious</title><content type='html'>[this is the only religious post you will ever encounter on this blog]&lt;br /&gt;&lt;font style="color:#000; background-color: #000"&gt;&lt;br /&gt;After an excessive amount of thinking, reading and &lt;br /&gt;weighting pros and cons I came to the final conclusion that &lt;br /&gt;actually and deep down in me, I beleive that&lt;br /&gt;1. God exists&lt;br /&gt;2. Christianity makes sense&lt;br /&gt;&lt;br /&gt;Many, many arguments exits against 1 and also 2.&lt;br /&gt;&lt;br /&gt;But as soon as you accept 1. arguing against 2 becomes&lt;br /&gt;really hard. All objections brought into field against 2. failed to&lt;br /&gt;convince me finally; ok some of them convinced me at first,&lt;br /&gt;and it took years to find out that they were errornous.&lt;br /&gt;Many objections seem clever at first, but really contain &lt;br /&gt;discrepancies or stem from pure ignorance.&lt;br /&gt;Most of those uttering them, do not really reflect &lt;br /&gt;these objections very well. A nice example is &lt;br /&gt;the following "objection" against 1. and partly 2.:&lt;br /&gt;"If god was almighty, could he create a &lt;br /&gt;stone so heavy, that he can't lift it?"&lt;br /&gt;It takes a bit of thinking, but is actually easy to debilitate. I will &lt;br /&gt;leave that as an exercise to the reader, I really don't want to &lt;br /&gt;take the fun out of this; I am sure, that also atheists will&lt;br /&gt;see the inherent logical problems in this objection :)&lt;br /&gt;&lt;br /&gt;I think that most religions can be unified to a common theme,&lt;br /&gt;I therefore believe, that some religions contain an abstract&lt;br /&gt;common base, that is below a thick tangible layer of &lt;br /&gt;"stories" - I prefer christianity, as it is the only one &lt;br /&gt;I know just good enough, to see how deeply consistent and&lt;br /&gt;consistent everything is. Although some peices seem odd or&lt;br /&gt;paradox at first, they make sense if you dig deeper and &lt;br /&gt;think about them...&lt;br /&gt;&lt;br /&gt;Regarding 1. How could a reasonable scientist exclude &lt;br /&gt;the existence of god, without leaving many&lt;br /&gt;questions open, and without entangling themselves in inconsistencies?&lt;br /&gt;Well even if my ignorance/stupidity is not a &lt;br /&gt;convincing argument that 1. is true, and you believe that&lt;br /&gt;something in this world *whatever that is* exists, you end up&lt;br /&gt;beleiving in some immaterial properties - one way or the other.&lt;br /&gt;I beleive that these properties exist (and might even be corner stones of a &lt;br /&gt;creation done be an intentional, allmighty being, which some call god) and are&lt;br /&gt;basic expressions of the Holy Ghost - as are the brain brain activities,&lt;br /&gt;that ask themselves now, wether this make sense or not.&lt;br /&gt;&lt;br /&gt;So ... please do not assume that I will bother anyone with my personal beleivesystem &lt;br /&gt;anymore, I just wanted share these thoughts, that's all I'll ever write about that &lt;br /&gt;topic.&lt;br /&gt;&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-2863439363449093425?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/2863439363449093425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=2863439363449093425' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/2863439363449093425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/2863439363449093425'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/08/got-religious.html' title='Got Religious'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-8666989470331805350</id><published>2008-08-07T02:26:00.004+02:00</published><updated>2008-08-07T02:34:38.753+02:00</updated><title type='text'>Erlang code snippet....</title><content type='html'>Code like that:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;blah(X) -&gt;&lt;br /&gt;  X1 = f(X),&lt;br /&gt;  X2 = g(X1),&lt;br /&gt;  X3 = h(X2),&lt;br /&gt;  i(X3).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;is very error prone, and worse very hard to extend. Just adding another&lt;br /&gt;function application between f(X) and g(X1) requires you to alter all lines&lt;br /&gt;upto the end of the function:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;blah(X) -&gt;&lt;br /&gt;  X1 = f(X),&lt;br /&gt;  X2 = j(X1)&lt;br /&gt;  X3 = g(X2),&lt;br /&gt;  X4 = h(X3),&lt;br /&gt;  i(X4).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This causes 2*numberoflinestoendoffunction potential error sources;&lt;br /&gt;&lt;br /&gt;And this is also not at all a very functional style.&lt;br /&gt;Why not rewriting it like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;blah(X) -&gt; &lt;br /&gt;    (chain([&lt;br /&gt;       f,&lt;br /&gt;       g,&lt;br /&gt;       h,&lt;br /&gt;       i&lt;br /&gt;      ]))(X).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;where one chains together the functions. Adding a function invocation in between is as easy as pie.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;chain(FunList) -&gt;&lt;br /&gt;  lists:foldl(&lt;br /&gt;    fun combine/2,&lt;br /&gt;    fun id/1,&lt;br /&gt;    FunList). &lt;br /&gt; &lt;br /&gt;id(X) -&gt; X.&lt;br /&gt;&lt;br /&gt;combine(F,G) -&gt;&lt;br /&gt;    RF = to_local_function(F),&lt;br /&gt;    RG = to_local_function(G),&lt;br /&gt;    fun(X) -&gt;&lt;br /&gt;     RF(RG(X))&lt;br /&gt;    end.&lt;br /&gt;&lt;br /&gt;to_local_function(F) -&gt;&lt;br /&gt;    case F of &lt;br /&gt; {FM, FF} -&gt; F;&lt;br /&gt; _ when is_atom(F) -&gt; {?MODULE, F}&lt;br /&gt;    end. &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Another solution might be using the state monad, wich was &lt;br /&gt;built for dealing with this kind of functional composition.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-8666989470331805350?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/8666989470331805350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=8666989470331805350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/8666989470331805350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/8666989470331805350'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/08/erlang-code-snippet.html' title='Erlang code snippet....'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-2483756515510799190</id><published>2008-08-04T15:41:00.015+02:00</published><updated>2008-08-04T23:29:49.251+02:00</updated><title type='text'>Lazy Evaluation(there be dragons and basement cats)</title><content type='html'>&lt;h2&gt;Lazy Evaluation and "undefined"&lt;/h2&gt;&lt;br /&gt;I am on the road to being a haskell programmer, and it still is a long way to go. Yesterday I had some nice guys from #haskell explain to me lazy evaluation.&lt;br /&gt;&lt;br /&gt;Take a look at this code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Prelude&gt; let x = undefined in "hello world"&lt;br /&gt;"hello world"&lt;br /&gt;Prelude&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Because of Haskells lazyness, x will not be evaluated because it is not used, hence undefined will not be evaluated and no exception will occur.&lt;br /&gt;&lt;br /&gt;The evaluation of "undefined" will result in a runtime exception:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Prelude&gt; undefined&lt;br /&gt;*** Exception: Prelude.undefined&lt;br /&gt;Prelude&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Strictness&lt;/h2&gt;&lt;br /&gt;Strictness means that the result of a function is undefined, if one of the arguments, the function is applied to, is undefined.&lt;br /&gt;Classical programming languages are strict. The following example in Java will demonstrate this. When the programm is run, it will throw a RuntimeException, although the variable "evilX" is never actually used, strictness requires that all&lt;br /&gt;arguments of a function are evaluated before that function is applied to(called with) these values:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;public class Strictness {&lt;br /&gt; public static void main(String[] args) {&lt;br /&gt;  int evilX = 1/0;&lt;br /&gt;  report_result("sven", evilX);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static void report_result(String name, int x) {&lt;br /&gt;  System.out.println("None cares about what "+name + " actually calculated...");&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When executed, the output of the program is:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Exception in thread "main" java.lang.ArithmeticException: / by zero&lt;br /&gt; at com.blogspot.sheyll.strictness.Strictness.main(Strictness.java:10)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A non-strict Haskell equivalent:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;module StrictnessFP where&lt;br /&gt;&lt;br /&gt;report_results name x = putStrLn $ "None cares about what " ++ name ++ " actually calculated..."&lt;br /&gt;&lt;br /&gt;main = let evilX = 1/0 in&lt;br /&gt;        report_results "Sven" evilX&lt;br /&gt;           &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When executed the following output appears:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;[1 of 1] Compiling StrictnessFP     ( C:/Users/sheyll/workspace/StrictnessFP/src/StrictnessFP.hs, interpreted )&lt;br /&gt;Ok, modules loaded: StrictnessFP.&lt;br /&gt;*StrictnessFP&gt; main&lt;br /&gt;None cares about what Sven actually calculated...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Enforcing strictness&lt;/h2&gt;&lt;br /&gt;Sometimes it makes sense to enforce strictness, in order to optimize the runtime performance. Lazy evaluation means that every value is encapsulated in a thunk, a&lt;br /&gt;function without paramaters, which is passed around instead of the actual value, and which is evaluated if needed. This might cause some overhead, compared to passing around the value directly. &lt;br /&gt;Another point to note is that evaluation order is undetermined, values are evaluated as needed, and therefore only as consequence to the interaction with the real world aka the IO Monad.&lt;br /&gt;In Haskell there is a standard operator to enforce strictness:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;seq:: a -&gt; t -&gt; t&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With the semantics:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;seq a t = if a /= undefined then t else undefined&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;THIS CODE WILL NOT RUN&lt;/b&gt; because the result of comparing something with undefined is always undefined, still this illustrates the idea, that seq will check(evaluate and throw away the result) its first parameter and only return the second parameter if the first did not evaluate to undefined.&lt;br /&gt;Why is this construct usefull? &lt;br /&gt;In case where we have the following structure, and want to optimize the performance and/or space requirements:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;complex_calculation x = seq x (... x ....)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;"seq" therefore ensures the order of evaluation, that's why it is called "seq".&lt;br /&gt;&lt;br /&gt;The following code will output the string "None cares about what Sven actually calculated...":&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;report_results name x = putStrLn ("None cares about what " ++ name ++ " actually calculated...")&lt;br /&gt;&lt;br /&gt;main = report_results "Sven" undefined&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Whereas the next version, that incorporates "seq", will throw an Exception at runtime:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;report_results name x = seq x (putStrLn ("None cares about what " ++ name ++ " actually calculated..."))&lt;br /&gt;&lt;br /&gt;main = report_results "Sven" undefined&lt;br /&gt;           &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Evaluation means reduction to weak head normal form&lt;/h2&gt;&lt;br /&gt;Simon Peyton Jones, one of the greatest Haskell-Hackers out there, coined the term&lt;br /&gt;"Weak Head Normal Form"(WHNF). &lt;br /&gt;In contrast, the "Head Normal Form"(HNF) requires, that during execution an expression must be reduced until it cannot be further reduced, i.e. all applyable lambda expressions must be applied.&lt;br /&gt;Whereas the WHNF is reached as soon as a lambda expression is achieved, even if it could be reduced further till finally the HNF is reached. &lt;br /&gt;Requirering reduction only to WHNF allows the program to stop the process of reduction, which actually is the process of executing the program, when a value is passed to a function, also if the value ist yet to be calculated by the application of another function.&lt;br /&gt;Requirering reduction to WHNF instead of HNF also allows the reuse of computation results and also helps a lot when implementing "lazy evaluation" in the compiler, because an algorithm called graph reduction can be used.&lt;br /&gt;Please search the net for weak head normal form.&lt;br /&gt;This concludes the theoretical part of this post. The next chapter will deal with&lt;br /&gt;a very practical issue:&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;There be Dragons: Stackoverflow!&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Everyone loves these two higher order functions foldr, foldl.&lt;br /&gt;Here is a possible definition of foldl that's close enough to reality:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;my_foldl f a (b:bs) = my_foldl f (f a b) bs&lt;br /&gt;my_foldl _ a [] = a &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If that definiton is used in the function below, we get a stack overflow exception:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;stack_overflow = my_foldl (\x y -&gt; x + y) 0 [1..1000000]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Because the x+y operations are contained in thunks, that pile up until the stack is full, because they are not evaluated! If they were, all that needs to be on the stack is a single integer, the result of each addition.&lt;br /&gt;&lt;br /&gt;For exactly that purpose a special version of foldl exists called " foldl' ", it's basically ....&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;A Strict "foldl"&lt;/h2&gt;&lt;br /&gt;The Data.List module of the Glasgow Haskell compiler contains a function called&lt;br /&gt;foldl' that has (roughly) the following definition:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;my_foldl' f a l = mfl a l&lt;br /&gt;    where mfl a [] = a&lt;br /&gt;          mfl a (x:xs) = let a' = f a x in a' `seq` mfl a' xs&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The variable a' contains the thunk for the computation f a x, and seq forces a' to be evaluated which means that the thunk called a' will be evaluated - which forces the application of f to a and x. &lt;br /&gt;&lt;br /&gt;In this example f is a lambda expression containing the addition of x and y, in fact&lt;br /&gt;it is similar to the expression that caused the stackoverflow:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;no_stack_overflow = my_foldl' (\x y -&gt; x + y) 0 [1..1000000]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;-  only this time there won't be a stackoverflow:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;*StrictnessFP&gt; no_stack_overflow&lt;br /&gt;500000500000&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So you think you're save now? Be aware, cause&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;&lt;a href="http://icanhascheezburger.com/2008/06/08/funny-pictures-cat-is-bsod-ur-dissertashun/"&gt;basement cat&lt;/a&gt; is in yar toople!!11oneeleven&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;What do you expect to be the outcome of the evaluation of basement_cat, as defined&lt;br /&gt;here:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;basement_cat = my_foldl' (\(x, y) i -&gt; (i, y + i)) (0,0) [1..10000000]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The surprising result is a stackoverflow, although we are using the strict version of foldl. &lt;br /&gt;The stuff piles up on the stack again, because the tuple construction (i, y+i) adds another layer of laziness ontop of the computation. The tuple itself is evaluated because we use the strict foldl, but the contents of the tuple are laziely chilling in thunks, that will not be evaluated until explicitely forced!&lt;br /&gt;&lt;br /&gt;The output of the basement_cat:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;*StrictnessFP&gt; basement_cat&lt;br /&gt;(10000000,*** Exception: stack overflow&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note how the first element of the tuple can still be evaluated, but not the second.&lt;br /&gt;&lt;br /&gt;So how can one get the desired result? The solution is to use the strictness operator "seq":&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ceiling_cat = my_foldl' (\(x, y) i -&gt; let y' = y + i in y' `seq` (i, y')) (0,0) [1..10000000]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When executed the interpreter outputs:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;*StrictnessFP&gt; ceiling_cat&lt;br /&gt;(10000000,50000005000000)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Write unit tests. Always. Even in Haskell.&lt;/h2&gt;&lt;br /&gt;So the conclusion for me is that lazy evaluation offers greate benefits:&lt;br /&gt;* optimization potential through graph reduction&lt;br /&gt;* declarative programming style i.e. thtough infinite lists&lt;br /&gt;* recursive functions and datastructures&lt;br /&gt;&lt;br /&gt;On the other hand one has to watch out for stack overflows and strictness issues when using i.e. tuples and lists, and all data constructors, as well as newtype contructors which contain tuples. It is essential to pay special attention to these &lt;br /&gt;issues, because they might be not very obvious, at least for a beginner.&lt;br /&gt;&lt;br /&gt;Further more the use of the strictness operator should be clear; it should be noted that it is not easiely possible to implement seq in haskell itself. I think it must somehow be built-in.&lt;br /&gt;As the name already suggests seq fixes the order of evaluation:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;a `seq` b&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Means first eval a then b.&lt;br /&gt;&lt;br /&gt;I am convinced, that especially the beginner needs to write unit tests; even in Haskell there are some non-trivial aspects that might cause unexpected behaviour.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-2483756515510799190?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/2483756515510799190/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=2483756515510799190' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/2483756515510799190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/2483756515510799190'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/08/lazy-evaluation-there-be-dragons-and.html' title='Lazy Evaluation(there be dragons and basement cats)'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-6372616553199298897</id><published>2008-08-01T03:19:00.002+02:00</published><updated>2008-08-01T12:30:29.797+02:00</updated><title type='text'>BlogPostAnswer.hs</title><content type='html'>{-&lt;br /&gt;&lt;h1&gt;Intro&lt;/h1&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;module BlogPostAnswer where&lt;br /&gt;&lt;br /&gt;import System.Environment&lt;br /&gt;&lt;br /&gt;{- &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is haskell source code, which relates&lt;br /&gt;to a nice blog post of someone comparing&lt;br /&gt;java with python.&lt;br /&gt;&lt;h2&gt;&lt;a href="http://www.clapper.org/bmc/blog/id/75"&gt;Original post&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;I picked some of the python-java comparisons&lt;br /&gt;from that post, which I would like to &lt;br /&gt;extend in order to contrast java and python&lt;br /&gt;with haskell.&lt;br /&gt;&lt;br /&gt;You can actually use the complete post as a&lt;br /&gt;haskell source code file. All prose is&lt;br /&gt;embedded in "{-" and "-}", wich are the block&lt;br /&gt;comment tokens in haskell syntax.&lt;br /&gt;&lt;br /&gt;I am a beginner haskell-hacker, and I dont have&lt;br /&gt;a clue about python, so enlighten me, if you spot&lt;br /&gt;a mistake.&lt;br /&gt;&lt;br /&gt;Like python, haskell allows you to use indenting &lt;br /&gt;as part of the syntax, unlike python however, you&lt;br /&gt;also have the choice of using "{", "}" and ";" &lt;br /&gt;instead of, or combined with, indentation.&lt;br /&gt;&lt;br /&gt;Also, like in python, and unlike java you don't need&lt;br /&gt;to put type declarations into you source code.&lt;br /&gt;&lt;br /&gt;The step from java to haskell is &lt;br /&gt;not the step from a statically typed language &lt;br /&gt;to a dynamically typed language. Neither is java &lt;br /&gt;really statically typed, nor is haskell &lt;br /&gt;dynamic. &lt;br /&gt;The opposite is true, haskell has a far stricter static&lt;br /&gt;typesystem than java has, but it uses a variation&lt;br /&gt;of the Hindley-Milner typesystem wich includes &lt;br /&gt;type inference - This effectivly frees one from &lt;br /&gt;writing type specs in most cases.&lt;br /&gt;&lt;br /&gt;Haskell has a rich typesystem with all kinds of &lt;br /&gt;good stuff. For someone who knows&lt;br /&gt;C++ template programming, learning haskell might be&lt;br /&gt;easier than learning java 5 generics.&lt;br /&gt;&lt;br /&gt;I will try to give code examples in haskell, that &lt;br /&gt;roughly correspond to the java and python code examples&lt;br /&gt;from the blog post.&lt;br /&gt;&lt;br /&gt;Plase aquire ghc and load this blogpost as haskell file. &lt;br /&gt;Every piece of code shown here, is complete and can be &lt;br /&gt;executed in the interactice haskell shell called ghci.&lt;br /&gt;&lt;br /&gt;Assuming ghci is started in the director where textfile &lt;br /&gt;with this source is located, the following commands  &lt;br /&gt;should be typed at the ghci prompt in order to compile and&lt;br /&gt;load the code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; :l (name of file)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(this loads the code)&lt;br /&gt;&lt;br /&gt;Now you can call every function in this source code from the prompt&lt;br /&gt;by writing the name and the arguments of that function seperated by&lt;br /&gt;spaces.&lt;br /&gt;i.e.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; test_matches_2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;to run the "main" function, you must compile the file outside the interactive shell and&lt;br /&gt;start the programm from the commandline like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;bash $ ghc --make (nameofsourcefile)&lt;br /&gt;bash $ ./(nameofsourcefile) "hallo welt"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Again, let me remind the reader, that I am not&lt;br /&gt;a haskell expert, and that there might be far&lt;br /&gt;more elegant ways to do it. &lt;br /&gt;&lt;br /&gt;ok, let's get started:&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Observation 1: Haskell is a unique mixture of readability and brevity&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Java:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Test&lt;br /&gt;{&lt;br /&gt;     public static void main(String[] args)&lt;br /&gt;     {&lt;br /&gt;         for (String s : args[0].split("\\s+"))&lt;br /&gt;             System.out.println(s);&lt;br /&gt;&lt;br /&gt;         System.exit(0);&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Haskell:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;main = getArgs &gt;&gt;= mapM putStrLn . words . head  &lt;br /&gt;&lt;br /&gt;{- &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This examples pipes a list of command line parameters into the&lt;br /&gt;functional combination of three functions that do the following in the &lt;br /&gt;order they are listed: &lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;takes the first element and ignores the rest: "head"&lt;/li&gt;&lt;br /&gt;&lt;li&gt;seperates this element into a list of words of wich the first element consists&lt;/li&gt;&lt;br /&gt;&lt;li&gt;write each word seperated by a newline to the stdout&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;As you may have noticed:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt; "&gt;&gt;=" pipes data &lt;/li&gt;&lt;br /&gt;&lt;li&gt; "." combines two functions to a new function&lt;/li&gt;&lt;br /&gt;&lt;li&gt; "mapM f"  call the function "mapM" with the parameter "f"&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;strong&gt;Haskell function application syntax is very similar to the&lt;br /&gt;typical unix shell function invocation syntax. &lt;br /&gt;The name of the function and the arguments are put in a line&lt;br /&gt;next to each other seperated by spaces instead of brackets.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Observation 2: No need for set/get methods in Haskell&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;One purpose of the 2nd code example from &lt;br /&gt;the above mentioned blogpost is to show off &lt;br /&gt;a nice python feature needed in a language &lt;br /&gt;with mutable state and oo features like instance &lt;br /&gt;variables.&lt;br /&gt;&lt;br /&gt;Haskell has neither mutable variables nor objects with variables.&lt;br /&gt;Haskell is a pure funcitonal programming language,&lt;br /&gt;meaning that like erlang, haskell has no notion of&lt;br /&gt;variables that may be changed after being bound.&lt;br /&gt;The typical OO-Class system, having classes with &lt;br /&gt;i.e. setters for properties is not possible in &lt;br /&gt;haskell without rolling your own little object &lt;br /&gt;system (wich isn't hard at all, but also not&lt;br /&gt;necessary).&lt;br /&gt;&lt;br /&gt;Haskell provides other means for grouping data.&lt;br /&gt;One way is to use algebraic data types:&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Observation 3: Haskell has useful constructs Java lacks&lt;/h2&gt;&lt;br /&gt;&lt;h3&gt;algebraic datatypes&lt;/h3&gt;&lt;br /&gt;Algeraic data types are those constructs that start with the reserved keyword "data". &lt;br /&gt;They create symbols associated with a place to create new structural type info associated&lt;br /&gt;with that symbol; with the hint that  "|" means "or" and that all words starting with capitals&lt;br /&gt;are symbols wich we associate witch structure and meaning, and that everything starting with a &lt;br /&gt;lowercase character is a (type-) parameter, have a look at the definiton of the datatype definitons in the follwoing;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;data Point2D = Point2D Double Double deriving (Show)&lt;br /&gt;&lt;br /&gt;{- &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;this defines a data type wich &lt;br /&gt;contains to floats: a 2-D point...&lt;br /&gt;before we go on, let's define another data type, &lt;br /&gt;but this time one that is &lt;br /&gt;parameterised with another type. &lt;br /&gt;Comparable with C++ templates:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;data Triangle p = Triangle p p p deriving (Show)&lt;br /&gt;&lt;br /&gt;{-&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; now we create a simple alias &lt;br /&gt; for 2D triangles (typedef in C++):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;type Triangle2D = Triangle Point2D&lt;br /&gt;&lt;br /&gt;{- &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Confused now? good, we can move on...&lt;br /&gt;&lt;br /&gt;Our Point2Ds can be created and read. &lt;br /&gt;Their contents (the two floats) are&lt;br /&gt;readonly. This of course doesn't bother &lt;br /&gt;us at all, it turns out in the long run&lt;br /&gt;to be a really nice feature &lt;br /&gt;concerning readability of code. &lt;br /&gt;&lt;br /&gt;Assume the following function that generates&lt;br /&gt;a "circle" made of n points with a radius of r: &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;generate_circle r n = [Point2D (calc sin i) (calc cos i) | i &lt;- [0 .. (n - 1)]]&lt;br /&gt;    where calc op i =  r * op ((i/n) * 2 * pi)&lt;br /&gt;&lt;br /&gt;{- &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;which looks like this in Java:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Point2d {&lt;br /&gt;  private final double x;&lt;br /&gt;  private final double y;&lt;br /&gt;&lt;br /&gt;  public Point2d(double x, double y) {&lt;br /&gt;    this.x = x;&lt;br /&gt;    this.y = y;&lt;br /&gt;  }&lt;br /&gt;  /* ... some getters... */&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public final class GenerateCircle {&lt;br /&gt;   &lt;br /&gt;   final Point2d[] points;&lt;br /&gt;   final double r;&lt;br /&gt;   final int n;&lt;br /&gt;&lt;br /&gt;   public GenerateCircle(double r, int n) {&lt;br /&gt;     points=new Point2d[n];&lt;br /&gt;     this.r = r;&lt;br /&gt;     this.n = n;&lt;br /&gt;     for ( int i = 0; i &lt; n; ++i) {&lt;br /&gt;       points[i] = new Point2d(calc_sin(i), calc_cos(i));&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt;   private float calc_sin(int i) {&lt;br /&gt;     return r * Math.sin((double)i/n * 2.0 * Math.PI);&lt;br /&gt;   }&lt;br /&gt;   private float calc_cos(int i) {&lt;br /&gt;     return r * Math.cos((double)i/n * 2.0 * Math.PI);&lt;br /&gt;   }&lt;br /&gt;   /* ... some getters ... */&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;pattern matching and guards&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Pattern matching is syntactic sugar that frees one&lt;br /&gt;from writing complicated if and switch constructs.&lt;br /&gt;Combined with algebraic data types, a feature that java lacks for sure -&lt;br /&gt;it is, as we have seen above, a way to simulate generic methods.&lt;br /&gt; &lt;br /&gt;Another useful construct is the function guard;&lt;br /&gt;let's look at a practical example:&lt;br /&gt; the programmer of the display function &lt;br /&gt;may use a simple constraints(a guard) to protect &lt;br /&gt;the precious display function:&lt;br /&gt;(the guard is the boolean expression &lt;br /&gt;between the "|" and the "=")&lt;br /&gt;Now if in that example x or y is less than 0 a runtime exception&lt;br /&gt;is thrown, with detailed information where and why the error was caused.(Try it already!)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;display_list primitives = [display p | p &lt;- primitives]&lt;br /&gt;    where display (Point2D x y)&lt;br /&gt;              | x &gt;= 0  &amp;&amp;  y &gt;= 0     = show (Point2D x y)&lt;br /&gt;&lt;br /&gt;{- &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;   All we do now is add a super type for primitives&lt;br /&gt;   and pimp our "display_list function a little to make&lt;br /&gt;   use of &lt;b&gt;pattern matching&lt;/b&gt; in conjunction with &lt;br /&gt;   algebraic data types(see below):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;data Primitive = Point Point2D | Tri Triangle2D&lt;br /&gt;&lt;br /&gt;display_primitives :: [Primitive] -&gt; [String]&lt;br /&gt;display_primitives primitives = [display p | p &lt;- primitives]&lt;br /&gt;    where&lt;br /&gt;      display (Point (Point2D x y)) &lt;br /&gt;          | x &gt;= 0 &amp;&amp; y &gt;= 0 = show (Point2D x y)&lt;br /&gt;      display (Tri (Triangle p1 p2 p3)) &lt;br /&gt;          = show (Triangle p1 p2 p3)&lt;br /&gt;&lt;br /&gt;{- &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;higher order functions, lambdas, currying and sections&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;When it comes to functions, lambdas and closures haskell really shines.&lt;br /&gt;In haskell &lt;b&gt;everything&lt;/b&gt; is done with functions. Let's have &lt;br /&gt;a look at a small example. &lt;br /&gt;Note that this example also makes heavy use of algebraic datatypes and pattern&lt;br /&gt;matching.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;data MyTree t = Leaf t | Node [MyTree t]&lt;br /&gt;&lt;br /&gt;{-&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In Java this would look like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface MyTree&amp;lt;T&amp;gt; {&lt;br /&gt;    public class Leaf&amp;lt;S&amp;gt; implements MyTree&amp;lt;S&amp;gt; {&lt;br /&gt; public S data;&lt;br /&gt;    }&lt;br /&gt;    public class Node&amp;lt;S&amp;gt; implements MyTree&amp;lt;S&amp;gt; {&lt;br /&gt; public MyTree&amp;lt;S&amp;gt; childs;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; This results in a tree with data in the leafs. Let's define a matches function,&lt;br /&gt; that returns a list of "ts" that match a user defined predicate(or matcher function):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;matches matcher (Leaf t)       = if matcher t then [t] else []&lt;br /&gt;matches matcher (Node childs)  = [e | child &lt;- childs,  e &lt;- matches matcher child] &lt;br /&gt;&lt;br /&gt;{-&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; well that's it! The first clause of the function "matches" is applied only to Leafs&lt;br /&gt; and the second clause uses list comprehension to call "matches" recursivly &lt;br /&gt; for every child node.&lt;br /&gt;&lt;br /&gt; In java is considerably harder to write (and to read).&lt;br /&gt;&lt;br /&gt;  Now let's leave this planet, and let's head off into a galaxy far far away...&lt;br /&gt;  Lets write a matcher that checks that the first letter is a capital "A", but let's &lt;br /&gt;  do this in two steps, lets first create a "startsWith" function that you should be&lt;br /&gt;  familiar with from other languages, and after the a function using the first one, &lt;br /&gt;  that checks for the capital "A".&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;startsWith str = (( == str) . (take (length str)))&lt;br /&gt;&lt;br /&gt;{- &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;  this can actually be translated to english:&lt;br /&gt;  "combine two functions: (this is the "." operator)&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;    &lt;br /&gt;    &lt;li&gt; A function that compares something for equality with str, this is "(== str)".&lt;br /&gt;    I used a fancy haskell feature here... (==str) is actually function call&lt;br /&gt;    to the function "==" which needs to arguments and returns True or False.&lt;br /&gt;    We gave the function only one argument "str". Of course the "==" function&lt;br /&gt;    cannot give us a Boolean value for that! But instead it gives us a new function,&lt;br /&gt;    a closure, that takes only one argument and returns a Bool. Isn't that cool?!&lt;br /&gt;    I mean once you get used to that, it's really readable and you will never want &lt;br /&gt;    to go back!&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;    &lt;li&gt; A function that returns a sublist of a list containing only the the first&lt;br /&gt;    "(length str)" elements: "(take (length str))"&lt;br /&gt;    BTW, a string in haskell is a list of characters, and "length" returns the number &lt;br /&gt;    of elements in a list.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;  Observe that startsWith takes only one argument not two! You may wonder how startsWith&lt;br /&gt;  can work, because it needs the string to search for and a string to search in.&lt;br /&gt;&lt;br /&gt;  Recall the weired (== str) construct. What happend here happens again: we created a new &lt;br /&gt;  anonymous function by calling a function named "==" with not enough arguments, btw.&lt;br /&gt;  this is called currying(- invented by the logician "Haskell Brooks Curry")&lt;br /&gt;  We also called "take" wich actually needs two arguments with only one argument&lt;br /&gt;  (the string length). The result is therefore a function the takes a string and returns&lt;br /&gt;  the desired sub-string with the same length that "str" has.&lt;br /&gt;  Now the combine operator (".") combines the two functions that each take one argument&lt;br /&gt;  and creates a new one such that the new function takes the input string for (take ...)&lt;br /&gt;  and returns the result of "(==str)" called with the result of "(take ...)";&lt;br /&gt;  &lt;br /&gt;  Let's forget about (==str) and (take...) for a while and let's look at the definition of&lt;br /&gt;  ".":&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  (f . g) x = f(g(x)) &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;  this might look familiar...&lt;br /&gt;  Now it should become clearer what the result of calling the startsWith function with&lt;br /&gt;  ONE parameter is: a new function that takes a string and returns a Bool indicating&lt;br /&gt;  wether or not the string given to that anonymous function starts with the string!&lt;br /&gt;&lt;br /&gt;  Once a programmer has learned very few core concepts about the function handling, &lt;br /&gt;  haskell source code is very readable, although it is often less terse than java code.&lt;br /&gt;&lt;br /&gt;  Also note that our startsWith function is perfectly generic, it can be applied to&lt;br /&gt;  ANY type of lists not just strings wich happen to be a synonym for lists of "Char"!&lt;br /&gt;  &lt;br /&gt;  Now I do not want to write down equivilant code for that in java, I think it is &lt;br /&gt;  possible. Also note that I do not want to judge the qualities of languages, &lt;br /&gt;  I just want to study them.&lt;br /&gt;&lt;br /&gt;  Ok, back to topic, let's create a test function that roughly corresponds to the one in &lt;br /&gt;  the original blogpost.&lt;br /&gt; &lt;br /&gt;  Remeber that we wanted to define a second function in terms of the first function, &lt;br /&gt;  that checks if a string starts with a capital "A"? &lt;br /&gt;  Here we use currying again, and simlpy and clearly write:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;startsWithA = startsWith "A"&lt;br /&gt;&lt;br /&gt;keywordTree = Node [ Node [ Leaf "Hallo"], Leaf "lieber", Leaf "Allerwertester", Node [Node [], Node [Leaf "Wie"], Leaf "gehts"], Leaf "dir"]&lt;br /&gt;&lt;br /&gt;test_matches_1 = matches startsWithA keywordTree&lt;br /&gt;&lt;br /&gt;{- &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;oh,  let's not forget to introduce a lambda!&lt;br /&gt;the greek symbol for a small lambda actually looks alot like the "\" (backslash) charakter,&lt;br /&gt;so in haskell a lambda is defined like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;\x  -&gt; x + 2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;in python:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;lambda x: x + 2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;another way in haskell:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(2 +)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A lambda expression with two parameters can be written in haskell like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;\x y -&gt; x + y&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;or simply:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(+)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;another way to write (==str) using a lambda:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;\x -&gt; x == str&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ok, back to the tree example,&lt;br /&gt;let's use a lambda expression as a parameter for "matches"&lt;br /&gt;to filter all words shorter than 5 characters.&lt;br /&gt;The then the complete expression looks like this:&lt;br /&gt;&lt;pre&gt;  &lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;test_matches_2 = matches (\x -&gt; length x &lt;= 5) keywordTree&lt;br /&gt;&lt;br /&gt;{-&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;of course we can assign the lamda expression to a name, and use that instead.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;shorter_than_5_chars = \x -&gt; length x &lt;=5&lt;br /&gt;test_matches_3 = matches shorter_than_5_chars keywordTree&lt;br /&gt;&lt;br /&gt;{-&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This can of course be written with haskells usual function definition syntax:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;shorter_than_4_chars x = length x &lt;= 4&lt;br /&gt;test_matches_4 = matches shorter_than_4_chars keywordTree&lt;br /&gt;&lt;br /&gt;{-&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And even more compact using functional compisition and sections:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;shorter_than_6_chars = (&lt;=6) . length&lt;br /&gt;test_matches_5 = matches shorter_than_6_chars keywordTree&lt;br /&gt;&lt;br /&gt;{-&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;shorter_that_6_chars is written in &lt;b&gt;point-free&lt;/b&gt; style, that means&lt;br /&gt;that in contrast to the previous definitons we didn't explicitly name&lt;br /&gt;the argument wupped around in the function, instead we just combined&lt;br /&gt;the the functions.&lt;br /&gt;This is very smilar to the pipe syntax in the bash:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; $ cat /proc/cpuinfo | grep bogo | awk '{print $3}' | sort -n&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here too no variable is mentioned, that actually contains the current line&lt;br /&gt;that is passed around.&lt;br /&gt;A functions stdin is its parameter and a functions stdout is its return value.&lt;br /&gt;That's also why it is so important in haskell to have currying automatically &lt;br /&gt;everywhere, because it allows me to use a function with more than one&lt;br /&gt;parameters as a function with one parameter wich returns a new function,&lt;br /&gt;wich takes one parameter and returns a new functions wich takes one parameter ... etc&lt;br /&gt;until final we get the actual result of the computation.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Factories?&lt;/h3&gt;&lt;br /&gt;Writing factories in haskell might by now seem not very interesting; still&lt;br /&gt;let's write some RPC class definitons in haskell:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;data RPC = XMLRPC String | JSONRPC String&lt;br /&gt;&lt;br /&gt;data RPCResult = Void | Str String | Strs [String] | Numbers [Int] -- define some results here...&lt;br /&gt;                 deriving (Show)&lt;br /&gt;                          &lt;br /&gt;callRemote :: RPC -&gt; String -&gt; [String] -&gt; RPCResult&lt;br /&gt;callRemote (XMLRPC conn) function args =&lt;br /&gt;    Str ("nyi, xmlrpc to "++ conn ++" func: " ++ function ++ " args: " ++ (show args))&lt;br /&gt;callRemote (JSONRPC conn) function args = &lt;br /&gt;    Str ("nyi, jsonrpc to "++ conn ++" func: " ++ function ++ " args: " ++ (show args))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;{-&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;Here is a little testfunction so you know how to use this;&lt;br /&gt;it will call the jsonrpc service "helloworld" at "http://..." with the arguments 1,2&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-}&lt;br /&gt;&lt;br /&gt;test_json_rpc = callRemote (JSONRPC "http://test.org/service") "helloworld" ["1", "2"]&lt;br /&gt;&lt;br /&gt;-- &lt;/pre&gt; now to a the factory:&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;rpc_factory ::  String -&gt; String -&gt; RPC &lt;br /&gt;rpc_factory impl arg = case impl of&lt;br /&gt;                         "JSON" -&gt; JSONRPC arg&lt;br /&gt;                         "XML"  -&gt; XMLRPC arg&lt;br /&gt;&lt;br /&gt;test_rpc_factory name = callRemote conn "trigger" []&lt;br /&gt;    where conn = rpc_factory name "http://alarm.org/sirene"&lt;br /&gt;{- &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Call the test_rpc_factory function with either "XML" or "JSON" from the &lt;br /&gt;ghci shell.&lt;br /&gt;&lt;br /&gt;A factory also makes sense when one wants to extend the programm at runtime.&lt;br /&gt;This can be done in haskell. Code can be dynamically loaded and recompiled&lt;br /&gt;in running haskell programms (see "hs-plugin"), with type checking and dependency&lt;br /&gt;resolution. &lt;br /&gt;&lt;br /&gt;It is possible to create a complete OO-Class infrastructure in haskell, &lt;br /&gt;similar to what exists in python, java and CLOS.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Lesser need for DI and friends&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;A nice application of factories is dependency injection. &lt;br /&gt;This extends the idea of factories, it allows programmers to wire all class&lt;br /&gt;instance dependencies and configuration values in one function in a declarative way.&lt;br /&gt;In powerfull functional languages this might be pointless in situation where this approach makes&lt;br /&gt;perfect sense in programs written in python or java, as the means of functional abstraction&lt;br /&gt;and combination, especially when used in combination with a powerfull type system, and pattern&lt;br /&gt;matching, render dependency injection frameworks simply useless - if the whole point&lt;br /&gt;of the dependency injection was merely the declarative wireing of class dependencies and&lt;br /&gt;configuration and not the ability to change all that at runtime.&lt;br /&gt;On the other hand, in systems like the erlang runtime complicated mechanisms exist to actually&lt;br /&gt;exchange code and the the dependencies of the code at runtime, &lt;br /&gt;while maintaining the serveral versions of the same code when it is still required, &lt;br /&gt;with automatically restarting services in the correct order when necessary, etc.&lt;br /&gt;&lt;br /&gt;Well I hope I have shown, that haskell can actually be fun to work with, and that &lt;br /&gt;diffrent approaches in the design of programming languages are always fun to look at.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;That's all folks&lt;/h2&gt;&lt;br /&gt;The original blog post author compared python with java to show the things he likes in python and&lt;br /&gt;he misses in java. &lt;br /&gt;This comparison has shown how similar phyton and java actually are when compared with haskell ;) &lt;br /&gt;My relation to haskell and java is similar to the blogpost authors relation to python and java,&lt;br /&gt;I think that the author should definitely have a look at haskell, for the &lt;br /&gt;relation to haskell and python might just develop to be of a similar nature, &lt;br /&gt;and the learning experience might also be pretty enlightening.&lt;br /&gt;&lt;br /&gt; -}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-6372616553199298897?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/6372616553199298897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=6372616553199298897' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/6372616553199298897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/6372616553199298897'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/08/blogpostanswerhs.html' title='BlogPostAnswer.hs'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-7259232127871454129</id><published>2008-05-27T14:31:00.003+02:00</published><updated>2008-05-27T21:39:04.529+02:00</updated><title type='text'>NumberCheck in haskell</title><content type='html'>&lt;pre&gt;&lt;br /&gt;import System.Environment&lt;br /&gt;import Data.Char&lt;br /&gt;&lt;br /&gt;main = do&lt;br /&gt;   arg:_ &lt;- getArgs&lt;br /&gt;   putStrLn (arg ++ " is " ++ (result arg))&lt;br /&gt;   where result arg = if check arg then "correct" else "incorrect"&lt;br /&gt;         check arg = dotOrDigit `all` arg &amp;&amp; oneOrZeroDots arg&lt;br /&gt;         dotOrDigit = (`elem` ['0'..'9'] ++ ['.'])&lt;br /&gt;         oneOrZeroDots = (&lt;=1) . length . (filter ('.'==))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-7259232127871454129?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/7259232127871454129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=7259232127871454129' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7259232127871454129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7259232127871454129'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/05/numbercheck-in-haskell.html' title='NumberCheck in haskell'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-273458198609522703</id><published>2008-05-21T02:47:00.016+02:00</published><updated>2008-05-27T21:45:44.882+02:00</updated><title type='text'>logs display, little experiment</title><content type='html'>this code ...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;module LogDiffMarker where&lt;br /&gt;&lt;br /&gt;type ReferenceWords = [String] &lt;br /&gt;type Lines = [Line]&lt;br /&gt;type Line = String&lt;br /&gt;&lt;br /&gt;mark_diffrent_words :: (ReferenceWords, Lines) -&gt; Line -&gt; (ReferenceWords, Lines)&lt;br /&gt;mark_diffrent_words (ref,i) line = (next_ref, i ++ [unwords line_with_em]) &lt;br /&gt;    where (line_with_em, next_ref) = mark_diffrences (words line) ref ([],[])       &lt;br /&gt;          mark_diffrences l1 [] (line_acc, ref_acc) = (line_acc ++ ["&amp;lt;b&gt;"] ++ l1 ++ ["&amp;lt;/b&gt;"], ref_acc ++ l1)&lt;br /&gt;          mark_diffrences [] r (line_acc, ref_acc) = (line_acc, ref_acc)&lt;br /&gt;          mark_diffrences (h1:t1) (h2:t2) (line_acc, ref_acc)&lt;br /&gt;                  | h1 == h2  = mark_diffrences t1 t2 (line_acc ++ [h1] ,ref_acc ++ [h2]) &lt;br /&gt;                  | otherwise = mark_diffrences t1 t2 (line_acc ++ ["&amp;lt;b&gt;" ++ h1 ++ "&amp;lt;/b&gt;"],ref_acc ++ [h1])&lt;br /&gt;&lt;br /&gt;mark_diffrent_lines :: Lines -&gt; Lines&lt;br /&gt;mark_diffrent_lines = (["&amp;lt;pre&gt;"]++) . (++["&amp;lt;/pre&gt;"]) . snd . (foldl mark_diffrent_words ([], []))&lt;br /&gt;  &lt;br /&gt;main = interact (unlines . mark_diffrent_lines . lines)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;...is a proof of concept of a highlighter algorithm for a logdisplayer that - if proofed useful - will be rewritten in javascript/html&lt;br /&gt;&lt;br /&gt;from:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;May 10 05:52:19 ubuntu syslogd 1.5.0#1ubuntu1: restart.&lt;br /&gt;May 10 06:22:02 ubuntu -- MARK --&lt;br /&gt;May 10 06:42:02 ubuntu -- MARK --&lt;br /&gt;May 10 06:51:49 ubuntu kernel: [ 2145.672201] nautilus[6101]: segfault at e1000020 eip b773f2d6 esp bfe4d9d0 error 5&lt;br /&gt;May 10 06:51:51 ubuntu kernel: [ 2147.588620] gdm[5658]: segfault at 10c03f90 eip b7801635 esp bf8100e0 error 4&lt;br /&gt;May 10 06:51:53 ubuntu kernel: [ 2149.171081] ip6_tables: (C) 2000-2006 Netfilter Core Team&lt;br /&gt;May 10 06:51:54 ubuntu exiting on signal 15&lt;br /&gt;May 12 19:07:04 ubuntu syslogd 1.5.0#1ubuntu1: restart.&lt;br /&gt;May 12 19:07:04 ubuntu kernel: Inspecting /boot/System.map-2.6.24-16-generic&lt;br /&gt;May 12 19:07:04 ubuntu kernel: Loaded 27704 symbols from /boot/System.map-2.6.24-16-generic.&lt;br /&gt;May 12 19:07:04 ubuntu kernel: Symbols match kernel version 2.6.24.&lt;br /&gt;May 12 19:07:05 ubuntu kernel: Loaded 32155 symbols from 83 modules.&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] Linux version 2.6.24-16-generic (buildd@palmer) (gcc version 4.2.3 (Ubuntu 4.2.3&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] BIOS-provided physical RAM map:&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000]  BIOS-e820: 0000000000000000 - 000000000009f800 (usable)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000]  BIOS-e820: 000000000009f800 - 00000000000a0000 (reserved)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000]  BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000]  BIOS-e820: 0000000000100000 - 000000007fff0000 (usable)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000]  BIOS-e820: 000000007fff0000 - 000000007fff3000 (ACPI NVS)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000]  BIOS-e820: 000000007fff3000 - 0000000080000000 (ACPI data)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000]  BIOS-e820: 00000000d0000000 - 00000000e0000000 (reserved)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000]  BIOS-e820: 00000000fec00000 - 0000000100000000 (reserved)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] 1151MB HIGHMEM available.&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] 896MB LOWMEM available.&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] found SMP MP-table at 000f52c0&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] Zone PFN ranges:&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000]   DMA             0 -&gt;     4096&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000]   Normal       4096 -&gt;   229376&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000]   HighMem    229376 -&gt;   524272&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] Movable zone start PFN for each node&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] early_node_map[1] active PFN ranges&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000]     0:        0 -&gt;   524272&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] DMI 2.3 present.&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] ACPI: RSDP signature @ 0xC00F6C50 checksum 0&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] ACPI: RSDP 000F6C50, 0014 (r0 Nvidia)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] ACPI: RSDT 7FFF3000, 0030 (r1 Nvidia AWRDACPI 42302E31 AWRD  1010101)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] ACPI: FACP 7FFF3040, 0074 (r1 Nvidia AWRDACPI 42302E31 AWRD  1010101)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] ACPI: DSDT 7FFF30C0, 4BF2 (r1 NVIDIA AWRDACPI     1000 MSFT  100000C)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] ACPI: FACS 7FFF0000, 0040&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] ACPI: MCFG 7FFF7D40, 003C (r1 Nvidia AWRDACPI 42302E31 AWRD  1010101)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] ACPI: APIC 7FFF7CC0, 007C (r1 Nvidia AWRDACPI 42302E31 AWRD  1010101)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] Nvidia board detected. Ignoring ACPI timer override.&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] If you got timer trouble try acpi_use_timer_override&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [    0.000000] ACPI: PM-Timer IO Port: 0x1008&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;to&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;May 10 05:52:19 ubuntu syslogd 1.5.0#1ubuntu1: restart.&lt;br /&gt;May 10 &lt;b&gt;06:22:02&lt;/b&gt; ubuntu &lt;b&gt;--&lt;/b&gt; &lt;b&gt;MARK&lt;/b&gt; &lt;b&gt;--&lt;/b&gt;&lt;br /&gt;May 10 &lt;b&gt;06:42:02&lt;/b&gt; ubuntu -- MARK --&lt;br /&gt;May 10 &lt;b&gt;06:51:49&lt;/b&gt; ubuntu &lt;b&gt;kernel:&lt;/b&gt; &lt;b&gt;[&lt;/b&gt; &lt;b&gt;2145.672201]&lt;/b&gt; nautilus[6101]: segfault at e1000020 eip b773f2d6 esp bfe4d9d0 error 5&lt;br /&gt;May 10 &lt;b&gt;06:51:51&lt;/b&gt; ubuntu kernel: [ &lt;b&gt;2147.588620]&lt;/b&gt; &lt;b&gt;gdm[5658]:&lt;/b&gt; segfault at &lt;b&gt;10c03f90&lt;/b&gt; eip &lt;b&gt;b7801635&lt;/b&gt; esp &lt;b&gt;bf8100e0&lt;/b&gt; error &lt;b&gt;4&lt;/b&gt;&lt;br /&gt;May 10 &lt;b&gt;06:51:53&lt;/b&gt; ubuntu kernel: [ &lt;b&gt;2149.171081]&lt;/b&gt; &lt;b&gt;ip6_tables:&lt;/b&gt; &lt;b&gt;(C)&lt;/b&gt; &lt;b&gt;2000-2006&lt;/b&gt; &lt;b&gt;Netfilter&lt;/b&gt; &lt;b&gt;Core&lt;/b&gt; &lt;b&gt;Team&lt;/b&gt;&lt;br /&gt;May 10 &lt;b&gt;06:51:54&lt;/b&gt; ubuntu &lt;b&gt;exiting&lt;/b&gt; &lt;b&gt;on&lt;/b&gt; &lt;b&gt;signal&lt;/b&gt; &lt;b&gt;15&lt;/b&gt;&lt;br /&gt;May &lt;b&gt;12&lt;/b&gt; &lt;b&gt;19:07:04&lt;/b&gt; ubuntu &lt;b&gt;syslogd&lt;/b&gt; &lt;b&gt;1.5.0#1ubuntu1:&lt;/b&gt; &lt;b&gt;restart.&lt;/b&gt;&lt;br /&gt;May 12 19:07:04 ubuntu &lt;b&gt;kernel:&lt;/b&gt; &lt;b&gt;Inspecting&lt;/b&gt; &lt;b&gt;/boot/System.map-2.6.24-16-generic&lt;/b&gt;&lt;br /&gt;May 12 19:07:04 ubuntu kernel: &lt;b&gt;Loaded&lt;/b&gt; &lt;b&gt;27704&lt;/b&gt; symbols from /boot/System.map-2.6.24-16-generic.&lt;br /&gt;May 12 19:07:04 ubuntu kernel: &lt;b&gt;Symbols&lt;/b&gt; &lt;b&gt;match&lt;/b&gt; &lt;b&gt;kernel&lt;/b&gt; &lt;b&gt;version&lt;/b&gt; &lt;b&gt;2.6.24.&lt;/b&gt;&lt;br /&gt;May 12 &lt;b&gt;19:07:05&lt;/b&gt; ubuntu kernel: &lt;b&gt;Loaded&lt;/b&gt; &lt;b&gt;32155&lt;/b&gt; &lt;b&gt;symbols&lt;/b&gt; &lt;b&gt;from&lt;/b&gt; &lt;b&gt;83&lt;/b&gt; modules.&lt;br /&gt;May 12 19:07:05 ubuntu kernel: &lt;b&gt;[&lt;/b&gt; &lt;b&gt;0.000000]&lt;/b&gt; &lt;b&gt;Linux&lt;/b&gt; &lt;b&gt;version&lt;/b&gt; &lt;b&gt;2.6.24-16-generic&lt;/b&gt; &lt;b&gt;(buildd@palmer)&lt;/b&gt; (gcc version 4.2.3 (Ubuntu 4.2.3-2ubuntu7)) #1 SMP Thu Apr 10 13:23:42 UTC 2008 (Ubuntu 2.6.24-16.30-generic)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;BIOS-provided&lt;/b&gt; &lt;b&gt;physical&lt;/b&gt; &lt;b&gt;RAM&lt;/b&gt; &lt;b&gt;map:&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;BIOS-e820:&lt;/b&gt; &lt;b&gt;0000000000000000&lt;/b&gt; &lt;b&gt;-&lt;/b&gt; &lt;b&gt;000000000009f800&lt;/b&gt; (usable)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] BIOS-e820: &lt;b&gt;000000000009f800&lt;/b&gt; - &lt;b&gt;00000000000a0000&lt;/b&gt; &lt;b&gt;(reserved)&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] BIOS-e820: &lt;b&gt;00000000000f0000&lt;/b&gt; - &lt;b&gt;0000000000100000&lt;/b&gt; (reserved)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] BIOS-e820: &lt;b&gt;0000000000100000&lt;/b&gt; - &lt;b&gt;000000007fff0000&lt;/b&gt; &lt;b&gt;(usable)&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] BIOS-e820: &lt;b&gt;000000007fff0000&lt;/b&gt; - &lt;b&gt;000000007fff3000&lt;/b&gt; &lt;b&gt;(ACPI&lt;/b&gt; NVS)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] BIOS-e820: &lt;b&gt;000000007fff3000&lt;/b&gt; - &lt;b&gt;0000000080000000&lt;/b&gt; (ACPI &lt;b&gt;data)&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] BIOS-e820: &lt;b&gt;00000000d0000000&lt;/b&gt; - &lt;b&gt;00000000e0000000&lt;/b&gt; &lt;b&gt;(reserved)&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] BIOS-e820: &lt;b&gt;00000000fec00000&lt;/b&gt; - &lt;b&gt;0000000100000000&lt;/b&gt; (reserved)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;1151MB&lt;/b&gt; &lt;b&gt;HIGHMEM&lt;/b&gt; &lt;b&gt;available.&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;896MB&lt;/b&gt; &lt;b&gt;LOWMEM&lt;/b&gt; available.&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;found&lt;/b&gt; &lt;b&gt;SMP&lt;/b&gt; &lt;b&gt;MP-table&lt;/b&gt; at 000f52c0&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;Zone&lt;/b&gt; &lt;b&gt;PFN&lt;/b&gt; &lt;b&gt;ranges:&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;DMA&lt;/b&gt; &lt;b&gt;0&lt;/b&gt; &lt;b&gt;-&gt;&lt;/b&gt; 4096&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;Normal&lt;/b&gt; &lt;b&gt;4096&lt;/b&gt; -&gt; &lt;b&gt;229376&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;HighMem&lt;/b&gt; &lt;b&gt;229376&lt;/b&gt; -&gt; &lt;b&gt;524272&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;Movable&lt;/b&gt; &lt;b&gt;zone&lt;/b&gt; &lt;b&gt;start&lt;/b&gt; &lt;b&gt;PFN&lt;/b&gt; for each node&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;early_node_map[1]&lt;/b&gt; &lt;b&gt;active&lt;/b&gt; &lt;b&gt;PFN&lt;/b&gt; &lt;b&gt;ranges&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;0:&lt;/b&gt; &lt;b&gt;0&lt;/b&gt; &lt;b&gt;-&gt;&lt;/b&gt; &lt;b&gt;524272&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;DMI&lt;/b&gt; &lt;b&gt;2.3&lt;/b&gt; &lt;b&gt;present.&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;ACPI:&lt;/b&gt; &lt;b&gt;RSDP&lt;/b&gt; &lt;b&gt;signature&lt;/b&gt; @ 0xC00F6C50 checksum 0&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] ACPI: RSDP &lt;b&gt;000F6C50,&lt;/b&gt; &lt;b&gt;0014&lt;/b&gt; &lt;b&gt;(r0&lt;/b&gt; &lt;b&gt;Nvidia)&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] ACPI: &lt;b&gt;RSDT&lt;/b&gt; &lt;b&gt;7FFF3000,&lt;/b&gt; &lt;b&gt;0030&lt;/b&gt; &lt;b&gt;(r1&lt;/b&gt; &lt;b&gt;Nvidia&lt;/b&gt; AWRDACPI 42302E31 AWRD 1010101)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] ACPI: &lt;b&gt;FACP&lt;/b&gt; &lt;b&gt;7FFF3040,&lt;/b&gt; &lt;b&gt;0074&lt;/b&gt; (r1 Nvidia AWRDACPI 42302E31 AWRD 1010101)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] ACPI: &lt;b&gt;DSDT&lt;/b&gt; &lt;b&gt;7FFF30C0,&lt;/b&gt; &lt;b&gt;4BF2&lt;/b&gt; (r1 &lt;b&gt;NVIDIA&lt;/b&gt; AWRDACPI &lt;b&gt;1000&lt;/b&gt; &lt;b&gt;MSFT&lt;/b&gt; &lt;b&gt;100000C)&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] ACPI: &lt;b&gt;FACS&lt;/b&gt; &lt;b&gt;7FFF0000,&lt;/b&gt; &lt;b&gt;0040&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] ACPI: &lt;b&gt;MCFG&lt;/b&gt; &lt;b&gt;7FFF7D40,&lt;/b&gt; &lt;b&gt;003C&lt;/b&gt; (r1 Nvidia AWRDACPI 42302E31 AWRD 1010101)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] ACPI: &lt;b&gt;APIC&lt;/b&gt; &lt;b&gt;7FFF7CC0,&lt;/b&gt; &lt;b&gt;007C&lt;/b&gt; (r1 Nvidia AWRDACPI 42302E31 AWRD 1010101)&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;Nvidia&lt;/b&gt; &lt;b&gt;board&lt;/b&gt; &lt;b&gt;detected.&lt;/b&gt; &lt;b&gt;Ignoring&lt;/b&gt; &lt;b&gt;ACPI&lt;/b&gt; &lt;b&gt;timer&lt;/b&gt; &lt;b&gt;override.&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;If&lt;/b&gt; &lt;b&gt;you&lt;/b&gt; &lt;b&gt;got&lt;/b&gt; &lt;b&gt;timer&lt;/b&gt; &lt;b&gt;trouble&lt;/b&gt; &lt;b&gt;try&lt;/b&gt; &lt;b&gt;acpi_use_timer_override&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;ACPI:&lt;/b&gt; &lt;b&gt;PM-Timer&lt;/b&gt; &lt;b&gt;IO&lt;/b&gt; &lt;b&gt;Port:&lt;/b&gt; &lt;b&gt;0x1008&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] ACPI: &lt;b&gt;LAPIC&lt;/b&gt; &lt;b&gt;(acpi_id[0x00]&lt;/b&gt; &lt;b&gt;lapic_id[0x00]&lt;/b&gt; &lt;b&gt;enabled)&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;Processor&lt;/b&gt; &lt;b&gt;#0&lt;/b&gt; &lt;b&gt;15:3&lt;/b&gt; &lt;b&gt;APIC&lt;/b&gt; &lt;b&gt;version&lt;/b&gt; 16&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;ACPI:&lt;/b&gt; &lt;b&gt;LAPIC&lt;/b&gt; &lt;b&gt;(acpi_id[0x01]&lt;/b&gt; &lt;b&gt;lapic_id[0x01]&lt;/b&gt; &lt;b&gt;enabled)&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;Processor&lt;/b&gt; &lt;b&gt;#1&lt;/b&gt; &lt;b&gt;15:3&lt;/b&gt; &lt;b&gt;APIC&lt;/b&gt; &lt;b&gt;version&lt;/b&gt; 16&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;ACPI:&lt;/b&gt; &lt;b&gt;LAPIC_NMI&lt;/b&gt; &lt;b&gt;(acpi_id[0x00]&lt;/b&gt; &lt;b&gt;dfl&lt;/b&gt; &lt;b&gt;dfl&lt;/b&gt; &lt;b&gt;lint[0x1])&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] ACPI: LAPIC_NMI &lt;b&gt;(acpi_id[0x01]&lt;/b&gt; dfl dfl lint[0x1])&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] ACPI: &lt;b&gt;IOAPIC&lt;/b&gt; &lt;b&gt;(id[0x02]&lt;/b&gt; &lt;b&gt;address[0xfec00000]&lt;/b&gt; &lt;b&gt;gsi_base[0])&lt;/b&gt;&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;IOAPIC[0]:&lt;/b&gt; &lt;b&gt;apic_id&lt;/b&gt; &lt;b&gt;2,&lt;/b&gt; &lt;b&gt;version&lt;/b&gt; &lt;b&gt;17,&lt;/b&gt; address 0xfec00000, GSI 0-23&lt;br /&gt;May 12 19:07:05 ubuntu kernel: [ 0.000000] &lt;b&gt;ACPI:&lt;/b&gt; &lt;b&gt;INT_SRC_OVR&lt;/b&gt; &lt;b&gt;(bus&lt;/b&gt; &lt;b&gt;0&lt;/b&gt; &lt;b&gt;bus_irq&lt;/b&gt; &lt;b&gt;0&lt;/b&gt; &lt;b&gt;global_irq&lt;/b&gt; &lt;b&gt;2&lt;/b&gt; &lt;b&gt;dfl&lt;/b&gt; dfl)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-273458198609522703?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/273458198609522703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=273458198609522703' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/273458198609522703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/273458198609522703'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/05/logs-anzeigen-kleines-experiment.html' title='logs display, little experiment'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-2931865743492027781</id><published>2008-04-30T01:38:00.001+02:00</published><updated>2008-04-30T02:36:04.639+02:00</updated><title type='text'>functional music, honorable mention of new composer C.W. Boese</title><content type='html'>just after the previous post a talented composer (Boese) used the small framework for functional music in haskell for one of his compisitions. His work balances harmony and disharmony in an unbalanced way and thereby balances the unbalancing and balancing forces driving the excellent piece of modern algorithmic music. with his silent permission the source as well the interpretation is attached to this post.&lt;br /&gt;&lt;br /&gt;Here's the interpretation using an artifical Clarinet: &lt;a href="http://file1.npage.de/001511/88/musik/boeseclarinet.mp3"&gt;play&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here's the source:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;boeseboese = Rest (2/4) :+: (hochlauf (-2) 3 boese) :=: (hochlauf (2) 3 boese) :+: boese&lt;br /&gt;boese = rpt 3 freak :=: rpt 3 ghoul :=: rpt 3 funk&lt;br /&gt;grund = (Note (Cis,5) 1)&lt;br /&gt;freak = rptm (Trans (round (abs (duration ghoul)))) 3 funk&lt;br /&gt;ghoul = akkord grund 0&lt;br /&gt;funk = Trans terz grund :=: rptm (Trans quinte) 4 ghoul&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;just append that to the previous program and adapt the main function.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Maybe it's also worth mentioning, that this was the first piece of haskell code written by him.&lt;br /&gt;Haskell syntax helps to create frameworks with very little effort, that reassemble DSLs. In this case parts of the DSL for functional music from the School Of Expression was used to aid composers in creating algorithmic music without the syntactic burdens of a low-level language like (Ihh.. pfui... bahh) "java", that lack many, even basic features, like being NullPointer free, pattern matching, currying, higher order functions, type inference, laziness, ...etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-2931865743492027781?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/2931865743492027781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=2931865743492027781' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/2931865743492027781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/2931865743492027781'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/04/functional-music-honorable-mention-of.html' title='functional music, honorable mention of new composer C.W. Boese'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-7943675031883226298</id><published>2008-04-29T19:11:00.000+02:00</published><updated>2008-04-29T21:14:14.639+02:00</updated><title type='text'>Learning Haskell, functional music</title><content type='html'>As you might have realized, I started to learn Haskell. One of the most fun things to do in any programming language is creating some kind of audible side effects with a program.&lt;br /&gt;Already back in the days when I started programming, I always played around with audio when toying around with a new language.&lt;br /&gt;&lt;br /&gt;I have found a wonderful set of lecture slides about haskell and multimedia programming, called school of expression. Inspired by the slides about functional music I implemented a little song. Ahh ... and yes it is intended to sound slightly &lt;i&gt;strange&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;I used the synthesis toolkit to transform the music to real noise, simply by piping skini message to std-out.&lt;br /&gt;&lt;br /&gt;I used this command line to achieve the results audible in the table:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sven@hhi1214a:~/Mukke$ ghc -o test1 test1.hs &amp;&amp;  ./test1 | stk-demo Plucked -n 16 -or -ip &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Sound samples:&lt;br /&gt;&lt;table&gt;&lt;br /&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Plucked&lt;/td&gt;&lt;td&gt;&lt;a href="http://file1.npage.de/001511/88/musik/funktionalemusikplucked.mp3"&gt;play&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Clarinet&lt;/td&gt;&lt;td&gt;&lt;a href="http://file1.npage.de/001511/88/musik/funktionalemusikclarinet.mp3"&gt;play&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Whistle(attention very crazy!)&lt;/td&gt;&lt;td&gt;&lt;a href="http://file1.npage.de/001511/88/musik/funktionalemusikwhistle.mp3"&gt;play&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;As always the source...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;stueck = anfang :+: mitte :+: ende&lt;br /&gt;&lt;br /&gt;anfang = groovy :+: (Trans (-5) trickie)&lt;br /&gt;mitte = seq_overlap (1/3) mitte1 mitte2&lt;br /&gt;mitte1 = (3/4) `schneller`  (Trans (-2) groovy) &lt;br /&gt;mitte2 = (3/4) `schneller` groovy&lt;br /&gt;ende = Rest (1/4) :+: (moll_akkord (Note (A,4) 1))&lt;br /&gt;&lt;br /&gt;groovy = dumschingbadumschingsching 3 (2/3) -- fast schon swing artiger rythmischer versatz&lt;br /&gt;trickie = dumschingbadumschingsching 2 (3/4)&lt;br /&gt;&lt;br /&gt;blim_sching af = ((Note (A,3) (1/4)) :+: (af (Note (A,4) (1/4))))&lt;br /&gt;dumdideldum af = quinten_hochlauf 4 (rpt 2 $ blim_sching af) -- 4 klingt leicht schief&lt;br /&gt;dumschingbadumschingsching r versatz = interleave r versatz (dumdideldum moll_akkord) (Trans 3 (dumdideldum dur_akkord))&lt;br /&gt;&lt;br /&gt;main :: IO ()&lt;br /&gt;main = do&lt;br /&gt;mapM_ putStrLn $ music_to_skini stueck 33&lt;br /&gt;&lt;br /&gt;-- functional music composition&lt;br /&gt;hochlauf tr n m = rep (Trans quinte) (delay (duration m)) n m&lt;br /&gt;quinten_hochlauf = hochlauf quinte&lt;br /&gt;interleave n dist m1 m2 = (rpt n m1) :=:  (Rest dist :+: (rpt n m2))&lt;br /&gt;schneller spdup m =  (Tempo ((duration m)*(spdup)) m)&lt;br /&gt;&lt;br /&gt;akkord grundton moll_dur = grundton :=: (Trans (3 + moll_dur) grundton) :=: (Trans 7 grundton)&lt;br /&gt;moll_akkord grundton = akkord grundton 0&lt;br /&gt;dur_akkord grundton = akkord grundton 1&lt;br /&gt;&lt;br /&gt;terz    = 3&lt;br /&gt;gr_terz = 4&lt;br /&gt;quarte  = 5&lt;br /&gt;quinte  = 7&lt;br /&gt;&lt;br /&gt;seq_overlap overlap m1 m2 = m1 :=: (delay ((duration m2) - overlap) m2)&lt;br /&gt;&lt;br /&gt;rpt 0 m = Rest 0&lt;br /&gt;rpt n m = m :+: rpt (n-1) m&lt;br /&gt;&lt;br /&gt;rptm f 0 m = Rest 0&lt;br /&gt;rptm f n m = m :+: rptm f (n - 1) (f m)&lt;br /&gt;&lt;br /&gt;rep f g 0 m = Rest 0&lt;br /&gt;rep f g n m = m :=: g (rep f g (n-1) (f m))&lt;br /&gt;&lt;br /&gt;--  functional music basics, based on the school of expression lecture slides&lt;br /&gt;data Music = Note Pitch Dur&lt;br /&gt;| Rest Dur&lt;br /&gt;| Music :+: Music&lt;br /&gt;| Music :=: Music&lt;br /&gt;| Tempo Dur Music&lt;br /&gt;| Trans Int Music&lt;br /&gt;| Instr Int Music&lt;br /&gt;| Control ControlMessage Music&lt;br /&gt;deriving (Show, Eq)&lt;br /&gt;&lt;br /&gt;type Dur = Rational&lt;br /&gt;&lt;br /&gt;type Pitch = (Tone, Octave)&lt;br /&gt;data Tone = C | Cis | D | Dis | E | F | Fis | G | Gis | A | B | H&lt;br /&gt;deriving (Show, Eq)&lt;br /&gt;type Octave = Int&lt;br /&gt;&lt;br /&gt;type ControlMessage = (Int, Int)&lt;br /&gt;&lt;br /&gt;-- absolute pitches&lt;br /&gt;type AbsPitch = Int&lt;br /&gt;&lt;br /&gt;trans :: Int -&gt; Pitch -&gt; Pitch&lt;br /&gt;trans i p = pitch (absPitch p + i)&lt;br /&gt;&lt;br /&gt;pitch :: AbsPitch -&gt; Pitch&lt;br /&gt;pitch p = ([C, Cis, D, Dis, E, F, Fis, G, Gis, A, B, H] !! mod p 12, p `quot` 12)&lt;br /&gt;&lt;br /&gt;absPitch :: Pitch -&gt; AbsPitch&lt;br /&gt;absPitch (n, o) = (o * 12) + (case n of C -&gt; 0; Cis -&gt; 1; D -&gt; 2; Dis -&gt; 3; E -&gt; 4; F -&gt; 5; Fis -&gt; 6; G -&gt; 7; Gis -&gt; 8; A -&gt; 9; B -&gt; 10; H -&gt; 11)&lt;br /&gt;&lt;br /&gt;-- delay&lt;br /&gt;delay :: Dur -&gt; Music -&gt; Music&lt;br /&gt;delay d = ((Rest d) :+:)&lt;br /&gt;&lt;br /&gt;-- absolute durations&lt;br /&gt;abs_dur :: BeatPM -&gt; Dur -&gt; AbsDur&lt;br /&gt;abs_dur bpm d = (fromRational d) / (bpm / (60.0))&lt;br /&gt;&lt;br /&gt;type BeatPM = Float&lt;br /&gt;type AbsDur = Float&lt;br /&gt;&lt;br /&gt;-- calculate the duration of a piece of music&lt;br /&gt;duration :: Music -&gt; Dur&lt;br /&gt;duration m = case m of&lt;br /&gt;Rest d -&gt; d&lt;br /&gt;Note _ d -&gt; d&lt;br /&gt;m1 :+: m2 -&gt; duration m1 + duration m2&lt;br /&gt;m1 :=: m2 -&gt; max (duration m1) (duration m2)&lt;br /&gt;Tempo d _ -&gt; d&lt;br /&gt;Trans _ m1 -&gt; duration m1&lt;br /&gt;Instr _ m1 -&gt; duration m1&lt;br /&gt;Control _ m1 -&gt; duration m1&lt;br /&gt;&lt;br /&gt;-- convert to a simple event stream of musical events with absolute values&lt;br /&gt;-- that soley consist of NoteOn and NoteOff events with midi notes and timestamps&lt;br /&gt;data MusicEvent = MusicEv MusicEventType AbsPitch AbsDur&lt;br /&gt;deriving (Show, Eq)&lt;br /&gt;&lt;br /&gt;data MusicEventType = NoteOn | NoteOff&lt;br /&gt;deriving (Show, Eq)&lt;br /&gt;&lt;br /&gt;to_event_stream :: BeatPM -&gt; Music -&gt; AbsDur -&gt; (AbsDur, [MusicEvent])&lt;br /&gt;to_event_stream bpm um start_time =&lt;br /&gt;    case m of&lt;br /&gt;Note p d -&gt;&lt;br /&gt; let dur = start_time + (abs_dur bpm d)&lt;br /&gt; in (dur, [(MusicEv NoteOn (absPitch p) start_time), (MusicEv NoteOff (absPitch p) dur)])&lt;br /&gt;&lt;br /&gt;Rest d -&gt;&lt;br /&gt; (start_time  + (abs_dur bpm d), [])&lt;br /&gt;&lt;br /&gt;Tempo d m1 -&gt;&lt;br /&gt; to_event_stream (bpm * (fromRational (duration m1)) * 1.0/(fromRational d)) m1 start_time&lt;br /&gt;&lt;br /&gt;m1 :+: m2 -&gt;&lt;br /&gt; (total_dur,  evt_str1 ++ evt_str2)&lt;br /&gt; where (st1, evt_str1) = to_event_stream bpm m1 start_time&lt;br /&gt;       (total_dur, evt_str2) = to_event_stream bpm m2 st1&lt;br /&gt;&lt;br /&gt;m1 :=: m2 -&gt;&lt;br /&gt; (max dur1 dur2, merge evt_str1 evt_str2)&lt;br /&gt; where (dur1, evt_str1) = to_event_stream bpm m1 start_time&lt;br /&gt;       (dur2, evt_str2) = to_event_stream bpm m2 start_time&lt;br /&gt;&lt;br /&gt;_ -&gt; (start_time, [])&lt;br /&gt;&lt;br /&gt;    where&lt;br /&gt;m = transpose_all um 0&lt;br /&gt;transpose_all :: Music -&gt; Int -&gt; Music&lt;br /&gt;transpose_all m tr = case m of&lt;br /&gt; Trans tr2 m1 -&gt; transpose_all m1 (tr + tr2)&lt;br /&gt; Note p d -&gt; Note (trans tr p) d&lt;br /&gt; m1 :+: m2 -&gt; (transpose_all m1 tr) :+: (transpose_all m2 tr)&lt;br /&gt; m1 :=: m2 -&gt; (transpose_all m1 tr) :=: (transpose_all m2 tr)&lt;br /&gt; other -&gt; other&lt;br /&gt;merge :: [MusicEvent] -&gt; [MusicEvent] -&gt; [MusicEvent]&lt;br /&gt;merge l1 l2 = mergea l1 l2 []&lt;br /&gt;mergea :: [MusicEvent] -&gt; [MusicEvent] -&gt; [MusicEvent] -&gt; [MusicEvent]&lt;br /&gt;mergea [] l2 acc = acc ++ l2&lt;br /&gt;mergea l1 [] acc = acc ++ l1&lt;br /&gt;mergea l1@(e1@(MusicEv _ _ dur1):r1) l2@(e2@(MusicEv _ _ dur2):r2) acc&lt;br /&gt; | dur1 &lt;=  dur2 = mergea r1 l2 (acc ++ [e1])      | dur1 &gt;   dur2 = mergea l1 r2 (acc ++ [e2])  &lt;br /&gt;&lt;br /&gt;-- convert to skinni&lt;br /&gt;{-&lt;br /&gt;&lt;type&gt; &lt;time&gt; &lt;channel&gt; &lt;arg1&gt; &lt;arg2&gt;&lt;br /&gt;NoteOn delay channel midi-note volume&lt;br /&gt;NoteOff delay channel midi-note volume&lt;br /&gt;time is always the time to wait after the last event&lt;br /&gt;arg1 is the midi note number&lt;br /&gt;arg2 is the volume&lt;br /&gt;-}&lt;br /&gt;to_skini :: [MusicEvent] -&gt; [[Char]]&lt;br /&gt;to_skini event_stream = skini_stream&lt;br /&gt;where (time_acc, skini_stream) = foldl make_skini (0.0, []) event_stream&lt;br /&gt; make_skini :: (AbsDur, [[Char]]) -&gt; MusicEvent -&gt; (AbsDur, [[Char]])&lt;br /&gt; make_skini (total_time, other_skini) (MusicEv mtype pitch ev_time)  =&lt;br /&gt;  (ev_time, other_skini ++ [(show mtype) ++ "   " ++ (show (ev_time - total_time)) ++ "   1   " ++ (show pitch) ++ "   127.0"])&lt;br /&gt;&lt;br /&gt;music_to_skini :: Music -&gt; BeatPM -&gt; [[Char]]&lt;br /&gt;music_to_skini m bpm = to_skini event_stream &lt;br /&gt;where (_, event_stream) = to_event_stream bpm m 0.0&lt;br /&gt;&lt;/arg2&gt;&lt;/arg1&gt;&lt;/channel&gt;&lt;/time&gt;&lt;/type&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-7943675031883226298?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/7943675031883226298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=7943675031883226298' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7943675031883226298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7943675031883226298'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/04/learning-haskell-functional-music.html' title='Learning Haskell, functional music'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-6995439591821981584</id><published>2008-04-11T03:59:00.000+02:00</published><updated>2008-04-11T04:00:57.231+02:00</updated><title type='text'>Haskell Thread Ring Benchmark</title><content type='html'>&lt;h2&gt;Not as fast as the erlang version coming soon:&lt;/h2&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;import Control.Monad&lt;br /&gt;import Control.Concurrent&lt;br /&gt;import System.Environment&lt;br /&gt;import System.CPUTime&lt;br /&gt;&lt;br /&gt;fork_ring_elem prev_mvar _ = do&lt;br /&gt;  next_mvar &lt;- newEmptyMVar&lt;br /&gt;  forkIO (ring_elem prev_mvar next_mvar)&lt;br /&gt;  return next_mvar&lt;br /&gt;&lt;br /&gt;ring_elem :: MVar Int -&gt; MVar Int -&gt; IO ()&lt;br /&gt;ring_elem prev_mv next_mv = run&lt;br /&gt;  where run = do&lt;br /&gt;          token &lt;- takeMVar prev_mv&lt;br /&gt;          putMVar next_mv (token - 1)         &lt;br /&gt;          when ( token &gt; 0 ) run&lt;br /&gt;&lt;br /&gt;first_ring_elem :: MVar Int -&gt; MVar Int -&gt; IO ()&lt;br /&gt;first_ring_elem prev_mv next_mv = run&lt;br /&gt;  where run = do&lt;br /&gt;          token &lt;- takeMVar prev_mv&lt;br /&gt;          putMVar next_mv (token - 1)         &lt;br /&gt;          putStrLn "."&lt;br /&gt;          when ( token &gt; 0 ) run&lt;br /&gt;&lt;br /&gt;main = do&lt;br /&gt;  (procsArg:roundsArg:_) &lt;- getArgs&lt;br /&gt;  first_mvar &lt;- newMVar ((read procsArg) * (read roundsArg))&lt;br /&gt;  t1 &lt;- getCPUTime&lt;br /&gt;  last_mvar &lt;- foldM fork_ring_elem first_mvar [2..(read procsArg)]&lt;br /&gt;  t2 &lt;- getCPUTime&lt;br /&gt;  putStrLn ("forked processes in " ++ (show (t2 - t1)) ++ " ps")&lt;br /&gt;  first_ring_elem last_mvar first_mvar&lt;br /&gt;  t3 &lt;- getCPUTime&lt;br /&gt;  putStrLn "\n***finished***"&lt;br /&gt;  putStrLn ("total time: " ++ (show (t3 - t1)) ++ " ps")&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-6995439591821981584?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/6995439591821981584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=6995439591821981584' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/6995439591821981584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/6995439591821981584'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/04/haskell-thread-ring-benchmark.html' title='Haskell Thread Ring Benchmark'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-5785040520653231646</id><published>2008-03-08T16:50:00.000+01:00</published><updated>2008-03-08T17:11:58.591+01:00</updated><title type='text'>coping emacs #1</title><content type='html'>After having written a lot of erlang code with emacs(uhhm ... no, erlide, the erlang eclipse plugin, is not yet a viable alternative...), I decided to start (back-)porting eclipse features to emacs. Yeahhhh! I am now among those 1337 |-|4&amp;gt;&amp;lt;025 that have their own ".emacs" in ~.&lt;br /&gt;&lt;br /&gt;Well one feature, that I can't live without, is moving the current line with Alt - up/down, this is really usefull together with &lt;strike&gt;another&lt;/strike&gt;&lt;b&gt;the other&lt;/b&gt; feature: duplicating the current line(Ctrl-Alt-up/down).&lt;br /&gt;&lt;br /&gt;Below is the elisp code that provides these features and binds them to the keys these are bound to in eclipse. Note: In contrast to the eclipse version of this feature, this implementation does not(yet) work with regions, but with lines only.&lt;br /&gt;&lt;br /&gt;Ok, put this in your ~/.emacs&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;;; Written by Sven Heyll in 2008&lt;br /&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;(defun sh-wind-col (thunk)&lt;br /&gt;  (let ((col (- (point) (line-beginning-position))))&lt;br /&gt;    (apply thunk '())&lt;br /&gt;    (beginning-of-line)&lt;br /&gt;    (forward-char col)))&lt;br /&gt;&lt;br /&gt;(defun sh-with-current-line (func)&lt;br /&gt;  (let ((cline (buffer-substring (line-beginning-position) (line-end-position))))&lt;br /&gt;    (apply func `(,cline))))&lt;br /&gt;&lt;br /&gt;(defun sh-dup-line-down ()&lt;br /&gt;  (interactive)&lt;br /&gt;  (sh-wind-col&lt;br /&gt;   (lambda ()&lt;br /&gt;     (sh-with-current-line&lt;br /&gt;      (lambda (cline)&lt;br /&gt; (end-of-line)&lt;br /&gt; (insert ?\n)&lt;br /&gt; (insert cline))))))&lt;br /&gt;&lt;br /&gt;(defun sh-dup-line-up ()&lt;br /&gt;  (interactive)&lt;br /&gt;  (sh-wind-col&lt;br /&gt;   (lambda ()&lt;br /&gt;     (sh-with-current-line&lt;br /&gt;      (lambda (cline)&lt;br /&gt; (beginning-of-line)&lt;br /&gt; (insert cline)&lt;br /&gt; (insert ?\n)&lt;br /&gt; (forward-line -1))))))&lt;br /&gt;&lt;br /&gt;(global-set-key [C-M-down] 'sh-dup-line-down)&lt;br /&gt;(global-set-key [C-M-up]   'sh-dup-line-up)&lt;br /&gt;   &lt;br /&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;(defun sh-move-line (dir)&lt;br /&gt;  (defun extract-a-line (dir)&lt;br /&gt;    (let ((line-start (line-beginning-position (+ 1 dir)))&lt;br /&gt;   (line-end   (line-end-position (+ 1 dir))))&lt;br /&gt;      (setq res (delete-and-extract-region line-start line-end))&lt;br /&gt;      (delete-region line-start (+ 1 line-start))&lt;br /&gt;      res))&lt;br /&gt;  (if (not &lt;br /&gt;       (or &lt;br /&gt; (and (&lt; dir 0) (= (line-beginning-position) (point-min)))&lt;br /&gt; (and (&gt; dir 0) (= (line-end-position) (- (point-max) 1)))))&lt;br /&gt;      (let&lt;br /&gt;   ((col (- (point) (line-beginning-position)))&lt;br /&gt;    (line (extract-a-line dir)))&lt;br /&gt; (if (&lt; dir 0)&lt;br /&gt;     (progn&lt;br /&gt;       (end-of-line)&lt;br /&gt;       (insert ?\n)&lt;br /&gt;       (insert line))&lt;br /&gt;   (progn &lt;br /&gt;     (beginning-of-line)&lt;br /&gt;     (insert line)&lt;br /&gt;     (insert ?\n)))&lt;br /&gt; (beginning-of-line (truncate (+ 0.5 (* 0.5 dir))))&lt;br /&gt; (forward-char col))))&lt;br /&gt;  &lt;br /&gt;(defun sh-line-down ()&lt;br /&gt;  (interactive)&lt;br /&gt;  (sh-move-line 1))&lt;br /&gt;&lt;br /&gt;(defun sh-line-up ()&lt;br /&gt;  (interactive)&lt;br /&gt;  (sh-move-line -1))&lt;br /&gt;&lt;br /&gt;(global-set-key [M-down] 'sh-line-down)&lt;br /&gt;(global-set-key [M-up] 'sh-line-up)&lt;br /&gt;&lt;br /&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-5785040520653231646?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/5785040520653231646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=5785040520653231646' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/5785040520653231646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/5785040520653231646'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/03/coping-emacs-1.html' title='coping emacs #1'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-9050042785986917745</id><published>2008-02-16T22:28:00.000+01:00</published><updated>2008-02-18T00:55:04.783+01:00</updated><title type='text'>Visualisation of DNA</title><content type='html'>After some attention has been caought by the wonderfull Rainbow DNA project, I have decided to join the club! Here is a very simplistic, far more useless way of visualising DNA: turtle graphics. &lt;br /&gt;I really cannot put up a website with comlete renderings of the DNA using turtle graphics, but I  uploaded two sample images to my flikr account. I wanted to find out if turtle graphics could reveal diffrent sets of patterns as those perceivable with a color plot of basepairs.&lt;br /&gt;&lt;br /&gt;Attached is source code so you can see what the program does. You can also reuse the part that proceses the contents of "gbk" files containing genome data.&lt;br /&gt;&lt;br /&gt;The code is just a hack done at night while I was waiting in a starbucks for a friend to pick me up, so if you think this code is a mess - you earned your degree, I was just curios after I found out about the rainbow dna project.&lt;br /&gt;&lt;br /&gt;Well the idea of the program is very simple:&lt;br /&gt;1. Initialise the turtle to be in center of the screen&lt;br /&gt;2. read the next basepair, for each base encountered look up the turtle rotation&lt;br /&gt;3. rotate the turtle&lt;br /&gt;4. draw 5 pixels&lt;br /&gt;5. goto step 2 until finished with a gene&lt;br /&gt;&lt;br /&gt;So here are the results, not surprisingly very unspectacular. If you want a good representation for the contents of the human genome, well ... look into a mirror. All other reps. just look ridiculous in comparison.&lt;br /&gt;&lt;br /&gt;I think it's funny, that one could argue that the dna seems to be like a multi-quine: not only that it conatins the code that creates organisms to reproduce itself through regular biological reproduction, it also encodes a brain with the ability to create turtle renderings of itself... &lt;br /&gt;&lt;br /&gt;In the following image rendering the following rules were applied. Whenever an "a" (as of a, c, t, g) is encountered turn the turle by -180 degree, on "c"  -60 degrees, "t" 60 deg and "g" 180 deg.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/23205009@N03/2272716536/" title="turtle dna rendering heyll-mode by sven.heyll, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2187/2272716536_2992343d1c_b.jpg" width="615" height="1024" alt="turtle dna rendering heyll-mode" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In the next rendering the following rules apply. Whenever an "a" turns the turle by 23 degree, on "c"  42 degrees, "t" 128 deg and "g" 15 deg.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/23205009@N03/2272716682/" title="turtle dna rendering boese-mode by sven.heyll, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2301/2272716682_1d135802c1_o.png" width="514" height="436" alt="turtle dna rendering boese-mode" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ok now here is the code.&lt;br /&gt;You might want to get the gbk files. Have a look at my &lt;a href="http://del.icio.us/sheyll"&gt;delicious account&lt;/a&gt;, I have stored a link to an ftp server where a gbk file for every chromosome of the human genome can be found.&lt;br /&gt;&lt;br /&gt;For my experiments I used parts of the X chromosome.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(require (lib "turtles.ss" "graphics"))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(load "boyer-moore.scm")&lt;br /&gt;(load "lazy-streams.scm")&lt;br /&gt;(load "list-utils.scm")&lt;br /&gt;&lt;br /&gt;;; read a line&lt;br /&gt;(define LS #\newline)&lt;br /&gt;                          &lt;br /&gt;(define (read-line port) &lt;br /&gt;  (let loop ((line '())&lt;br /&gt;             (c (read-char port)))&lt;br /&gt;    (if (eof-object? c)&lt;br /&gt;        (reverse (cons c line))&lt;br /&gt;        (if (eqv? c LS)&lt;br /&gt;            (reverse line)&lt;br /&gt;            (loop (cons c line) (read-char port)) ) )))&lt;br /&gt;&lt;br /&gt;(define (lazy-line-stream port)&lt;br /&gt;  (define current-line (read-line port))&lt;br /&gt;  (define result-stream &lt;br /&gt;    (cons-lazy-stream current-line (lazy-line-stream port)))&lt;br /&gt;  (if (eof-object? (car current-line))&lt;br /&gt;      the-empty-lazy-stream&lt;br /&gt;      result-stream))&lt;br /&gt;&lt;br /&gt;(define (filter-bases char-list)&lt;br /&gt;  (filter &lt;br /&gt;   (lambda (c) (or (eqv? c #\a) (eqv? c #\c) (eqv? c #\g) (eqv? c #\t))) &lt;br /&gt;   char-list))  &lt;br /&gt;&lt;br /&gt;(define (process-gbk port info-block-func base-pair-func post-draw)&lt;br /&gt;  (define (loop-base-pairs line-stream)&lt;br /&gt;    (if (empty-lazy-stream? line-stream) &lt;br /&gt;        (display "stream exhausted(while basepair parsing).")&lt;br /&gt;        (if (and (eqv? (car (lazy-head line-stream)) #\/) (eqv? (cadr (lazy-head line-stream)) #\/))&lt;br /&gt;            (begin&lt;br /&gt;              (post-draw)&lt;br /&gt;              (loop-header (lazy-tail line-stream) '())) &lt;br /&gt;            (begin          &lt;br /&gt;              (base-pair-func (filter-bases (lazy-head line-stream))) &lt;br /&gt;              (loop-base-pairs (lazy-tail line-stream))))))&lt;br /&gt;  (define (loop-header line-stream info-block-A)&lt;br /&gt;    (if (empty-lazy-stream? line-stream) &lt;br /&gt;        (begin (newline)&lt;br /&gt;               (display "stream exhausted(while parsing header).")&lt;br /&gt;               (newline))&lt;br /&gt;        ;; ok there's more stuff to read so. Find the ORIGIN string indicating the start of a DNA string &lt;br /&gt;        (if (equal? #f (&gt;&gt;boyer-moore (string-&gt;list "ORIGIN") (lazy-head line-stream)))&lt;br /&gt;            (begin&lt;br /&gt;              (loop-header (lazy-tail line-stream) `(,@info-block-A  ,(lazy-head line-stream))))&lt;br /&gt;            ;; ok found the ORIGIN string &lt;br /&gt;            (begin &lt;br /&gt;              (newline)&lt;br /&gt;              (display "found beginning of base pair sequence.")&lt;br /&gt;              (newline)&lt;br /&gt;              (info-block-func info-block-A)&lt;br /&gt;              (loop-base-pairs (lazy-tail line-stream))))))&lt;br /&gt;  ;; well the file is always assumed to start with a header&lt;br /&gt;  (loop-header (lazy-line-stream port) '()))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;;; simple function that just displays the base pairs&lt;br /&gt;(define (simple-base-pair-displayer L)&lt;br /&gt;  (display L)&lt;br /&gt;  (newline))&lt;br /&gt;&lt;br /&gt;;; now some turtle functions&lt;br /&gt;;; simple turtle moving and turning&lt;br /&gt;&lt;br /&gt;;&lt;br /&gt;;(define base-table ;; pun intended&lt;br /&gt;;  '((#\a 23)&lt;br /&gt;;    (#\c 42)&lt;br /&gt;;    (#\t 128)&lt;br /&gt;;    (#\g 15)))&lt;br /&gt;;(define angle-factor 1)&lt;br /&gt;;(define step-len 5)&lt;br /&gt;&lt;br /&gt;;(define base-table ;; pun intended&lt;br /&gt;;  '((#\a -3)&lt;br /&gt;;    (#\c -1)&lt;br /&gt;;    (#\t 1)&lt;br /&gt;;    (#\g 3)))&lt;br /&gt;;(define angle-factor 60)&lt;br /&gt;;(define step-len 5)&lt;br /&gt;&lt;br /&gt;(define base-table ;; pun intended&lt;br /&gt;  '((#\a -2)&lt;br /&gt;    (#\c -1)&lt;br /&gt;    (#\t 1)&lt;br /&gt;    (#\g 2)))&lt;br /&gt;(define angle-factor 60)&lt;br /&gt;(define step-len 4)&lt;br /&gt;&lt;br /&gt;;(define base-table ;; pun intended&lt;br /&gt;;  '((#\a 0)&lt;br /&gt;;    (#\c 1)&lt;br /&gt;;    (#\t 2)&lt;br /&gt;;    (#\g 3)))&lt;br /&gt;;(define angle-factor 90)&lt;br /&gt;;(define step-len 4)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(turtles #t)&lt;br /&gt;&lt;br /&gt;;;simple turtle func that will draw a line &lt;br /&gt;(define (basepair-drawer L)&lt;br /&gt;  (define (draw-loop L)&lt;br /&gt;    (if (not (equal? L '()))&lt;br /&gt;        (begin &lt;br /&gt;          (turn (* angle-factor (cadr (assoc (car L) base-table))))&lt;br /&gt;          (draw step-len))))&lt;br /&gt;  (draw-loop L))&lt;br /&gt;&lt;br /&gt;(define (info-block-func info-block)&lt;br /&gt;  (display "GOT AN INFO BLOCK, STARTING NEW RENDERING")&lt;br /&gt;  ;(display info-block)&lt;br /&gt;  (newline)&lt;br /&gt;  (clear))&lt;br /&gt;&lt;br /&gt;(define (post-draw)&lt;br /&gt;  (display "FINISHED DRAWING")&lt;br /&gt;  (newline)&lt;br /&gt;  (sleep 5))&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;;; main prog&lt;br /&gt;(define (start)&lt;br /&gt;  (call-with-input-file "ref_chrX.gbk" &lt;br /&gt;    (lambda (port)&lt;br /&gt;      (process-gbk port info-block-func basepair-drawer post-draw))))&lt;br /&gt;(start)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-9050042785986917745?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/9050042785986917745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=9050042785986917745' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/9050042785986917745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/9050042785986917745'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/02/visualisation-of-dna.html' title='Visualisation of DNA'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2187/2272716536_2992343d1c_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-2206952627600230268</id><published>2008-02-16T14:39:00.000+01:00</published><updated>2008-02-16T17:38:41.057+01:00</updated><title type='text'>Boyer Moore Search Algorithm</title><content type='html'>I needed to find a String in a text file, so I wrote(rather hacked) a scheme imlementation of the boyer moore string search algoritm.&lt;br /&gt;&lt;br /&gt;This is just a hack. But it is commented. What do you think?&lt;br /&gt;(I decided to use this blog also as my cut-paste-source from now on.)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;;; searches for string using boyer moore algorithm&lt;br /&gt;(define (&gt;&gt;boyer-moore needle haystack)&lt;br /&gt;  (define needle-len (string-length needle))&lt;br /&gt;  (define hs-len (string-length haystack))&lt;br /&gt;  (define r-needle-list (reverse (string-&gt;list needle)))&lt;br /&gt;  ;; two tables are build&lt;br /&gt;  ;; compute the bad character shift table&lt;br /&gt;  ;; it contains the number of chars to skip, if a character is encountered that is not the last of the search string.&lt;br /&gt;  ;; (this table is only used after the search cursor was replaced)&lt;br /&gt;  (define bad-char-shift-table &lt;br /&gt;    (let loop &lt;br /&gt;      ((shift 0)&lt;br /&gt;       (nlist r-needle-list)&lt;br /&gt;       (table '()))&lt;br /&gt;      (if (eq? nlist '())&lt;br /&gt;          table&lt;br /&gt;          (if (assv (car nlist) table)&lt;br /&gt;              (loop (+ 1 shift) (cdr nlist) table)&lt;br /&gt;              (loop (+ 1 shift) (cdr nlist) `((,(car nlist) ,shift) ,@table))))))&lt;br /&gt;  ;; the good char table contains the number of chars to skip forwar, if a substring starting from the &lt;br /&gt;  ;; end of a needle was matched befor a mismatch occurs&lt;br /&gt;  ;; it contains the next possible position from the current search position where a&lt;br /&gt;  ;; string match might end...&lt;br /&gt;  (define good-suffix-shift-table&lt;br /&gt;    ;; for every reverse substring define a shift value&lt;br /&gt;    (let char-pattern-loop &lt;br /&gt;       ((pattern '())&lt;br /&gt;        (pattern-len 0)&lt;br /&gt;        (nlist r-needle-list)&lt;br /&gt;        (table '()))&lt;br /&gt;      (if (eq? nlist '())&lt;br /&gt;          table&lt;br /&gt;          (char-pattern-loop&lt;br /&gt;           `( ,@pattern ,(car nlist))&lt;br /&gt;           (+ 1 pattern-len)&lt;br /&gt;           (cdr nlist)&lt;br /&gt;           `(,@table &lt;br /&gt;               (,pattern ,(let loop &lt;br /&gt;                            ((shift 0)&lt;br /&gt;                             (unmatched (car nlist)))&lt;br /&gt;                            (if (equal? (ncar pattern-len (ncdr shift r-needle-list)) (ncar (- needle-len shift) pattern))&lt;br /&gt;                                (if (eqv? shift needle-len)&lt;br /&gt;                                    shift&lt;br /&gt;                                    (if (&gt;= (+ shift pattern-len) needle-len)&lt;br /&gt;                                        shift&lt;br /&gt;                                        (if (eqv? (car (ncdr shift nlist)) unmatched)&lt;br /&gt;                                            ;; ok nicht gefunden weiter schieben/suchen&lt;br /&gt;                                            (loop (+ 1 shift) unmatched)&lt;br /&gt;                                            shift)))&lt;br /&gt;                                (loop (+ 1 shift) unmatched)))))))))&lt;br /&gt;  ;; searching at a position&lt;br /&gt;  (define  (search-needle-at index)&lt;br /&gt;    (letrec ((sub-hs (reverse (string-&gt;list (substring haystack index (+ needle-len index))))) ;; den kaefer erstma aufn ruecken drehen...&lt;br /&gt;             (first-char (car sub-hs)))&lt;br /&gt;      (if (eqv? first-char (car r-needle-list)) ;; first time is special&lt;br /&gt;          ;; if the fist char matches, proceed with subpattern search&lt;br /&gt;          (let ((common (common-sublist sub-hs r-needle-list)))&lt;br /&gt;            (if (= (car common) needle-len)&lt;br /&gt;                0 ;; found&lt;br /&gt;                (cadr (assoc (cdr common) good-suffix-shift-table))))  &lt;br /&gt;          ;;if the first char did not match, look up shift in bad-char-shift table&lt;br /&gt;          (let ((shift (assv first-char bad-char-shift-table)))&lt;br /&gt;            (if (eq? shift #f)&lt;br /&gt;                needle-len ;; return the needle length if nothing better could be found in the bad-char jump table&lt;br /&gt;                (cadr shift)))))) ;; ...otherwise return the value obtained from the table&lt;br /&gt;                &lt;br /&gt;  ;; search mainloop&lt;br /&gt;  (let main-loop ((current-index 0))&lt;br /&gt;    (if (&gt; (+ needle-len current-index) hs-len)&lt;br /&gt;        #f&lt;br /&gt;        (let ((minimum-chars-to-skip (search-needle-at current-index)))&lt;br /&gt;          (if (= 0 minimum-chars-to-skip)&lt;br /&gt;              current-index ;; juhu found string!&lt;br /&gt;              (main-loop (+ current-index minimum-chars-to-skip)))))))&lt;br /&gt;    &lt;br /&gt;       &lt;br /&gt;(&gt;&gt;boyer-moore "ANPANMAN" "NNNNNAXPANPANMANANMAN")       &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Some utility definitions are missing from the above code, these are:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;;; returns the rest of the list after removing n elements&lt;br /&gt;(define (ncdr n list)&lt;br /&gt;  (if (eqv? n 0)&lt;br /&gt;      list&lt;br /&gt;      (if (eq? list '())&lt;br /&gt;          list&lt;br /&gt;          (ncdr (- n 1) (cdr list)))))&lt;br /&gt;&lt;br /&gt;;; returns the fist n items of the list&lt;br /&gt;(define (ncar n list)&lt;br /&gt;  (let loop ((result '())&lt;br /&gt;             (rest list)&lt;br /&gt;             (c n))&lt;br /&gt;  (if (eqv? c 0)&lt;br /&gt;      result&lt;br /&gt;      (if (eq? rest '())&lt;br /&gt;          result&lt;br /&gt;          (loop `(,(car rest) ,@result) (cdr rest) (- c 1) )))))&lt;br /&gt;&lt;br /&gt;;; return the common begining sublist of two lists&lt;br /&gt;(define (common-sublist listA listB)&lt;br /&gt;  (let loop&lt;br /&gt;    ((listC '())&lt;br /&gt;     (restA listA)&lt;br /&gt;     (restB listB)&lt;br /&gt;     (count 0))&lt;br /&gt;    (if (or (eq? restA '()) (eq? restB '()))&lt;br /&gt;        (cons count listC)&lt;br /&gt;        (if (eqv? (car restA) (car restB))&lt;br /&gt;            (loop `(,@listC ,(car restA)) (cdr restA) (cdr restB) (+ 1 count))&lt;br /&gt;            (cons count listC)))))&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The above code might be complete bullsh*t, I dont know I just hacked it down while reading the wikipedia article of the algorithm. I didn't bother to lookup a reference implementation...&lt;br /&gt;Also it was like 4:00 am when I hacked it...(apologies accepted?)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-2206952627600230268?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/2206952627600230268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=2206952627600230268' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/2206952627600230268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/2206952627600230268'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2008/02/boyer-moore-search-algorithm.html' title='Boyer Moore Search Algorithm'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-7324856388090293739</id><published>2007-11-03T17:43:00.000+01:00</published><updated>2007-11-03T17:48:42.308+01:00</updated><title type='text'>An Alle die dies tatsaechlich lesen...</title><content type='html'>... macht euch bitte lustig. Ich selbst nehme mich schliesslich auch nicht so ernst, ausserdem bin ich (und werde es immer bleiben) ein Anfaenger.&lt;br /&gt;&lt;br /&gt;This is my zen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-7324856388090293739?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/7324856388090293739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=7324856388090293739' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7324856388090293739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7324856388090293739'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2007/11/alle-die-dies-tatsaechlich-lesen.html' title='An Alle die dies tatsaechlich lesen...'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-7286886082526894374</id><published>2007-09-14T00:25:00.000+02:00</published><updated>2007-09-14T00:55:02.629+02:00</updated><title type='text'>on the path to enlightenment...</title><content type='html'>My (and others who I infected) reaction to playing around with erlang, scheme and common lisp, was frustration. Not because these languages are bad, but because they are so nice and fun to programm with! One could even argue, that this alone results in reduced development time and better programms, but while this is definitely true, it hides the fact, that the afore mentioned languages increase efficiency of sw development also by technical means. To provide evidence for this hypothesis is out of the scope of this document, please look for yourself, there's plenty of  good material about common lisp, scheme and erlang on the web, there are even life lisp coding videos on google video!&lt;br /&gt;&lt;br /&gt;I recently bought the new erlang book. It is great and I would recommend it without hesitation. &lt;br /&gt;There are also great books online that I started reading: htdp and sicp.&lt;br /&gt;Oh and not to forget to mention "little schemers" of wich the chapter about the Y-combinator is online ...(yeahh nice!)&lt;br /&gt;&lt;br /&gt;Now, all I need to do is convince my boss to start using erlang or common lisp.&lt;br /&gt;&lt;br /&gt;There is just no point in wasting my time with java (except for j2me!).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-7286886082526894374?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/7286886082526894374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=7286886082526894374' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7286886082526894374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7286886082526894374'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2007/09/on-path-to-enlightenment.html' title='on the path to enlightenment...'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-8386791189385875276</id><published>2007-07-25T00:32:00.000+02:00</published><updated>2007-07-25T00:33:06.240+02:00</updated><title type='text'>Blub Paradox</title><content type='html'>Ich habe da einen interessanten Artikel ueber das Blub Paradoxon gefunden.&lt;br /&gt;Jenes besagt, das fast alle Programmierer der These zustimmen,&lt;br /&gt;dass Programmiersprachen sich in ihrer "Macht" und Generalitaet unterscheiden, aber trotzdem&lt;br /&gt;nicht bereit sind einzusehen, das andere Programmierespachen besser sind als die, die sie&lt;br /&gt;habituell verwenden.&lt;br /&gt;Verdeutlicht wird das am Beispieln eines eingefleischten "Blub" Programmierers.&lt;br /&gt;"Blub" ist eine P.Sprache die im mittleren Bereich des Generalitaetskontinuums&lt;br /&gt;liegt, das sich zwischen Maschinencode an einem Ende - und Lisp am anderen Ende&lt;br /&gt;erstreckt.&lt;br /&gt;Der Blub Programmierer kennt alle Sprachen, die schwaecher als Blub sind, und fragt sich,&lt;br /&gt;wie man bloss ohne eine Feature "x" vernuenftig programmieren kann(- natuerlich verfuegt Blub ueber x).&lt;br /&gt;Ausserdem findet er, dass Blub alle Features hat die er braucht, und ihm erscheinen features in&lt;br /&gt;"hoeheren" Sprachen als verwirrend und unnoetig. Er denkt in Blub, und Blub ist sein Horizont -&lt;br /&gt;und alle Probleme die er fuer loesungswuerdig befindet, sind in Blub loesbar!&lt;br /&gt;&lt;br /&gt;http://www.paulgraham.com/avg.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-8386791189385875276?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/8386791189385875276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=8386791189385875276' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/8386791189385875276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/8386791189385875276'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2007/07/blub-paradox.html' title='Blub Paradox'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-6150766460744115341</id><published>2007-07-15T21:05:00.002+02:00</published><updated>2007-07-15T21:49:35.373+02:00</updated><title type='text'>functional vs oo</title><content type='html'>well it's been a while and I have come to trivial but usefull conclusions lately.&lt;br /&gt;Once I thought functional programming was fundamentaly diffrent then &lt;br /&gt;oo style programming, but I actually realized how well many aspects&lt;br /&gt;of fp match to elements of oop;&lt;br /&gt;&lt;br /&gt;Functions are simply Objects,&lt;br /&gt;Closures are anonymous class,&lt;br /&gt;certain design patterns ressemble &lt;br /&gt;monads(decorator, chain of reponsibility,...)&lt;br /&gt;&lt;br /&gt;oo style programming can be seen as a restricted variation of functional programming.&lt;br /&gt;&lt;br /&gt;That matters because the key aspects of oop is encapsulation and&lt;br /&gt;information hiding. This can easyly be achieved in fp through the&lt;br /&gt;use of closures and the fact that functions can be treated like &lt;br /&gt;any other data.&lt;br /&gt;&lt;br /&gt;In oop very explicit notations usually exists, wich couple&lt;br /&gt;certain functions to certain data through the notion of objects. Both, to increase readability of complex programms, and to lighten the restrictions that come with encapsulation, an explicit notion of inheritance is used.&lt;br /&gt;&lt;br /&gt;While all this seems pretty obvious to most, frankly, I did not&lt;br /&gt;appreciate oop after doing a a bit of fp, until I found myself reading through some javascript code that I wanted to optimize.&lt;br /&gt;The code was using a many closures like this, which I removed&lt;br /&gt;by placing the variables that the closures contained in &lt;br /&gt;properties of objects, that also contained the functions &lt;br /&gt;corresponding to the closures' code.&lt;br /&gt;&lt;br /&gt;When I was finished I had not only increased speed by 40-60%&lt;br /&gt;but was also surprised by the fact that my code looked a lot&lt;br /&gt;like good oo-style code.&lt;br /&gt;&lt;br /&gt;So in my opinion every programmer should learn to think functional&lt;br /&gt;in order to get a hold of what the importance of encapsulation and code reuse.&lt;br /&gt;&lt;br /&gt;That said, most javascript interpreters(javascript by itself not a purely functional language like haskell anyway) could do this manual optimization of closures automatically.&lt;br /&gt;&lt;br /&gt;It is rumored that modern lisp systems and erlang(using HiPE) interpreters/compilers are very close to compiled "C" code performance:&lt;br /&gt;See i.e. http://www.sics.se/~joe/apachevsyaws.html&lt;br /&gt;or http://bob.pythonmac.org/archives/2006/09/21/erlang-binary-performance/&lt;br /&gt;&lt;br /&gt;But to emphasis my point of oop vs fp regard this page:&lt;br /&gt;http://openmap.bbn.com/~kanderso/performance/java/index.html&lt;br /&gt;&lt;br /&gt;That's it for today.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-6150766460744115341?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/6150766460744115341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=6150766460744115341' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/6150766460744115341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/6150766460744115341'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2007/07/functional-vs-oo.html' title='functional vs oo'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-5027298780632286865</id><published>2007-03-24T19:55:00.000+01:00</published><updated>2007-03-25T16:20:40.002+02:00</updated><title type='text'>Recent Comparison of jMock 1.1 and EasyMock 2.2</title><content type='html'>My Colleges and me are in the process of figureing out wich mock frameworks to use. One of my colleges has experiences with jMock and I have used diffrent versions of easymock. We wanted a detailed comparison to help us decide what the strengths and weaknesses are of the diffrent Mockframeworks. During a web search we discovered &lt;a href="http://www.jmock.org/easymock-comparison.html"&gt;this&lt;/a&gt; comparison between jMock and Easymock. Although, regarding the authors background not necessarily, but to me most likely, this comparison of Jmock to an unspecified version of Easymock is biased towards jMock.&lt;br /&gt;Many diffrences/disadvantages in this comparison are obsoleted by more recent versions of Easymock, and speculating on the version used in favour of the author would imho result in 1.3 wich dates way back to 2005.&lt;br /&gt;&lt;br /&gt;The desription of the link to the jMock project on the easymock project page, states that jMock opposed to easymock uses&lt;br /&gt;&lt;blockquote&gt;another approach to define expectations that results in more flexibility to set expectations (you may specify almost everything imaginable) at the cost of less flexibility when refactoring (refactorings like method renaming and parameter reordering will break the tests) and loss of code completion when defining expectations or test-driving code.&lt;/blockquote&gt;Well this note is definitely true for older version of easymock, and probably stems from the same era as the comparision hosted on the  jMock page. Since version 2.0 easymock started to look a lot more like jMock in terms of behaviuor specification. I found that the easymock approach helped me doing test first programming, in cases where I was not only specifying the class under test but also the mocked interfaces, because modern IDEs like eclipse 3.1 and higher may come up with some fancy hinting/auto fixing feature, that will create non existing methods and classes.&lt;br /&gt;&lt;br /&gt;Back to the jMock hosted comparison of easymock vs jMock, one drawback the authour of the comparison states is:&lt;br /&gt;&lt;blockquote&gt;EasyMock lets you change the way that arguments are matched on a call-by-call basis, but the syntax is awkward and same matcher applies to &lt;em&gt;all&lt;/em&gt; arguments.&lt;br /&gt;&lt;/blockquote&gt;Luckily this is not true for Easymock versions higher than 1.3, but let's take closer look anyway.&lt;br /&gt;As example of how (not awkward and brittle) one specifies the beahaviuor in jmock this code fragment send on its mission to insult its readers intelligence:&lt;br /&gt;&lt;pre&gt;mock.expects(once()).method("method1").with( eq(a) );&lt;br /&gt;mock.expects(once()).method("method2").with( same(b1), ANYTHING )&lt;br /&gt;.will(returnValue(method2Result));&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Did I just read that a mock object(wich really is NOT the mock object) expects an invocation of a local method called once()(wich it does not), and that the result of the expecation is some object that returns probably a method (wich it also doesnt) with something equal to "a"?&lt;br /&gt;Of course I do understand what this behaviour specification is all about, but to be able to write such a specification, one has to learn a syntax/api not as Java-ish as EasyMock, where the only necessary quirk is the distinction between behaviour recording and verification(wich was clear to me at once when I first saw it).&lt;br /&gt;&lt;br /&gt;The author continues to state that:&lt;br /&gt;&lt;blockquote&gt; This means that expectations are more verbose but precisely and clearly specify the expected behaviour of the object.By precisely specifying expected behaviour you get &lt;a href="http://www.jmock.org/yoga.html"&gt;flexible tests&lt;/a&gt;&lt;span class="LinkFootnoteRef"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/span&gt; that break only when the actual behaviour is different from expected behaviour, and do not break when you make unrelated changes to application code.  &lt;/blockquote&gt;To my knowledge it possible  - without extensive API knowledge or awkward syntax - to specify any behaviour with abitrarily varied levels of precision with easymock. In jMock you were spoiled with this kind of flexibility right from the beginning, but this flexibilty is achieved only by introducing some drawbacks i.e.:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;test development/refactoring is harder because mock-method  invocation errors will only show up during runtime&lt;/li&gt;&lt;li&gt;after i.e. adding a parameter to method1 one has even more problems fixing this than merely changing the name of method1&lt;/li&gt;&lt;/ul&gt;The last point is especially dangerous in a multi developer team. The brittleness of the test cases is exactly what I want. There is added value in compile time checks.&lt;br /&gt;&lt;br /&gt;Now let's have a look at the Easymock (2.0 and higher) version of the code snippet:&lt;br /&gt;&lt;pre&gt;mock.method1(eq(a));&lt;br /&gt;expect(mock.method2(same(b), anyInt())).andReturn(method2result);&lt;br /&gt;&lt;/pre&gt;Notice the subtile diffrences, in jMock one provides the method parameters in a non typesafe way through the "with" method, while in easymock one provides the arguments matchers where the actual parameters would be written. Also through the use of Java 5 generics in easymock  the behaviuor definitions can be checked at compile time for type related mistakes.&lt;br /&gt;&lt;br /&gt;Another great diffrence between the two examples are that in the jmock example "mock" is a control object and in the easymock example, "mock" is the mock object, that implements the interface we wich to "mock".&lt;br /&gt;&lt;br /&gt;One drawback of easymock is that because method1 returns void we have to call "expectLastCall()" to get an object that allows us to specify some more expectation&lt;br /&gt;like the number of invocations of the last method:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mock.method1(eq(a));&lt;br /&gt;expectLastCall().anyTimes();&lt;br /&gt;&lt;br /&gt;expect(mock.method2(same(b), anyInt())).once().andReturn(method2result);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://tcay.com/dev/JMockVsEasyMock.htm"&gt;Another&lt;/a&gt; more recent comparison dated around march 2006, seems to be done with a newer version of easymock, but it seems that also the author did not (yet) regard/compare more than the absolute minimum mock framework features one might want to use. The key point in favour of easymock were&lt;br /&gt;&lt;ul&gt;&lt;li&gt;method identification through actual method of the proxy&lt;/li&gt;&lt;li&gt;no extension of testcase base class&lt;/li&gt;&lt;li&gt;mixing of class mocking and interface mocking is very easy (you just use another implementation of MockControl)&lt;/li&gt;&lt;li&gt;very low API complexity&lt;/li&gt;&lt;/ul&gt;The points in favour of jMock were:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No control object is required&lt;/li&gt;&lt;li&gt;no replay/verify steps are necessary&lt;/li&gt;&lt;/ul&gt;Lets shed some more light upon this comparison:&lt;br /&gt;The main point, that no control object is required in jMock is imho false. One exclusively operates on the control object and invokes a getter for the proxy. That is the reason just why&lt;br /&gt;one cannot use the actual methods to specify behaviour. Easymock achieves refactoring safe actual method specification by introducton of its replay/verify concept. Furthermore, by exploiting new Java 1.5 features(static imports, generics, varargs) easymock almost completely frees the user from the burdern of being aware of this dichotomy in his daily work, and it even frees the user from the burden of subclassing some special test case base class as in jMock.&lt;br /&gt;&lt;br /&gt;JMock on the other hand allows the user to specify behaviuor without having the recording/playback states, and mock behaviuor is automgically verified by base class methods after the method finishes. Also mock control object can be instantiated by a base class member method.&lt;br /&gt;While this is for sure some helpful syntactic sugar, it is not so hard to do any of this with easymock because of the clever design of the easymock MockControl class and the usage of static imports.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Also the possibility to specify argument matchers was judged as "difficult" in easymock and easy in jMock.&lt;br /&gt;&lt;br /&gt;Finally, I would like to point to an interesting article done by Martin Fowler, who explains some interesting aspects of overall applicability of Mock/Stubs/Dummies and Fakes, and tries to open a more general perspective on test doubles of all kinds. He also includes a small comparison of jMock and EasyMock. He also compares jMock to a &lt;span style="font-style: italic;"&gt;very &lt;/span&gt;outdated version of Easymock it seems, as the code he provides as example, does not make use of the "import static" feature of Java 1.5, as well as some other features that could have been used to make the code alot more like typical jMock code. The article can be found &lt;a href="http://www.martinfowler.com/articles/mocksArentStubs.html"&gt;here&lt;/a&gt;.&lt;br /&gt;Although this article was updated &lt;a href="http://www.martinfowler.com/articles/mocksArentStubs.html#SignificantRevisions"&gt;02 Jan 07&lt;br /&gt;&lt;/a&gt; the easymock example he provides is also based on an obsolete version of easymock. Exactly why the author values mentioning some diffrences between jMOck and easymock is not clear to me. The article focuses on explaining the distinction between stubs and mock, not on comparing mock frameworks.&lt;br /&gt;I will use this opportunity to rewrite this example of easymock:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class OrderEasyTester extends TestCase {&lt;br /&gt;private static String TALISKER = "Talisker";&lt;br /&gt;&lt;br /&gt;private MockControl warehouseControl;&lt;br /&gt;private Warehouse warehouseMock;&lt;br /&gt;&lt;br /&gt;public void setUp() {&lt;br /&gt;warehouseControl = MockControl.createControl(Warehouse.class);&lt;br /&gt;warehouseMock = (Warehouse) warehouseControl.getMock();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void testFillingRemovesInventoryIfInStock() {&lt;br /&gt;//setup - data&lt;br /&gt;Order order = new Order(TALISKER, 50);&lt;br /&gt;&lt;br /&gt;//setup - expectations&lt;br /&gt;warehouseMock.hasInventory(TALISKER, 50);&lt;br /&gt;warehouseControl.setReturnValue(true);&lt;br /&gt;warehouseMock.remove(TALISKER, 50);&lt;br /&gt;warehouseControl.replay();&lt;br /&gt;&lt;br /&gt;//exercise&lt;br /&gt;order.fill(warehouseMock);&lt;br /&gt;&lt;br /&gt;//verify&lt;br /&gt;warehouseControl.verify();&lt;br /&gt;assertTrue(order.isFilled());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void testFillingDoesNotRemoveIfNotEnoughInStock() {&lt;br /&gt;Order order = new Order(TALISKER, 51);&lt;br /&gt;&lt;br /&gt;warehouseMock.hasInventory(TALISKER, 51);&lt;br /&gt;warehouseControl.setReturnValue(false);&lt;br /&gt;warehouseControl.replay();&lt;br /&gt;&lt;br /&gt;order.fill((Warehouse) warehouseMock);&lt;br /&gt;&lt;br /&gt;assertFalse(order.isFilled());&lt;br /&gt;warehouseControl.verify();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here  is the rewrite:&lt;br /&gt;&lt;pre&gt;import static org.easymock.EasyMock.*;&lt;br /&gt;&lt;br /&gt;public class OrderEasyTester extends TestCase {&lt;br /&gt;private static String TALISKER = "Talisker";&lt;br /&gt;&lt;br /&gt;private Warehouse warehouseMock;&lt;br /&gt;&lt;br /&gt;public void setUp() {&lt;br /&gt;warehouseMock = createMock(Warehous.class);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void testFillingRemovesInventoryIfInStock() {&lt;br /&gt;//setup - data&lt;br /&gt;Order order = new Order(TALISKER, 50);&lt;br /&gt;&lt;br /&gt;//setup - expectations&lt;br /&gt;expect(warehouseMock.hasInventory(TALISKER, 50).andReturn(true);&lt;br /&gt;warehouseMock.remove(TALISKER, 50);&lt;br /&gt;replay(warehouseMock);&lt;br /&gt;&lt;br /&gt;//exercise&lt;br /&gt;order.fill(warehouseMock);&lt;br /&gt;&lt;br /&gt;//verify&lt;br /&gt;verify(warehouseMock);&lt;br /&gt;assertTrue(order.isFilled());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void testFillingDoesNotRemoveIfNotEnoughInStock() {&lt;br /&gt;Order order = new Order(TALISKER, 51);&lt;br /&gt;&lt;br /&gt;warehouseMock.hasInventory(TALISKER, 51).andReturn(false);&lt;br /&gt;replay(warehouseMock);&lt;br /&gt;&lt;br /&gt;order.fill((Warehouse) warehouseMock);&lt;br /&gt;&lt;br /&gt;assertFalse(order.isFilled());&lt;br /&gt;verify(warehouseMock);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;to be continued...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-5027298780632286865?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/5027298780632286865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=5027298780632286865' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/5027298780632286865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/5027298780632286865'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2007/03/recent-comparison-of-jmock-11-and.html' title='Recent Comparison of jMock 1.1 and EasyMock 2.2'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-8506911872199016389</id><published>2007-03-16T23:27:00.000+01:00</published><updated>2008-02-16T17:35:18.872+01:00</updated><title type='text'>Future of Webdevelopment</title><content type='html'>The longterm future in Webdevelopment is for sure associated with fading boundaries between systems that provide a service wich incorporates distributed knowledge to form new knowledge, wich it distributes, probably only to one client in a secure fashion.&lt;br /&gt;&lt;br /&gt;These boundaries are hard boundaries in terms of possible incompatibilities between interacting systems in heterogenous environment. We are confronted with securtiy issues, incompatibilies in protocol interpretations and service metadata propagation for automatic wiring of resources as opposed to hand crafted wiring as i.e. done with hyperlinks between dynamic system with a proprietary but similar structure, we are confronted wich diffrences on many layers of abstraction and orthogonal technical aspects like the necessesity to transform data not only to diffrent semiotic representationens but also to devices with diffrent availibility and diffrent means of human interaction.&lt;br /&gt;&lt;br /&gt;As diversity greatly increases, the call for unification and simplification, that emerged from the complexity, gets louder and louder - and is eventually the root for the development of simple webframeworks of wich there are many(i.e. ruby on rails and groovy).&lt;br /&gt;I think that while it is not the true path to oversimplifiy things, it is at the same time not much better to overcomplicate a specific system, that is the result of what can be refered to as &lt;span style="font-style: italic;"&gt;webdevelopment activity&lt;/span&gt; to a state, where user recognized functionality of such a system is superseded by a system done by less less developers in less time.&lt;br /&gt;&lt;br /&gt;It is also most often perceived, that many legacy systems exist, wich have grown old and big over many years, and wich are hard to extend or modify, but due to their long term presense have somehow proven to work and also have delivered ROI. They also mirror long time adaption to many improvements and changes that were realized required as the system faced reality year after year; &lt;br /&gt;such a code contains real world experiences, that might be worth keeping. These nuggest often have the downside of not being documented properly, so that are hard to extract and a rewrite that preserves the current state of the system get expensive.&lt;br /&gt;&lt;br /&gt;I see a need for some kind of methodology that allows to ¨pimp¨ existing legacy applications so that they are interoperable with modern web technologies.&lt;br /&gt;I will have  deeper look at REST based webservices, and means of simple object serialisation.&lt;br /&gt;I am eager to create some utility that will adapt existing and new Java applications to web basesd interaction partners, be it a webbrowser rendering an Ajax based user experience or a &lt;span style="font-style: italic;"&gt;machine &lt;/span&gt;utilizing a service offered by the Java application.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-8506911872199016389?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/8506911872199016389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=8506911872199016389' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/8506911872199016389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/8506911872199016389'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2007/03/future-of-webdevelopment.html' title='Future of Webdevelopment'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-9151314060207441307</id><published>2007-01-16T21:35:00.000+01:00</published><updated>2007-03-27T20:51:48.513+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jira'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='XP'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Back again</title><content type='html'>After a lot of meditation over efficient programming styles, some new ideas finally condensed in my defected mind:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;always underestimated is the emotional aspect of coding, in a team environment one must be able to critisize and be critizised; also bad code pisses me of so much, that it pulls down my overall productivity&lt;br /&gt;&lt;/li&gt;&lt;li&gt;test driven development saves time, most of the time&lt;/li&gt;&lt;li&gt;clear structure and good documentation helps, because maintainance will be &lt;span style="font-style: italic;"&gt;nicer (see 1.)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;usefull integration testing is a far away dream, never to be reached in a pure XP manner including acceptance tests.&lt;/li&gt;&lt;li&gt;jira is cool - combined with good ole paper on the wall does best. customer requests - the customer(or any other person not a freak) will not put sufficient details for a bug or a feature request into the bugtracker or be helplessly faced with a complex and flexible task of specifeing an issue, here improvements to the GUI to reduce complexity by providing more project specific defaults would be nice)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;wikis are usefull, although sometimes they suck!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;eclipse on badly configured linux workstations sucks, too..&lt;/li&gt;&lt;li&gt;everything in the world &lt;span style="font-weight: bold;"&gt;could&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;be&lt;/span&gt; modelled by interfaces ... but doesnt have to be....&lt;br /&gt;&lt;/li&gt;&lt;li&gt;doing today what you think, you might need next year, and hence imposing privations upon oneselves until next year, just to realise then, that you have to do it a diffrent way due to some fucked up details, well ... this actually does suck, also very badly&lt;/li&gt;&lt;li&gt;well, ... and last but not least... using Java for web applications sometimes sucks too: no higher order functions, no continuations, no cool typesystem, apart from some bright highlights: laborious and longnamed language syntax&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-9151314060207441307?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/9151314060207441307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=9151314060207441307' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/9151314060207441307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/9151314060207441307'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2007/01/back-again.html' title='Back again'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-4102481683252655305</id><published>2006-10-09T13:31:00.000+02:00</published><updated>2006-10-09T14:05:57.217+02:00</updated><title type='text'>Open and closed Source voting</title><content type='html'>In several countries voices are raised against the use of voting computers. The latest objection was raised by the CCC in germany. According to security analysis, voting machines are insecure, and allow for untracable manipulation of voting results and voter privacy. The software can be exchanged and votes could be manipulated without any traces. The systems used for voting in Germany are very similar to those in the Nederlands. Similar objects were raised before in this country. Andy Müller Maguhn wrote:&lt;br /&gt;&lt;blockquote&gt;Die Bauartzulassung der Nedap-Wahlcomputer ist nach den nunmehr vorliegenden Forschungsresultaten hinfällig. Das Bundesinnenministerium muss daher die Zulassung entsprechend § 3 Absatz 3 der Bundeswahlgeräteverordnung widerrufen&lt;/blockquote&gt;&lt;a href="http://www.ccc.de/updates/2006/wahlcomputer"&gt;&lt;/a&gt;It does not surprise that similar story are percepted in the USA, where some rumour around the company "Diebold Election Systems" raised, after a group of college students found some memos about the poor security of the system from developers of this company, which somehow sliped onto a public area of the companies website.&lt;br /&gt;&lt;br /&gt;After the companies lawyers tried with the help of the "Digital Millennium Copyright Act" to force the university to remove these memos from the servers(yes they are copyrighted material...) the sutdents had to use peer to peer file shareing software to keep the memos online.&lt;br /&gt;The NY Times wrote in an article:&lt;br /&gt;&lt;blockquote&gt;The files circulating online include thousands of e-mail messages and memorandums dating to March 2003 from January 1999 that include discussions of bugs in Diebold‚s software and warnings that its computer network are poorly protected against hackers. Diebold has sold more than 33,000 machines, many of which have been used in elections.&lt;/blockquote&gt;&lt;br /&gt;Now a debate araised around the question wheter voting software should be open source or closed source, to assure maximum demoncracy. While I think that one should also keep in mind that the main problem of  demoncracy is missing participation, I am convinced that an open source solution is the only appropriate way to ensure a secure voting process.&lt;br /&gt;Clive Thompson wrote:&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;So now you're caught up. The reason I give this bloated preamble is to point to the real solution: Open-source software. &lt;/p&gt;  &lt;p&gt;As the Diebold scandal illustrates, it's incredibly dangerous to let a private company develop proprietary voting software. If they "own" the code, they'll keep it a secret. That means we'll have to trust them that the software is secure. If they're lying to us -- or, more likely, if they're well-intentioned but just unable to realize how buggy their code is -- democracy is screwed.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;Open source software could be manipulated by enemies of demoncracy, but that, at least would show up  immediately, and it is an advantage of open source software, that the participants are not bound by any contracts or employers, and may talk freely about the problems of the software without the vendors commercially motived blur.&lt;br /&gt;&lt;br /&gt;I therefore disagree with Barry Briggs, who answers to Clive Thompson:&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt; I don't think it's perfect at all. Open-source rests on several cornerstones including programmer anonymity and zero accountability. What if we were to find out that a key contributor to our voting machine software was a member of Al-Qaeda? &lt;/p&gt;&lt;p&gt; In fact, the last people I'd trust to verify the correctness and trustworthiness of something as critical as voting machine software would be a loose group of international programmers who could care less about the integrity of our republic.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;And who will be eager to write such software? Of course not the enemies of demoncracy, but those who realize the very value and importance of free elections. And it is really motivating to be part of the team that wrote the software, that drives a vital part of the election process.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Links:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ccc.de/updates/2006/wahlcomputer"&gt;http://www.ccc.de/updates/2006/wahlcomputer&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.collisiondetection.net/mt/archives/000568.html"&gt;Clive Thomspons Blog&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://select.nytimes.com/gst/abstract.html?res=F10D15F93A540C708CDDA80994DB404482"&gt;NY Times Article&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.edithere.com/barry/2003/11/04#a654"&gt;Barry Briggs Blog&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-4102481683252655305?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/4102481683252655305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=4102481683252655305' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/4102481683252655305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/4102481683252655305'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/10/open-and-closed-source-voting.html' title='Open and closed Source voting'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-8544481757955800863</id><published>2006-10-06T15:16:00.001+02:00</published><updated>2006-10-06T15:16:27.455+02:00</updated><title type='text'>Real Programmers :-)</title><content type='html'>&lt;h1&gt;Real Programmers Don't Use Pascal!&lt;/h1&gt;&lt;br /&gt;&lt;a href="http://www.pbm.com/%7Elindahl/real.programmers.html"&gt;Read more...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-8544481757955800863?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/8544481757955800863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=8544481757955800863' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/8544481757955800863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/8544481757955800863'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/10/real-programmers.html' title='Real Programmers :-)'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-1322888621672653973</id><published>2006-10-06T14:49:00.000+02:00</published><updated>2006-10-06T15:15:58.134+02:00</updated><title type='text'>Java Locking</title><content type='html'>Here are some nice Articles about Double checked locking, the singleton pattern&lt;br /&gt;and the friendly comepetition between people doing VM level locking (aka Synchronized) and Java locking (1.5 Reentrant locks)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://weblogs.java.net/blog/mason/archive/2006/09/rechecking_doub_1.html"&gt;Double Checked Locking 1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www-128.ibm.com/developerworks/java/library/j-dcl.html"&gt;Double Checked Locking 2&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://altair.cs.oswego.edu/pipermail/concurrency-interest/2005-February/001368.html"&gt;Why is ReentrantLock faster than synchronized ?&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-1322888621672653973?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/1322888621672653973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=1322888621672653973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/1322888621672653973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/1322888621672653973'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/10/java-locking.html' title='Java Locking'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-190625312705714959</id><published>2006-10-05T12:23:00.001+02:00</published><updated>2006-10-05T12:23:51.361+02:00</updated><title type='text'>AMDD</title><content type='html'>I like MDD, SCRUM and extreme Programming, so &lt;a href="http://www.agilemodeling.com/essays/amdd.htm"&gt;AMDD&lt;/a&gt; just seems so &lt;span style="font-style: italic;"&gt;natural&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-190625312705714959?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/190625312705714959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=190625312705714959' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/190625312705714959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/190625312705714959'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/10/amdd.html' title='AMDD'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-7435739838719556790</id><published>2006-10-02T15:58:00.000+02:00</published><updated>2006-10-02T16:14:02.253+02:00</updated><title type='text'>AntiPattern: AbstractionInversion</title><content type='html'>After trying to understand the &lt;a href="http://c2.com/cgi/wiki?AbstractionInversion"&gt;AbstractionInversion&lt;/a&gt; antipattern,  I wonder if this pattern is really a unique pattern and not actually more like a &lt;span&gt;combination of other, more abstract AntiPatterns. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Is AbstractionInversion a special case of code duplication, where a dependend class not only duplicates effort, but also escapes its &lt;span style="font-style: italic;"&gt;level&lt;/span&gt; in a stack of abstracness layers inside an application?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It seems to be common to most examples I have read so far, that AbstractionInversion occurs in conjunction with code/concept duplication in two dependent modules with diffrent levels of abstraction. To explain my thought I will rely on the ADA RendezVous example mentioned &lt;a href="http://c2.com/cgi/wiki?AbstractionInversion"&gt;here.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If i.e. a mutex is implemented by using the RendezVous concept, a mutex concept is actually implemented by using something at least as complex as a mutex, and code is likely duplicated.&lt;br /&gt;Furthermore the one-class-one responsibility rule seems violated in the above example, as the abstraction to the gory details of the model relate to the concepts used in order implement the level of abstraction used by a dependend class, that itselfs tries to escape its level of abstraction by using concepts with a much lower level of abstractness that would actually be appropriate for the position of the dependent class in the hierachy of abstractions.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Does AOP solve the problem?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Another observation in the ADA example is, that abstraction invsersion stems from some backdraws of object oriented desing, wich lacks efficient and clear modeling of cross cutting concerns(&lt;span style="font-style: italic;"&gt;like Mutexes&lt;/span&gt;), and therefore confuses unexperienced developers, by creating the temptation to include certain aspects into strict hierachies of abstractions, aka class hierachies, even if this is not required by the application domain, but merely by technical issues.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-7435739838719556790?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/7435739838719556790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=7435739838719556790' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7435739838719556790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7435739838719556790'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/10/after-trying-to-understand.html' title='AntiPattern: AbstractionInversion'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-7326264433791877200</id><published>2006-10-01T23:18:00.000+02:00</published><updated>2006-10-01T23:21:10.313+02:00</updated><title type='text'>New Emoticons</title><content type='html'>Every owner of a german keyboard, will know these already, but might not have noticed them as first class emoticons painted so obviously on the keys ...&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:180%;"&gt;Ü&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;and&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:180%;"&gt;ö&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-7326264433791877200?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/7326264433791877200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=7326264433791877200' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7326264433791877200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7326264433791877200'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/10/new-emoticons.html' title='New Emoticons'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-3228792375497029700</id><published>2006-09-24T19:57:00.000+02:00</published><updated>2006-09-24T20:00:36.956+02:00</updated><title type='text'>Java Development Tips</title><content type='html'>Oh, if they would just read it...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.squarebox.co.uk/download/javatips.html"&gt;http://www.squarebox.co.uk/download/javatips.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-3228792375497029700?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/3228792375497029700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=3228792375497029700' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/3228792375497029700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/3228792375497029700'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/09/java-development-tips.html' title='Java Development Tips'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-3039081463195793915</id><published>2006-09-18T15:29:00.000+02:00</published><updated>2006-09-18T15:32:43.574+02:00</updated><title type='text'>The purpose of the MOCK</title><content type='html'>&lt;span style="font-weight: bold;"&gt;In response to a much nicer blog entry, that can be found &lt;/span&gt;&lt;a style="font-weight: bold;" href="http://coffeedrivenjava.blogspot.com/2006/08/unit-tests-specify-post-conditions-not.html"&gt;here&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There are actually several distinct "tests" that make up usual unit tests, among them two that really do stand out:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; one kind of testing to test method flows, &lt;/li&gt;&lt;li&gt; one to test some sort of computation.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Mock objects are for the purpose of testing method flows. A method flow is a series of message transmissions to dependent objects.&lt;br /&gt;&lt;br /&gt;The control flow logic inside the method(the ifs and whiles) will alter the flow&lt;br /&gt;&lt;ul&gt;&lt;li&gt;in repsonse to the parameters of the method call parameters passed by calling the method under test, &lt;/li&gt;&lt;li&gt;depending on the state of the object that contains the method under test and &lt;/li&gt;&lt;li&gt;the return values of the external method calls(aka responses to the messages sent).&lt;/li&gt;&lt;/ul&gt;There should be one test method for every branch of an if statement, and usuale some sort of  mock control objects in the mock framework will handle loop checking.&lt;br /&gt;&lt;br /&gt;BTW: &lt;span style="font-style: italic;"&gt;I partly use message transmission instead of method invocation to include other kinds of "not really method invocations" like "exceptions".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The author of the afore mentioned post is quite right with his observation, that his test resembles the method under test quite closely, except, of course, for the control flow code(loops, conditionals). And that is absolutely desired, as he is testing mainly the "method flow" - there is not much computation necessary in JDBC code like this anyway.&lt;br /&gt;&lt;br /&gt;It is tempting to raise the objection that a change in the order of messages sent to another object inside the method under test will result in a failing test, but it is easy to perceive the fact that the order of messages send to ONE object SHOULD be relevant. If it is not, well then there is no point in changing the method under test, isn't there?&lt;br /&gt;&lt;br /&gt;Even if the method under test send variuos messages to various distinct objects, the order will be relevant at some level of abstraction. Therefore mock-checking of the order of method invocations can be(and must be) adjusted, at least if multiple distinct objects are addressed by the method under test.&lt;br /&gt;&lt;br /&gt;And nothing else is it, that the author proposes, although, a little more complicated, than necessary when using easymock, for what I know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-3039081463195793915?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/3039081463195793915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=3039081463195793915' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/3039081463195793915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/3039081463195793915'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/09/purpose-of-mock.html' title='The purpose of the MOCK'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-8938918416821602663</id><published>2006-09-15T16:37:00.000+02:00</published><updated>2006-09-15T16:41:22.080+02:00</updated><title type='text'>Free Programming Books</title><content type='html'>I stumbled over some  &lt;span style="font-style: italic;"&gt;not so common &lt;/span&gt; class of free programming books:&lt;br /&gt;&lt;br /&gt;Although these books are not the most recent spiffy Ajax/Java books, the are worth reading:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt; &lt;a href="http://docs.mandragor.org/files/Misc/Mozilla_applications_en/"&gt;A nice book about Mozilla programming&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iam.unibe.ch/%7Educasse/FreeBooks.html"&gt;Some Free Smalltalk books(yes smalltalk ain't dead yet)&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-8938918416821602663?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/8938918416821602663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=8938918416821602663' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/8938918416821602663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/8938918416821602663'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/09/free-programming-books.html' title='Free Programming Books'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-7094210519930906537</id><published>2006-09-14T18:08:00.000+02:00</published><updated>2006-09-14T18:13:04.694+02:00</updated><title type='text'>Maven Changelog plugin</title><content type='html'>I tried to use the maven changelog plugin, as described here&lt;br /&gt;but maven complained that it could not find the plugin!&lt;br /&gt;&lt;br /&gt;That was due to the fact this plugin is not yet stable, this wasnt mentioned anywhere I looked.&lt;br /&gt;&lt;br /&gt;To enable the plugin you must first add the apache maven snapshot repository, read &lt;a href="http://maven.apache.org/guides/development/guide-testing-development-plugins.html"&gt;this&lt;/a&gt; site to find out how.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-7094210519930906537?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/7094210519930906537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=7094210519930906537' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7094210519930906537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/7094210519930906537'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/09/maven-changelog-plugin.html' title='Maven Changelog plugin'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-115811128642127879</id><published>2006-09-13T03:01:00.000+02:00</published><updated>2006-09-13T10:26:56.713+02:00</updated><title type='text'>AntiPatterns</title><content type='html'>I just realized some nice Articles in the English and German wikipedia about &lt;span style="font-weight: bold;"&gt;anti patterns&lt;/span&gt;. I was well aware of the existence of software engineering related anti patterns, but I read about two other categories of anti patterns, well explained in the afore mentioned articles:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;organizational&amp;project management&lt;/span&gt; anti-patterns&lt;/li&gt;&lt;li&gt;and &lt;span style="font-weight: bold;"&gt;Meta-(anti)-Patterns&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I found it both enlightening and shocking to learn about these patterns. Nevertheless the most funniest were IMHO:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Programmer Experience Clumping&lt;/li&gt;&lt;li&gt;Fear of success&lt;/li&gt;&lt;li&gt;Management by numbers&lt;/li&gt;&lt;li&gt;Single head of knowledge&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Sources:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.mindview.net/WebLog/log-0056"&gt;Programmer Experience Clumping source&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://de.wikipedia.org/wiki/Anti-pattern"&gt;German Wiki Article: AntiPattern&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Anti-pattern"&gt;English Article: AntiPattern&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-115811128642127879?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/115811128642127879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=115811128642127879' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/115811128642127879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/115811128642127879'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/09/antipatterns.html' title='AntiPatterns'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-115809187188753268</id><published>2006-09-12T22:06:00.000+02:00</published><updated>2006-09-13T04:29:30.760+02:00</updated><title type='text'>Maven Source-Formatting/-Metrics</title><content type='html'>I needed to add source code formatting and some code metrics to my maven based project. These  are the places on the web where I found help.&lt;br /&gt;&lt;br /&gt;I wanted to get the Jalopy plugin to format my source code, and promptly failed to get the snaptshots from the mojo projects without the help of this resource,&lt;br /&gt;this resources helped me to get the codehaus mojo snapshot plugins:&lt;br /&gt;&lt;a href="http://maven.apache.org/guides/development/guide-plugin-snapshot-repositories.html"&gt;What to put in settings.xml&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;after that I could simply run:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mvn  -Pcodehaus jalopy:format&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As I was bothered by the command line cluttering by -Pcodehaus, I actived the profile by adding &amp;lt;activeByDefault/&amp;gt; into the activation tag in the profile definiton for the "codehaus" profile.&lt;br /&gt;Now ....&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mvn  jalopy:format&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;... and voila! Jalopy formatted my sources.&lt;br /&gt;&lt;br /&gt;See also: &lt;a href="http://mojo.codehaus.org/jalopy-maven-plugin/howto.html"&gt;maven Jalopy plugin&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Very helpful for the "other" reports was &lt;a href="http://www.javaworld.com/javaworld/jw-02-2006/jw-0227-maven.html"&gt;an interesting java world article...&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I also wanted JDepend to check my project, to I added &lt;a href="http://mojo.codehaus.org/jdepend-maven-plugin/usage.html"&gt;Jdepend&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-115809187188753268?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/115809187188753268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=115809187188753268' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/115809187188753268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/115809187188753268'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/09/maven-source-formatting-metrics.html' title='Maven Source-Formatting/-Metrics'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-115807579745964288</id><published>2006-09-12T17:21:00.000+02:00</published><updated>2006-09-13T16:32:49.326+02:00</updated><title type='text'>my first  migration of a legacy project to maven 2</title><content type='html'>I had to do migrate a legacy webstart swing application to the maven build process. The app was build into several(signed) jars from a single source directory(containing a mix of java files, property files and html help files). The app was deployed with webstart.&lt;br /&gt;&lt;br /&gt;Sometimes the &lt;a href="http://maven.apache.org/ref/current/maven-model/maven.html"&gt;pom file reference&lt;/a&gt; and &lt;a href="http://maven.apache.org/maven-settings/settings.html"&gt;settings file reference&lt;/a&gt; were helpful...&lt;br /&gt;&lt;br /&gt;Important is the &lt;a href="http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html"&gt;introduction to maven lifecycles&lt;/a&gt;.&lt;br /&gt;Interresting is the fact, that maven uses &lt;a href="http://plexus.codehaus.org/ref/feature-comparison.html"&gt;plexus container&lt;/a&gt; for IoC, reading the comparison, I figured I should try using plexus in another project...&lt;br /&gt;&lt;br /&gt;These are the steps that needed to be done to migrate the project:&lt;br /&gt;&lt;br /&gt;1. Install 3rd party jars into the local repository&lt;br /&gt;- I checked in this repository&lt;br /&gt;&lt;br /&gt;2. use the maven2 jar plugin to create a manifest wich points out the main class:&lt;br /&gt;&lt;a href="http://maven.apache.org/plugins/maven-jar-plugin/index.html"&gt;Maven2 Jar plugin&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;3. use the jar plugin to sign the jar&lt;br /&gt;- use the maven keytool plugin to create the keystore automatically after reading &lt;a href="http://mojo.codehaus.org/keytool-maven-plugin/howto.html"&gt;this page&lt;/a&gt;.&lt;br /&gt;- add the jar plugin sign goal&lt;br /&gt;&lt;br /&gt;4. use the assembly plugin to creat a  a zip file with my (bad practice) manually created jnlp file.&lt;br /&gt;- read the &lt;a href="http://maven.apache.org/plugins/maven-assembly-plugin/howto.html"&gt;assemply plugin introduction&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://maven.apache.org/plugins/maven-antrun-plugin/usage.html"&gt;this pages&lt;/a&gt; describes howto use the maven-antrun-plugin.&lt;br /&gt;&lt;br /&gt;5. create the appropriate ant build file&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-115807579745964288?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/115807579745964288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=115807579745964288' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/115807579745964288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/115807579745964288'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/09/my-first-migration-of-legacy-project.html' title='my first  migration of a legacy project to maven 2'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34271990.post-115807038474648210</id><published>2006-09-12T15:18:00.000+02:00</published><updated>2006-09-12T21:25:13.993+02:00</updated><title type='text'>Maven 2 3rd Party Jars</title><content type='html'>&lt;span style="font-weight: bold;font-size:130%;" &gt;Maven: Installing 3rd Party JARs &lt;/span&gt;&lt;br /&gt;&lt;a href="http://maven.apache.org/guides/mini/guide-installing-3rd-party-jars.html"&gt;This page&lt;/a&gt; states that one should install a file into the local repository; But another option I found more useful in a team development environment is to deploy 3rd party jars to a maven repository in the companies network via ssh/scp.&lt;br /&gt;&lt;br /&gt;If multiple developers work on the project it is advisable to have a linux box somewhere with an ssh server installed and apache running. Just configure this&lt;br /&gt;server in your settings.xml and define the deployment to use that server.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;All 3rd party jars, the project website/reports and the project itself can then be deployd to that server with this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mvn deploy:deploy-file -DgroupId=&lt;group-id&gt;        -DartifactId=&lt;artifact-id&gt;        -Dversion=&lt;version&gt;        -Dpackaging=&lt;type-of-packaging&gt;        -Dfile=&lt;path-to-file&gt;        -DrepositoryId=&lt;id-to-map-on-server-section-of-settings.xml&gt;        -Durl=&lt;url-of-the-repositor-to-deploy&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Taken from&lt;a href="http://maven.apache.org/guides/mini/guide-3rd-party-jars-remote.html"&gt;here.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I truely love maven ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34271990-115807038474648210?l=sheyll.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sheyll.blogspot.com/feeds/115807038474648210/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34271990&amp;postID=115807038474648210' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/115807038474648210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34271990/posts/default/115807038474648210'/><link rel='alternate' type='text/html' href='http://sheyll.blogspot.com/2006/09/maven-2-3rd-party-jars.html' title='Maven 2 3rd Party Jars'/><author><name>Sven Heyll</name><uri>http://www.blogger.com/profile/03679162798471066263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
