-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.json
236 lines (236 loc) · 89.6 KB
/
search.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
[
{
"id": 0,
"title": "A fresh start",
"category": "<a class='category' href='/blog/categories/stuff/'>stuff</a>",
"tags": "<a class='tag' href='/tags/blog/'>blog</a>",
"url": "/blog/2014/02/06/A-fresh-start/",
"content": "2014 has just started a month ago and I've painfully realized that I\ndidn't come up with any New Year's resolutions at that time. There is\nno resolution to violate, consequently, no reason to feel bad at all -\nso why not start a new blog which I could then feel bad about when I\npost nothing for months?! Well, to be serious, that's at least how all\nmy blogging attempts have ended so far. I definitely don't know if\nhistory will repeat itself again this time. Maybe this post will actually stay the\nonly post for two months? Any bets? ;-)\n\nAnyway, I better shortly summarize what I plan blogging about. Being a\nsoftware developer, tech topics will probably dominate. Still I can't\npromise not to rant about some random topic from time to time ;-) As\nan Emacs user I might blog about my **Elisp** learning progress or other\nstuff like the one and only **org-mode**. Using **Octopress** as my blogging\nengine it will be unavoidable to mention it as well, ranging from\nplugins and customizations to its philosophy. From time to time I'd also\nlike talking about my journeys to **Haskell** wonderland and\n**Clojure(Script)** development. Or mention some Android apps? There are\nenough topics for sure, we'll see if there is enough motivation to\ncarry on blogging as well ;-)\n\nLet's hope the best!\n",
"date": {
"year": "2014",
"month": "February",
"day": "06"
}
},
{
"id": 1,
"title": "Why Blogging Matters",
"category": "<a class='category' href='/blog/categories/stuff/'>stuff</a>",
"tags": "<a class='tag' href='/tags/blog/'>blog</a>",
"url": "/blog/2014/02/07/Why-Blogging-Matters/",
"content": "There is that fancy phrase \"pics or it didn't happen\". It's just\nclaiming evidence for a, more or less, hardly credible experience which has often to do\nwith some sort of drug abuse. Yes, experience shows it's\nsometimes cleverer to do without taking a photo, anyway, it crossed my mind that that phrase might be\napplicable not only to excess-like experiences but to… pretty much\neverything in life.\n\n<!-- more -->\n\nI'll come back later to what that actually means.. actually, I've just found a nice <a href=\"http://mdswanson.com/blog/2013/08/11/write-things-tell-people.html\" target=\"_blank\">blog post</a>\nabout the importance of running a blog as a developer which goes\nnicely with what I've been thinking. The author, Matt Swanson, says\n\"Do things, write about it\" and explains how sharing his learning on\nhis blog has been incredibly rewarding: Firstly, people told him how much they\nenjoy reading his posts (those compliments alone may be worth it!) and secondly, he gained reputation by\ndemonstrating his abilities and initiative. As a result, he somehow became some\nsort of a \"super hero\" in people's minds although his posts are not\nexactly rocket-science. Regular posts (content is still king!) and a\npretty straight-forward way of expressing things were enough to raise\nhis value… the question is: Did Matt just fool his readers? Isn't he a clever guy after all? \n\nOf course he is \"clever\". He is \"clever\" **because** he shares his\nprojects, learnings and insights on his blog. Being a Software\ndeveloper, blogging about your projects is the most efficient way of\ngaining an over-all reputation - a manager, who considers hiring you, won't read commit logs of Open Source\nProjects where your name might appear but he can enjoy a well-written blog! In fact,\nthe 'positive' effect on the manager's decision seems inevitable; and that's\nwhere the \"pics or it didn't happen\" attitude comes into play. In\norder to convey your abilities to the manager you need definite proof,\npretty similiar to the situation in court, actually: In the end, the\njudge reaches a verdict and **decides what is the truth**. Analogously,\nyou will always **be** exactly as \"clever\" as your vis-à-vis, respectively the\nreaders of your blog, think you are! It goes without saying that you\ncan replace the word \"clever\" with whatever other positive quality you'd\nlike to convey - \"competent\", \"open-minded\", \"innovative\", …, you\nname it.\n\nFunnily enough, you will actually get cleverer when you blog regularly\n;-) Strange? Well, first let's get rid of the word \"clever\" once and\nfor all, it is somehow inaccurate - what I want to say is: You will\nget better at those topics you're blogging about. (And that not only\napplies to tech blogs!) The reason for that: The extra thinking\nnecessary for presenting your work in a nicely structured way on your\nblog will actually force you to nicely structure your projects as\nwell! In addition, your inner urge to at least blog once, twice or X\ntimes a week will actually force you to pursue your projects and\nlearnings 'cause otherwise you wouldn't have anything to blog about.\nAs a result, you'll inevitably get better at reasoning and get a\nbetter understanding of your blog posts' topics… briefly, you get\n\"cleverer\"! Isn't that ironic? ;-) \n\nAnyway, I haven't been able to post regularly in the past, for\nwhatever reasons. In the end that always led to abandonning my past blogs altogether, so I'm not\nquite sure the above argumentation is too believable coming from me,\nto be honest. However, for the moment, it is enough motivation for me to try a fresh\nstart with this blog. After all, it's all about motivation and inspiration.\n",
"date": {
"year": "2014",
"month": "February",
"day": "07"
}
},
{
"id": 2,
"title": "Book Catalogue",
"category": "<a class='category' href='/blog/categories/tech/'>tech</a>",
"tags": "<a class='tag' href='/tags/android/'>android</a>, <a class='tag' href='/tags/app/'>app</a>, <a class='tag' href='/tags/book/'>book</a>",
"url": "/blog/2014/02/10/Book-Catalogue/",
"content": "{% img left /images/book-catalogue.png 200px %}\n\nA week ago I've downloaded the app\n<a href=\"https://play.google.com/store/apps/details?id=com.eleybourn.bookcatalogue&hl=de\" target=\"_blank\">Book Catalogue</a> from the Android Play store. As its name suggests it's\nabout creating a catalogue of your books. My family and I thought it would be handy\nto file our books as we easily lose track of what books we actually own\nand where we have stored them.\n\n**Book Catalogue** makes it all possible: adding books by scanning the\nbarcode, by ISBN, by searching author/title or by adding all\ninformation manually. Of course, every book is stored to be in exactly\none bookshelf - you can create as many bookshelves as necessary and\ncan name them as you want.\n\n<!-- more -->\n\nIn addition, **Book Catalogue** provides syncing to a <a href=\"http://www.goodreads.com/\" target=\"_blank\">GoodReads</a> account.\nI was really looking forward to this as it would make sharing the\ndigital library with my family extremely easy… but only in theory.\nIt turned out that the GoodReads API only allows books to be added if\nthe book already exists on GoodReads. Anyway, the app makes a good\njob to actually inform you which books couldn't be uploaded\nsuccessfully. You could then add those books on the GoodReads web\nsite, however, it's very cumbersome to do that for all missing books;\nso far, I have filed a few hundred books and about a fifth of them\nGoodReads does not know. So the GoodReads sync option is not *really*\nusable after all (especially if you have many old or rare books as\nthey are then likely to be unknown to GoodReads). Luckily, a CSV\nimport/export is provided as well so that I'm not entirely dependent on\nGoodReads's good will ;-)\n\nStill, **Book Catalogue** really is a great app in my opinion (the imperfect GoodReads\nAPI is not the app's fault). Firstly, it's interface is really beautiful and\nprovides nice ways to list the books in various ways. More\nimportantly, the identification of books by barcode and ISBN really\nworks well, including the downloading of meta information from several\nsources like Amazon, LibraryThing, GoodReads and Google Books in\na blink!\n\nWell, it needs to be mentioned that **Book Catalogue** is an Open Source\nproject and <a href=\"https://github.com/eleybourn/Book-Catalogue\" target=\"_blank\">can be found on GitHub</a>. So I might actually implement a\nworking syncing option when I'm really convinced it's worth the work.\nUntil then I'll keep fiddling with CSV export files to keep\neverybody's installation up-to-date on our shared library. It's not\nperfect but it works…\n",
"date": {
"year": "2014",
"month": "February",
"day": "10"
}
},
{
"id": 3,
"title": "Explaining Haskell RankNTypes for all",
"category": "<a class='category' href='/blog/categories/programming/'>programming</a>",
"tags": "<a class='tag' href='/tags/extension/'>extension</a>, <a class='tag' href='/tags/ghc/'>ghc</a>, <a class='tag' href='/tags/haskell/'>haskell</a>, <a class='tag' href='/tags/rankntypes/'>rankntypes</a>",
"url": "/blog/2014/02/12/Explaining-Haskell-RankNTypes-for-all/",
"content": "The Glasgow Haskell Compiler supports a language extension called\n`RankNTypes` which I've had my problems to understand. The moment I\nunderstood that it mostly refers to first-order logic universal\nquantification things became easier, though… but first let's explore why we\nneed it in a step-by-step example.\n\n<!-- more -->\n\n## length :: forall a. [a] -> Int\n``` haskell\n:t length\n-- length :: [a] -> Int\nlength [1,2,3]\n-- 3\nlet intLength :: [Int] -> Int; intLength = length\n:t intLength\n-- intLength :: [Int] -> Int\nintLength [1,2,3]\n-- 3\n```\n\nWe start with the well-known polymorphic function `length` in a fresh\nGHCI session. Above we\nsee how the type checker instantiates `a` to be `Int` in the type of\n`intLength`. Likewise we could create a function `charLength` -\nanyway, `length` can be instantiated to oblige to a list of any type\nwe want, so it is defined *for all* possible types `a`. For the sake\nof simplicity, I'll call a function like `intLength` (which actually\ncorresponds to instantiating the type variable `a` of `length`) a\n*version* of `length`.\n\nAs a matter of fact, a normal Haskell type signature such as `[a]\n-> Int` always implies that the type variable(s) are universally\nquantified with 1 *forall* section located at the beginning of the\ntype declaration. `length`'s type thus corresponds to `forall a. [a] ->\nInt`. We call such a type a *Rank-1-Type* as there is 1 *forall* in\nthe type annotation. The fact that we can omit the *forall* usually -\nand aren't used to it as a consequence - will make things look complicated\nwhen we actually need it, as we'll see later on. In the end, *forall* provides\na scope just like its first-order logic equivalent.\n\n## Apply a length-like function to a list\n``` haskell\nlet apply :: ([a] -> Int) -> [a] -> Int; apply f x = f x\napply length \"hello world\"\n-- 11\napply intLength [1,2,3]\n-- 3\n```\n\nThe `apply` function just applies a function that takes a list and\nreturns an `Int` (like `length` does) to a value.\nNothing fancy nor useful at all, obviously. Still, let's note that under the hood\nthe type of `apply` is `forall a. ([a] -> Int) -> [a] -> Int`. So far, so\ngood, the type checker is happy. Now let's a write a function\n`applyToTuple` that applies a function like `length` to a tuple of\nlists so that the lists of the tuple can be of different types.\n\n## Apply a length-like function to a tuple of lists\n``` haskell\nlet applyToTuple f (a@(x:xs),b@(y:ys)) = (f a, f b) :: (Int, Int)\napplyToTuple length (\"hallo\",[1,2,3])\n--No instance for (Num Char)\n-- arising from the literal `1'\n-- ...\n:t applyToTuple\n-- applyToTuple :: ([t] -> Int) -> ([t], [t]) -> (Int, Int)\n```\n\nI wrote `applyToTuple` without a full type signature. `:: (Int,Int)`\njust makes sure my wanted result type and by the help of the list\ndestructuring `a@(x:xs)` I make sure that the type inference algorithm\nwill conclude \nthat I have a tuple of lists in mind. Consequently, the type of the\nfunction given to `applyToTuple` is inferred to correspond to\n`length`'s type; at least, that's what I would expect naively.\n\nHowever, type inference of `applyToTuple` does not result in the type I had\nin mind. As we can see the types of lists in the tuple `([t],[t])` are\nthe same so that calling `applyToTuple length` with a heterogeneous\ntuple like `(\"hallo\",[1,2,3])` doesn't work. Being stubborn I could\nthen try \"forcing\" the type by providing a type signature:\n\n``` haskell\nlet applyToTuple :: ([a] -> Int) -> ([b],[c]) -> (Int, Int); applyToTuple f (x,y) = (f x, f y)\n-- Couldn't match type `b' with `a' ...\n-- Couldn't match type `c' with `a' ...\n```\n\nThis attempt also fails as GHCI complains about the fact that the\ntypes `b` and `a`, `c` and `a` respectively, do not match! However, the\n`length`-like function `([a] -> Int)` should be applicable to a list of\nwhatever type, shouldn't it?!? That's the moment\nyou'd start doubting either GHCI or your mental health as you know precisely\nthat it *should be possible* to write such a function. After all, you\nknow intuitively that it **is** possible to apply a function like `length`\nto both parts of a heterogeneous tuple of lists as in the code below;\ndoing that in a more generic way in a function like `applyToTuple`\nshould be possible as well!\n\n``` haskell\n-- Obviously, that works without a problem:\n(\\(a,b) -> (length a, length b)) (\"hallo\",[1,2,3])\n-- (5,3)\n```\n\n## applyToTuple :: (forall a.[a] -> Int) -> ([b],[c]) -> (Int, Int)\nWell, there is just one explanation: the type `([a] -> Int)\n->([b],[c]) -> (Int, Int)` is not really what we need for our purpose.\nIn fact, we need `RankNTypes`!\nWe first enable the extension in GHCI and can then write the correct\n`applyToTuple` implementation using the `forall` keyword in the type\nof the first parameter function. (If you want to use the\n`RankNTypes` extension in a file to compile, you actually need to add `{-#\nLANGUAGE RankNTypes #-}` at the top of the file)\n\n``` haskell\n:set -XRankNTypes\nlet applyToTuple :: (forall a.[a] -> Int) -> ([b],[c]) -> (Int, Int); applyToTuple f (x,y) = (f x, f y)\napplyToTuple length (\"hello\", [1,2,3])\n-- (5,3)\n```\n\nThis time it works! :-)\n\n## Explanation\nWe noted earlier that every Haskell type signature's type variables\nare *implicitly* universally quantified by an 'invisible' `forall`\nsection. Thus, under the hood we get the types as follows:\n\n``` haskell\n-- just a reminder:\n-- length :: forall a. [a] -> Int \nlet intLength :: [Int] -> Int; intLength = length \n\n-- applyToTuple:\nlet applyToTuple :: forall a b c. ([a] -> Int) -> ([b], [c]) -> (Int, Int); applyToTuple f (x,y) = (f x, f y) \n-- correct applyToTuple:\nlet applyToTuple :: forall b c. (forall a. [a] -> Int) -> ([b], [c]) -> (Int, Int); applyToTuple f (x,y) = (f x, f y)\n```\n\nNow things get clearer: The function in the type of the correct\n`applyToTuple` has the type `(forall a. [a] -> Int)` which is exactly\nthe type given for `length` above, hence it works. On the other hand,\nthe type `([a] -> Int)` of the function parameter in the wrong\n`applyToTuple` type signature *looks* like the type of `length` **but it isn't**!\n\nHave a look at what the type\nchecker would \"think\" confronted with the wrong `applyToTuple` type\nsignature. When it reads the expression `applyToTuple length` it would\nexpect the type variables `a`, `b` and `c` to be **different**\nconcrete types, so `([a] -> Int)` might become `([Char] -> Int)` or\n`([Int] -> Int)` like our `intLength` function, shortly, some\n*version* of `length`. In the implementation `(f x, f y)` seeks to apply that *version* of\n`length` to two lists of **different** types - however, **any** *version* of\n`length` expects its list to always be of 1 concrete type only, e.g. `Int` in\nthe case of our function `intLength`, consequently, the type checker\nrefuses the lists of the tuple to possibly be of different types!\n\nWhy does the correct definition of `applyToTuple` work then? It\nexpects a `length`-like function of type `(forall a. [a] -> Int)`, that's a function\nwhich works **for all** types `a`, no matter what type you throw at it!\nThus, it forces that function to be a polymorphic function just like\n`length` and rules out any candidate *version* of `length` (like `intLength`) as a consequence.\nSince you can throw a list of any type at that function it can deal with the 2\nlists of different types and the code compiles! \n\n## Conclusion\nUsing `RankNTypes` and the *forall* keyword you can specify that a\nfunction's argument needs to be a *polymorphic* function (like\n`length` in our example). In spite of the fact that you can omit the top-level\n*forall* in the type signature of a polymorphic type, you need to include\nit when you reference it as a parameter.\n\nIn a future blog post I will investigate an important application of\n`RankNTypes` in the Haskell standard library. It will be about the\n`ST` monad which provides a *safe* environment for **mutation** in\nHaskell with the help of `RankNTypes`. Mutation and Haskell?! Yes,\nyou can do it thanks to `RankNTypes`!\n\n*PS: There is a nice*\n<a href=\"http://stackoverflow.com/questions/3071136/what-does-the-forall-keyword-in-haskell-ghc-do\" target=\"_blank\">stackoverflow thread</a> *which investigates the use of \"forall\" in other\nlanguage extensions as well. Actually, my \"applyToTuple\" function is based on*\n<a href=\"http://stackoverflow.com/a/3071932/928944\" target=\"_blank\">that answer</a> of the thread.\n",
"date": {
"year": "2014",
"month": "February",
"day": "12"
}
},
{
"id": 4,
"title": "This is not an org-mode tutorial",
"category": "<a class='category' href='/blog/categories/org-mode/'>org-mode</a>",
"tags": "<a class='tag' href='/tags/plaintext/'>plaintext</a>, <a class='tag' href='/tags/productivity/'>productivity</a>",
"url": "/blog/2014/02/16/This-is-not-an-org-mode-Tutorial/",
"content": "I guess it was about a year ago when I decided to give `org-mode`\nanother go; I had used it before but hadn't been able to quite wrap my head\naround it. This time I managed to get through the hard first\ndifficulties so that I'm a vivid `org-mode` user by now… but first\nmake clear: what is `org-mode` anyway and what has it to do with plain text?\n\n<!-- more -->\n\n## Org-mode\n`org-mode` is an Emacs major mode. There is lots of\n<a href=\"http://orgmode.org/#docs\" target=\"_blank\">documentation and tutorials</a> on `org-mode` and I won't be tempted to\ngive another tutorial (the sheer amount of `org-mode` features to present would\nmake that post very, very long…). I'd rather like to give an\nexplanation of its philosophy and applicability.\n\nOn its <a href=\"http://orgmode.org/\" target=\"_blank\">official website</a> it is characterized as\nfollows: **Org mode is for keeping notes, maintaining TODO lists, planning projects, and authoring documents with a fast and effective\nplain-text system**. Although that obviously is a description without a doubt,\n`org-mode` still has a broader area of applicability - in fact, the HTML title\nof that <a href=\"http://orgmode.org/\" target=\"_blank\">official website</a> describes it best: **Your Life in Plain Text**.\n\nTo put it bluntly, `org-mode` can act as a replacement for any\napplication you normally use for structuring any text-based\ninformation. Well, what is 'text-based' information? Actually, this is\npretty much everything; only images and audio files come to my mind as\nexceptions. However, even for images and audio files you normally\nstore text-based information in the form of meta information. So,\ngenerally, nearly all information that needs structuring is of a\ntext-based nature which is accessible to `org-mode` as a consequence.\n\n## Org-mode's killer feature\nSo the 'killer feature' of `org-mode` is not any specific\napplication - neither 'TODO lists', nor\n'planning projects' - it is rather the fact that you can use it for\nstructuring/managing whatever text-based information you want! You\ndon't need to use 20 different applications for your daily\n'informational needs' any longer, you just need 1 to rule them all!\nThat fact alone of replacing 20 different things with 1 single, more\ngeneral thing somehow makes my programmer's soul smile - just imagine\nthe improvement of code quality when you factor out a common pattern\nof 20 similar methods into 1 generalized method. Or: Imagine a\n'collection' interface which provides methods like 'length' for all\n'collection' implementations… Anyway, I'm\nconvinced that such an abstraction not only shines in programming\nbut also in 'real life' - look at it from this point of view: for any\nrise of efficiency you'll achieve in mastering\n`org-mode` you would have needed an equal rise of efficiency in all 20\napplications in the first place! *And:* you **own** all your information in plain\ntext. I'll explain in a second the benefits of 'owning'; first, let's address\nanother objection which will lead us there.\n\n## We are slaves of interfaces\nYou might argue that you don't even need close to 20 applications but you'd be\nsurprised how fast they add up: preparing slides,\nmanaging your calendar, writing your thesis, managing contacts, TODOs,\nwriting a blog post, adding bookmarks, etc. - with the rise of IT we have gradually become slaves\nof a lot of programs. Still some of us might remember the *organizers*\nwe once had for taking down anything a decade or two ago - handwritten, plain text was\ngood enough in those times - they were the **Personal Information\nManagers** of the pre-IT era. Gradually, we have been convinced to use\ndifferent desktop applications with specialized interfaces for\nmanaging text-based information; the smartphone and tablet era has\nactually even amplified that trend of veering away from plain text.\n\n## We don't own our information\nThose 20 applications from before have 'hidden' our information in databases which only understand SQL.\nSo you would need to learn SQL to connect to 'your' information - apart from\nthe fact that the application in question might be a web application\nand you don't have any direct access to the server where 'your'\ninformation is located… that legal loss of ownership is not what bugs\nme for this blog post's sake, though. It is rather losing one's grasp\non one's information.\nSuppose it's a TODO list application: you need the\ncorresponding app for our tablet/smartphone/etc. to get to your\nTODO items. For many domains of applications a plain text export option can\n**not** be taken for granted. Even for an application with a that simple\ndomain model like a TODO list application you might have troubles to\njust copy the TODO items from your browser window as this would not\nsave the \"done\" status ;) (Calendar applications normally are the\nexception as they provide some standardized import/export options)\n\nI want to emphasize that this should **not** be understood as a rant on the IT world and evil web\napps which hide my data ;) On the contrary, I like my iPad and the\napplications which provide me nice interfaces to add my text-based\ninformation. I just pity the fact all those IT developments have led to\na loss of control of our information which is equally proportional to the\ndegree of which we moved away from plain text! Anways, we are lucky, there is a\npossible escape: Use `org-mode`'s plain text as the *data source* and\nthe beautiful iPad app as its *view* only! For instance, that works well\nfor my `org-mode` calendar data which I can sync with Google Calendar.\nAnother example is this blog post: I'm actually writing this in\n`org-mode` and export it in a Markdown format which the Octopress\nblogging framework understands.\n\nAnyway, I will perhaps post several customizations of how I tailored `org-mode` to my\nneeds in future posts.\n\n## Conclusion\n`org-mode` provides the power of structuring text-based information\nand numerous export options to communicate those information to the\noutside-world. If you care about information and you are an Emacs user anyway, give it a try.\n\nIf you shy away from Emacs you might be interested in the web\napplication <a href=\"https://workflowy.com/\" target=\"_blank\">workflowy</a>. It provides some portion of `org-mode`'s benefits of\nmanaging hierarchical textual information with only structure and no\nlayout in mind. If you need the full power there is no alternative to\n`org-mode`, though. After all, there is only one ring to rule them all.\n",
"date": {
"year": "2014",
"month": "February",
"day": "16"
}
},
{
"id": 5,
"title": "Why Git is better than SVN... or is it?",
"category": "<a class='category' href='/blog/categories/programming/'>programming</a>",
"tags": "<a class='tag' href='/tags/git/'>git</a>, <a class='tag' href='/tags/scm/'>scm</a>, <a class='tag' href='/tags/svn/'>svn</a>",
"url": "/blog/2014/02/24/git-diff-svn/",
"content": "I don't know the numbers of SVN users vs. Git users but in any case there are\nstill many companies out there using SVN (probably more than using\nGit?!) The question is: Why shouldn't they? Does Git actually provide\nenough benefits which are worth the hassle of migrating? If yes, how\nwould you convince a SVN user? **Have you experienced that you couldn't comprehensively convince an SVN advocate of Git's\nsuperiority although you're absolutely sure of it?** Or more generally:\nHow to best convince anybody to use another technology?\n\n<!-- more -->\n\n## \"git svn differences\"\nIt's interesting to actually google \"*git svn differences*\" and to\nskim the results you get. The links I got led to some texts which rather 'objectively'\nenumerate the core differences, however, there are also some which\nclearly try to persuade the reader of Git's benefits. Anyway, in\nboth types of text the core differences tend to be the following:\n\n<ul><li>\n\nGit is faster\n\n</li><li>\n\nBranching is cheaper\n\n</li><li>\n\nGit is distributed, SVN is centralized\n\n</li></ul>\n\nFunnily enough, quite often I stumbled across what I call the tale of the 'Hermit\nProgrammer' scenario: The programmer has no connection to the SVN\nserver and can't commit therefore (imagine yourself miles away from\ncivilization and your life depends on the ability to commit just\n*now*… for whatever reason?!), whereas the programmer could commit to their local repository if they used Git.\nHooray! *Hooray!* Well, seriously… it's a nice story but would it make you\nshutdown your working SVN infrastructure in favor of Git, in view\nof the complexity of migrating all repos, the need of learning Git\ncommands and your coworkers' anger when you tell them that they now\nneed to learn Git because some commands run *faster*?\n\n## Wrong ways of advertising Git\nObviously, all the above arguments are valid but they are not really\nconvincing enough to persuade anyone to replace SVN with Git. Imagine a conversation between\na Git fan and a SVN user:\n\n**Git fan**: Hey! You know, Git is really better, it works much\nfaster!\n\n**SVN user**: Ah, I don't care. SVN is fast enough for me. I commit\nonce a day, that takes a few seconds, so no problem at all…\n\n**Git fan**: Anyway, it's not only faster, it also takes less disk\nspace, especially branches!\n\n**SVN user**: Branches?! Ah, I don't even remember the last time I\ncreated a branch. I know, theoretically you could create \"feature branches\" but\nwe don't do this at work. Why should we? Anyway, we have enough\nstorage in any case.\n\n**Git fan**: Well, you know, *[dramatic pause as now comes his 'killer\nargument']*, Git is distributed, so everybody has a local repository\nand the whole project history. So it can't get lost when a *central*\nserver crashes!\n\n**SVN User**: No problem, we create daily backups of all our\nrepositories. \n\n## The alternative\nWhen I express my favorite Git features (and I'm somehow convinced that those actually\nrepresent the *quintessence* of Git's benefits over SVN in daily use) it sounds like that:\n\n<ul><li>\n\nYou can rewrite your history with Git!\n\n</li><li>\n\nYou have \"pull requests\" for Open Source projects collaboration!\n\n</li><li>\n\nA branch is just a reference to a commit!\n\n</li><li>\n\nInstead of merging you can 'rebase' a branch on another!\n\n</li></ul>\n\nThis time the above SVN User just wouldn't understand the meaning of\nmy arguments! I would need to first explain all that concepts in\ndetail and I'd need to introduce the workflows which are easily possible using Git\nand impossible or a pain in SVN… that lengthy talk doesn't go nicely with our\ninitial goal of convincing\nour vis-à-vis with some quick bullet point arguments, obviously. So it\nseems like we can't have it all. Unless you have some ideas.\n\n## Conclusion\nIf you really want to convey Git's benefits to a fellow SVN coworker you need to take your\ntime. You need to **show** the features, you should give **examples**\nand everyday **scenarios** where Git's capabilities make work at lot\neasier. Believe me, such insights weigh a lot more than purely\nrational arguments like *Git is faster*!\n",
"date": {
"year": "2014",
"month": "February",
"day": "24"
}
},
{
"id": 6,
"title": "Migrating a mutating algorithm from C to Haskell",
"category": "<a class='category' href='/blog/categories/programming/'>programming</a>",
"tags": "<a class='tag' href='/tags/c/'>C</a>, <a class='tag' href='/tags/st/'>ST</a>, <a class='tag' href='/tags/haskell/'>haskell</a>, <a class='tag' href='/tags/laziness/'>laziness</a>, <a class='tag' href='/tags/mutation/'>mutation</a>, <a class='tag' href='/tags/performance/'>performance</a>",
"url": "/blog/2014/03/11/Case-Study---From-C-to-Haskell/",
"content": "I've recently stumbled on a C implementation of an algorithm computing\nthe *combinations without repetition* (of a certain size **k**) of the first **n** natural\nnumbers. So the wanted result is a list of combinations like for\nexample `0 1 2 3 4` or `11 13 20 33 49` in the case of `k=5` and\n`n=50` (*without repetition* means that no number occurs twice in the\nsame combination). As a matter of fact, I wanted to migrate that\nfunction to Haskell; so this post is about the evolution of the\nsolution I came up with. I guess this case study is somehow kind of exemplary for\nthe thought process which you need to undergo whenever you migrate a\nnot-so-trivial algorithm from C to Haskell as it touches upon the\ntopics of *laziness* and *mutation*.\n\n<!-- more -->\n\n# The C Version\nSo let's start with the C Version:\n\n``` c\n#include <stdio.h>\n\nint idx = 0;\n/* puts all combinations into the array of its first argument */\nvoid combinationsWithoutRepetition(int *combinations, int *feld,int bound,int length,int pos,int val){ \n\tif(pos==length) {\n\t\tint i;\n\t\tfor(i=0; i<length; i++) {\n\t\t\tcombinations[idx++] = feld[i];\n\t\t}\n\t} else {\n\t\tint* feldPos = &feld[pos];\n\t\tint i;\n\t\tfor(i=val;i<bound;++i){ \n\t\t\t*feldPos=i; \n\t\t\tcombinationsWithoutRepetition(combinations,feld,bound,length,pos+1,i+1); \n\t\t}\n\t}\n} \nint main(int argc, char **argv) {\n\tint n=50;\n\tint k=5;\n\tint nrOfCombinations = 2118760; // assume that's correct for n=50,k=5\n\tint *combinations;\n\tcombinations = malloc(nrOfCombinations*k*sizeof(int));\n\n\tint *singleCombination;\n\tsingleCombination = malloc(k*sizeof(int));\n\n\tcombinationsWithoutRepetition(combinations,singleCombination,n,k,0,0); \n\tint i = 0;\n\tfor (i=0; i < 50; i=i+5) {\n\t\tprintf(\"%d %d %d %d %d \\n\", combinations[i],combinations[i+1],combinations[i+2],combinations[i+3],combinations[i+4]);\n\t}\n}\n```\n\nSo `combinationsWithoutRepetition` does all the work, however, memory\nneeds to be allocated for the two pointers to int first. (Surely, in a\nreal program `nrOfCombinations` would call a subroutine computing the\nnecessary number of computations, I omitted it for brevity's sake.) In\nthe end, the computed combinations can be accessed through the pointer\n`combinations`.\n\nAnyway, `combinationsWithoutRepetition` didn't look straightforward to\nme, I didn't really understand how it worked and above all, I couldn't\nsee how I could tweak the algorithm so that I could do without the mutation\nof `combinations` and `idx` in the Haskell solution. Consequently, I decided to\ntranslate the C version more or less directly to Haskell, using the\n`ST` monad.\n\nThe `ST` monad makes it possible to have references pointing to\nmutable memory in Haskell. This comes in handy when you want to solve\na problem for which there is no efficient algorithm known doing\nwithout mutation. In our case it gives us the power to create a first\nrunning Haskell version without fully understanding the underlying\nalgorithm of the C implementation. Bear in mind that you always need to run `runST` to\nget a value out of the `ST` monad like below.\n\n## The ST Version\n``` haskell\ncomb1 :: Int -> [Int] -> [[Int]]\ncomb1 k elements = runST $ do\n\tlet bound = length elements\n\t\t\tboundMinus1 = bound-1\n\t\t\telementArray = listArray (0, bound-1) elements\n\n\t\t\tcomb1' :: STRef s [[Int]] -> (Int, Int) -> ST s ()\n\t\t\tcomb1' combos (pos, val) = \n\t\t\t\tlet comb1'' currentCombo (!pos, val)\n\t\t\t\t\t\t\t| pos == k = modifySTRef combos ((:) currentCombo)\n\t\t\t\t\t\t\t| otherwise = forM_ [val..boundMinus1] $ \\x -> comb1'' (elementArray!x : currentCombo) (pos+1,x+1)\n\t\t\t\tin\n\t\t\t\t comb1'' [] (pos, val)\n\tcombos <- newSTRef []\n\tcomb1' combos (0,0)\n\treadSTRef combos\n```\n\nThis version already has two conceptual advantages: It can use an arbitrary list\nof `Int` s as its second parameter (actually it could even be polymorphic\nin the type of the list) and returns a list of lists which is\nsemantically more correct than the C implementation which implicitly\nreturned a long concatenation of the combination lists. Moreover, I\ndidn't need any mutable equivalent of `idx`.\n\nObviously, I wasn't too satisfied with this implementation, though.\nAbove all, the lack of *laziness* proves to be really annoying - the\nwhole list of combinations needs to be computed before you can access\nthe first element of it! This is devastating as in every real word\nscenario of a decently large `n` and `k` the resulting list of\ncombinations is unlikely to fit into your available memory. So comes\nthe lazy `ST` monad to the rescue! \n\n## The Lazy ST Version\n``` haskell\ncomb2 :: Int -> [Int] -> [[Int]]\ncomb2 k elements = L.runST $ do\n\tlet bound = length elements\n\t\t\tboundMinus1 = bound-1\n\t\t\telementArray = listArray (0, bound-1) elements\n\n\t\t\tcomb2' :: STRef s [[Int]] -> (Int, Int) -> L.ST s [[Int]]\n\t\t\tcomb2' combos (pos, val) = \n\t\t\t\tlet comb2'' currentCombo (!pos, val)\n\t\t\t\t\t\t\t| pos == k = do { L.strictToLazyST $ modifySTRef combos ((:) currentCombo); return [currentCombo] }\n\t\t\t\t\t\t\t| otherwise = fmap concat $ forM [val..boundMinus1] $ \\x -> comb2'' (elementArray!x : currentCombo) (pos+1,x+1)\n\t\t\t\tin\n\t\t\t\t comb2'' [] (pos, val)\n\tcombos <- L.strictToLazyST $ newSTRef []\n\tcomb2' combos (0,0)\n```\n\nAnyway, that's the first lazy `ST` implementation I could come up with\nand luckily, it gave me the intuition how I could get completely rid of the `ST`\nmonad. It is obvious that the `modifySTRef` calls are absolutely\npointless as `fmap concat` just concatenates the `[currentCombo]`\nlists returned by the base cases of the recursion and `combos` is not\neven considered in the result of the computation. So let's see the\nversion resulting from throwing the `ST` monad into the garbage can:\n\n## The No ST Version\n``` haskell\ncomb3 :: Int -> [Int] -> [[Int]]\ncomb3 k elements = \n\tlet bound = length elements\n\t\t\tboundMinus1 = bound-1\n\t\t\telementArray = listArray (0, bound-1) elements\n\t\t\tcomb3' (pos, val) = comb3'' [] (pos, val)\n\t\t\t\twhere\n\t\t\t\tcomb3'' currentCombo (!pos, val)\n\t\t\t\t\t| pos == k = [currentCombo]\n\t\t\t\t\t| otherwise = concat [comb3'' (elementArray!x : currentCombo) (pos+1, x+1) | x <- [val..boundMinus1]]\n\t\t\tin\n\tcomb3' (0,0)\n```\n\nThat's much better but still a little obscure. In the end, I found a nice\ndeclarative solution at last:\n\n## The Declarative Version\n``` haskell\ncomb4 :: Int -> [Int] -> [[Int]]\ncomb4 0 _ = [[]]\ncomb4 n (x:xs) = map (x:) (comb4 (n-1) xs) ++ comb4 n xs\ncomb4 _ _ = []\n```\n\nIt just reads as: \"In order to get all *k*-combinations of a *n*\nlength list take the first element of the list, prepend it to all\ncombinations of size *k-1* of the tail of the list and then add all\nthose *k*-combations of the tail of the list!\" It finally makes sense\nwhen you think about it for a long time ;) In addition, that approach\ncan be made a little bit more efficient for certain *n* and *k* using\na very simple memoization strategy. (This simple strategy very quickly\neats up your memory, though.)\n\n## The memoized Declarative Version\n``` haskell\n-- Version with very simple memoization (\"memo table\")\ncombTable = [[ comb5 n (drop elementNr numbers) | elementNr <- zeroToLength] | n <- zeroToLength]\n\t where\n\t zeroToLength = [0..length numbers]\n\ncomb5 :: Int -> [Int] -> [[Int]]\ncomb5 0 _ = [[]]\ncomb5 k (x:xs) = map (x:) (combTable !! (k-1) !! newlength) ++ (combTable !! k !! newlength)\n\t\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\t\t\tnewlength = n-length xs\ncomb5 _ _ = []\n```\n\n# Conclusion\nOriginally, I planned to examine each version's performance in detail,\nhowever, that soon felt too cumbersome to me. Anyway, the *lazy*\nversions do have a significant practical advantage as they do not need\nto compute all combinations in order to get the first 10 combinations!\nJudging from a few tests I have made, it also turns out that `comb3` (not using mutation) performs better\nthan both versions using `ST` even when all combinations are\nrequested so this seems to be a case where mutation does not buy you\nanything in Haskell. If things look differently on your machine, feel\nfree to tell me ;)\n\nYou can find all solution versions <a href=\"/combinations/haskell-all.hs\" target=\"_blank\">here</a>, ready for GHCi. Anyway, feel\nfree to post other solutions to the problem which may score better in\nterms of laziness/time performance/space performance/etc.\n",
"date": {
"year": "2014",
"month": "March",
"day": "11"
}
},
{
"id": 7,
"title": "Explaining the Magic",
"category": "<a class='category' href='/blog/categories/programming/'>programming</a>",
"tags": "<a class='tag' href='/tags/haskell/'>haskell</a>",
"url": "/blog/2014/06/25/Explaining-the-Magic/",
"content": "Yesterday I came across a <a href=\"http://www.reddit.com/r/haskell/comments/28zx87/whats_your_favorite_response_to_the_show_me_the/\" target=\"_blank\">post</a> on the haskell reddit where somebody\nposted the following application of *replicateM*:\n\n``` haskell\n:m +Control.Monad\nreplicateM 3 \"01\"\n-- [\"000\",\"001\",\"010\",\"011\",\"100\",\"101\",\"110\",\"111\"]\n```\n\n## Dark Magic\nIt obviously results in all three-character combinations of zeros and\nones and in general, <em>replicateM x \"01\"</em> generates all x-character\ncombinations of zeros and ones accordingly.\n\n*replicateM* is a standard library function and its haddock\ndocumentation says: \"*replicateM n act* performs the action n times,\ngathering the results\" and its type actually is `replicateM :: Monad m\n=> Int -> m a -> m [a]`. So *replicateM* is **not** a function\nexplicitly crafted for the purpose of a \"get me all x-ary combinations\nof my string\" task, it is actually defined for all monads. Just\nimagine a more obvious application using the IO monad, which *performs the action of\nprinting hello 3 times and gathers the result*.\n\n``` haskell\nreplicateM 3 (putStrLn \"hello\")\n-- hello\n-- hello\n-- hello\n-- [(),(),()]\n```\n\nIt is typical Haskell practice to use a function with such a *general* look\nto solve a rather *special* problem as our original one - to such a\ndegree that it seems like **magic** to programmers with a different\nbackground. Actually, it might look like \"dark\" magic when you don't\ngrasp how/why the hell that result comes about in spite of looking at\nthe source of *replicateM*, and you might start getting annoyed with\nHaskell altogether if that happens several times… anyway, there is no\nsuch thing as (dark) magic ;) so let's demystify that interesting example!\n\n<!-- more -->\n\n## Why it works\nBefore looking at the source - and getting to the operational side of\n*replicateM* - let's ask ourselves *why* we get that result. \n\nBy taking the documentation into account we can paraphrase <em>replicateM 3 \"01\"</em> by saying: \n<em>It performs \"01\" 3 times and gathers the results</em>. But what sort of action is <code>\"01\"</code>.\nAs a string is a list of characters, it's equal to <code>['0','1']</code> which denotes a 'non-deterministic' character value.\nImagine it as a two-faced character which doesn't know if it really is a '0' or a '1'! So what does <em>performing \"01\"</em> really mean?\nI picture it as creating two parallel universes where that value dissolves into '0' in the first and into '1' in the second universe.\nPerforming another \"01\" branches those two universes again so that we get 4 universes. Doing that a third time, those 4 \nuniverses branch again in choosing the third value of either '0' or '1'. As a result, we get 8 universes which really are 8 lists of characters.\nWhen you gather them you obviously get <em>[\"000\",\"001\",\"010\",\"011\",\"100\",\"101\",\"110\",\"111\"]</em>! Confused? Maybe you like the 'How' better!\n\n## How it works\n<a href=\"http://www.haskell.org/hoogle/\" target=\"_blank\">Hoogle</a> is my tool of choice to quickly get to base library haskell\nsource. So <a href=\"http://hackage.haskell.org/package/base-4.7.0.0/docs/src/Control-Monad.html#replicateM\" target=\"_blank\">this</a> tells how *replicateM* is defined:\n\n``` haskell\nreplicateM n x = sequence (replicate n x)\n:t replicateM\n-- replicateM :: Monad m => Int -> m a -> m [a]\n```\n\nBy hoogling for <a href=\"http://hackage.haskell.org/package/base-4.7.0.0/docs/src/GHC-List.html#replicate\" target=\"_blank\">replicate</a> and <a href=\"http://hackage.haskell.org/package/base-4.7.0.0/docs/src/Control-Monad.html#sequence\" target=\"_blank\">sequence</a> we get the whole picture:\n\n``` haskell\n\nsequence ms = let k m m' = do { x <- m; xs <- m'; return (x:xs) } in foldr k (return []) ms\nreplicate n x = take n (repeat x)\n\n:t sequence \n--sequence :: Monad m => [m a] -> m [a]\n:t replicate\n--replicate :: Int -> a -> [a]\n```\n\n*replicate* surely is the easiest function to grasp: `replicate n x`\nresults in a list with *n* elements of value *x*. For instance:\n\n``` haskell\nreplicate 3 \"01\"\n--[\"01\",\"01\",\"01\"]\n```\n\nSo we can actually get the following equations:\n\n``` haskell\nreplicateM 3 \"01\" == sequence [\"01\",\"01\",\"01\"] == \n[\"000\",\"001\",\"010\",\"011\",\"100\",\"101\",\"110\",\"111\"]\n```\n\nSo the magic somehow lies in the *sequence* method or rather in the\nList monad!\n\n### Sequence\nAs in our application *sequence* operates in the list monad you can\npicture it using a list comprehension if you are more familiar with it:\n\n``` haskell\nsequence ms = let k m m' = [x:xs | x <- m, xs <- m'] in foldr k (return []) ms\n-- m is a string, x is a character\n-- m' is a list of strings (= the accumulator), xs is a string\n:t sequence\n-- sequence :: [[a]] -> [[a]]\n```\n\nLet's have a closer look at the last call of *k* in *sequence*.\n\n``` haskell\nreplicateM 3 \"01\" \n-- == k \"01\" [\"00\",\"01\",\"10\",\"11\"] ==\n[x:xs | x <- \"01\", xs <- [\"00\",\"01\",\"10\",\"11\"]]\n-- == [\"000\",\"001\",\"010\",\"011\"] ++ [\"100\",\"101\",\"110\",\"111\"]\n-- == [\"000\",\"001\",\"010\",\"011\",\"100\",\"101\",\"110\",\"111\"]\n```\n\nAt first *x* is selected to be '0' and prepended to all strings of\n*xs*, the resulting list of strings is then concatenated with *x*\nbeing '1' prepended to all strings of *xs* again. As a result, we will\nalways get a lexicographically correct ordering of all *n*-ary combinations of\n\"01\" no matter what *n* we choose in **replicateM n ['0','1']**.\n\nWe have seen how an innocent-looking function like *replicateM* can -\nwhen it is used with the List monad - produce a \"magical\" result, only to then discover that there is no magic involved ;)\n",
"date": {
"year": "2014",
"month": "June",
"day": "25"
}
},
{
"id": 8,
"title": "The notoriously point-free \"((x.).)\" trick",
"category": "<a class='category' href='/blog/categories/programming/'>programming</a>",
"tags": "<a class='tag' href='/tags/haskell/'>haskell</a>",
"url": "/blog/2014/08/14/Composing-two-argument-functions/",
"content": "<a href=\"http://www.haskell.org/haskellwiki/Pointfree\" target=\"_blank\">Point-free</a> code is ubiquitous in every well-polished Hackage library.\nIt's more concise than its pointed counterparts and feels more\n\"hygienic\" as function composition immediately translates to its\nmathematical background.\n\n``` haskell\nlet pointFree = (+1) . read \nlet notPointFree x = (+1) (read x)\n-- notPointFree 'mentions' its argument \"x\"\n```\n\nSo far, so good. However, you get a problem in your chain of function\ncomposition when your right-most function \"takes two parameters\".\n\n``` haskell\nlet plusOne = (+1) :: Int -> Int\nlet readTwoArgs = (\\x y -> read x + read y) :: String -> String -> Int\n\nlet coolSolution = plusOne . readTwoArgs :: String -> String -> Int \n-- Type checker doesn't like coolSolution\n\nlet boringSolution x y = plusOne (readTwoArgs x y) \n-- it's boring since it's not point-free\n```\n\nUnfortunately, `coolSolution` is not well-typed; this might drive you\nnuts for some time: It's obvious that composing those functions must\nsomehow work. You'd think: \"Even GHCI must have understood what I\nmean!\" However, Haskell doesn't care for what you mean as much as it\ncares for type-safety ;) ! So you might fall back on `boringSolution`\nwhich is only half the fun as it's not point-free… anyway, there IS\na way to compose those functions!\n\n<!-- more -->\n\nIn the following I will use\n<a href=\"http://www.haskell.org/haskellwiki/GHC/TypedHoles\" target=\"_blank\">Typed holes</a>. They are a nice tool to look into the type checker's\n\"thoughts\". \nWell, first have a look at why `coolSolution` did not type-check at all.\n\n{% codeblock %}\nCouldn't match type ‘Int’ with ‘String -> Int’\nExpected type: Int -> String -> Int\n Actual type: Int -> Int\nIn the first argument of ‘(.)’, namely ‘plusOne’\nIn the expression: plusOne . readTwoArgs :: String -> String -> Int\n{% endcodeblock %}\n\nEssentially, this tells us that `plusOne` does not have the right type\nto be used together with `(. readTwoArgs)`. Now let's ask this\nquestion to the type checker: What do I need to apply to `plusOne` so\nthat you are happy?\n\n``` haskell\n((_ plusOne) . readTwoArgs) \"3\" \"2\" :: Int\n```\n\nThe answer we get is: \n\n{% codeblock %}\nFound hole ‘_’\n with type: (Int -> Int) -> (String -> Int) -> [Char] -> Int\nRelevant bindings include it :: Int (bound at <interactive>:88:1)\nIn the expression: _\nIn the first argument of ‘(.)’, namely ‘(_ plusOne)’\nIn the expression: (_ plusOne) . readTwoArgs\n{% endcodeblock %}\n\nOkay, this help us. Our \"hole function\"'s type is `(Int -> Int) ->\n(String -> Int) -> [Char] -> Int`. Now we just write that\nfunction - actually, the type signature and our knowledge of what\nshould be the result of the whole expression give rise to that *unique* `holeFunction`:\n\n``` haskell\nlet holeFunction plusOne' stringToInt string = plusOne' (stringToInt string)\nlet holeFunction plusOne' stringToInt string = plusOne' . stringToInt $ string\nlet holeFunction plusOne' stringToInt = plusOne' . stringToInt\nlet holeFunction plusOne' stringToInt = (.) plusOne' stringToInt\nlet holeFunction plusOne' = (.) plusOne'\nlet holeFunction = (.)\n```\n\nBy (re)writing it in a point-free style and by applying eta-reductions we\nget a very simple definition. It turns out that our `holeFunction` is\njust ordinary function composition^^. Anyway, let's have a look if that works.\n\n``` haskell\nlet coolSolution = ((.) plusOne). readTwoArgs\nlet coolSolution = (plusOne .). readTwoArgs\n-- (coolSolution \"3\" \"4\") == 8\n```\n\nYes, it does! That \".).\" looks funny and will surely confuse everybody\nwhose doesn't know that \"trick\" (and does not have a type-checker in\ntheir brain). However, it gets even funnier. When your right-most\nfunction expects even more arguments you just add 'a couple of' \".)\"s\nin between!\n\n``` haskell\nlet wasteFourArgs = (\\a b c d -> read a + read b) :: String -> String -> String -> String -> Int\nlet coolSolution' = (((plusOne .) .) .). wasteFourArgs\n```\n\n## Conclusion\nThus, we have found a way to use the (point-free) function\ncomposition even when you need to feed more than a single argument\ninto it!\n\nAs point-free code is more concise it can be clearer about what you\nwant to do, however, it can obfuscate your intentions as well! (Look\nat those <a href=\"http://www.haskell.org/haskellwiki/Pointfree#Combinator_discoveries\" target=\"_blank\">combinators</a>). In the\ncase of this *((x.).)* trick, I think it can still be beneficial if\nand only if everybody in your team \"knows the trick\" and does not have\nto think about it. The nice reason is: As soon as you delete that \".)\"\nchain mentally you immediately grasp the meaning of the resulting function!\n",
"date": {
"year": "2014",
"month": "August",
"day": "14"
}
},
{
"id": 9,
"title": "Using Google Universal Analytics with Octopress",
"category": "<a class='category' href='/blog/categories/octopress/'>octopress</a>",
"tags": "<a class='tag' href='/tags/analytics/'>analytics</a>, <a class='tag' href='/tags/blog/'>blog</a>",
"url": "/blog/2014/08/16/Using-Google-Universal-Analytics-with-Octopress/",
"content": "When I first set up my Github pages Octopress blog I followed <a href=\"http://stefanalfbo.github.io/blog/2013/04/17/octopress-google-analytics-github-pages/\" target=\"_blank\">those\ninstructions</a> to set Google Analytics tracking up - and it worked. However, in May Google\nAnalytics somehow decided to move my account to *Universal\nAnalytics* - maybe I had approved it without really knowing what it\nmeant…\n\nWell, what is *Universal Analytics*? I have no idea! The\nimportant thing to notice is, though, that you need to change your\nJavaScript **tracking code** if you make that transition; obviously, I\ndidn't know that. Otherwise tracking wouldn't work any longer; would\nit? As a matter of fact, it *somehow* did.\n\n{% blockquote Wolfgang Pauli %}\nIt is not only not right, it is not even wrong.\n{% endblockquote %}\n\nActually, my Analytics dashboard **did** show some visits and hits, that's\nwhy I didn't notice the problem for a long time, however, I guess it\nonly mentioned 10% of them! Anyway, after a long\ndebugging session with <a href=\"https://www.google.at/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCAQFjAA&url=https%3A%2F%2Fchrome.google.com%2Fwebstore%2Fdetail%2Ftag-assistant-by-google%2Fkejbdjndbnbjgmefkgdddjlbokphdefk&ei=xivvU6rFCoTE7AbJ54GgBw&usg=AFQjCNHiOEtvqJl1-RFk6_Q6oVWZTGRFPw&sig2=cuQ2UpUVHzSDJBg77fP0hw&bvm=bv.73231344,d.ZGU\" target=\"_blank\">Google Tag Assistant</a> and <a href=\"https://www.google.at/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCAQFjAA&url=https%3A%2F%2Fchrome.google.com%2Fwebstore%2Fdetail%2Fgoogle-analytics-debugger%2Fjnkmfdileelhofjcijamephohjechhna&ei=NizvU-u2Nef17AaSp4CIAg&usg=AFQjCNHR1yQN0Rdzn4xwMA1bTPZkNEGK_Q&sig2=CEZMIArRE6i7HVQLoSVTiQ&bvm=bv.73231344,d.ZGU\" target=\"_blank\">Google Analytics Debugger</a> I figured out the necessity to change the code, finally.\n\nShortly, you just need to change your\n`source/_includes/google_analytics.html` to this code: \n\n{% codeblock %}\n{% raw %}\n{% if site.google_analytics_tracking_id %}\n <script type=\"text/javascript\">\n (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\nm=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n})(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\nga('create', '{{ site.google_analytics_tracking_id }}', 'auto');\nga('send', 'pageview');\n </script>\n{% endif %}\n{% endraw %} \n{% endcodeblock %}\n\nConcerning Github pages, it's not necessary to include a call to set your domain to\n**github.io** any longer. It just works out of the box - what a\nprogress! It is not only right, it is not even wrong now!\n",
"date": {
"year": "2014",
"month": "August",
"day": "16"
}
},
{
"id": 10,
"title": "Using XMonad with a projector",
"category": "<a class='category' href='/blog/categories/productivity/'>productivity</a>, <a class='category' href='/blog/categories/setup/'>setup</a>",
"tags": "<a class='tag' href='/tags/haskell/'>haskell</a>, <a class='tag' href='/tags/xmonad/'>xmonad</a>",
"url": "/blog/2014/11/07/Using-XMonad-with-a-projector/",
"content": "I've been using XMonad for a few years now (lately in combination with\nGNOME) but just recently I have found a way to make it work in a useful way\nin the context of a presentation with a projector as a second screen.\n\nIn general, XMonad does have decent multi-screen support. Building on\nXinerama, the default configuration provides key-binding support for\nthree screens; how workspaces are mapped to the screens and how this\nmapping can change, respectively, can be pretty confusing at first, though -\nit is best explained in <a href=\"http://www.reddit.com/r/xmonad/comments/ndww5/dual_screens_multi_monitors_tips_and_tricks/c38dsfx\" target=\"_blank\">here</a>. Whenever I want to use a projector\nthings get pretty tricky, however.\n\n<!-- more -->\n\nThe thing is: Using a projector as a second screen, I want to have\nexactly the same workspace (accordingly the same windows, same layout,\nobviously) on both screens. Apparently, I could do that by 'mirroring'\nthe screens and thus circumventing XMonad multi-screen support. I'm\nnot too happy with it, though, as, for some reason, I can't get *xrandr*\nmake show a reasonable resolution on both screens in that scenario -\npart of what is shown on own screen is hidden on the other. Disabling\nmirroring, however, it is **impossible** for XMonad to show exactly the\nsame on both screens - obviously, this is a restriction imposed by\nXinerama as it manages all workspaces across screens as *one*\nlarge workspace under the hood.\n\nThe cure for that disease is the trick I found in another reddit\nthread:\n<a href=\"http://www.reddit.com/r/xmonad/comments/2ha25r/same_workspaces_on_multiple_monitors_without/ckrobfj\" target=\"_blank\">same workspaces on multiple monitors</a>.\nSo let's assume the following setup: Workspace 1 is shown on your\nprojector screen, Workspace 2 is shown on your internal screen. You\nstart a VNC server on workspace 1 on localhost:\n\n{% codeblock %}\nx11vnc -usepw -clip xinerama0 -noxdamage -geometry 1920x1080\n{% endcodeblock %}\n\n(You might need to replace 'xinerama0' by 'xinerama1'. '1920x1080'\nconforms to the resolution of my internal screen. '-noxdamage' is\noptional but seems to be recommended.)\n\nOn Workspace 2 you start a VNC client:\n\n{% codeblock %}\nvncviewer ViewOnly=1 UseLocalCursor=0 localhost:0\n{% endcodeblock %}\n\n(Again you might need to replace 'localhost:0' by 'localhost:1'.)\n\nWell, now you get to see your projected presentation on your internal screen,\ntoo, showing the X display of your VNC server screen! Move to Workspace 1 and start your presentation (or your live\ncoding, for example) while you actually watch your presentation on your internal screen on Workspace\n2! As a bonus, during your presentation you could easily do things\nwhich are not intended to be shown by the projector and/or move\nwindows from an internal workspace to Workspace 1 when they need to be shown.\n\nStarting the vncviewer with the 'ViewOnly' option makes it necessary\nthat you actually make your live in-presentation changes on Workspace\n1, as I said (while watching your own changes on Workspace 2 on your\ninternal screen). That's my recommendation anyway, in my experience the viewer setup thus works more\nstable and some keyboard inputs wouldn't be translated correctly from\nthe viewer to the server using a non-ViewOnly mode.\n",
"date": {
"year": "2014",
"month": "November",
"day": "07"
}
},
{
"id": 11,
"title": "else return null",
"category": "<a class='category' href='/blog/categories/programming/'>programming</a>",
"tags": "<a class='tag' href='/tags/haskell/'>haskell</a>, <a class='tag' href='/tags/maybe/'>maybe</a>, <a class='tag' href='/tags/monadplus/'>monadplus</a>",
"url": "/blog/2015/01/05/else-return-null/",
"content": "I guess everybody has a story or two in store about Nullpointer\nexceptions in Java (or in any language with nullable values). Sooner or later you will make the acquaintance of the dreaded stacktrace line\ndenoting that you did something terribly wrong, demanding a value\nwhere none exists, and you just wonder *why, how the hell can that\nobject be null?!* during an hour of painful debugging… you know\nthat? Good. Well, I won't ponder over how to avoid it, how to apply\nproper error handling etc. (that's way too complicated, I'm tired) but I'd just like to point out my personal\nfavourite, the\nfamous `else return null` idiom.\n\n<!-- more -->\n\nAnyway, the below snippet shows what I actually mean by that.\n\n``` java\n// Version 1\nif (password == \"12345\")\n\t return valuableTreasure;\nelse \n\t return null;\n\n// or, equivalently\n// Version 2\nif (password == \"12345\")\n\t return valuableTreasure;\nreturn null;\n```\n\nTo make things more familiar, in Version 2 you could imagine multiple `return null` lines hidden in\nvarious control structures in an endless method and you surely get an idea\nhow people feel when they try to reason about an object being *null*\nor not.\nAnyway, spotting an `else return null` I always get a bad gut feeling\nsaying that things are not what they are supposed to be. I'm aware\nthat this obviously touches upon the question if you should avoid\n*null* values altogether. Anyway, I can't help my bad gut feeling\nwhenever I see it ;)\n\nThe funny thing is that I recently wrote similar code myself; that\nalone would not be a surprise yet, but I actually wrote it in\nHaskell which does not have that notion of *null* values and the\ncorresponding Nullpointer exception. In Haskell, there is the <a href=\"https://www.haskell.org/haskellwiki/Maybe\" target=\"_blank\">Maybe monad</a> which facilitates chaining \"partial\" computations together without\nthe risk of a Nullpointer exception. Here is the snippet of that code\n(obviously, only the `else Nothing` is 'important'). \n\n``` haskell\nnewState =\n\tif not shouldBeCompiled && w' == view T.word W.immediate' then\n\t (oldState ^. lastColonDefinition ) >>=\n\t (\\x -> return $ oldState & definedWords %~ (ix x %~ set isImmediate True))\n\telse \n\t Nothing\n```\n\nAnyway, believe me, if you ever write such an `else Nothing` in Haskell, that should\nbe the trigger - take a deep breath, take a coffee and think about your\nproblem again. At the least, you are overcomplicating things as using\nthe *Monad* or *MonadPlus* nature of *Maybe* would make life easier\nbut probably it's an indication that your thoughts are about to go\nastray and you get lost in old `else return null` habits or worse - so better\nstop it and take a break!\n\nHow would the *MonadPlus* and *Monad* instances make life better? Look\nat the below version. In any case, it's functionally equivalent, so\nhow would it be 'better'? In my opinion, it conveys much\nmore the impression that the programmer actually knows what they are doing.\n\n``` haskell\nnewState = do \n\tguard $ not shouldBeCompiled && w' == (view T.word W.immediate')\n\n\tx <- oldState ^. lastColonDefinition\n\treturn $ oldState & definedWords %~ (ix x %~ set isImmediate True)\n```\n\nEssentially, the `guard` function does the trick. `guard`, which has the type\n*guard :: MonadPlus m => Bool -> m ()*, makes the containing *do*\nblock evaluate to `Nothing` if the `Bool` argument evaluates to\n`False`. In that sense, the `guard` expression actually looks like an\nassertion! The whole *MonadPlus* magic can be further explored <a href=\"http://en.wikibooks.org/wiki/Haskell/MonadPlus\" target=\"_blank\">here</a>.\n\nIn my case, I finally ended up removing those lines altogether. As suspected, the\ngood old `else Nothing` was the symptom that I had lost track of\nwhat I was coding at all - completely lost in nothingness - and I really needed a\nbreak.\n\nSo what is your typical 'silly code' that you typically start writing when\nyou should rather take a break?\n",
"date": {
"year": "2015",
"month": "January",
"day": "05"
}
},
{
"id": 12,
"title": "Preview your Github Markdown before committing!",
"category": "<a class='category' href='/blog/categories/emacs/'>emacs</a>",
"tags": "<a class='tag' href='/tags/github/'>github</a>, <a class='tag' href='/tags/markdown/'>markdown</a>",
"url": "/blog/2015/01/19/Preview-your-Github-Markdown-before-committing/",
"content": "Writing software documentation can be a pretty dull task and is\nneglected too often (at least by me). But what purpose does the best program\nserve if nobody knows how to use it? None.\n\nLooking at Github, the Markdown formatted **README.md** is the front\n page of every repository and the first (and mostly only) source of\n documentation. \nUntil recently, I have treated my **README.md** files rather shabbily; I\n would have thought that this lack of motivation originates from a\n general dislike of writing documentation, however, I might have\n changed my opinion. This <a href=\"http://increasinglyfunctional.com/2014/12/18/github-flavored-markdown-previews-emacs/\" target=\"_blank\">blog post</a> has opened my eyes to an\n alternative explanation: writing Github Markdown documentation is not\n trivial when you don't have a chance to preview the resulting\n markdown before committing! In that case the output will look\n not as expected more often than not - which makes the committer angry\n as s/he needs to push another commit just for improving the Markdown.\n Anyway, I remember feeling annoyed quite frequently by that procedure in\n retrospective. It does not need a stretch of imagination to foresee\n the negative influence that annoyance has on my willingness to\n provide **README.md** documentation… ;)\n\nThe solution is obvious but not that trivial. Obviously, there surely\nare plugins for various IDEs which can parse Markdown and output HTML\nmarkup. I remember having once installed such an Eclipse plugin. But things get trickier as Github does not use vanilla\nMarkdown but its own brand of Markdown - it is not that easy to find a\nway to display Github Markdown with good confidence in its conformity;\nin addition it shouldn't force me to use any special IDE as I do most\nstuff in Emacs.\n\nThe script that I use now was mentioned in the referenced blog post\nabove: <a href=\"https://gist.github.com/joshuamiller/6d58f8bd239df56cabe8\" target=\"_blank\">flavor.rb</a>. It is a ruby script which actually asks the Github API (!) to do the hard\nwork, namely providing the HTML output! That looks stupid at first\nglance but it is actually the only way to be really sure of the\npreview's congruence with the actual display on the Github page…\n",
"date": {
"year": "2015",
"month": "January",
"day": "19"
}
},
{
"id": 13,
"title": "Partial matching in R",
"category": "<a class='category' href='/blog/categories/programming/'>programming</a>",
"tags": "<a class='tag' href='/tags/r/'>r</a>, <a class='tag' href='/tags/statistics/'>statistics</a>, <a class='tag' href='/tags/syntax/'>syntax</a>",
"url": "/blog/2015/02/20/Partial-matching-in-R/",
"content": "I've not been too exposed to statistics programming in the last few\nyear, however, sometimes it couldn't be avoided - and R couldn't be\navoided! (I still have too much self-esteem to think about\nfalling back to Excel, even for the simplest things.)\n\nI don't hate R and I don't like R; it just strikes me as very\n**strange**. Often, the syntax strikes me as odd and above all, the\nmultitude of ways to express the same thing reminds of my little Perl\nexperience. Anyway, I have subscribed to the Coursera R course for fun\nand in hope to somehow \"get the better of R\", to grok in on a deep\nlevel or to at least get a more profound idea as to why I don't like it ;)\n\nAnyway, here is a language construct which is very **strange** and a\nlittle bit absurd, no whatever how often I think about it. It's called\n<span class=\"underline\">partial matching</span>. To put it bluntly, partial matching makes it\npossible to avoid spelling out the whole name of an element of a list\nin oder to access it. Let's have a look.\n\n<!-- more -->\n\n``` r\nx <- list(a_is_the_first_letter = 1 : 5)\n```\n\nNow let's access `a_is_the_first_letter`! That's the normal way:\n\n``` r\nx$a_is_the_first_letter\n# 1 2 3 4 5\n```\n\nHowever, you could make your life a lot \"easier\":\n\n``` r\nx$a\n# 1 2 3 4 5\n```\n\nWell, the crucial question is: what happens if the prefix of your\npartial matching is not unique?\n\n``` r\nx <- list(a_is_the_first_letter = 1 : 5,\n\t\t\t\t\ta_is_my_first_letter_too = 6 : 10)\nx$a\n# NULL\n```\n\nThe result is `NULL`!\n\n``` r\nx <- list(a_is_the_first_letter = 1 : 5,\n\t\t\t\t\ta_is_my_first_letter_too = 6 : 10)\nx$a_is_m\n# 6 7 8 9 10\n```\n\nHere the prefix is unique again. Hooray!\n\nFunny, isn't it? I don't like it, though. Why? Because it's not 'obvious'.\nYou need to know that feature beforehand, otherwise the fact that an\naccidentally misspelled field is handled the same way as a non-unique\nfield prefix (both returning `NULL`) is awkward, to say the least.\nIt's nearly as though I said to the R interpreter: 'Give me field\nxy or any field that is somehow similar… or just do what you fucking\nwant (= return NULL)!' Anyway, it introduces complexity and indeterminism into the code. \n\nThere is another twist to partial matching. Of course, there is more\nthan one way to access a field of a list. Making use of the double bracket\nsyntax, that feature of partial matching is handled differently.\n\n``` r\nx <- list(a_is_the_first_letter = 1 : 5)\nx[[\"a\"]]\n# NULL\n```\n\nUsing the double bracket field accessing method, partial matching is\nnot the default. But R is perly so you still have a way to get that\nbehavior in a different way:\n\n``` r\nx[[\"a\", exact = FALSE]]\n# 1 2 3 4 5\n```\n\nAt least I now have a better idea why I don't really like R. It\nintroduces a sort of laisser-faire programming which I consider too\n\"inexact\". I mean, would you really want something like the following to be the\nfuture of programming:\n\n``` java\ninterface God { \n\t\tvoid killMankind();\n\t\tvoid keepUpTheGoodWork();\n}\n\n// ...\ngod.k() // What the hell happens? Who cares.\n```\n",
"date": {
"year": "2015",
"month": "February",
"day": "20"
}
},
{
"id": 14,
"title": "Approximating PI with PureScript",
"category": "<a class='category' href='/blog/categories/programming/'>programming</a>, <a class='category' href='/blog/categories/web/'>web</a>",
"tags": "<a class='tag' href='/tags/functional/'>functional</a>, <a class='tag' href='/tags/graphics/'>graphics</a>, <a class='tag' href='/tags/javascript/'>javascript</a>, <a class='tag' href='/tags/jquery/'>jquery</a>, <a class='tag' href='/tags/purescript/'>purescript</a>",
"url": "/blog/2015/03/14/Approximating-PI-with-PureScript/",
"content": "Oh, it is Pi day! To be honest, I had not known about it until today\nbut it somehow made it into my Twitter stream. Well, after some relaxed Saturday morning browsing I stumbled across the <a href=\"http://demonstrations.wolfram.com/ApproximatingPiWithInscribedPolygons/\" target=\"_blank\">Wolfram Pi approximation demonstration</a>. It looks like this:\n\n<script type='text/javascript' src='http://demonstrations.wolfram.com/javascript/embed.js' ></script><script type='text/javascript'>var demoObj = new DEMOEMBED(); demoObj.run('ApproximatingPiWithInscribedPolygons', '', '389', '613');</script><div id='DEMO_ApproximatingPiWithInscribedPolygons'><a class='demonstrationHyperlink' href='http://demonstrations.wolfram.com/ApproximatingPiWithInscribedPolygons/' target='_blank'>Approximating Pi with Inscribed Polygons</a> from the <a class='demonstrationHyperlink' href='http://demonstrations.wolfram.com/' target='_blank'>Wolfram Demonstrations Project</a> by Rob Morris</div><br />\n\nPi is approximated by computing the area of the inscribed\npolygon and by dividing that area by the square of the circle radius -\nafter all, the area of a circle is **r²π**. Obviously, that idea is\nthat beautiful and so simple that Pi has thus been approximated thousands of\nyears ago (of course, there are many better and faster ways!), so\nI decided to implement it myself.\n\n<!-- more -->\n\n## PureScript\nSome days ago I stumbled across **PureScript** which compiles to\nJavaScript. It is heavily influenced by Haskell and shares its quality\nof static typing. However, it has been designed to target JavaScript\nfrom the getgo such that it incorporates the strict evaluation\nsemantics of JavaScript. In addition, it provides a syntax similar to\nnative JavaScript for accessing object properties. Given some Haskell knowledge,\nPureScript seems to be a decent alternative to Fay or Haste for\ncreating Javascript code! So I thought I would give\nit a try and implement something similar to the above Wolfram\ndemonstration! So this is the result I accomplished after one day's\nwork on a <a href=\"/pi/html/index.html\" target=\"_blank\">PureScript clone</a>:\n\n<iframe src=\"/pi/html/index.html\" width=\"500\" height=\"720\" style=\"margin:auto;display:block\"></iframe>\n\n### PureScript learning resources\nFirst of all these are the best resources on PureScript development that I found:\n\n<ul><li>\n\n<a href=\"https://gist.github.com/paf31/8e9177b20ee920480fbc\" target=\"_blank\">24 days of PureScript</a>\n\n</li><li>\n\n<a href=\"https://leanpub.com/purescript\" target=\"_blank\">PureScript by Example</a> - very detailed but excellent!\n\n</li><li>\n\n<a href=\"https://github.com/purescript/purescript/wiki\" target=\"_blank\">PureScript Wiki</a> \n\n</li></ul>\n\n<a href=\"https://gist.github.com/paf31/8e9177b20ee920480fbc\" target=\"_blank\">24 days of PureScript</a> gives a very good overview of the PureScript\nlibrary landscape. Above all, running code for every introduced\nlibrary is given which is crucial to getting quickly started. In\naddition, there is a project called <a href=\"http://pursuit.purescript.org/\" target=\"_blank\">Pursuit</a> which provides a search\nengine for functions of PureScript packages. It is still far from\nbeing as useful as Hoogle or Hayoo for Haskell development, though.\n\n## PureScript libraries and building process\nPureScript libraries are managed by **bower** which has worked\nsurprisingly well for me. However, at the beginning I had problems getting the interpreter `psci` running with\nall dependencies as I'm not used to **grunt** (and **npm**) which are\ntypically needed in the whole building process. Anyway, when I decided\nto use certain PureScript libraries for my implementation their\nintegration worked like a charm! \n\n## HTML5 Canvas bindings\nPureScript has very decent wrappers of the HTML5 Canvas API in form\nof `purescript-canvas` and `purescript-free-canvas`. Obviously, I made\nheavy use of those to get the circle and the polygon drawn.\n\n``` haskell\ncenter = { x : 210, y : 210 }\ndrawCircle = do \n\tarc { x: center.x, y: center.y, r: radius, start: 0, end: Math.pi * 2 }\n\tsetFillStyle \"#000000\"\n\tfill\n```\n\nAs an argument to `arc` we actually have an example of the *Object*\nsyntax of PureScript which is just like native JavaScript.\n\n## Angular, React or something else?\nPureScript does have bindings to AngularJS and React (find PureScript\nlibraries by <a href=\"http://bower.io/search/?q=purescript\" target=\"_blank\">searching bower</a>), however, they are both still\nexperimental and alpha. So I somehow didn't want to commit to something\nhalf-working which could be very hard to understand for a PureScript\nnewbie like me. Anyway, I decided that the JQuery binding of\n`purescript-jquery` should be enough for my Pi approximation application; in the end, I\nalso used `purescript-rx` (also mentioned on <a href=\"https://gist.github.com/paf31/8e9177b20ee920480fbc\" target=\"_blank\">24 days of PureScript)</a>\nbut I only scratched the surface of reactive PureScript UI modelling.\n\n## What about the slider?\nI definitely wanted a fancy slider for setting the number of vertices\nof the polygon like in the Wolfram demo - without\ntoo much ado, I immediately decided on using the vanilla <a href=\"http://jqueryui.com/slider/\" target=\"_blank\">JQuery-UI\nslider</a>. Copy-Paste. That however means that my PureScript has to\nsomehow interact with the native slider JavaScript.\n\n## The main function\nThe first few lines are about getting representations of the HTML\nelements with `purescript-jquery`. Then I define event handlers for\nchanging the number of vertices and for toggling the checkbox to\nshow/hide the triangles. `onAsObservable` actually is from the\n`purescript-rx` binding to the reactive <a href=\"https://github.com/Reactive-Extensions/RxJS\" target=\"_blank\">RxJS</a> libraries which could be\nused to define complex event handling.\n\n``` haskell\nmain = do\n\tcanvas <- getCanvasElementById \"canvas\"\n\tcontext <- getContext2D canvas\n\tverticesInput <- select \"#vertices\"\n\tpolygonArea <- select \"#polygonArea\"\n\tpi <- select \"#pi\"\n\ttriangles <- select \"#triangles\"\n\n\tlet updateUI num showTriangles = do \n\t\t\t{ pArea : polygonAreaPercent, pi : piApprox } <- showPolygon canvas context num showTriangles\n\t\t\tsetText (show polygonAreaPercent <> \"%\") polygonArea\n\t\t\tsetText (show piApprox) pi\n\tlet updateUI' = do \n\t\t\t\tshowTriangles <- ((== \"true\") <<< stringify) <$> getProp \"checked\" triangles\n\t\t\t\tnum <- (stringify >>> readInt 10) <$> getValue verticesInput\n\t\t\t\tupdateUI num showTriangles\n\n\ttrianglesChange <- \"click\" `onAsObservable` triangles\n\ttrianglesChange `subscribe` \\_ -> void updateUI'\n\n\tverticesChange <- \"focus\" `onAsObservable` verticesInput\n\tverticesChange `subscribe` \\_ -> void updateUI'\n\n\tupdateUI defaultVertices defaultShowTriangles\n```\n\n## The Foreign Function Interface\nIn the above code I accessed the current value of the checkbox and the\nslider value with the `purescript-jquery` functions `getValue` and\n`getProp`. However, it was surprisingly difficult to use those values\nas they were not of type `String` but `Foreign` and I got those\ndragged into the field of the Foreign Function Interface for\ncommunicating with JavaScript code. Anyway, after some digging in I\nended up writing the function `stringify` which trivially transforms the\nincoming Javascript value to a `String`.\n\n``` haskell\nforeign import stringify\n\t\"function stringify(x) {\\\n\t\\ return x+\\\"\\\";\\\n\t\\}\" :: Foreign -> String\n```\n\nThat's an example of how you can integrate JavaScript functions in\nPureScript. It is a little bit of a joke as of now sice you need to add all\nthose backslashes, however, things might get easier in case PureScript\ngets a meta programming facility like **TemplateHaskell** in the Haskell\nworld in the future.\n\n## Conclusion\nAll in all, PureScript really makes a nice impression. There is already\na surprising number of libraries available; decent, mature bindings to\nAngular or React would be crucial for getting easy web development\nadoption, though. Meta programming integration of JavaScript code would\nalso prove very nice as would be Source Map support… anyway, I'm\nlooking forward to using it again and might get into improving it myself.\n\nPS: You find the code for the PureScript application on <a href=\"https://github.com/sleepomeno/InscribePolygons\" target=\"_blank\">my GitHub</a>.\n",
"date": {
"year": "2015",
"month": "March",
"day": "14"
}
},
{
"id": 15,
"title": "Historical Elo Tennis Rating",
"category": "<a class='category' href='/blog/categories/programming/'>programming</a>, <a class='category' href='/blog/categories/tennis/'>tennis</a>",
"tags": "<a class='tag' href='/tags/r/'>r</a>, <a class='tag' href='/tags/statistics/'>statistics</a>",
"url": "/blog/2015/09/08/Historical-ELO-Tennis-Rating/",
"content": "Recently I've come across <a href=\"http://fivethirtyeight.com/features/serena-williams-and-the-difference-between-all-time-great-and-greatest-of-all-time/\" target=\"_blank\">that fivethirtyeight article</a> comparing the\nfemale tennis all-time greats by means of an <a href=\"https://en.wikipedia.org/wiki/Elo_rating_system\" target=\"_blank\">Elo rating variant</a> (originally known from chess). It concludes that Serena Williams does\n**not** have the highest rating in history, although she is frequently\nconsidered as the greatest player of all time nowadays. Obviously, I \nwondered what's the situation like in the men's tennis world. Have\nRoger Federer's record 17 Grand Slam wins led to the highest Elo\nrating as well? What about players like Borg and McEnroe? Anyway, I\nhave found surprising results.\n\n<!-- more -->\n\n## Technical approach\n<a href=\"https://github.com/JeffSackmann/tennis_atp\" target=\"_blank\">This</a> is where I got the match data on ATP matches from 1968\nonwards providing the source of the Elo evaluation in yearly CSV\nfiles. I have adopted the mathematical details of the computation from\n<a href=\"https://en.wikipedia.org/wiki/Elo_rating_system#Mathematical_details\" target=\"_blank\">the Elo rating Wikipedia page</a>, while I took the recommendation for the\ncomputation of the **K-factor** from <a href=\"http://fivethirtyeight.com/features/serena-williams-and-the-difference-between-all-time-great-and-greatest-of-all-time/#fn-3\" target=\"_blank\">fivethirtyeight</a>. In addition, I\nvalued Grand Slam tournament matches higher than other matches\n(because of the longer and more challenging best-of-5-sets distance) by\nincreasing the rating changes resulting from those matches by 10%.\nAnyway, I wrote an R script which can be found <a href=\"https://github.com/sleepomeno/tennis_atp/blob/master/examples/elo.R\" target=\"_blank\">here</a>.\n\n## The top 10 highest tennis Elo ratings\nObviously, the main question is: Who has acquired the highest Elo\nrating? The answer is: <span class=\"underline\">Novak Djokovic</span> in May 2015! That's the top 10:\n\n<table class=\"stat\"><thead><tr><th>Rank</th><th>Rating</th><th>Player</th></tr></thead><tbody> <tr><td>1</td><td>2335</td><td>Novak Djokovic</td></tr> <tr><td>2</td><td>2310</td><td>Bjorn Borg</td></tr> <tr><td>3</td><td>2304</td><td>John McEnroe</td></tr> <tr><td>4</td><td>2274</td><td>Rafael Nadal</td></tr> <tr><td>5</td><td>2254</td><td>Roger Federer</td></tr> <tr><td>6</td><td>2253</td><td>Ivan Lendl</td></tr> <tr><td>7</td><td>2191</td><td>Jimmy Connors</td></tr> <tr><td>8</td><td>2168</td><td>Boris Becker</td></tr> <tr><td>9</td><td>2159</td><td>Andy Murray</td></tr> <tr><td>10</td><td>2132</td><td>Pete Sampras</td></tr></tbody></table>\n\nInteresting to see that Borg, McEnroe and Lendl (dominating the 1980s) rank in between the likes of\nDjokovic, Nadal and Federer who have dominated the last decade.\n\nAnyway, you might be surprised to see 14-time Grand Slam winner Pete\nSampras only in 10th place. In my opinion, his case demonstrates a **practical**\nrequirement to get to the top of the above list - or rather\na lack thereof: High-ranked opponents. \n\n<div style=\"clear:both\"> </div>\n\n## Everything is relative - being the best, too!?\nNo matter how good a professional tennis player you are, you will lose\nsooner or later \"because you are human\" (this is obviously\ncontroversial and Elo does not account for this). When the defeat happens it is\nbetter to lose against higher Elo-rated opponents since you then lose\nless points. To put it bluntly: When you have an hypothetical Elo advantage of 1000\npoints with regard to the next-best player at the start of the season and you win\n99 of 100 matches, you will most likely have a worse rating in the end\nof that wonderful season due to that one devastating loss!\nConsequently, it could be said that Sampras might have lacked high-valued contemporaries to\nmake an even deeper run. In contrast, Djokovic has benefited from the\nhigh ratings of Nadal and Federer to get to the very top. (Apart from\nthat, <a href=\"https://en.wikipedia.org/wiki/Elo_rating_system#Ratings_inflation_and_deflation\" target=\"_blank\">Elo inflation</a> might be a reason for higher ratings nowadays, too.) Similarly,\nBorg, McEnroe and Lendl have benefited from the strong competition in\nboosting their respective peaks. That's why I have looked for a way to\nabstract the performance from absolute ratings: I have compared the\nmargins that the above best players could amass in comparison to the\nnext-best player at their ratings' peaks. Thus, it can be analyzed by\nwhat margin a player has been able to set oneself apart from the\ncompetition, which I consider as an indicator as significant as the\nmaximal Elo rating.\n\n<table class=\"stat\"><thead><tr><th>Gap</th><th>Player</th></tr></thead><tbody> <tr><td>225</td><td>Roger Federer</td></tr> <tr><td>194</td><td>Ivan Lendl</td></tr> <tr><td>181</td><td>Bjorn Borg</td></tr> <tr><td>172</td><td>Novak Djokovic</td></tr> <tr><td>154</td><td>Pete Sampras</td></tr> <tr><td>148</td><td>John McEnroe</td></tr> <tr><td>61</td><td>Rafael Nadal</td></tr> </tbody></table>\n\nIn February 2007 Federer reached his rating peak and the next-best\nplayer at that time, Rafael Nadal, trailed 225 Elo points. That event\nhas marked the biggest gap of the Elo rating's leader and the rest\nof the world; a difference of 225 Elo points means a winning chance of\n78% for the higher-ranked player. Well, two months later Federer lost to Nadal in the 2007 French\nOpen final, nevertheless.\n\n<div style=\"clear:both\"> </div>\n\n## Conclusion\nNo matter whether you 'prefer' the first or the second table - both\ntables shows the current top players count among the best of all\ntimes, however, they don't really outperform the likes of Borg,\nMcEnroe and Lendl! The R source code for my analysis can be found <a href=\"https://github.com/sleepomeno/tennis_atp/blob/master/examples/elo.R\" target=\"_blank\">here</a>.\n",
"date": {
"year": "2015",
"month": "September",
"day": "08"
}
},
{
"id": 16,
"title": "Toying with Racket",
"category": "<a class='category' href='/blog/categories/programming/'>programming</a>, <a class='category' href='/blog/categories/tennis/'>tennis</a>",
"tags": "<a class='tag' href='/tags/graphics/'>graphics</a>, <a class='tag' href='/tags/racket/'>racket</a>",
"url": "/blog/2015/09/13/Toying-with-Racket/",
"content": "2 hours to go… I've been waiting for the men's tennis US Open final\nto start. What should I do? In the end, I've been killing time listening to <a href=\"http://www.functionalgeekery.com/episode-24-matthew-flatt/\" target=\"_blank\">that</a> Functional Geekery podcast episode\nwhich features Matthew Flatt talking about the <a href=\"http://racket-lang.org/\" target=\"_blank\">Racket</a> programming\nlanguage. Realizing the irony, my thoughts went something like: \"Racket, tennis?! Can't be a coincidence! Still\nsome time to burn, so I will programm something tennis-like in\nRacket!\" So let's open the Racket <a href=\"http://docs.racket-lang.org/quick/\" target=\"_blank\">quickstart</a> to somehow learn Racket\nand get an idea what the tennis-like thing should be.\n\n<!-- more -->\n\n{% img left /images/court.png 200px %}\n\nThe idea came instantly when I saw that Racket offers quite\nnewbie-friendly picture drawing examples in its tutorial. Now, it's\nobvious what I would do, isn't it? Exactly, I would draw a tennis\ncourt! So I <a href=\"http://download.racket-lang.org/\" target=\"_blank\">downloaded</a> Racket and found the executable\nfor the Racket IDE DrRacket in the **bin** folder of the resulting\ndirectory. Given the examples of the <a href=\"http://docs.racket-lang.org/quick/\" target=\"_blank\">quickstart</a> tutorial I could come\nup with that code which got the job done. And it even has (kind of) the blue\ncolor of the US Open hard court ;)\n\n{% codeblock %}\n(let* ([color \"blue\"]\n\t\t\t[blue (lambda (pict) (colorize pict color))]\n\t\t\t[double (blue (filled-rectangle 203 30))]\n\t\t\t[base (blue (filled-rectangle 90 133))]\n\t\t\t[margin 3]\n\t\t\t[doubles (hc-append margin double double)]\n\t\t\t[service (blue (filled-rectangle 110 65))]\n\t\t\t[services (vc-append margin service service)]\n\t\t\t[middle1 (hc-append margin base services)]\n\t\t\t[middle2 (hc-append margin services base)]\n\t\t\t[middles (hc-append margin middle1 middle2)])\n\t\t(frame (frame (vc-append margin doubles middles doubles) #:color \"white\" #:line-width 18) #:color color #:line-width 12))\n{% endcodeblock %}\n\nThe code can also be found in that <a href=\"https://gist.github.com/sleepomeno/f8f0af59b19324166619\" target=\"_blank\">gist</a>.\n\nAnyway, now the final is about to start, so only a few impressions of\nusing Racket for the first time: DrRacket proved easy to use and the\n<a href=\"http://docs.racket-lang.org/pict/Basic_Pict_Constructors.html\" target=\"_blank\">documentation</a> made it easy to find the right functions for drawing. It\nwas quite pleasant to see that I could get things done in Racket even\nunder severe time pressure ;)\n\nGo, Federer!\n",
"date": {
"year": "2015",
"month": "September",
"day": "13"
}
},
{
"id": 17,
"title": "Rolling the dice using random Enum values",
"category": "<a class='category' href='/blog/categories/programming/'>programming</a>",
"tags": "<a class='tag' href='/tags/enum/'>enum</a>, <a class='tag' href='/tags/evil/'>evil</a>, <a class='tag' href='/tags/haskell/'>haskell</a>, <a class='tag' href='/tags/random/'>random</a>",
"url": "/blog/2017/04/02/Generating-random-Enum-values/",
"content": "Every wanted to roll the dice in Haskell? Let's say you have a data type like\n\n``` haskell\ndata Number = One | Two | Three | Four | Five | Six \n\t deriving (Enum, Bounded, Eq, Show)\n```\n\nHow do you generate a random `Number` value? There are several ways to do it, usually in an `IO` context, obviously. In order to use it in a \ncommon monad transformer stack, the primitives of the `MonadRandom` type class come to my mind. So it would be most convenient to get a\n random value using `getRandom`. Anyway, as much fun as rolling the dice is, let's derive a solution working for all bounded Enums.\n\n<!-- more -->\n\nAnyway, import **Control.Monad.Random** as we want to use `getRandom` of the `MonadRandom` class which looks like:\n\n``` haskell\nclass Monad m => MonadRandom (m :: * -> *) where\n\tgetRandom :: Random a => m a\n-- other functions we don't need\n\nclass Random a where\n-- needs to provide:\n\trandomR :: RandomGen g => (a, a) -> g -> (a, g)\n\trandom :: RandomGen g => g -> (a, g)\n```\n\nShortly, `randomR` needs to be able to provide a random `Number` value in the specified interval, given a random number generator. So the idea is about mapping the Enum values to `Int` values\nand deriving a random Enum value from a randomly generated number. \n\n``` haskell\n-- :t fromEnum\n-- fromEnum :: Enum a => a -> Int\n-- :t toEnum\n-- toEnum :: Enum a => Int -> a\n\n-- 1)\ninstance Random Number where\n\trandomR (a,b) g = \n\t\tcase randomR (fromEnum a, fromEnum b) g of\n\t\t\t\t(x, g') -> (toEnum x, g')\n\trandom g = randomR (One, Six) g\n\n-- 2) - more general solution making use of Bounded\ninstance Random Number where\n\trandomR = enumRandomR\n\trandom g = randomR (minBound, maxBound) g\n\nenumRandomR (a, b) g =\n\tcase randomR (fromEnum a, fromEnum b) g of\n\t\t(x, g') -> (toEnum x, g')\n```\n\nWhile we still used the explicit `Number` interval values in **1)**, we get a more general solution in **2)** using the fact that we had auto-derived an instance of `Bounded` for `Number` and thus have `minBound` and `maxBound` at our disposal.\n\nAt last, we can generate a random `Number` value:\n\n``` haskell\nλ> getRandom :: IO Number\nTwo\n```\n\nAnyway, our generated `Number` values are uniformly distributed, every value occurs with equal probability. What if you want to tamper with the die at little, e.g.\nwhen your opponent throws the dice they should not get a `Six` quite so often. You could do that providing a respective `Random` instance for a newtype wrapper:\n\n``` haskell\n-- you need GeneralizedNewtypeDeriving pragma to derive Enum\nnewtype MaxBoundLessLikely a = MaxLessLikely {\n\tgetValue :: a } deriving (Bounded, Eq, Enum, Show)\n\ninstance (Enum a, Eq a, Bounded a) => Random (MaxBoundLessLikely a) where\n\trandomR (a,b) g = case enumRandomR (a,b) g of\n\t\tresult@(MaxLessLikely value, g') -> \n\t\t\t if value == maxBound then\n\t\t\t\t enumRandomR (a,b) g'\n\t\t\t else result\n\trandom g = randomR (minBound, maxBound) g\n```\n\nYour `rollDice` function then looks so inconspicuous, your opponent might not even notice:\n\n``` haskell\ndata Player = Me | Opponent\n\nrollDice Me = getRandom\nrollDice Opponent = fmap getValue getRandom\n\nhowManySixes :: MonadRandom m => Player -> Int -> m Int\nhowManySixes player nrThrows = do\n\tresults <- replicateM nrThrows (rollDice player)\n\treturn $ length . filter (== Six) $ results\n```\n\nThey might actually think that they are just unlucky:\n\n``` haskell\nλ> howManySixes Me 1000\n170\nλ> howManySixes Opponent 1000\n46\n```\n\nYou can find the source <a href=\"/enum/RandomEnum.hs\" target=\"_blank\">here</a>.\n",
"date": {
"year": "2017",
"month": "April",
"day": "02"
}
}
]