Skip to main content

Functional programming for python

Project description

Pamda

PyPI version License: MIT

Python wrapper for functional programming in object oriented structures.

Inspired heavily by Ramda.

Documentation for Pamda Functions

https://connor-makowski.github.io/pamda/pamda/pamda.html

Key Features

  • Simplified functional programming for python
  • Core Functions include:
    • curry arbitrary methods and functions
    • thunkify arbitrary methods and functions
    • pipe data iteratively through n functions
  • List based path access and features for nested dictionaries

Setup

Make sure you have Python 3.9.x (or higher) installed on your system. You can download it here.

Installation

pip install pamda

Getting Started

Basic Usage

from pamda import pamda

data={'a':{'b':1, 'c':2}}
# Example: Select data given a path and a dictionary
pamda.path(['a','b'])(data) #=> 1

# See documentation for all core pamda functions at
# https://connor-makowski.github.io/pamda/pamda.html

Curry Usage

from pamda import pamda

# Define a function that you want to curry
def myFunction(a,b,c):
    return [a,b,c]

# You can call pamda.curry as a function to curry your functions
curriedMyFn=pamda.curry(myFunction)

# Inputs can now be passed in an async fashion
# The function is evaluated when all inputs are added
x=curriedMyFn(1,2)
x(3) #=> [1,2,3]
x(4) #=> [1,2,4]

# Each set of inputs returns a callable function
# You can stack inputs on a single line for clean functional programming
curriedMyFn(1,2)(3) #=> [1,2,3]

For enforcing types, pamda relies on type_enforced but curried objects do not play nice with type_enforced objects. To fix this, there is a special curry function, curryType, that enables type_enforced annotations for your curried functions:

>>> from pamda import pamda
>>>
>>> # Pamda CurryTyped
>>> @pamda.curryTyped
... def add(a:int,b:int):
...     return a+b
...
>>> add(1)(1)
2
>>> add(1)(1.5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/conmak/development/personal/pamda/pamda/pamda_curry.py", line 43, in __call__
    results = self.__fnExecute__(*new_args, **new_kwargs)
  File "/home/conmak/development/personal/pamda/venv/lib/python3.10/site-packages/type_enforced/enforcer.py", line 90, in __call__
    self.__check_type__(assigned_vars.get(key), value, key)
  File "/home/conmak/development/personal/pamda/venv/lib/python3.10/site-packages/type_enforced/enforcer.py", line 112, in __check_type__
    self.__exception__(
  File "/home/conmak/development/personal/pamda/venv/lib/python3.10/site-packages/type_enforced/enforcer.py", line 34, in __exception__
    raise TypeError(f"({self.__fn__.__qualname__}): {message}")
TypeError: (add): Type mismatch for typed variable `b`. Expected one of the following `[<class 'int'>]` but got `<class 'float'>` instead.

Thunkify Usage

from pamda import pamda

# Define a function that you want to thunkify
# thunkify can be called as a function or decorator
@pamda.thunkify
def myFunction(a,b,c):
    return [a,b,c]

# The function is now curried and the evaluation is lazy
# This means the function is not evaluated until called
x=myFunction(1,2)
x(3) #=> <pamda.curry_obj object at 0x7fd514e4c820>
x(3)() #=> [1,2,3]

y=x(4)
y() #=> [1,2,4]

Thunkified functions can be executed asynchronously.

from pamda import pamda
import time

@pamda.thunkify
def test(name, wait):
    print(f'{name} start')
    time.sleep(wait)
    print(f'{name} end')
    return wait

async_test_a = pamda.asyncRun(test('a',2))
async_test_b = pamda.asyncRun(test('b',1))
async_test_a.asyncWait()
async_test_c = pamda.asyncRun(test('c',1))

The above code would output:

a start
b start
b end
a end
c start
c end

Pipe

from pamda import pamda

def square(x):
    return x**2

def half(x):
    return x/2

def negate(x):
    return -x

# You can pipe data through multiple functions for clean functional programming
pamda.pipe([square, half, negate])(args=(6,),kwargs={}) #=> -18

Use pamda as a subclass

from pamda import pamda

class myClass(pamda):
    def myFunction(self, a):
        return self.inc(a)

mc=myClass()
mc.myFunction(2) #=> 3

@mc.curry
def addUp(a,b):
    return a+b

addUp(1)(2) #=> 3

Pamda Utils

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pamda-2.9.0.tar.gz (21.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pamda-2.9.0-py3-none-any.whl (23.9 kB view details)

Uploaded Python 3

File details

Details for the file pamda-2.9.0.tar.gz.

File metadata

  • Download URL: pamda-2.9.0.tar.gz
  • Upload date:
  • Size: 21.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for pamda-2.9.0.tar.gz
Algorithm Hash digest
SHA256 02f867620262173ccee9d3d7f0c44c41794711d016420c044aff2ebd4e4a13a1
MD5 693659cb4329f60db33b323f9fe88c5b
BLAKE2b-256 a98070f2d69fdb1f5ebdbe9960c6c877394ad0be48a831263cec2390e46fbb5b

See more details on using hashes here.

File details

Details for the file pamda-2.9.0-py3-none-any.whl.

File metadata

  • Download URL: pamda-2.9.0-py3-none-any.whl
  • Upload date:
  • Size: 23.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for pamda-2.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7dabe301fba4101507c8d58e3b67cb35f7ef504b829c5cc93966d56ea0867db2
MD5 5547ad9259d21ccc69ae78fc33ea5b4f
BLAKE2b-256 10f498b321bc63bc4d930e75adf1615a8dd2a52ee0e98e0f2f0f3cae1c0941d8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page