Domů » Informatika » Programovací jazyk » Featherweight Java


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, superreturn
  • žá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

  1. CLS ::= class CLS extends CLS { [CON f ;] K [MTD ;] }
  2. CON ::= CLS ( [CLS f] ) { super ( [f] ) ; [this.f = f ;] }
  3. MTD ::= CLS m ( [CLS x] ) { return EXP ; }
  4. 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

  1. /**
  2.  * Uspořádaná dvojice.
  3.  */
  4. class Tuple extends Object
  5. {
  6.   Object first;
  7.   Object second;
  8.  
  9.   Tuple(Object f, Object s)
  10.   {
  11.     super();
  12.     this.first = f;
  13.     this.second = s;
  14.   }
  15.  
  16.   Object first()
  17.   {
  18.     return first;
  19.   }
  20.  
  21.   Object second()
  22.   {
  23.     return second;
  24.   }
  25.  
  26.   Tuple setFirst(Object f)
  27.   {
  28.     return new Tuple(f, this.second);
  29.   }
  30.  
  31.   Tuple setSecond(Object s)
  32.   {
  33.     return new Tuple(this.first, s);
  34.   }
  35. }
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

  1. /**
  2.  * Nedefinovaná hodnota.
  3.  */
  4. class Unknown extends Object
  5. {
  6.   public Unknown()
  7.   {
  8.     super();
  9.   }
  10. }
  11.  
  12. /**
  13.  * Nedefinovaná logická hodnota.
  14.  */
  15. class UnknownBool extends Bool
  16. {
  17.   UnknownBool()
  18.   {
  19.     super();
  20.   }
  21. }
  22.  
  23. /**
  24.  * Logická hodnota.
  25.  */
  26. class Bool extends Object
  27. {
  28.   Bool()
  29.   {
  30.     super();
  31.   }
  32.  
  33.   Object ifStatement(Object thenCase, Object elseCase)
  34.   {
  35.     return new Unknown();
  36.   }
  37.  
  38.   Bool not()
  39.   {
  40.     return new UnknownBool();
  41.   }
  42.  
  43.   Bool and(Bool other)
  44.   {
  45.     return new UnknownBool();
  46.   }
  47.  
  48.   Bool or(Bool other)
  49.   {
  50.     return new UnknownBool();
  51.   }
  52.  
  53.   Bool equals(Bool other)
  54.   {
  55.     return new UnknownBool();
  56.   }
  57. }
  58.  
  59. /**
  60.  * Hodnota TRUE.
  61.  */
  62. class TrueBool extends Bool
  63. {
  64.   TrueBool()
  65.   {
  66.     super();
  67.   }
  68.  
  69.   Object ifStatement(Object thenCase, Object elseCase)
  70.   {
  71.     // podmínka je TRUE, vykoná se první větev
  72.     return thenCase;
  73.   }
  74.  
  75.   Bool not()
  76.   {
  77.     // negace TRUE je FALSE
  78.     return new FalseBool();
  79.   }
  80.  
  81.   Bool and(Bool other)
  82.   {
  83.     // toto je TRUE, výsledek závisí jen na druhé hodnotě
  84.     return other;
  85.   }
  86.  
  87.   Bool or(Bool other)
  88.   {
  89.     // jeden z operátorů je TRUE
  90.     // výsledek tedy nezávisí na druhé hodnotě a je vždy TRUE
  91.     return this;
  92.   }
  93.  
  94.   Bool equals(Bool other)
  95.   {
  96.     // je-li druhý TRUE: (TRUE == TRUE) == TRUE
  97.     // je-li druhý FALSE: (TRUE == FALSE) == FALSE
  98.     // výsledek je roven druhému operandu
  99.     return other;
  100.   }
  101. }
  102.  
  103. /**
  104.  * Hodnota FALSE.
  105.  */
  106. class FalseBool extends Bool
  107. {
  108.   FalseBool()
  109.   {
  110.     super();
  111.   }
  112.  
  113.   Object ifStatement(Object thenCase, Object elseCase)
  114.   {
  115.     // podmínka je FALSE, vykoná se druhá větev
  116.     return elseCase;
  117.   }
  118.  
  119.   Bool not()
  120.   {
  121.     // negace FALSE je TRUE
  122.     return new TrueBool();
  123.   }
  124.  
  125.   Bool and(Bool other)
  126.   {
  127.     // jeden z operátorů je FALSE
  128.     // výsledek tedy nezávisí na druhé hodnotě a je vždy FALSE
  129.     return this;
  130.   }
  131.  
  132.   Bool or(Bool other)
  133.   {
  134.     // toto je FALSE, výsledek závisí jen na druhé hodnotě
  135.     return other;
  136.   }
  137.  
  138.   Bool equals(Bool other)
  139.   {
  140.     // je-li druhý TRUE: (FALSE == TRUE) == FALSE
  141.     // je-li druhý FALSE: (FALSE == FALSE) == TRUE
  142.     // výsledek je roven negaci druhého operandu
  143.     return other.not();
  144.   }
  145. }
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

  1. /**
  2.  * Přirozená číslo.
  3.  */
  4. class NaturalNumber extends Object
  5. {
  6.   NaturalNumber()
  7.   {
  8.     super();
  9.   }
  10.  
  11.   Bool isZero()
  12.   {
  13.     return new UnknownBool();
  14.   }
  15.  
  16.   Bool isEqual(NaturalNumber other)
  17.   {
  18.     return new UnknownBool();
  19.   }
  20.  
  21.   Bool isEqual(Zero other)
  22.   {
  23.     return new UnknownBool();
  24.   }
  25.  
  26.   Bool isEqual(NonZero other)
  27.   {
  28.     return new UnknownBool();
  29.   }
  30.  
  31.   NaturalNumber plus(NaturalNumber other)
  32.   {
  33.     return new UnknownNumber();
  34.   }
  35.  
  36.   NaturalNumber increment()
  37.   {
  38.     return new NonZero(this);
  39.   }
  40.  
  41.   NaturalNumber decrement()
  42.   {
  43.     return new UnknownNumber();
  44.   }
  45. }
  46.  
  47. /**
  48.  * Neznámé číslo.
  49.  */
  50. class UnknownNumber extends NaturalNumber
  51. {
  52.   UnknownNumber()
  53.   {
  54.     super();
  55.   }
  56. }
  57.  
  58. /**
  59.  * Nula.
  60.  */
  61. class Zero extends NaturalNumber
  62. {
  63.   Zero()
  64.   {
  65.     super();
  66.   }
  67.  
  68.   Bool isZero()
  69.   {
  70.     return new TrueBool();
  71.   }
  72.  
  73.   Bool isEqual(NaturalNumber other)
  74.   {
  75.     // (simulace double dispatch)
  76.     return other.isEqual(this);
  77.   }
  78.  
  79.   Bool isEqual(Zero other)
  80.   {
  81.     // nula je rovna nule
  82.     return new TrueBool();
  83.   }
  84.  
  85.   Bool isEqual(NonZero other)
  86.   {
  87.     // nula není rovna nenule
  88.     return new FalseBool();
  89.   }
  90.  
  91.   NaturalNumber plus(NaturalNumber other)
  92.   {
  93.     // nula + A = A
  94.     return other;
  95.   }
  96. }
  97.  
  98. /**
  99.  * Nenula.
  100.  */
  101. class NonZero extends NaturalNumber
  102. {
  103.   NaturalNumber previous;
  104.  
  105.   NonZero(NaturalNumber prev)
  106.   {
  107.     super();
  108.     this.previous = prev;
  109.   }
  110.  
  111.   Bool isZero()
  112.   {
  113.     return new FalseBool();
  114.   }
  115.  
  116.   Bool isEqual(NaturalNumber other)
  117.   {
  118.     // (simulace double dispatch)
  119.     return other.isEqual(this);
  120.   }
  121.  
  122.   Bool isEqual(Zero other)
  123.   {
  124.     // nenula není rovna nule
  125.     return new FalseBool();
  126.   }
  127.  
  128.   Bool isEqual(NonZero other)
  129.   {
  130.     // N == N právě když N-1 == N-1
  131.     // na konci narazí rekurze na nulu
  132.     return other.previous.isEqual(this.previous);
  133.   }
  134.  
  135.   NaturalNumber plus(NaturalNumber other)
  136.   {
  137.     // první sčítanec klesá k nule, druhý se zvyšuje
  138.     // na konci narazí rekurze na nulu
  139.     return previous.plus(new NonZero(other));
  140.   }
  141.  
  142.   NaturalNumber decrement()
  143.   {
  144.     return previous;
  145.   }
  146. }
Ćí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. /**
  2.  * 1
  3.  */
  4. class One extends NonZero
  5. {
  6.   One()
  7.   {
  8.     // 1 = 1 + 0
  9.     super(new Zero());
  10.   }
  11. }
  12.  
  13. /**
  14.  * 2
  15.  */
  16. class Two extends NonZero
  17. {
  18.   Two()
  19.   {
  20.     // 2 = 1 + 1
  21.     super(new One());
  22.   }
  23. }
  24.  
  25. /**
  26.  * 3
  27.  */
  28. class Three extends NonZero
  29. {
  30.   Three()
  31.   {
  32.     // 3 = 1 + 2
  33.     super(new Two());
  34.   }
  35. }
  36.  
  37. /**
  38.  * 4
  39.  */
  40. class Four extends NonZero
  41. {
  42.   Four()
  43.   {
  44.     // 4 = 1 + 3
  45.     super(new Three());
  46.   }
  47. }
  48.  
  49. /**
  50.  * 5
  51.  */
  52. class Five extends NonZero
  53. {
  54.   Five()
  55.   {
  56.     // 5 = 1 + 4
  57.     super(new Four());
  58.   }
  59. }
  60.  
  61. /**
  62.  * 6
  63.  */
  64. class Six extends NonZero
  65. {
  66.   Six()
  67.   {
  68.     // 6 = 1 + 5
  69.     super(new Five());
  70.   }
  71. }
  72.  
  73. /**
  74.  * 7
  75.  */
  76. class Seven extends NonZero
  77. {
  78.   Seven()
  79.   {
  80.     // 7 = 1 + 6
  81.     super(new Six());
  82.   }
  83. }
  84.  
  85. /**
  86.  * 8
  87.  */
  88. class Eight extends NonZero
  89. {
  90.   Eight()
  91.   {
  92.     // 8 = 1 + 7
  93.     super(new Seven());
  94.   }
  95. }
  96.  
  97. /**
  98.  * 9
  99.  */
  100. class Nine extends NonZero
  101. {
  102.   Nine()
  103.   {
  104.     // 9 = 1 + 8
  105.     super(new Eight());
  106.   }
  107. }
  108.  
  109. /**
  110.  * 10
  111.  */
  112. class Ten extends NonZero
  113. {
  114.   Ten()
  115.   {
  116.     // 10 = 1 + 9
  117.     super(new Nine());
  118.   }
  119. }
Seznam

kód v jazyce Java - Zobrazit

  1. /**
  2.  * Seznam.
  3.  */
  4. class List extends Object
  5. {
  6.   List()
  7.   {
  8.     super();
  9.   }
  10.  
  11.   NaturalNumber size()
  12.   {
  13.     return new UnknownNumber();
  14.   }
  15. }
  16.  
  17. /**
  18.  * Prázdný seznam.
  19.  */
  20. class EmptyList extends List
  21. {
  22.   EmptyList()
  23.   {
  24.     super();
  25.   }
  26.  
  27.   NaturalNumber size()
  28.   {
  29.     // prázdný seznam má délku 0
  30.     return new Zero();
  31.   }
  32. }
  33.  
  34. /**
  35.  * Neprázdný seznam (jednosměrně zřetězený).
  36.  */
  37. class ListValue extends List
  38. {
  39.   Object value;
  40.   List tail;
  41.  
  42.   ListValue(Object value, List tail)
  43.   {
  44.     super();
  45.     this.value = value;
  46.     this.tail = tail;
  47.   }
  48.  
  49.   NaturalNumber size()
  50.   {
  51.     // velikost neprázdného seznamu je 1 + délka seznamu bez hlavičky
  52.     return new NonZero(tail.size());
  53.   }
  54.  
  55.   Object value()
  56.   {
  57.     return value;
  58.   }
  59.  
  60.   List tail()
  61.   {
  62.     return tail;
  63.   }
  64. }

Reference