{"id":22018840,"url":"https://github.com/thautwarm/flowpython","last_synced_at":"2025-05-07T03:28:15.645Z","repository":{"id":57431474,"uuid":"98456271","full_name":"thautwarm/flowpython","owner":"thautwarm","description":"tasty feature extensions for python3(NO MAINTENANCE!).","archived":false,"fork":false,"pushed_at":"2019-07-07T13:18:28.000Z","size":106588,"stargazers_count":62,"open_issues_count":2,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-30T05:02:53.351Z","etag":null,"topics":["language-extensions","pattern-matching"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thautwarm.png","metadata":{"files":{"readme":"ReadMe.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-26T18:59:49.000Z","updated_at":"2025-02-05T16:28:07.000Z","dependencies_parsed_at":"2022-09-02T11:51:33.663Z","dependency_job_id":null,"html_url":"https://github.com/thautwarm/flowpython","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thautwarm%2Fflowpython","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thautwarm%2Fflowpython/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thautwarm%2Fflowpython/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thautwarm%2Fflowpython/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thautwarm","download_url":"https://codeload.github.com/thautwarm/flowpython/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252806089,"owners_count":21807154,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["language-extensions","pattern-matching"],"created_at":"2024-11-30T05:14:19.113Z","updated_at":"2025-05-07T03:28:15.625Z","avatar_url":"https://github.com/thautwarm.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# License\n\nThis project is totally based on the entire [CPython](https://github.com/python/cpython), \nso it is licensed under the terms of the PSF License Agreement.\n\nSee [LICENSE](https://github.com/thautwarm/flowpython/blob/master/LICENSE) for the details.\n\n# Install \u0026 Uninstall\n\n- Support Windows 32bit/64bit and Linux 64bit for CPython 3.6.x/3.5.x.\n- Will support CPython 3.7 sooner.\n- Will never support CPython 2.x :)\n\nYou now have to go to release page and download the binaries directly...\n\nAfter downloading, just  replace the original files with flowpython items.\n\n\n\n# **Flowpython Project**\n\n- Version : 0.2.3\n\n- See [Flowpython project](/flowpython/ReadMe.rst) here. \n\n# **SourceForCompiling**\n    \n- [BasedOnCPython3.5](https://github.com/thautwarm/cpython/tree/3.5)\n\n- [BasedOnCPython3.6](https://github.com/thautwarm/cpython/tree/3.6)\n\nClone them and  \n```shell\n./configure CC=clang\nmake\n...\n\npython\nPython 3.5.4+ (heads/3.5-dirty:0a8ff1b, Oct  8 2017, 13:56:29) \n[GCC 4.2.1 Compatible Clang 3.8.0 (tags/RELEASE_380/final)] on linux\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n\u003e\u003e\u003e .x -\u003e x+1\n\u003cfunction \u003clambda\u003e at 0x7f159379aae8\u003e\n```\n\n\n\n\n# **History**\n\n\n## Feature - List\n- [Old-Works](#old-works)\n- [Add-where-syntax](#add-where-syntax)\n- [Fix-lambda-closure](#fix-where-syntax-in-lambda-closure)\n- [Fix-keyword-conflictions](#fix-keyword-conflictions)\n- [Powerful-pattern-matching](#powerful-pattern-matching)\n- [Arrow-Transform](#arrow-transform)\n- [Matching-Filter](#matching-filter)\n- [Library fp.py](#fp-module)\n- [Branches](#branches)\n- [Pipeline/Monad](#pipeline)\n- [Logs](#logs)\n- [Auto Compose](#auto-compose)\n\n\n----\n\n### Old Works\n\n(P.S This is not available for CPython 3.5.x\n\nfix `if-expr` and add some new ways to define `lambda`.\n\n- `if-expr`  \n    you can write\n    ```python\n            ret  =  e1 if j1 else\n                    e2 if j2 else\n                    e3 \n    ```\n    instead of\n\n    ```python\n            ret  =  e1 if j1 else \\\n                    e2 if j2 else \\\n                    e3 \n    ```\n- `lambda`  \n\n    ```python\n             .x -\u003e x+1\n             as-with x def x+1\n             as-with x def as y def x+y\n    ```\n\n### Add Where Syntax  \n- principle:\n    - **Parse**:\n        - change Grammar/Grammar\n            1. Firstly, add a new grammar *where_stmt*.  \n            \u0026emsp;\u0026emsp;``where_stmt: 'where' ':' suite``  \n            add this grammar to `compound_stmt`\n            2. Then change the end of *simple_stmt*,replace *NEWLINE* with   \n            \u0026emsp;\u0026emsp;``(NEWLINE | where_stmt)``\n        - change Parser/Python.asdl\n            1. Add a data structure *Where* as a kind of *expr*  \n            ```\n            Where(expr target, stmt* body)\n            ```\n             \n    - **AST**:\n        - change Python/ast.c\n            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.\n    - **Compile\u0026Interpret**\n        - change Python/compile.c  \n                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.\n        - change Python/symtable.c  \n                Quite similar to *compile.c*. \n            \n        - P.S for *Compile\u0026Interpret*  \n                If your want to get a complete knowledge about how Python works, you should understand how the two C Module works firstly.\n    \n\n### Auto Compose\n\n    ```python\n    from flowpython.composing import auto_logger, auto_compose, flow_map, flow_filter\n    auto_logger(__builtin__.__dict__)\n    \n    \u003e\u003e sum.filter(.x-\u003ex,[0,1,2,3,0])\n    \u003e\u003e 6\n    ``` \n\n### Fix Where Syntax in Lambda Closure\n- Particularly, fixed **where** syntax for *lambda*, to make the **scope** of statements in *where* syntax to be the **closure of the innermost lambda**.  \n    You can write following codes:\n    ```python\n    as-with x def as y def as z def ret_value where:\n        ret_value = x + y +z\n    ```\n    instead of:\n    ```python\n    as-with x def as y def as z def tmp(x+y+z) where:\n        def tmp(x,y,z):\n            return x +y +z\n    ```\n    Does it seem to be currying?\n    ```\n    .x-\u003e.y-\u003e.z-\u003e ret where:\n        ret = x +y +z\n    ```\n  \n### Fix Keyword Conflictions\n* **fix-keyword**\n* **switch-case-otherwise -\u003e condef-case-otherwise**\n\n    Some new keywords brought by Flowpython, such as **where, condef, case, otherwise**, used to conflict with **Standard Library**\n    and some important Libaraies from **Third Party**.\n\n    I fixed these conflictions with making the Parser module to ignore some grammar structures which would be checked in AST module.   \n\n    So you can write these codes now:\n\n    ```python\n        # no confliction\n        \n        where = 1\n        where += where where:\n            where += where\n        \n        case = 1\n        otherwise = 2\n        condef 1:\n            case case =\u003e case \n            otherwise =\u003e otherwise\n    ```\n\n    Take care that each syntax in [ **where, case, otherwise** ] are not real keywords, and **condef** is.\n\n    ```python\n        condef = 1\n        \u003e\u003e\u003e SyntaxError: invalid syntax\n    ```\n\n### Powerful Pattern Matching\n\n* **pattern-matching**\n\n    There are four kinds of matching rules in Flowpython:\n    1. **comparing operator matching**\n    ```C\n\n        condef [ == ] expr:\n            [\u003e] \n            case test1 =\u003e\n                    \u003cbody1\u003e\n            case test2 =\u003e \n                    \u003cbody2\u003e\n            otherwise  =\u003e\n                    \u003cbody3\u003e\n    ```\n    which equals to \n    ```python\n\n        if (expr \u003e test1 )\n            \u003cbody1\u003e\n        elif (expr == test2 )\n            \u003cbody2\u003e\n        else:\n            \u003cbody3\u003e\n    ```\n    Each in `[], (), +(), +[], {} ` are called the **operator comparing mode**.     \n    **Giving a mode followed by *condef* keyword means giving a default mode.**  \n    The results are concluded [here](#conclusion-for-pattern-matching)  \n    \n        for operator comparing mode \"[\u003coptional\u003e]\"\n        \u003coptional\u003e can be\n        ==      \n        \u003e\n        \u003c\n        \u003e=\n        \u003c=\n        in\n        not in\n        is \n        is not\n    \n    2. **callable object matching**\n    ```C\n    condef (f) expr:\n        case test1 =\u003e \n            \u003cbody1\u003e\n        [!=] \n        case test2 =\u003e\n            \u003cbody2\u003e\n    ```\n    equals\n    ```python\n    if (f(expr) == test1):\n        \u003cbody1\u003e\n    elif expr != test2:\n        \u003cbody2\u003e\n    ```\n\n    3. **dual callable comparing matching**\n\n    ```C\n    condef {f} expr:\n        case test1 =\u003e \n            \u003cbody1\u003e\n    ```\n    equals\n    ```python\n    if f(expr, test1):\n        \u003cbody1\u003e\n    ```\n\n    4. **Python Pattern Matching**\n    - This one is the implementation for traditional pattern matching in CPython.\n    ```C\n    condef +[\u003e] 1:\n        case a:2   =\u003e\n            \u003cbody1\u003e\n        +(type) \n        case a:int =\u003e\n            \u003cbody2\u003e\n    ```\n    The codes above can be explained as following process:  \n    1. `if` we can do assignment `a = 1` and expression `a \u003e 2` can be satisfied, then do `\u003cbody1\u003e`.\n    2. `else if` we can do assignment `a = 1` and expression `type(a) == int` can be satisfied, then do `\u003cbody2\u003e`.  \n    - There are much more ways to use **Pattern Matching**, take a look\n    at [**test_patm.py**](https://github.com/thautwarm/flowpython/blob/master/test/test_patm.py)\n    3. **Take care**  \n    if you write the following codes without default mode,\n    ```C\n    condef [1,2,3]:\n        ...\n    condef {1,2,3}:\n        ...\n    condef (1,2,3):\n        ...\n    ```\n    it will lead to **syntax Error**. But you can use this instead:\n    ```C\n    condef() [1,2,3]:\n        ...\n    condef[] {1,2,3}:\n        ...\n    condef{} (1,2,3):\n        ...\n    ```\n\n#### Conclusion for Pattern Matching\n\u003ccenter\u003e\n\n| Matching Method                    | Identity      |       \n| -------------                      |:-------------:| \n| comparing operator matching        | [`operator`]  | \n| callable object matching           | (`callable`)  | \n| dual callable comparing matching   | {`callable`}  | \n| python pattern matching(comparing) | +[`operator`] | \n| python pattern matching(callable)  | +(`callable`) |          \n\u003c/center\u003e\n\n### Arrow Transform\n\n- **arrow transform expression**  \n    This one looks like **lambda**, and they have quite a lot of features in common.  \n    Look at this example:  \n    - `arrow transform`\n    ```C\n    \u003e\u003e 1 -\u003e _+1\n    \u003e\u003e 2\n    \u003e\u003e x = [1,2,3]\n    \u003e\u003e x -\u003e map(.x-\u003ex+1, _) -\u003e  list(_)\n    \u003e\u003e [2,3,4]\n    ```\n    - `lambda`\n    ```python\n    \u003e\u003e .x -\u003e x\n    \u003e\u003e _(1)\n    \u003e\u003e 1\n    \u003e\u003e var = [1,2,3]\n    \u003e\u003e .x -\u003e map(.x-\u003ex+1, x) -\u003e list(_)\n    \u003e\u003e _(var)\n    \u003e\u003e [2,3,4]\n    ```\n    To conclude, `lambda` is the `lazy` form of `arrow transform`.  \n    The grammar identity `.` means **Take It As Lazy**\n\n### Matching Filter\n\n    ```C\n        condef[] [1,2,3]:\n            +(type)\n            case (*a,b) -\u003e a:list =\u003e \n                print(\"just match 'a' with 'list' \")\n            \n            otherwise           =\u003e\n                print(\"emmmmmm,,\")\n\n    ```\n\n### FP Module\n\n- library: fp.py\n\nTo support some basic operations in Functional Programming, here are methods implemented in `flowpython.fp`.\n\n```C\nfrom flowpython.fp import compose, andThen, foldr, foldl, flat_map, flatten\nfrom flowpython.fp import strict, norecursion\n\nstrict_flatten = strict.flatten\nstrict_fastmap = strict.fastmap \nstrict_flat_map= strict.flat_map  \nnorec_flatten  =  norecursion.lazy.flatten\n\n\n# fastmap( use generator instead of map in original Python )\nfastmap(.x -\u003e x+1, [1,2,3]) -\u003e list(_)\n# -\u003e [2,3,4]\n\nstrict_flat_map(.x-\u003ex+1, [1,2,3]) # -\u003e [2,3,4] \n\n# flatten\nflatten([1,2,[3,4],[[5],[6]]]) -\u003e list(_)\n# -\u003e [1,2,3,4,5,6]\n\n# compose : Callable-\u003eCallable-\u003eAny\nf1 -\u003e compose(f2)(_)\n\n# andThen : Callable-\u003eCallable-\u003eAny\nf1 -\u003e andThen(f2)(_)\n\n# foreach : Callable-\u003eCallable-\u003eAny\nrange(20) -\u003e foreach(print)(_) \n# -\u003e 0 \\n 1 \\n 2 ...\n\n\n# fold : Dual Callable-\u003e(zero:Any)-\u003eIterator-\u003eAny\nfoldr # (not recommended)\nfoldl # (not recommended)\n\nrange(20) -\u003e foldr(. x,y -\u003e print(x) or x+y)(0)(_) \nrange(20) -\u003e foldr(. x,y -\u003e print(y) or x+y)(0)(_)\n\n# flat_map : Iterator -\u003e Callable -\u003e Iterator\n# default lazy\nflat_map(.x-\u003ex+1)([[1,2,[3,4],[5,6]],[7,8]]) -\u003e list(_)\n# -\u003e [2,3,4,5,6,7,8,9]\n\n# object in norecursion class use no recursive methods.\nnorec_flatten([[1,[2],[[3]],[[[4]]]]] -\u003e list(_) \n\n\n\n```\n\n### Branches\n \nAn easy way to define `if-elif-else` statements:  \n( It's not `guard` in Haskell ! )\n```python\n\n    otherwise = True\n\n    | x == 1           =\u003e x += 1\n    | type(x) is str   =\u003e x = int(x) \n    | otherwise        =\u003e\n            x = 2*x\n            y = 1\n    def defined(key):\n        return key in globals()\n\n    print(x)\n    print(defined(\"y\")) \n\n    func = .x -\u003e ret where:\n        otherwise = True\n        | x is 0                =\u003e ret = 0.0\n        | type(x) in (str,int)  =\u003e ret = float(x)\n        | otherwise             =\u003e ret = x\n        \n```\n\n\n## Pipeline\n\nSorry for the shortage of documents for new grammar, and I'm busy with my new semester.   \nIt would be completed as sooner as possible.\n```python\n    \n    \u003e\u003e 1 -\u003e\u003e .x -\u003e x*10 =\u003e .x-\u003e x+1 \n    \u003e\u003e 11\n\n```\n\n```python\n\n    \u003e\u003e range(100)  -\u003e\u003e f1 \\\n                    =\u003e f2 \\\n                    =\u003e groupby(.x-\u003ex)  \\\n                    =\u003e lambda Dict: map(.key-\u003e(key,len(Dict[key])), Dict) \\\n                    =\u003e dict \\\n                    =\u003e print where:\n                    from flowpython.fp import groupby\n                    f1 = . seq -\u003e map(.x-\u003ex%2, seq)\n                    f2 = . seq -\u003e filter(.x -\u003e x, seq)\n    \u003e\u003e {1:50}\n\n```\n\n\n\n## Logs\n- date : before 2017-07-30\n- date : 2017-07-30\n    - Add **where** syntax\n- date: 2017-08-06\n    - Fix `closure` for `where` syntax in case of **Lambda Definition**.\n- date: 2017-08-07\n    - Add `switch syntax`.\n- date: 2017-08-08\n    - Fix the keyword conflicts against the standard libraries and the packages from Third Party.\n    - Change the grammar of `switch` syntax.  \n        `switch-case-otherwise -\u003e condef-case-otherwise`\n- date: 2017-08-10\n    - Add `pattern matching` syntax.\n    - Add arrow transform expression.\n    - Remove `switch` syntax(which can be totally replaced by `pattern matching`).\n- date: 2017-08-10\n    - Add matching filter syntax for `pattern matching` .\n- date: 2017-08-13\n    - Add module `fp.py`.\n- date: 2017-08-15  \n    - Add `branches` grammar.\n- data: 2017-08-25\n    - Add `pipeline` grammar.\n    - Change keyword for pattern matching from `condic` to `condef`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthautwarm%2Fflowpython","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthautwarm%2Fflowpython","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthautwarm%2Fflowpython/lists"}