Your first Featherweight Java program
FJ's smallest program is barely a program at all — one class, one field, one expression. Building it is still the fastest way to see the parts that make BFJ worth using: a constructor that appears without being asked for, and two semantics views that fill in the moment you press Run.
A workspace with nothing assumed
A fresh BFJ workspace is empty, and that emptiness is deliberate. FJ has no main, no
static entry point, no Goal wrapper the way B-MJ does — a program is simply a
set of class declarations plus one loose top-level expression sitting beside them on the canvas,
and that loose expression is the thing that actually gets reduced. Nothing stops you from
dropping several candidate expressions down at once; only the one you Run, or Load into a
stepper, is evaluated.
Your first class
Build the shipped Field access example by hand once, so the pieces are familiar later:
- From Class, drag an
fj_classblock onto the workspace. Name itAand leave itextends Object. - From Members, drag an
fj_fieldblock into the class's field socket and give it a type and a name —Object fis enough. - Look at what is already sitting under the field. That is covered next.
- Drop an
fj_newblock from Expressions beside the class, set it toA, then chain anfj_field_accessonto it for.f. This loose expression,new A().f, is your program.
That is also exactly the shipped Field access example, so if a step feels fiddly the first time, load the example from the Examples menu instead and read the blocks it produced.
The constructor writes itself
Notice there was no step above for building a constructor. fj_ctor is already
attached under the field list, and it has no sockets to fill in — it is labelled
constructor (auto) and stays that way.
FJ's own typing rules say the constructor for a class is fully determined by
fields(C) — the class's fields plus its superclass's fields, in order.
BFJ enforces that literally: fj_ctor is synthesized, not built, so there is no
way to construct two different block trees that mean the same class. That is what keeps the
block↔AST bijection proved in chapter 06 from
breaking on day one. See Blocks for the full argument.
The Editable Code panel
Open the FJ Inspector's Editable Code tab. It already shows genuine, javac-shaped Java
source for the class and expression you just built, including the synthesized constructor's
super(...) call. Add a second field and watch the constructor's parameter list and
body grow in the text before you have touched anything else — the panel is synchronised
live in both directions, the same parser and printer covered in
Translation.
Running it
▶ Run in the workspace title bar reduces the expression to a value and
puts it on the Inspector's Output tab. For new A().f that value is
null-free by construction — FJ has no null, so a field that was
never assigned anything but a value obtained the same way still prints as a fully-applied
constructor call.
Open the bottom dock with Ctrl + J and press Load on the Reduction tab: it precomputes the whole substitution trace for your expression, one numbered line per step, each tagged with the rule that fired. Do the same on CK Machine and you get the same reduction again, this time as an explicit Control/Kontinuation pair you can Step and Back through one transition at a time. Both are the subject of chapter 05.
Searching the toolbox
Press Ctrl + Shift + F, or use the search field at the top of the
sidebar, to filter block labels and category names live — useful once you are past the
thirteen blocks in the toolbox and just want
fj_invk without scrolling past Types and Arguments to find
it.