Newspeak First Public Release

February 28th, 2009

We’re very excited to announce the first public release of Newspeak. We have been working hard on making this initial release as easy to use as possible. Newspeak is still very much a prototype, and the language is far from complete. However, we already have a fully functional IDE, debugger, and unit test GUI.

Initially, we had hoped to release Newspeak earlier this year, and I’m certainly to blame for delaying it. However, we needed a debugger which could run in native mode to really show of the power of Newspeak. Fortunately, the fundamentals of the Squeak debugger aren’t tied as closely to the Morphic tool as we initially thought. After abstracting the Squeak classes Process and Thread in a mirror api, we had a pretty powerful base and just needed to get the UI just right. I think we did pretty well:

But a screenshot isn’t really a good way to get a feel for a new programming language. Download the release and give it a spin. Be sure to read the included tutorial (newspeak-101.pdf), it has great example which walks you through building you own GUI application in the Hopscotch framework.

Open Sourcing Newspeak

May 6th, 2008
Gilad just announced that we will open source Newspeak using the Apache 2.0 license. Notice that the announcement is that we will open source Newspeak; we need to audit the sources before we can release it.

Java 6 for Leopard

February 25th, 2008
Apple finally released a preview of Java SE 6 in December 2007.

Call to Boycott Language Design by Voting

February 15th, 2008
Please don’t answer this poll.

Tanenbaum on Shared Data Structures

January 31st, 2008

I just read the essay Tanenbaum-Torvalds Debate: Part II by Andy Tanenbaum. It showed up on Slashdot today, almost two years late. Tanenbaum makes a number of interesting observations on shared data structures:

Linus also made the point that shared data structures are a good idea. Here we disagree. [...] It is exceedingly hard to get this right, even with semaphores, monitors, mutexes, and all that good stuff.
My view is that you want to avoid shared data structures as much as possible. Systems should be composed of smallish modules that completely hide their internal data structures from everyone else.

Java Compiler API on IBM’s developerWorks

January 14th, 2008
David Biesack of SAS Institute, Inc. wrote Create dynamic applications with javax.tools. It walks you through an example that uses javac to compile user provided expressions and then plot them as a function. This is similar to my JavaOne demo evalexpr, but sleeker.

Newspeak Constructors

January 2nd, 2008

Constructors in Newspeak are unlike constructors in the Java™ programming language. We use the terminology to refer to methods generated by the compiler to initialize a newly created instance of a class.

Unlike Smalltalk, but just as in the Java programming language, Newspeak has complete syntax for class declarations. However, there is no single part of the syntax which maps directly to the constructor. Instead, the constructor is compiled from various parts of the class header.

The overall syntax is:

ClassDeclaration ::= ClassHeader InstanceSide : ClassSide
ClassHeader ::= class ClassName ConstructorMessagePattern = Superclass SuperConstructorCall ( | SlotInitializers | InitializerExpression )

Some of these syntax productions are optional, but I will ignore that for now. Here is an example of an immutable point:

class Point x: xVal y: yVal = Object new (
  |
  x = xVal.
  y = yVal.
  |
) (
  printString = ( ^x printString, ‘@’, y printString )
)

Slot initializers can be arbitrary expressions, so we can define a version initialized from polar coordinates:

class Point r: r theta: theta = Object new (
  |
  x = r * theta cos.
  y = r * theta sin.
  |
) (
  printString = ( ^x printString, ‘@’, y printString )
)

As the constructor is defined implicitly in the class declaration, a Newspeak class has exactly one constructor. However, you can define additional class-side methods which are indistinguishable from constructors (except to subclasses which must refer to the one constructor in SuperConstructorCall). So we can define a point which can be initialized from cartesian and polar coordinates:

class Point x: xVal y: yVal = Object new (
  |
  x = xVal.
  y = yVal.
  |
) (
  printString = ( ^x printString, ‘@’, y printString )
) : (
  r: r theta: theta = ( ^x: r * theta cos y: r * theta sin )
)

This was written in response to Christian’s Newspeak Constructors.

Java Programming Language is a trademark of Sun Microsystems, Inc.

Modules and Dependency Injection

December 17th, 2007
Gilad has revealed more details on our project. Read his take on dependency injection.

Declaration-Site Extension Methods

November 26th, 2007

Neal Gafter and others are suggesting to add extension methods to the Java programming language. To be clear about Neal’s proposal, I will call it use-site extension methods. I call them so because the user specifies which extension methods are to be used.

To be concrete, let me repeat Neal’s example of adding a sort() method to java.util.List:

import static java.util.Collections.sort;

List<String> list = …;
list.sort();

A clear benefit to this is that it builds on an existing language construct, static import. And as such, it may seem to be a simple extension. Unfortunately, in Java, nothing is simple. By itself, static import has a number of limitations. For example, you cannot import a method with the same name from different types. [update: actually you can, see also the comments.]

Another potential issue is source compatibility: currently, adding a public method to a final class is a source compatible change. However, if you add use-site extension methods, this is no longer true. A client of the final class could be extending it with a method with the same name as the new method. Imagine that the signature of the added method is compatible with the extension method, in this case, the compiler will not flag this as a potential error, instead it will silent change what method is called. This is a potential for subtle bugs.

An alternative is declaration-site extension methods in which the library designer specifies extension methods when declaring the type to be extended.

For example, instead of having each user of java.util.List import a sort method, the interface could declare that it is extended by java.util.Collections.sort:

package java.util;
interface List<E> … {
  …
  void sort() import static java.util.Collections.sort;
  …
}

This will instruct the compiler to compile:

java.util.List<String> list = …;
list.sort();
as if the user had written:
java.util.List<String> list = …;
java.util.Collections.sort(list);

Declaring sort within java.util.List<String> should only affect the compilation of clients of the interface. The compiler must record that the interface is extended by adding a new kind of attribute to the class file, but this should be defined to affect neither the calculation of default serialVersionUID nor how methods are looked up by the JVM.

Acknowledgements

Alex Buckley coined the terms use-site extension methods and declaration-site extension methods inspired by Thorup and Torgersen’s use-site variance. See also, Adding Wildcards to the Java Programming Language.

How to Create a Disk Image Installer for Apple Mac OS X

October 18th, 2007

Creating a disk image installer (product container) for OS X is pretty easy. Apple's Software Delivery Guide provides a good overview of the basic steps needed to create a disk image. However, there are a few less obvious steps you have to take to make your disk image look as professional as that of Firefox or Skype. Also, we want to make this process scriptable so we can generate the disk image as part of an unattended build system.

I know of two problems in particular:

  • Column view interferes with your layout
  • Source for background image clutters your layout

You may be blissfully unaware of the column view issue, so I recommend that you, at least for the duration of building your disk image, enable Open new windows in column view in Finder > Preferences > General.

While writing this post, I was notified about a new version of Google Notifier. This is what I saw when I opened the installer disk image:

google-notifier-columns.png

I hit Cmd-1 to switch to icon view and that improved the layout:

google-notifier-no-columns.png

Notice that there is white line at the bottom of the window; looks like a status bar will fit there:

google-notifier-statusbar.png

I recommend reading parts of the Software Delivery Guide before reading any further; start no later than Product Containers and stop when you reach Managed Installs. But don't follow the directions on creating a disk image from a folder, as this will make it harder to get the professional look we are going for.

You also need to install Apple's Xcode. It doesn't cost a thing.

Creating a Disk Image Template

First, we want a disk image that we can use as a template in a script or automated build system. Open Disk Utility which you find in the Utilities folder in Applications. Click the new image button, and select a size that is at least twice as much as you ever figure you will need on your disk image. You should select the sparse image format. Carefully select the name of the image, as this will be the name of the directory that will eventually open on your customer's desktop when they open the final disk image. In this example, I will use YoyodyneApp.

When you click on create, a new disk image is created and mounted. You will see that two new items show up in the left column of Disk Utility:

  • YoyodyneApp.sparseimage
    • YoyodyneApp

The first item is the actual disk image, and the second item is a partition within the disk image. When you select the partition, you can see where it is mounted. In my case, the mount point is /Volumes/YoyodyneApp. Notice that the mount point is a link. Click on the link thereby opening the YoyodyneApp directory in a regular finder window with toolbars (and column view if you set the preference as described above):

yoyodyneapp-initial-view.png

This is not how we want to present the installer to the end user. Let's fix that:

  • Open a Terminal window and type:
bless --folder /Volumes/YoyodyneApp \
  --openfolder /Volumes/YoyodyneApp
  • In the Finder window for YoyodyneApp:
    • Click the little pill shaped icon to hide the toolbar.
    • Hit Cmd-1 to switch to icon view.
    • Hit Cmd-E to eject the disk image (important).
  • Switch to Disk Utility
    • Select Yoyodyne.sparseimage.
    • Click open.

yoyodyneapp-blank-canvas.png

Eventually, we want to send a compressed version of the disk image to the end user. During that process, your layout can be lost (due to column view) unless you follow the steps above exactly.

Customizing the Background

Now is the time to brand the installer disk image with a custom background.

Drag your background image to the Finder window for YoyodyneApp. It has to be in the disk image to display properly at the end user's computer.

  • In the Finder window for YoyodyneApp:
    • Hit Cmd-J to open the view options for YoyodyneApp.
    • Make sure you select This window only.
    • Select Picture under Background:
    • Select the background image you just dragged to this folder. (I have to click on Picture once more after selecting the file).
    • You can make other customizations if you like, I prefer setting the icon and text sizes to their maximum values.
  • Open a Terminal window and type (use the actual name of your background image):
/Developer/Tools/SetFile -a V \
  /Volumes/YoyodyneApp/YoyodyneLogo.png

This will hide the background image from Finder. But not until you eject and open the image from Disk Utility. So do that now.

Link to Applications

Apple recommends that you include a symbolic link to /Applications if you expect the user to drag your application there (manual install):

  • Open a Terminal window and type:
ln -s /Applications /Volumes/YoyodyneApp/.
(include the period)

yoyodyne-branded.png

Application Placeholder

The goal is to create a template with our preferred layout. Most of the steps to create this template are manual and not easily scriptable. So we need to create the final layout once and save it as a template we can use in the future as part of an automated build process. Since Mac applications are all saved in a directory with a special bit set, we can create the applications directory so we can finish the layout.

  • In the Finder window for YoyodyneApp:
    • Hit Shift-Cmd-N to create a new folder.
    • Type in the name followed by .app, for example Yoyodyne.app. Finder will hide the extension, but change the icon.

yoyodyne-placeholder.png

Finalizing the Layout

Oops, I created the icons in the wrong order. I prefer having the Applications folder on the right of the application. That is easy to fix:

  • In the Finder window for YoyodyneApp:
    • Move the application icon near the left side of the window.
    • Move the Application folder icon near the right side of the window.
    • Hit Cmd-A to select all the icons.
    • Select Clean Up Selection in the View menu.
    • Move both icons so the are nicely centered.

yoyodyne-aligned.png

I designed an icon for the application:
yoyodyneicon.png

This is PNG file, perhaps you already have an .icns file. The procedure is the same:

  • Open a Terminal window
    • Change directory to the folder where you stored the icon.
    • Type:
sips -i YoyodyneIcon.png
(works on most graphic image files, including .icns files)
open .

This will use the picture/icon found in the file as the icon for that file, and then open the folder.

  • In the Finder window you just opened:
    • Select the icon file.
    • Hit Cmd-I to open an info window.
  • In the info window you just opened:
    • Click on icon next to the file name at the very top of this window (it should get a blue halo).
    • Hit Cmd-C to copy the icon to the clipboard.
  • Go back and select the application placeholder
    • Hit Cmd-I to open an info window.
  • In the info window you just opened:
    • Click on icon next to the file name at the very top of this window (it should get a blue halo).
    • Hit Cmd-V to copy the icon from the clipboard.
  • Close the info windows.

yoyodyne-app-logo.png

Following the same procedure, you can also change the icon of the mounted disk image. Locate it on the desktop and hit Cmd-I to get started:

yoyodyne-disk-icon.png

This concludes the layout part.

Testing the Disk Image Template

Make sure you have ejected the disk image before you proceed.

  • Open a Terminal window
    • Change directory to the folder where you stored the disk image template (YoyodyneApp.sparseimage).
    • Type:
hdiutil convert YoyodyneApp.sparseimage \
  -format UDBZ -o YoyodyneApp.dmg
open YoyodyneApp.dmg

This will open the compressed image. Now carefully examine the new window. The following should be true:

  • Your background art is clearly visible (the window is not in column view).
  • There are no tool- or status-bars.
  • The disk image icon is what you chose.

I also recommend that you copy the .dmg file to a USB stick or similar, and check that it looks right on a co-worker's computer.

At this point you should eject the image and store it in your version control system. Make sure you eject it before you try to store it. Store the .dmg, not the .sparseimage.

Automated Build of Disk Image Installer

The template we made in the previous step should be pretty small, around 42K and can easily be managed by version control software. Let's assume the built application is also under version control. For example, let say we are using subversion, and the .dmg and application are stored as:

  • svn://svn.yoyodyne.com/YoyodyneApp/YoyodyneApp.dmg
  • svn://svn.yoyodyne.com/YoyodyneApp/Yoyodyne.app

Building the disk image installer then becomes as easy as:

svn export \
  svn://svn.yoyodyne.com/YoyodyneApp/YoyodyneApp.dmg
hdiutil convert YoyodyneApp.dmg \
  -format UDSP -o YoyodyneApp
rm YoyodyneApp.dmg
hdiutil mount YoyodyneApp.sparseimage
svn export \
  svn://svn.yoyodyne.com/YoyodyneApp/Yoyodyne.app/Contents \
  /Volumes/YoyodyneApp/Yoyodyne.app/Contents
hdiutil unmount /Volumes/YoyodyneApp
hdiutil convert YoyodyneApp.sparseimage \
  -format UDBZ -o YoyodyneApp.dmg

YoyodyneApp.dmg is now ready to ship to your customers.