当前位置:朝夕网 » 数码科技 » 我在函数式编程上犯下的几个错误

我在函数式编程上犯下的几个错误

【CSDN 编者按】提到编程思想,你首先想到的会是面向对象还是面向函数编程呢?本文作者分享了自己在函数式编程实践中踩过的一些坑,分享给大家,希望能对你有所帮助。原文链接:https://robertw

【CSDN 】提到编程思想,你首先想到的会是面向对象还是面向函数编程呢?本文作者分享了自己在函数式编程实践中踩过的一些坑,分享给大家,希望能对你有所帮助。

原文链接:https://robertwpearce.com/how-to-lose-functional-programming-at-work.html

作者 | Robert Pearce 译者 | 弯月出品 | CSDN(ID:CSDNnews)

在过去几年里,我在使用函数式编程开发拥有大量 JavaScript 代码的应用程序时,犯了不少错误,也走了一些弯路,再此复盘并分享给大家。

不使用静态类型检查

不使用如下工具:

TypeScript

Flow

ReasonML

Elm

const processData = composeP(syncWithBackend, cleansePII, validateData)// * What arguments and their types are expected here?//// * If each function is written like this, how can// one suss out what data are flowing where?//// * How hard is this going to be to debug?// Use this everywhere: `(x) => (console.log(x), x)`

这些参数的类型应该是什么?如果每个函数都这样写,谁能猜出它们传递的是什么数据?这段代码的调试会非常困难。

或许你认为,这种““Point-free or die””的编程风格才是真正的问题。那么来看看这两种写法:

async function processData(data) { await validateData(data) const cleansedData = cleansePII(data) await syncWithBackend(cleansedData) return data}

或者使用Promise链:

// or for the Promise-chainers…const processData = data => validateData(data) .then(cleansePII) .then(syncWithBackend) .then(() => data)

无论哪种写法,想想三个月之后还有谁能明白它们是做什么的。

不使用众所周知的代码文档工具

比如 jsdoc。这些工具会加剧其他团队成员理解代码的难度,同时还无法使用自动补齐。

下面是一个例子,注意其中的文档标签并不是jsdoc的标准标签:

// NOTE: this is an untested, small example/** * @typedef {Object} ReportingInfo * @property {(\”light\”|\”dark\”)} userTheme – Current user\’s preferred theme * @property {string} userName – Current user\’s name * @property {UUID} postId – The current post\’s ID *//** * Validates that the reporting data (current user site prefences and post info) * is OK, removes personally identifiable information, syncs this info with the * backend, and gives us back the original data. * * @param {ReportingInfo} data – The current user\’s site preferences and post info * @returns {Promise<ReportingInfo>} – The original reporting data */const processData = data => // …不认真培训新老同事

不要以为写几篇文章、找一些学习资源,交给刚接触函数式编程的人,鼓励他们问问题,就能有好结果。

也不要走向另一个极端:把所有的时间精力都花在几个人身上,忽略其他人,不记录学习经验,还不鼓励他们互相帮助。

不必麻烦其它工程团队加入,也无需所有人朝同一个方向努力

“我构建出来,他们就会注意到……不是吗?”

利用午餐时间学习函数编程?不行,万一他们发现我什么都不懂,怎么办?

与其他团队领导会面,问问他们是否对函数编程感兴趣,看看他们还有什么更好的方法,或者听听他们不感兴趣的原因?不行,这事儿得向经理报告,他们会认为我太天真或太能折腾,那我岂不是得不偿失?

将自己所学的技术私藏起来,其他团队无法做出贡献,也无法改善现状。

宁可使用错误的抽象,也不采用错误的重复

在 2014 年美国芝加哥举行的 RailsConf 大会上,Sandi Metz 发表的演讲(https://www.youtube.com/watch?v=8bZh5LMaSmE&ab_channel=Confreaks)给我留下了深刻的印象,她认为“即使不得不重复,也不要使用错误的抽象”。两年后,她在博客上发表了一些很棒的评论“错误的抽象”(https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction)。

她认为,提取核心的业务逻辑,反复抽象为广泛的概念,最后将导致没有人能充分理解这些概念,更没有人了解这些抽象如何工作。

// 👇 These 4, plus Promisified versions of them,// plus combinations of them all used at once;// doesn\’t include ramda\’s pipeWith and composeWith// composeconst getHighScorers = compose( mapProp(\’name\’), takeN(3), descBy(\’score\’) )// pipeconst getHighScorers = pipe( descBy(\’score\’), takeN(3), mapProp(\’name\’) )// composeWithValueconst getHighScorers = players => composeWithValue( mapProp(\’name\’), takeN(3), descBy(\’score\’), players )// pipeWithValueconst getHighScorers = players => pipeWithValue( players, descBy(\’score\’), takeN(3), mapProp(\’name\’) )// …but then now mix and match them with actual,// real-life business logic.代码里写满晦涩难懂的代数操作符

在代码里使用这些代数操作符,肯定会让你的队友一头雾水:

Task, Maybe, Either, Result, Pair, State

bimap

chain

bichain

option

coalesce

fork

sequence

ap

map — 我指的不是 Array.prototype.map, 也不是 new Map(), 也不是键值对象的那个map

自己转换数据,而不是让SQL完成

本来 SQL 非常适合转换数据,但非要以“不可变数据”为名,建立数据流水线,在流水线中逐步转换,用这种方式来尽可能能消耗内存。

在同事的 PR 中建议遵循你的函数式风格

“这段代码非常好,要是把所有参数都反过来、删掉中间变量,然后将这些操作都映射到Either上怎样?”

或者

“我注意到你在函数中明确地构造了这些对象。要是能使用<某个函数>,就能定义输出对象的形状,然后把函数作为值来查找或计算每个值。”

还有一些…

持续用函数式编写代码,虽然整个团队里没有第二个人这么做;

消极地使用表情符号给别人的PR写评论;

在公司发表“函数式编程”的演讲,把你的错误传递到整个公司。

总结

上面提到的许多错误表面上是经验不足、缺乏技术领导力造成的。但我认为,真实原因应该更深。

不变性:重新创建对象,而非修改原来的对象,以获得更好的性能;

纯函数:使用相同的参数调用相同的函数,得到相同的结果;

将副作用放到程序的逻辑边缘上;

类很少,没有继承,没有map/filter/reduce 等。

以上就是朝夕生活(www.30zx.com)关于“我在函数式编程上犯下的几个错误”的详细内容,希望对大家有所帮助!

免责声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如有侵权行为,请第一时间联系我们修改或删除,多谢。朝夕网 » 我在函数式编程上犯下的几个错误