Cet article présente le langage Coconut, un sur-ensemble fonctionnel du langage Python, qui vise à créer un code élégant et fonctionnel tout en restant dans un environnement et des bibliothèques Python familiers, et fournit quelques exemples illustratifs.
", !" |> x -> x.replace('', 'Coconut') |> print
Le langage Coconut (au moment d'écrire ces lignes, sa dernière version est la v1.5.0) est un sur-ensemble strict orienté fonction du langage Python, et donc tout ce qui est valide pour Python l'est également pour Coconut, tandis que Coconut est transpilé en Python. En fait, Coconut est un terrain de jeu pour maîtriser le paradigme de la programmation fonctionnelle, tester des idées dans le domaine de la PF, pratiquer des techniques pour résoudre des problèmes dans ce paradigme et à des fins éducatives.
La page du site Web de la langue indique que Coconut est conçu pour vous être utile. Coconut élargit le répertoire du programmeur Python en tirant parti des outils de programmation fonctionnelle moderne, rendant ces outils plus faciles à utiliser et plus puissants. En d'autres termes, Coconut fait avec la programmation fonctionnelle ce que Python a fait avec la programmation impérative.
Espérons que cet article prouve ces affirmations dans la pratique.
Au cas où, vous pouvez installer Coconut en utilisant le gestionnaire de packages pip: pip install coconut
La noix de coco est un sur-ensemble strict du langage 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]
J'espère que la clarté des exemples ci-dessus suscitera l'intérêt des lecteurs et les encouragera à s'engager dans une étude plus approfondie du paradigme de la PF. En fait, Coconut propose du sucre syntaxique, c'est-à-dire une série d'optimisations de codage de code qui rendent le code fonctionnel en étant un terrain de jeu pour tester des idées en utilisant le paradigme de programmation fonctionnelle.
Matériel de référence:
Le message a été préparé en utilisant les informations du site Web linguistique et des documents d'Anthony Kwong.