希望能有偿咨询一下, 虽然这是我写的最顺的语言, 但还是有很多问题. 希望找人交流一下.
1
rpman 2022-07-08 02:34:10 +08:00
写 ClojureScript 的给你顶一下 🐶
|
2
wdv2ly 2022-07-08 07:47:23 +08:00 via Android
来我司入职吧🐶后端唯一指定开发语言
|
3
ymmud 2022-07-08 08:15:04 +08:00
感觉 clojure 的热度大不如前
|
4
HENQIGUAI 2022-07-08 09:08:24 +08:00
我记得 Leancloud 好像挺喜欢 Clojure 的
|
7
ca1123 OP @ymmud lisp 这种描述操作过程的, 和现在流行的统计学习这一套确实不搭. 不过手写 AST 可以最大限度同态于自己的思维, 以前写 java, js, python, wolframe, matlab, 写着写着就不知道自己在干什么了. clojure 也会晕, 但是看看结构 8 成能想起来当时在干什么. 只要习惯了迭代, 还是很爽的.
|
9
FaiChou 2022-07-08 09:41:32 +08:00
```
(defn interpereter [expr env] (if (list? expr) (let [[p1 p2 p3 p4] expr] (match [p1 p2 p3 p4] ['if pred true-branch false-branch ] (if (interpereter pred env) (interpereter true-branch env) (interpereter false-branch env)) ['* arg1 arg2 nil] (* (interpereter arg1 env) (interpereter arg2 env)) ['dec arg nil nil] (dec (interpereter arg env) ) ['zero? param nil nil] (zero? (interpereter param env)) [func params nil nil] ((interpereter func env) (interpereter params env)) ['fn [x] body nil] (fn [arg] (interpereter body (fn [y] (if (= x y) arg (env y))))) :else (assert false (str "未能捕获 list:" expr)))) (match [expr] [(n :guard symbol?)] (env n) [(n :guard number?)] n :else (assert false (str "未能捕获元素:" expr))))) (interpereter '(((fn [!] (fn [n] ((! !) n))) (fn [!] (fn [n] (if (zero? n) 1 (* n ((! !) (dec n))))))) 5) (fn [e] (assert false (str "no such element.." e) ))) ``` |
10
FaiChou 2022-07-08 09:42:57 +08:00
<script src="https://gist.github.com/FaiChou/4572188fed132d545ab03c458455f509.js"></script>
|
12
zhuangzhuang1988 2022-07-08 10:16:15 +08:00
太动态了 ide 不友好
直接学 F#好还有 Fable 写前端. |
13
ca1123 OP @FaiChou 写各种求值器是很爽, 我看 Y 组合子的时候, 虽然匿名 recur 起来, 这个能接受, 但是最终的 arg 怎么送进去的, 还是有点蒙古. 感觉你可以整个更吊的, 把 if 也换成丘奇定义 IFTHENELSE := λp.λa.λb.p a b
另外, 我正好问你个问题, 宏展开的时候, 怎么把作为参数的 s-exp 组合到宏的模板里面, 然后再一股脑求值. 而不是把 s-exp 用~解了 syntax quote 以后就不管了. 比如 ``` (defmacro println-test [form] `(println ~form)) (let [form `(+ 3 1)] (println-test form)) ``` 我不要 ``` (clojure.core/+ 3 1) => nil ``` 我想要 ``` 4 => nil ``` 有不用 eval 的办法么, 套两层 defmacro 行么? |
14
ca1123 OP @zhuangzhuang1988 是的, 已经感觉到了. 但是我觉得我写 java 写着写着就迷失了, 就是因为 ide 指挥我怎么写代码
|
18
Dregs2 2022-07-08 12:27:59 +08:00 via Android
我之前也研究了好久,好像如果不用 eval 编译评估的话就要手动评估,宏应该只是在编译期生效,对于动态传入的 list 好像没法做到这种效果。
|
20
ca1123 OP @Dregs2 你说的对, 出现在 macro 定义里面的函数当场就求值了, 不会等到运行时. 在 runtime 里面, unquote 的时候, 这个部分处理过了, runtime 就去看别的地方了, 不会关注处理出来的值是不是还要求值, 就不会再处理了, 就相当于一个 quote. 我想要的是先 unquote, 和模板拼好, 然后再求值, 所以应该用 macroexpand-1 和参数上的 unquote 让 runtime 先拼模板, 模板拼好了, 一股脑丢给 eval 就行了. 主要是看别人说 eval 不好, 少用, 但是 eval 能用的特殊情况中其中一个用法就是 runtime 才知道参数内容.
|
21
1hscj3sm63 2022-07-08 16:14:54 +08:00
clj 搞一些函数式运算,还有研究宏造 DSL 还是很爽的,不过感觉平时业务都是搬砖,不太用的上
|
22
Dregs2 2022-07-08 17:38:56 +08:00 via Android
你发的例子中
(let [form `(+ 3 1)] (println-test form)) form 已经是是一个 list 在宏里面能拿到的也是这个 list ,没法通过宏来展开,运行时评估看起来还是得用 eval |
23
ca1123 OP @1hscj3sm63 我哭死, 我写不来 C 系的语言, 都是谭浩强的错
|
25
ca1123 OP @Dregs2 我今天又怼了一天 macro, 自定义 macro 组装 go-loop, 里面还有<!和作为传进来参数的 channel. 人都麻了. clojure 还真是有点问题, 数据结构上, 不像其它 lisp 是封闭的, clojure 很多数据本质是 java 对象, 包括语言本身的要素, 正向求值 fn 的时候没问题. 但是在 macro 里面如果, 就不能形成 clojure 代码的 closure. 如果 var 里面是一个 java object, 它也可以 unquote, 但是 eval 不认... 这时候就得手操 dynamic var, 或者 intern symbol, 或者 laziness (如果这个 object 其实是 clojure 代码产生的), 把 macro 里面 eval 要用的数据套一个 clojure var 的形式, eval 这个东西, 还不接受 lexical binding, fn 参数符号和 let 的符号都不认. 不过这个用 macro 接收 s-exp 拼一个能运行的 form 的目的总算有点眉目了.
|