Updated on January 7, 2009 to reflect changes in F-Script 2.0 alpha 7.
Work is progressing well on the next alpha of F-Script 2.0. The biggest new feature in alpha 3 will be a nice syntax for creating classes on the fly. Here is an example where we define a Circle class. A circle can be initialized with a color and asked to draw itself.
Circle : NSObject
{
color
+ circleWithColor:aColor
{
^ self alloc initWithColor:aColor
}
- (void) draw
{
color set.
(NSBezierPath bezierPathWithOvalInRect:(400<>100 extent:100<>100)) fill
}
- initWithColor:aColor
{
self := super init.
self ~~ nil ifTrue:
[
color := aColor
].
^self
}
}
We can then instantiate a circle and draw it:
c := Circle circleWithColor:NSColor greenColor.
c draw
Here is what it looks like in the F-Script console:

This example demonstrates subclassing an Objective-C class (here, NSObject), defining an instance variable (color), a class method and two instance methods. This dynamically creates a native Cocoa class that can then be used from F-Script and Objective-C.
wow, increadible!!!!
thanks a lot for this great improvement!
can’t wait to try the new alpha out!
Karsten
It looks very clean. I’m a little concerned about FScript becoming littered. One of the most beautiful things about Smalltalk is its consistency. It seems odd to have syntax for some things and not for others; creating classes and not for conditionals etc. Are there plans to add more special forms? Am I mistaken about this? All in all good work. It’s nice to see things progressing :).
Hi,
I’d like to say firstly that I am always glad when you post something new to your site, as your work always impresses me.
Compared to what we produce in investment banking; I hang my head in shame. :(
I know nothing of language design but I think that the ‘{}’s look somewhat odd.
I think I understand that it might make easier for the parser but what about a more Smalltalky/Rubyesque way.
Circle<NSObject
@color
+circleWithColor:aColor
self alloc initWithColor:aColor
-draw
color set.
(NSBezierPath bezierPathWithOvalInRect:(400100 extent:100100)) fill
-initWithColor:aColor
self := super init.
(self == nil) ifFalse:
[
color := aColor
].
self
William,
one thing in Smalltalk is that methods are not stored in files like in ruby or objc. instead methods are objects and stored as such… if you put many methods into one file you need some way to separate them. in Smalltalk it’s typically some sort of chunk-file, so there’s just one junk for each method, or even class definition.
i’d love it if the class definition and method definition could be separated as well in f-script, but having this new syntax is also pretty cool!
one thing i wondered however: what is the definition for a return? is it c-ish via “return aValue” or smalltalkish via “^aValue”? from what i saw in alpha 1, i couldn’t tell.
Karsten
@Mark
Love the consistency, and simplicity, of Smalltalk too. Such qualities are going to be preserved. This new syntax bring so much value that it’s worth adding it, I believe; but such additions are going to be made very conservatively.
Eventually, we might have a syntax for dictionaries literals. I’m also pondering introducing string interpolation.
@William
I’d love to get rid of the “{}” (or equivalent constructs), but there is a need for some markers. For example, in the code you show, the language would have no way to know if “- draw” starts a method definition or if it is a message expression (i.e., invoking the binary method “-” with a variable named “draw” as argument on the object referenced by the variable named “aColor”)
@Karsten
The return instruction (which will be part of alpha 3 too) uses the Smalltalk syntax:
^ aValue
why not use [] instead of {} ?
class Circle : NSObject [
+ circleWithColor: aColor [
self initWithColor: aColor.
]
]
@Norlan
Using “[]” has been considered (actually, this is how GNU Smalltalk does it). The concern is that this bracket notation is already used to denote blocks. Methods are not exactly the same things as blocks and using a similar notation, I fear, would be confusing, especially for beginners.
Note, however, that the syntax is still in flux and might change before the final release. I’m particularly interested by feedback on the proposed syntax.
- Philippe
I knew I’d be no good at this language design stuff. :(
My initial reaction to the curlies{} was that the code looked almost the same as a piece of Objective-C.
Although it is so easy to get hung up the minutia.
As Mark Lee said “One of the most beautiful things about Smalltalk is its consistency.”
I’m not sure what the answer is. Perhaps using ‘def’ to introduce definitions of methods etc. Now that does look odd.
Color<NSObject
def color.
def +circleWithColor:aColor
self alloc initWithColor:aColor
def -draw
color set.
(NSBezierPath bezierPathWithOvalInRect:(400100 extent:100100)) fill
def -initWithColor:aColor
self := super init.
(self == nil) ifFalse:
[
color := aColor
].
self
Phillip, would the new compiler also support the chunk file format? i.e. methods without the {}’s:
myMethod: anArg
^ anArg doSomething.
that’d really be great!!
Karsten, can you tell me more about what it would be useful for?
well, i’d like to write some sort of Smalltalk IDE based on F-Script… methods wouldn’t be saved in one big file, but rather in objects, so there’s no need for the {}’s there….
@Karsten
OK I see. It will be possible to create such an IDE for F-Script (in particular, it will be possible to dynamically modify a given F-Script class).
Note that what such a tool displays does not have to be a directly interpretable linguistic element of the F-Script language. The IDE can display a methods the way it want (e.g. without “{}”).
yeah, that’s true… i think that’ll be the easiest way to write apps for os x, once it’s up and running ;-)
I love F-Script will get support for creating classes. I don’t like the objective-c-ish definition of the clases though, when it should be more like smalltalk.
I’d like something like
NSObject subclass: #Circle
instanceVariables: #color
classMethods: [ #Circle |
Circle<<circleWithColor:aColor
[
self alloc initWithColor:aColor
].
]
instanceMethods: [#Circle |
Circle<<draw
[
color set.
(NSBezierPath bezierPathWithOvalInRect:(400100 extent:100100)) fill
].
Circle<<initWithColor:aColor
[
self := super init.
self == nil ifFalse:
[
color := aColor
].
self
].
]
.
I feel the exact opposite. The use of curly brackets makes it super clear whether your reading a Block or the definition for an Objective-C object, and helps keep the barrier low for new programers coming from Objective-C. Yes, I come from a Cocoa/Objective-C background so am probably biased.
P.S…. A feature request.
Would it be possible to limit the scope of an FSInterpreter that’s embedded into my Cocoa app in the future versions.
I want to use FScript as the language for plugins for my Cocoa app since integrates so well with objects in Objective-C (the transparent conversion of numbers and pointers is just stunningly useful… and array programming !! just wow). But exposing my application to a coding novice is a scary thought.
My ideal would be to offer a default safe mode, which would only have access to a restricted set of classes (foundation classes and some of my own), with an option in the user preferences to allow for the free exploration the internals of my app (after a health warning). I have yet to look at the code too see how feasible this is. But I can’t hurt to ask.
I for one, welcome our new… oops, wrong quote.
I think the hybrid SmallTalk / Objective-C syntax is pretty nice, especially if you’re coming from C-like languages, which arguably more of us use in our daily lives. I’m a big fan of the SuperCollider language, which is very SmallTalk-eque semantically, but very C, Java, JavaScript like syntax wise.
Is there a way to define class variables yet? I keep wanting to write a +sharedInstance methods on my Console class:
Console : NSObject {
stdout
+ sharedInstance {
“Where do I put the shared instance?”
^(Console new)
}
– init {
self := super init.
self == nil ifFalse:
[
stdout := NSFileHandle fileHandleWithStandardOutput
].
^self
}
– print:string {
stdout writeData:(string dataUsingEncoding:4)
}
}
@jzilla
Feedback noted. I’m considering eventually adding a programatic interface for creating classes (e.g., subclass:instanceVaiables:… methods) in addition to the “literal” form shown in this post.
I’m wary of using brackets to delimit methods, as they are already used for blocks. I think braces make the code very clear, as we can imediately see we are dealing we classes and method definitions. Note that this is not particularly un-Smalltalkish, as there is no standard or widely accepted “scripting” syntax in Smalltalk for defining classes.
@Harry
A “safe” mode might be interesting. The idea would be to make it possible to register in the F-Script runtime a list of classes and messages that it would be ok to use from F-Script code. Since the interpreter is in charge of sending messages specified in F-Script code, it could dynamically check each receiver and each message against the authorization list and either allow the code to process or abort. The same kind of mechanism could be added to the object browser too.
I don’t plan to add that right now (because I have a ton of even cooler stuff to implement!) but it should not be hard to add by yourself to your F-Script custom version if you need it.
@Patrick
Thanks for your feedback on the syntax.
No class variables in the current alpha, but this is something that is in the work.
In the meantime, you can implement your + sharedInstance method in Objective-C (in a superclass of your F-Script class) and manage the storage of the shared instance as usual using a static variable.
No expert on Smalltalk or Cocoa here but…
one of the reasons I am interested in F-Script is because it is useful for learning Cocoa while at the same time teaching me Smalltalk.
I think Smalltalk’s time has come, finally.
It seems Squeak/Smalltalk-80 already has a class definition syntax. Everything else being equal, I’d vote for that syntax so as to make my learning portable.
Anyway, thanks for the great work on F-Script.
I think one should stay with the semantics of the language upon which one has chosen to mostly model. Of course, when that language does not provide the syntactic elements to address a particular set of requirements, there often arises other methods which are colloquially known as ‘convention’.
Conventions are, for all intents and purposes, ways to correct perceived flaws in a language. Thats why its always interesting to investigate a new language’s ‘conventions’ even prior to investigating it syntax. Much insight can be gained there.
Of course, this is my opinion, and like butts, everyone has one and they all stink.
The convention in Smalltalk, when discussing classes in documentation perhaps, is to Append ‘>>’ to the class name and follow it with the method name.
I disagree that Methods are dissimilar from blocks. They are simply ‘promoted’ blocks with more responsibilities and benefits. Therefore, its quite acceptable to me to see ‘[ ...blah ]‘ as the definition of a method. It makes perfect sense since a method has a value of some sort usually and provides some service. Finally, if one wants to make clear the difference, use the assignment operator ‘:=’ to do so.
I am from a C background and I’m here to say that I prefer the Smalltalk approach because it is even more concise than is C! Brevity is elegant and useful!