Friday, October 27, 2006

Sausage and Egg Burrito

Philip Wadler succeeded with the impossible, he made me by another Java book: Java Generics The talk was a historic talk about how Haskell came about and how the ideas from Haskell where later put into Java Generics. The highlight was when Philip Wadler described how “this is a case for lambda” and ripped of his shirt and showed his superman costume with a lambda instead of an S. The same techniques have also been put into links, a language for creating multi-tier web applications.

The onward track presented two papers: The Commensalistic Software System was a first try of implementing Dick Gabriels and Ron Goldmans Conscientious System_. This paper deals with Self-Healing and Self-Protection from Autonomic Computing.

Collaborative Diffusion: Programming Antiobjects was about reversing the responsibility between an object and its environment by letting the environment do things that are usually done by the object. Diffusion means spontaneous spreading. In this context it uses a function to calculate the relation between objects.

Martin Rinard talked of Minimizing Understanding in the Construction and Maintenance of Software Systems. This was probably the best presentation of the week. Martin said that there are three methods of reasoning about computer systems: Rationalism, empiricism, and cluelessness. Contrary to what you may think Martin suggested that selective cluelessness is the way to go. The reason for this is that we are always working at the edge of our cognitive understanding and if we want to build more complicated things we need to let go of our need of understanding everything. The common approach of searching for truth, elegance and understanding is to hard for the common programmer. The simple fact is that: Nobody understands a whole system! The way to get things done is by brute force instead of elegance because elegance takes to long. We have to plan to live with errors. Programs need to be acceptable not correct.

Martin and his team has implemented a compiler that ignores addressing errors, stops memory leaks by cyclic allocation and removes infinite loops by cutting them off after a specified number of iterations. They tested the compiler on Apache, sendmail, etc and they worked better than they did before without any noticeable errors. We need to give up correctness for robustness! Martin even went so far as to say that if a system must stay alive we should wrap all out call in try-catch-ignore clauses.

Wednesday, October 25, 2006

Mount Hood Skillet

Eggs, onion, sausage, bacon, peppers, jack-cheese and cilantro is a very tasty breakfast.

Dr. Guy L. Steele Jr. presented his new programming language Fortress. Is is loosely based on Fortran in that it is intended as a mathematical language. It is created with an intent of doing for Fortran what Java did for C, increase programmer productivity! The language is parallel by default but you can easily create sequential constructs. The language is created with a minimalist approach and it has a minimal kernel explicitly created for allowing you to create powerful libraries that blend in with the language. Fortress has explicit support for version control to allow early design mistakes to be corrected.

The language makes full use of unicode allowing you to use any mathematical notation that is appropriate. A wiki-like markup is also supported if you are restricted to ascii input. This syntax is however just a view of the actual program representation. The language has stole features from multiple languages. The type system is based on Traits which is basically multiple inheritance through the use of mix-ins as in Ruby. Everything, including primitives, is first-class in the language. The language has stolen both type inference and monads from Haskell. The language has also stolen contracts from Eiffel. Apart from contracts special constraints are also supported. Tests may be included with the code that make sure that the code conforms to the constraints.

Fortress supports operator overloading, but discipline is encouraged since they do not want the overloading hell that C++ has. Much of the parallelism is achieved by generators and reducers.

Intentional Software and Charles Simonyi are creating a Language Workbench that will allow programmers and domain experts to create DSL that can be used by the domain experts to describe their knowledge as code. The programmer will then write code generators that will convert the DSL into source code that can be compiled and run. The DSL is represented as an internal structure that may be viewed and edited in many different notations. Examples of notations are: Sun Coding Standard, Mathematical, Spreadsheets and BNF. I like the approach but I have no idea when these tools will become available to us as programmers.

Pegasus: First Steps Towards a Naturalistic Programming Language want to allow programming in natural language to allow you to program in different languages. Like Intentional Software, they are using an internal structure to represent the program. Their approach seems to be pretty far from reality though.

Joshua Bloch talked about API design. It was a good talk but he didn’t mention anything new. A good API should be:
  • easy to learn
  • easy to use
  • hard to misuse
  • easy to read (code that is written to it)
  • easy to evolve
  • appropriate to audience
A good API should be:
  • as small as possible
  • unaffected by implementation details
  • well documented, class – what does instance represent, method – pre/post-conditions and side-effects, parameters – units, form, ownership.
  • concise, the client should not have to do anything the API can do.
  • as immutable as possible.

Panel: Aspects and/versus Modularity raised the issue of DRY vs clear semantics. It made me more convinced that AOP is right. I’ll start using it as soon as possible!

Country Breakfast

The morning started with an invited speaker: Brenda Laurel who was speaking of how to ubiquitous distributed computing to get in more contact with nature. Interesting quotes where Look for the Void, and Look where nobody is doing anything. Interesting thoughts!

After the break, Dick Gabriel and Ron Goldman, talked about Conscientious Software. Dick Gabriel is a big man in the OOPSLA community and he wrote an article many year ago called Lisp: Good News, Bad News, How to Win Big, which I just happened to read on the way over here! In it he explained a philosophy called Worse is Better. Very interesting!

The presentation was a mix of biology, music, city planning and design. A very thought provocative presentation that succeeded in making me think about the inherent problems with complex programming. The paper that the presentation is related to is about software that need to be aware of it’s environment and of itself.

The afternoon I started with Framework and Tools which contained three research papers:

A Framework for Implementing Pluggable Type Systems was about creating a new annotation based type systems for Java that would allow you to specify more specific types such as @NonNull and @ReadOnly

Design Fragments Make Using Frameworks Easier. The reason for code fragments is that programmers copy and paste code and many things may go wrong. The code may be wrong to start out with or the context may not be the same as the one it will be reused in. One good idea that was presented was to have a repository of code fragments index by name and context. However, the idea of letting programmers reuse code fragments by allowing them to bind certain variables in a code fragment does not seem to be a usable way to work to me. I would prefer to solve the same problem with macros and multiple inheritance.

JTL – The Java Tools Language is basically a query language for posing structured queries of code. It is to be used by tools such as IDE’s and as an aspect query language to find join-points. I don’t think it will be used in practice.

In the late afternoon I watched a panel about Ultra Large Scale Systems with, Steven Fraser, Gregor Kiczales, Ricardo Lopez, Peter G. Neumann, Linda Northrop, Martin Rinard, Douglas Schmidt, and Kevin Sullivan.

The solution to ULS is not about formal specification but more about creating an environment that will allow heterogeneous systems to communicate. Conways Law states Any piece of software reflects the organizational structure that produced it. Two software modules A and B cannot interface correctly with each other unless the designer and implementer of A communicates with the designer and implementer of B. and is a real problem in ULS design since there are too many people involved to allow efficient communication. There also seems to be a need for new abstractions but nobody knows what this abstraction should be. Overall, there seems to be a huge problem in this area of computing.

Tuesday, October 24, 2006

Sausages, Eggs and Biscuits

To my disappointment the Monday tutorial on Dynamic Programming at the Model Level was no longer on the program. I have contacted the presenters to find out why…

Instead I went to Refactoring Databases : Evolutionary Database Design with Scott Ambler and Pramod Sadalage and it was quite good but there was too much agile propaganda.

Data is important and since it is it should not be treated as a second class citizen, but should be included in the normal development and refactoring process. The current state in the database world is not good. There are no tests and no evolutionary process of caring for the data.

The main issue of evolutionary database design is to let every developer have his own database allowing him to make changes without disturbing the flow of everyone else. Scripts to setup the database and populate it with with base data should be available for every developer. These scripts are the database schema and should be updated and versions as development goes along. An article by Martin Fowler discussed this issue about three years ago.

While updating the database scripts migration scripts should also be added to enable transitions from one version of the database to another. Tools for simplifying migrations are: MIGRATEdb and Sundog Refactoring Tool. The migration scripts should be checked into the repository along with the code changes and be run by the continuous integration tool.

For migrating production databases a strategy of adding additional columns and tables for a transitory period should be employed. The redundant data should be kept in sync by database triggers. After the transition period has past the redundant columns should be removed.

The afternoon tutorial was Concurrent Object-Oriented Programming for Modern Architectures. It is about a second generation OO language called X10. It is a new language but it reuses most of the Java language to facilitate the transition from Java and to use some of the advantages of Java. The language is designed to perform well on clusters and parallel hardware. X10 takes Java and remove threading and dynamic class loading and adds asynchronous constructs:
  • async stmt – runs stmt asynchronously.
  • finish stmt – waits for statements started by stmt.
  • foreach stmt – runs stmt in different threads.
  • atomic stmt – performs stmt inside a transaction.

X10 uses a global address space where object reside in places that never move. The places may reside locally or globally.

I ended the day with “Data Refactoring for Amateurs” by Avi Bryant creator of the continuation based web framework for Smalltalk. Avi had a number of refactorings that end users are in need of doing while working in a spreadsheet like environment: They are: Assign Type, Limit Options, Extract Table, Move field to related table, Merge fields and Invert relation.

Monday, October 23, 2006

Grand American Breakfast

Eggs, bacon, hash-browns and country sausages is another great way to start a day.

The PLoP continues sunday morning with patterns for Extensible Program Design. The patterns are about efficiently representing code for fast browsing in an IDE. These pattern are very interesting and relate Eclipse and IntelliJ as well as true code browsers such as Squeak.

A Writers Workshop consists of eight parts:
  1. The author describes what parts he wants the review to focus on.
  2. The author reads a selected part of the pattern.
  3. The author becomes a “fly on the wall”. He can listen but not participate.
  4. The reviewing members summarizes the pattern to make sure everyone has the same understanding of the pattern.
  5. The praise section is the part where all positive aspects of the paper are discussed.
  6. The improvement suggestion section is the part where all the negative critique is discussed in a positive way to help the authors improve the paper.
  7. The author is let back in to ask clarifying questions, NOT to explain himself.
  8. The author in applauded for having the courage to be scrutinized.

The afternoon contains patterns for Device Drivers and patterns for Error Containment. The device driver patterns were nothing special but the error containment patterns by Bob Hammer were really interesting. The patterns reviewed were: Error Containment Boundary and Marked Data, but they were just two patterns from a larger collection about error containment. A lot of wisdom here. I’m looking forward to seeing the full collection in the future.

Sunday, October 22, 2006

Mexican Burrito Breakfast

A filling breakfast with fried potatos and a burrito filled with scrambled eggs, peppers, onion and spicy meat.

Pattern Languages of Programming (PLoP) with Ward Cunningham, Guy Steele, Ralph Johnson, Linda Rising, ... We sat in a room and talked about patterns that people had sent in, giving emphasis to what was good and what could be improved. A great way to learn new things. The first pattern, Mutator, was a non-pattern that could be replaced by Iterator. But the other patterns about documenting frameworks where quite interesting. The discussion gave more than the patterns themselves though. Definitely worth looking into.

Friday, October 20, 2006

OOPSLA Yiiiihaaa!!!

I’m finally going to OOPSLA. One of the great things about having to travel for twelve hours is that I can catch up on my reading. So far I managed to finish off two great articles that have been lying around for ages: Growing a Language by Guy L. Steele Jr., who will be speaking about his new language Fortress at OOPSLA, and Lisp: Good News, Bad News, How to Win Big by Richard P. Gabriel.

I also managed to pack a couple of books: The Algorithm Design Manual which seems to be entertaining as well as comprehensive, and the second edition of Programming Language Pragmatics which has been updated to include scripting languages. This should suffice for both there and back.

Sunday, October 01, 2006

Higher Order Functions

The last few years I have been spending my spare time with languages like Scheme, Ruby, Haskell and Erlang. The reason I’m doing this is that the expressiveness of these languages is a lot higher than that of my work language, Java. I’m able to do more with less code. And the reason for this is higher order functions. Higher order functions is enabled by having functions as first class citizens of the language.

Map

The first of the higher order funtions is map. Map takes two arguments a function and a list and returns a new list with the result of applying the funtion to every element of the list. Map raises the abstraction of list iteration by allowing me to focus on converting one element of this into one element of that instead of worrying about how to convert a list of this into a list of that. It simplifies my job.


; Map in Scheme
(define (map f l)
(if (null? l)
 '()
 (cons (f (car l)) (map f (cdr l)))))

>(map plusone '(1 2 3 4))
(2 3 4 5)

-- Map in Haskell
map f []     = []
map f (x:xs) = f x : map f xs

> map (+ 1) [1..8]
[2,3,4,5,6,7,8,9]

Filtering

Map always returns a list of the same length as the one given as argument. Sometime I only want the elements that fulfill some criteria to be returned. This calls for filtering.

; Filter in Scheme
(define (filter p l)
 (cond
   ((null? l) '())
   ((p (car l)) (cons (car l) (filter p (cdr l))))
   (else (filter p (cdr l)))))

>(filter even? '(1 2 3 4 5 6))
(2 4 6)

-- Filter in Haskell
filter p [] = []
filter p (x:xs)
 | p x = x : filter p xs
 | otherwise = filter p xs      

> fil odd [1..8]
[1,3,5,7]

Reduce

Another thing commonly done with lists is to combine the arguments into one value. This can be done with reduce.

; Reduce in Scheme
(define (reduce op l)
 (if (null? (cdr l))
   (car l)
   (op (car l) (reduce op (cdr l)))))

>(reduce + '(1 2 3 4))
10
>(reduce - '(1 2 3 4))
2

-- Reduce in Haskell
reduce op (x:[]) = x
reduce op (x:xs) = (op x (reduce op xs))

> reduce (+) [1..4]
10

Compose

We now have the ability to transform lists by mapping a function to every element or by filtering the elements according to some predicate function. We are also able to reduce a list by combining the elements with a binary function. We would also like the ability to create new functions by combining two functions and this is where compose comes in:

; Compose in Scheme
(define (compose f g)
 (lambda (x)
   (f (g x))))

; Add as a higher order function
(define odd? (compose even? plusone))

> (odd? 3)
#t

-- Compose in Haskell
compose :: (b -> c) -> (a -> b)  -> (a -> c)
compose f g = \x -> f (g x)

-- Odd as a higer order function
odd = compose even plusone

> compose even plusone
10

It is important that the type signatures of the functions set to compose match as can be seen in the type definition of the Haskell example above. The type returned by function g must be the input of function f.

Currying

Another method of creating new methods is currying1. Currying means creating new functions by only suppling part of the required arguments to the function. Instead of failing a new function is created. This is directly supported in Haskell, but must be done explicitly in Scheme (or by use of macros).

-- Currying in Haskell  
-- + is a binary function but only given one parameter it returns a closure.
plusone = (+ 1)

> plusone 3
4   

; Currying in Scheme
(define (curry f . args)
 (lambda x
   (apply f (append args x))))

> (define plusone (curry + 1))
> (plusone 3)
4

Const

In order to combine useful functions it is sometimes necessary to have simplifying functions and const is as simple as they come. const returns the same value no matter what argument it is given.

; Const in Scheme
(define (const k)
 (lambda (x) k))

> (define five (const 5))
> (five 6)
5

-- Const in Haskell
const k = \x -> k

five = const 5

> five 6
5


Even Higher Order Functions

All the functions above, there are more in any good book on functional programming, gives me the ability to produce many other functions simply by combining them together.

; Length in Scheme
(define length
 (compose (curry reduce +) (curry map (const 1))))

> (length '(1 2 3 4))
4


-- Length in Haskell
length = compose (reduce (+)) (map (const 1))

> length [1, 2, 3, 4, 5, 6]
6
      

To be able to raise the level of abstraction like this is what makes programming fun and I long for it when using rigid languages like Java.

1 The technique was named by Christopher Strachey after logician Haskell Curry, though it was invented by Moses Schönfinkel and Gottlob Frege.