Pattern matching v programovacím jazyku Coconut (2)

27. 6. 2024
Doba čtení: 39 minut

Sdílet

 Autor: Depositphotos
V dnešním článku budeme pokračovat v popisu technologie strukturálního pattern matchingu, jenž je nedílnou součástí programovacího jazyka Coconut. Některé vzorky, které si ukážeme, přesahují možnosti Pythonu. V tomto ohledu je tedy Coconut o jeden či dva kroky napřed.

Obsah

1. Test, jaké hodnoty jsou uloženy ve dvojici s jejich vzájemným porovnáním

2. Vzorek odpovídající libovolnému řetězci

3. Výsledek transpřekladu se vzorkem odpovídajícím libovolnému řetězci

4. Vzorek obsahující řetězec, zástupný symbol a další řetězec

5. Výsledek transpřekladu vzorku s textovým literálem následovaným zástupným symbolem

6. Několik vzorků obsahujících řetězec, zástupný symbol a další řetězec

7. Jediná větev case s několika vzorky spojenými operátorem |

8. Test, zda je hodnota instancí nějaké třídy

9. Vzorek s testem atributů objektu, včetně podrobnější podmínky

10. Test atributů objektu s dodatečnou podmínkou jejich existence

11. Strukturální pattern matching se slovníky

12. Vzorky založené na seznamu

13. Vzorek se seznamem se známou hlavou (head)

14. Výsledek transpřekladu se vzorkem obsahujícím seznam se známou hlavou

15. Vzorek se seznamem se známým koncem (tail)

16. Výsledek transpřekladu

17. Vzorek se známým začátkem i koncem seznamu

18. Výsledek transpřekladu

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

20. Odkazy na Internetu

1. Test, jaké hodnoty jsou uloženy ve dvojici s jejich vzájemným porovnáním

V předchozím článku jsme si kromě dalších vzorků ukázali i skript, který po svém spuštění zjistí, kolik prvků obsahuje seznam, který byl předán nějaké funkci. Navíc skript zjistil i to, jaké jsou hodnoty těchto prvků a zda se vůbec jedná o seznam. Ovšem ve skutečnosti mohou být vzorky zapsány i složitějším způsobem. Podívejme se na následující příklad, který dokáže zjistit a následně porovnat hodnoty prvků ve dvojici. Prvky buď mohou být totožné (viz první vzorek, v němž se opakuje zástupný symbol x), nebo může být první prvek větší, než prvek druhý, popř. naopak. Realizace takového testu vypadá následovně:

def pair(p):
    match p:
        case [x,x]:
            return "same values!"
        case [x,y] if x>y:
            return "1st value is greater"
        case [x,y]:
            return "2nd value is greater"
    else:
        return "other"
 
 
pair([1, 1]) |> print
pair([1, 2]) |> print
pair([2, 1]) |> print
Poznámka: povšimněte si ještě jednou „implicitního“ testu na rovnost prvků a taktéž toho, že součástí vzorku může být nějaká podmínka, ve které se vyskytují zástupné symboly (placeholdery).

Výsledky získané po spuštění tohoto skriptu dobře ukazují jeho chování:

same values!
2nd value is greater
1st value is greater

2. Vzorek odpovídající libovolnému řetězci

Strukturální pattern matching realizovaný v programovacím jazyce Coconut umožňuje, aby se ve vzorku nacházely i řetězce, popř. řetězce spojené se zástupnými symboly (placeholdery). To je v ekosystému Pythonu relativní novinka, protože samotný programovací jazyk Python zápis takových vzorků nepodporuje (což je škoda). Ukažme si ovšem nejprve velmi jednoduchý příklad se vzorkem, který odpovídá libovolné hodnotě (teprve později se přiblížíme ke komplikovanějším vzorkům):

def say_hello(name):
    match name:
       case x:
           print(f"Hello {x}!")
 
 
say_hello("Marvin")

Po spuštění se vypíše očekávaná zpráva:

Hello Marvin!

3. Výsledek transpřekladu se vzorkem odpovídajícím libovolnému řetězci

Tento skript bude (trans)přeložen do Pythonu následujícím způsobem. Povšimněte si, že se nejprve připraví pomocné proměnné naplňované při testu jednotlivých vzorků a posléze se pouze provede test s hodnotou True, která je konstantně přiřazena do druhé proměnné. Takto mechanicky jsou překládány všechny vzorky, což vede k poměrně dlouhému výslednému kódu (někdy o délce několika kilobajtů):

# Compiled Coconut: -----------------------------------------------------------
 
def say_hello(name):  #1 (line in Coconut source)
    _coconut_case_match_to_0 = name  #2 (line in Coconut source)
    _coconut_case_match_check_0 = False  #2 (line in Coconut source)
    _coconut_match_set_name_x = _coconut_sentinel  #2 (line in Coconut source)
    _coconut_match_set_name_x = _coconut_case_match_to_0  #2 (line in Coconut source)
    _coconut_case_match_check_0 = True  #2 (line in Coconut source)
    if _coconut_case_match_check_0:  #2 (line in Coconut source)
        if _coconut_match_set_name_x is not _coconut_sentinel:  #2 (line in Coconut source)
            x = _coconut_match_set_name_x  #2 (line in Coconut source)
    if _coconut_case_match_check_0:  #2 (line in Coconut source)
        print("Hello {_coconut_format_0}!".format(_coconut_format_0=(x)))  #4 (line in Coconut source)
 
 
 
say_hello("Marvin")  #7 (line in Coconut source)

4. Vzorek obsahující řetězec, zástupný symbol a další řetězec

Skript ze druhé kapitoly byl pouze jakousi ochutnávkou mnohem sofistikovanějších vzorků. Programovací jazyk Coconut totiž umožňuje, aby vzorek vypadat i takto:

  1. řetězcový literál + zástupný symbol
  2. zástupný symbol + řetězcový literál
  3. řetězcový literál + zástupný symbol + řetězcový literál

V praxi to znamená, že v Coconutu není zapotřebí zneužívat regulární výrazy jen proto, abychom například zjistili, jaké jméno je použito ve větě „My name is Marvin.“ (včetně oné tečky na konci). Můžeme totiž zjištění jména ponechat na technologii pattern matchingu a program přepsat do podoby:

def say_hello(about_me):
    match about_me:
       case "My name is " + name + ".":
           print(f"Hello {name}!")
 
 
say_hello("My name is Marvin.")
Poznámka: to v důsledku znamená, že programy psané v Coconutu většinou používají pattern matching i tam, kde by se v Pythonu musely používat regulární výrazy, řezy řetězců, použití metod string.startswith a string.endswithapod.

Podívejme se na výsledek získaný po spuštění tohoto skriptu, abychom zkontrolovali korektnost provedení pattern matchingu:

Hello Marvin!

5. Výsledek transpřekladu vzorku s textovým literálem následovaným zástupným symbolem

Zajímavé bude zjistit, jakým způsobem se vlastně předchozí skript (trans)přeloží do Pythonu, protože to naznačuje, jak bychom mohli tento problém řešit ručně. Povšimněte si, že Coconut detekoval zástupný symbol uprostřed řetězce a využil tedy metody startswith a endwith. Taktéž využil řezy řetězcem (tj. zápis řetězec[od:do]):

# Compiled Coconut: -----------------------------------------------------------
 
def say_hello(about_me):  #1 (line in Coconut source)
    _coconut_case_match_to_0 = about_me  #2 (line in Coconut source)
    _coconut_case_match_check_0 = False  #2 (line in Coconut source)
    _coconut_match_set_name_name = _coconut_sentinel  #2 (line in Coconut source)
    if (_coconut.isinstance(_coconut_case_match_to_0, _coconut.str)) and (_coconut.len(_coconut_case_match_to_0) >= 12) and (_coconut_case_match_to_0.startswith("My name is ")) and (_coconut_case_match_to_0.endswith(".")):  #2 (line in Coconut source)
        _coconut_match_temp_0 = _coconut_case_match_to_0[11:-1]  #2 (line in Coconut source)
        _coconut_match_set_name_name = _coconut_match_temp_0  #2 (line in Coconut source)
        _coconut_case_match_check_0 = True  #2 (line in Coconut source)
    if _coconut_case_match_check_0:  #2 (line in Coconut source)
        if _coconut_match_set_name_name is not _coconut_sentinel:  #2 (line in Coconut source)
            name = _coconut_match_set_name_name  #2 (line in Coconut source)
    if _coconut_case_match_check_0:  #2 (line in Coconut source)
        print("Hello {_coconut_format_0}!".format(_coconut_format_0=(name)))  #4 (line in Coconut source)
 
 
 
say_hello("My name is Marvin.")  #7 (line in Coconut source)

6. Několik vzorků obsahujících řetězec, zástupný symbol a další řetězec

Pochopitelně nám nic nebrání v přidání několika dalších vzorků založených na testování, jaké „pevné“ a „proměnné/zástupné“ části řetězec obsahuje. Například můžeme předchozí demonstrační příklad rozšířit o získání jmen z několika různých oznamovacích vět. Řešení založené na pattern matchingu je stále poměrně přímočaré a dobře čitelné:

def say_hello(about_me):
    match about_me:
       case "My name is " + name + ".":
           print(f"Hello {name}!")
       case "His name is " + name + ".":
           print(f"Hello {name}!")
       case "He is named " + name + ".":
           print(f"Hello {name}!")
       case _:
           print("Sorry, I don't know your name")
 
 
say_hello("My name is Marvin.")
say_hello("His name is Marvin.")
say_hello("He is named Marvin.")
say_hello("Its name is Marvin.")

Opět si vše otestujme:

Hello Marvin!
Hello Marvin!
Hello Marvin!
Sorry, I don't know your name

7. Jediná větev case s několika vzorky spojenými operátorem |

Stejný algoritmus ovšem můžeme zapsat i odlišně, konkrétně s využitím znaku | ve vzorku. Takový vzorek je možné rozdělit na více řádků, ovšem musíme zde použít znak \ na konci, takže je otázkou, jestli se jedná o dobré řešení či nikoli (v tomto případě je asi vhodné, protože se nebude opakovat příkaz zapsaný přímo ve větvi):

def say_hello(about_me):
    match about_me:
       case "My name is " + name + "."| "His name is " + name + "." | "He is named " + name + ".":
           print(f"Hello {name}!")
       case _:
           print("Sorry, I don't know your name")
 
 
say_hello("My name is Marvin.")
say_hello("His name is Marvin.")
say_hello("He is named Marvin.")
say_hello("Its name is Marvin.")

Výsledek by měl být stejný, jako tomu bylo v předchozím demonstračním příkladu:

Hello Marvin!
Hello Marvin!
Hello Marvin!
Sorry, I don't know your name

8. Test, zda je hodnota instancí nějaké třídy

V předchozím článku jsem si ukazovali i několik příkladů, v nichž byly použity n-tice nebo seznamy pro reprezentaci komplexních čísel. V těchto příkladech jsme rozhodovali o tom, zda je komplexní číslo nulové, zda obsahuje nulovou reálnou složku atd. Ovšem v praxi se spíše setkáme s tím, že bude komplexní číslo reprezentováno objektem, konkrétně instancí třídy Complex apod. (jedná se opět o školní příklad, protože Python obsahuje podporu pro komplexní čísla jako plnohodnotných základních datových typů).

Díky existenci strukturálního pattern matchingu však můžeme zapsat vzorky i pro objekty, konkrétně pro otestování, jaké jsou hodnoty atributů těchto objektů. Nebo se může jednat o jednoduchý test, jestli je vůbec hodnota typu Complex, přesněji řečeno instance této třídy (bez ohledu na hodnoty atributů tohoto objektu). Pokusme se tedy skripty z předchozího článku přepsat takovým způsobem, že se budou testovat i vlastnosti komplexního čísla typu Complex předaného do funkce test_number. Nejprve přidáme test, jestli je předaná hodnota typu Complex, v dalším příkladu pak přidáme i testy na atributy. Povšimněte si, že ve skriptu je obsažena podpora i pro původní reprezentaci komplexních čísel jako dvojice hodnot:

class Complex():
 
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag
 
    def __str__(self):
        return f"Complex number {self.real}+i{self.imag} represented as object"
 
 
def test_number(value):
    match value:
        case (0, 0):
            print("Zero")
        case (real, 0) if real>0:
            print(f"Positive real number {real}")
        case (real, 0):
            print(f"Negative real number {real}")
        case (0, imag) if imag<0:
            print(f"Negative imaginary number {imag}")
        case (0, imag):
            print(f"Negative imaginary number {imag}")
        case (real, imag):
            print(f"Complex number {real}+i{imag}")
        case Complex():
            print(value)
        case _:
            raise ValueError("Not a complex number")
 
 
test_number((0,0))
test_number((1,0))
test_number((-1,0))
test_number((0,1))
test_number((0,-1))
test_number((1,1))
 
test_number(Complex(0,0))
test_number(Complex(1,0))
test_number(Complex(-1,0))
test_number(Complex(0,1))
test_number(Complex(0,-1))
test_number(Complex(1,1))

Vše si otestujeme spuštěním skriptu:

Zero
Positive real number 1
Negative real number -1
Negative imaginary number 1
Negative imaginary number -1
Complex number 1+i1
Complex number 0+i0 represented as object
Complex number 1+i0 represented as object
Complex number -1+i0 represented as object
Complex number 0+i1 represented as object
Complex number 0+i-1 represented as object
Complex number 1+i1 represented as object

9. Vzorek s testem atributů objektu, včetně podrobnější podmínky

V předchozím skriptu jsme testovali, jestli je předávaná hodnota typu Complex (tj. instancí této třídy). Jednalo se o následující vzorek:

case Complex():
    print(value)

Ovšem relativně snadno můžeme přidat i test nejenom na typ hodnoty, ale i na konkrétní vlastnosti atributů tohoto objektu. Příkladem může být test na nulové komplexní číslo (tj. na „komplexní nulu“). Tento zápis vypadá následovně a je v této podobě kompatibilní i s jazykem Python:

case Complex(real=0, imag=0):
    print("Zero complex represented as object")

Jednoduše tedy můžeme přidat tento další test, který musí být umístěn za obecnějším testem, do skriptu, jenž získá následující podobu:

class Complex():
 
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag
 
    def __str__(self):
        return f"Complex number {self.real}+i{self.imag} represented as object"
 
 
def test_number(value):
    match value:
        case (0, 0):
            print("Zero")
        case (real, 0) if real>0:
            print(f"Positive real number {real}")
        case (real, 0):
            print(f"Negative real number {real}")
        case (0, imag) if imag<0:
            print(f"Negative imaginary number {imag}")
        case (0, imag):
            print(f"Negative imaginary number {imag}")
        case (real, imag):
            print(f"Complex number {real}+i{imag}")
        case Complex(real=0, imag=0):
            print("Zero complex represented as object")
        case Complex():
            print(value)
        case _:
            raise ValueError("Not a complex number")
 
 
test_number((0,0))
test_number((1,0))
test_number((-1,0))
test_number((0,1))
test_number((0,-1))
test_number((1,1))
 
test_number(Complex(0,0))
test_number(Complex(1,0))
test_number(Complex(-1,0))
test_number(Complex(0,1))
test_number(Complex(0,-1))
test_number(Complex(1,1))

Následují výsledky s otestováním vlastností nové větve se vzorkem:

Zero
Positive real number 1
Negative real number -1
Negative imaginary number 1
Negative imaginary number -1
Complex number 1+i1
Zero complex represented as object
Complex number 1+i0 represented as object
Complex number -1+i0 represented as object
Complex number 0+i1 represented as object
Complex number 0+i-1 represented as object
Complex number 1+i1 represented as object

10. Test atributů objektu s dodatečnou podmínkou jejich existence

V některých situacích je vhodné zjistit, jestli objekt skutečně obsahuje zvolené atributy (protože netřídní atributy jsou v Pythonu vytvářeny dynamicky a není zaručena jejich existence ve všech případech). Vzorek s testem existence (a hodnoty) atributu musí před názvem atributu obsahovat tečku. Takový vzorek je unikátní pro jazyk Coconut a nelze ho použít přímo v Pythonu:

case Complex(.real=0, .imag=0):
    print("Zero complex represented as object")

Doplňme si tedy náš skript pro rozpoznávání různých variant komplexních čísel ještě o výše uvedenou větev s novým typem vzorku. Finální varianta bude vypadat následovně:

class Complex():
 
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag
 
    def __str__(self):
        return f"Complex number {self.real}+i{self.imag} represented as object"
 
 
def test_number(value):
    match value:
        case (0, 0):
            print("Zero")
        case (real, 0) if real>0:
            print(f"Positive real number {real}")
        case (real, 0):
            print(f"Negative real number {real}")
        case (0, imag) if imag<0:
            print(f"Negative imaginary number {imag}")
        case (0, imag):
            print(f"Negative imaginary number {imag}")
        case (real, imag):
            print(f"Complex number {real}+i{imag}")
        case Complex(.real=0, .imag=0):
            print("Zero complex represented as object")
        case Complex():
            print(value)
        case _:
            raise ValueError("Not a complex number")
 
 
test_number((0,0))
test_number((1,0))
test_number((-1,0))
test_number((0,1))
test_number((0,-1))
test_number((1,1))
 
test_number(Complex(0,0))
test_number(Complex(1,0))
test_number(Complex(-1,0))
test_number(Complex(0,1))
test_number(Complex(0,-1))
test_number(Complex(1,1))

Vše si otestujme:

Zero
Positive real number 1
Negative real number -1
Negative imaginary number 1
Negative imaginary number -1
Complex number 1+i1
Zero complex represented as object
Complex number 1+i0 represented as object
Complex number -1+i0 represented as object
Complex number 0+i1 represented as object
Complex number 0+i-1 represented as object
Complex number 1+i1 represented as object

11. Strukturální pattern matching se slovníky

Prozatím jsme si ukázali zhruba jen polovinu typů strukturálních vzorků. Víme již, jak zjistit (a popř. zachytit) hodnoty prvků seznamu. Ovšem prakticky stejným způsobem lze pracovat i s množinami a se slovníky. V následujícím skriptu jsou ukázány vzorky, které nám umožní zjistit, zda předaný slovník obsahuje hodnoty uložené pod zadanými klíči. Jedná se o (zjednodušenou) implementaci funkci pro login, které se předává buď slovník se jménem a příjmením uživatele, nebo slovník s jeho vygenerovaným ID. Na obě možnosti, které mohou nastat, je možné reagovat následujícím způsobem. Povšimněte si, že (podle očekávání) dokážeme zachytit jméno a příjmení, popř. ID do zástupných symbolů x a y, popř. pouze do symbolu x:

def login(value):
    match value:
        case {"name": x, "surname": y}:
            print(f"User identified by name {x} and surname {y}")
        case {"id": x}:
            print(f"User identified by ID {x}")
    else:
        print("Unable to identify user")
 
 
login({"name": "John", "surname": "Joe"})
login({"id": 42})
login({"id": 42, "name": "John"})
login({"id": 42, "name": "John", "surname": "Joe"})
login({"foo": "bar"})

Ukázka, jak tento skript pracuje:

User identified by name John and surname Joe
User identified by ID 42
User identified by ID 42
User identified by name John and surname Joe
Unable to identify user

12. Vzorky založené na seznamu

Poměrně často se setkáme se situací, kdy je nutné zjistit, jestli nějaká n-tice nebo seznam začíná, popř. zda končí nějakou sekvencí hodnot. A pokud n-tice, resp. seznam má odpovídající začátek nebo konec, budeme chtít uložit zbytek sekvence do zástupného symbolu a dále ho nějakým způsobem zpracovat. I tohoto chování je pochopitelně možné v jazyku Coconut dosáhnout, na rozdíl od Pythonu, kde to alespoň prozatím možné není.

13. Vzorek se seznamem se známou hlavou (head)

V dalším demonstračním příkladu je ukázán vzorek, který odpovídá seznamu začínajícího třemi prvky se známou hodnotou 1, 2 a 3. V případě, že seznam obsahuje více hodnot, budou tyto hodnoty uloženy do zástupného symbolu x, což je vlastně chování velmi podobné vzorkům s řetězci:

def list_type(value):
    match value:
        case [1, 2, 3] + x:
            print(f"List starting with expected head, followed by item(s) = {x}")
    else:
        print(f"Unexpected value {value}")
 
 
[] |> list_type
[1] |> list_type
[1, 2] |> list_type
[1, 2, 3] |> list_type
[1, 2, 3, 4] |> list_type
[1, 2, 3, 4, 5] |> list_type
[2, 2, 3, 4, 5] |> list_type

Pokusme se tento skript spustit a zjistit, jakým způsobem rozpozná či naopak nerozpozná vzor pro seznamy různé délky a obsahu:

Unexpected value []
Unexpected value [1]
Unexpected value [1, 2]
List starting with expected head, followed by item(s) = []
List starting with expected head, followed by item(s) = [4]
List starting with expected head, followed by item(s) = [4, 5]
Unexpected value [2, 2, 3, 4, 5]

Povšimněte si, že do zástupného symbolu x je vždy uložen zbytek seznamu, kromě známé a ve vzorku specifikované „hlavy“ seznamu.

14. Výsledek transpřekladu se vzorkem obsahujícím seznam se známou hlavou

Použití podobných vzorků, jakým je i vzorek z předchozí kapitoly, může být v praxi velmi užitečné, takže se podívejme na to, jak je vlastně celá funkce přeložena do Pythonu:

# Compiled Coconut: -----------------------------------------------------------
 
def list_type(value):  #1 (line in Coconut source)
    _coconut_case_match_to_0 = value  #2 (line in Coconut source)
    _coconut_case_match_check_0 = False  #2 (line in Coconut source)
    _coconut_match_set_name_x = _coconut_sentinel  #2 (line in Coconut source)
    if (_coconut.isinstance(_coconut_case_match_to_0, _coconut.abc.Sequence)) and (_coconut.len(_coconut_case_match_to_0) >= 3) and (_coconut_case_match_to_0[0] == 1) and (_coconut_case_match_to_0[1] == 2) and (_coconut_case_match_to_0[2] == 3):  #2 (line in Coconut source)
        _coconut_match_temp_0 = _coconut.list(_coconut_case_match_to_0[3:])  #2 (line in Coconut source)
        _coconut_match_set_name_x = _coconut_match_temp_0  #2 (line in Coconut source)
        _coconut_case_match_check_0 = True  #2 (line in Coconut source)
    if _coconut_case_match_check_0:  #2 (line in Coconut source)
        if _coconut_match_set_name_x is not _coconut_sentinel:  #2 (line in Coconut source)
            x = _coconut_match_set_name_x  #2 (line in Coconut source)
    if _coconut_case_match_check_0:  #2 (line in Coconut source)
        print("List starting with expected head, followed by item(s) = {_coconut_format_0}".format(_coconut_format_0=(x)))  #4 (line in Coconut source)
    if not _coconut_case_match_check_0:  #5 (line in Coconut source)
        print("Unexpected value {_coconut_format_0}".format(_coconut_format_0=(value)))  #6 (line in Coconut source)
 
 
 
(list_type)([])  #9 (line in Coconut source)
(list_type)([1,])  #10 (line in Coconut source)
(list_type)([1, 2])  #11 (line in Coconut source)
(list_type)([1, 2, 3])  #12 (line in Coconut source)
(list_type)([1, 2, 3, 4])  #13 (line in Coconut source)
(list_type)([1, 2, 3, 4, 5])  #14 (line in Coconut source)
(list_type)([2, 2, 3, 4, 5])  #15 (line in Coconut source)
Poznámka: Coconut už v době překladu zná začátek seznamu, takže může použít operace řezu atd.

15. Vzorek se seznamem se známým koncem (tail)

Podobným způsobem je možné napsat funkci se vzorkem, který rozpozná, jestli seznam končí trojicí prvků [7, 8, 9]. Začátek takového seznamu (obecně n prvků nebo i prázdný seznam) je v takovém případě vložen do zástupného symbolu nazvaného x:

def list_type(value):
    match value:
        case x + [7, 8, 9]:
            print(f"List ending with expected tail, preceded by item(s) = {x}")
    else:
        print(f"Unexpected value {value}")
 
 
[8, 9] |> list_type
[7, 8, 9] |> list_type
[6, 7, 8, 9] |> list_type
[5, 6, 7, 8, 9] |> list_type
[4, 5, 6, 7, 8, 9] |> list_type
[3, 4, 5, 6, 7, 8, 9] |> list_type
[2, 3, 4, 5, 6, 7, 8, 9] |> list_type
[1, 2, 3, 4, 5, 6, 7, 8, 9] |> list_type
[1, 2, 3, 4, 5, 6, 7, 8, 1] |> list_type

Otestujme si tento skript, a to opět pro seznamy s různým obsahem:

Unexpected value [8, 9]
List ending with expected tail, preceded by item(s) = []
List ending with expected tail, preceded by item(s) = [6]
List ending with expected tail, preceded by item(s) = [5, 6]
List ending with expected tail, preceded by item(s) = [4, 5, 6]
List ending with expected tail, preceded by item(s) = [3, 4, 5, 6]
List ending with expected tail, preceded by item(s) = [2, 3, 4, 5, 6]
List ending with expected tail, preceded by item(s) = [1, 2, 3, 4, 5, 6]
Unexpected value [1, 2, 3, 4, 5, 6, 7, 8, 1]

16. Výsledek transpřekladu

V (trans)přeloženém kódu opět můžeme vidět operace řezu (slice), tentokrát však se zápornými indexy, tj. s indexy, které se počítají od konce seznamu či jiné sekvence:

# Compiled Coconut: -----------------------------------------------------------
 
def list_type(value):  #1 (line in Coconut source)
    _coconut_case_match_to_0 = value  #2 (line in Coconut source)
    _coconut_case_match_check_0 = False  #2 (line in Coconut source)
    _coconut_match_set_name_x = _coconut_sentinel  #2 (line in Coconut source)
    if (_coconut.isinstance(_coconut_case_match_to_0, _coconut.abc.Sequence)) and (_coconut.len(_coconut_case_match_to_0) >= 3) and (_coconut_case_match_to_0[-3] == 7) and (_coconut_case_match_to_0[-2] == 8) and (_coconut_case_match_to_0[-1] == 9):  #2 (line in Coconut source)
        _coconut_match_temp_0 = _coconut.list(_coconut_case_match_to_0[:-3])  #2 (line in Coconut source)
        _coconut_match_set_name_x = _coconut_match_temp_0  #2 (line in Coconut source)
        _coconut_case_match_check_0 = True  #2 (line in Coconut source)
    if _coconut_case_match_check_0:  #2 (line in Coconut source)
        if _coconut_match_set_name_x is not _coconut_sentinel:  #2 (line in Coconut source)
            x = _coconut_match_set_name_x  #2 (line in Coconut source)
    if _coconut_case_match_check_0:  #2 (line in Coconut source)
        print("List ending with expected tail, preceded by item(s) = {_coconut_format_0}".format(_coconut_format_0=(x)))  #4 (line in Coconut source)
    if not _coconut_case_match_check_0:  #5 (line in Coconut source)
        print("Unexpected value {_coconut_format_0}".format(_coconut_format_0=(value)))  #6 (line in Coconut source)
 
 
 
(list_type)([8, 9])  #9 (line in Coconut source)
(list_type)([7, 8, 9])  #10 (line in Coconut source)
(list_type)([6, 7, 8, 9])  #11 (line in Coconut source)
(list_type)([5, 6, 7, 8, 9])  #12 (line in Coconut source)
(list_type)([4, 5, 6, 7, 8, 9])  #13 (line in Coconut source)
(list_type)([3, 4, 5, 6, 7, 8, 9])  #14 (line in Coconut source)
(list_type)([2, 3, 4, 5, 6, 7, 8, 9])  #15 (line in Coconut source)
(list_type)([1, 2, 3, 4, 5, 6, 7, 8, 9])  #16 (line in Coconut source)
(list_type)([1, 2, 3, 4, 5, 6, 7, 8, 1])  #17 (line in Coconut source)

17. Vzorek se známým začátkem i koncem seznamu

Dostáváme se k dnešnímu poslednímu příkladu. V něm je použit vzorek se seznamem, u kterého jsou známé prvky jak na jeho začátku, tak i na jeho konci. I takové vzorky nám Coconut umožňuje specifikovat, pochopitelně s tím, že „prostředek“ seznamu se opět uloží do zvoleného zástupného symbolu. A navíc je možné přidat i doplňkový test, pokud to bude zapotřebí:

ict ve školství 24

def list_type(value):
    match value:
        case [1, 2, 3] + x + [7, 8, 9]:
            print(f"Items between head and tail: {x}")
    else:
        print(f"Unexpected value {value}")
 
 
[1, 2, 3, 7, 8, 9] |> list_type
[1, 2, 3, 6, 7, 8, 9] |> list_type
[1, 2, 3, 5, 6, 7, 8, 9] |> list_type
[1, 2, 3, 4, 5, 6, 7, 8, 9] |> list_type
[9, 2, 3, 4, 5, 6, 7, 8, 9] |> list_type
[1, 2, 3, 4, 5, 6, 7, 8, 1] |> list_type
Items between head and tail: []
Items between head and tail: [6]
Items between head and tail: [5, 6]
Items between head and tail: [4, 5, 6]
Unexpected value [9, 2, 3, 4, 5, 6, 7, 8, 9]
Unexpected value [1, 2, 3, 4, 5, 6, 7, 8, 1]

18. Výsledek transpřekladu

Již naposledy se podívejme na to, jak vypadá výsledek (trans)překladu skriptu ze sedmnácté kapitoly. Uvidíme zde poměrně otrockou kontrolu prvních a posledních prvků v seznamu. Tuto část by pravděpodobně bylo možné napsat lépe (opět s využitím řezů porovnávaných s konstantní sekvencí atd.):

# Compiled Coconut: -----------------------------------------------------------
 
def list_type(value):  #1 (line in Coconut source)
    _coconut_case_match_to_0 = value  #2 (line in Coconut source)
    _coconut_case_match_check_0 = False  #2 (line in Coconut source)
    _coconut_match_set_name_x = _coconut_sentinel  #2 (line in Coconut source)
    if (_coconut.isinstance(_coconut_case_match_to_0, _coconut.abc.Sequence)) and (_coconut.len(_coconut_case_match_to_0) >= 6) and (_coconut_case_match_to_0[0] == 1) and (_coconut_case_match_to_0[1] == 2) and (_coconut_case_match_to_0[2] == 3) and (_coconut_case_match_to_0[-3] == 7) and (_coconut_case_match_to_0[-2] == 8) and (_coconut_case_match_to_0[-1] == 9):  #2 (line in Coconut source)
        _coconut_match_temp_0 = _coconut.list(_coconut_case_match_to_0[3:-3])  #2 (line in Coconut source)
        _coconut_match_set_name_x = _coconut_match_temp_0  #2 (line in Coconut source)
        _coconut_case_match_check_0 = True  #2 (line in Coconut source)
    if _coconut_case_match_check_0:  #2 (line in Coconut source)
        if _coconut_match_set_name_x is not _coconut_sentinel:  #2 (line in Coconut source)
            x = _coconut_match_set_name_x  #2 (line in Coconut source)
    if _coconut_case_match_check_0:  #2 (line in Coconut source)
        print("Items between head and tail: {_coconut_format_0}".format(_coconut_format_0=(x)))  #4 (line in Coconut source)
    if not _coconut_case_match_check_0:  #5 (line in Coconut source)
        print("Unexpected value {_coconut_format_0}".format(_coconut_format_0=(value)))  #6 (line in Coconut source)
 
 
 
(list_type)([1, 2, 3, 7, 8, 9])  #9 (line in Coconut source)
(list_type)([1, 2, 3, 6, 7, 8, 9])  #10 (line in Coconut source)
(list_type)([1, 2, 3, 5, 6, 7, 8, 9])  #11 (line in Coconut source)
(list_type)([1, 2, 3, 4, 5, 6, 7, 8, 9])  #12 (line in Coconut source)
(list_type)([9, 2, 3, 4, 5, 6, 7, 8, 9])  #13 (line in Coconut source)
(list_type)([1, 2, 3, 4, 5, 6, 7, 8, 1])  #14 (line in Coconut source)

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

Zdrojové kódy všech prozatím popsaných demonstračních příkladů určených pro programovací jazyk Coconut byly uloženy do Git repositáře dostupného na adrese https://github.com/tisnik/most-popular-python-libs.

# Příklad Stručný popis Adresa
1 hello-world.coco Program typu „Hello, world“ naprogramovaný v jazyce Coconut https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/hello-world.coco
2 hello-world.py překlad pipeline s voláním funkce print do Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/hello-world.py
3 hello-world-non-optim.py ukázka celého souboru (čistý Python), který vznikne výsledkem transpřekladu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/hello-world-non-optim.py
4 hello-world-minified.py ukázka celého souboru (čistý Python), který vznikne výsledkem transpřekladu s povolenou minifikací https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/hello-world-minified.py
       
5 lambda-old-style.coco zápis anonymní funkce s využitím operátoru → (původní styl Pythonu) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-old-style.coco
6 lambda-old-style.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-old-style.py
7 lambda-new-style.coco zápis anonymní funkce s využitím operátoru ⇒ (doporučovaný styl) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-new-style.coco
8 lambda-new-style.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-new-style.py
       
9 original-factorial-1.py výpočet faktoriálu naprogramovaný v Pythonu: použití anonymní funkce https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/original-factorial-1.py
10 original-factorial-2.py výpočet faktoriálu naprogramovaný v Pythonu: vnořené anonymní funkce https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/original-factorial-2.py
11 original-factorial-3.py výpočet tabulky s faktoriály bez použití programových smyček https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/original-factorial-3.py
       
12 lambda-factorial-1.coco výpočet faktoriálu s anonymní funkcí se dvěma parametry (nekorektní zápis) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-factorial-1.coco
13 lambda-factorial-1.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-factorial-1.py
14 lambda-factorial-2.coco výpočet faktoriálu s anonymní funkcí se dvěma parametry (korektní zápis) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-factorial-2.coco
15 lambda-factorial-2.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-factorial-2.py
16 lambda-factorial-3.coco vnořené anonymní funkce https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-factorial-3.coco
17 lambda-factorial-3.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-factorial-3.py
18 lambda-factorial-4.coco výpočet tabulky s faktoriály bez použití programových smyček https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-factorial-4.coco
19 lambda-factorial-4.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-factorial-4.py
20 lambda-factorial-5.coco výpočet tabulky s faktoriály bez použití programových smyček + použití pipe https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-factorial-5.coco
21 lambda-factorial-5.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/lambda-factorial-5.py
       
22 implicit-lambda-1.coco lambda výraz s implicitním parametrem https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/implicit-lambda-1.coco
23 implicit-lambda-1.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/implicit-lambda-1.py
24 implicit-lambda-2.coco lambda výraz bez parametru https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/implicit-lambda-2.coco
25 implicit-lambda-2.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/implicit-lambda-2.py
       
26 statement-lambda-1.coco plnohodnotná anonymní funkce https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/statement-lambda-1.coco
27 statement-lambda-1.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/statement-lambda-1.py
28 statement-lambda-2.coco anonymní funkce s příkazem a výrazem https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/statement-lambda-2.coco
29 statement-lambda-2.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/statement-lambda-2.py
       
30 statement-lambda-type-hints.coco anonymní funkce s typovými informacemi https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/statement-lambda-type-hints.coco
31 statement-lambda-type-hints-python-2.py výsledek překladu skriptu do standardního Pythonu verze 2 https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/statement-lambda-type-hints-python-2.py
32 statement-lambda-type-hints-python-3.py výsledek překladu skriptu do standardního Pythonu verze 3 https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/statement-lambda-type-hints-python-3.py
       
33 original-partial-1.py částečně vyhodnocená funkce, realizace provedená ve standardním Pythonu, první verze (funkce se dvěma parametry) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/original-partial-1.py
34 original-partial-2.py částečně vyhodnocená funkce, realizace provedená ve standardním Pythonu, druhá verze (funkce se třemi parametry) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/original-partial-2.py
35 original-partial-3.py částečně vyhodnocená funkce, realizace provedená ve standardním Pythonu, třetí verze (funkce se čtyřmi parametry) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/original-partial-3.py
       
36 partial-1.coco částečně vyhodnocená funkce zapsaná v jazyku Coconut, první verze (funkce se dvěma parametry) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/partial-1.coco
37 partial-1.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/partial-1.py
38 partial-2.coco částečně vyhodnocená funkce zapsaná v jazyku Coconut, druhá verze (funkce se třemi parametry) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/partial-2.coco
39 partial-2.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/partial-2.py
40 partial-3.coco částečně vyhodnocená funkce zapsaná v jazyku Coconut, třetí verze (funkce se čtyřmi parametry) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/partial-3.coco
41 partial-3.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/partial-3.py
       
42 partial-map.coco částečně vyhodnocená funkce vyššího řádu fmap https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/partial-map.coco
43 partial-map.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/partial-map.py
       
44 sequences1A.coco ukázka rozdílu v chování funkcí map a fmap https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/se­quences1A.coco
45 sequences1A.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/se­quences1A.py
46 sequences1B.coco přepis předchozího demonstračního příkladu tak, že se využije zkrácený zápis lambda výrazů https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/se­quences1B.coco
47 sequences1B.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/se­quences1B.py
48 sequences1C.coco přepis předchozího demonstračního příkladu tak, že se využije zkrácený zápis lambda výrazů s implicitním parametrem https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/se­quences1C.coco
49 sequences1C.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/se­quences1C.py
50 sequences2A.coco ukázka funkcí reduce, takewhile a dropwhile https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/se­quences2A.coco
51 sequences2A.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/se­quences2A.py
52 sequences2B.coco přepis předchozího demonstračního příkladu tak, že se využije zkrácený zápis lambda výrazů https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/se­quences2B.coco
53 sequences2B.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/se­quences2B.py
54 sequences2C.coco přepis předchozího demonstračního příkladu tak, že se využije zkrácený zápis lambda výrazů s implicitním parametrem https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/se­quences2C.coco
55 sequences2C.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/se­quences2C.py
       
56 custom-operator-1.coco vytvoření nového binárního operátoru https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/custom-operator-1.coco
57 custom-operator-1.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/custom-operator-1.py
58 custom-operator-2.coco vytvoření nového binárního operátoru https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/custom-operator-2.coco
59 custom-operator-2.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/custom-operator-2.py
60 custom-operator-3.coco vytvoření nového unárního operátoru https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/custom-operator-3.coco
61 custom-operator-3.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/custom-operator-3.py
       
62 infix-notation-1.coco infixový zápis volání funkce add https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/infix-notation-1.coco
63 infix-notation-1.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/infix-notation-1.py
64 infix-notation-2.coco infixový zápis volání funkce factorial https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/infix-notation-2.coco
65 infix-notation-2.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/infix-notation-2.py
66 infix-notation-3.coco infixová definice funkce nad https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/infix-notation-3.coco
67 infix-notation-3.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/infix-notation-3.py
68 infix-notation-4.coco infixový zápis volání funkcí a priorita operací https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/infix-notation-4.coco
69 infix-notation-4.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/infix-notation-4.py
       
70 py3-only-async-await.coco konstrukce platná pouze v Pythonu 3.x – asyncawait https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/py3-only-async-await.coco
71 py3-only-async-await.py výsledek překladu skriptu do standardního Pythonu verze 3.x https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/py3-only-async-await.py
72 py3-only-counter_closure.coco konstrukce platná pouze v Pythonu 3.x – nelokální proměnná https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/py3-only-counter_closure.coco
73 py3-only-counter_closure.py výsledek překladu skriptu do standardního Pythonu verze 3.x https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/py3-only-counter_closure.py
74 py3-only-walrus-operator.coco konstrukce platná pouze v Pythonu 3.x – mroží operátor https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/py3-only-walrus-operator.coco
75 py3-only-walrus-operator.py výsledek překladu skriptu do standardního Pythonu verze 3.x https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/py3-only-walrus-operator.py
       
76 pipeline-basic.coco základní forma kolony, v níž data proudí zleva doprava https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-basic.coco
77 pipeline-basic.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-basic.py
78 pipeline-backward.coco základní forma kolony, v níž data proudí zprava doleva https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-backward.coco
79 pipeline-backward.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-backward.py
       
80 pipeline-none-not-aware.coco kolona, která nerozeznává hodnoty None https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-none-not-aware.coco
81 pipeline-none-not-aware.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-none-not-aware.py
82 pipeline-none-aware.coco kolona, která rozeznává hodnoty None https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-none-aware.coco
83 pipeline-none-aware.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-none-aware.py
84 pipeline-none-aware-2.coco kolona, která rozeznává hodnoty None, explicitní tisk výsledků https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-none-aware-2.coco
85 pipeline-none-aware-2.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-none-aware-2.py
       
86 pipeline-backward-none-not-aware.coco „zpětná“ kolona, která nerozeznává hodnoty None https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-backward-none-not-aware.coco
87 pipeline-backward-none-not-aware.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-backward-none-not-aware.py
88 pipeline-backward-none-aware.coco „zpětná“ kolona, která rozeznává hodnoty None https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-backward-none-aware.coco
89 pipeline-backward-none-aware.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-backward-none-aware.py
       
90 pipeline-multiple-arguments.coco kolona přenášející větší množství argumentů mezi funkcemi https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-multiple-arguments.coco
91 pipeline-multiple-arguments.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-multiple-arguments.py
92 pipeline-multiple-arguments-2.coco použití standardního operátoru pro rozdíl v koloně https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-multiple-arguments-2.coco
93 pipeline-multiple-arguments-2.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-multiple-arguments-2.py
94 pipeline-keyword-arguments.coco kolona přenášející keyword argumenty https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-keyword-arguments.coco
95 pipeline-keyword-arguments.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pipeline-keyword-arguments.py
       
96 function-composition-1.coco použití kompozice funkcí v koloně https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/function-composition-1.coco
97 function-composition-1.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/function-composition-1.py
98 function-composition-2.coco uložení kompozice funkcí do nového symbolu (nové funkce) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/function-composition-2.coco
99 function-composition-2.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/function-composition-2.py
100 function-composition-3.coco kompozice funkcí operátorem <.. https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/function-composition-3.coco
101 function-composition-3.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/function-composition-3.py
102 function-composition-4.coco kompozice funkcí a hodnota None https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/function-composition-4.coco
103 function-composition-4.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/function-composition-4.py
       
104 pattern-matching-1.coco výpočet faktoriálu realizovaný v původní syntaxi jazyka Coconut https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-1.coco
105 pattern-matching-1.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-1.py
106 pattern-matching-2.coco výpočet faktoriálu realizovaný v syntaxi jazyka Coconut kompatibilní s Pythonem 3.10 https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-2.coco
107 pattern-matching-2.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-2.py
108 pattern-matching-3.coco ve větvi s rekurzí se kontroluje, zda je vstupní hodnota kladná https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-3.coco
109 pattern-matching-3.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-3.py
110 pattern-matching-4.coco test na typ předané hodnoty (původní syntaxe) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-4.coco
111 pattern-matching-4.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-4.py
112 pattern-matching-5.coco test na typ předané hodnoty (nová syntaxe) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-5.coco
113 pattern-matching-5.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-5.py
114 pattern-matching-6.coco spojení dvou vzorků pomocí operátoru | https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-6.coco
115 pattern-matching-6.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-6.py
       
116 pattern-matching-7.coco zjištění, kolik prvků obsahuje sezname https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-7.coco
117 pattern-matching-7.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-7.py
118 pattern-matching-8.coco vylepšení předchozího příkladu, tisk hodnot prvků ze seznamu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-8.coco
119 pattern-matching-8.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-8.py
120 pattern-matching-9.coco test, zda je do funkce list_type předán skutečně seznam, první varianta https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-9.coco
121 pattern-matching-9.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-9.py
122 pattern-matching-A.coco test, zda je do funkce list_type předán skutečně seznam, druhá varianta https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-A.coco
123 pattern-matching-A.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-A.py
       
124 pattern-matching-B.coco pattern matching a dvojice hodnot představujících komplexní čísla https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-B.coco
125 pattern-matching-B.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-B.py
126 pattern-matching-C.coco detekce, zda není reálná nebo imaginární složka komplexního čísla nulová https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-C.coco
127 pattern-matching-C.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-C.py
128 pattern-matching-D.coco dtto, ovšem využití seznamu s dvojicí hodnot namísto n-tice https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-D.coco
129 pattern-matching-D.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-D.py
       
129 pattern-matching-E.coco test, jaké hodnoty jsou uloženy ve dvojici https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-E.coco
130 pattern-matching-E.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-E.py
131 pattern-matching-F.coco vzorek odpovídající libovolnému řetězci https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-F.coco
132 pattern-matching-F.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-F.py
133 pattern-matching-G.coco vzorek obsahující řetězec, zástupný symbol a další řetězec https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-G.coco
134 pattern-matching-G.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-G.py
135 pattern-matching-H.coco několik vzorků obsahujících řetězec, zástupný symbol a další řetězec https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-H.coco
136 pattern-matching-H.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-H.py
       
137 pattern-matching-I.coco test, zda je hodnota instancí nějaké třídy https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-I.coco
138 pattern-matching-I.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-I.py
139 pattern-matching-J.coco vzorek s testem atributů objektu, včetně podrobnější podmínky https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-J.coco
140 pattern-matching-J.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-J.py
141 pattern-matching-K.coco test atributů objektu s dodatečnou podmínkou jejich existence https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-K.coco
142 pattern-matching-K.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-K.py
143 pattern-matching-L.coco strukturální pattern matching se slovníky https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-L.coco
144 pattern-matching-L.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-L.py
145 pattern-matching-M.coco vzorek se seznamem se známou hlavou (head) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-M.coco
146 pattern-matching-M.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-M.py
147 pattern-matching-N.coco vzorek se seznamem se známým koncem (tail) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-N.coco
148 pattern-matching-N.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-N.py
149 pattern-matching-O.coco vzorek se seznamem se známou hlavou a současně i koncem (head + tail) https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-O.coco
150 pattern-matching-O.py výsledek překladu skriptu do standardního Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/coconut/pattern-matching-O.py

20. Odkazy na Internetu

  1. Pattern matching (Wikipedia)
    https://en.wikipedia.org/wi­ki/Pattern_matching
  2. Coconut: funkcionální jazyk s pattern matchingem kompatibilní s Pythonem
    https://www.root.cz/clanky/coconut-funkcionalni-jazyk-s-pattern-matchingem-kompatibilni-s-pythonem/
  3. Coconut aneb funkcionální nadstavba nad Pythonem (2.část)
    https://www.root.cz/clanky/coconut-aneb-funkcionalni-nadstavba-nad-pythonem-2-cast/
  4. Python 3.10 and the Elegance of Pattern Matching
    https://python.plainenglish.io/python-3–10-and-the-elegance-of-pattern-matching-2620a02b2379
  5. More Pattern Matching in Python 3.10
    https://towardsdatascience.com/more-advanced-pattern-matching-in-python-3–10–2dbd8598302a
  6. Pattern Matching in Python 3.10
    https://towardsdatascience.com/pattern-matching-in-python-3–10–6124ff2079f0
  7. Python 3.10.0
    https://www.python.org/dow­nloads/release/python-3100/
  8. The fate of reduce() in Python 3000
    http://lambda-the-ultimate.org/node/587
  9. PEP 634 – Structural Pattern Matching: Specification
    https://peps.python.org/pep-0634/
  10. PEP 635 – Structural Pattern Matching: Motivation and Rationale
    https://peps.python.org/pep-0635/
  11. PEP 636 – Structural Pattern Matching: Tutorial
    https://peps.python.org/pep-0636/
  12. PEP 622 – Structural Pattern Matching
    https://peps.python.org/pep-0622/
  13. Python 3.10 se strukturálním pattern matchingem
    https://www.root.cz/zpravicky/python-3–10-se-strukturalnim-pattern-matchingem/
  14. Null coalescing operator
    https://en.wikipedia.org/wi­ki/Null_coalescing_operator
  15. Operátor koalescence
    https://cs.wikipedia.org/wi­ki/Oper%C3%A1tor_koalescen­ce
  16. Clojure core.match
    https://github.com/clojure/core.match
  17. The Rust Programming Language: Patterns and Matching
    https://doc.rust-lang.org/book/ch18–00-patterns.html#patterns-and-matching
  18. The Rust Programming Language: Pattern Syntax
    https://doc.rust-lang.org/book/ch18–03-pattern-syntax.html
  19. Elvis operator
    https://en.wikipedia.org/wi­ki/Elvis_operator
  20. Safe navigation operator
    https://en.wikipedia.org/wi­ki/Safe_navigation_operator
  21. Setting stacksize in a python script
    https://stackoverflow.com/qu­estions/5061582/setting-stacksize-in-a-python-script
  22. What is the maximum recursion depth in Python, and how to increase it?
    https://stackoverflow.com/qu­estions/3323001/what-is-the-maximum-recursion-depth-in-python-and-how-to-increase-it?rq=1
  23. Does Python optimize tail recursion?
    https://stackoverflow.com/qu­estions/13591970/does-python-optimize-tail-recursion
  24. Programovací jazyk APL: programování bez smyček
    https://www.root.cz/clanky/pro­gramovaci-jazyk-apl-programovani-bez-smycek/
  25. Programovací jazyk APL – dokončení
    https://www.root.cz/clanky/pro­gramovaci-jazyk-apl-dokonceni/
  26. Tail call
    https://en.wikipedia.org/wi­ki/Tail_call
  27. Tail Call Optimization for Python
    https://github.com/baruchel/tco
  28. Tail Recursion Elimination
    http://neopythonic.blogspot­.cz/2009/04/tail-recursion-elimination.html
  29. Origins of Python's „Functional“ Features
    http://python-history.blogspot.cz/2009/04/origins-of-pythons-functional-features.html
  30. Tail recursion decorator revisited
    http://fiber-space.de/wordpress/2009/04/20/tail-recursion-decorator-revisited/
  31. Koncová rekurze
    https://cs.wikipedia.org/wi­ki/Koncov%C3%A1_rekurze
  32. Recursion (computer science)
    https://en.wikipedia.org/wi­ki/Recursion_%28computer_sci­ence%29
  33. Coconut: Simple, elegant, Pythonic functional programming
    http://coconut-lang.org/
  34. coconut 1.1.0 (Python package index)
    https://pypi.python.org/py­pi/coconut/1.1.0
  35. Coconut Tutorial
    http://coconut.readthedoc­s.io/en/master/HELP.html
  36. Coconut FAQ
    http://coconut.readthedoc­s.io/en/master/FAQ.html
  37. Coconut Documentation
    http://coconut.readthedoc­s.io/en/master/DOCS.html
  38. Python gains functional programming syntax via Coconut
    https://www.infoworld.com/ar­ticle/3088058/python-gains-functional-programming-syntax-via-coconut.html
  39. Repositář projektu pyparsing
    https://github.com/pyparsin­g/pyparsing
  40. Repositář projektu cPyparsing
    https://github.com/evhub/cpyparsing
  41. Projekty vylepšující interaktivní režim Pythonu: bpython, ptpython, DreamPie a IPython
    https://www.root.cz/clanky/projekty-vylepsujici-interaktivni-rezim-pythonu-bpython-ptpython-dreampie-a-ipython/
  42. Coconut na Redditu
    https://www.reddit.com/r/Pyt­hon/comments/4owzu7/coconut_fun­ctional_programming_in_pyt­hon/
  43. Repositář na GitHubu
    https://github.com/evhub/coconut
  44. patterns
    https://github.com/Suor/patterns
  45. Source-to-source compiler
    https://en.wikipedia.org/wiki/Source-to-source_compiler
  46. The Lua VM, on the Web
    https://kripken.github.io/lu­a.vm.js/lua.vm.js.html
  47. Lua.vm.js REPL
    https://kripken.github.io/lu­a.vm.js/repl.html
  48. lua2js
    https://www.npmjs.com/package/lua2js
  49. Wisp na GitHubu
    https://github.com/Gozala/wisp
  50. Wisp playground
    http://www.jeditoolkit.com/try-wisp/
  51. REPL v prohlížeči
    http://www.jeditoolkit.com/in­teractivate-wisp/
  52. Minification (programming)
    https://en.wikipedia.org/wi­ki/Minification_(programmin­g)
  53. JavaScript is Assembly Language for the Web: Sematic Markup is Dead! Clean vs. Machine-coded HTML
    http://www.hanselman.com/blog/Ja­vaScriptIsAssemblyLanguage­ForTheWebSematicMarkupIsDe­adCleanVsMachinecodedHTML­.aspx
  54. JavaScript is Web Assembly Language and that's OK.
    http://www.hanselman.com/blog/Ja­vaScriptIsWebAssemblyLangu­ageAndThatsOK.aspx
  55. Dart
    https://www.dartlang.org/
  56. CoffeeScript
    http://coffeescript.org/
  57. TypeScript
    http://www.typescriptlang.org/
  58. JavaScript: The Web Assembly Language?
    http://www.informit.com/ar­ticles/article.aspx?p=1856657
  59. asm.js
    http://asmjs.org/
  60. List of languages that compile to JS
    https://github.com/jashke­nas/coffeescript/wiki/List-of-languages-that-compile-to-JS
  61. Permutation
    https://en.wikipedia.org/wi­ki/Permutation
  62. Pattern matching (Wikipedia)
    https://en.wikipedia.org/wi­ki/Pattern_matching
  63. Programovací jazyky používané v SSSR (část 2 – SNOBOL)
    https://www.root.cz/clanky/pro­gramovaci-jazyky-pouzivane-v-sssr-cast-2-ndash-snobol/
  64. Pattern matching v Rustu
    https://www.root.cz/clanky/rust-funkce-lambda-vyrazy-a-rozhodovaci-konstrukce-match/#k13
  65. SNOBOL
    https://en.wikipedia.org/wiki/SNOBOL
  66. Podpůrný plugin pro Vim
    https://github.com/manicma­niac/coconut.vim
  67. Příkaz (programování)
    https://cs.wikipedia.org/wi­ki/P%C5%99%C3%ADkaz_%28pro­gramov%C3%A1n%C3%AD%29
  68. Threading Macros Guide
    https://clojure.org/guides/thre­ading_macros
  69. Nejdůležitější novinka v Pythonu 3.10: strukturální pattern matching
    https://www.root.cz/clanky/nej­dulezitejsi-novinka-v-pythonu-3–10-strukturalni-pattern-matching/
  70. Rosetta Code: Roman_numerals
    http://rosettacode.org/wi­ki/Roman_numerals
  71. Category:SNOBOL4
    http://rosettacode.org/wi­ki/Category:SNOBOL4
  72. An introduction to SNOBOL by James Ford
    http://drofmij.awardspace.com/snobol/
  73. AWK
    https://en.wikipedia.org/wiki/AWK
  74. Get started with GAWK: AWK language fundamentals
    https://web.archive.org/web/20150427143548/htt­ps://www6.software.ibm.com/de­veloperworks/education/au-gawk/au-gawk-a4.pdf
  75. Pattern Matching
    https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching
  76. Parsing expression grammar
    https://en.wikipedia.org/wi­ki/Parsing_expression_gram­mar
  77. Abort, Retry, Fail?
    https://en.wikipedia.org/wi­ki/Abort,_Retry,_Fail%3F
  78. SNOBOL4 and SPITBOL Information
    http://www.snobol4.com/
  79. Vanilla Snobol4 Reference Manual
    http://burks.bton.ac.uk/bur­ks/language/snobol/catspaw/ma­nual/contents.htm
  80. SNOBOL4.ORG – SNOBOL4 Resources
    http://www.snobol4.org/
  81. Snobol3 – Snobol 3 Interpreter Implemented in Java
    http://serl.cs.colorado.e­du/~dennis/software/s3.html
  82. Exploring Beautiful Languages – A guick look at SNOBOL
    http://langexplr.blogspot­.com/2007/12/quick-look-at-snobol.html
  83. Rekurze a pattern matching v programovacím jazyku F#
    https://www.root.cz/clanky/rekurze-a-pattern-matching-v-programovacim-jazyku-f/
  84. Programovací jazyk OCaml: rekurze, pattern matching a práce se seznamy
    https://www.root.cz/clanky/pro­gramovaci-jazyk-ocaml-rekurze-pattern-matching-a-prace-se-seznamy/
ikonka

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.

Autor článku

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