Smalltalk and Cocoa Programming in Cocoalogue: How it Blends

25 09 2008

As I mentioned in my last post, I’ve made a pre-release of Cocoalogue available for the PMC bundle. Only one person took advantage of the offer, which was so surprising to me I had sent him a license for Clockwork because I didn’t realize what he actually purchased! So not only is he Cocoalogue user #1 for all time, he’s also the happy owner of a Clockwork license! (See what you all missed out on?)

A Simple Cocoalogue Overview

Cocoalogue is an interpreted computer programming system, oftentimes called a scripting system or dynamic language these days. While the system shares a great deal in common with the Smalltalk-80 system on which it was based, Cocoalogue’s current executable model is more like the one used for Perl, Python, Ruby, AppleTalk, any of the shell programs which have scripting support, etc. It also includes a Cocoa bridge to allow use of the Objective-C/Cocoa frameworks on Mac OS X, and extensions to the Smalltalk syntax to allow static typing, namespaces, and more.

There are four main components to Cocoalogue as it now exists: the language compiler, the virtual machine, and the run-time system. They are designed to function fairly independently, so modification of any component doesn’t adversely affect the others. They can also be replaced independently, so a language compiler for Ruby could be substituted, for example; or the run-time system can be replaced with one written for Apple’s Open Scripting Architecture. Also, they are generally written in C using POSIX libraries for portability, although some functionality was implemented in Objective-C/Cocoa for expediency’s sake.

What is this Smalltalk of Which You Speak?

Since I’m pimping Smalltalk so often, I should explain a little bit about it so you understand some basic Cocoalogue concepts. Smalltalk is a programming environment developed at Xerox’ Palo Alto Research Center (PARC), incorporating programming language, tools and user interface, that was originally designed for educational purposes in the hope that the researchers developing it would discover how to make computers easier to use. Windowing Graphical User Interfaces (GUI) such as used by all implementations of the Mac OS and Windows, and Integrated Development Environments (IDE) used by Xcode and Visual Studio are based on inventions arising out of the Smalltalk initiative.

Wikipedia has a more detailed explanation of the history and implementation of Smalltalk than I have space for here. But I’ll briefly cover its syntax to explain what Cocoalogue has. Resources, or objects, used by programs are represented as variables in the Smalltalk language, and are sent messages that represent the actions the programmer wishes the objects to perform.

rectanglesContainingX: xCoordinate andY: yCoordinate
| rectangles aPoint|
rectangles := OrderedCollection
     with: (Rectangle left: 0 right: 10 top: 100 bottom: 200)
     with: (Rectangle left: 10 right: 10 top: 110 bottom: 210).
aPoint := Point x: xCoordinate y: yCoordinate.
^ rectangles select: [:aRect | aRect containsPoint: aPoint].

The example is for demonstrating Smalltalk syntax, not coding quality; so don’t use it as a template for your own work. ;) It defines a method named #rectanglesContainingX:andY: that returns an OrderedCollection, or list, of rectangles which contain a specific point given as an x-y coordinate, and represented in the example by xCoordinate and yCoordinate, respectively. The method defines two temporary variables, rectangles and aPoint, which are used to hold values computed for use while the method executes. The method creates an OrderedCollection object with two rectangles for elements (technically, it sends the message #left:right:top:bottom: to the Rectangle class two different times which has the responsibility to create the two rectangles, and those rectangles are then sent to the OrderedCollection class as part of the #with:with: message) and assigns the result to the rectangles temporary variable. It then creates a point for the given x-y coordinate (again technically, it sends #x:y: to the Point class along with the x-y coordinate). The last statement sends #select: to the OrderedCollection object represented by the rectangles variable, which has the responsibility of going through each rectangle element in the collection and finding every one which meets some criteria, passing the criteria test in an executable sequence of code as an object called a block. The collection’s #select: method returns a new collection which contains all the elements matching the test “contains aPoint“. The #rectanglesContainingX:andY: method then returns that result to whatever object called it.

Cocoalogue Isn’t Smalltalk

As much as I love Smalltalk, and have made having a professional-grade programming environment based on Smalltalk my goal, strict adherence to Smalltalk isn’t my objective for Cocoalogue. My objective is to create a development and work environment based on the interactive model I enjoyed using systems such as Squeak, BASIC, and Instant-C; which incorporate modern code development and management tools such as SCM; and use of legible programming languages such as Smalltalk. I’ll spell out the major deviations from Smalltalk systems as I outline the components below.

The Cocoalogue Run-Time System

The run-time system is itself composed of four parts: the memory management system, which uses an indirect pointer similar to relocatable blocks on the classic/Carbon Mac API combined with reference counting; the data types system, which permits the definition of types and their operators; the class library, which provides the pre-defined types and classes used to write programs; and the Cocoa bridge (it’s odd that there are Wikipedia entries for PyObjC, CamelBones, RubyCocoa, but none for Cocoa bridge) which allows interaction with objects created or used by Mac OS X’s Cocoa frameworks. Soon, the Cocoa bridge will also allow the declaration and invocation of normal C functions, but the syntax to do this hasn’t been finalized yet.

Cocoalogue’s Run-time Differences with Smalltalk

The largest distinguishable differences the current implementation of Cocoalogue has with Smalltalk are

  • lack of a persistent image;

    Although it would be relatively trivial to provide an image-based environment typical to Smalltalk implementations, I’ve forgone support in Cocoalogue’s current implementation to speed up development of other features. In addition, as the supported classes and functionality undergoes enhancement it’ll be best not to keep an image around which will undergo repeated changes to its fundamental objects.

  • fine-grained control over the execution environment;

    To support the ability to define types of arbitrary width (such as Smalltalk’s LargeInteger and Fraction) a type must be able to specify how, and whether, exceptional conditions should be handled by the run-time system. For the LargeInteger class, calculations which result in either over- or under-flow conditions should cause the class to widen the resulting object to fully contain the result whereas for types having an Int32 specification should discard the excess result bits, yet still permit the method or object which invoked the operation to know or respond to the exception itself.

  • Cocoa classes instead of Smalltalk’s;

    Smalltalk-compatible classes aren’t developed yet, so programming still requires familiarity with the Cocoa frameworks. Literals are instantiated from the corresponding Cocoa classes (NSNumber, NSString, etc.).

  • DataType vs Object as fundamental type primitive;

    To support primitive types for languages such as C, all types are derived from DataType in Cocoalogue’s language by specifying their widths in Bits, a concrete subclass of DataType. Operators are declared and invoked via the standard Smalltalk syntax so the functionality is inherited by Objects.

    DataStructure is an abstract type derived from DataType and which defines aggregate structures whose members’ alignment and packing can be specified by the programmer, or the environment by default.

    DataShared is an abstract type derived from DataStructure which defines structures whose members share the same offset from one end of the structure so their members “overlap” in storage.

    Object is a concrete type derived from DataStructure which acts as the base type for all data types of the standard OOP model, and can contain either objects or DataTypes.

  • Classes don’t need a Metaclasses support object;

    Rather than maintain Smalltalk’s legacy of Class/Metaclass structure for inheritance, class methods, class variables, etc., I’ve shifted the classical class-based model into the DataType/DataStructure/Object/Class framework. This will allow the addition of other execution architectures into the run-time system.

Cocoalogue’s Virtual Machine

The virtual machine is a hybrid of abstract syntax tree and bytecode techniques to keep semantic info sufficiently close to executable code for debugging purposes and to give me enough leeway to optimize along any of several directions. They’re stored in sequences as literals along with standard data type literals, and are nestable and suitable for parameter passing to allow the declaration of the expected Smalltalk blocks (closures) as well as other sophisticated techniques for specifying code order and execution.

Cocoalogue’s Compiler

The compiler handles an extended version of the Smalltalk grammar that allows the specification of explicit types, bit widths, and byte-ordering for data. I sought to maintain strict conformity with Smalltalk syntax as much as possible, except perhaps for a place or two where I thought the syntax was inelegant. The additions to the syntax I made are generally in keeping with the beauty I found in the syntax, although admittedly with my own biases.

Cocoalogue’s Compiler Syntax Differences with Smalltalk’s
One of the basic questions for an explicit-typing extension to Smalltalk is, what does it look like? For Cocoalogue, one of the ways types can be specified is like this:

variableDeclaration = variableName ‘::’ className { inflection }.

wherever a variable is declared for use as a parameter, temporary, instance var, etc. inflection can be a type modifier such as ’signed’ or ‘unsigned’, an array specifier [delimited by '(' and ')'], or a pointer specifier (’^').

Smalltalk methods always pass a result back as an object, even when a result isn’t specified through the return (’^') expression when the result is the object currently executing the method in question. Thus Smalltalk methods have no syntax to specify the result. So Cocoalogue also has an extension to allow the type of the result to be specified. The default type for the result is Object. Otherwise, the result’s type is specified by appending “::^ className { inflection }” to the method’s message pattern. The Smalltalk example code given above might now look like the following in Cocoalogue:

rectanglesContainingX: xCoordinate::CGFloat andY: yCoordinate::CGFloat ::^ NSArray^
|  rectangles :: NSArray^.
   aPoint :: NSPoint.
   each :: NSRect.
   enumerator :: NSEnumerator^.
   selectedRectangles :: NSMutableArray^. |
rectangles := #( (NSRect x: 0 y: 100 w: (10 - 0) h: (200 - 100))
                        (NSRect x: 10 y: 110 w: (10 - 10) h: (210 - 110) ).
aPoint := NSPoint x: xCoordinate y: yCoordinate.
enumerator := rectangles objectEnumerator.
selectedRectangles := NSMutableArray alloc init.
[(each := enumerator nextObject) != nil]
     whileTrue:
          [[eachRectangle containsPoint: aPoint]
               ifTrue:
                   [selectedRectangles := addObject: eachRectangle]]].
^selectedRectangles

In accordance with the Cocoa frameworks, view coordinates are expressed from a normal Cartesian (bottom-left) orientation. As you can tell, the bulk of the code is to make up for the lack of support in Objective-C for closures which results in it being unsupported in Cocoa. When Smalltalk-like collection classes are added to Cocoalogue, the bulk of this example will be significantly reduced.

That’s a little overview of Cocoalogue as I promised in my last post. Once Mori 1.7 is released I’ll be able to continue completing basic Cocoalogue functionality. The main purpose of releasing it in scripting model form is to get it released and into use quickly. “Enhancements” (read greater Smalltalk class support) and surely bugfixes will follow.






purchase accutane online buy accutane cialis prescription order cialis without prescription buy cheap soma online generic synthroid accutane pills cheapest generic viagra lowest price acomplia propecia without a prescription cheap cialis from usa tablet viagra certified viagra buy cialis without prescription levitra discount cheap viagra in usa lowest price clomid order cheap viagra acomplia sale cialis rx order lasix viagra bangkok cheapest cialis prices online viagra cialis vendors buy soma online clomid sale buy cheap lasix online viagra free sample cialis in us viagra canada buy cialis from us soma no prescription cialis pill buy soma buy viagra in us soma for sale where to order viagra viagra buy drug viagra buy cialis in uk synthroid cheap cheap generic cialis buy cheap synthroid online discount propecia acomplia pharmacy order lasix online buy cialis in us soma without a prescription cheap propecia tablets cheap viagra tablets find cheap cialis cialis sales clomid online stores clomid prices compare viagra prices online cheap cialis no rx lasix without prescription cialis pills cialis purchase online pharmacy viagra buy cheap accutane find viagra on internet cialis order buy viagra cheap cheapest levitra cost of viagra cheap lasix tablets order cialis on internet order viagra in canada zithromax no prescription lowest price zithromax cheapest viagra prices