# public twopoint718 /twopoint718.github.com

### Subversion checkout URL

You can clone with HTTPS or Subversion.

publish

 `@@ -4,8 +4,203 @@` 4 4 ` sencjw.com - rss feed` 5 5 ` recent blog posts from sencjw.com` 6 6 ` http://sencjw.com/blog.html` 7 `-Sat, 05 May 2012 18:56:54 +0000` 8 `-Sat, 05 May 2012 18:56:54 +0000` 7 `+Tue, 04 Sep 2012 12:31:28 +0000` 8 `+Tue, 04 Sep 2012 12:31:28 +0000` 9 `+` 10 `+ <![CDATA[the dipert problem]]>` 11 `+ point-free.` 16 `+answer must be a function value! #clojure"` 17 `+` 18 `+In case your office has banned 4clojure for being a huge distraction,` 19 `+I'll post the problem here:` 20 `+` 21 `+ (= 256 ((__ 2) 16),` 22 `+ ((__ 8) 2))` 23 `+` 24 `+ (= [1 8 27 64] (map (__ 3) [1 2 3 4]))` 25 `+` 26 `+ (= [1 2 4 8 16] (map #((__ %) 2) [0 1 2 3 4]))` 27 `+` 28 `+In problem 107, your challenge is to write a function that satisfies` 29 `+all of these (it could be dropped in place of the `__`s above). I will` 30 `+let you go take a crack at solving it. Because up next is some serious` 31 `+spoiler action.` 32 `+` 33 `+Got your solution? I came up with this:` 34 `+` 35 `+ (fn [x] (fn [y] (reduce * (repeat x y))))` 36 `+` 37 `+or (what I was really doing) in Haskell:` 38 `+` 39 `+ f :: Int -> Int -> Int` 40 `+ f x y = foldl1 (*) (replicate x y)` 41 `+` 42 `+We are doing manual exponentiation: "make a list of *y*s that is *x* in` 43 `+length (e.g. `replicate 8 2 == [2, 2, 2, 2, 2, 2, 2, 2]`). Then you` 44 `+just run multiplication through the list:` 45 `+` 46 `+ foldl1 (*) [2,2,2,2,2,2,2,2] == 2 * 2 * 2 * ... 2 == 256` 47 `+` 48 `+Now comes the "Dipert Problem." He has told us that we have to rewrite` 49 `+the solution (or any solution) using so-called *point-free* style. I'm` 50 `+sure that there's more to it, but essentially that means that *we are` 51 `+not allowed to mention any variables!* When I first heard about this` 52 `+style, it sounded impossible! The cool thing is that it *isn't* and it` 53 `+leads to some massively simple code. Let's try it out.` 54 `+` 55 `+I'm going to start with my solution above called `f` and then write` 56 `+some successive versions of it, each time, I'll remove a variable and` 57 `+call it the "next" version: `f1`, `f2`, okay? Cool.` 58 `+` 59 `+ f, f1, f2 :: Int -> Int -> Int` 60 `+ f x y = foldl1 (*) (replicate x y)` 61 `+` 62 `+For the first transformation, we need to get rid of the `y` that's` 63 `+hanging off the end of both sides of our equation. We'll need to juggle` 64 `+the innards a bit because here is what the types look like so far:` 65 `+` 66 `+ foldl1 (*) :: [Int] -> Int` 67 `+ replicate x y :: Int -> a -> [a]` 68 `+` 69 `+`replicate` takes two arguments and then produces a list that the` 70 `+`foldl1 (*)` wants to consume. The trouble is, and what tripped me up a` 71 `+bunch, is that I can't just do this:` 72 `+` 73 `+ foldl1 (*) . replicate` 74 `+` 75 `+Wah, wah (sad trombone). GHCI tells me:` 76 `+` 77 `+ Expected type: Int -> [c0]` 78 `+ Actual type: Int -> a0 -> [a0]` 79 `+` 80 `+Okay, that makes sense, for the fold and replicate to "line up" for` 81 `+composition, replicate has to take one argument then produce a list.` 82 `+The crux is that composition (the "dot" or period in the code) only` 83 `+works for single-argument-functons:` 84 `+` 85 `+ (.) :: (b -> c) -> (a -> b) -> a -> c` 86 `+` 87 `+This is a little pipeline, but reversed because that's how mathematics` 88 `+does it. It says "the right-side function takes an *a* and gives a *b*,` 89 `+and the left-side function expects a *b* and gives a *c*; now you can` 90 `+stitch them together and have a function that *skips* the *b* and` 91 `+takes you right from *a* to *c*." But we have a function that looks like:` 92 `+` 93 `+ (a -> b -> c)` 94 `+` 95 `+on the right-hand side; it won't work. how do we convert a `(a -> b ->` 96 `+c)` to a `(a -> (b -> c))`? This way:` 97 `+` 98 `+ {-` 99 `+ f x y = foldl1 (*) ((replicate x) y)` 100 `+ f x y = (foldl1 (*) . (replicate x)) y` 101 `+ -}` 102 `+ f1 x = foldl1 (*) . (replicate x)` 103 `+` 104 `+*Note:* the first two lines are commented in case you are cut-n-pasting` 105 `+along. The first line just puts parenthesis in where they really are in` 106 `+haskell. Each time you see a function of two arguments, it *is really*` 107 `+a function which takes one argument and returns a function that expects` 108 `+the second argument! This weird but remarkable fact of haskell is` 109 `+called [currying](http://www.haskell.org/haskellwiki/Currying).` 110 `+` 111 `+Now, on to the second line, we see that we have the right types! (I am` 112 `+cheating a bit on types, if you like, you can define `rep` which *just*` 113 `+uses `Int`s)` 114 `+` 115 `+ replicate x :: Int -> [Int] -- cheating: where 'x' is a specific int` 116 `+ foldl1 (*) :: [Int] -> Int` 117 `+` 118 `+ foldl1 (*) . replicate x :: Int -> Int` 119 `+` 120 `+And that brings us to `f1`! We used grouping and composition to move` 121 `+the `y` outside the computation and then we dropped it from both sides.` 122 `+` 123 `+Next we'll tackle the x:` 124 `+` 125 `+ {-` 126 `+ f x = (foldl1 (*) .) (replicate x)` 127 `+ f x = ((foldl1 (*) .) . replicate) x` 128 `+ -}` 129 `+ f2 = (foldl1 (*) .) . replicate` 130 `+` 131 `+It may look different, but the same thing is going on. We can group the` 132 `+composition with the fold without changing anything. This is just like` 133 `+doing:` 134 `+` 135 `+ 3 + 4 == (3 +) 4` 136 `+` 137 `+Next we do that same trick again where we can now compose the inner` 138 `+functions because the types line up (again, I'm simplifying types a` 139 `+bit):` 140 `+` 141 `+ ((foldl1 (*) .) .) :: (a -> b -> [c]) -> a -> b -> c` 142 `+` 143 `+it looks a bit hairy, but in our case, it is just what we want! If I` 144 `+fill in the actual types we'll be using, it becomes clearer:` 145 `+` 146 `+ ((foldl1 (*) .) .) :: (Int -> Int -> [Int]) -> Int -> Int -> Int` 147 `+` 148 `+Booyah! This contraption takes a *function* of two `Ints` that produces` 149 `+a list of ints, `[Int]`. Well, that's just what `replicate` is! So if` 150 `+we then feed in replicate:` 151 `+` 152 `+ (foldl1 (*) .) . replicate :: Int -> Int -> Int` 153 `+` 154 `+And that's it, we have a point-free function that takes two `Int`s and` 155 `+returns an `Int`. And so that's our last, and final function:` 156 `+` 157 `+ f2 = (foldl1 (*) .) . replicate` 158 `+` 159 `+In general, and I don't know a term for this, but the operation of` 160 `+successive function composition lets us compose higher and higher arity` 161 `+functions together. Here's a dumb example using my little point-free `succ`` 162 `+function:` 163 `+` 164 `+ g :: Int -> Int` 165 `+ g = (+1)` 166 `+ (g .) :: (a -> Int) -> a -> Int` 167 `+ (g .) .) :: (a -> b -> Int) -> a -> b -> Int` 168 `+ (g .) .) .) :: (a -> b -> c -> Int) -> a -> b -> c -> Int` 169 `+` 170 `+Clear pattern. I kinda think of this as saying something like "please` 171 `+give me a function which *eventually* promises to give me what I want."` 172 `+The *eventually* part is essentially "after you've collected all the` 173 `+stuff you need." It would be trivially satisfied by some function that` 174 `+ignores its args and returns a constant:` 175 `+` 176 `+ (((g .) .) .) (\x y z -> 1) 4 5 6 == 2` 177 `+` 178 `+Remembering that `g` just increments, the x y z are *totally ignored*.` 179 `+The function supplied to the multiply-composed `g` is like some kind of` 180 `+integer "pre-processor"; the *x*, *y* and *z* can be whatever you need` 181 `+to do to figure out how to give g an integer. Or at least that's how` 182 `+I'm thinking of it.` 183 `+` 184 `+I had a lot of fun trying to figure this out!` 185 `+]]>` 186 `+ blog.html#2012-09-03` 187 `+ 1445c3b04654edf2a94a8501c8313a22c513d0f9` 188 `+ Mon, 03 Sep 2012 00:00:00 +0000` 189 `+` 190 `+` 191 `+ <![CDATA[my "transparent web" talk]]>` 192 `+ ` 193 `+` 194 `+Without much ado at all, here's my talk. I'm covering the *real*` 195 `+basics of using both [Ur/Web](http://www.impredicative.com/ur/)` 196 `+and [Opa](http://opalang.org/). I create a basic "Hello world"` 197 `+page in each and then I go on to write a little "comments"` 198 `+system.` 199 `+]]>` 200 `+ blog.html#2012-08-22` 201 `+ b42bab6db5d8328b7e335df29236c08c97fef9d6` 202 `+ Wed, 22 Aug 2012 00:00:00 +0000` 203 `+` 9 204 ` ` 10 205 ` <![CDATA[my gpl talk]]>` 11 206 `