Scala - gimmicks
Věci, které mě zaujaly natolik, abych o nich napsal aspoň jednu větu, ale nemají na vlastní článek.
for println
Pokud chcete něco vypsat upostřed for comprehension s mnoha generátory, můžete to udělat takto:
for { c <- collection _ = println(c) s <- c.subCollection } yield s
Vnořené komentáře
Scala podporuje strukturované komentáře. Každý začátek víceřádkového komentáře /*
musí mít odpovídající ukončení */
. Na první pohled se to může jevit jako zbytečnost, ale ve skutečnosti je to docela užitečná funkce.
Když mám nějaký takovýhle kód:
code
/*
anotherCode
*/
stuff
andNowSomethingCompletelyDifferent
A chchi zakomentovat blok od code
do stuff
:
/*
code
/*
anotherCode
*/
stuff
*/
andNowSomethingCompletelyDifferent
Se strukturovanými komentáři to funguje přesně jak člověk zamýšlel. Kdyby Scala měla šla tradiční cestou, kdy komentář skončí jakmile narazí na */
, nevungovalo by to, protože stuff
by byl už mimo.
Vnitřní metody definované přes def vs. =>
// tyto dva zápisy jsou ekvivalentní // funkce x vrátí funkci, která vrací Int, tedy () => () => Int def x = { () => 2 } def x = { def a = 2; a _ }
Přílišná specializace
Vezměte si následující kód. Schválně, co dělá?
class X[@specialized A, @specialized B, @specialized C](a: A, b: B, c: C)
Nic moc. Když ho zkusíte zkompilovat, bude to chvíli trvat a ve výsledku vygeneruje 729 tříd. Paráda. Specializace je super vlastnost, ale musí se užívat jenom tam, kde je to nezbytně nutné.
Jenom pro úplnost čtyři specializované parametry vygenrují přes 6500 tříd a v podobném duchu to pokračuje dál.
Podtržítka bez podtržítek
Funkční objekt se z metody vytvoří kouzelným podtržítkem.
val a = println() // a je Unit val b = println(_) // b je funkce Unit => Unit, _ nahrazuje jeden argument val c = println _ // c je funkce Unit => Unit, _ nahrazuje všechny argumenty
Pokud má být požadovaným argumentem funkce, může se podtržítko vynechat.
Seq(1, 2, 3).foreach(println _) Seq(1, 2, 3).foreach(println(_)) Seq(1, 2, 3).foreach(println) // <- _ vynecháno
Tohle pravidlo platí i v některých neočekávaných situacích. Pohleďte:
Seq(1, 2, 3).map(x => 1 + x) // vrátí Seq(2,3,4), nic překvapivého Seq(1, 2, 3).map(1 + _) // pořád dobré Seq(1, 2, 3).map(1+) // eh... funguje úplně stejně
Syntaxe metod
Scala má velice flexibilní syntaxi. Následující útžky kódu jsou ekvivalentní
obj.meth(a).meth(b).meth(c) obj.meth(a)meth(b)meth(c) obj meth a meth b meth c
Typová rekurze
K tomu, aby byl programovací jazyk Turing-kompletní stačí while cyklus, podmíněný skok nebo rekurze. Samotný typový systém Scaly obsahuje rekurzi a je sám o sobě Turing-kompletní.
Co s tím?
Můžeme provozovat nějakou černou magii nebo na to balit holky.