Piping and multi-dispatch for python
Project description
coppertop - piping and multi-dispatch for python
Coppertop provides a bones-style aggregation manipulation experience in python via the following:
- partial (application of) functions
- piping syntax
- multiple-dispatch
- type system with primitives, intersections, unions, products, exponentials, overloads and type schemas thus allowing Python to be a library implementation language for bones
- immutable updates
- contextual scope
- and an embryonic core library of common pipeable functions
Partial (application of) functions
By decorating a function with @coppertop (and importing _) we can easily create partial functions, for example:
syntax: f(_, a)
-> f(_)
where _
is used as a sentinel place-holder for arguments yet to be confirmed (TBC)
from coppertop.pipe import *
@coppertop
def appendStr(x, y):
assert isinstance(x, str) and isinstance(y, str)
return x + y
appendWorld = appendStr(_, " world!")
assert appendWorld("hello") == "hello world!"
Piping syntax
The @coppertop function decorator also extends functions with the >>
operator
and so allows code to be written in a more essay style format - i.e. left-to-right and
top-to-bottom. The idea is to make it easy to express the syntax (aka sequence) of a solution.
unary style - takes 1 piped argument and 0+ called arguments
syntax: A >> f(args)
-> f(args)(A)
from dm.std import anon
@coppertop
def addOne(x):
return x + 1
1 >> addOne
"hello" >> appendStr(_," ") >> appendStr(_, "world!")
1 >> anon(lambda x: x +1)
binary style - takes 2 piped argument and 0+ called arguments
syntax: A >> f(args) >> B
-> f(args)(A, B)
from coppertop.core import NotYetImplemented
from dm.std import each, inject
@coppertop(style=binary)
def add(x, y):
return x + y
@coppertop(style=binary)
def op(x, action, y):
if action == "+":
return x + y
else:
raise NotYetImplemented()
1 >> add >> 1
1 >> op(_,"+",_) >> 1
[1,2] >> each >> (lambda x: x + 1)
[1,2,3] >> inject(_,0,_) >> (lambda x,y: x + y)
ternary style - takes 3 piped argument and 0+ called arguments
syntax: A >> f(args) >> B >> C
-> f(args)(A, B, C)
from dm.std import both, check, equal
[1,2] >> both >> (lambda x, y: x + y) >> [3,4] >> check >> equal >> [4, 6]
as an exercise for the reader
[1,2] >> both >> (lambda x, y: x + y) >> [3,4]
>> each >> (lambda x: x * 2)
>> inject(_,1,_) >> (lambda x,y: x * y)
>> addOne >> addOne >> addOne
>> to(_,str) >> appendStr(" red balloons go by")
>> check >> equal >> ???
Multiple-dispatch
Just redefine functions with different type annotations. Missing annotations are taken as fallback wildcards. Class inheritance is ignored when matching caller and function signatures.
@coppertop
def addOne(x:idx) -> idx:
return x + 1
@coppertop
def addOne(x:str) -> str:
return x + 'One'
@coppertop
def addOne(x): # fallback
if isinstance(x, list):
return x + [1]
else:
raise NotYetImplemented()
1 >> addOne >> check >> equal >> 2
'Three Two ' >> addOne >> check >> equal >> 'Three Two One'
[0] >> addOne >> check >> equal >> [0, 1]
Type system
As an introduction, consider:
from ribs.types import BTAtom, S, num, idx, str, O
num = BTAtom.ensure('num') # nominal
_ccy = BTAtom.ensure('_ccy') # nominal
ccy = num & _ccy # intersection
ccy + null # union
ccy * idx * str # tuple (sequence of types)
S(name=str, age=num) # struct
N ** ccy # collection of ccy accessed by an ordinal (N)
str ** ccy # collection of ccy accessed by a python string
(num*num) ^ num # (num, num) -> num - a function
T, T1, T2, ... # type variable - to be inferred at build time
I(domestic=ccy&T, foreign=ccy&T) # named intersection (aka discrimated type)
Example - Cluedo notepad
See algos.py, where we track a game of Cluedo and make inferences for who did it. See games.py for example game input.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file coppertop-bones-2022.7.30.tar.gz
.
File metadata
- Download URL: coppertop-bones-2022.7.30.tar.gz
- Upload date:
- Size: 41.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.9.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ce3fd6be841170979d30fa9b0b2cd244a24768c822b202074c509c3540c3f59d |
|
MD5 | 0013649b32de75cf5ea221ec836cf37c |
|
BLAKE2b-256 | 642e2504ec57f09370f56b3edf99b6e2c171a68414fff7616f8e60a4eb84d679 |