戏说R语言系列4

上一集讲到 R语言是 S语言的一支方言。其实呢, R语言还受另外一款语言的影响,就是Scheme

Scheme是一种函数式编程语言,是Lisp的两种主要方言之一(另一种为 Common Lisp)。不同于 Common Lisp,Scheme遵循极简主义哲学,以一个小型语言核心作为标准,加上各种强力语言工具(语法糖)来扩展语言本身。

上面这段话摘自维基百科。

廖雪峰 在他的 python教程里这样描述函数式编程。

函数式编程......其思想更接近数学计算。
在计算机的层次上,CPU执行的是加减乘除的指令代码,以及各种条件判断和跳转指令,所以,汇编语言是最贴近计算机的语言。
而计算则指数学意义上的计算,越是抽象的计算,离计算机硬件越远。
对应到编程语言,就是越低级的语言,越贴近计算机,抽象程度低,执行效率高,比如C语言;越高级的语言,越贴近计算,抽象程度高,执行效率低,比如Lisp语言。

David Springate 在他的博客里讲到了函数式编程的特征,以及函数式编程在 R语言里的应用。

我讲几个印象比较深刻的特征。

向量运算

for循环在各种语言都是很普遍的一种语法。程序员们在写多层复杂嵌套的for循环上都有一些拿手的绝活。

但实际上,R语言是极其不鼓励写for循环的,而是鼓励使用向量计算这种较为抽象的方法。David Springate举了下面这个例子,他分别用for循环和向量计算求1~200000之间的偶数。

for循环计算
向量计算

在这里,我们也计算了这两种方法的运行时间,很明显,用for循环计算并返回结果的时间(31秒多)要远远高于向量计算的时间(0.02秒)。从计算效率上讲,向量计算要优于for循环计算的,这也是为什么 R语言不鼓励使用for循环的原因。

简单一点说,向量计算在处理一个数和一组数字上是没有区别的。例如,求数字2的平方根,在R语言里执行sqrt(2)就可以了。如果求一组数字,例如 1、2、3、4、5,每个数字的平方根,并不需要写成 sqrt(1)、sqrt(2)、sqrt(3)、sqrt(4)、sqrt(5),只要写成 sqrt(1:5) 就可以了。也就是说,sqrt() 这个函数是向量化的,R语言里大部分的函数都是向量化的,所以,这也是R语言可以大量使用向量计算的原因。

C++本来是没有向量运算的,后来出现了Rcpp(为了提升R语言的执行效率,一种可以在R程序里嵌入C++程序,也可以在C++程序里嵌入R程序的工具),考虑到R用户使用向量计算的习惯,特意加了语法糖:可以用向量运算来编写C++程序。实际上,不同语言的相互学习、渗透已经很普遍了。

Lisp甚至没有for循环的语法。R语言虽然是强函数式编程语言,但还是保留了for循环的语法,否则学的人可能就更少了。

高阶函数

高阶函数和向量计算有点类似,如下图所示。高阶函数将输入向量(或矩阵、list、dataframe等数据结构)的每个元素按顺序代入函数中,并将求出的结果按顺序返回。

摘自David Springate的讲义

廖雪峰的python讲义里也提到了python的几个高阶函数,分别是 map/reduce 、filter、sorted,我不知道这是不是python的全部高阶函数。

R语言有一个大类的高阶函数被称为 apply族群,之所以叫“族群”,是因为在最基本的apply()、lapply()、sapply()、Reduce()的基础上,发展了很多工具。例如 Hadley Wickham(前几集一直再讲他)的plyr、dplyr,除此之外,还有更多的类似的工具。作为一种函数式编程语言,只要能想象到的抽象计算,都可以转换成高阶函数。

我个人更喜欢 Hadley Wickham 的 plyr,更有魔力的一种工具。

闭包(closure)

我在javascript看到闭包的概念,R语言也有闭包的概念。

John D Cook 这句 “An object is data with functions. A closure is a function with data.” 说的挺好,对象就是带着函数的数据,闭包就是带着数据的函数。

摘自David Springate的讲义

闭包就是在原有函数的基础上去生产新的函数,或者简称为函数的函数,也就是函数本身可以作为参数代入新的函数里。一些纯函数式编程语言甚至没有变量这个东西,都是函数,想想挺神奇的。

David Springate在讲义里举例说明了闭包的优势。这个案例讲的是如何设计一个 bootstrap 的抽样方案来做一个简单的回归分析。如下图所示。

源代码摘自David Springate讲义

这个是用闭包来编写的,boot_lm是一个函数,iris_boot是在boot_lm基础上的一个新的函数。真正执行的是bstrap那一步。所以说,闭包这种方式的一个好处是,编程者可以在函数定义上不断优化。

同样的问题,David Springate换了一种非函数式编程方法。如下图所示。

源代码摘自David Springate讲义

David Springate 这样评价这段代码 “This ugly beast is full of fors and ifs and braces and brackets and double brackets. It has a load of extra boilerplate code to define the variables and fill the matrices.” ,这个就不翻译了,看起来很愤怒。出于专业精神,我们还是要知道 shit 在哪里。

主要问题其实就是,没有把函数的定义过程和计算过程分离开来,如果执行不下去的话,很难发现到底是哪里出错了。

很多评论说,函数式编程语言是 “ free-debug”的,大概意思就是,只要函数编的好,就不会有太多问题。

网上有一些文章对面向对象编程和函数式编程进行了比较。印象里说 javascript 因为从函数式编程转到面向对象编程,才有了今天的辉煌。也有说,C语言需要一年时间完成开发某个功能,Lisp语言只需要不到三星期。

我觉着实际上没那么夸张。

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

推荐阅读更多精彩内容

  • 第一部分Common Lisp介绍第1章 介绍一下Lisp你在学的时候觉得已经明白了,写的时候更加确信了解了,教别...
    geoeee阅读 2,898评论 5 8
  • 3.4 说说相等和内部表示 在Lisp中主要有5种相等断言,因为不是所有的对象被创建的时候都是相等意义上的相等。数...
    geoeee阅读 1,786评论 0 6
  • 原文链接:https://github.com/EasyKotlin 值就是函数,函数就是值。所有函数都消费函数,...
    JackChen1024阅读 5,941评论 1 17
  • 据说,被上天选中的人。上帝都会为他精心准备一场十分‘精彩’的生存游戏…… 所谓精彩,不过是饿其体肤,空乏其身,苦其...
    半言倾语阅读 287评论 0 1
  • 今天上语文课时,班里的同学静悄悄的,因为我感受到了前所未有的“杀气”。 果不其然,号称“缺德”这一...
    严一然阅读 241评论 0 0