Umka ist eine statisch typisierte, einbettbare Skriptsprache. Es kombiniert die für die Skripterstellung erforderliche Einfachheit und Flexibilität mit einem Schutz vor Typfehlern zur Kompilierungszeit. Ziel ist es, dem Python-Zen-Prinzip zu folgen. Explizit ist besser als implizit, konsistenter als dynamisch typisierte Sprachen im Allgemeinen.
400 x 400 Matrixmultiplikation (AMD A4-3300M bei 1,9 GHz, Windows 7)
fn main() {
printf("Hello Umka!n")
}
const a = 3
const b* = 2.38 // Exported identifier
const (
c = sin(b) / 5
d = "Hello" + " World"
)
type IntPtr = ^uint16 // Pointer
type Arr = [a]real // Array
type (
DynArr = [][5]int // Dynamic array
String = str // String
Button = enum { // Enumeration
left
middle
right
}
MyMap = map[str]real // Map
Quat = struct { // Structure
q: [4]real
normalized: bool
}
Printable = interface { // Interface
print(): int
}
ErrFn = fn(code: int) // Function
)
var e: int
var f: String = d + "!"
var (
g: Arr = [3]real{2.3, -4.1 / 2, b}
h: DynArr
m: MyMap
)
q := Quat{q: [4]real{1, 0, 0, 0}, normalized: true}
fn tan(x: real): real {return sin(x) / cos(x)}
fn getValue(): (int, bool) {return 42, true}
fn (a: ^Arr) print(): int {
printf("Arr: %vn", a^)
return 0
}
h = make([][5]int, 3) // Dynamic arrays and maps are initialized with make()
m = make(MyMap)
m["Hello Umka"] = 3.14
sum := 0.0
y := tan(30 * std::pi / 180)
h = append(h, [5]int{10, 20, 30, 40, 50})
h = delete(h, 1)
g.print()
if x, ok := getValue(); ok {
printf("Got %vn", x)
}
switch a {
case 1, 3, 5, 7: std::println(std::itoa(a) + " is odd")
case 2, 4, 6, 8: std::println(std::itoa(a) + " is even")
default: std::println("I don't know")
}
switch v := type(a) {
case int: printf("int: %d + 5 = %dn", v, v + 5)
case str: printf("str: %s + 5 = %sn", v, v + "5")
default: printf("unknown: %vn", a)
}
for k := 1; k <= 128; k *= 2 {
printf("%vn", k)
}
for i, x in g {
if fabs(x) > 1e12 {break}
if x < 0 {continue}
sum += x
}
a := new(int)
child := make(fiber, |a| {
for i := 0; i < 5; i++ {
std::println("Child : i=" + std::itoa(i) + " buf=" + std::itoa(a^))
a^ = i * 3
resume()
}
})
for i := 0; i < 10; i++ {
std::println("Parent: i=" + std::itoa(i) + " buf=" + std::itoa(a^))
a^ = i * 7
if valid(child) {
resume(child)
}
}
Während Go eine kompilierte Systemprogrammiersprache mit einer komplexen Laufzeitbibliothek und großen Ausgabebinärdateien ist, ist Umka eine Skriptsprache mit einem schlanken Interpreter, der als gemeinsam genutzte Bibliothek problemlos in jede Anwendung eingebettet werden kann.
Syntaktisch ist Umka Go sehr ähnlich. In einigen Aspekten ist es jedoch anders. Es hat kürzere Schlüsselwörter: fn
für func
, str
für string
, in
für range
. Zur besseren Lesbarkeit ist in Deklarationen ein :
zwischen Variablennamen und -typen erforderlich. Es folgt nicht der unglücklichen C-Tradition der Zeiger-Dereferenzierung. Anstelle von *p
wird die Pascal-Syntax p^
verwendet. Da das *
-Zeichen nicht mehr für Zeiger verwendet wird, wird es wie in Oberon zum Exportzeichen, sodass ein Programmierer frei Groß-/Kleinbuchstaben in Bezeichnern gemäß seinem eigenen Stil verwenden kann. Typzusicherungen haben keine spezielle Syntax; Sie sehen aus wie Umwandlungen vom Typ Zeiger. Abschlussdefinitionen erfordern explizite Listen erfasster Variablen.
Umka ermöglicht implizite Typumwandlungen und unterstützt Standardparameter in Funktionsdeklarationen. Es enthält den ternären Bedingungsoperator, der in Go bewusst weggelassen wurde. Es gibt keine Slices als separate Datentypen. Stattdessen unterstützt es dynamische Arrays, die wie die Slices von Go deklariert und durch den Aufruf von make()
initialisiert werden. Methodenempfänger müssen Zeiger sein. Das Multithreading-Modell in Umka ist eher von Lua und Wren als von Go inspiriert. Es bietet leichte Fäden, sogenannte Fasern, anstelle von Goroutinen und Kanälen. Der Garbage-Collection-Mechanismus basiert auf der Referenzzählung, daher muss Umka weak
Zeiger unterstützen. Vollständige Unicode-Unterstützung ist in der Entwicklung.