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:
A postagem foi preparada usando informações do site de idiomas e materiais de Anthony Kwong.