Functional programming 如何将Lisp/Scheme/Racket符号放在末尾?

Functional programming 如何将Lisp/Scheme/Racket符号放在末尾?,functional-programming,scheme,lisp,racket,infix-notation,Functional Programming,Scheme,Lisp,Racket,Infix Notation,Lisp/Scheme/Racket中的表单将符号放在第一个位置。此代码适用于球拍: (define (? a b) (if a (display b) 0)) (? #t "Hello") 但是我想模拟a?b:C/C++中的0语句,以及符号应该位于末尾的问号,在a之后 如何放置?a和b的顺序是什么 我需要使用define语法或类似的东西吗?对于你的问题,我有三个答案 不要那样做 每种语言都有规则、惯例和语用学。如果你试图强迫它看起来像C/C++,你的球拍体验将是痛苦的。您将在此类问题上浪费时

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

(define (? a b) (if a (display b) 0))
(? #t "Hello")
但是我想模拟a?b:C/C++中的0语句,以及符号应该位于末尾的问号,在a之后

如何放置?a和b的顺序是什么


我需要使用define语法或类似的东西吗?

对于你的问题,我有三个答案

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

例如,Racket的规则是,表达式、定义、声明等的表单以类似display或list的运算符或+或类似define或if的语法关键字开头。该规则消除了妨碍可扩展语法的许多复杂问题。例如,中缀语法相对于其他特殊形式的优先级是多少;在拉姆达?那是lambda表还是坏表?形式

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

2部分解 Racket的阅读器对中缀语法的支持形式有限。如果在括号中的单个术语周围加上点,读者会将所附术语移到前面。因此,读者对以下两个术语的处理是相同的:

(1 . < . 2)
(< 1 2)
我个人认为,这通常会使代码更难阅读

3开放性研究课题
人们正在研究如何扩展Racket的语言构建框架,以便与基于非s表达式的语法配合使用。一个例子是Honu;看报纸。还有其他问题,这个话题仍然没有定论。

我对你的问题有三个答案

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

例如,Racket的规则是,表达式、定义、声明等的表单以类似display或list的运算符或+或类似define或if的语法关键字开头。该规则消除了妨碍可扩展语法的许多复杂问题。例如,中缀语法相对于其他特殊形式的优先级是多少;在拉姆达?那是lambda表还是坏表?形式

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

2部分解 Racket的阅读器对中缀语法的支持形式有限。如果在括号中的单个术语周围加上点,读者会将所附术语移到前面。因此,读者对以下两个术语的处理是相同的:

(1 . < . 2)
(< 1 2)
我个人认为,这通常会使代码更难阅读

3开放性研究课题
人们正在研究如何扩展Racket的语言构建框架,以便与基于非s表达式的语法配合使用。一个例子是Honu;看报纸。还有其他问题,这个主题仍然没有解决。

让我通过重写应用程序语法来提供另一种解决方案。下面是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 ...)])
由于应用程序语法的优先级最低,因此将首先考虑其他语法:

> (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所说,从某种意义上说,这不是一个好的Racket代码,因为它违反了Racket约定,没有人能理解您的代码,除非您能够理解您的代码。

让我通过重写应用程序语法来提供另一种解决方案。下面是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 ...)])
由于应用程序语法的优先级最低,因此将首先考虑其他语法:

> (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所说,从某种意义上说,这不是一个好的敲打代码,因为它违背了敲打惯例,没有人能理解你的代码,除非你能理解你的代码。

可以想象使用特殊的帕伦来表示这种允许使用中缀的上下文。例如{语言名称……}。这将使它明确无误。tks,我知道这破坏了规则,但只是尝试一下:可以想象使用特殊类型的paren来表示这种允许中缀的上下文。例如{语言名称……}。tks,我知道这会破坏规则,但只是尝试一下:tks,这是我想要的语法错误模块:标识符的重复定义当我尝试使用define syntax parser定义第二个语法时,我发现了如何使用define syntax parser,不能使用两次,将所有语法放在同一个define syntax parser块中
ks,这是我想要的语法错误模块:标识符的重复定义当我尝试使用define syntax parseri定义第二个语法时,我发现了如何,不能使用define syntax parser两次,将所有语法放在同一define syntax parser块中