LuminousMonkey

Style

I don't think anyone would doubt, that authors have a style. For example, if you started reading a story by HP Lovecraft, and were familar with his works, you would probably pick up the little nuances that make it feel like Lovecraft. Be it the flowery language, the themes of dreams or indescribable terrors that send you mad, a Lovecraft story has a taste.

Is there a similar thing with code? Admittedly code is a bit more restrictive in some ways than natural language, given that the intended target has no intelligence at all. But, could you look at code, and determine who wrote it? Can you get the same flavour? I'm not so sure.

But, this leads me to another thought, really not my thought, but one from my reading of: The Design of Design. In particular chapter 12, "Esthetics and Style in Technical Design". The last point the chapter makes is that studying the style of others will help, the same that an author reading a large number of other works will help with their own writing.

So, to this end, I think I will try and find code, and analyse it's style. This is just going to be my own amateur musings and not worth much.

What is a Monad like a writing desk?

I have seen this talk, however, given that someone I know was recently asked about monads in an interview, I thought it best to link to it here so I can find it later.

What is a Monad like a writing desk?

Even if you're not interested in monads, you should watch this talk, because it tells a story. Talks are not about dense information, but are about getting people interested in the subject.

What follows are my own notes, for no other reason, but for me to follow along and try to understand.

Monadic return operation:

(defn return [v] (fn [] v))

You define a function that takes a value and wraps that value in a function. When that function is executed, it returns the value.

((return "jelly")) ;=> "jelly"

This is not a monadic return, because the value is not wrapped up in a function:

(defn return [v] v)

(return "jelly") ;=> jelly

Monadic bind operation:

(defn bind [mv f] (f (mv)))

(defn with-toast [s]
  (return (str "toast & " s)))

(bind (return "jelly") with-toast)
;=> container/monadic value (Our value wrapped in a function)

((bind (return "jelly") with-toast))
;=> "toast & jelly"

Bind will take a monadic value, and a function, calling the monadic value so it will get the actual value, and pass that in as a parameter. The function passed into bind must be a monadic value (wrapped in a function.)

Ok, I follow this, but… why?

Can you write a function that makes you grow and returns a monadic value. Sure:

(return "me")

(defn grow [s]
  (return (str s (last s))))

(grow "me") ;=> monadic value

((grow "me")) ;=> "mee"

Using bind to grow:

(defn m-grow [mv]
  (bind mv grow))

((m-grow (return "me"))) ;=> "mee"

Ok, and you can chain them… but what is the purpose? What is the benefit? Handling of nil. With modifications to bind, you can have monadic operations occur with nil, that don't blow up. Instead it could pass though a call chain, and return nil wrapped in a monadic value.

Monads are like astronauts, monads are like burritos. Yeah, what the hell are they on about?

Updating of return and bind, so they can include state:

;; Will now return a monadic value that needs a parameter.
(defn return [v]
  (fn [s] [v s]))

;; Same here
(defn bind [mv f]
  (fn [s]
    (let [[v sn] (mv s)]
      ((f v) sn))))

There was a tea function, which I haven't written down, but it's used again without modification here.

(defn m-tea [mv name]
  (bind mv (fn [v]
             (return (str v " and " name)))))

((-> (return "me") (m-tea "you")) 10)
;=> ["me and you" 10]

So, we can track state.

(defn take-sugar [mv]
  (bind mv (fn [v]
             (fn [s] [v (sec s)]))))

Seems to be all about using closures for state and composing operations?

Identity monad: return, bind.

Maybe monad: The handling of nil.

(defn bind [mv f]
  (let [v (mv)]
    (if (nil? v)
      (return nil)
      (f v))))

State monad: Tea.

Things in common:

Left Unit - "return" acts as a neutral element of bind.

(bind (return v) f) ; same as (f v)

(defn return [v] (fn [] v))
(defn bind [mv f] (f (mv)))

(defn grow [s] (return (str s (str (last s)))))

((bind (return "me") "grow")) ;=> "mee"
((grow "me"))                 ;=> "mee"

Right Unit - "return" acts as a neutral element of bind.

(bind mv return) ; same as mv

(defn return [v] (fn [] v))
(defn bind [mv f] (f (mv)))

(defn grow [s] (return (str s (str (last s)))))

((bind (return "me") return)) ;=> "me"
((return "me"))               ;=> "me"

Associative - Binding two functions in succession is the same as binding one function that can be determined from them.

(bind (bind mv f) g) ;same as (bind mv (fn [x] (bind (f x) g)))

(defn return [v] (fn [] v))
(defn bind [mv f] (f (mv)))

(defn grow [s] (return (str s (str (last s)))))

((bind (bind (return "me") grow) grow)) ;=> "meee"
((bind (return "me")
       (fn [v] (bind (grow v) grow))))  ;=> "meee"

Monads are all about keeping inside functions pure and having messy stuff on the outside.

Trying Org Mode

Apparently the static site generator I use supports Org Mode. So, this is a test post.

(let [fish (+ 1 2 3)]
  (println fish))

#"Test"

(+ 1 2 3)

(defproject artemis "0.1.0-SNAPSHOT"
  :description "Artemis stores the data for DirectGPS and tracks the
  GPS units"
  :url "https://directcommunications.kilnhg.com/Code/Artemis"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [compojure "1.2.0"]
                 [cheshire "5.3.1"]
                 [ring/ring "1.3.1"]
                 [ring/ring-json "0.3.1"]
                 [http-kit "2.1.19"]
                 [org.clojure/data.json "0.2.5"]
                 [camel-snake-kebab "0.2.4"]
                 [prismatic/schema "0.3.0"]
                 [com.fasterxml.jackson.core/jackson-core "2.4.3"]
                 [org.clojure/tools.logging "0.3.1"]
                 [log4j "1.2.17" :exclusions [javax.mail/mail
                                              javax.jms/jms
                                              com.sun.jdmk/jmxtools
                                              com.sun.jmx/jmxri]]
                 [org.slf4j/slf4j-log4j12 "1.7.5"]
                 [clojurewerkz/propertied "1.2.0"]
                 [com.datomic/datomic-pro "0.9.4956" :exclusions
                  [org.slf4j/slf4j-nop org.slf4j/log4j-over-slf4j]]
                 [crypto-random "1.2.0"]
                 [clj-oauth-server "1.0.5"]]
  :plugins [[lein-ring "0.8.5"]]
  :ring {:init artemis.config/load-config
         :handler artemis.routes/app-routes}
  :profiles {:dev
             {:dependencies [[midje "1.6.3"]
                             [ring-mock "0.1.5"]
                             [org.clojure/test.check "0.5.9"]
                             [org.clojure/tools.namespace "0.2.7"]]
              :source-paths ["dev"]}}
  :repositories {"my.datomic.com" {:url "https://my.datomic.com/repo"
                                   :creds :gpg}})
1: (save-excursion
2:   (goto-char(point-min)))

In line 1 we remember the current position. Line 2 jumps to point-min.

This should have some math…

Foo bar \(f(x) = \frac{x^3}{n}\) chicken checken.

\begin{equation} x=\sqrt{b} \end{equation}

If \(a^2=b\) and \( b=2 \), then the solution must be either $$ a=+\sqrt{2} $$ or \[ a=-\sqrt{2} \].

3D Robots

There are some units, at Curtin University, where you have to do a project. This is not an unsual prospect, lecturers have been using students for such things all the time at pretty much any University. My team is no different, we have been tasked, essentially, to develop from scratch the Open Academic Robot Kit. Now, I've sounded a little cynical, and I probably am a little, but it's actually a pretty neat project. To be sour about it, makes you sound like the kind of person who would be sour against more money being given to hospitals.

The basic idea is allow people to create robots, robots that they can 3D print, and construct from a few parts. The type of people that are targeted for this, are people who wouldn't normally have the skills necessary in making these robots. Physical designs can be downloaded, modified, and constructed into whatever sort of robot that people would want to make. But the primary goal would be to allow, say, high school students to put these together and experiment. You know, get kids interested in science! I'm sounding a little cynical again, I'm not, I'm just trying my own poor brand of humour.

Physical designs are the easy part, our particular trick, is to come up with the software they can use for these robots. This is a big problem, not the technical issues, those are easy to tackle, no, the problem here is the abstraction. Computers are easy, they follow logical rules, and (if you have the right access to the source code, or other way of seeing what is going on, something you can eventually get right). But abstractions, they involve humans, human brains which are all different, and think about things in different ways. This is also a problem domain that none of our team have experience with, so we don't even know the right approach for an abstraction that will make sense.

So, future blog posts will probably be documenting my descent into madness, fair warning.

Should have used CVS

It seems that I lost all my old blog data, I thought I had saved the SQL database (I was using Wordpress previously). But I can't find it, whoops, that's a few years of blogging lost.

Maybe I'll check the Internet Wayback Machine, and recover anything that seems interesting from there.