k47.cz  — každý den dokud se vám to nezačne líbit
foto Praha výběr povídky kultura
twitter FB RSS

Scala - gimmicks

7. 2. 2011 — k47 (CC by-sa) (♪)

Věci, které mě za­u­jaly na­to­lik, abych o nich napsal aspoň jednu větu, ale nemají na vlastní článek.


for println

Pokud chcete něco vypsat upo­střed for com­pre­hension s mnoha ge­ne­rá­tory, můžete to udělat takto:

for {
  c <- collection
  _ = println(c)
  s <- c.subCollection
} yield s

Vno­řené ko­men­táře

Scala pod­po­ruje struk­tu­ro­vané ko­men­táře. Každý za­čá­tek ví­ce­řád­ko­vého ko­men­táře /* musí mít od­po­ví­da­jící ukon­čení */. Na první pohled se to může jevit jako zby­teč­nost, ale ve sku­teč­nosti je to docela uži­tečná funkce.

Když mám nějaký ta­ko­vý­hle kód:

code

/*
anotherCode
*/

stuff

andNowSomethingCompletelyDifferent

A chchi za­ko­men­to­vat blok od code do stuff:

/*
code

/*
anotherCode
*/

stuff
*/

andNowSomethingCompletelyDifferent

Se struk­tu­ro­va­nými ko­men­táři to fun­guje přesně jak člověk za­mýš­lel. Kdyby Scala měla šla tra­diční cestou, kdy ko­men­tář skončí jakmile narazí na */, ne­vun­go­valo by to, pro­tože stuff by byl už mimo.

Vnitřní metody de­fi­no­vané 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á spe­ci­a­li­zace

Vez­měte si ná­sle­du­jí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 zku­síte zkom­pi­lo­vat, bude to chvíli trvat a ve vý­sledku vy­ge­ne­ruje 729 tříd. Paráda. Spe­ci­a­li­zace je super vlast­nost, ale musí se užívat jenom tam, kde je to ne­zbytně nutné.

Jenom pro úpl­nost čtyři spe­ci­a­li­zo­vané pa­ra­me­try vy­ge­nrují přes 6500 tříd a v po­dob­ném duchu to po­kra­čuje dál.

Pod­tr­žítka bez pod­tr­ží­tek

Funkční objekt se z metody vy­tvoří kou­zel­ným pod­tr­žít­kem.

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­ža­do­va­ným ar­gu­men­tem funkce, může se pod­tr­žítko vy­ne­chat.

Seq(1, 2, 3).foreach(println _)
Seq(1, 2, 3).foreach(println(_))
Seq(1, 2, 3).foreach(println) // <- _ vynecháno

Tohle pra­vi­dlo platí i v ně­kte­rých ne­o­če­ká­va­ných si­tu­a­cích. Po­hleď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ě

Syn­taxe metod

Scala má velice fle­xi­bilní syn­taxi. Ná­sle­du­jící útžky kódu jsou ekvi­va­lentní

obj.meth(a).meth(b).meth(c)
obj.meth(a)meth(b)meth(c)
obj meth a meth b meth c

Typová re­kurze

K tomu, aby byl pro­gra­mo­vací jazyk Turing-kom­pletní stačí while cyklus, pod­mí­něný skok nebo re­kurze. Sa­motný typový systém Scaly ob­sa­huje re­kurzi a je sám o sobě Turing-kom­pletní.

Co s tím?

Můžeme pro­vo­zo­vat ně­ja­kou černou magii nebo na to balit holky.

píše k47 & hosté, ascii@k47.cz