This project is totally based on the entire CPython, so it is licensed under the terms of the PSF License Agreement.
See LICENSE for the details.
- Support Windows 32bit/64bit and Linux 64bit for CPython 3.6.x/3.5.x.
- Will support CPython 3.7 sooner.
- Will never support CPython 2.x :)
You now have to go to release page and download the binaries directly...
After downloading, just replace the original files with flowpython items.
-
Version : 0.2.3
-
See Flowpython project here.
Clone them and
./configure CC=clang
make
...
python
Python 3.5.4+ (heads/3.5-dirty:0a8ff1b, Oct 8 2017, 13:56:29)
[GCC 4.2.1 Compatible Clang 3.8.0 (tags/RELEASE_380/final)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> .x -> x+1
<function <lambda> at 0x7f159379aae8>
- Old-Works
- Add-where-syntax
- Fix-lambda-closure
- Fix-keyword-conflictions
- Powerful-pattern-matching
- Arrow-Transform
- Matching-Filter
- Library fp.py
- Branches
- Pipeline/Monad
- Logs
- Auto Compose
(P.S This is not available for CPython 3.5.x
fix if-expr
and add some new ways to define lambda
.
-
if-expr
you can writeret = e1 if j1 else e2 if j2 else e3
instead of
ret = e1 if j1 else \ e2 if j2 else \ e3
-
lambda
.x -> x+1 as-with x def x+1 as-with x def as y def x+y
- principle:
-
Parse:
- change Grammar/Grammar
- Firstly, add a new grammar where_stmt.
where_stmt: 'where' ':' suite
add this grammar tocompound_stmt
- Then change the end of simple_stmt,replace NEWLINE with
(NEWLINE | where_stmt)
- Firstly, add a new grammar where_stmt.
- change Parser/Python.asdl
- Add a data structure Where as a kind of expr
Where(expr target, stmt* body)
- change Grammar/Grammar
-
AST:
- change Python/ast.c
found the function
ast_for_stmt
,ast_for_expr_stmt
,ast_for_flow_stmt
,ast_for_assert_stmt
, change it as what I did in flowpython/Python/ast.c. It tells the Python compiler how to get the data structure from the parsed codes.
- change Python/ast.c
found the function
-
Compile&Interpret
-
change Python/compile.c
This part is kind of complicated to bring out, and I think that you'd better use version controller to detect out what's the differences between Flowpython and CPython 3.6.2. -
change Python/symtable.c
Quite similar to compile.c. -
P.S for Compile&Interpret
If your want to get a complete knowledge about how Python works, you should understand how the two C Module works firstly.
-
-
```python
from flowpython.composing import auto_logger, auto_compose, flow_map, flow_filter
auto_logger(__builtin__.__dict__)
>> sum.filter(.x->x,[0,1,2,3,0])
>> 6
```
- Particularly, fixed where syntax for lambda, to make the scope of statements in where syntax to be the closure of the innermost lambda.
You can write following codes:instead of:as-with x def as y def as z def ret_value where: ret_value = x + y +z
Does it seem to be currying?as-with x def as y def as z def tmp(x+y+z) where: def tmp(x,y,z): return x +y +z
.x->.y->.z-> ret where: ret = x +y +z
-
fix-keyword
-
switch-case-otherwise -> condef-case-otherwise
Some new keywords brought by Flowpython, such as where, condef, case, otherwise, used to conflict with Standard Library and some important Libaraies from Third Party.
I fixed these conflictions with making the Parser module to ignore some grammar structures which would be checked in AST module.
So you can write these codes now:
# no confliction where = 1 where += where where: where += where case = 1 otherwise = 2 condef 1: case case => case otherwise => otherwise
Take care that each syntax in [ where, case, otherwise ] are not real keywords, and condef is.
condef = 1 >>> SyntaxError: invalid syntax
-
pattern-matching
There are four kinds of matching rules in Flowpython:
- comparing operator matching
condef [ == ] expr: [>] case test1 => <body1> case test2 => <body2> otherwise => <body3>
which equals to
if (expr > test1 ) <body1> elif (expr == test2 ) <body2> else: <body3>
Each in
[], (), +(), +[], {}
are called the operator comparing mode.
Giving a mode followed by condef keyword means giving a default mode.
The results are concluded herefor operator comparing mode "[<optional>]" <optional> can be == > < >= <= in not in is is not
- callable object matching
condef (f) expr: case test1 => <body1> [!=] case test2 => <body2>
equals
if (f(expr) == test1): <body1> elif expr != test2: <body2>
- dual callable comparing matching
condef {f} expr: case test1 => <body1>
equals
if f(expr, test1): <body1>
- Python Pattern Matching
- This one is the implementation for traditional pattern matching in CPython.
condef +[>] 1: case a:2 => <body1> +(type) case a:int => <body2>
The codes above can be explained as following process:
if
we can do assignmenta = 1
and expressiona > 2
can be satisfied, then do<body1>
.else if
we can do assignmenta = 1
and expressiontype(a) == int
can be satisfied, then do<body2>
.
- There are much more ways to use Pattern Matching, take a look at test_patm.py
- Take care
if you write the following codes without default mode,
condef [1,2,3]: ... condef {1,2,3}: ... condef (1,2,3): ...
it will lead to syntax Error. But you can use this instead:
condef() [1,2,3]: ... condef[] {1,2,3}: ... condef{} (1,2,3): ...
Matching Method | Identity |
---|---|
comparing operator matching | [operator ] |
callable object matching | (callable ) |
dual callable comparing matching | {callable } |
python pattern matching(comparing) | +[operator ] |
python pattern matching(callable) | +(callable ) |
- arrow transform expression
This one looks like lambda, and they have quite a lot of features in common.
Look at this example:arrow transform
>> 1 -> _+1 >> 2 >> x = [1,2,3] >> x -> map(.x->x+1, _) -> list(_) >> [2,3,4]
lambda
To conclude,>> .x -> x >> _(1) >> 1 >> var = [1,2,3] >> .x -> map(.x->x+1, x) -> list(_) >> _(var) >> [2,3,4]
lambda
is thelazy
form ofarrow transform
.
The grammar identity.
means Take It As Lazy
```C
condef[] [1,2,3]:
+(type)
case (*a,b) -> a:list =>
print("just match 'a' with 'list' ")
otherwise =>
print("emmmmmm,,")
```
- library: fp.py
To support some basic operations in Functional Programming, here are methods implemented in flowpython.fp
.
from flowpython.fp import compose, andThen, foldr, foldl, flat_map, flatten
from flowpython.fp import strict, norecursion
strict_flatten = strict.flatten
strict_fastmap = strict.fastmap
strict_flat_map= strict.flat_map
norec_flatten = norecursion.lazy.flatten
# fastmap( use generator instead of map in original Python )
fastmap(.x -> x+1, [1,2,3]) -> list(_)
# -> [2,3,4]
strict_flat_map(.x->x+1, [1,2,3]) # -> [2,3,4]
# flatten
flatten([1,2,[3,4],[[5],[6]]]) -> list(_)
# -> [1,2,3,4,5,6]
# compose : Callable->Callable->Any
f1 -> compose(f2)(_)
# andThen : Callable->Callable->Any
f1 -> andThen(f2)(_)
# foreach : Callable->Callable->Any
range(20) -> foreach(print)(_)
# -> 0 \n 1 \n 2 ...
# fold : Dual Callable->(zero:Any)->Iterator->Any
foldr # (not recommended)
foldl # (not recommended)
range(20) -> foldr(. x,y -> print(x) or x+y)(0)(_)
range(20) -> foldr(. x,y -> print(y) or x+y)(0)(_)
# flat_map : Iterator -> Callable -> Iterator
# default lazy
flat_map(.x->x+1)([[1,2,[3,4],[5,6]],[7,8]]) -> list(_)
# -> [2,3,4,5,6,7,8,9]
# object in norecursion class use no recursive methods.
norec_flatten([[1,[2],[[3]],[[[4]]]]] -> list(_)
An easy way to define if-elif-else
statements:
( It's not guard
in Haskell ! )
otherwise = True
| x == 1 => x += 1
| type(x) is str => x = int(x)
| otherwise =>
x = 2*x
y = 1
def defined(key):
return key in globals()
print(x)
print(defined("y"))
func = .x -> ret where:
otherwise = True
| x is 0 => ret = 0.0
| type(x) in (str,int) => ret = float(x)
| otherwise => ret = x
Sorry for the shortage of documents for new grammar, and I'm busy with my new semester.
It would be completed as sooner as possible.
>> 1 ->> .x -> x*10 => .x-> x+1
>> 11
>> range(100) ->> f1 \
=> f2 \
=> groupby(.x->x) \
=> lambda Dict: map(.key->(key,len(Dict[key])), Dict) \
=> dict \
=> print where:
from flowpython.fp import groupby
f1 = . seq -> map(.x->x%2, seq)
f2 = . seq -> filter(.x -> x, seq)
>> {1:50}
- date : before 2017-07-30
- date : 2017-07-30
- Add where syntax
- date: 2017-08-06
- Fix
closure
forwhere
syntax in case of Lambda Definition.
- Fix
- date: 2017-08-07
- Add
switch syntax
.
- Add
- date: 2017-08-08
- Fix the keyword conflicts against the standard libraries and the packages from Third Party.
- Change the grammar of
switch
syntax.
switch-case-otherwise -> condef-case-otherwise
- date: 2017-08-10
- Add
pattern matching
syntax. - Add arrow transform expression.
- Remove
switch
syntax(which can be totally replaced bypattern matching
).
- Add
- date: 2017-08-10
- Add matching filter syntax for
pattern matching
.
- Add matching filter syntax for
- date: 2017-08-13
- Add module
fp.py
.
- Add module
- date: 2017-08-15
- Add
branches
grammar.
- Add
- data: 2017-08-25
- Add
pipeline
grammar. - Change keyword for pattern matching from
condic
tocondef
.
- Add