Moonscript: jazyk inspirovaný CoffeeScriptem určený pro ekosystém jazyka Lua (2)

11. 11. 2021
Doba čtení: 34 minut

Sdílet

Autor: Depositphotos
Ve druhé části článku o jazyku Moonscript si nejprve ukážeme novou syntaxi použitou při zápisu metod (včetně zjednodušení přístupu k atributům objektů) a posléze si popíšeme další konstrukce, například generátorovou notaci seznamu.

Obsah

1. Moonscript: jazyk inspirovaný CoffeeScriptem určený pro ekosystém jazyka Lua (2)

2. Funkce, jejíž návratová hodnota se použije jako parametr jiné funkce

3. Metody deklarované s využitím operátoru „tlusté šipky“

4. Zjednodušený přístup k atributům objektů, implicitní parametry metod

5. Problematika zápisu funkcí s mnoha parametry

6. Kdy jsou kulaté závorky při volání funkce povinné?

7. Generátorová notace seznamu

8. Základní syntaxe generátorové notace seznamu

9. Zkrácený zápis iteračního příkazu v generátorové notaci seznamu

10. Filtrace prvků v zápisu generátorové notace seznamu

11. Generátorová notace seznamu založená na numerické smyčce

12. Malé doplnění: operace s prvky při použití numerické smyčky v generátorové notaci seznamu

13. Generátorová notace slovníku

14. Řezy zdrojového seznamu v generátorové notaci seznamu

15. Filtrace prvků zkombinovaná s použitím řezu

16. Objektově orientované programování v jazyce Lua

17. Příklad vytvoření objektu s konstruktorem a dvojicí metod

18. Obsah následující části článku o Moonscriptu

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. Moonscript: jazyk inspirovaný CoffeeScriptem určený pro ekosystém jazyka Lua (2)

Na úvodní článek o jazyku Moonscript dnes navážeme. V první části jsme si popsali především relativně jednoduchý „syntaktický cukr“, který byl do Moonscriptu přidán, aby programátorům zjednodušil zápis operací, které provádí prakticky dennodenně. Jedná se například o nové operátory spojující přiřazení s další operací, dále pak o přímou podporu pro víceřádkové řetězce, podporu pro interpolaci řetězců nebo o zkrácený zápis funkcí, který je založen na použití operátoru „tenké šipky“. Dnes si ukážeme další vlastnosti Moonscriptu, které již mnohdy musí být do jazyka Lua transformovány složitějším způsobem. Jedná se například o generátorovou notaci seznamu, generátorovou notaci tabulky, popř. o podporu objektově orientovaného programování (což bude ovšem nosné téma třetího článku o Moonscriptu).

Na začátek si připomeňme, jak lze v Moonscriptu definovat novou funkci. Bude se jednat o funkci se dvěma parametry, která bude vracet součet těchto parametrů. V Moonscriptu lze celý zápis provést na jediném řádku s využitím „tenké šipky“:

--
-- Skript zapsaný v jazyce Moonscript
--
 
sum = (x, y) -> x + y
 
print sum 10, 20

Transpřeklad do jazyka Lua je v tomto případě přímočarý:

--
-- Skript transpilovaný do jazyka Lua
--
 
local sum
sum = function(x, y)
  return x + y
end
 
return print(sum(10, 20))
Poznámka: na tento jednoduchý demonstrační příklad navážeme v dalších kapitolách.

2. Funkce, jejíž návratová hodnota se použije jako parametr jiné funkce

Zcela běžně se setkáme s tím, že se má návratová hodnota jedné funkce použít jako parametr funkce jiné. Typické je například volání nějaké funkce s následným výpisem její návratové hodnoty funkcí print. Příklad v jazyku Lua je triviální:

print(sum(10, 20))

V programovacím jazyku Moonscript může být takové volání realizováno bez použití kulatých závorek, ovšem pouze za předpokladu, že transpřekladač bude přesně vědět, jak „rozdělit“ parametry zapsané na jediném řádku. Podívejme se nejprve na (nefunkční) příklad, kdy funkci print předáváme dva parametry – řetězec „sum:“ a výsledek volání sum 10, 20, 30:

--
-- Skript zapsaný v jazyce Moonscript
--
 
sum = (x, y) -> print "sum", x + y
 
print "sum:", sum 10, 20, 30

V tomto konkrétním příkladu nebylo zřejmé, jaké funkci mají patřit parametry 20 a 30, takže transpřekladač provedl tuto transformaci:

--
-- Skript transpilovaný do jazyka Lua
--
 
local sum
sum = function(x, y)
  return print("sum", x + y)
end
return print("sum:", sum(10, 20, 30))

Abychom dosáhli konkrétního chování, je nutné použít kulaté závorky při volání funkce sum:

--
-- Skript zapsaný v jazyce Moonscript
--
 
sum = (x, y) -> print "sum", x + y
 
print "sum:", sum(10, 20), 30

Výsledek je již v tomto případě korektní a lze ho spustit:

--
-- Skript transpilovaný do jazyka Lua
--
 
local sum
sum = function(x, y)
  return print("sum", x + y)
end
return print("sum:", sum(10, 20), 30)
Poznámka: k této problematice se ještě vrátíme v šesté kapitole.

3. Metody deklarované s využitím operátoru „tlusté šipky“

Víme již, jak lze deklarovat běžné funkce s využitím operátoru „šipky“, resp. přesněji řečeno „tenké šipky“ (tenká se jí říká proto, že začíná znakem „-“). Ovšem v programovacím jazyce Lua jsou podporovány i metody – viz též sedmnáctou kapitolu. A při volání metod se explicitně nebo implicitně předává i reference na daný objekt, což je reflektováno názvem tohoto parametru – self (jinde this). A právě aby se tato reference nemusela explicitně zapisovat, lze při deklaraci metody namísto „tenké šipky“ použít „tlustou šipku“.

Metoda f1 bez dalších parametrů, která vrací referenci na svůj objekt, může být deklarována následovně:

--
-- Skript zapsaný v jazyce Moonscript
--
 
f1 = => self
 
foo = {}
 
print f1(foo)

Způsob překladu do jazyka Lua je proveden takto:

--
-- Skript transpilovaný do jazyka Lua
--
 
local f1
f1 = function(self)
  return self
end
local foo = { }
return print(f1(foo))
Poznámka: povšimněte si, že parametr self byl v tomto případě do vygenerované funkce přidán automaticky.

Nyní se podívejme na nepatrně praktičtější příklad, konkrétně na metodu, která sníží hodnotu atributu balance (předaného objektu) a zadanou hodnotu (explicitní parametr). V jazyce Moonscript je jedna z variant zápisu této funkce následující:

--
-- Skript zapsaný v jazyce Moonscript
--
 
withdraw = (value) => self.balance -= value

Výsledek transpřekladu do jazyka Lua:

--
-- Skript transpilovaný do jazyka Lua
--
 
local withdraw
withdraw = function(self, value)
  self.balance = self.balance - value
end

4. Zjednodušený přístup k atributům objektů, implicitní parametry metod

Vzhledem k tomu, že v metodách se prakticky vždy přistupuje k atributům objektu (jehož reference je předána přes automaticky vytvořený parametr self), poskytuje programovací jazyk Moonscript možnost zjednodušeného přístupu k těmto atributům. Namísto zápisu:

self.balance

popř. sémanticky totožného zápisu:

self["balance"]

je možné použít:

@balance

Ukažme si například, jak lze tímto zkráceným způsobem zapsat metodu, která od hodnoty uložené na účtu (tedy v atributu balance) odečte předanou hodnotu:

--
-- Skript zapsaný v jazyce Moonscript
--
 
withdraw = (value) => @balance -= value

Způsob převodu do programovacího jazyka Lua:

--
-- Skript transpilovaný do jazyka Lua
--
 
local withdraw
withdraw = function(self, value)
  self.balance = self.balance - value
end

Metody pochopitelně mohou akceptovat nepovinné parametry s nastavenou výchozí hodnotou. Jedná se vlastně o kombinaci zápisu funkce s nepovinnými parametry se zápisem metody s využitím „tlusté šipky“:

--
-- Skript zapsaný v jazyce Moonscript
--
 
withdraw = (value=0) => @balance -= value

Způsob transpřekladu takto zapsané metody do jazyka Lua:

--
-- Skript transpilovaný do jazyka Lua
--
 
local withdraw
withdraw = function(self, value)
  if value == nil then
    value = 0
  end
  self.balance = self.balance - value
end
Poznámka: opět můžeme vidět, jak se nepovinné parametry inicializují uvnitř těla metody – nejedná se tedy o žádné magické operace prováděné ještě před zavoláním metody.

5. Problematika zápisu funkcí s mnoha parametry

Poněkud problematický může být zápis funkcí nebo metod v případě, že je použito velké množství parametrů, popř. pokud jsou názvy parametrů dlouhé. V takových případech se nemusí hlavička funkce vlézt na jediný řádek, zejména ve chvíli, kdy se dodržuje například limit osmdesáti znaků na programovém řádku. Následuje poněkud umělý příklad s funkcí, která očekává deset parametrů a vrátí jejich součet:

--
-- Skript zapsaný v jazyce Moonscript
--
 
supersum = (a, b, c, d, e, f, g, h, i, j) ->
   a + b + c + d + e + f + g + h + i + j
 
print supersum 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Jak samotná deklarace této funkce tak i její volání se přeloží do jazyka Lua takto:

--
-- Skript transpilovaný do jazyka Lua
--
 
local supersum
supersum = function(a, b, c, d, e, f, g, h, i, j)
  return a + b + c + d + e + f + g + h + i + j
end
return print(supersum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))

Parametry funkce v její deklaraci můžeme rozdělit na větší množství řádků, stejně jako výpočet ve funkci realizovaný výrazem. Musíme však dodržet odsazení!:

--
-- Skript zapsaný v jazyce Moonscript
--
 
supersum = (a, b, c, d, e,
            f, g, h, i, j) ->
   a + b + c + d + e +
   f + g + h + i + j
 
print supersum 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Překlad do jazyka Lua je stále stejný, tj. totožný s předchozím příkladem:

--
-- Skript transpilovaný do jazyka Lua
--
 
local supersum
supersum = function(a, b, c, d, e, f, g, h, i, j)
  return a + b + c + d + e + f + g + h + i + j
end
return print(supersum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))

Dokonce je možné samotné volání funkce s předáním parametrů zapsat na větší množství programových řádků. Opět je vhodné dodržet vizuální odsazení:

--
-- Skript zapsaný v jazyce Moonscript
--
 
supersum = (a, b, c, d, e,
            f, g, h, i, j) ->
   a + b + c + d + e +
   f + g + h + i + j
 
print supersum 1, 2, 3, 4, 5,
               6, 7, 8, 9, 10

Výsledek po transpřekladu do jazyka Lua:

--
-- Skript transpilovaný do jazyka Lua
--
 
local supersum
supersum = function(a, b, c, d, e, f, g, h, i, j)
  return a + b + c + d + e + f + g + h + i + j
end
return print(supersum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))

6. Kdy jsou kulaté závorky při volání funkce povinné?

Při zápisu programů v Moonscriptu se většinou obejdeme bez nutnosti použití kulatých závorek (výjimkou jsou pochopitelně složitější aritmetické výrazy). Někdy je ovšem nutné překladači „pomoci“ v určení, kterým funkcím náleží parametry. Jeden z příkladů jsme mohli vidět ve druhé kapitole, situace se ovšem ještě nepatrně mění ve chvíli, kdy se parametry funkce rozepisují na větší množství programových řádků. Podívejme se na demonstrační příklad, ve kterém je volána funkce print se třemi parametry – přičemž konkrétní hodnoty těchto parametrů jsou získány zavoláním funkce sum s parametry 1, 2, 3 (první volání), 4, 5, 6 (druhé volání) a konečně 7, 8, 9 (třetí volání). Díky rozepsání na tři řádky je nutné kulaté závorky uvést pouze při prvním volání funkce sum:

--
-- Skript zapsaný v jazyce Moonscript
--
 
sum = (a, b, c) -> a + b + c
 
print sum(1, 2, 3),
      sum 4, 5, 6,
      sum 7, 8, 9

Způsob překladu do jazyka Lua naznačuje, že Moonscript správně pochopil, které parametry patří druhému a třetímu volání funkce sum:

--
-- Skript transpilovaný do jazyka Lua
--
 
local sum
sum = function(a, b, c)
  return a + b + c
end
return print(sum(1, 2, 3), sum(4, 5, 6), sum(7, 8, 9))
Poznámka: důležité je, že první volání funkce sum musí být uvedeno na stejném řádku, jako volání funkce print, takže pouze zde jsou kulaté závorky nezbytné.

7. Generátorová notace seznamu

V dalším textu se budeme zabývat zejména popisem velmi praktické konstrukce, díky níž je možné v Moonscriptu používat takzvanou generátorovou notaci seznamu, což je poněkud nepřesně přeložený anglický termín list comprehension. O způsobu překladu tohoto termínu se vedly a pravděpodobně dodnes vedou poměrně vášnivé diskuse; já se zde budu držet překladu použitého například v knize Ponořme se do Python(u) 3 (původně Dive Into Python 3), kterou si můžete stáhnout na stránkách http://knihy.nic.cz/, popř. si zde objednat i papírovou verzi knihy.

S využitím generátorové notace seznamu je možné v programovacích jazycích, které tento zápis podporují, zapsat deklaraci vytvoření nového seznamu s využitím seznamu jiného, a to pomocí aplikace nějaké zvolené funkce na všechny prvky zdrojového seznamu. V mnoha programovacích jazycích je nutné pro generátorovou notaci seznamů používat zvláštní příkaz či deklaraci, tj. vlastně novou syntaktickou kategorii. Z těch známějších jazyků podporujících list comprehension se jedná například o Python, Haskell, Scala či Erlang. Programovací jazyk Moonscript taktéž pro generátorovou notaci používá vlastní syntaktická pravidla, která budou ukázána na několika demonstračních příkladech.

Poznámka: seznamem zde budeme myslet tabulku, jejíž prvky mají indexy 1, 2, len(seznam).

8. Základní syntaxe generátorové notace seznamu

Základní způsob zápisu generátorové notace seznamu se do značné míry podobá Pythonu:

doubled = [item * 2 for i, item in ipairs list]
Poznámka: povšimněte si iterace s využitím generátoru ipairs, který v každé iteraci vrátí dvojici index+hodnota prvku z tabulky.

Úplný skript, který nejprve vytvoří seznam s pěti celočíselnými prvky a následně z tohoto seznamu vygeneruje seznam nový (s prvky s dvojnásobnou hodnotou), může být zapsán takto:

--
-- Skript zapsaný v jazyce Moonscript
--
 
print_list = (list) ->
   print "i", "item"
   for i, item in ipairs list
      print i, item
   print!
 
 
list = { 1, 2, 3, 4, 5 }
 
print_list list
 
doubled = [item * 2 for i, item in ipairs list]
 
print_list doubled

Převod do jazyka Lua je již komplikovanější, ale stále ještě poměrně dobře čitelný:

--
-- Skript transpilovaný do jazyka Lua
--
 
local print_list
print_list = function(list)
  print("i", "item")
  for i, item in ipairs(list) do
    print(i, item)
  end
  return print()
end
local list = {
  1,
  2,
  3,
  4,
  5
}
print_list(list)
local doubled
do
  local _accum_0 = { }
  local _len_0 = 1
  for i, item in ipairs(list) do
    _accum_0[_len_0] = item * 2
    _len_0 = _len_0 + 1
  end
  doubled = _accum_0
end
return print_list(doubled)
Poznámka: povšimněte si v této oblasti typického použití „akumulátoru“.

9. Zkrácený zápis iteračního příkazu v generátorové notaci seznamu

V předchozím příkladu jsme použili naprosto standardní programovou smyčku pro průchod prvky seznamu, resp. pole. Připomeňme si, že jak pole, tak i slovníky jsou v jazyce Lua řešeny tabulkou s klíči a hodnotami, přičemž u polí se používají indexy rostoucí od jedničky do délky pole (a taková tabulka je interně optimalizována). Průchod je řešen následovně – zavoláním generátoru ipairs, který pro dané pole (nebo chcete-li seznam) vrací index a hodnotu:

for i, item in ipairs list
   print i, item

Prakticky stejnou konstrukci jsme použili v zápisu generátorové notace seznamu:

doubled = [item * 2 for i, item in ipairs list]

Ovšem vzhledem k tomu, že se často opakuje nutnost iterovat nad prvky seznamu (a zahodit přitom index), existuje v Moonscriptu i kratší zápis, který sice může vypadat divně, ale je velmi praktický:

doubled = [item * 2 for item in *list]

Tento zápis použijeme v dalším skriptu:

--
-- Skript zapsaný v jazyce Moonscript
--
 
print_list = (list) ->
   print "i", "item"
   for i, item in ipairs list
      print i, item
   print!
 
 
list = { 1, 2, 3, 4, 5 }
 
print_list list
 
doubled = [item * 2 for item in *list]
 
print_list doubled

S výsledkem, který je ovšem odlišný od výsledku, který jsme mohli vidět v předchozí kapitole:

--
-- Skript transpilovaný do jazyka Lua
--

local print_list
print_list = function(list)
  print("i", "item")
  for i, item in ipairs(list) do
    print(i, item)
  end
  return print()
end
local list = {
  1,
  2,
  3,
  4,
  5
}
print_list(list)
local doubled
do
  local _accum_0 = { }
  local _len_0 = 1
  for _index_0 = 1, #list do
    local item = list[_index_0]
    _accum_0[_len_0] = item * 2
    _len_0 = _len_0 + 1
  end
  doubled = _accum_0
end
return print_list(doubled)
Poznámka: povšimněte si, že se původní programová smyčka typu for-each změnila na standardní počítanou smyčku!

10. Filtrace prvků v zápisu generátorové notace seznamu

Moonscript je, jak již víme, založen na CoffeeScriptu a ten je inspirován (kromě jiných jazyků) i Pythonem. V Pythonu můžeme v konstrukci generátorové notace seznamu prvky filtrovat, a to například následujícím způsobem, kterým získáme pouze sudé prvky (tedy prvky dělitelné dvěma):

evens = [item for item in list if item % 2 == 0]

V Moonscriptu je zápis nepatrně odlišný, protože se namísto klíčového slova if používá klíčové slovo when. Sémanticky stejný příklad tedy můžeme do Moonscriptu přepsat takto:

evens = [item for item in *list when item % 2 == 0]

Podívejme se nyní na úplný příklad, v němž ze seznamu s prvky 1 až 10 vyfiltrujeme pouze sudé hodnoty, které budou uloženy do nového seznamu:

--
-- Skript zapsaný v jazyce Moonscript
--
 
print_list = (list) ->
   print "i", "item"
   for i, item in ipairs list
      print i, item
   print!
 
 
list = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
 
print_list list
 
evens = [item for item in *list when item % 2 == 0]
 
print_list evens

Transformace tohoto skriptu do jazyka Lua je stále velmi přímočará – provedl se přepis na smyčku s vloženou konstrukcí if-then:

--
-- Skript transpilovaný do jazyka Lua
--
 
local print_list
print_list = function(list)
  print("i", "item")
  for i, item in ipairs(list) do
    print(i, item)
  end
  return print()
end
local list = {
  1,
  2,
  3,
  4,
  5,
  6,
  7,
  8,
  9,
  10
}
print_list(list)
local evens
do
  local _accum_0 = { }
  local _len_0 = 1
  for _index_0 = 1, #list do
    local item = list[_index_0]
    if item % 2 == 0 then
      _accum_0[_len_0] = item
      _len_0 = _len_0 + 1
    end
  end
  evens = _accum_0
end
return print_list(evens)

Pochopitelně si můžeme obě možnosti zkombinovat a vytvořit seznam obsahující původně sudé prvky, ovšem vynásobené konstantou 3 – viz zvýrazněnou část skriptu:

--
-- Skript zapsaný v jazyce Moonscript
--
 
print_list = (list) ->
   print "i", "item"
   for i, item in ipairs list
      print i, item
   print!
 
 
list = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
 
print_list list
 
x = [item*3 for item in *list when item % 2 == 0]
 
print_list x

Výsledek po transpřekladu do programovacího jazyka Lua bude vypadat takto:

--
-- Skript transpilovaný do jazyka Lua
--
 
local print_list
print_list = function(list)
  print("i", "item")
  for i, item in ipairs(list) do
    print(i, item)
  end
  return print()
end
local list = {
  1,
  2,
  3,
  4,
  5,
  6,
  7,
  8,
  9,
  10
}
print_list(list)
local x
do
  local _accum_0 = { }
  local _len_0 = 1
  for _index_0 = 1, #list do
    local item = list[_index_0]
    if item % 2 == 0 then
      _accum_0[_len_0] = item * 3
      _len_0 = _len_0 + 1
    end
  end
  x = _accum_0
end
return print_list(x)
Poznámka: stále se ještě jedná o čitelný kód, ovšem vývojář by měl být rád za možnost použít mnohem stručnější a idiomaticky zapsanou generátorovou notaci seznamu.

11. Generátorová notace seznamu založená na numerické smyčce

Předchozí demonstrační příklady byly ve skutečnosti vytvořeny neefektivně, protože nejdříve jsme ručně vytvořili seznam (tabulku) s prvky tvořícími část aritmetické posloupnosti. Takové prvky lze například v Pythonu vytvořit generátorem range. V Moonscriptu ke stejnému účelu poslouží programová smyčka typu for s čítačem (někdy se takové smyčce říká „numerická smyčka“). Vytvoření seznamu s prvky z rozsahu od 1 do 100, které jsou sudé, bude vypadat takto:

evens = [i for i=1,100 when i % 2 == 0]

A celý spustitelný program vytvořený v Moonscriptu:

--
-- Skript zapsaný v jazyce Moonscript
--
 
print_list = (list) ->
   print "i", "item"
   for i, item in ipairs list
      print i, item
   print!
 
evens = [i for i=1,100 when i % 2 == 0]
 
print_list evens

Zajímavé bude zjistit, jak se interně takový seznam se sudými čísly vytvoří po převodu výše uvedeného programu do jazyka Lua:

--
-- Skript transpilovaný do jazyka Lua
--
 
local print_list
print_list = function(list)
  print("i", "item")
  for i, item in ipairs(list) do
    print(i, item)
  end
  return print()
end
local evens
do
  local _accum_0 = { }
  local _len_0 = 1
  for i = 1, 100 do
    if i % 2 == 0 then
      _accum_0[_len_0] = i
      _len_0 = _len_0 + 1
    end
  end
  evens = _accum_0
end
return print_list(evens)

12. Malé doplnění: operace s prvky při použití numerické smyčky v generátorové notaci seznamu

Jen pro úplnost si ukažme příklad, v němž se z původní sekvence prvků od 1 do 100 vytvoří seznam obsahující násobky hodnoty 3, tedy 3, 6, … 300. Jedno z možných řešení vypadá takto:

--
-- Skript zapsaný v jazyce Moonscript
--
 
print_list = (list) ->
   print "i", "item"
   for i, item in ipairs list
      print i, item
   print!
 
values = [i*3 for i=1,100]
 
print_list values

A výsledný programový kód po transpilaci do jazyka Lua:

--
-- Skript transpilovaný do jazyka Lua
--
 
local print_list
print_list = function(list)
  print("i", "item")
  for i, item in ipairs(list) do
    print(i, item)
  end
  return print()
end
local values
do
  local _accum_0 = { }
  local _len_0 = 1
  for i = 1, 100 do
    _accum_0[_len_0] = i * 3
    _len_0 = _len_0 + 1
  end
  values = _accum_0
end
return print_list(values)

13. Generátorová notace slovníku

Speciální notace existuje v jazyku Moonscript i pro vytváření slovníků, tedy (v řeči Luy) tabulek, jejichž klíče obecně netvoří posloupnost celých čísel od 1 do len(t), ale mohou být libovolného typu i hodnoty (řetězce atd.), s výjimkou hodnoty nil. Zápis generátorové notace slovníku vypadá následovně:

slovnik = {key, value for key, value in pairs x}

V dalším demonstračním příkladu se prochází slovníkem x a vytváří se nový slovník, který obsahuje shodné klíče, ovšem namísto původních hodnot (což jsou konkrétně řetězce) se zapisuje délka původních hodnot, tedy namísto „Pepek“ je ve výsledném slovníku uložena hodnota 5 atd.:

--
-- Skript zapsaný v jazyce Moonscript
--
 
print_table = (tbl) ->
   print "key", "value"
   for key, value in pairs tbl
      print key, value
   print!
 
x = {
  name: "Pepek"
  surname: "Vyskoc"
}
 
lengths = {k,#v for k,v in pairs x}
 
print_table lengths

Transpřeklad do jazyka Lua je stále ještě poměrně dobře čitelný a relativně stručný (ovšem novou notaci pochopitelně překonat nemůže):

--
-- Skript transpilovaný do jazyka Lua
--
 
local print_table
print_table = function(tbl)
  print("key", "value")
  for key, value in pairs(tbl) do
    print(key, value)
  end
  return print()
end
local x = {
  name = "Pepek",
  surname = "Vyskoc"
}
local lengths
do
  local _tbl_0 = { }
  for k, v in pairs(x) do
    _tbl_0[k] = #v
  end
  lengths = _tbl_0
end
return print_table(lengths)

14. Řezy zdrojového seznamu v generátorové notaci seznamu

Programovací jazyk Moonscript obsahuje ještě jeden zajímavý syntaktický prvek – při konstrukci seznamu z jiného seznamu jsou podporovány řezy (slice), které známe například z Pythonu, popř. z jazyka Go. Vytvoření řezu je ukázáno v dalším příkladu, který nejprve z původního desetiprvkového seznamu získá prvky s indexy od 4 do 8 a teprve nad nimi provede požadovanou operaci, zde konkrétně operaci vytvoření seznamu nového:

--
-- Skript zapsaný v jazyce Moonscript
--
 
print_list = (list) ->
   print "i", "item"
   for i, item in ipairs list
      print i, item
   print!
 
list = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
 
slice = [item for item in *list[4,8]]
 
print_list slice

Transpřeklad do jazyka Lua je poměrně efektivní, což můžeme vidět při pohledu na zápis vygenerované programové smyčky:

--
-- Skript transpilovaný do jazyka Lua
--
 
local print_list
print_list = function(list)
  print("i", "item")
  for i, item in ipairs(list) do
    print(i, item)
  end
  return print()
end
local list = {
  1,
  2,
  3,
  4,
  5,
  6,
  7,
  8,
  9,
  10
}
local slice
do
  local _accum_0 = { }
  local _len_0 = 1
  local _max_0 = 8
  for _index_0 = 4, _max_0 < 0 and #list + _max_0 or _max_0 do
    local item = list[_index_0]
    _accum_0[_len_0] = item
    _len_0 = _len_0 + 1
  end
  slice = _accum_0
end
return print_list(slice)
Poznámka: ve skutečnosti jsou řezy v Moonscriptu podporovány jen na několika místech!

15. Filtrace prvků zkombinovaná s použitím řezu

Vzhledem k tomu, že se řezy používají v programové konstrukci generátorové notace seznamu, není asi velkým překvapením, že je lze snadno zkombinovat s filtrací založené na podmínce when. To je ukázáno na dalším příkladu:

--
-- Skript zapsaný v jazyce Moonscript
--
 
print_list = (list) ->
   print "i", "item"
   for i, item in ipairs list
      print i, item
   print!
 
list = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
 
slice = [item for item in *list[4,8] when item % 2 == 0]
 
print_list slice

A pro úplnost dodejme ještě skript vzniklý transpřekladem do jazyka Lua:

--
-- Skript transpilovaný do jazyka Lua
--
 
local print_list
print_list = function(list)
  print("i", "item")
  for i, item in ipairs(list) do
    print(i, item)
  end
  return print()
end
local list = {
  1,
  2,
  3,
  4,
  5,
  6,
  7,
  8,
  9,
  10
}
local slice
do
  local _accum_0 = { }
  local _len_0 = 1
  local _max_0 = 8
  for _index_0 = 4, _max_0 < 0 and #list + _max_0 or _max_0 do
    local item = list[_index_0]
    if item % 2 == 0 then
      _accum_0[_len_0] = item
      _len_0 = _len_0 + 1
    end
  end
  slice = _accum_0
end
return print_list(slice)

16. Objektově orientované programování v jazyce Lua

V navazujícím článku si ukážeme, jak je implementováno OOP v Moonscriptu, ovšem možná na tomto místě stojí za připomenutí, jakým způsobem lze přímo v jazyku Lua používat metatabulky a metametody při psaní skriptů využívajících objektově orientovaný přístup. Jazyk Lua sice nenabízí pro deklaraci tříd a objektů vlastní syntaxi, ale to neznamená, že by objektově orientované programování nebylo možné – objekty lze vytvářet buď na základě uzávěrů (closures) při jejichž použití jsou atributy i metody objektu „zabaleny“ právě v uzávěru (ostatně stejný princip je využitý i v některých funkcionálních jazycích), a/nebo lze využít druhého způsobu založeného na asociativních polích a již zmíněných metatabulkách a metametodách. Tvorba objektů je pak ze sémantického hlediska podobná technice používané v původním JavaScriptu, který byl inspirovaný jazykem Self a takzvaným prototypováním. Právě těmito technikami se budeme zabývat v následujícím textu.

Mezi podporované datové typy programovacího jazyka Lua patří i asociativní pole, někdy také nazývané hashmapa (hešmapa) či hešovací mapa. Jedná se o datovou strukturu, v níž jsou uloženy dvojice klíč–hodnota, přičemž klíčem může být hodnota libovolného datového typu kromě typu nil a hodnota může být zcela libovolná (může se jednat i o další asociativní pole, řetězec, funkci atd.). Právě možnost uložení funkce do asociativního pole je důležitá při konstrukci objektů.

Význačným a do jisté míry i unikátním znakem programovacího jazyka Lua je možnost přiřadit prakticky každé hodnotě takzvanou metatabulku (metatable). Přímo z Lua skriptu lze sice přiřadit metatabulku pouze asociativním polím, nikoli ostatním typům hodnot, ovšem z céčkového programu (který volá interpretr Lua) je možné měnit i metatabulku ostatních hodnot pomocí API funkce lua_setmetatable(). Metatabulka je běžné asociativní pole, se kterým lze provádět stejné operace, jako s každým jiným asociativním polem v Lue, ovšem význam některých položek uložených v tomto poli má speciální význam při práci s danou hodnotou (povšimněte si, že metatabulka je, stejně jako typ, přiřazena přímo hodnotě a nikoli proměnné, což je význačný rys prakticky všech dynamicky typovaných jazyků). Metatabulku je možné asociativnímu poli přiřadit funkcí setmetatable(objekt, metatabulka), opětovné získání metatabulky se provádí funkcí getmetatable(). V případě, že se při volání setmetatable() místo metatabulky předá konstanta nil, je původní metatabulka odstraněna. Naopak funkce getmetatable() může vrátit konstantu nil v případě, že žádná metatabulka nebyla ještě objektu (asociativnímu poli) přiřazena.

17. Příklad vytvoření objektu s konstruktorem a dvojicí metod

Ukažme si nyní, jak lze reprezentovat objekt, jak lze vytvořit jeho konstruktor a metody. Objektem může být běžná tabulka, jejíž atributy budou atributy objektu:

Account = {balance = 0}

Konstruktor je ve skutečnosti tvořen metodou, které se předává reference self. V konstruktoru měníme tzv. událost __index v metatabulce; tím je zajištěn přístup k metodám pro všechny objekty odvozené od Account:

function Account:new(o)
    -- create object if user does not provide one
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end

Metody lze definovat dvěma způsoby. Buď s explicitním použitím parametru self (tj. jako v Pythonu):

function Account.withdraw(self, value)
    self.balance = self.balance - value
end

nebo s využitím syntaktického cukru, kdy se namísto tečky zapíše dvojtečka a první parametr self se vynechá:

function Account:deposit(value)
    self.balance = self.balance + value
end

Konstrukce objektů a zavolání jejich metod, opět s použitím dvojtečky:

local a = Account:new{balance=0}
local b = Account:new{balance=50}
 
a:withdraw(100.00)
b:withdraw(100.00)
 
a:deposit(200.00)
b:deposit(200.00)

Celý skript vypadá zbytečně složitě, ale jak uvidíme příště, je možné v Moonscriptu mnohý „boilerplate“ zcela odstranit:

Account = {balance = 0}
 
function Account:new(o)
    -- create object if user does not provide one
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end
 
function Account.withdraw(self, value)
    self.balance = self.balance - value
end
 
function Account:deposit(value)
    self.balance = self.balance + value
end
 
local a = Account:new{balance=0}
local b = Account:new{balance=50}
 
print("account A", a.balance)
print("account B", b.balance)
 
a:withdraw(100.00)
b:withdraw(100.00)
 
print("account A", a.balance)
print("account B", b.balance)
 
a:deposit(200.00)
b:deposit(200.00)
 
print("account A", a.balance)
print("account B", b.balance)

18. Obsah následující části článku o Moonscriptu

Ve třetí části článku o programovacím jazyce Moonscript si ukážeme, jaké nové syntaktické konstrukce umožňují deklaraci tříd a konstrukci objektů, tedy instancí těchto tříd. Jedná se o (v kontextu ekosystému programovacího jazyka Lua) zcela nový koncept, který se nepodobá způsobu práce s objekty, který jsme si ve stručnosti přiblížili v rámci předchozí kapitoly a který byl sice postaven na jednoduchých základech, ovšem nepodobal se dnes přece jen populárnějším (resp. přesněji řečeno mainstreamovým) objektovým systémům.

bitcoin_smenarna

19. Repositář s demonstračními příklady

Všechny minule i dnes popsané demonstrační příklady určené pro Moonscript byly uloženy do Git repositáře, který je dostupný na adrese https://github.com/tisnik/moonscript-examples. Příklady si můžete v případě potřeby stáhnout i jednotlivě bez nutnosti klonovat celý (dnes prozatím stále velmi malý) repositář:

# Příklad Stručný popis příkladu Adresa (zdrojový kód)
1 01_hello_world.lua tradiční program typu „Hello, world!“ napsaný v Lue https://github.com/tisnik/moonscript-examples/blob/master/01_he­llo_world.lua
2 02_hello_world.lua okolo jediného parametru funkce není zapotřebí psát závorky https://github.com/tisnik/moonscript-examples/blob/master/02_he­llo_world.lua
3 03_hello_world.moon tradiční program typu „Hello, world!“ napsaný v Moonscriptu https://github.com/tisnik/moonscript-examples/blob/master/03_he­llo_world.moon
4 03_hello_world.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/03_he­llo_world.lua
5 04_local_variable.moon lokální proměnné v Moonscriptu https://github.com/tisnik/moonscript-examples/blob/master/04_lo­cal_variable.moon
6 04_local_variable.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/04_lo­cal_variable.lua
7 05_local_variable.moon opětovné přiřazení do lokální proměnné https://github.com/tisnik/moonscript-examples/blob/master/05_lo­cal_variable.moon
8 05_local_variable.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/05_lo­cal_variable.lua
9 06_local_variable.moon čtení z neexistující proměnné https://github.com/tisnik/moonscript-examples/blob/master/06_lo­cal_variable.moon
10 06_local_variable.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/06_lo­cal_variable.lua
11 07_string_interpolation.moon interpolace řetězců v Moonscriptu https://github.com/tisnik/moonscript-examples/blob/master/07_strin­g_interpolation.moon
12 07_string_interpolation.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/07_strin­g_interpolation.lua
13 08_string_interpolation.moon interpolace řetězců, složitější příklad v Moonscriptu https://github.com/tisnik/moonscript-examples/blob/master/08_strin­g_interpolation.moon
14 08_string_interpolation.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/08_strin­g_interpolation.lua
15 09_string_interpolation.moon zákaz interpolace řetězců v Moonscriptu https://github.com/tisnik/moonscript-examples/blob/master/09_strin­g_interpolation.moon
16 09_string_interpolation.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/09_strin­g_interpolation.lua
17 10_multiline_string.moon víceřádkové řetězce v Moonscriptu https://github.com/tisnik/moonscript-examples/blob/master/10_mul­tiline_string.moon
18 10_multiline_string.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/10_mul­tiline_string.lua
19 11_comparison_operator.moon nový operátor pro test na nerovnost v Moonscriptu https://github.com/tisnik/moonscript-examples/blob/master/11_com­parison_operator.moon
20 11_comparison_operator.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/11_com­parison_operator.lua
21 12_simple_assignment.moon operátor jednoduchého přiřazení https://github.com/tisnik/moonscript-examples/blob/master/12_sim­ple_assignment.moon
22 12_simple_assignment.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/12_sim­ple_assignment.lua
23 13_operator_assignment.moon přiřazení zkombinované s aritmetickou operací https://github.com/tisnik/moonscript-examples/blob/master/13_o­perator_assignment.moon
24 13_operator_assignment.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/13_o­perator_assignment.lua
25 14_operator_assignment.moon přiřazení zkombinované s připojením řetězce https://github.com/tisnik/moonscript-examples/blob/master/14_o­perator_assignment.moon
26 14_operator_assignment.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/14_o­perator_assignment.lua
27 15_operator_assignment.moon přiřazení zkombinované s logickou operací https://github.com/tisnik/moonscript-examples/blob/master/15_o­perator_assignment.moon
28 15_operator_assignment.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/15_o­perator_assignment.lua
29 16_function_parameters.moon volání funkce bez parametrů, s jedním parametrem i více parametry https://github.com/tisnik/moonscript-examples/blob/master/16_fun­ction_parameters.moon
30 16_function_parameters.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/16_fun­ction_parameters.lua
31 17_function_no_parenthesis.moon volání funkce bez použití kulatých závorek https://github.com/tisnik/moonscript-examples/blob/master/17_fun­ction_no_parenthesis.moon
32 17_function_no_parenthesis.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/17_fun­ction_no_parenthesis.lua
33 18_arrow_empty_function.moon deklarace prázdné funkci s využitím operátoru šipky https://github.com/tisnik/moonscript-examples/blob/master/18_a­rrow_empty_function.moon
34 18_arrow_empty_function.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/18_a­rrow_empty_function.lua
35 19_arrow_noarg_function.moon deklarace funkce bez parametrů s využitím operátoru šipky https://github.com/tisnik/moonscript-examples/blob/master/19_a­rrow_noarg_function.moon
36 19_arrow_noarg_function.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/19_a­rrow_noarg_function.lua
37 20_arrow_noarg_larger_function.moon delší funkce bez parametrů vytvořená s využitím operátoru šipky https://github.com/tisnik/moonscript-examples/blob/master/20_a­rrow_noarg_larger_function­.moon
38 20_arrow_noarg_larger_function.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/20_a­rrow_noarg_larger_function­.lua
39 21_arrow_return_value.moon funkce vracející jednu hodnotu vytvořená operátorem šipky https://github.com/tisnik/moonscript-examples/blob/master/21_a­rrow_return_value.moon
40 21_arrow_return_value.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/21_a­rrow_return_value.lua
41 22_arrow_return_value.moon návratová hodnota funkce bez nutnosti použití klíčového slova return https://github.com/tisnik/moonscript-examples/blob/master/22_a­rrow_return_value.moon
42 22_arrow_return_value.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/22_a­rrow_return_value.lua
43 23_arrow_function_parameters.moon parametry funkce vytvořené operátorem šipky https://github.com/tisnik/moonscript-examples/blob/master/23_a­rrow_function_parameters.mo­on
44 23_arrow_function_parameters.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/23_a­rrow_function_parameters.lua
45 24_arrow_multiple_return_values.moon více návratových hodnot funkce https://github.com/tisnik/moonscript-examples/blob/master/24_a­rrow_multiple_return_valu­es.moon
46 24_arrow_multiple_return_values.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/24_a­rrow_multiple_return_valu­es.lua
47 25_arrow_default_arguments.moon parametry s implicitní hodnotou https://github.com/tisnik/moonscript-examples/blob/master/25_a­rrow_default_arguments.mo­on
48 25_arrow_default_arguments.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/25_a­rrow_default_arguments.lua
49 26_arrow_default_arguments.moon způsob inicializace parametrů s implicitní hodnotou https://github.com/tisnik/moonscript-examples/blob/master/26_a­rrow_default_arguments.mo­on
50 26_arrow_default_arguments.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/26_a­rrow_default_arguments.lua
       
51 27_arrow_function.moon zopakování z minula – deklarace funkce operátorem šipky https://github.com/tisnik/moonscript-examples/blob/master/27_a­rrow_function.moon
52 27_arrow_function.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/27_a­rrow_function.lua
53 28_function_parenthesis.moon funkce volaná v pozici parametru jiné funkce a problematika závorek https://github.com/tisnik/moonscript-examples/blob/master/28_fun­ction_parenthesis.moon
54 28_function_parenthesis.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/28_fun­ction_parenthesis.lua
55 29_function_parenthesis.moon funkce volaná v pozici parametru jiné funkce a problematika závorek https://github.com/tisnik/moonscript-examples/blob/master/29_fun­ction_parenthesis.moon
56 29_function_parenthesis.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/29_fun­ction_parenthesis.lua
57 30_fat_arrow.moon operátor „tlusté šipky“, funkce bez těla https://github.com/tisnik/moonscript-examples/blob/master/30_fat_arrow.moon
58 30_fat_arrow.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/30_fat_arrow.lua
59 31_fat_arrow.moon operátor „tlusté šipky“, funkce s parametrem a tělem https://github.com/tisnik/moonscript-examples/blob/master/31_fat_arrow.moon
60 31_fat_arrow.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/31_fat_arrow.lua
61 32_fat_arrow.moon operátor „tlusté šipky“, zjednodušený přístup k atributu https://github.com/tisnik/moonscript-examples/blob/master/32_fat_arrow.moon
62 32_fat_arrow.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/32_fat_arrow.lua
63 33_fat_arrow.moon operátor „tlusté šipky“, zjednodušený přístup k atributu, výchozí hodnota parametru https://github.com/tisnik/moonscript-examples/blob/master/33_fat_arrow.moon
64 33_fat_arrow.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/33_fat_arrow.lua
65 34_multiline_arguments.moon funkce s velkým množstvím parametrů, zápis na jediném řádku https://github.com/tisnik/moonscript-examples/blob/master/34_mul­tiline_arguments.moon
66 34_multiline_arguments.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/34_mul­tiline_arguments.lua
67 35_multiline_arguments.moon funkce s velkým množstvím parametrů, zápis na více řádcích https://github.com/tisnik/moonscript-examples/blob/master/35_mul­tiline_arguments.moon
68 35_multiline_arguments.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/35_mul­tiline_arguments.lua
69 36_multiline_arguments.moon volání funkce s mnoha parametry, zápis na více řádcích https://github.com/tisnik/moonscript-examples/blob/master/36_mul­tiline_arguments.moon
70 36_multiline_arguments.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/36_mul­tiline_arguments.lua
71 37_multiline_arguments.moon problematika závorek při volání funkcí https://github.com/tisnik/moonscript-examples/blob/master/37_mul­tiline_arguments.moon
72 37_multiline_arguments.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/37_mul­tiline_arguments.lua
73 38_list_comprehension.moon generátorová notace seznamu, základní konstrukce https://github.com/tisnik/moonscript-examples/blob/master/38_lis­t_comprehension.moon
74 38_list_comprehension.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/38_lis­t_comprehension.lua
75 39_list_comprehension.moon generátorová notace seznamu, náhrada ipairs za * https://github.com/tisnik/moonscript-examples/blob/master/39_lis­t_comprehension.moon
76 39_list_comprehension.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/39_lis­t_comprehension.lua
77 40_list_comprehension.moon generátorová notace seznamu, podmínka when https://github.com/tisnik/moonscript-examples/blob/master/40_lis­t_comprehension.moon
78 40_list_comprehension.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/40_lis­t_comprehension.lua
79 41_list_comprehension.moon generátorová notace seznamu, kombinace předchozích možností https://github.com/tisnik/moonscript-examples/blob/master/41_lis­t_comprehension.moon
80 41_list_comprehension.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/41_lis­t_comprehension.lua
81 42_numeric_comprehension.moon „numerická“ generátorová notace seznamu, základní varianta https://github.com/tisnik/moonscript-examples/blob/master/42_nu­meric_comprehension.moon
82 42_numeric_comprehension.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/42_nu­meric_comprehension.lua
83 43_numeric_comprehension.moon „numerická“ generátorová notace seznamu https://github.com/tisnik/moonscript-examples/blob/master/43_nu­meric_comprehension.moon
84 43_numeric_comprehension.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/43_nu­meric_comprehension.lua
85 44_table_comprehension.moon generátorová notace tabulky https://github.com/tisnik/moonscript-examples/blob/master/44_ta­ble_comprehension.moon
86 44_table_comprehension.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/44_ta­ble_comprehension.lua
87 45_slicing.moon slicing prováděný v konstrukci generátorové notace seznamu https://github.com/tisnik/moonscript-examples/blob/master/45_slicing.moon
88 45_slicing.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/45_slicing.lua
89 46_slicing.moon slicing prováděný v konstrukci generátorové notace seznamu https://github.com/tisnik/moonscript-examples/blob/master/46_slicing.moon
90 46_slicing.lua transpřeklad předchozího zdrojového kódu do jazyka Lua https://github.com/tisnik/moonscript-examples/blob/master/46_slicing.lua

20. Odkazy na Internetu

  1. Stránky projektu Moonscript
    https://moonscript.org/
  2. Moonscript na GitHubu
    https://github.com/leafo/moonscript
  3. MoonScript online compiler
    https://moonscript.org/compiler/
  4. Vydání Moonscriptu
    https://github.com/leafo/mo­onscript/releases
  5. Moonscript-vim
    https://github.com/leafo/moonscript-vim
  6. Moonscript Examples
    https://github.com/leafo/mo­onscript/wiki/Moonscript-Examples
  7. CoffeeScript
    https://coffeescript.org/
  8. CoffeeScript na Wikipedii
    https://en.wikipedia.org/wi­ki/CoffeeScript
  9. CoffeeScript: řádně oslazený JavaScript
    https://zdrojak.cz/clanky/coffeescript-radne-oslazeny-javascript/
  10. CoffeeScript: druhá dávka steroidů pro vaše skripty
    https://zdrojak.cz/clanky/coffeescript-druha-davka-steroidu-pro-vase-skripty/
  11. Why CoffeeScript is still alive
    https://codeburst.io/why-coffeescript-is-still-alive-aeb369b91b85
  12. The CoffeeScript Wiki
    https://github.com/jashke­nas/coffeescript/wiki
  13. CoffeeScript In The Wild
    https://github.com/jashke­nas/coffeescript/wiki/In-The-Wild
  14. How CoffeeScript Got Forgotten
    https://betterprogramming.pub/how-coffeescript-got-forgotten-812328225987
  15. Objektově orientované programování v jazyku Lua
    https://www.root.cz/clanky/objektove-orientovane-programovani-v-lua/
  16. Objektově orientované programování v jazyku Lua (II)
    https://www.root.cz/clanky/objektove-orientovane-programovani-v-lua-ii/
  17. ULua: Universal Lua Distribution
    https://ulua.io/index.html
  18. LuaRocks
    https://luarocks.org/
  19. Awesome Lua – A curated list of quality Lua packages and resources.
    https://github.com/LewisJEllis/awesome-lua
  20. LuaJIT
    https://luajit.org/
  21. Running LuaJIT
    https://luajit.org/running.html
  22. LuaJIT na GitHubu
    https://github.com/luajit
  23. Lua Implementations
    http://lua-users.org/wiki/LuaImplementations
  24. Coconut: funkcionální jazyk s pattern matchingem kompatibilní s Pythonem
    https://www.root.cz/clanky/coconut-funkcionalni-jazyk-s-pattern-matchingem-kompatibilni-s-pythonem/
  25. Coconut aneb funkcionální nadstavba nad Pythonem (2.část)
    https://www.root.cz/clanky/coconut-aneb-funkcionalni-nadstavba-nad-pythonem-2-cast/
  26. Coconut: Simple, elegant, Pythonic functional programming
    http://coconut-lang.org/
  27. coconut 1.1.0 (Python package index)
    https://pypi.python.org/py­pi/coconut/1.1.0
  28. Coconut Tutorial
    http://coconut.readthedoc­s.io/en/master/HELP.html
  29. Coconut FAQ
    http://coconut.readthedoc­s.io/en/master/FAQ.html
  30. Coconut Documentation
    http://coconut.readthedoc­s.io/en/master/DOCS.html
  31. Coconut na Redditu
    https://www.reddit.com/r/Pyt­hon/comments/4owzu7/coconut_fun­ctional_programming_in_pyt­hon/
  32. Repositář na GitHubu
    https://github.com/evhub/coconut
  33. patterns
    https://github.com/Suor/patterns
  34. Source-to-source compiler
    https://en.wikipedia.org/wiki/Source-to-source_compiler
  35. The Lua VM, on the Web
    https://kripken.github.io/lu­a.vm.js/lua.vm.js.html
  36. Lua.vm.js REPL
    https://kripken.github.io/lu­a.vm.js/repl.html
  37. lua2js
    https://www.npmjs.com/package/lua2js
  38. Wisp na GitHubu
    https://github.com/Gozala/wisp
  39. Wisp playground
    http://www.jeditoolkit.com/try-wisp/
  40. REPL v prohlížeči
    http://www.jeditoolkit.com/in­teractivate-wisp/
  41. Minification (programming)
    https://en.wikipedia.org/wi­ki/Minification_(programmin­g)
  42. Roblox
    https://en.wikipedia.org/wiki/Roblox
  43. Category:Lua (programming language)-scriptable game engines
    https://en.wikipedia.org/wi­ki/Category:Lua_(programmin­g_language)-scriptable_game_engines
  44. Goodbye Lua (shrnutí následujícího článku)
    https://www.reddit.com/r/lu­a/comments/4ld6ao/goodbye_lu­a/
  45. Goodbye, Lua
    https://realmensch.org/2016/05/28/go­odbye-lua/
  46. 6th Edition – ECMAScript 2015
    https://en.wikipedia.org/wi­ki/ECMAScript#6th_Edition_%E2%80%93_EC­MAScript_2015

Autor: Pavel Tišnovský   2021

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.