Feeds:
Posts
Comments

Archive for November, 2009

Jonathan Sterling discusses writing fully native Cocoa applications in Smalltalk with F-Script in "Writing Mac OS X applications in Smalltalk"

What I really wanted was a version of Smalltalk that used the same object model as Objective-C, like Pragmatic Smalltalk of Etoilé, or even MacRuby on Mac OS. Most of all, I wanted it to treat me like an adult: I don't need a class browser, thank you, I'm more comfortable working with plain-old files. The persistent image construct in Smalltalk really makes me uncomfortable. Eventually, I found F-Script, a scripting environment for Mac OS based on Smalltalk. It is not really meant for developing full applications, but with a little work, I was able to make this work. Read more…

Read Full Post »

Fabian Schuiki explains how F-Script can be used as a debugging tool when developing Cocoa applications in "F-Script: The Ultimate Debugging Console".

If it weren’t for F-Script, I would have spent 5 hours today writing debugging code and creating some testing UI for Artifica which would have been another source for bugs which increases complexity of the debugging process again. F-Script gives you the possibility to completely split up the development of your object model and your view model, which not only saves you a lot of time and is more productive, but is also less frustrating since you never have to go figure whether your app’s functionality is broken due to a bug in the UI, the object model or even worse, somewhere in between. Read more…

Read Full Post »

Joint Ruby and Smalltalk BlockCamp in Paris

The french Ruby and Smalltalk communities are organizing the first BlockCamp event in Paris on the 28th november 2009. I will be there and will talk about F-Script 2.0. Come join us! More information here…

Read Full Post »

In this fun video clip, it takes Jeff only a few seconds to bring support for Snow Leopard’s text substitutions to WriteRoom… Cool demo of F-Script injection, for those unfamiliar with it.

Read Full Post »

Beyond Blocks

Blocks (aka lambda expressions or closures) are versatile and powerful. I like them. I have even implemented a programming language in which they play a central role.

However, for a number of common programming situations, I think that some alternative approaches based on higher order messaging provide better solutions than classic block-based approaches. Marcel Weiher provides a good example in Blocked-C. He shows some Objective-C code that uses a block to iterate over a collection of strings and to create a new collection with some suffix added to the original strings:

 NSMutableArray *filteredItems = [NSMutableArray array];
 [items enumerateObjects WithOptions:0 withBlock:
    ^(id item, NSUInteger index, BOOL *stop) {
       [filteredItems addObject:[item stringByAppendingString:@"suffix"]];
    }
 ];

Then, he goes on to show how the same can be achieved using a higher order messaging (HOM) technique:

 [[items collect] stringByAppendingString:@"suffix"];

The conciseness and expressiveness of the HOM version is impressive and should at the very least warrant further examination. Regarding this, we are lucky since this approach, and its application to Objective-C, is described in an OOPSLA paper titled "Higher Order Messaging" (download).

With some support in the programming language, higher order messaging techniques can go even further. F-Script is a Smalltalk dialect for Cocoa which extends Smalltalk with array programming and messaging patterns. Messaging pattern is a generalization of message sending that applies to entire collections of objects. In a number of common situations, this provides an interesting alternative to the classic block-based approach. Indeed, here is our example coded in F-Script:

 items stringByAppendingString:'suffix'.

A key aspect of this programming model (and of Weiher’s HOM) is that it liberates us from the classic "one object at a time" style, and lets us manipulate whole collections of objects at once, using higher level constructs. We are freed from the low level details of accessing and dealing with individual elements. In my experience, introducing array programming in object-oriented programming, as F-Script does, has positive effects similar to those of the introduction of vectors in math, which is quite nice… This model is described in another OOPSLA paper titled "OOPAL: Integrating Array Programming in Object-Oriented Programming" (download)

To get a better sense of this programming model, let’s see how it stacks up against classic block based approaches for collections manipulation as seen in Ruby and Smalltalk. For the same price, I also add Python’s list comprehensions and C# Linq to the mix. In some common situations, those are interesting alternatives to blocks that are still representative of the "one object at a time" approach.

In the example below, we have a list of songs (a collection of Song objects) and we want to get their names. Here is how we’d do it using various approaches:

  • Smalltalk and Ruby with blocks
  • Python with list comprehension
  • C# with Linq
  • F-Script with array programming
Smalltalk songs collect:[:aSong| aSong name]
Ruby songs.collect(&:name)
Python [aSong.name() for aSong in songs]
C# from aSong in songs select aSong.name()
F-Script songs name

We can note that the array programming version (F-Script) is free from syntactic noise and low-level iteration logic, as is the brain of the programmer. Actually, in that particular situation, it seems hard to do better.

For the ruby version, we use a feature adopted in Ruby 1.9, which allows for automatic conversion of symbols to blocks. This is a useful trick as it provides a way, in some situations, to have a compact notation for some kind of blocks. Note, however, that when we need to provide more that just a method name, we have to use the classic Ruby block notation. This is the case in our original example (i.e., invoking the stringByAppendingString method with a given argument), for which we would have to do: items.collect {|item| item.stringByAppendingString("suffix")}.

We can carry on the comparison further by introducing some need for filtering. In the following example, we want to get the names of songs with a bit rate greater than or equal to 256 kb/s.

Smalltalk (songs select:[:aSong| aSong bitRate >= 256]) collect:[:aSong| aSong name]
Ruby songs.select {|aSong| aSong.bitRate >= 256}.collect(&:name)
Python [aSong.name() for aSong in songs if aSong.bitRate() >= 256]
C# from aSong in songs select aSong.name() where aSong.bitRate() >= 256
F-Script songs name where: songs bitRate >= 256

We see that the F-Script programming model allows for conciseness and expressiveness. Note that, in F-Script, where: is not a keyword or a special construct. It is just a regular message selector. The where: method, defined in a category of NSArray, takes an array of booleans as argument and returns the elements of the receiver whose positional matching element in this boolean array is true. Such boolean array is exactly what is produced by the expression songs bitRate >= 256, as messages are automatically broadcasted to each individual elements of the receivers (i.e., the bitRate message is sent to each element of the songs array, producing an array of numbers whose elements are then sent the >= 256 message, producing the array of booleans). This is the powerful compression operation of array programming adapted to object-oriented programming.

Finally, here is an example of sorting a collection of objects. In this example, we want to create a sorted collection of our songs, sorting on the songs’ names. In the case of Python, since its list comprehensions don’t have specific support for sorting, we use a solution based on lambda expressions.

Smalltalk songs asSortedCollection:[:song1 :song2| song1 name < song2 name]
Ruby songs.sort_by(&:name)
Python sorted(songs, key=lambda aSong: aSong name)
C# from aSong in songs orderby aSong.name() select aSong
F-Script songs at: songs name sort

As in the previous examples, the F-Script version shows that we can do sophisticated collection manipulation without relying on blocks but only using message passing. The result of the sort message sent to the array of song names is an array of integers containing the indices that will arrange the receiver of sort in ascending order. We then pass this array of indices to the at: method. The at: method allows for indexing an array by either a single integer or a whole array of indices. This is this latter capability, a fundamental element of array programming, that we use here to produce our sorted list of songs.

Conclusion

Blocks are great, especially in programming languages which don’t have (and don’t want) specific syntax for classic control structures (if/then/else, while, etc.). However, we should take them with a grain of salt and see that, for some common problems, there are alternative approaches that are worth considering.

Further reading

F-Script documentation set
Blocked-C II
Can Programming Be Liberated from the von Neumann Style? A Functional Style and Its Algebra of Programs

Special bonus

You can easily, and interactively, experiment with the code provided in the examples: launch F-Script.app, connect to iTunes and immediately start querying and manipulating your iTunes song collection from F-Script.

You connect to iTunes using the standard Cocoa Scripting Bridge technology. For example, you can enter the following code in the F-Script console:

iTunes := SBApplication applicationWithBundleIdentifier:'com.apple.iTunes'

The iTunes variable now points to a dynamically generated Cocoa object that stands for the iTunes application.

You can get at your songs with:

 songs := ((iTunes sources at:0) playlists at:1) tracks

You can then directly paste, in the console, the code of the examples provided in this article. If your song library is huge you might notice some latency, as Cocoa messages are automatically converted to Apple Events that flow back and forth between F-Script and iTunes.

Read Full Post »

Stepwise

Stepwise has been removed from the universe. It was one of my favorite Web sites back in the 90’s and, I think, a mythical place for many NeXT and early Mac OS X developers. I remember, among other things, the wonderful WWDC reports published there.

Thanks to Scott Anguish and everyone involved.

Read Full Post »

NSConference

The NSConference 2010 setup looks great. I’ve been lucky to attend and speak at the 2009 edition, which was terrific, thanks to the vision, work and human qualities of the folks at MDN, Steve Scott and Tim Isted. The videos of the 2009 edition are all available for purchase. This includes the talk I gave on “New Cocoa programming superpowers”.

There are also a number of backstage and interview videos at Pomcast.com (search for "NSConf"), including the super geeky Hacking F-Script & Pick&Play, starring Jason Harris, and the french F-Script interview in the dark.

Read Full Post »

Older Posts »