【发布时间】:2021-01-15 17:12:28
【问题描述】:
我正在研究使用类似于 unix 的管道的球拍语法,如下所示:
> ("FOO" > string-replace "O" "E" > string-append "x" > string-downcase)
"feex"
这是一个蛮力解决方案,它支持带有 2、1 和 0(额外)参数的过程:
(require (prefix-in racket/base/ racket/base) syntax/parse/define)
(define-syntax-parser #%app
[(_ data (~literal >) proc a b (~literal >) rest ...) #'(#%app (proc data a b) > rest ...)]
[(_ data (~literal >) proc a (~literal >) rest ...) #'(#%app (proc data a) > rest ...)]
[(_ data (~literal >) proc (~literal >) rest ...) #'(#%app (proc data) > rest ...)]
[(_ data (~literal >) proc rest ...) #'(#%app proc data rest ...)]
[(_ rest ...) #'(racket/base/#%app rest ...)])
问题在于寻找下一个管道,因为语法模式不允许多个 ... 模式。宏需要知道下一个管道在哪里关闭第一个管道的表单。除非有办法用不匹配的括号构建部分语法对象?
我可以嵌套省略号,但是我必须使用额外的括号:
(define-syntax-parser #%app
[(_ data (~literal >) (proc params ...) > rest ...) #'(#%app (proc data params ...) > rest ...)]
[(_ data (~literal >) proc rest ...) #'(#%app proc data rest ...)]
[(_ rest ...) #'(racket/base/#%app rest ...)])
> ("FOO" > (string-replace "O" "E") > (string-append "x") > string-downcase)
"feex"
没有多余的括号有什么办法吗?
我知道 clojure 的线程宏,但如果你必须嵌套它们,它们就很难遵循。
编辑:这个问题的解决方案现在可以通过racket package 和github 获得
【问题讨论】:
标签: racket pointfree tacit-programming