[原创译书] JS函数编程 3.2 开发和生产环境

?? Functional Programming in Javascript 主目录第三章 建立函数式编程环境

开发和生产环境

环境

编程风格与应用所部署或者将要部署的环境没啥关系。但是库就有关系了。

浏览器

主要的Javascript应用还是跑在客户端的,也就是浏览器。基于浏览器的环境对于开发来说非常好,
因为浏览器无处不在,你可以在本地机器上写代码,解释器是浏览器的Javascript引擎,
所有的浏览器都有开发者终端。火狐的FireBug提供了非常有用的错误信息,并支持断点等等,
不过同样的代码运行在Chrome和Safari上的交叉引用的错误输出会很有用。甚至连IE都包含开发者工具。

浏览器的问题是他们对Javascript的解析不尽相同!尽管不是普遍现象,但是可能有些代码在不同的浏览器上会得到非常不同的结果。
不过主要的差别在于它们如何处理DOM,而不是在原型和函数如何工作上。举个明显的例子,Math.sqrt(4)
在任何浏览器和shell上都会返回2。但是scrollLeft方法依赖于浏览器的布局策略。

编写针对浏览器的特定代码是在浪费时间,这也是为何要使用库的另外一个原因。

服务器端Javascript

Node.js已经成为创建服务器端和基于网络应用的标准平台。函数式编程可以用于服务器端应用的编程吗?
可以!OK,不过现在的这些函数式库是为这种注重性能的环境设计的吗?答案仍然是肯定的。

这章提到的所有的函数式库都可以工作在Node.js上,有些需要依赖browserify.js模块来处理浏览器元素。

服务器端环境的一个函数式用例

在我们的网络系统这个无畏的新世界里,服务器端应用开发人员总在担心并发问题,这是应该的。
经典的例子就是一个应用允许多个用户修改同一个文件,如果他们打算同时修改这个文件,你将会陷入令人作呕的混乱。
这就是困扰了程序员几十年的状态维持问题。

假设下面这个情景:

  1. 一天早晨,亚当打开了一份报告开始编辑,但是出去吃午饭的时候没有保存。
  2. 比利打开了同一份报告,添加了内容,并且保存了报告。
  3. 亚当吃完午饭回来,又往这份报告里添加了内容,并且保存,不知情地覆盖了比利的内容。
  4. 第二天,比利发现他的内容消失了。他的老板冲他咆哮,所有的人都一起冲着开发人员发飙,结果开发人员丢了工作。

长期以来,解决这个问题的办法就是给文件建立状态。当有人编辑这个文件的时候就把状态切换为加锁,
这就防止其他人编辑这个文件,并在保存这个文件后把状态切换为解锁。在我们的情景里,比利应该无法修改报告,
直到亚当吃完饭回来。并且只要文件没被保存就没有其他人可以编辑它。

这正是函数式编程关于不可变数据和状态的思想具有实际意义之处。函数式的实现并不是直接修改文件,
而是修改文件的一个拷贝,也就是一个新的版本。如果要保存这个版本而此时一个新的版本已经存在,
我们就知道已经有别人修改了原来的文件。危险规避了。

现在这个场景可以这样展开了:

  1. 一天早晨,亚当打开了一份报告开始编辑,但是出去吃午饭的时候没有保存。
  2. 比利打开了同一份报告,添加了内容,保存为了一个新的版本。
  3. 亚当吃完饭回来继续添加内容,当他要保存时,系统告诉他现在已经存在一个新版本了。
  4. 亚当打开了这个新版本,添加了自己的内容,并保存为另一个新版本。
  5. 通过查看版本历史,老板看到了一切在平稳运行。所有人都很开心,应用的开发人员也得到了晋升和奖赏。

这个叫做事件源。不需要维护明确的状态,只需要事件。这个过程非常清晰,整个事件的历史都可以回顾。

这个思想以及其它一些优势是函数式编程在服务器端日益增长的原因。

CLI

尽管web和node.js是两个主要的Javascript环境,但是一些务实和进取的用户在寻找把Javascript用于命令行的方式。

把Javascript作为一个命令行界面(CLI)脚本语言使用会是应用函数式编程的一个绝佳机会。
想象一下在搜索本地文件时使用惰性求值,或把整个bash脚本用函数式的Javascript写成一行。

与其它Javascript模块一起使用函数式库

web应用由许多东西组成:框架、库、API等等。他们可以互相依赖,作为对方的插件,或者仅仅是共存的对象。

  • Backbone.js

    • 一个使用RESTful JSON的MVP(model-view-provider)框架
    • 需要underscore.js库,这是backbone的唯一必需依赖
  • jQuery
    • Bacon.js通过绑定融入jQuery
    • Underscore和jQuery很好地互补
  • Prototype
    • 提供与Ruby的Enumerable风格相近的一系列函数
  • Sugar.js
    • 修改原生对象及其方法
    • 和其它库混合使用时需小心,尤其是Prototype

编译为Javascript的函数式语言

有时Javascript函数式核心之外那厚重的C外衣让你想要换一个函数式语言。好,可以滴!

  • Clojure和ClojureScript

    • Clojure是一个现代的Lisp实现,是一个具备全部函数式特征的语言
    • ClojureScript将Clojure编译为Javascript
  • CoffeeScript
    • CoffeeScript是一个函数式语言及其编译器的名称,它编译为Javascript
    • CoffeeScript表达式和Javascript表达式可以一一对应

这样的语言还有很多,包括Pyjs、Roy、TypeScript、UHC、PureScript等等。

第三章总结

你选择使用哪个数据库取决于你的需要是什么。需要函数响应式编程来处理事件和动态值?使用bacon.js。
需要无限流而不需要别的?用stream.js。想要一个函数式助手来补充jQuery?试试underscore.js。
需要严格特定多态的结构化环境?看看bilby.js。需要面面俱到的函数式编程工具?使用Lazy.js。
用这些都不爽?你自己写一个。

任何库都只擅长于它所使用的方式。尽管这章提到的库里面有几个缺点很少,大多数错误都会在不经意间就出现。
这取决于你选择的库是否正确,是否符合你的需求。

如果我们在Javascript环境中引入了代码库,也许我们同时还引入了想法和原则。也许我们可以通过
《Python之禅》来表达。作者:Tim Peter。

Beautiful is better than ugly

Explicit is better than implicit.

Simple is better than complex.

Complex is better than complicated.

Flat is better than nested.

Sparse is better than dense.

Readability counts.

Special cases aren‘t special enough to break the rules.

Although practicality beats purity.

Errors should never pass silently.

Unless explicitly silenced.

In the face of ambiguity, refuse the temptation to guess.

There should be one—and preferably only one—obvious way to do it.

Although that way may not be obvious at first unless you‘re Dutch.

Now is better than never.

Although never is often better than "right" now.

If the implementation is hard to explain, it‘s a bad idea.

If the implementation is easy to explain, it may be a good idea.

Namespaces are one honking great idea—let‘s do more of those!

下一章 在Javascript中实现函数式编程的技术

时间: 2024-10-12 15:55:55

[原创译书] JS函数编程 3.2 开发和生产环境的相关文章

[原创译书] JS函数式编程 3.建立函数式编程环境

?? Functional Programming in Javascript 主目录上一章 函数式编程基础 第三章 建立函数式编程环境 介绍 如果只是为了用函数式编程写应用,我们是否需要了解高级数学知识--类型理论.lambda演算和多态? 我们需要重新发明轮子吗?简单来说,这两个问题的答案都是:不需要. 在这章,我们将竭尽所能去调研所有会影响用Javascript编写函数式程序的方式,包括: 库 工具集 开发环境 编译成Javascript的函数式语言 更多 你要明白现在Javascript

在package.json里面的script设置环境变量,区分开发及生产环境。注意mac与windows的设置方式不一样

在package.json里面的script设置环境变量,区分开发及生产环境. 注意mac与windows的设置方式不一样. "scripts": { "publish-mac": "export NODE_ENV=prod&&webpack -p --progress --colors", "publish-win": "set NODE_ENV=prod&&webpack -p -

spring boot--日志、开发和生产环境切换、自定义配置

Spring Boot日志常用配置: # 日志输出的地址:Spring Boot默认并没有进行文件输出,只在控制台中进行了打印 logging.file=/home/zhou # 日志级别 debug-> info -> warning -> error # 默认级别为 info # 如果设置了debug=true的时候,日志级别会自动降低为debug # ROOT代表默认全局设置 logging.level.ROOT=INFO # 可以设置指定包的输出级别,这样的话,指定的包,级别以下

webpack开发与生产环境配置

前言 作者去年就开始使用webpack, 最早的接触就来自于vue-cli.那个时候工作重点主要也是 vue 的使用,对webpack的配置是知之甚少,期间有问题也是询问大牛 @吕大豹.顺便说一句,对于前端知识体系迷茫的童鞋可以关注豹哥的微信公众号,<大豹杂说>.豹哥对于刚开始小白的自己(虽然现在也白)知无不谈,而且回复超快超认真.这里真的很感谢豹哥.前段时间工作不忙,自己就啃了啃webpack的官方文档,毕竟知识还是在自己脑袋里踏实.然后根据vue-cli的配置文件丰富了一点新的东西,发布出

vue-cli3区分开发和生产环境

vue-cli3出来很久了,之前一直使用vue-cli2的配置,并且区分了生产和开发环境,自己的理解,环境分两大类,开发环境 和生产环境 对于命令来说,就是dev和build的区别, 一般都会有预发布和正式生产两个环境区别 预发布 就使用预发布的接口 正式的就使用正式的接口 对于程序员来说,本地测试也需要测试预发布的接口和生产的接口,上线也需要区分上到预发布或者上到生产 所以根据这些的不同,分成了两大部分,每一部分都分了预发和正式 具体可以参照下图 根据这些不同呢,就在package.json中

Maven_如何为开发和生产环境建立不同的配置文件 --我的简洁方案

其实也是最近才看Maven, 以前都是用ant+ivy, 对于轻量级的项目来说足够了, 而且非常灵活. 看了看Maven, 约定.... 现在编程都说约定, 约定是挺好, 问题是超出约定的事情太多了, 到头来还要依赖其他东西, 真不想用maven啊. 以前我们开发环境和生产环境的配置文件都是单独分开目录存放的, ant脚本搞个变量就自动打包不同的文件了. 我觉得管理起来也很容易, 所以看到很多maven为解决开发/生产环境的方案真是不太理解啊:  1. 什么 ${your.configurati

spring 项目分开发和生产环境

1.pom 文件修改 <profile> <!-- 本地开发环境 --> <id>dev</id> <properties> <profiles.active>dev</profiles.active> <webXmlPath>src/main/filters/dev/web.xml</webXmlPath> </properties> <activation> <ac

[原创译书] JS函数式编程 前言

前言 函数式编程是一种能够让你编写更聪明的代码的方式,可以减低复杂度,增强模块化. 它是一种通过灵巧地变化.组合.使用函数达到编写简洁代码的方式. Javascript提供了一个实现这些的超赞的途径.Javascript,这个Internet的脚本语言, 它的核心实际上是一个函数式语言.通过学习如何显露出它作为一个函数式语言的真实身份, 我们可以实现强大的.更易维护的以及更可靠的web应用. 通过这些,Javascript的那些怪癖和缺陷将会立刻变得清晰,并且语言本身也将会无限精彩. 学习如何使

[原创译书] JS函数式编程 2.1 函数式编程语言

?? Functional Programming in Javascript 主目录第二章 函数式编程基础 函数式编程语言 函数式编程语言是那些方便于使用函数式编程范式的语言.简单来说,如果具备函数式编程所需的特征, 它就可以被称为函数式语言.在多数情况下,编程的风格实际上决定了一个程序是否是函数式的. 是什么让一个语言具有函数式特征? 函数式编程无法用C语言来实现.函数式编程也无法用Java来实现(不包括那些通过大量变通手段实现的近似函数式编程). 这些语言不包含支持函数式编程的结构.他们是