TweetFollow Us on Twitter

Learn F-Script in 20 Minutes

Volume Number: 23 (2007)
Issue Number: 05
Column Tag: Programming

Learn F-Script in 20 Minutes

And have fun playing with Core Image

By Philippe Mougin

Welcome

If you are a Cocoa programmer chances are that you've heard of F-Script, an open-source scripting layer dedicated to Cocoa. If you haven't tried it yet, this is your chance to learn how it can improve your productivity as well as those of the users of your own Cocoa applications. In this article, our goal will be to produce a nice little animation using fancy Core Image effects. In doing so, we will learn the basics of F-Script. So install yourself comfortably in front of your Mac, download the latest F-Script version from http://www.fscript.org and enjoy the trip!

First Contacts

We are going to learn F-Script by taking advantage of one of its key functionalities: the ability to be used interactively. With its console, you can interactively type commands in order to manipulate Objective-C objects on the fly. The F-Script console opens automatically when you launch F-Script.app. Inside it, you can type F-Script expressions or scripts and have them immediately executed when you press Return.


Figure 1. The F-Script console, waiting for your input

F-Script is a Smalltalk dialect for Cocoa and should look very familiar to you. Indeed, Brad Cox, who created objective-C describes it as "a hybrid language that contains all of C language plus major parts of Smalltalk". Here is an example of a message sending expression, both in Objective-C and F-Script. In this example, we ask for the current date using the NSDate class provided by Cocoa.

Objective-C F-Script (i.e., Smalltalk)
[NSDate date] NSDate date

As you can see, the expression is similar, except for the fact that, in F-Script, you don't have to put brackets around your message. This is because F-Script is a very simple language and sending a message is nearly the only thing you can do. Therefore, there is no need to have a special syntax to delimit messages. Now, if you type this expression in the console and hit Return, it will be immediately evaluated and the result will be displayed (obviously, the result you'll get will differ from the one shown below):

> NSDate date
2007-03-16 17:01:45 +0100

F-Script provides numerous tools to assist you during such interactive Cocoa sessions. In this first session, you are likely to find the following tips useful:

The console keeps a history of your commands. You can navigate it using the up and down arrows of your keyboard. For instance, if you mistype something and F-Script signals an error, you can use this feature to get back at your command without having to retype it.

You can insert a line break by pressing the Enter key (usually found on the numeric keypad) or by pressing Return while holding the Control key.

The console also provides a code completion mechanism that you can use by pressing the F5 key. You can then navigate between arguments placeholders with Control-Slash.

A graphical object browser opens automatically at startup. It is a very powerful tool with which you can explore objects and send them messages.

Before continuing to talk about the language itself, let me give you a little bit of the history: Smalltalk was created in the early seventies at the famous Xerox Palo Alto Research Center, the PARC, by a team led by Alan Kay. As you might know, since then, Smalltalk has been having a big influence on the software industry. For instance, you might have heard about a visit that Steve Jobs made at the PARC in 1979. A visit that had a considerable influence on the design of the Lisa and the Macintosh computers. What Steve Jobs was shown there was Smalltalk. It had a graphical interface, was the first object-oriented system, and supported networking. "You guys are sitting on a gold mine here. Why aren't you making this a product?" asked the young Steve Jobs. A short time later, several people from the PARC were working at Apple and the rest is history...

So, what is the basic concept of Smalltalk? The key insight leading to the design of Smalltalk is that we can describe everything in terms of objects. As Alan Kay puts it "Smalltalk's design is due to the insight that everything we can describe can be represented by the recursive composition of a single kind of behavioral building block that hides its combination of state and process inside itself and can be dealt with only through the exchange of messages". Indeed, in Smalltalk, everything is an object, even numbersnumbers, or booleansBooleans.

It is also important to note that F-Script provides an interactive environment with which you can directly interact with your objects, instead of having to develop a specific application each time you want to do something.

F-Script's Syntax

In a F-Script program the main control structure is message sending. In F-Script, as well as in Objective-C, a message with no argument is called a "unary message". A message with one or more colons in its selector is called a "keyword message". And, unlike Objective-C, there is a third kind of message in F-Script: a message that is composed of non-alphabetical characters like +, -, etc., is called a "binary message". A binary message always has only one argument.

Message type Objective-C F-Script
Unary [NSDate date] NSDate date
Keyword [NSDate dateWithTimeIntervalSinceNow:10] NSDate dateWithTimeIntervalSinceNow:10
Binary Not available date1 < date2

The Objective-C equivalent to date1 < date2 would be [date1 compare:date2] == NSOrderedDescending.

As in Objective-C, messages can be chained together. Expressions are evaluated from left to right, giving us the same semantics, as shown below.

Objective-C F-Script (i.e., Smalltalk)
[[NSDate date]
timeIntervalSinceNow]
NSDate date timeIntervalSinceNow

But sometimes, we need a way to determine the order of evaluation of messages. F-Script introduces a precedence rule (the only precedence rule in the language): unary messages are evaluated first, then binary messages, and then keyword messages. If you want to change the order of evaluation, you can use parenthesis to delimit a message.

The following example shows a few other differences between F-Script and Objective-C:

Objective-C F-Script (i.e., Smalltalk)
NSDate *date1 =
[NSDate date];
date1 := NSDate date.

As you see, there is no type declaration in F-Script. Everything is an object and variable need not be explicitly typed. The assignment syntax uses := instead of just = in Objective-C, and the instruction separator is not the semicolon, but the period symbol, like in English sentences. The following table shows other differences. As you can see, strings are enclosed in single quotes, and comments are enclosed in double quotes.

 
Objective-C F-Script
@"A string" 'a string'
/* A comment */ "A comment"
@selector(dateWithTimeIntervalSinceNow:) #dateWithTimeIntervalSinceNow:
[NSMutableArray arrayWithObjects:@"Hi", @"mom", nil] {'Hi', 'mom'}
NSMakePoint(200, 80) 200<>80

Displaying a picture on screen

We now know enough of F-Script to begin with our Core Image program. We will first create an NSURL object referring to the image we want to display. In this exampleexample, we will use an image that is stored on disk in the desktop picture folder. You can type the code below in the F-Script console to have it executed immediately.

imageLocation := NSURL fileURLWithPath:'
/Library/Desktop Pictures/Nature/Clown Fish.jpg'.

The imageLocation variable now points to our NSURL object. We will now create a CIImage object, initialized with our image on-disk.

image := CIImage imageWithContentsOfURL:imageLocation.

Note that we are using standard methods provided by the Mac OS X frameworks. Now that we have an image object, we can ask it to draw itself on screen, again using a standard method.

image drawInRect:(200<>80 extent:300<>200) 
fromRect:image extent operation:NSCompositeSourceOver fraction:1.

After executing this code, we should see a beautiful little image displayed in the console, as shown below.


Figure 2. Loading and displaying an image using Core Image and F-Script

The first argument passed to the drawing method is the rectangle we want to draw in, which is denoted with 200<>80 extent:300<>200. This expression actually creates an NSValue object representing a rectangle with an origin at (200, 80), a width of 300 and a height of 200. When passed to the method, the NSValue is automatically mapped by F-Script to an NSRect structure. This kind of automatic mapping between objects and primitives Objective-C types makes it possible to use the Mac OS X Objective-C based frameworks from a pure object language such as F-Script. You can change the rectangle size to make the image bigger or smaller and immediately see the result on-screen.

The drawing method draws the image in the current graphic context, which, in our example, happens to be the F-Script console. It is possible, of course, to draw elsewhere, using standard Mac OS X techniques.

Using core image filters

Core Image filters allow us to do all kind of highly optimized image processing. Mac OS X comes bundled with dozens of filters. Going forward with our exploration, we will apply a filter known as CIBumpDistortion, which creates a bump in the image. You are encouraged to try other filters as well. F-Script's interactivity makes it fun and efficient to explore such Mac OS X capabilities. The following F-Script code creates a CIBumpDistortion filter object and configures it to process our image, creating a bump of radius to 800 and of scale 2.

filter := CIFilter filterWithName:'CIBumpDistortion'.
filter setValue:image forKey:'inputImage'.
filter setValue:(CIVector vectorWithX:1000 Y:700) forKey:'inputCenter'.
filter setValue:900 forKey:'inputRadius'.
filter setValue:1 forKey:'inputScale'.

Now that the filter is configured, it will apply itself to our image when asked to provides its output, creating a new image and giving it back to us:

bumpedImage := filter valueForKey:'outputImage'.

We can now draw this new image on screen:

bumpedImage drawInRect:(200<>80 extent:300<>200) 
fromRect:image extent operation:NSCompositeSourceOver fraction:1.


Figure 3. Our image after processing by a Core Image "bump" filter

To understand how the filter works, it is interesting to change its configuration (for instance, the values of its radius and its scale) and to regenerate and redisplay the image. If you are sitting behind an F-Script console, you are encouraged to do so!

Using blocks to create an animation

Now that we know how to process and display an image, we can create a nice little animation by repeatedly processing the image with a varying filter and displaying the result. To do that we just need to learn how write a loop using F-Script.

But, wait a minute... Isn't F-Script supposed to have a very simple syntax, where everything is expressed by sending messages to objects? Well, this is exact and, in fact, F-Script does not have any special syntax for control structures such as loops or conditionals. So the question here is "How can we express useful programs without such syntax?" To answer that, let me introduce you to the concept of code blocks in F-Script. Below, we see a code block in Objective-C and one in F-Script. Note the use of brackets in F-Script, instead of curly braces.

Objective-C F-Script (i.e., Smalltalk)
{
instruction1;
instruction2;
}
[
instruction1.
instruction2.
]

The code blocks look similar, but the way they work is quite different. In Objective-C, when the computer executes the code block, it simply executes the instructions in it immediately. In F-Script, the code block is actually a kind of literal notation for an object that contains the instructions. In other words, a block represents a deferred sequence of actions. In F-Script, the presence of a code block does not lead to the execution of its content, but to the creation of a block object, that can then be asked to execute the instructions. To do that, we send the "value" message to the block. The result returned by the execution of a block is the result of the evaluation of its last instruction.

As you can see below, F-Script blocks can have local variables, just like in Objective-C. If the instructions in the block refer to a variable that is not declared as local, F-Script will look for it in the enclosing lexical context of the block, as is the case in Objective-C.

Objective-C F-Script (i.e., Smalltalk)
{
id local1,local2;

instruction1;
instruction2;
}
[
|local1 local2|

instruction1.
instruction2.
]

The main point to understand here is that F-Script blocks are objects. Like with any object, you can send messages to a block, you can assign a block to a variable, store a block in a collection, pass a block as an argument to a method, archive a block on-disk, and so on. Blocks are not unique to F-Script (or Smalltalk). They are present in numerous languages (sometimes under the name of "closure" or "lambda expressions") such as Ruby, Python, Lisp, GroovyGroovy, and the forthcoming C# 3.

Now that we have blocks, it is easy to do conditional evaluation. Boolean objects provide a method named ifTrue: which takes a block as argument. If the value of the Boolean is true, then the block is executed by the method.

Objective-C F-Script (i.e., Smalltalk)
if (a > b) 
{
instructions
}
(a > b) ifTrue:
[
instructions
]

Boolean objects also have a method named ifTrue:ifFalse: that lets you have something equivalent to the if/else control structure of Objective-C. This method takes two blocks as arguments. One that gets executed if the booleanBoolean is true and the other one that gets executed if the booleanBoolean is false.

Objective-C F-Script
if (a > b) 
{
  instructions
}
else
{
  instructions
}
(a > b) ifTrue:
[
  instructions
]
ifFalse:
[
  instructions
]	

For performing our animation, we need a way to repeatedly evaluate a block. Let's review how F-Script provides this.

Blocks provide a method named whileTrue:, which takes another block as argument. The receiver of the whileTrue: message evaluates itself, and, if the result of this evaluation is a booleanBoolean with a value of true, the argument gets evaluated. This process is repeated as long as the receiver evaluates to true.+

Note that in the example with conditionals, the ifTrue: message was sent to a booleanBoolean object. In the latest example, the whileTrue: message is sent to a block that returns a booleanBoolean. This is very different. Indeed, it would not make sense to implement a whileTrue: method in the booleanBoolean class. This is because the value of a particular booleanBoolean never changes; whereas the value returned by the evaluation of a block can change from one evaluation to another.

Now that we know how to express repetitive evaluation, we can finally write our animation:

keyWindow := NSApplication sharedApplication keyWindow.
rect := (200<>100 extent:300<>200).
i := 0.
[i < 2500] whileTrue:
[
    filter setValue:(CIVector vectorWithX:i Y:700) forKey:'inputCenter'.
    bumpedImage := filter valueForKey:'outputImage'.
    bumpedImage drawInRect:rect fromRect:image extent ¬ 
    operation:NSCompositeSourceOver fraction:1.
    keyWindow flushWindow.
    i := i + 5.
]

As you can see, we move the bump across the image, by varying the X component of the CIVector object that define the center of the bump. We use a control variable named "i" that we increment by five at each iteration of our loop until it becomes equal to 2500. We also ask the window to flush itself at each step of our iteration in order to display the new image and produce the animation effect.

Blocks with arguments

For such kind of iteration, however, a for loop is more appropriate, and you might wonder if F-Script provides it. Well, it does! But in order to master it we must learn another feature of blocks: support for arguments. Block arguments are declared at the beginning of the block, just after the opening bracket. Each argument name is specified after a colon and a vertical bar ends the argument list. A block must then be executed using an appropriate "value..." message. For example, here is a block with no argument. We evaluate it by sending it the value message.

['hello world'] value      returns       'hello world'

Below is a block with one argument. In this case, we send a value: message, specifying the argument that will be passed to the block.

[:a| a class] value:'a string'      returns       String

Here is a block with two arguments. To evaluate it, we send it a value:value: message.

[:a :b| a + b] value:2 value:3      returns       5

Now that we have blocks with arguments, we can make use of powerful methods. For example, numbers have a method named to:do: which takes an number and a block as arguments. The block is evaluated for each integer between the receiver and the first argument (both included).

Objective-C F-Script
for (int i=0; i <= 100; i++) 
{
  instructions using i
}
 0 to:100 do:
[:i|
  instructions using i
]	

F-Script also provides a to:by:do: method that let us specify an iteration step.

Objective-C F-Script
for (int i=0; i <= 100; i = i + 5) 
{
  instructions using i
}
0 to:100 by:5 do:
[:i|
  instructions using i
] 

We can make use of it in our animation script, which then becomes:

keyWindow := NSApplication sharedApplication keyWindow.
rect := (200<>100 extent:300<>200).
0 to:2500 by:5 do:
[:i|
    filter setValue:(CIVector vectorWithX:i Y:700) forKey:'inputCenter'.
    bumpedImage := filter valueForKey:'outputImage'.
    bumpedImage drawInRect:rect fromRect:image extent 
operation:NSCompositeSourceOver fraction:1.
    keyWindow flushWindow.
]

You can change the value of the step to see how it makes the animation faster or slower.

Conclusion

Now that you are familiar with F-Script, you can use it whenever you want to explore a new Objective-C API, interactively prototype code or debug an application. And since you can easily embed it into your own application, you can provide your users with an interactive and scripting layer for your application's functionalities, by just exposing them as Objective-C objects.


Philippe Mougin is the creator of F-Script. He works at OCTO Technology, a French consulting company, where he explores and promotes the use of dynamic languages in enterprise systems. You can reach him at pmougin@acm.org.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

VueScan 9.5.82 - Scanner software with a...
VueScan is a scanning program that works with most high-quality flatbed and film scanners to produce scans that have excellent color fidelity and color balance. VueScan is easy to use, and has... Read more
Postbox 5.0.17 - Powerful and flexible e...
Postbox is a new email application that helps you organize your work life and get stuff done. It has all the elegance and simplicity of Apple Mail, but with more power and flexibility to manage even... Read more
CleanMyMac 3.8.6 - $39.95
CleanMyMac makes space for the things you love. Sporting a range of ingenious new features, CleanMyMac lets you safely and intelligently scan and clean your entire system, delete large, unused files... Read more
Default Folder X 5.1.6b3 - Enhances Open...
Default Folder X attaches a toolbar to the right side of the Open and Save dialogs in any OS X-native application. The toolbar gives you fast access to various folders and commands. You just click on... Read more
Amazon Chime 4.6.5852 - Amazon-based com...
Amazon Chime is a communications service that transforms online meetings with a secure, easy-to-use application that you can trust. Amazon Chime works seamlessly across your devices so that you can... Read more
VOX 2.8.30 - Music player that supports...
VOX just sounds better! The beauty is in its simplicity, yet behind the minimal exterior lies a powerful music player with a ton of features and support for all audio formats you should ever need.... Read more
iFFmpeg 6.4.3 - Convert multimedia files...
iFFmpeg is a comprehensive media tool to convert movie, audio and media files between formats. The FFmpeg command line instructions can be very hard to master/understand, so iFFmpeg does all the hard... Read more
Alfred 3.4.1 - Quick launcher for apps a...
Alfred is an award-winning productivity application for OS X. Alfred saves you time when you search for files online or on your Mac. Be more productive with hotkeys, keywords, and file actions at... Read more
SyncTwoFolders 2.2.4 - Syncs two user-sp...
SyncTwoFolders simply synchronizes two folders. It supports synchronization across mounted network drives and it is a possibility to run a simulation showing in a log what will be done. Please visit... Read more
Maintenance 2.2.7 - System maintenance u...
Maintenance is a system maintenance and cleaning utility. It allows you to run miscellaneous tasks of system maintenance: Check the status of the hard disk Repair permissions Run periodic scripts... Read more

War Wings beginner's guide - how to...
War Wings is the newest project from well-established game maker Miniclip. It's a World War II aerial dogfighting game with loads of different airplane models to unlock and battle. The game offers plenty of single player and multiplayer action. We... | Read more »
How to win every 2v2 battle in Clash Roy...
2v2 is coming back to Clash Royale in a big way. Although it's only been available for temporary periods of time, 2v2 has seen a hugely positive fan response, with players clamoring for more team-based gameplay. Soon we'll get yet another taste of... | Read more »
Roll to Win with Game of Dice’s new upda...
Joycity’s hit Game of Dice gets a big new update this week, introducing new maps, mechanics, and even costumes. The update sets players loose on an exciting new map, The Cursed Tower, that allows folks to use special Runes mid-match. If you feel... | Read more »
Bottom of the 9th (Games)
Bottom of the 9th 1.0.1 Device: iOS iPhone Category: Games Price: $4.99, Version: 1.0.1 (iTunes) Description: Play the most exciting moment of baseball in this fast-paced dice and card game! | Read more »
The best apps for viewing the solar ecli...
If you somehow missed the news, many parts of the United States will be witness to a total solar eclipse on August 21 for the first time in over 90 years. It'll be possible to see the eclipse in at least some capacity throughout the continental U... | Read more »
The 5 best mobile survival games
Games like ARK: Survival Evolved and Conan Exiles have taken the world of gaming by storm. The market is now flooded with hardcore survival games that send players off into the game's world with nothing but maybe the clothes on their back. Never... | Read more »
Portal Walk (Games)
Portal Walk 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Portal Walk is adventure and relaxing platform game about Eugene. Eugene stuck between worlds and trying to find way back home.... | Read more »
Technobabylon (Games)
Technobabylon 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: City of Newton, 2087. Genetic engineering is the norm, the addictive Trance has replaced almost any need for human interaction,... | Read more »
5 reasons why 2v2 is the best mode in Cl...
Supercell has been teasing fans with 2v2 windows that allow players to team up for limited periods of time. The Summer of 2v2 was just this past July, but players are already clamoring for more of that sweet, sweet team-based action. The fans have... | Read more »
The best deals on the App Store this wee...
It seems like the week's only just started, and yet here we are with a huge pile of discounted games to sort through. There are some real doozies on sale this week. We're talking some truly stellar titles. Let's take a look at four of the best... | Read more »

Price Scanner via MacPrices.net

Norton Core Secure Wi-Fi Router Now Available...
First introduced at the 2017 Consumer Electronics Show (CES), Norton Core, a secure, high-performance Wi-Fi router, fundamentally changed the concept of Wi-Fi routers by making security the primary... Read more
ViewSonic Adds New 27-inch 4K UHD Monitor to...
ViewSonic Corp. has introduced the VP2785-4K, a 27-inch 4K UHD (3840×2160) monitor that delivers precise and consistent color representation and performance to ensure incredible image quality. Built... Read more
Apple now offering Certified Refurbished 2017...
Apple is now offering Certified Refurbished 2017 27″ iMacs for up to $350 off original MSRP. Apple’s one-year warranty is standard, and shipping is free. The following models are available: – 27″ 3.... Read more
13-inch 2.3GHz MacBook Pros on sale for $100...
Amazon has the new 2017 13″ 2.3GHz MacBook Pros on sale today for $100 off MSRP, each including free shipping: – 13″ 2.3GHz/128GB Space Gray MacBook Pro (MPXQ2LL/A): $1199.99 $100 off MSRP – 13″ 2.... Read more
Clearance 2016 13-inch MacBook Airs available...
B&H Photo has clearance 2016 13″ MacBook Airs available for up to $200 off original MSRP. Shipping is free, and B&H charges NY & NJ sales tax only: – 13″ 1.6GHz/128GB MacBook Air (MMGF2LL... Read more
Clearance 21-inch and 27-inch iMacs available...
B&H Photo has clearance 21″ and 27″ Apple iMacs available for up to $500 off original MSRP, each including free shipping plus NY & NJ sales tax only: – 27″ 3.3GHz iMac 5K: $1799 $500 off... Read more
New iOS 11 Productivity Features Welcome But...
The iOS community is in late summer holding mode awaiting the September arrival of the iPhone 8 and iOS 11. iOS 11 public betas have been available for months — number six was released this week —... Read more
Samsung Electronics Launches New Portable SSD...
Samsung Electronics America, Inc. has announced the launch of Samsung Portable SSD T5 – its newest portable solid state drive (PSSD) that raises the bar for the performance of external memory... Read more
TrendForce Reports YoY Gain of 3.6% for 2Q17...
Market research firm TrendForce reports that the global notebook shipments for this second quarter registered a sequential quarterly increase of 5.7% and a year-on-year increase of 3.6%, totaling 39.... Read more
Sale! 10-inch iPad Pros for $50 off MSRP, no...
B&H Photo has 10.5″ iPad Pros in stock today and on sale for $50 off MSRP. Each iPad includes free shipping, and B&H charges sales tax in NY & NJ only: – 10.5″ 64GB iPad Pro: $599, save $... Read more

Jobs Board

Business Development Manager - *Apple* Medi...
Job Summary Apple Music is a single, intuitive app that...- all in one place. You can stream any Apple Music song, playlist or album, and download it Read more
Development Operations and Site Reliability E...
Development Operations and Site Reliability Engineer, Apple Payment Gateway Job Number: 57572631 Santa Clara Valley, California, United States Posted: Jul. 27, 2017 Read more
Frameworks Engineering Manager, *Apple* Wat...
Frameworks Engineering Manager, Apple Watch Job Number: 41632321 Santa Clara Valley, California, United States Posted: Jun. 15, 2017 Weekly Hours: 40.00 Job Summary Read more
Program Manager, *Apple* Pay Business Opera...
…Manager to deliver and sustain a seamless user and support experience for Apple Pay Cash, the upcoming person-to-person payments feature in iMessage. On the Business Read more
Sr. Software Engineer, Core Services, *Apple...
…You will be part of the server team that powers various features within the Apple client applications - iTunes, App Store, iBooks, Podcast, Apple Music etc. You Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.