Skip to content

Latest commit

 

History

History
54 lines (28 loc) · 4.75 KB

ch01.md

File metadata and controls

54 lines (28 loc) · 4.75 KB

简介

标签(空格分隔): Yesod-Book


简介

自从web编程兴起,人们就一直在尝试着将开发工作变得更加有趣。作为社区,我们不断尝试推出新技术,来解决各种挥之不去的安全问题,HTTP的无状态性,多种编程语言(HTML, CSS,Javascript)必要性,去创建一个功能强大的 web 应用,等等。

Yesod 尝试着充分利用Haskell的强大特性来让 web 开发变得更加容易。Haskell 强大的 compile-time 保证了程序的正确性, 不仅仅只是类型方面,referential transparency 保证我们不可能产生一个意外的副作用。在代数数据类型上的模式匹配可以保证我们已经完整的考虑到每一种可能的情况。使用Haskell,就进入了一个没有bug的世界。

不幸地是,单单使用Haskell还是不够的。web的本质并不是类型安全。即使最简单的integer和string之间区别也是不可能的:在 web 的所有数据都是以原始字节方式传输的,完全忽略掉了我们在类型安全上的所有努力。每个应用作者留下验证输入参数的任务。我称这种问题为边界错误:程序内部的类型安全检查即使再多,外部世界的边界仍然需要清洁。

类型安全

这是Yesod的切入点。通过使用高层次声明式技术,你可以指定你需要的确定的输入类型。另外一种方式:用来处理类型安全的URLs时, 你可以确保你发送的数据的格式是正确的。

客户端处理的时候,边界错误(boundary issue)并不是唯一的问题:相同的问题也存在于数据持久化和加载数据的时候。

简洁

我们都知道,在 web 应用中,存在许多样本代码。只要有可能,Yesod就会尝试使用Haskell特性减少你手指的工作:

  • forms 库借助Applicative 类型类(type class)减少大量重复代码。
  • 在不牺牲类型安全性的前提下,使用很简洁的格式声明路由。
  • 从数据库中存取序列化数据是通过代码生成器(code generation)自动完成的。 在Yesod中,我们有两类代码生成器(code generation)。我们提供了一个方便的工具来设置你的文件和目录结构。但是,大多数代码生成器(code generation)是通过元编程在编译时期工作的。这就意味着你生成的代码是永远不会过时的,即使一个很小的库升级,也会把你生成的代码升级到最新版本。

但是对于想要一直掌握控制权,明确自己代码在做什么的人,你总是可以更接近于编译器,完全自己动手写代码。

性能

Haskell主要的编译器,GHC,有着惊人的性能,而且还在不断提升当中。选择这种语言给Yesod带来的性能优势是其他不能比的。但是这还不够:我们还需要一个高性能的架构。

举个例子,对于模板:允许HTML,CSS和JavaScript在编译时候进行解析,Yesod避免了在运行时磁盘I/O消耗,而且可以优化渲染代码。但架构的意义更为深远:我们使用先进的技术,例如在底层库中,管道建造者(builders)能确保我们的代码能保持一个常量的内存消耗,不用折磨人的文件句柄和其他资源。通过提供高层次的抽象,你可以深度压缩和合理缓存CSS和JavaScript。

Yesod的旗舰web服务器,Warp,是最快的Haskell web 服务器。当这两项技术相结合,就产生了世界上最快的web应用。

模块化

Yesod已经衍生出来许多包,这其中大多数都可以在Yesod之外使用。 这个项目的其中一个目标就是尽可能的给社区做贡献;比如如果你没有打算在下一个项目中使用Yesod,本书的一大部分内容仍然能够满足你的需求。

当然,这些库已经全部集成在一起,通过使用Yesod框架,思考这些API会给你带来一种强烈的组合思维。

坚实的基础

我曾经看到过一个PHP框架打广告说,他们支持UTF-8。这让我大为震惊:难道对UTF-8的支出不是自动的?在Haskell的世界中,字符编码之类的问题已经被完美的解决和支持。事实上,我们通常有相反的问题:这里有大量良好设计的包对这些问题提供强大的支持。Haskell社区坚持不断地为每个问题寻求更为简洁高效的解决方案。

这种强大的生态系统也有它的缺点,就是有太多的选择性。通过使用Yesod, 你已经选择了许多工具,你应该保证它们之间能够工作。

举个真实的例子,Yesod和Hamlet(默认的模板语言)使用blaze-builder作为文本内容生成器。这是因为blaze提供了最快的处理UTF-8数据的接口。如果有这方面的需求,你没有理由不选择它。