Archives for the month of: March, 2008

Henry just wrote a post I’ve been meaning to write for quite a while. It’s fortunate as his argumentation is much clearer than mine would have been and I pretty much agree with his short list.

  • MIT: minimal, sweet and very permissive, do what the fuck you want, only more politically correct.
  • AL 2.0: BSD only better because more generic and including patent termination.
  • MPL: weak copyleft (or weak viral), way clearer than LGPL and still has a strong supporting community.
  • GPL 3.0: strong copyleft (or stong viral) because there is no other choice.
  • AGPL 3.0: strong copyleft, even hosted.

I would even go as far as arguing that most people who like GPL 2.0 and dislike GPL 3.0 (like Linus) should really be looking at MPL instead.

License proliferation makes the use of any open source software harder. It’s hurting open source because anytime a package is used you have to figure out what the license is and play the compatibility game. Is it compatible with my license? Will it “pollute” it? With just 5 licenses it’s already is a bit of a headache, manageable but sometimes painful. With too many licenses, some more documented than others, it gets close to impossible to release something sane. So choose well and think of your users.

Considering which license to use when you start a new project is really important. It determines where and how your software can be used, how freely and with which restrictions. It’s a balance between protecting your code and maintaining you ownership on one side and making it available with as few strings attached as possible on the other. You can’t achieve both so you have to think of where exactly you stand. Don’t just use the license du jour because that’s what everybody does, all licenses haven’t been created equal and some of them are really clunky.

As a result of your choice, some people who would like to use your software won’t be able to (like Apache if you choose GPL). Is that a problem? As a result of your choice, some people you may not want to give your software for free to, will use it for free (some BigCos if you use MIT or AL 2.0). Is that a problem?

Open source is all about freedom, the one you keep for yourself, the one you give to others, as a gift. Licenses are at the core of this freedom. Pick one carefully.

I’ve been watching the Structure and Interpretation of Computer Programs videos recently while riding the Caltrain and enjoyed it quite a bit. For some reason I can’t quite grasp, I find these fun. Maybe it’s the fact that these are 20 years old now and still terribly relevant (especially for functional programming), maybe it’s the look of the attendance, very eighties, or maybe the obvious delectation Hal Abelson and Gerald Jay Sussman have teaching. Anyways, pretty intesting stuff.

One of the thing they emphasize a lot during their lessons is the blurring line between data structures and functions when programming in a functional style extensively. The Javascript accessors overriding technique in my last post was a pretty good example of it but there’s a much better one in the video: constructing a Pair data structure out of pure nothingness. I’ve adapted it in 3 different functional languages below, just take your pick.

Javascript

js> var Pair = function(a,b) { return function(pick) { return (pick > 0) ? b : a; } };
js> var head = function(p) { return p(0); };
js> var tail = function(p) { return p(1); }
js> head(Pair(3,’b’));
3

Ruby

irb> def make_pair(a,b)
irb>   lambda { |pick| pick > 0 ? b : a }
irb> end
irb> def head(p); p[0]; end
irb> def tail(p); p[1]; end
irb> tail(make_pair(8, :foo))
=> :foo

Arc

arc> (def make_pair (a b) (fn (pick) (if (> pick 0) b a)))
arc> (def head (p) (p 0))
arc> (def tail (p) (p 1))
arc> (tail (make_pair ‘a ‘b))
b

It’s a very good illustration of how to introduce data structures in any functional language. Once you have a pair, you have a list. Once you have a list, you have a hash. I won’t argue that those would probably be a few order of magnitude slower than data structures mapped directly in memory but still, it sort of turns the world upside down. Instead of having objects that are bags of functions, you have functions that operate on something that feels like an object.

The implementation is of course a bit awkward, using this little pick parameter to select the right value in the closure. But that’s not the point, if I were to tell you that I’ve made a Pair API for you with a way to build a pair, get its head and its tail, the way it’s programmed would be irrelevant to you. I can change my implementation anytime without you even noticing. The abstraction is complete.

Photo (and painting) by Rob Lee

Follow

Get every new post delivered to your Inbox.