今天看到有读者抱怨我那本书是把源代码打印出来卖。这个感受我能理解,但是其实这个写作风格是反复尝试的结果,而不是偷懒。书里附带的源码,有很多是用 Scala 来注解 Java 。例如昨天我的好友问我Java版 Env 类型的 get 方法为何用了一个 try catch,
public Object get(String name) throws ParserException {
try {
return findIn(name);
} catch (ParserException notfound) {
return findOut(name);
}
}
这个其实在下一页的 Scala 版本中就是非常干净的
def get(name: String): Try[Any] = {
findIn(name).orElse(findUp(name))
}
。Java 的实现,只是为了尽可能接近 Scala 的 Try[T] ,这里更接近是一个getOrElse而不是错误处理。这种不同语言的对比,在我开发和写作的过程中,带来了很多启发和乐趣,也是我想向读者分享的体验。
我个人读书,有时候不够耐心,会经常跳过文字啃代码,这也影响了写作。未来也是一个要改进的地方。
整理这些代码的时候,我的想法更像是在编写数学题的解题过程。文字说明、图解肯定可以帮助理解,未来的版本我也会尽量添加,但是最终,编程的问题,还是要通过编写代码解决。这些代码是反复修改成为现在这个状态的,比 github 中的更便于阅读。我也尽可能去掉了一些工程代码。当然,一般来说,同一个功能,Java 的实现通常总是比 Scala 更冗长一些。但是也有一些有意思的细节值得展现。而 Scala 的代码,如果去掉变量和函数的显式类型定义,肯定可以漂亮的多,但是如果读者照着那样的代码去练习,会遇到很多编译器警告甚至类型推导错误。这一点上,我其实希望未来 scala 能够像 haskell 那样标注类型,毕竟 scala 3 连缩进语法都能实现,开发者的态度还是很开放的。Haskell 风格的标注类型,组合缩进语法,会非常利于排版打印和阅读。
书中还有一些实现,同时给出了 Scala 2 和 Scala 3 的版本,这是因为 Scala 3 的FP语法有了非常大的改变,更接近 Haskell 的体系。通过展示 Scala 3 的版本,能更好的说明这些设计为何如此。
另外就是如果读者能够直接阅读github中 JISP和 SISP 的代码,当然对我来说也是很开心的。不过那些代码其实缺失了一些信息,主要是 Commit 记录不一定代表了正确、清晰的构建过程,这中间有大量的 debug、parsec升级和思考、试验、试错以及书写修正。未来我会尽量构建一个流程清晰的,带章节划分的教学库。目前没有,是因为这三年来 Jaskell 库还在快速的发展,我这几年基本上都是每个月都有一些修订。而教学演示和文档,只能依靠投入大量的工作量去解决,没有捷径。
最后,还是要感谢每一位读者的意见和建议,你们是我前进的动力。