Posting ini memperkenalkan bahasa Coconut, superset fungsional dari bahasa Python, yang bertujuan untuk membuat kode fungsional yang elegan sambil tetap berada di lingkungan dan pustaka Python yang sudah dikenal, dan memberikan beberapa contoh ilustratif.
", !" |> x -> x.replace('', 'Coconut') |> print
Bahasa Coconut (pada saat penulisan ini, versi terbarunya adalah v1.5.0) adalah superset ketat berorientasi fungsi dari bahasa Python, dan oleh karena itu semua yang valid untuk Python juga berlaku untuk Coconut, sementara Coconut ditranslasikan ke Python. Padahal, Coconut adalah arena bermain untuk menguasai paradigma pemrograman fungsional, menguji ide-ide di bidang FP, mempraktikkan teknik-teknik pemecahan masalah dalam paradigma ini dan untuk tujuan pendidikan.
Halaman situs bahasa menyatakan bahwa Coconut dirancang untuk berguna bagi Anda. Coconut memperluas repertoar programmer Python dengan memanfaatkan alat pemrograman fungsional modern, membuat alat ini lebih mudah digunakan dan lebih kuat. Dengan kata lain, Coconut melakukan pemrograman fungsional seperti yang dilakukan Python dengan pemrograman imperatif.
Semoga postingan ini membuktikan klaim tersebut dalam praktiknya.
Untuk berjaga-jaga, Anda dapat menginstal Coconut menggunakan pengelola paket pip: pip install coconut
Coconut adalah superset ketat dari bahasa 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]
Saya berharap kejelasan contoh-contoh di atas dapat menggugah minat pembaca dan mendorong mereka untuk mendalami paradigma FP. Faktanya, Kelapa menawarkan gula sintaksis, mis. serangkaian pengoptimalan pengkodean kode yang membuat kode berfungsi dengan menjadi tempat bermain untuk menguji ide-ide menggunakan paradigma pemrograman fungsional.
Bahan referensi:
Posting disiapkan menggunakan informasi dari situs bahasa dan materi dari Anthony Kwong.