A forward-oriented programming paradigm for Python.


Keywords
metaprogramming, component-based, programming, software, as, a, service
License
Apache-2.0
Install
pip install pyfop==0.3.5

Documentation

pyfop Implements forward-oriented programming in Python. This shares configuration arguments across multiple components and determines their values after the main business logic.

build codecov Downloads

Dependencies: makefun
Developer: Emmanouil (Manios) Krasanakis
Contant: maniospas@hotmail.com

Features

⚗️ Adapt arguments to usage context
🏄 Argument sharing between methods
🚀 Speed up library development
🛠️ Easy adoption with decorators

Quickstart

Enable lazy execution and automatically annotate arguments with defaults as aspects:

from pyfop import lazy, autoaspects

@lazy
@autoaspects
def affine(x, scale=1, offset=0):
    return x*scale + offset

Produce results with python code:

GM = (affine(2)*affine(8))**0.5

Set aspect values of previous code:

print(GM(scale=3))  # 12

Advanced features

Internal call of lazy methods while exposing their aspects.
@lazy
@autoaspects
def gm(x, y, affine=affine):  # pass the method as an argument
    return (affine(x)*affine(y))**0.5

GM = gm(2, 8)
print(GM(scale=3))  # 12
Print list of aspects.
print(GM.get_input_context(scale=3))
# context:
#	- scale:
#		 value: 3,
#		 priority: Priority.HIGH
#		 shares: 1
#	- offset:
#		 value: 1,
#		 priority: Priority.INCREASED
#		 shares: 4
Aspects are shared between everything contributing to the result.
@lazy
@autoaspects
def square(x, scale=1):
    return scale*x*x

print(affine(2)(scale=2))  # 4
print((affine(2)+square(1))(scale=2))  # 5
Priority-based selection between defaults.
@lazy
def logpp(x, offset=Aspect(1, Priority.INCREASED)):
    import math
    return math.log(x+offset)/math.log(2)

result = affine(2)+log(3)
print(result(scale=2))  # 5+2=7
Toggle caching.
@lazy  # automatically performs caching
def inc(x):
    print("running")
    return x+1

print(inc(2)())
# running
# 3 
print(inc(2)())
# 3
print(inc(3)())
# running
# 4
@lazy_no_cache  # disables caching
def inc(x):
    print("running")
    return x+1

print(inc(2)())
# running
# 3 
print(inc(2)())
# running
# 3
print(inc(3)())
# running
# 4