以racket为例,一个简单的例子:
#lang racket
(define person%
(class object%
(init-field name age) ; 1 定义字段
(define/public (get-name) name) ; 2 显式访问器
(define/public (get-age) age)
(super-new)))
(define p (new person% [name "Alice"] [age 25]))
(send p get-name) ; => "Alice"
(send p get-age) ; => 25
(get-field name p) ; => "Alice"
(get-field age p) ; => 25
“Racket 对象没有 obj.field”,只能通过send发消息或者get-field来访问。
那么问题来了,为什么会这样?为什么不搞简单点,直接使用.来访问数据成员和成员函数呢?读者可能希望能直接这样写:
(. p get-name)
(. p get-age)
(. p name)
(. p age)
或者干脆这样:
(p.get-name)
(p.get-age)
(p.name)
(p.age)
实际上.在Scheme里已经有了其他用途:
> '(1 2 3 . 4)
'(1 2 3 . 4)
读者可能得出结论:“因为.被用于创建improper list,所以就不好用在对象成员访问了。”但是这种理由是站不住脚的,因为创建improper list的点号前后是隔了空格的,词法、语法分析器是能分辨出.是对象成员访问还是创建improper list.
唯一的可能是各个Scheme或lisp标准没有人做类似提案,或者有过提案,但是提案没有进正式的rnrs标准,解释器或者编译器实现者就不会去实现。
另外,Lisp/Scheme里没有return break continue关键字,虽然能通过call/cc模拟,个人还是喜欢直接写return,而不是通过一段call/cc来模拟,就我本人而言,能记住并写好一段call/cc并不容易,如果不抄代码,甚至是做不到。在我本人编写的一个Scheme子集解释器里,实现了return,AI帮助编写的,这很简单。Lisp/Scheme社区的大牛们应该很容易实现,没有这些特性的原因如上,没有提案或者提案没有进正式标准。
希望有一天这些特性能进标准,能再见识一个新的Lisp方言。
--
修改:zhangxp024 FROM 183.161.94.*
FROM 183.161.94.*