我想在 Racket 中解析 JSON 文件,但我不知道如何处理这个问题,也找不到任何类似的例子。任何人都可以提供如何做到这一点的提示或示例吗?
我是计划新手,在使用 car 和 cdr 方面遇到困难。我在 ast 中有一个 AST 字符串文字。
(define ast '(program
((assign (var i int) (call (func getint void int) ()))
(assign (var j int) (call (func getint void int) ()))
(while (neq (var i int) (var j int))
((if (gt (var i int) (var j int))
((assign (var i int) (minus (var i int) (var j int))))
((assign (var j int) (minus (var j int) (var i int)))))))
(call (func putint int void) ((var i int)))))
)
Run Code Online (Sandbox Code Playgroud)
我知道汽车返回ast的头。所以 …
抱歉,我刚刚开始使用球拍。我对此很陌生。我写了这段代码:
(define (save_sheets lst num)
(if(= num (- (length lst) 1))
('())
(
(my_save_image (join_sheet (list-ref lst num)) num)
(save_sheets lst (+ num 1)))))
Run Code Online (Sandbox Code Playgroud)
当然,当我运行这个时,我收到以下错误:
application: not a procedure;
expected a procedure that can be applied to arguments
given: (object:image% ...)
arguments...: [none]
Run Code Online (Sandbox Code Playgroud)
(join_sheet (list-ref lst num))应该返回一个图像,错误显示该图像,但是my_save_image应该将其接收,对吗?它的参数是图像和数字。谢谢!
在球拍中,我知道有一个member函数会返回某个元素的第一次出现(如果存在)或#f其他情况,但是是否有一个函数仅返回#t或#f判断该元素是否存在于列表中?
foldr(fold-right) 基本上是按列表中存储的值从右到左的顺序执行递归计算。并且foldl是相反的foldr。我想知道人们可以foldr使用 来实现该功能foldl吗?任何想法都表示赞赏,提前致谢。
有没有一种方法可以将函数的关键字参数指定为字典,类似于.允许我们提供位置参数列表的方法?我正在寻找类似于 python 的*args 和 **kwargs的东西。
更详细地说:
如果我们想在函数中处理任意数量的位置参数,我们可以这样定义它:
(define (my-add . args)
(apply + args))
Run Code Online (Sandbox Code Playgroud)
并将其与可变数量的参数一起使用,如下所示:
(define numbers '(1 2 3))
(apply my-add numbers) ;=> 6
(define numbers '(1 2 3 4 5))
(apply my-add numbers) ;=> 15
Run Code Online (Sandbox Code Playgroud)
即使对于没有通过.语法显式处理位置参数的“其余”部分的函数,我们也可以使用它apply从列表中解包位置参数。
(apply expt '(2 3)) ;=> 8
Run Code Online (Sandbox Code Playgroud)
我发现除了位置参数之外,apply 它还转发关键字参数。但是,只有当调用的函数本身标识了它所期望的特定关键字参数时,这才有效。例如,在分派情况下,函数本身不使用关键字参数,而只是打算将它们转发到某个适当的处理程序,以这种方式使用 apply 并不能满足我们的需要,因为函数需要了解其分派到的任何函数接受的所有关键字参数,更不用说在调用处理程序之前以某种方式重新打包它们了。
作为说明该问题的具体示例,请考虑一个简单的“echo args”函数,该函数会回显传递给它的所有参数:
(define (echo-args . args)
(printf "~a" args))
Run Code Online (Sandbox Code Playgroud)
仅使用位置参数:
> (echo-args 1 2 5)
(1 2 5)
Run Code Online (Sandbox Code Playgroud)
使用关键字参数:
> …Run Code Online (Sandbox Code Playgroud) 我正在使用语法转换器在 Racket 中定义宏。我想创建一些辅助函数来帮助我操作语法。但是,我在语法转换器外部定义的函数在语法转换器内部不可用。例如,在下面的代码中
(define (my-function x) (+ x 1))
(define-syntax my-macro
(lambda (stx)
(datum->syntax stx (my-function (cadr (syntax->datum stx))))))
Run Code Online (Sandbox Code Playgroud)
我收到错误“我的函数:在阶段:1 处引用未绑定标识符;变压器环境”。
经过一番搜索后,我能够编写以下代码,以便my-function在语法转换器中可用。
(begin-for-syntax
(define (my-function x) (+ x 1)))
(provide (for-syntax my-function))
(define-syntax my-macro
(lambda (stx)
(datum->syntax stx (my-function (cadr (syntax->datum stx))))))
Run Code Online (Sandbox Code Playgroud)
但问题是,my-function这次在语法转换器之外不可用。有时我想在普通代码中检查这些辅助函数,因此我需要能够从语法转换器的内部和外部调用它,就像 function 一样cadr。我怎样才能做到这一点?
我知道我的问题与 Racket 的语法模型有关,特别是“阶段级别”的概念,但我从来没有真正理解它。如果您能提供一些易于理解的教程来解释它,我将更加感激。
我\xe2\x80\x99最近冒险进入了编写Scheme解释器的伟大领域,并且我\xe2\x80\x99遇到了一个障碍:闭包。据我了解,它们封装了一个本地环境,其中包含一个每次调用闭包时都会恢复的过程(这可能不完全正确)。我在网上任何地方都能找到的问题是如何正式定义闭包,即在 EBNF 语法中。我见过的大多数例子都说闭包是一个零参数的过程,它有一个嵌套在 let 表达式中的 lambda 表达式。这是定义Scheme闭包的唯一方法吗?更重要的是,如果\xe2\x80\x99s没有正式的方法来正式定义闭包,那么你实际上如何解释它?如果将所有 let 表达式转换为 lambda 会发生什么?例如,如果我这样声明一个闭包
\n(define (foo) (let ((y 0)) (\xce\xbb (x) (\xe2\x80\xa6))))\nRun Code Online (Sandbox Code Playgroud)\n然后将其赋值给一个变量
\n(define bar (foo))\nRun Code Online (Sandbox Code Playgroud)\n按什么顺序评估?从我\xe2\x80\x99所看到的,当foo声明时,它存储一个指向父环境的指针,并声明它自己的环境。如果我调用(bar),我应该立即替换到保存的本地环境中吗?
我很困惑 S-Expression 不是什么?
在scheme/racket中,任何带有define的东西都不是S表达式:
(define a 2)
(define (my-print x)
(println x))
Run Code Online (Sandbox Code Playgroud)
或者也许这只是不评估“价值”的事情?喜欢导入和评论吗?:
#lang racket/base
; and comments?
Run Code Online (Sandbox Code Playgroud)
我不确定我是否真的理解哪些东西不符合 s 表达式?
只是想更好地理解 S 表达式。
(equal? \'(1 2) (cons 1 2)) ; #f\nRun Code Online (Sandbox Code Playgroud)\n为什么这两个不等价,考虑到列表只是建立在 cons cells 之上的 \xe2\x80\x94 幻觉。
\n