"FP em Python com coco!" |> imprimir

Esta postagem apresenta a linguagem Coconut, um superconjunto funcional da linguagem Python, que visa criar um código elegante e funcional enquanto permanece em um ambiente Python e bibliotecas familiares, e fornece alguns exemplos ilustrativos.





", !" |> x -> x.replace('', 'Coconut') |> print
      
      



A linguagem Coconut (no momento da redação deste artigo, sua versão mais recente é v1.5.0) é um superconjunto estrito orientado a funções da linguagem Python e, portanto, tudo que é válido para Python também é válido para Coconut, enquanto Coconut é transpilado para Pitão. Na verdade, Coconut é um playground para o domínio do paradigma da programação funcional, testando ideias na área de PF, praticando técnicas de resolução de problemas neste paradigma e para fins educacionais.





A página do site de idiomas afirma que o Coconut foi projetado para ser útil para você. O Coconut expande o repertório do programador Python ao alavancar as ferramentas de programação funcional moderna, tornando essas ferramentas mais fáceis de usar e mais poderosas. Em outras palavras, o Coconut faz com a programação funcional o que o Python fez com a programação imperativa.





Esperançosamente, esta postagem prova essas afirmações na prática.





Por precaução, você pode instalar o Coconut usando o gerenciador de pacotes pip: pip install coconut







Coconut é um superconjunto estrito da linguagem Python

Python , , , , . Coconut - Python, - Python.





, Python . Python -, , . , . , .





2016 Python , - , Haskell Scala. Coconut , Python. , . , print(", !")



", !" |> print



. , Python, , (x) -> x2



lambda x: x2



.





, Coconut:









match [head] + tail in [0, 1, 2, 3]:
    print(head, tail)
      
      







data Empty()
data Leaf(n)
data Node(l, r)

def size(Empty()) = 0

addpattern def size(Leaf(n)) = 1

addpattern def size(Node(l, r)) = size(l) + size(r)
      
      







{"list": [0] + rest} = {"list": [0, 1, 2, 3]}
      
      







range(10) |> map$(pow$(?, 2)) |> list
      
      







(| first_elem() |) :: rest_elems()
      
      







(f..g..h)(x, y, z)
      
      







x -> x ** 2
      
      







5 `mod` 3 == 2
      
      







", !" |> x -> x.replace('', 'Coconut') |> print
      
      







product = reduce$(*)
      
      







def factorial(n, acc=1):
    case n:
        match 0:
            return acc
        match _ is int if n > 0:
            return factorial(n-1, acc*n)
      
      







range(100) |> parallel_map$(pow$(2)) |> list
      
      



coconut-develop



(pip install coconut-develop



) Python 3.10, Coconut. Coconut v1.6.0.





Coconut Python Coconut :





, Python, Coconut . , , , , Coconut , , , : Coconut Python, Python, Coconut.





coconut - , Python, . Python Coconut, , Python — - Python.





, Python , Coconut . , .





(Sieve of Eratosthenes) - n, . , , , . , ( ) .





Python

Python : primes



sieve



. primes



sieve



.





from itertools import count, takewhile

def primes():
    def sieve(numbers):
        head = next(numbers)
        yield head
        yield from sieve(n for n in numbers if n % head)
    return sieve(count(2))

list(takewhile(lambda x: x < 60, primes()))
      
      



[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59]
      
      



sieve



count



, , 2 . sieve



(yield



) . (yield from



) sieve



, .





, numbers



next(numbers)



numbers



n for n in numbers if n % head



. , next



- : , .





list



, takewhile



, list



.





, - : , ..





Python Coconut

7 « »() Python Coconut.





1. lambda





lambda



->



.





from itertools import count, takewhile

def primes():
    def sieve(numbers):
        head = next(numbers)
        yield head
        yield from sieve(n for n in numbers if n % head)
    return sieve(count(2))

list(takewhile(x -> x < 60, primes()))
      
      



2.





f(g(h(d)))



-: d -> h -> g -> f



|>



.





from itertools import count, takewhile

def primes():
    def sieve(numbers):
        head = next(numbers)
        yield head
        yield from sieve(n for n in numbers if n % head)
    return sieve(count(2))

primes() |> ns -> takewhile(x -> x < 60, ns) |> list
      
      



3.





, , - . $



.





from itertools import count, takewhile

def primes():
    def sieve(numbers):
        head = next(numbers)
        yield head
        yield from sieve(n for n in numbers if n % head)
    return sieve(count(2))

primes() |> takewhile$(x -> x < 60) |> list
      
      



4.





, yield



, yield



yield from



. , ::



.





from itertools import count, takewhile

def primes():
    def sieve(numbers):
        head = next(numbers)
        return [head] :: sieve(n for n in numbers if n % head)
    return sieve(count(2))

primes() |> takewhile$(x -> x < 60) |> list
      
      



5.





, , , , . ::



, . , .





from itertools import count, takewhile

def primes():
    def sieve([head] :: tail):
        return [head] :: sieve(n for n in tail if n % head)
    return sieve(count(2))

primes() |> takewhile$(x -> x < 60) |> list
      
      



6.





. , . return



=



:



.





from itertools import count, takewhile

def primes() =
    def sieve([x] :: xs) = [x] :: sieve(n for n in xs if n % x)
    sieve(count(2))

primes() |> takewhile$(x -> x < 60) |> list
      
      



7.





, import



. , .. .





def primes() =
    def sieve([x] :: xs) = [x] :: sieve(n for n in xs if n % x)
    sieve(count(2))

primes() |> takewhile$(x -> x < 60) |> list
      
      



[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59]
      
      



. : primes



sieve



, sieve



. :





from itertools import count, takewhile

def primes():
    def sieve(numbers):
        head = next(numbers)
        yield head
        yield from sieve(n for n in numbers if n % head)
    return sieve(count(2))

list(takewhile(lambda x: x < 60, primes()))
      
      



:





def primes() =
    def sieve([x] :: xs) = [x] :: sieve(n for n in xs if n % x)
    sieve(count(2))

primes() |> takewhile$(x -> x < 60) |> list
      
      



, Coconut Haskell:





primes :: [Int]
primes = sieve [2..]
where
    sieve (x :: xs) = x : sieve (filter (\n -> n `rem` x /= 0) xs
    sieve []        = []
                                 
?> takewhile (<60) primes 
      
      







def quick_sort([]) = []

@addpattern(quick_sort)
def quick_sort([head] + tail) =
    """ , 
      ."""
    (quick_sort([x for x in tail if x < head])
    + [head]
    + quick_sort([x for x in tail if x >= head]))
    
quick_sort([3,6,9,2,7,0,1,4,7,8,3,5,6,7])
      
      



[0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 7, 7, 8, 9]
      
      







def factorial(0, acc=1) = acc

@addpattern(factorial)
def factorial(n is int, acc=1 if n > 0) =
    """ n!,  n -    >= 0."""
    factorial(n-1, acc*n)

def is_even(0) = True

@addpattern(is_even)
def is_even(n is int if n > 0) = is_odd(n-1)
def is_odd(0) = False

@addpattern(is_odd)
def is_odd(n is int if n > 0) = is_even(n-1)

factorial(6)  # 720
      
      







@recursive_iterator
def fib_seq() =
    """   ."""
    (1, 1) :: map((+), fib_seq(), fib_seq()$[1:])
            
fib_seq()$[:10] |> parallel_map$(pow$(?, 2)) |> list
      
      



[1, 1, 4, 9, 25, 64, 169, 441, 1156, 3025]
      
      







def zipwith(f, *args) =
    zip(*args) |> map$(items -> f(*items))
    
list(zipwith(lambda x: x > 4, [1,2,3,4,5,6,7,8,9,0]))
      
      



[False, False, False, False, True, True, True, True, True, False]
      
      



Espero que a clareza dos exemplos acima desperte o interesse dos leitores e os incentive a se engajar em um estudo mais profundo do paradigma de FP. Na verdade, o coco oferece açúcar sintático, ou seja, uma série de otimizações de codificação de código que tornam o código funcional, sendo um playground para testar ideias usando o paradigma de programação funcional.





Materiais de referência:





  • Site da linguagem





  • Tutorial





  • Documentação





  • Repositório Github





  • Intérprete online





A postagem foi preparada usando informações do site de idiomas e materiais de Anthony Kwong.








All Articles