这才是我苦苦追寻的lisp呀!

生物学上,我们知道基因有隐性和显性。如果爸爸的眼睛是蓝色,妈妈的眼睛是棕色,那么他应该继承了来自父母的基因:即有蓝色又有棕色的。而表象可能他的眼睛是棕色的。

对于语言也是一样,我们要区分真正的基因...和表象。我们强调的是基因而不是表象。

lisp的基因:递归作为表达过程调用的主要方式

使用链表表示复杂数据结构

通过定义函数来编程

垃圾回收

代码即数据

事实上Python,Ruby,Clojure甚至TCL/tk都带有lisp的基因。

:::::::::::::::::::::::::::::::::::::::::: 先怼传统老掉牙的lisp :::::::::::::::::::::::::::::::::::::

common lisp,曾经是最正统的lisp。但是25年之后,它不再是lisp基因的正确表象。

为什么?它犯了一些错误:

首先,它太臃肿了。

但是它又确缺少一些重要的东西。FFI,线程和并发(它发明的年代还没有这些东西)。

库。混乱,拙劣,并且低质量的库(形容Python亦可,嗯,放个嘲讽)。

没有模式匹配和静态类型。非常过程式。

委员会的那一群傻逼既肤浅又保守,不思进取。新手们都受不了那一堆括号,他们却耸耸肩:“你不懂lisp”。

那一堆的括号根本就不是基因,CL还在强调那些老掉牙的表象,而缺失了真正的lisp基因。

反倒是python,在lisp基因上面套了一层语法糖,这门语言就流行了。

在shen之前我最喜欢的lisp方言是scheme。它的哲学是:“计算机语言不应该进行功能的堆砌,而应该尽可能减少弱点和限制,使剩下的功能显得必要”。这一点我不能同意得更多。然而受限于lisp的表象,它走得还不够远。

shen显然在common lisp里面吸取教训:不要沉迷于表象。表达真正的基因。

:::::::::::::::::::::::::::::::::::::::::: 再怼那些欺负lisp没有类型的傻逼语言 ::::::::::::::::::::::::

这是一门足够先进的lisp方言。

shen回归到了简单,它的核心定义了一个非常小的lisp,比scheme规模还要小得多,在它那边叫kernal lambda。内嵌了yacc和prolog,语法糖和类型都编译到kernal lambda。

shen保留了lisp基因,并且从ML,甚至prolog那边拿到了一些真正好的东西。比如基于模式匹配的函数式编程,类型系统和安全性。

据说它的类型系统的实现只用了511行的代码。怎么做到的?用这些代码它会生成大约200多条规则和公理,然后将这些规则变成大约27,000行的Common Lisp代码!天呐,这么神奇?因为lisp的代码即数据呀。

为了说明它的先进性,让我们看一个例子。如果我要定义一个集合类型set,该怎么办?集合是这样的,它里面没有重复的元素。

(datatype set

____________

[] : (set A);

if (not (element? X Y))

X : A; Y : (set A);

================

[X | Y] : (set A);)

这段代码是说,空[]算是一个集合;

如果Y是一个集合,如果X不是Y里面的元素,那么,`[X | Y]`也是一个集合。

[1 2 3] : (set number)

["sasdf" "bc"] : (set string)

[1 1 2] : type error

["aa" 1] : type error

牛逼不!这是实现了dependent type类型啊!请我们有本事的ML/Haskell语言也定义一个set类型试试?

Haskell,请开始你的表演(此处应有掌声)。

参考资料:

回复评论。

知乎的评论系统小抽风了,那边回复不了。 @nameoverflow

set类型的例子其实是一个简化的版本,是为了方便不了解shen的人理解。

实际上这样定义set之后,下面这个函数根本没法编译:

(define union

{(set A) --> (set A) --> (set A)}

[] S -> S

[X | Y] S -> [X | (union Y S)] where (not (element? X (union Y S)))

[_ | Y] S -> (union Y S))

为了让union能编译,需要修改下set的类型定义:

(datatype set

_____________

[] : (set A);

X : A; Y : ((set A) & (without X));

===================================

[X | Y] : (mode (set A) -);

X : (set A);

_____________

X : (list A);

X : P; X : Q;

====================

X : (mode (P & Q) -);

________________

[] : (without X);

if (not (= X Z))

Y : (without Z);

______________________

[X | Y] : (without Z);

______________________________________________

(not (element? X Y)) : verified >> Y : (without X);)

其中最最最重要的就是verified这个关键字,它可以解答你的疑问。

[X | Y] S -> [X | (union Y S)] where (not (element? X (union Y S)))

这里面有个where条件,就是说,只有满足条件才走这个句子,而对应的在类型定义里,它就是verified。

也就是它并不是在运行期去check条件满足,而是编译期能知道条件满足。你可以当它是个trick。不得不承认,在理解shen的类型系统的实现之前,使用起来还是比较不那么方便的。

再补充,实名反对 @开源哥 的部分观点

Shen 的类型系统是基于 Sequent Calculus 做的,定义类型的方法是手写推理规则

这就是我说的语法不够 Lisp 的地方(之一)

你怎么能这么说呢?宏和DSL本来就是lisp的精华之一! Shen 在这里恰巧把 Lisp 的精华表达到了极致!

不是 Shen 的语法不够 Lisp,而是你没领会 Lisp 语法的真正魅力呀,同学!

那么问题来了,Lisp 的特征之一,quote 呢?

抱歉,不存在的

1. quote到底好不好?

纵观函数式语言的发展史,语法从 ISWIM 那个地方就开始分叉:Lisp 和 Haskell。Lisp 从发明之后 sexp 就没有真正变过(本来也没有真正意义上的语法)。而另一支 KRC & Miranda,ML 到 Haskell 这边都是受到 ISWIM 影响的,你可以看一下《the next 700 Programming Languages》。

看起来你受其它语法影响比较重。quote 让“符号”和“语法”之间成为模糊的存在,但我不认为它是 Lisp 精华的东西,它并不“所见即所得”。比如,像这种东西真的好读么?

(cdddr`(this list contains ,(list 'a)))

2. quote 是不是必须的特征?

转念一想,quote 是不是必须的呢?答案:不是。

像 scheme 这种lisp1里面,当输入 `map` 会对 symbol 求值。所以scheme会得到map绑定的函数...也就是,它把map是当作变量解释的。于是为了得到 map 这个纯粹的符号,需要使用特殊表 quote。

而 Shen 对 symbol 的求值规则有点特殊(lisp2)。它对symbol不会直接求值,于是你输入 `map` 得到的就是 map 这个符号。

这个问题的根源是这样的:尽管 Lisp 可以做到“代码即数据”,写代码的人还是得写明白,他想把一个东西当代码使还是当数据解释。

导致的结果是:在 scheme 中,一个 syntax 想当 symbol 使用的时候,都要用 quote 关键字。在 Shen 里面,一个 syntax 想当变量或者函数使用的时候,都是写成 (value xxx) 或者 (function xxx)。

这很蛋疼,所以在 Shen 里面做了一个约定,大写开头全是变量,缓解这个问题。

quote 存在的真正意义就是,让用户可以选择到底是代码还是数据,但它只是实现的途径之一,但并不是必须的。

所以在 Shen 里你做不到 Lisp 的“像操作数据一样操作代码”

是不是区分圆括号和中括号之后,Shen 就不是代码即数据了?这些在进入到内部表示之前,都不算真正的 sexp。在内部只有统一的一种形式,reader 会自动处理,你可以理解成统一只剩下中括号那种表示(转化到内部的 sexp 之后外部表示是啥不重要)。

(define x ''(list a)) 变成

(define x (quote (quote (list a))))

(define x [[list a]]) 变成

[define x [cons list [cons a nil]]]

我觉得没啥区别呀,这怎么就不能像操作数据一样操作代码了?你要讲道理呀,同学!

最后,我看你签名是 Making LISP Great Again (

哥!你真的不是 Haskell 派过来 Lisp 阵营的奸细?

深圳python如何评价_如何评价shen 语言?相关推荐

  1. 如何评价python知乎_如何评价《Python Web开发实战》?

    我先说一个「为什么给人没有太多实战的感觉」的问题吧.我这本书借着「豆瓣」这个title出版,相信很多人对其中豆瓣相关的内容都很关注,最后可能会比较失望,因为比较少的介绍到豆瓣自己造的轮子.另外我给其他 ...

  2. python图像质量评价_图像质量评价(三):FSIM

    feature similarity index mersure(FSIM)利用特征相似性进行质量评价.因为human visual system (HVS)是基于一些低层次特征来感知图像的,而相位一 ...

  3. python评语生成_如何评价生成模型框架 ZhuSuan?

    抛砖引玉: 整个平台是清华大学副教授朱军的学生们主导的,有国家经费的支持,个人觉得是一个很有意义的项目.先搬砖翻译项目介绍:珠算(ZhuSuan)是一个构建于 TensorFlow 之上的用于生成模型 ...

  4. 曼达洛人对机器人的评价_如何评价《曼达洛人 》?

    若是评选好莱坞乃至全球最具影响力的IP,<星球大战>绝对名列前茅,也正因它的出现,好莱坞才得以大步进入特效大片的辉煌时代. <曼达洛人>作为全球顶级IP<星球大战> ...

  5. python 单词纠错_自然语言处理1——语言处理与Python(内含纠错)

    学习Python自然语言处理,记录一下学习笔记. 运用Python进行自然语言处理需要用到nltk库,关于nltk库的安装,我使用的pip方式. pip nltk 或者下载whl文件进行安装.(推荐p ...

  6. python七夕快乐_用22种语言祝大家七夕节快乐!

    原标题:用22种语言祝大家七夕节快乐! C:printf("祝大家七夕快乐!"); C++ : cout< QBasic : Print "祝大家七夕快乐!&quo ...

  7. 生日快乐python编程代码_如何用C语言编写一个很炫的生日快乐的程序?

    我也是网上找的,把下面的话改一下差不多了 很多人说没法运行,我也不是专业的,但是这用codeblock c++是可以运行的,其他的我不知道 #include #include #include #de ...

  8. 易语言python代码长短_怎样用易语言取网络文件长度源码

    新建一个程序集1,输入如下内容: .如果 (http.创建 ("WinHttp.WinHttpRequest.5.1", )) http.方法 ("SetTimeouts ...

  9. python +selenium 实现教学质量评价自动化

    每个学期都要对各科老师的教学质量作出评价,每次评价的时候总是不忍心把老师评价成c或者D,想想老师一个学期的辛苦付出,大家都不容易,也就都给个A,说两句好话,然而这又是一个机械重复的枯燥过程,今年的科目 ...

最新文章

  1. 360前端星学习笔记-深入CSS
  2. 二分查找--AVL查找树
  3. C++源码的调用图生成
  4. ActiveMQ消息形式
  5. mysql第3章数据定义_【MySQL数据库】第3章解读:服务器性能剖析 (下)
  6. linux cpu核数查看_Linux日常必备的 8 个小技能
  7. nginx简单代理配置
  8. 练习题(第二模块...模块...选择填空)
  9. win10 默认程序 edge
  10. 技术不错的我去面试大厂,5分钟,就被秒了!憋屈~
  11. 谷歌浏览器如何免费复制百度文库,解决禁止复制,禁止使用右键等
  12. IP防护等级测试设备(IPX1.2.3.4.5.6.9)
  13. html js3d魔方,40行JavaScript代码实现的3D旋转魔方动画效果
  14. Uchome分页方法
  15. 【山科OJ】Problem C: Matrix Problem (III) : Array Practice
  16. cpua55和a53哪个好_OPPOA55和OPPOA53详细参数对比测评详情-哪款更值得购买
  17. 入门必学 | R语言数据的独立性,正态性及方差齐性检验
  18. vbs新年祝福,怎么样
  19. python复制excel模板并保留表格样式
  20. 阿德莱德大学计算机专业学费,阿德莱德大学本科及研究生学费是多少(含各专业学费)?...

热门文章

  1. STM32 MPU6050与匿名上位机通讯(V2.6版)
  2. 更改电脑默认打开的浏览器
  3. 70后80后90后00后网民研究报告(2017年)
  4. android 开发邮箱随手笔记之收件箱
  5. microtime() 函数
  6. C++中goto的使用
  7. mysql冷热分离的技术_冷热数据分离思路
  8. Android实现真正的344格式化手机号码输入框
  9. python压缩教程_如何使用Python压缩/解压缩zip文件?(代码示例)
  10. Spring中Singleton模式的线程安全