F3: New statically typed scripting language for java

Chris Oliver has been working on F3 ("form follows function"), a new scripting language for the java platform. Here is a detailed description of F3's features.

It is already in heavy development but not yet released, and there are plugins for both Netbeans and Eclipse. Some of its functionality and the examples Chris has shared indicate it could be an alternative to Flash and processing.

Summary of some of its features:

• It is case-sensitive and uses curly braces, so it is very java-like.
• It is statically typed with type inference (like boo). It uses "var" for type inferenced declarations (var x = 3;), like in groovy or C# 3.0.
• It supports a JSON-like declarative syntax for building GUIs (as opposed to XML or YAML).
• Has a ".." range literal: var result = sum([1,3..100]);
• Supports SQL notation for querying arrays:
var squares = select n*n from n in [1..100];
//another example:
var titleTracks =
select indexof track + 1 from album in albums,
track in album.tracks
where track == album.title; // yields [1,4]

• You can also embed the JSON-like syntax in code (or vice-versa):
        var chris = Person {
name: "Chris"
children:
[Person {
name: "Dee"
},
Person {
name: "Candice"
}]
};

• Supports expressions inside strings:
var answer = true;
var s = "The answer is {if answer then "Yes" else "No"}"; // s = 'The answer is Yes'

• Supports "do" or "do later" for code that either allows background events to occur or runs in a background thread itself:
        import java.lang.System;
var saying1 = "Hello World!";
var saying2 = "Goodbye Cruel World!";
do later {
System.out.println(saying1);
}
System.out.println(saying2);

• It may be using a MultiVM technique where different applications run in the same JVM instance, saving memory and improving start-up time.
• All methods and attributes of a class have to be declared first (like in C and C++, yay), and then the implementations are written outside the class body (like in nice).
• Instead of constructors and setters, F3 uses "triggers":
         import java.lang.System;
class X {
attribute nums: Number*;
}
trigger on new X {
insert [3,4] into this.nums;
}
var x = new X();
System.out.println(x.nums == [3,4]); // prints true


Comment viewing options

Separating declarations and definitions

All methods and attributes of a class have to be declared first (like in C and C++, yay), and then the implementations are written outside the class body (like in nice).

Does that mean every time you add, rename, or change the signature of a method, you have to edit two different pieces of text? If so, can you explain why that elicits a "yay" not a "boo, hiss"?

I think that the 'yay' was

I think that the 'yay' was sarcastic.

Triggers

Aren't triggers just a special kind of method/operator overloading? Or even less in that they just add behaviour to an operation as they do in all examples?

Edit: Ah..., there are many triggers per attribute, not per class. This makes an important difference of course. In other languages we would have to define a class first, overload methods and create a member variable with an object instance. In f3 one might skip the class creation and define additional behaviours per member variable/operator using "triggers".

I'm also not sure about bind? I would expect binding a function f to an attribute a1 being updated when the value of another attribute a2 is modified. So far I have the impression that bind just creates an object reference.

F3

Hi,

I'm not exactly sure how relevant F3 is on this forum, but I'd be happy to discuss it as well as the problem it tries to solve and any input or criticism is appreciated. I started trying to write a comment to try to put F3 into perspective, but it got too big so I posted in on my weblog here.

Hi Chris, I like your F3

Hi Chris,

I like your F3 project a lot as it resembles my SuperGlue project (declarative, object-oriented, support for time-varying values) and I believe this is the future of scripting. Have you thought about writing a paper or tech report on the language? It would be nice to see more of this kind of material at ECOOP and OOPSLA.

SuperGlue

Thanks, I see the resemblance to SuperGlue.

Here's a link to something I came across related to this subject that this forum might find interesting Monads for Incremental Computing

Thanks! I have a hard time

Thanks! I have a hard time grokking Haskell code, which is funny since I'm supposed to be a language researcher. You might want to check out FlapJax: http://www.flapjax-lang.org/, which is a JavaScript version of their FrTime system (functional-reactive programming on Scheme). This stuff is a bit more approachable than the Haskell-based FRP. All very related to F3, and I think we'll be seeing more things like this in the future.

hiya

Chris, I actually tried to send you an email, but could not find the address anywhere and guessed. I've been coding a lot on Flapjax and am very curious about your approach to objects in F3. At least based on the initial posts, it seems like a transparent reactive / data flow system, though the more recent entries make it seem to facilitate more traditional code. Any discussions of your choices and experiences with recursion/cycles, state accumulation, collections, and your object system would probably be very enlightening. Alternatively, my email is my username @cs.brown.edu .

Again, I'm curious to see what you're actually doing :)

dataflow

This stuff is incredibly interesting to me and I would love to be able to use it in my day job. Luckily this has been discussed several times here:

Perhaps the best description of Functional Reactive Programming is in this paper: Embedding Dynamic Dataflow in a Call-by-Value Language.

The Haskell version of FRP is indeed not an easy read, but this is completely incomprehensible to me: The essence of Dataflow Programming (and sigfpe's writeup on comonads doesn't help).

Don Syme has an article on Imperative Reactive Programming using his F# language.

Sean's PhD dissertation on SuperGlue contains interesting information for those who wish to apply FRP concepts to some real-world problems (GUI data binding, etc.).

I think FRP or data flow is one of those things that is still getting cooked in the academic world, but goes to the heart of many practical, day-to-day problems faced by developers.

I'm very much looking forward to F3 and Scala's versions of data-flow'esque features.

An Eyesore

I know beauty is in the eye of the beholder and all that, but god, what an eyesore. I think that nesting curly braces inside other expressions gives rise to some very ugly looking code....Not that it's terribly better in a verbose language like Java or C, but at least the curly brackets have a fairly uniform usage. Oh well, to each his own, I suppose.

Agree that bracketed

Agree that bracketed lists of curly-brace delimited object literals aren't very nice. In C struct literals use curly braces. In C and Java array literals use curly braces. For F3 I followed JavaScript and used brackets for arrays. I don't have any great ideas for alternatives at the moment. I don't see any great alternative to using curly braces to delimit expressions inside string literals either. But maybe someone else does...

There are two issues. Array

There are two issues. Array literals (also called array initializers) and new array constructions.

One possibility is to use square brackets "[]" to denote both of these, in the same sort of way that some variants of Lisp allow using parentheses to construct new lists (often as shorthand notation for a series of cons's).

I think the reason that Java does not do this is because for new array creations, it requires type inference (specifically, unification) to figure out the type of the list from the types of the elements inside, and an empty array literal doesn't have any information to infer the type (and cannot really be given a parameterized type because of Java's retarded generics system).

Java:
 int[] x = { 0, 1 }; int[] x = new int[2] {0, 1}; f(new int[2] { 0, 1 }); 

With sufficient type inference a language could support:

 var x = [0, 1]; var x = [0, 1]; f([0, 1]); 

Which would generate identical machine or byte code as the Java code given above.