Package: gamla
READMEλamla is a performant functional programming library for python which supports mixingasyncand regular functions.Installation:pip install gamlaAPI reference:https://gamla.readthedocs.io/Basic examplegamlacan help you turn this:importdataclasses@dataclasses.dataclassclassPerson:age:intname:strdefis_eligible(self):returnself.age>9defget_names_eligible_for_vaccine(people):result=[]forpersoninpeople:ifperson.is_eligible():result.append(person.name)returnresultinto this:importdataclassesfromgamlaimportattrgetter,greater_than,compose_left,filter,map@dataclasses.dataclass(frozen=True)classPerson:age:intname:stris_eligible=compose_left(attrgetter("age"),greater_than(9))get_names_eligible_for_vaccine=compose_left(filter(is_eligible),map(attrgetter("name")),list)Is this a good thing? that's for you to decide.The upside:Functional programming is mainly about how to split your code into composable parts. Composability means that things are easy to move, replace or combine together like lego. It helps you identify recurring patterns (e.g.filter), factor them out and reuse them. If your generalizations are good, they free your mind to focus on the new logic. Concretely it saves a lot of code and helps a reader understand what a piece of code is doing. For example, if you are familiar with whatfilteris, you don't have to squint and realize that anifand aforactually do a filtering pattern.The downside:Programming in this style in python means some tools won't be so useful (e.g. your debugger, static analysis tools).Debugging anonymous compositionsgamla.debugClassic breakpoints are less useful when working with compositions, as there isn't always a line of code to place the breakpoint on. Instead one can usegamla.debugandgamla.debug_exception.gamla.debugcan be used within pipelines and will provide apdbbreakpoint prompt where the value at this position can be referenced byx.defincrement(x):returnx+1increment_twice=gamla.compose_left(increment,gamla.debug,increment)increment_twice(1)The above code will break withxbeing 2.When you have a long pipeline and want to debug at each step of the way, you can usegamla.debug_composeandgamla.debug_compose_left.gamla.debug_exceptionIn some cases tracking down an exception involves inspecting code that runs many times. Consider the following example:defincrement(x):returnx+1defsometimes_has_a_bug(x):ifx==666:raiseExceptionreturnxincrement_with_bug=gamla.map(gamla.compose_left(increment,sometimes_has_a_bug))tuple(increment_with_bug(range(1000)))Adding agamla.debughere can be quite tedious, because the code will break many times.Instead we can usegamla.debug_exceptionto break only in the case the inner function raises, at which case we would get a breakpoint prompt, and be able to inspect the value causing the exception, use the namex. This would like this:increment_with_bug = gamla.map(gamla.compose_left(increment, gamla.debug_exception(sometimes_has_a_bug)))One can also usegamla.debug_exceptionusing a decorator.@gamla.debug_exceptiondefsometimes_has_a_bug(x):ifx==666:raiseExceptionreturnxMixing asynchronous and synchronous codeMost functions in this lib will work seamlessly withasyncand regular functions, and allow the developer to focus on the logic instead of deciding where to place anawait.For example:importasyncioimportgamladefincrement(i):returni+1asyncdefincrement_async(i):awaitasyncio.sleep(1)returni+1asyncdefrun():mixed_composition=gamla.compose_left(increment,increment_async,increment)returnawaitmixed_composition(0)# returns 3!Releasing a new versionIncrement the version in master, and pypi will automatically update.Updating documentation after change in README.mdWhile in gamla directory:Install md-to-rst converter:pip install m2rConvert README.md to README.rst:m2r README.mdMove README.rst to docs/source folder instead of existing one:mv README.rst docs/source