![Maven Central Adds Sigstore Signature Validation](https://cdn.sanity.io/images/cgdhsj6q/production/7da3bc8a946cfb5df15d7fcf49767faedc72b483-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Maven Central Adds Sigstore Signature Validation
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
This package is used as utility to support more thorough FP (functional programming) functionalities in Python. For more, you can refer to FPU.pptx
(Source link) Functional programming has a long history. In a nutshell, its a style of programming where you focus on transforming data through the use of small expressions that ideally don’t contain side effects. In other words, when you call my_fun(1, 2), it will alway return the same result. This is achieved by immutable data typical of a functional language.
With this feature, you can:
Let's take a example to explain the usage of functional composition. Below is the imperative way to get the minimum value of all maximum values from values:
dataSet = [{'values':[1, 2, 3]}, {'values':[4, 5]}]
# Imperative
def min_max_imp(dataSet):
max_list = []
for d in dataSet:
max_list.append(max(d['values']))
return min(max_list)
min_max_imp(dataSet) # 3
Above function min_max_imp
actually comprises two sub steps:
This implies you can compose above two steps (function) into one by leveraging exist functions:
# FP
from fpu.fp import *
from functools import reduce, partial
# compose2(f, g) = f(g())
min_max = compose2(
partial(reduce, min), \
partial(map, lambda d: max(d['values']))
)
min_max(dataSet)
With composing feature, you can write less dump code and make use of exist function to generate new function!
The side effects can refer to many things. I suggest you to read below materials to know more:
There are many python packages support you to carry out this requirement. One of them is pyrsistent. Below is a few usage of it to show immutable data
:
In [2]: v1 = v(1, 2, 3)
In [3]: v2 = v1.append(4) # Any operation on v1 will return new vectory to reflect the modification
In [4]: v1
Out[4]: pvector([1, 2, 3]) # v1 stay immutable
In [5]: v2
Out[5]: pvector([1, 2, 3, 4]) # v2 reflect the change for appending 4
In [6]: v3 = v2.set(1, 5)
In [7]: v2
Out[7]: pvector([1, 2, 3, 4])
In [8]: v3
Out[8]: pvector([1, 5, 3, 4])
Above is a demonstration on data structure vector. There are more for PMap, PSet, PRecord and PClass.
A Closure which simply creates a scope that allows the function to access and manipulate the variables in enclosing scopes. Normally, you will follow below steps to create a Closure in Python:
Below is a simple example to create closure:
In [10]: def addN(n):
...: def _add(v):
...: return v + n
...: return _add
...:
In [11]: addOne = addN(1)
In [12]: addOne(2)
Out[12]: 3
In [13]: addOne(3)
Out[13]: 4
In [14]: addTwo = addN(2)
In [15]: addTwo(2)
Out[15]: 4
In [16]: addTwo(3)
Out[16]: 5
Currying is like a kind of incremental binding of function arguments. It is the technique of breaking down the evaluation of a function that takes multiple arguments into evaluating a sequence of single-argument functions:
add(a, b)
AND add(a)(b)
Unfortunately, Python doesn't support curring in default. Below is a workaround for you to do curring in Python3:
from inspect import signature
def curry(x, argc=None):
if argc is None:
argc = len(signature(x).parameters)
def p(*a):
if len(a) == argc:
return x(*a)
def q(*b):
return x(*(a + b))
return curry(q, argc - len(a))
return p
@curry
def myfun(a,b,c):
print("{}-{}-{}".format(a,b,c))
myfun(1, 2, 3)
myfun(1, 2)(3)
myfun(1)(2)(3)
FP favors recursion over for-loop. However, the recursion will use precious resource as stack. You can use below sample code to retrieve the recursive limit:
In [17]: import sys
In [18]: sys.getrecursionlimit()
Out[18]: 3000
This package use class TailCall to store the function call in heap instead of stack. Below is one usage example:
In [1]: def fibRec(n, x=0, y=1):
...: if n == 0:
...: return x
...: else:
...: return fibRec(n-1, y, x + y)
...:
In [2]: fibRec(3)
Out[2]: 2
In [3]: fibRec(3000)
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
<ipython-input-3-035cf1755b78> in <module>
----> 1 fibRec(3000)
<ipython-input-1-f509e891ef84> in fibRec(n, x, y)
3 return x
4 else:
----> 5 return fibRec(n-1, y, x + y)
6
... last 1 frames repeated, from the frame below ...
<ipython-input-1-f509e891ef84> in fibRec(n, x, y)
3 return x
4 else:
----> 5 return fibRec(n-1, y, x + y)
6
RecursionError: maximum recursion depth exceeded in comparison
The exception is raised owing to recursion limitation. We can get by this limition by adopting TailCall:
In [5]: from fpu.fp import *
In [6]: ret = TailCall.ret; sus = TailCall.sus
In [22]: def fib(n, x=0, y=1):
...: return ret(x) if n == 0 else sus(Supplier(fib, n-1, y, x + y))
...:
In [23]: fib(3)
Out[23]: <fpu.fp.Suspend at 0x7f2be96be710>
In [24]: fib(3).eval()
Out[24]: 2
In [25]: fib(3000).eval()
Out[25]: 410615886307971260333568378719267105220125108637369252408885430926905584274113403731330491660850044560830036835706942274588569362145476502674373045446852160486606292497360503469773453733196887405847255290082049086907512622059054542195889758031109222670849274793859539133318371244795543147611073276240066737934085191731810993201706776838934766764778739502174470268627820918553842225858306408301661862900358266857238210235802504351951472997919676524004784236376453347268364152648346245840573214241419937917242918602639810097866942392015404620153818671425739835074851396421139982713640679581178458198658692285968043243656709796000
Here we will be going to review what advantage/disadvantage FP will bring to you.
Here we are going to look at few examples from HackerRank to know how FP can help you write code gracefully.
The problem simply ask you to extract element exist in every rock. The imperative approach will look like:
arr = ['abcdde', 'baccd', 'eeabg']
# Complete the gemstones function below.
def gemstones_imp(arr):
set_list = []
for s in arr:
set_list.append(set(list(s)))
# Imperative code
uset = None
for aset in set_list:
if uset is None:
uset = aset
else:
uset = uset & aset
return len(uset)
print("Output of gemstones_imp={}".format(gemstones_imp(arr)))
The FP (declarative approach) code will be neat and graceful:
from fpu.flist import *
def gemstones_dec(arr):
rlist = fl(arr)
return len(
rlist.map(lambda r: set(list(r))) \
.reduce(lambda a, b: a & b)
)
print("Output of gemstones_imp={}".format(gemstones_dec(arr)))
FAQs
Functional Programming Utility
We found that fpu demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.