SunDawning avatar

函数式编程源自弱小人类对抗浩瀚宇宙的迫切需求

sundawning

Published: 07 May 2018 › Updated: 07 May 2018函数式编程源自弱小人类对抗浩瀚宇宙的迫切需求

函数式编程源自弱小人类对抗浩瀚宇宙的迫切需求

以Common Lisp程序为例。

一个Common Lisp程序本来可以只是一个函数,但为了便于人类进行阅读,故将一个函数拆分为多个小函数,至于模块化重用性易调试,实乃意想不到的收获。如果将整个程序只写在一个函数里,因为用于显示程序的屏幕是有限的,肉眼的视角是有限的,肉眼一次性能捕捉到的内容将非常受限,那么每次移动屏幕和视觉所获取的信息都会大打折扣。物理上屏幕和生理上视角的双重局限,压迫人类进行手动拆分函数过程,然究其根本,实为“渺沧海之一粟,寄蜉蝣于天地”的无奈。小小的人,却欲观尽浩渺苍穹,茫茫千万年,前赴后继,何其悲壮。也许世界的全部,就是人类自身,就是万千众生,曰“一花一世界”,不正如是?

函数"string-to-html",目的是将大段的文字转换成符合"HTML"语法的文字,如果是一段文字就添加"<p></p>"标签,如果是空行,就添加"<p><br/></p>"标签。

例如,给定大段文字:

(defparameter *string-to-html*
  "0

1")

需要转换成:

"

0


1

"

不把函数分拆时,把所有操作都包含在一个函数里:

(defun string-to-html (string)
  (format nil "~{

~A

~}"
(mapcar (lambda (i) (if (or (null i) (and (stringp i) (= (length i) 0))) "
"
i)) (let ((var nil) (stream (make-string-input-stream string))) (do ((line (read-line stream nil 'eof) (read-line stream nil 'eof))) ((eql line 'eof)) (push line var)) (reverse var)))))

调用:

(string-to-html *string-to-html*)

"

0


1

"

拆分后的全局函数:

(defun null-string-p (string)
  (or (null string)
      (and (stringp string)
           (= (length string)
              0))))

(defun %%string-to-html-1 (string)
  (let ((var nil)
        (stream (make-string-input-stream string)))
    (do ((line (read-line stream nil 'eof)
               (read-line stream nil 'eof)))
        ((eql line 'eof))
      (push line var))
    (reverse var)))

(defun %string-to-html-1 (%%string-to-html-1)
  (mapcar (lambda (i)
            (if (null-string-p i)
                "
"
i)) %%string-to-html-1)) (defun string-to-html-1 (%string-to-html-1) (format nil "~{

~A

~}"
%string-to-html-1))

调用时:

(string-to-html-1
 (%string-to-html-1
  (%%string-to-html-1 *string-to-html*)))

"

0


1

"

拆分后的局部函数:

(defun string-to-html-2 (string)
  (labels ((null-string-p (string)
             (or (null string)
                 (and (stringp string)
                      (= (length string)
                         0))))
           (%%string-to-html-2 (string)
             (let ((var nil)
                   (stream (make-string-input-stream string)))
               (do ((line (read-line stream nil 'eof)
                          (read-line stream nil 'eof)))
                   ((eql line 'eof))
                 (push line var))
               (reverse var)))
           (%string-to-html-2 (%%string-to-html-2)
             (mapcar (lambda (i)
                       (if (null-string-p i)
                           "
"
i)) %%string-to-html-2))) (format nil "~{

~A

~}"
(%string-to-html-2 (%%string-to-html-2 string)))))

对比上述三种实现方式,分拆成全局函数时:

  • 成本
    • 需要输入更多的字符和行数,曰物理成本:(90-54)/54=2/3
      • 不分拆函数时字符:Region has 16 lines, 54 words, and 661
        characters.
      • 分拆后的局部函数:Region has 23 lines, 90 words, and 899
        characters.
      • 分拆后的全局函数:Region has 25 lines, 90 words, and 673
        characters.
    • 需要为多个小函数选择合适的名字,曰精神成本:用一个名字抽象化一个过程
      • 需结合函数的功能
      • 需调试时能见函数名就知功能
  • 效益
    • 易阅读:小块内容,缩进量少,显而易见的函数功能。
    • 模块化:使用返回值时只用确保参数符合要求,自然就返回合适的值。
    • 重用性:直接分离出某个小函数,用于别的项目。
    • 易调试:函数出错时容易定位到某个小函数 -

从上述的数据里可见,为了所谓的效益,人类宁可多打点字,尽管要增加2/3的打字量,宁可想个好名字,尽管要多费点心神去打磨。

赞美函数式编程本身就像宣扬人类有多么无奈、弱小一样,生怕强大的宇宙不知道人类有多么菜,但这确确实实是弱小人类对抗浩瀚宇宙的有效举措,再说了,任何函数式的程序天生就有拿来即用的禀赋,于人于己都有益处,多费时间就多费时间吧,人类在抽象这条路上算是越走越远了。

Leave 函数式编程源自弱小人类对抗浩瀚宇宙的迫切需求 to:

Written by

Read more #programming posts


Best Posts From SunDawning

We have not curated any of sundawning's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.

More Posts From SunDawning