Functional Python Programming - ch[01]

Learning notes on Functional Python Programming

  • Book: Functional Python Programming
  • Chapter: Introducing Functional Programming

Functional programming and Imperative programming

  • python is an imperative programming language, which indicates which indicates the state of computation is reflected by the variables in various namespaces.

    • Like concept of "Everything is a file" in UNIX world, for imperative languages "Every state is a snapshot of variables"
    • Like the pipeline/redirection/filter concepts in UNIX, the program will always focus on states of variables, the program is nothing more then a pipeline connected filter(algorithm) collections, which may try to redirect the input data to the target output data
  • python also holds some functional programming features

    • In functional programming, the states of variables were being replaced by function evaluations, each evaluation will create a new object from the current object
    • As the program is a collection of functions, it is very similar to the solving procedures in Math, we can make easy functions, then regroup them by iteration or recusion to achieve complex functions
  • Comparison among different models in imperative programming: Procedural and OO

    • Procedural: procudural model will treate the data as a stream, everything will be built around the stream, the state of the program is defined by variables
    • OO: The state of the program is also determined by variables
# example Procedural
count=0
for idx in range(0,11):
    if idx % 3 == 0 or count % 5 == 0:
        count += 1

# example OO
count=0
tgtList=list()
for idx in range(0,11):
    if idx % 3 == 0 or count % 5 == 0:
        tgtList.append(idx)
sum(tgtList);

# Another OO example: a class with a method sum
class sum_list(list):
    def sum(self):
        s = 0
        for v in self.__iter__():
            s += v
        return s
  • Functional Paradigm
    • To calc the sum of the multiples of 3 and 5 can be defined in two parts:
      • The sum of a sequence of numbers
      • The number for sum must pass a simple test to be selected
# A resursive sum function
def sum(sequence):
    if len(sequence) == 0:
        return 0
    return sequence[0]+sum(sequence[1:])
sum([x for x in range(1,11)]);

In the last case, the sum function is being transformed into a "divide-calc-merge" function, first divide the funtion into parts, where all parts follow a same pattern then calc it by recursion, at last merge the result at the final dest., it is a great idea to apply the resursive here.

# An impletation of function until
def until(n, filter_func, v):
    # End subject, until the bound
    if v == n:
        return []
    # If v can satisfy the selection function, then return v and check next
    if filter_func(v):
        return [v]  + until (n, filter_func, v+1)
    # If v cannot satisfy the selection function, then check next
    else:
        return until(n, filter_func, v+1)

In functional programming, it is all based on the lambda calc in math, a new keyword lambda is used to expand the area of original python.

# This usage seems like to check whether the x is belongs to a set
mult_3_5 = lambda x: x%3 == 0 or x%5 == 0
print (mult_3_5(2), mult_3_5(3))
False True
# Combine the new lambda calc with the until() function, the result is just like find the join set of the set 'lambda' and the original full set
until(11, mult_3_5, 0)
[0, 3, 5, 6, 9, 10]

Python also supports the hybrid solution to include FP into procedural programming:

print([x for x in range(0,11) if x % 3 == 0 or x %5 == 0])
[0, 3, 5, 6, 9, 10]

The last form uses Nested Generated Expressions to iterate through the collection of the vars and select the taret ones

# In python the simple orderized sum seems won't be avoided by order
import timeit
print(timeit.timeit("((([]+[1])+[2])+[3])+[4]"), timeit.timeit("[]+([1]+([2]+([3]+[4])))"))
0.3882635319896508 0.39000111201312393

Using FP flavour python to calc sqrt()

Use FP method it is very easy to generate math results

# Newton method to approach sqrt(2)
# It is also a mathematical method, convert f(x) into the lambda calc result based on x
n = 2;
def next_(n, x):
    return (x+n/x)/2
f = lambda x: next_(n, x)

a = 1.0
[round(x ,4) for x in [a, f(a), f(f(a)), f(f(f(a)))]]
[1.0, 1.5, 1.4167, 1.4142]
# A simple repeat for function f with init var a
def repeat(f, a):
    yield a
    for v in repeat(f, f(a)):
        yield v

Python is not a pure FP lanuage and the current computer arches are not LISP machines, python uses recursive method to represent the yielding of the infinite list, then we must select a iterator as the generator of the values:

# General form
# for y in some_iter: yield y;
def within(eps, iterable):
    # Check whether is satisfy the end subject or just try to iter into next
    def head_tail(eps, a, iterable):
        b = next(iterable)
        if abs(a-b) <= eps:
            return b
        return head_tail(eps, b, iterable)
    return head_tail(eps, next(iterable), iterable)
# Full sqrt function in FP:
def sqrt(a, eps, n):
    return within(eps, repeat(lambda x: next_(n, x), a))

tgt=sqrt(1.0, 0.000001, 2)
print(tgt)
1.414213562373095

Summary

This FP flavour calc of sqrt() consists of following steps:

  • Define the function model to use and the iterator function
  • Define the end subject of the iteration
  • Iter and check the result: whether ||f(iter)-f(next_iter)|| meets the end subject
# Framework of this method:
# divide-calc-merge

#-divide
def next_(n, x):
    return (x+n/x)/2
f = lambda x: next_(n, x)

#-calc(multi times, generate f_n(a))
def repeat(f, a):
    yield a
    for v in repeat(f, f(a)):
        yield v

#-merge
def within(eps, iterable):
    # Check whether is satisfy the end subject or just try to iter into next
    def head_tail(eps, a, iterable):
        b = next(iterable)
        if abs(a-b) <= eps:
            return b
        return head_tail(eps, b, iterable)
    return head_tail(eps, next(iterable), iterable)

#-main
def sqrt(a, eps, n):
    return within(eps, repeat(lambda x: next_(n, x), a))

tgt=sqrt(1.0, 0.000001, 2)
print(tgt)
1.414213562373095
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容