Lisp的特点具备函数式编程和元编程的能力,问题是元编程是在现有语言很难解决某个问题时,才用它来构造一个DSL解决问题。至于函数式编程,现代的语言在这方面不逊于lisp。所以感觉除了elisp和个别其他领域的lisp之外,并没有现代的语言实用。只停留在教学的话意义上
我觉得就是S表达式贼爽。
这个可能是重点
对于我们这种讲究简单和无歧义的人来说,确实是这么一回事,但万物都有反常,极其糟糕的设计在大量使用的时候,人们就叫它“艺术”
你觉得「现有语言很难解決」这个情況出現很少,我覚得很多。比如,我現在在写一个 jit binding, 代码中会有百來行
jitProlog :: Lightning ()
jitProlog = liftL $ _jit_node Prolog
jitArg :: Lightning JitNodePtr
jitArg = liftL $ _jit_node Arg
...
我立马就要用 Template Haskell,谁会手写这种东西啊?然而 TH 用起來还是不如 Lisp Macro 順手,限制太多,主要原因就是 Haskell 语法树比 Lisp 太复杂。实际上我还是靠先实現 liftL
简化代码表达式才让 TH 这边工作变简单些。
Common Lisp 是有相當先进的 OOP 的语言,用什么二流子的函数式。
要真那么少,Rust那个对于lisp用户来说难用得要死的macro_rules!
也不会有那么多人吹
macro_rules! thread {
($($fn:expr),*) => {
|v| {
thread!(NEXT v, $($fn),*)
}
};
(NEXT $v:expr, $fn:expr, $($rest:expr),*) => {
thread!(NEXT $fn($v), $($rest),*)
};
(NEXT $v:expr, $last:expr) => {
$last($v)
};
}
fn main() {
let a = " I will be the best ";
let f = thread! {
|x: &str| x.replace('l', "~"),
|x: String| x.len(),
|x: usize| x & 1
};
println!("{:?}", f(a));
println!("{:?}", a);
}
实现个threading macro都要借助显式的中间符号NEXT
如果你有像这样一个 case 表达式:
这是什么破例子,在我眼里这两个一样丑好么
case x of
Short _ -> 1
VeryLooooooooooooooooooooooooog _ -> 2
(case x
((Short _) 1)
((VeryLooooooooooooooooooooooooog _) 2))
我以为正当的做法是一开始就別用这么奇怪的名字。
如果是表达式这种不能省的,用 let
或 where
fun x =
| exp1 x = 1
| short2 x = 2
where short2 = veryLooooooooooooooooooooooooogExp
然后 Lisp 因为不是 call by need 所以不能在 case clause 里用 let
,还是得用 symbol-macro
。
順帯 product type case match 是 ALGOL 先有的。
见你多处不厌其烦(死乞白赖)的推荐王艮, 咱也去拜读了. dammed good. 采访下, 他的博文中, 最喜欢哪三篇?
当然是他的XX智慧三连啦
理性阅读,不可全信,说不定什么时候垠神又对他的观点“真香”了(而且已经真香过多次)
王垠自己的博客删去好多内容了,不过有有心人备份
嗯, 不错, “整理房间的智慧” 写得挺好.O(∩_∩)O
好多优点被借鉴走了,然而我觉得lisp最大的优势是s表达式本身…
优势并没有消失,Lisp有两大优势:
-
Lisp是动态类型语言:动态类型意味着所有在静态语言里的各种高级多态技术,在Lisp里变成了非常trivial的东西(只要你有自己的代码约定和注释)。
-
Lisp支持宏:宏意味着很多其他语言的特有的原语和语法糖,在Lisp里都可以用宏实现。
王垠的博客很全啊。
这两点都不是 Lisp 特有的。动态语言很多,支持宏的语言也不少。
但是都没有 S 表达式本身来的爽快。 借用楼上的话
都能用宏实现喔
那实现一个最简单的
1 + 9 * 6
不允许带括号哦
先做加法再做乘法,不用括号实现给我看下呗
你用宏实现这个干什么? 宏是让你自定义 语法糖 和 新的语言构造的,不是拿来改变语法的。
你这个东西叫做具体语法,你真的想改,也很简单,使用 Reader Extension(比如:在Racket里,你可以用read-syntax写一个parser来实现自己的DSL)
看了一下
https://docs.racket-lang.org/reference/reader.html#(part._parse-reader)
但由于没接触过racket,所以看的是一头雾水
哪里有具体的例子吗? 或者 你给普及一下也行。
是的。字数补丁