(elegant coding from a more civilized age)

Lisp++

B.A.Z.N.E.X. - Boston Autonomous Zone Nerd Nexus

| Comments

B.A.Z.N.E.X.: Boston Autonomous Zone Nerd Nexus

The short version is that we’re a self-directed organization focused on the joys of software development, community, and learning.

BAZNEX

Before we get into more details about what we are let’s start with what it is NOT

  • BAZNEX is not a meetup, but we do meet together.
  • BAZNEX is not a forum, but we do discuss.
  • BAZNEX is not a lesson, because there is no one teacher.
  • BAZNEX is not corporate sponsored, because we don’t have ulterior motives of hiring you. We’re here to better ourselves and, ultimately, the world. But who knows who you might meet, and what connections might be born.
  • BAZNEX is not an open source programming club, but we might work on some open source projects.
  • BAZNEX is not a place to teach or be taught, but it is a place to grow together with others, and to teach when called upon to do so.
  • BAZNEX has NO agenda. There are no lectures and no prearranged topics. You come, you meet others, and you join the party. That good vibe you feel here is what we call the Nerd Nexus.
  • BAZNEX has no leader, but for the force of willpower generated through a phenomenon called a Nerd Nexus – that moment with the vibes so delicious, and the love of computer science and software development, as well as the inspired action for the community, and for the history of computing.

Okay, BAZNEX isn’t any of those things. So what IS it??

  • BAZNEX is appreciating and revering the history of our profession.
  • BAZNEX is sharing cool software stuff.
  • BAZNEX is experiencing the greater nerd community of Boston.
  • BAZNEX is pairing together with others to share expertise, and to contribute back to the Open Source community, and the community at large.
  • BAZNEX is about the community of software developers.
  • BAZNEX is about appreciating the venerable greats of our industry and mooching off of their awesomeness by osmosis.
  • BAZNEX is about bringing up novices.
  • Yes. BAZNEX is a software osmosis, free-form, group software block-party.
  • On any given BAZNEX meeting (we call them nexuses) pretty much anything could happen.
  • But you can generally count on working on some code, and learning cool stuff from those you pair up with at the nexus. You are encouraged to write on the wiki what your interests are; that way others who are interested in learning with you can say hello and you may pair together, and vice versa!
  • BAZNEX grows organically; your presence makes you a part of it all, and so your desires matter.

What you can do if you’re interested in joining the Nexus

We’re very much in a primordial state. We have had one small (successful!) gathering of three at the Andala coffee shop in Central Square Cambridge where we discussed why I love index cards, a bit about teaching others programming, took a look at the SeeSaw Clojure Swing-wrapping library, and took time to work on adding a feature to Midje, a Clojure testing/mocking framework.

The current process we’ve done (a total of one time) is to have everyone write down on index cards the different activities they might want to do at that gathering. Then put them all together and we split up into pairs or triples. Last gathering index cards were written such as “ want to look at SeeSaw?”, “talk more about teaching programming”, “fix the code Alex broke in Midje”, “do some remote pairing, or at least learn more about how we could”, “create a Content Management system in Clojure”, “can anyone help me with my 5 minute lightning talk on Clojure I’m doing tomorrow?”

We’re looking into finding larger venues preferably closer to downtown Boston for easier access by all of us, and places that can fit more of us than just a coffee shop can handle. Sprout in Davis Square is going to be our next location to try out on Wednesday Nov 1.

Also, if this all is jiving with you, we’ve got a BAZNEX Google Group we’ve just started, where all future discussion of BAZNEX will transpire.

Please tell anyone you think may be interested. The more the merrier. Any suggestions, offerings, additions, or displays of exuberance, also invited.

A Few Nice Features of Clojure, Part #1: Using Macros to Freeze Time

| Comments

I thought it might be fun to show some of Clojure’s features off by taking a look at how I use some of them in my own project EmailClojMatic. I’ve got 4 features in mind and will show one feature each post.

Problem #1:

We want to unit test a function that depends on the current date.

Solution #1:

Fortunately we are using JodaTime, a great Java date/time library. JodaTime has built in features for setting the ‘now’ time. Let’s use those to create a function to wrap our test code in, that will set the time at a given DateTime.

1
2
3
4
5
6
7
8
9
10
(defn do-at* [date-time f]
  (DateTimeUtils/setCurrentMillisFixed (.getMillis date-time))
  (try
    (f)
    (finally (DateTimeUtils/setCurrentMillisSystem))))

;; you might use this code like this:

(do-at* (DateMidnight. 2000 1 1)
  (fn [] (DateMidnight.))) ;;=> (DateMidnight. 2000 1 1)

If you are like me and you find yourself writing test code using this construct frequently you can use Clojure’s macro functionality to essentially extend the Clojure language to have a new feature for evaluating an expression at a given DateTime. This way we won’t have to always wrap the expression in a function like we are doing in the do-at* function.

Let’s see the macro version that I decided to call do-at, because it is just like the built in Clojure function do except it evaluates at the given time. [It’s probably worth noting that xyz* function with xyz companion macro is a common Clojure idiom. –@darevay]

1
2
3
4
5
6
7
8
9
10
11
(defmacro do-at [date-time & body]
  "like clojure.core.do except evalautes the
  expression at the given time"
  `(do-at* ~date-time
    (fn [] ~@body)))

;; nice. Now we can see the actual code that was hiding
;; behind all of those parens and fn creation:

(do-at (DateMidnight. 2000 1 1)
  (DateMidnight.)) ;;=> (DateMidnight. 2000 1 1)

It’s pretty powerful the way that macros give you the ability to shape your library so that it is free of boiler plate.

Simplicity Is a Prerequisuite for Reliability

| Comments

(This blog post is based on Rich Hickey’s keynote speech at Strange Loop 2011)

Word origins

  • Could we go back to what these words REALLY mean?
  • Simple: sim-plex – one fold/braid
  • Complex: many folds/braids
  • Easy: … lie near

Simple

  • One fold/braidOne roleOne task!One conceptOne dimension
  • But not one instance one operation it’s about lack of interleaving, it’s not cardinality
  • Interleavage is an Objective notion

Easy

  • Near, physically on our own hard drive, in our toolset, IDE, apt get, gem install.
  • Near, to our current understand/skill set familiar – mentally near.
  • We’re generally overly fixated on these two meanings of easy.
  • If you want everything to be familiar, you learn NOTHING.
  • There’s a third meaning of easy:
  • Near, to our capabilities.
  • Easy is RELATIVE – unlike simple

Limits

  • We can only hope to make reliable those things we understand.
  • We can only consider a few things at a time.
  • Intertwined things must be considered together. This is a mental burden and the intertwining tends to grow combinatorially.
  • Complexity undermines understanding.

Simplicity Driven Development

  • If you ignore complexity – you will invariably sloooowwww down over time.
  • If you focus on ease – you will have a fast at start, and slow down every iteration to redo everything.
  • If you focus on simplicity – you will go a bit slower at the start, but then ramp up to a higher steady state of productivity.

What is In Your Toolkit?

  • Complex
  • Simple
  • state, objects, values, methods, functions, namespaces, vars, managed refs, inheritence, switch, matching polymorphism, syntax data, imperative loops, fold set functions, actors queues, ORM declarative data manipulation, conditionals, rules, inconsistency consistency

Complect

archaic word meaning “to braid together” don’t do it complecting things is a source complexity best to avoid in the first place

Compose

  • meaning “to place together”
  • composing simple components is the way we write robust software!
  • We can make simple systems by making them modular.
  • What do we want to make these two parts of code allowed to think about??
  • In other words, program towards abstractions!
  • Don’t be fooled by code organization. Two things can be physically separate, but to change one means you need to change the other – they are complected

State is Never Simple

  • It complects value and time
  • But it is so EASY!
  • It interleaves everything that touches it, directly or indirectly.

Programming Features That Complect

Feature Complects

State everything they touch

Objects state, identity, value

Methods function and state, namespaces

Syntax meaning, order

Inheritance types switching/matching multiple who what pairsvariables value, timeloop, fold what/howactors what to do, who does itORM OMG Simplicity is NOT the same as Easy – Remember that – It is KEY The Simplicity Recipe

You do not need C#/Java/C++. You can make big systems with dramatically simpler tools.

We make hundreds of variations that make it tough to manipulate the essence of this stuff – data. We should use simple data so we can write code to work on the essence of this stuff. Develop sensibilities around entanglement – learn to see the complecting.

Tools for reliability like testing, refactoring, etc are all safety nets that are orthogonal to this problem.

Choose simple constructs over constructs that encourage braided together code.

Simplify the problem space before you start. Simplicity often mean you have more things… it’s not about counting. Reap the benefits!

A Scala Writer Monad

| Comments

In Scala we’re quite familiar with the built in Monads:

  • Option
  • List
  • Either Left Projection
  • Either Right Projection

There are other cool things you can do with the Monad pattern, though, one of which is termed the Writer monad.

“This data type represents logging in a pure functional environment where you maintain compositionality of your code (i.e. no side-effects) and also, brevity of code.” – http://blog.tmorris.net/the-writer-monad-using-scala-example/

Writer Monad 0.1

1
2
3
4
5
6
7
8
9
10
11
12
case class Writer(value: Int, diary: String) {
  def flatMap(f: Int => Writer) = {
      f(value) match {
          case Writer(result, d) => Writer(result, diary + d)
      }
  }
  def map(f: Int => Int) = Writer(f(value), diary)
}
// This enables us to say:
new Writer(2, "").flatMap { new Writer(3, "three") }
                 .flatMap { new Writer(4, "four") }
// => Writer(4, "threefour")

There’s a Problem. It’s not generic. Let’s make the value type generic.

1
2
3
4
5
6
7
8
case class Writer[A](value: A, diary: String) = {
   def flatMap[B](f: A => Writer[B]) = {
       f(value) match {
           case Writer(result, d) => Writer(result, diary + d)
       }
   }
   def map[B](f: A => B]) = Writer(f(value), diary)
}

But it only works with Strings: Introducing the Typeclass pattern

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
case class Writer[A, D](value: A, diary: D)(implicit m: Monoid[D]) {
  def flatMap[B](f: A => Writer2[B, D]) =  f(value) match {
      case Writer(result, d) => Writer(result, m.append(diary, d)
  }
  def map[B](f: A => B) = Writer[B, D](f(value), diary)
}
trait Monoid[T] {
   def zero: T
   def append(a: T, b: T): T
}
object Monoid {
   implicit val StringMonoid = new Monoid[St ring] {
       override def zero = ""
       override def append(s1: String, s2: String) = s1 + s2
   }
}

Our new version still works

1
2
3
4
Writer(5, "").flatMap { num => Writer(num + 3, "added three")
             .flatMap { Writer(_ * 5, "times five")}

// => Writer(40, "added threetimes 5") 

Why didn’t we just extend String with a trait?

Notice we could have implemented this using traits, and specified in the type signature that type D of diary had to extend Monoid. Had we done that, we would have needed to own the String class (which we don’t have access to) so it could extend trait Monoid, or we would have had to extend it manually at run-time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
object Monoid {
 implicit val StringMonoid = new Monoid[String] {
     override def zero = ""
     override def append(s1: String, s2: String) = {
             val  delimiter = if (s1 == zero || s2 == zero) ""
                              else ", "
             s1 + delimiter + s2
     }
 }
}

Writer(5).flatMap { n => Writer(n + 3, added three)
           .flatMap { n => Writer(n * 5, "times five") }
           .flatMap { n => Writer(n + 2, "plusTwo") }
// => Writer(42, "added three, times 5, plus two") 

Watch how using the typeclass pattern made it simple to use other classes as the ‘diary’ for our Writer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
object Monoid {
    implicit val StringBuilderMonoid = new Monoid[StringBuilder] {
        override def zero = new StringBuilder("")
        override def append(sb1: StringBuilder, sb2: StringBuilder) = {
            val  delimiter = if (sb1.toString == "" ||
                                 sb2.toString == "") ""
                             else ", "
            sb1.append(delimiter).append(sb2)
        }
    }
}

Writer(22, new StringBuilder("")).flatMap { n =>
    Writer(n + 2, new StringBuilder("plus two"))
}.flatMap { n =>
    Writer(n * 4, new StringBuilder("times four"))
})

// => Writer(96, StringBuilder("plus two, times four")) 

What we learned

We could get our Writer to work with a 3rd party class without needing to change either the Writer or the StringBuilder code.

This Writer pattern can be used with anything that starts from nothing (zero) and can be built up piece by piece (diary). In essence Writer Monad is a sort of immutable, functional Builder pattern.

We saw that we’re not limited to the monads Scala comes packaged with. We can use our own monads to define computational contexts to suit our code’s unique needs.

Writer Monad Materials