Je viens de Go

Les deux langages sont petits à dessein et compilent en natif. Keal diffère sur trois points : la nullité est dans le type au lieu que chaque pointeur soit nil-able, les génériques compilent vers une copie par instanciation, et l'échec est un throw qu'on attrape plutôt qu'une seconde valeur de retour.

ConceptGoKeal
Liaisonx := 1val x = 1
Mutablevar x = 1var x = 1
Structtype P struct { X int }record P(val x: Int)
Méthodefunc (p P) Len() intfunc length(): Int (inside the class)
Interfacetype Ord interface { … }trait Ord { … }
Nilvar s *string = nilval s: String? = null
Erreurv, err := f(); if err != niltry { f() } catch (e) { … }
Slice[]int{1, 2}[1, 2]
Mapmap[string]int{"a": 1}{"a": 1}
Goroutinego work(ch)sys.spawn({ self, msg -> … })
Switchswitch n { case 0: }when (n) { 0 -> … }

Ce qui vous surprendra

Les erreurs sont lancées, pas retournées

throw "…" et try { } catch (e) { }, sur les trois moteurs y compris le code natif — où cela compile en déroulement vérifié plutôt qu'en setjmp.

Les génériques sont monomorphisés

Une fonction C par instanciation, sans boxing ni passage de dictionnaire. firstOr<T> utilisé en Int et String devient deux fonctions ordinaires.

Des acteurs au lieu de canaux

Il n'y a ni select ni type canal. Un acteur possède son état, les messages sont copiés en profondeur à l'entrée, et le vérificateur refuse un gestionnaire qui atteint un état mutable partagé.

Compilez un paquet Go en c-archive et passez-le à keal build ; l'exemple du dépôt fait exactement cela.