Featherweight Java
„Uvnitř každého velkého jazyka je jazyk menší, který se
snaží probojovat ven.“
– T. Hoare
Featherweight Java (Java lehčí než peří) je teoretický programovací
jazyk, který vznikl kolem roku 2002 jako akademický experiment. Jedná se
o malou podmnožinu jazyka Java, ke
které jsou přidána formální pravidla určující sémantiku. Celý jazyk
přebírá mnoho myšlenek z lambda
kalkulu.
Jeho výhodou je, že je velmi srozumitelný a lze jej bez větších
komplikací přeložit standardním překladačem jazyka Java.
Hlavními rozdíly oproti plnohodnotnému jazyku Java jsou:
- jediným základním kamenem je třída Object, od které se
odvozují další třídy (logické hodnoty, čísla a další)
- každá třída má právě jednoho předka a konstruktor tohoto předka
musí volat ve svém konstruktoru (to platí i pro potomky třídy
Object)
- konstruktory mohou pouze inicializovat předka a vnitřní proměnné ve
stejném pořadí, v jakém byly nadeklarovány
- neexistují žádné modifikátory, cykly, kvalifikátory, ani jiné
složitější konstrukce, z klíčových slov se vyskytuje jen class,
extends, super a return
- žádné proměnné se nemohou během spuštění programu měnit (podobně,
jako kdyby u sebe měly modifikátor final)
- každá metoda obsahuje pouze příkaz return
Syntaxe
Následuje neformální, ale velmi stručný popis syntaxe. Prvky
v hranatých závorkách se mohou několikrát opakovat.
kód v jazyce (žádný) - Zobrazit
-
CLS ::= class CLS extends CLS { [CON f ;] K [MTD ;] }
-
CON ::= CLS ( [CLS f] ) { super ( [f] ) ; [this.f = f ;]
}
-
MTD ::= CLS m ( [CLS x] ) { return EXP ; }
-
EXP ::= x | EXP.f | EXP.m ( [EXP] ) | new CLS ( [ EXP ] ) |
(CLS) EXP
Sémantika
Třída
Každá třída definuje svého předka (svůj nadtyp), seznam proměnných,
konstruktor a další metody.
Konstruktor
Konstruktor inicializuje všechny proměnné třídy ve stejném pořadí,
v jakém jsou nadeklarovány. Konstruktor může mít libovolné množství
argumentů (parametrů). Před inicializací proměnných se musí povinně
zavolat konstruktor předka (nadtypu).
Metoda
Každá metoda má návratovou hodnotu a libovolný počet argumentů
(parametrů).
Výraz
- získání hodnoty proměnné: € e.f €
- volání metody: € e.m(e) €
- vytvoření nové instance třídy: € \mathrm{new} \; C(e) €
- přetypování: € (C) €
Pravidla pro typovou kontrolu
€€ C \; \triangleleft \; C €€ €€ \frac{C \; \triangleleft \; D
\;\;\;\; D \; \triangleleft \; E}{C \; \triangleleft \; E} €€ €€
\frac{\mathrm{class} \; C \; \mathrm{extends} \; D \; \{\ldots\}}{C \;
\triangleleft \; D} €€
Příklady
Uspořádaná dvojice
kód v jazyce Java - Zobrazit
-
/**
-
* Uspořádaná
dvojice.
-
*/
-
class Tuple extends Object
-
{
-
Object first;
-
Object second;
-
-
Tuple(Object f, Object s)
-
{
-
super();
-
this.first = f;
-
this.second = s;
-
}
-
-
Object first()
-
{
-
return first;
-
}
-
-
Object second()
-
{
-
return second;
-
}
-
-
Tuple setFirst(Object f)
-
{
-
return new Tuple(f, this.second);
-
}
-
-
Tuple setSecond(Object s)
-
{
-
return new Tuple(this.first, s);
-
}
-
}
Logické hodnoty
Příklad obsahuje definici logických hodnot (true, false), operátoru
if a základních logických operátorů (and, or, not, equals).
kód v jazyce Java - Zobrazit
-
/**
-
* Nedefinovaná
hodnota.
-
*/
-
class Unknown extends Object
-
{
-
public Unknown()
-
{
-
super();
-
}
-
}
-
-
/**
-
* Nedefinovaná logická
hodnota.
-
*/
-
class UnknownBool extends Bool
-
{
-
UnknownBool()
-
{
-
super();
-
}
-
}
-
-
/**
-
* Logická hodnota.
-
*/
-
class Bool extends Object
-
{
-
Bool()
-
{
-
super();
-
}
-
-
Object ifStatement(Object thenCase, Object elseCase)
-
{
-
return new Unknown();
-
}
-
-
Bool not()
-
{
-
return new UnknownBool();
-
}
-
-
Bool and(Bool other)
-
{
-
return new UnknownBool();
-
}
-
-
Bool or(Bool other)
-
{
-
return new UnknownBool();
-
}
-
-
Bool equals(Bool other)
-
{
-
return new UnknownBool();
-
}
-
}
-
-
/**
-
* Hodnota TRUE.
-
*/
-
class TrueBool extends Bool
-
{
-
TrueBool()
-
{
-
super();
-
}
-
-
Object ifStatement(Object thenCase, Object elseCase)
-
{
-
// podmínka je TRUE, vykoná
se první větev
-
return thenCase;
-
}
-
-
Bool not()
-
{
-
// negace TRUE je
FALSE
-
return new FalseBool();
-
}
-
-
Bool and(Bool other)
-
{
-
// toto je TRUE, výsledek
závisí jen na druhé hodnotě
-
return other;
-
}
-
-
Bool or(Bool other)
-
{
-
// jeden z operátorů je
TRUE
-
// výsledek tedy nezávisí na
druhé hodnotě a je vždy TRUE
-
return this;
-
}
-
-
Bool equals(Bool other)
-
{
-
// je-li druhý TRUE: (TRUE ==
TRUE) == TRUE
-
// je-li druhý FALSE: (TRUE ==
FALSE) == FALSE
-
// výsledek je roven druhému
operandu
-
return other;
-
}
-
}
-
-
/**
-
* Hodnota FALSE.
-
*/
-
class FalseBool extends Bool
-
{
-
FalseBool()
-
{
-
super();
-
}
-
-
Object ifStatement(Object thenCase, Object elseCase)
-
{
-
// podmínka je FALSE, vykoná
se druhá větev
-
return elseCase;
-
}
-
-
Bool not()
-
{
-
// negace FALSE je
TRUE
-
return new TrueBool();
-
}
-
-
Bool and(Bool other)
-
{
-
// jeden z operátorů je
FALSE
-
// výsledek tedy nezávisí na
druhé hodnotě a je vždy FALSE
-
return this;
-
}
-
-
Bool or(Bool other)
-
{
-
// toto je FALSE, výsledek
závisí jen na druhé hodnotě
-
return other;
-
}
-
-
Bool equals(Bool other)
-
{
-
// je-li druhý TRUE: (FALSE ==
TRUE) == FALSE
-
// je-li druhý FALSE: (FALSE
== FALSE) == TRUE
-
// výsledek je roven negaci
druhého operandu
-
return other.not();
-
}
-
}
Přirozená čísla
Příklad obsahuje definici přirozených čísel spolu se sčítáním,
rovností a ověřováním nulovosti.
K vytvoření základní implementace přirozených čísel je třeba
využít výše definované logické hodnoty.
kód v jazyce Java - Zobrazit
-
/**
-
* Přirozená číslo.
-
*/
-
class NaturalNumber extends Object
-
{
-
NaturalNumber()
-
{
-
super();
-
}
-
-
Bool isZero()
-
{
-
return new UnknownBool();
-
}
-
-
Bool isEqual(NaturalNumber
other)
-
{
-
return new UnknownBool();
-
}
-
-
Bool isEqual(Zero
other)
-
{
-
return new UnknownBool();
-
}
-
-
Bool isEqual(NonZero
other)
-
{
-
return new UnknownBool();
-
}
-
-
NaturalNumber plus(NaturalNumber other)
-
{
-
return new UnknownNumber();
-
}
-
-
NaturalNumber increment()
-
{
-
return new NonZero(this);
-
}
-
-
NaturalNumber decrement()
-
{
-
return new UnknownNumber();
-
}
-
}
-
-
/**
-
* Neznámé číslo.
-
*/
-
class UnknownNumber extends NaturalNumber
-
{
-
UnknownNumber()
-
{
-
super();
-
}
-
}
-
-
/**
-
* Nula.
-
*/
-
class Zero extends NaturalNumber
-
{
-
Zero()
-
{
-
super();
-
}
-
-
Bool isZero()
-
{
-
return new TrueBool();
-
}
-
-
Bool isEqual(NaturalNumber
other)
-
{
-
// (simulace double
dispatch)
-
return other.isEqual(this);
-
}
-
-
Bool isEqual(Zero
other)
-
{
-
// nula je rovna
nule
-
return new TrueBool();
-
}
-
-
Bool isEqual(NonZero
other)
-
{
-
// nula není rovna
nenule
-
return new FalseBool();
-
}
-
-
NaturalNumber plus(NaturalNumber other)
-
{
-
// nula + A = A
-
return other;
-
}
-
}
-
-
/**
-
* Nenula.
-
*/
-
class NonZero extends NaturalNumber
-
{
-
NaturalNumber previous;
-
-
NonZero(NaturalNumber
prev)
-
{
-
super();
-
this.previous = prev;
-
}
-
-
Bool isZero()
-
{
-
return new FalseBool();
-
}
-
-
Bool isEqual(NaturalNumber
other)
-
{
-
// (simulace double
dispatch)
-
return other.isEqual(this);
-
}
-
-
Bool isEqual(Zero
other)
-
{
-
// nenula není rovna
nule
-
return new FalseBool();
-
}
-
-
Bool isEqual(NonZero
other)
-
{
-
// N == N právě když N-1 ==
N-1
-
// na konci narazí rekurze na
nulu
-
return other.previous.isEqual(this.previous);
-
}
-
-
NaturalNumber plus(NaturalNumber other)
-
{
-
// první sčítanec klesá k
nule, druhý se zvyšuje
-
// na konci narazí rekurze na
nulu
-
return previous.plus(new NonZero(other));
-
}
-
-
NaturalNumber decrement()
-
{
-
return previous;
-
}
-
}
Ćíslice 1–10
Číslo 0 je definované již výše. Čísla v poziční desítkové
soustavě by se dala reprezentovat jako seznam těchto číslic, které lze
převést na přirozené číslo postupným rekurzivním násobením na řád
umocněným základem soustavy (10).
kód v jazyce Java - Zobrazit
-
/**
-
* 1
-
*/
-
class One extends NonZero
-
{
-
One()
-
{
-
// 1 = 1 + 0
-
super(new Zero());
-
}
-
}
-
-
/**
-
* 2
-
*/
-
class Two extends NonZero
-
{
-
Two()
-
{
-
// 2 = 1 + 1
-
super(new One());
-
}
-
}
-
-
/**
-
* 3
-
*/
-
class Three extends NonZero
-
{
-
Three()
-
{
-
// 3 = 1 + 2
-
super(new Two());
-
}
-
}
-
-
/**
-
* 4
-
*/
-
class Four extends NonZero
-
{
-
Four()
-
{
-
// 4 = 1 + 3
-
super(new Three());
-
}
-
}
-
-
/**
-
* 5
-
*/
-
class Five extends NonZero
-
{
-
Five()
-
{
-
// 5 = 1 + 4
-
super(new Four());
-
}
-
}
-
-
/**
-
* 6
-
*/
-
class Six extends NonZero
-
{
-
Six()
-
{
-
// 6 = 1 + 5
-
super(new Five());
-
}
-
}
-
-
/**
-
* 7
-
*/
-
class Seven extends NonZero
-
{
-
Seven()
-
{
-
// 7 = 1 + 6
-
super(new Six());
-
}
-
}
-
-
/**
-
* 8
-
*/
-
class Eight extends NonZero
-
{
-
Eight()
-
{
-
// 8 = 1 + 7
-
super(new Seven());
-
}
-
}
-
-
/**
-
* 9
-
*/
-
class Nine extends NonZero
-
{
-
Nine()
-
{
-
// 9 = 1 + 8
-
super(new Eight());
-
}
-
}
-
-
/**
-
* 10
-
*/
-
class Ten extends NonZero
-
{
-
Ten()
-
{
-
// 10 = 1 + 9
-
super(new Nine());
-
}
-
}
Seznam
kód v jazyce Java - Zobrazit
-
/**
-
* Seznam.
-
*/
-
class List
extends Object
-
{
-
List()
-
{
-
super();
-
}
-
-
NaturalNumber size()
-
{
-
return new UnknownNumber();
-
}
-
}
-
-
/**
-
* Prázdný seznam.
-
*/
-
class EmptyList extends List
-
{
-
EmptyList()
-
{
-
super();
-
}
-
-
NaturalNumber size()
-
{
-
// prázdný seznam má délku
0
-
return new Zero();
-
}
-
}
-
-
/**
-
* Neprázdný seznam (jednosměrně
zřetězený).
-
*/
-
class ListValue extends List
-
{
-
Object value;
-
List tail;
-
-
ListValue(Object value, List tail)
-
{
-
super();
-
this.value = value;
-
this.tail = tail;
-
}
-
-
NaturalNumber size()
-
{
-
// velikost neprázdného
seznamu je 1 + délka seznamu bez hlavičky
-
return new NonZero(tail.size());
-
}
-
-
Object value()
-
{
-
return value;
-
}
-
-
List tail()
-
{
-
return tail;
-
}
-
}
Reference