大括号 {} 替换 Racket 中的“开始”

2024-04-22

是否可以有一个宏,使用大括号{}来表示一个语句块,从而替换'begin'关键字。因此,代替:

(if (condition)
    (begin 
        (statement1)
        (statement2)
        (statement3)
        (statement4))
    (else-statement))

我们可以使用:

(if (condition) {
        (statement1)
        (statement2)
        (statement3)
        (statement4) }
    (else-statement))

如何才能做到这一点?感谢您的回答。


这是完全可能的,并且有多种方法可以做到。 (在开始之前快速说明,我将使用block http://docs.racket-lang.org/reference/block.html代替begin因为它在内部定义中表现得更好。)

方法一:重新定义#%app

一种稍微有点 hack 的方法是重新定义函数应用的含义,以便对大括号进行特殊处理。您可以通过定义一个来做到这一点#%app macro:

#lang racket
(require racket/block syntax/parse/define (prefix-in - racket))
;; This #%app macro redefines what function application means so that
;; { def-or-expr ... } expands into (block def-or-expr ...)
;; Otherwise it uses normal function application
(define-syntax-parser #%app
  [{_ def-or-expr:expr ...}
   #:when (equal? #\{ (syntax-property this-syntax 'paren-shape))
   ;; group them in a block
   #'(block def-or-expr ...)]
  [(_ f:expr arg ...)
   #:when (not (equal? #\{ (syntax-property this-syntax 'paren-shape)))
   ;; expand to the old #%app form, from (prefix-in - racket)
   #'(-#%app f arg ...)])
;; using it:
(define (f x)
  (if (< 5 x) {
        (define y (- x 5))
        (f y)
      }
      x))
(f 1) ; 1
(f 5) ; 5
(f 6) ; 1
(f 10) ; 5
(f 11) ; 1

方法2:扩展阅读器

另一种方法是定义一个新的#lang语言并使用不同的条目扩展可读表{特点。让我去这样做......

定义一个#lang语言,您需要将阅读器实现放入your-language/lang/reader.rkt。这就是curly-block/lang/reader.rkt,其中curly-block目录作为单个集合包安装(raco pkg install path/to/curly-block).

卷曲块/lang/reader.rkt

;; s-exp syntax/module-reader is a language for defining new languages.
#lang s-exp syntax/module-reader
racket
#:wrapper1 (lambda (th)
             (parameterize ([current-readtable (make-curly-block-readtable (current-readtable))])
               (th)))

;; This extends the orig-readtable with an entry for `{` that translates
;; { def-or-expr ... } into (block def-or-expr ...)
(define (make-curly-block-readtable orig-readtable)
  (make-readtable orig-readtable
    #\{ 'terminating-macro curly-block-proc))

;; This is the function that the new readtable will use when in encounters a `{`
(define (curly-block-proc char in src ln col pos)
  ;; This reads the list of things ending with the character that closes `char`
  ;; The #f means it uses the racket reader for the first step, so that `{`
  ;; uses the normal behavior, grouping expressions into a reader-level list
  (define lst (read-syntax/recursive src in char #f))
  (cons 'block lst))

使用它:

#lang curly-block
(require racket/block)
(define (f x)
  (if (< 5 x) {
        (define y (- x 5))
        (f y)
      }
      x))
(f 1) ; 1
(f 5) ; 5
(f 6) ; 1
(f 10) ; 5
(f 11) ; 1
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

大括号 {} 替换 Racket 中的“开始” 的相关文章

  • 一个拼接语法类,匹配可选模式并绑定属性

    我的拼接语法类定义如下 语法类匹配两个语句 第一个模式 其中一个语句 第三个和第二个模式 的序列 甚至可能根本不匹配这些语句 最后一个模式 正如您所看到的 有相当多的 重复 代码 因为每个模式要么返回模式中捕获的某些内容的属性 要么返回空的
  • 方案作业

    当我每次得到值 10 时评估以下表达式 lambda x lambda set x x 10 x 0 不过 我只是通过用名称抽象上述过程来进行修改 并在每次值增加 10 时调用 foo define foo lambda x lambda
  • 有没有办法检查一个列表的所有元素是否都包含在球拍的另一个列表中?

    我想要一个执行类似操作的函数 gt function 1 2 3 4 1 2 3 4 5 t 在这种情况下返回 t 因为第一个列表的所有元素都包含在第二个列表中 有没有一个函数可以做到这一点而不必担心顺序 在这种情况下 您不会将列表进行比较
  • 在Scheme中编写一个自动记忆器。有关宏和包装器的帮助

    我在Scheme中编写自动记忆器时遇到了一些问题 我有一个有效的 memoize 函数 它创建一个哈希表并检查该值是否已经计算出来 如果之前已经计算过 则返回值 否则调用该函数 define memoizer fun let a table
  • 方案let语句

    在函数式编程语言scheme中 没有赋值语句 但在一个let陈述 let x 2 x 3 您正在分配2 to x 那么为什么这不违反函数式编程中没有赋值语句的原则呢 Scheme 是一种函数式编程语言 这一说法是不正确的 在Scheme中
  • 对方案中的列表进行排序

    如何编写一个排序算法 以升序返回列表 ex 1 3 5 2 9 回报 1 2 3 5 9 大多数Scheme 实现都附带一个对列表进行排序的过程 如果您的实现没有提供这一功能 那么为您提供一个并不困难 下面是快速排序算法的实现 gt def
  • Scheme/Racket有枚举操作吗?

    Scheme Racket 是否有相当于 Haskell 中的 a b 表示法的枚举表示法 在 Haskell 中 1 5 计算结果为列表 1 2 3 4 5 for list i in range 1 6 i sequence gt li
  • 查找 lambda 表达式中的自由变量

    有谁知道如何找出 lambda 表达式中的自由变量 自由变量是不属于 lambda 参数的变量 我当前的方法 这对我毫无帮助 是简单地使用 car 和 cdr 来遍历表达式 我的主要问题是确定一个值是否是一个变量或者它是否是方案原语之一 有
  • 在Scheme中插入二叉树

    我想知道如何将列表中的元素插入二叉搜索树 我想知道为什么下面的代码不能按我的预期工作 输出是 4 1 5 13 6 我的下一个问题是对列表中的元素进行排序 但现在我只想插入它们 我的输出对于我所说的问题是否正确 我的代码如下 define
  • 为什么我的 Scheme 函数返回错误“应用程序:不是过程”?

    我想获得 a b c 的第二个值 但我不想使用 cadr 我可以得到正确的答案 car cdr a b c b 但是当我构建该函数时 define test lambda list car cdr list test a b c 我收到以下
  • (Chez) 用于隐藏 lambda 的方案宏

    我想编写一个宏来创建速记语法来隐藏更详细的 lambda 表达式 但我很难理解如何编写宏 我意识到这是反对使用它们的一个论据 给出这个例子 define alist example x 1 2 3 y 4 5 6 z 7 8 9 defin
  • 经验丰富的计划者的 get-first、get-next 和 waddle 函数

    define get first lambda l call with current continuation lambda here set leave here waddle l leave quote define get firs
  • 方案功能[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我试图解释这个方案函数的作用 define y s lis cond null lis equal s car lis lis else
  • 方案语言:合并两个数字

    如何将列表中的两个整数合并为一个 方案中 例子 11 223 gt 11223 假设列表恰好有两个元素 并且都是数字 define merge numbers lst let 1st number gt string first lst 2
  • Scheme 和 Racket 中嵌套引号的行为

    在 Racket 中编写函数时 我不小心在符号前面放了两个单引号而不是一个 即我不小心写了 a 并发现嵌套引号的一些行为看起来很奇怪 我正在使用 DrRacket 并使用 Racket lang 和 R5RS lang 对此进行了测试 wr
  • 方案字符串追加?递归复制字符串

    设计一个名为 string dup 的程序 它使用一个字符串 s 和一个数字 n 并返回一个由 s n 次连接而成的字符串 每个 s 实例之间有空格 即 string dup a 3 gt a a a 不使用复制 但我想我们可以使用字符串追
  • 如何在球拍中查看扩展宏?

    我得到了这个答案https stackoverflow com a 70318991 https stackoverflow com a 70318991关于编写一个简单的宏来记录宏扩展时的时间 然后始终返回该时间 lang racket
  • 从when语句内的函数返回

    我想做的就是使用 when 语句返回一个值 我想要以下功能 if x return y 我正在尝试使用 when x y 但是when语句并没有以退出函数并返回y的方式进行计算 它只是愉快地继续下一行 有没有办法做到这一点而不需要制作一个看
  • 在Racket中将结构递归转化为累积递归

    我有一些代码来查找最大高度并将其替换为关联的名称 身高和姓名有单独的列表 每个列表的长度相同且非空 我可以使用结构递归来解决这个问题 但必须将其更改为累积递归 而且我不确定如何做到这一点 我见过的所有例子都让我困惑 有人能够将代码变成使用累
  • 学习 LISP 的最佳方法是什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi

随机推荐

  • 将硬编码文件路径更改为 VBA 中提示的用户?

    现在 我有一个用于 Word 的 VBA 宏 它可以解析文档中的某种字体 并将所选类型的所有字体输出到文本文件 我打开文本文件的硬编码行是这样的 Open C Documents and Settings Output txt For Ou
  • 实现共享功能的标准方法

    我需要在 iOS 中实现 共享为 功能 例如 一个按钮名为 共享为 并弹出一个对话框 其中包括电子邮件 短信 Facebook Twitter 等项目 我想知道是否有一个标准对话框可以完成这项工作 经过搜索 我发现在 iOS6 中使用 UI
  • 如何使用 C 客户端通过 ActiveMQ 启用 SSL

    我已经配置了 ActiveMQ http activemq apache org http activemq apache org 通过以下方式使用 ssl 上下文RedHat 的 SSL TLS 教程 https access redha
  • HTML 树全宽悬停效果

    我有一个 html 树 主要由嵌套的无序列表组成 我需要为每个叶子创建全宽悬停效果 类似于 Windows 文件菜单树悬停效果 悬停效果是 div div 具有背景颜色和边框 我做了一个模拟全宽度的黑客 但侧面边框不再可见 我可以使用 CS
  • C++/CLI:CA2123:需要 SecurityCriticalAttribute?

    我对这样的错误有点迷失 警告 7 CA2123 Microsoft Security 添加以下安全属性 到 RithmicConnector 连接 字符串 为了匹配基地的 LinkDemand 方法 IConnector Connect S
  • 如何向 Monaco 编辑器添加新的语言语法?

    我添加了我的语言并按照此处的说明进行构建https github com Microsoft monaco languages https github com Microsoft monaco languages npm run prep
  • 选择日期最高的行

    我的表中有一些重复的值 我只想选择那些具有最新 最高日期的值 即 ID Type Name Value Date 1 FRUIT APPLE Imported 2011 03 19 22 08 13 5 FRUIT LEMON Import
  • Promise.all:解析值的顺序

    看着MDN https developer mozilla org en US docs Web JavaScript Reference Global Objects Promise all它看起来像values传递给then Promi
  • C 基本头命令

    我正在尝试为我的编程课从 Linux 重新创建 head 和 tail 命令 我们刚刚开始使用 C 所以我对分配内存和指针的想法很陌生 我想知道为什么这不起作用 include
  • C#:如何将 long 转换为 ulong

    如果我尝试使用 BitConverter 它需要一个字节数组 但我没有 我有一个 Int32 我想将其转换为 UInt32 在 C 中这没有问题 您只需要一个简单的演员阵容即可 由于这样做可能会丢失精度 因此转换是显式的 long x 10
  • 将具有 key=value 对的字符串解析为 JSON

    我的节点应用程序接收以下格式的一系列字符串 a x b y c z 即包含多个空格分隔的字符串key value pairs 将此类字符串转换为以下形式的 JSON 对象的最巧妙方法是什么 a x b y c z 我打赌有一个单行解决方案
  • Spring Boot - 无法从 application.properties 在 xml 中解析属性

    我有一个 Spring Boot 应用程序 My Configuration class使用加载 xml 配置 ImportResource path to xml 其中包含以下行
  • 自动链接:地图如何工作

    我在用TextView 的 android autoLink map 属性转到地图并查找与该文本视图关联的地址 但它的行为很奇怪只找到一些地址 这是我正在尝试的代码
  • 使用 webpack 生成捆绑 TypeScript 定义文件

    我目前正在使用 gulp 来生成我的包的定义文件 如下所示 dtsGenerator default name ngFramework project out Typings raw index d ts 但是 我正在迁移到 webpack
  • 在 Selenium 中捕获 JavaScript 错误

    有没有办法捕获发生的错误DOM in Selenium并且可能与页面中的错误标记相同 举一个简单的例子 假设我试图在一个不存在的 HTML 控件上绑定一个事件 我的浏览器会抛出一个错误 element abcd not found in t
  • pyqt5不显示窗口[重复]

    这个问题在这里已经有答案了 我真的希望有人能帮助我解决这个问题 我正在尝试开始使用pyqt5 并且几乎从我正在学习的课程中复制了这段代码 代码似乎执行没有任何问题 但我应该看到的窗口根本没有出现 我做错了什么 我正在尝试ubuntu 18顺
  • Pycharm交互式控制台不起作用

    我对 python 和 Pycharm 都很陌生 因此 请毫不犹豫地指出我哪里做错了以及如何解决问题 问题是IPython无法像往常一样导入我想要执行的函数 即使 python 文件运行后 我也无法在 IPython 控制台中导入该文件中的
  • 我收到内存异常“System.IO.out of exception”错误

    对于小目录大小 代码工作正常 当目录文件大小很大时 它会给出此错误消息 我的代码 IEnumerable
  • 首选项列表仅显示第一个元素

    我正在开发一个PreferenceActivity与定制Preference意见 我的问题是我创建了一个视图ListView它只显示第一个元素 我发布我的代码和图像 http imageshack us photo my images 54
  • 大括号 {} 替换 Racket 中的“开始”

    是否可以有一个宏 使用大括号 来表示一个语句块 从而替换 begin 关键字 因此 代替 if condition begin statement1 statement2 statement3 statement4 else stateme