如何在最后放置 Lisp/Scheme/Racket 符号?

How to put Lisp/Scheme/Racket symbol at the end?

Lisp/Scheme/Racket 中的表格将符号放在第一个位置。此代码适用于 Racket:

(define (? a b) (if a (display b) 0))
(? #t "Hello")

但我想在C/C++中模拟a? b:0语句,问号(符号)应该在最后,在a之后。

如何把?ab按这个顺序排列?

(define (a ? b) (if a (display b) 0))
(#t ? "Hello")

我需要使用 define-syntax 之类的东西吗?

你的问题我有三个答案。

1 不要那样做

每种语言都有规则、惯例和语用学。如果你试图强迫它看起来像 C/C++,你的 Racket 体验将会很痛苦。你会在这样的问题上浪费时间,而不是学习在 Racket 编程模型中思考并使用 Racket 围绕该模型开发的工具。

对于一个具体的例子,Racket 有一个规则,即一个形式(表达式、定义、声明等)以 运算符 开头(如 displaylist+) 或 语法关键字 (如 defineif)。该规则消除了许多妨碍可扩展语法的复杂问题。例如,与其他特殊形式相比,中缀语法的优先级是什么?在 (lambda ? 5) 中,是 lambda 形式还是(错误的)? 形式?

澄清一下:Racket 绝对鼓励您在 S 表达式、运算符优先语法的范围内使用新的语法形式扩展语言。

2 部分解决方案

Racket 的 reader 对 "infix syntax" 的支持形式有限。如果您在带括号的组中的单个术语周围加上点,reader 会将括起来的术语移到前面。因此 reader 将以下两个术语视为相同:

(1 . < . 2)
(< 1 2)

所以你可以这样写

(#t . ? . "Hello")

就个人而言,我认为这通常会使代码更难阅读。

3 个开放研究课题

人们正在研究扩展 Racket 的语言构建框架,以便与基于非 S 表达式的语法很好地协同工作。一个例子是 Honu;请参阅论文 "Honu: Syntactic Extension for Algebraic Notation through Enforestation。还有其他的,话题还没完呢

让我通过覆盖应用程序语法来提供替代解决方案 #%app。下面是类 C 语言中的三元运算符示例:

#lang racket

(require syntax/parse/define
         (only-in racket [#%app racket:#%app]))

(define-syntax-parser #%app
  [(_ test-expr {~datum ?} then-expr {~datum :} else-expr)
   #'(if test-expr then-expr else-expr)]
  [(_ xs ...)
   #'(racket:#%app xs ...)])
> ((= 42 42) ? "a" : "b")
"a"
> ((= 42 0) ? "a" : "b")
"b"

因为应用语法的优先级最低,所以会优先考虑其他语法:

> (define-simple-macro (discard-all xs ...) 1)
> (discard-all ? 42 : 123)
1
> (if ? 1 : 2)
if: bad syntax ;; because if should have exactly three subforms, but the above line has four.

但正如 Ryan 所说,从某种意义上说,这不是 "good" Racket 代码,因为它违背了 Racket 惯例,没有人(嗯,可能除了你)能够理解你的代码。