Object Commando languages, development and design

21Mar/100

SICP – Chapter 1

I have began reading through Structure and Interpretation of Computer Programs through a study group (a spawn from the Lambda Lounge). A classic computer science textbook, I've wanted to read it for a while now, and I'm amazed that thus far I have avoided reading it. Maybe because it's older is the reason I missed the SICP cut-off. I have to say, I'm impressed with the pace of the book. It's partially a function of the language, but I really like how the text gets the the bare metal, in that it builds everything from the ground up. Scheme allows it to do this in that many things that are syntax in other languages (like basic arithmetic operations) are not syntax in Scheme. Languages like Java have operations like addition and division built into the syntax of the language. My answers to the exercises in the textbook are here. They are written in Clojure and I've been pretty surprised at how closely Clojure code corresponds with Scheme code.

The Good Stuff

Like I described above, Abelson and Sussman getting to the bare metal in terms of Scheme I think is a real benefit. I'm sure it took a lot of restraint to not use the fancy macros or functions early on and start small. I really liked the way that they described the benefits of tail recursion. I have been asked on several occasions to give such a description. I have to say their approach using visuals is much better than mine. I will definitely be borrowing theirs when asked that question in the future. Building on that I though that the exercises that were in 1.2 did a good job of covering how to go about making something tail recursive. I think their coverage of higher order functions was thorough and look forward to them revisiting the flexibility of this in the coming chapters.

The Bad Stuff

I thought their coverage of recurrences and asymptotic growth was particularly bad. I think recurrences are a very tough topic and section 1.22 barely skimmed the surface enough to give an exercise like 1.13. Maybe the students at MIT had a prerequisite that covered that or something, but I spent many hours in grad school trying to understand recurrences and I know I would have been drowning with such a light coverage of the topic. Maybe asymptotic growth will be covered in depth in another section, but I though that just skimmed the surface as well. The only other negative comment I have is that the amount of math makes the book less approachable. I know why they did it, it's the only base that could be built upon easily for them to use their bare metal sort of approach. I also don't think you need a very extensive math background to read it, they don't come in expecting a whole lot. But math is intimidating to many people and just having something that smells and looks like hard math will turn people away.

Conclusion

In conclusion, chapter 1 from SICP has been worth the time and definitely a good start for a foundation in computer science. I think that the first chapter is a good read for any software developer. I'm looking forward to continuing with the rest of the book.

Filed under: Clojure, Languages No Comments
14Mar/100

Worse is Better and Clojure

I've been writing code in Clojure now for a few weeks and I'm really enjoying the simplicity and power of the language. I think that the progress being made right now in the Clojure community is great and that there are definitely good things to come. I couldn't help but thinking back to the Worse is Better series of papers the first week or so I was learning the language. For those that haven't read the paper, I'd highly recommend it, along with the rebuttal found here and another here. I wrote a blog entry about it about 3 or 4 years ago, but unfortunately it looks like it's been taken down. It was on a company blog and it looks like it's been replaced with another blog system.

I remember reading the article for the first time and realizing how right Richard Gabriel was and how I wanted him to be wrong. The realization that the best solution to the problem isn't always the right solution floored me. As someone who enjoys a hard problem and tries hard to come up with the best solution I can to problems, the C analogy was very thought provoking. This brings me to Clojure. Clojure seems like it might well be the compromise talked about in Worse is Better, yet with enough of the essence of Lisp to still have the right solution. There's no doubt that the Clojure folks have had to make some compromises to fit into the mould of the JVM. An example is Tail Recursion in Clojure, implemented via the recur special form. As a user of the language, I obviously would prefer tail calls to just work, without me having to tell it. That is a hard problem in the context of the JVM, so I understand the decision. This felt to me like the PC loser-ing problem In the context of Worse is Better. Although the right decision might be to crack the hard problem or worse yet, wait for the tail calls on the JVM, this seems like a small trade-off that is still workable.

Another good call by the Clojure folks, in my opinion, is the Java integration. Below is a quote from Worse is Better on integration:

In the worse-is-better world, integration is linking your .o files together, freely intercalling functions, and using the same basic data representations. You don’t have a foreign loader, you don’t coerce types across function-call boundaries, you don’t make one language dominant, and you don’t make the woes of your implementation technology impact the entire system.

Sound familiar? Not only is calling Java from Clojure seamless, there's actually syntax sugar (through macros) to make calling Java code easier. No need to convert everything over to a specific Clojure object format or anything like that, it just works. You might have to make a Java collection seq-able or something similar, but it's pretty minimal fuss. There are also facilities for Clojure code to create Java proxies and Java interfaces (though I've not used them). This allows Java code to integrate with Clojure code. It seems to me that the Java integration in Clojure very much fits with the quote from Richard Gabriel. This tight integration I believe will be the path in to Clojure for many developers.

Filed under: Clojure, Languages No Comments
7Mar/100

Emacs Talk Online

A video of the talk I gave at Lambda Lounge last Thursday can be found here.

Filed under: Languages No Comments
7Mar/102

Design By Contract with Clojure

I just learned about the design by contract features of Clojure, and I'm impressed by the simplicity. It's implemented using regular Clojure metadata (i.e. no new language constructs to support this). {Small correction to this previous statement. It looks like metadata, and can be read as metadata, but is actually compiled into the function (i.e. can't be modified at runtime). Thanks for the correction Alex.} Several times I desired DbC in Java and have tried some of the libraries written for Java. The Java ones were generally built on comments or annotations. Bottom line is that they just didn't feel like they seamlessly integrated into the language, and they seemed to have a short shelf life. By short shelf life, I mean there were a lot of proof of concepts and abandoned projects, but none that were viable over the long term.

DbC in Clojure

Pretty slick how it's implemented in Clojure. First we take a normal function definition;

(defn pos-add [& args]
(apply + args))

It doesn't really do anything interesting, just delegates to the plus operator, but should only be used for positive integers. If you've not seen the & symbol, it just collects all function arguments in as a sequence. So a precondition of this function is that all arguments passed into pos-add should be zero or greater. To add this, the code looks like:

(defn pos-add [& args]
{:pre [(not-any? neg? args)]
:post [(<= 0 %)]}
(apply + args))

So there are two new pieces, a :pre that takes expressions, all of the expressions must return true for the pre-condition to pass. In the example above, there is only one expression, and it ensures that there are not-any negative numbers in the argument parameters. It also insures the the result is 0 or greater. The post condition isn't of much value here, but I added it to demonstrate where it would go. Calling the function is the same as calling any other function, but if the pre/post conditions are not met, an AssertionError is thrown. Below are some basic tests for the function:

(is (= 10 (pos-add 1 2 3 4)))
(is (zero? (pos-add 0 0 0 0)))
(is (= 5 (pos-add 1 1 2 1)))
(is (thrown? AssertionError (pos-add 1 2 3 -4)))

What led me to Clojure's DbC features was reading On Clojure and there was a proposal for a new DbC syntax. I like DbC in the original style, but I think that the one at On Clojure has some additional benefits because it can provide some hints as to what types are expected in the function. If you read Smalltalk Best Practice Patterns by Kent Beck, he recommends to name the variables after the type that is expected. So if the method is findByName, the parameter would be aString to give the caller a hint as to what is expected. What was detailed in the On Clojure blog not only provided hints about the type but also would also let you know acceptable values just by looking at the function declaration and the accepted parameters.

I would like to see the pre/post condition information somehow worked into the documentation generated by Clojure. Seems like it would be a very useful feature for callers of APIs.

Filed under: Clojure, Languages 2 Comments
3Mar/100

Emacs Talk at Lambda Lounge

I'm giving a talk tomorrow at the Lambda Lounge on Emacs. I'm planning on spending about half the talk on some Emacs conceptual basics. When it comes to the basics I'm going to try and avoid the "this key does this" and "that key does that". I think going over cursor movements etc will just be lost. If you're truely new to Emacs, you'll need to go through the Emacs Tutorial (which comes with Emacs, there's a link to it on startup) to get the basic movements down. Instead I'm planning to go over the concepts of buffers in Emacs, the modeline, the minibuffer, the .emacs file etc. I'm also planning on spending a decent amount of time going over the help system, both the info system and the built-in Elisp documentation. Then I'm planning on going over some Emacs Lisp basics, Eshell, org-mode and a little on Dired. Then I'm planning on doing some development demos, specifically highlighting REPL environment integration into Emacs with SLIME, Tuareg Mode and maybe some Ruby.

Filed under: Languages No Comments