这不是重复的
set-car!, set-cdr! unbound in racket?或
的
Implement SICP evaluator using Racket
或的
How to install sicp package module in racket?,
而是一个后续问题,因为其中提出的解决方案没有
为我工作。首先,需要:SICP的5.5.5节,编译器加上
显式控制评估器(code here in "ch5-eceval-compiler.scm")是
完全依赖set-car!
和set-cdr!
到显式引用列表中。一世
想要复制和修改此代码,而无需完全自下而上的重写
不变的形式。我也会接受对可以实现的方案实现的引用
开箱即用地运行代码,或进行一些最少,直接的修改,
即具有set-car!
和set-cdr!
或某些
解决方法。狡猾的人和球拍都无法让我轻松地运行此代码。
EDIT :mit方案将加载eceval编译器。我把问题留给那些可能想要用球拍打发的人(例如,我更愿意)。
这里有更深入的解释,包括我探索和尝试过的东西,以及
我如何将报价单诊断为最深层的问题。当我手动转换时
将引号列表放入mquoted
的{{1}}嵌套中,代码崩溃的情况更糟
方式和兔子洞变得更深了。我经过几次
数小时的精细脑部手术失败了。
这是5.5.5节所依赖的那种MVE。这很小,但结构上像真实的东西:
mlists
真实的东西是这样开始的:
(define foo '(a b))
(set-cdr! foo '(c))
并持续了一段时间。评估者是引号中的“机器代码”
列表,各种生成的代码会将(define eceval
(make-machine
'(exp env val proc argl continue unev
compapp ;*for compiled to call interpreted
)
eceval-operations ;; ----------------------------------------------
'( ;; <<<<<<<<======== BIG QUOTED LIST CAUSING TROUBLE / NOT MCONSES!
;;SECTION 5.4.4, as modified in 5.5.7 ;; -------------------------------
;;*for compiled to call interpreted (from exercise 5.47)
(assign compapp (label compound-apply))
;;*next instruction supports entry from compiler (from section 5.5.7)
(branch (label external-entry))
read-eval-print-loop
(perform (op initialize-stack))
(perform
(op prompt-for-input) (const ";;; EC-Eval input:"))
...
和set-car!
写入寄存器
和环境框架等。代码加载失败。
似乎没有简单的方法可以将评估程序转换为不可变形式
没有完整的重写,我正在努力避免这种情况。当然,set-cdr!
和
set-car!
中没有set-cdr!
,我认为它们不在
guile,或者(至少guile拒绝加载“ ch5-eceval-compiler.scm”,
抛出一个可变性错误,对此我没有做更深入的研究。
在
set-car!, set-cdr! unbound in racket?是
根据{{1}}使用#lang racket
,mcons
,mcar
等重写代码。那些兼容性
软件包无法替代mlist
,因此我尝试编写自己的(require
compatibility/mlist) (require rnrs/mutable-pairs-6)
。一世
在这样的重构上花了几个小时,但是练习没有
会聚,只是越来越深地钻入兔子洞,最后变成
更深层次的问题。看来即使要进行重构,我也必须
了解有关“ ch5-eceval-compiler.scm”的更多语义,并且如果必须的话,我
最好以不变的形式重写它。
在
set-car!, set-cdr! unbound in racket?
使用quote
或mquote
。以下三个实验
引用了堆栈溢出的其他答案:
#lang sicp
#lang r5rs
指向明确定义#lang r5rs
(define foo '(a b))
(set-cdr! foo '(c))
foo
的地方:
Error: struct:exn:fail:contract:variable
set-cdr!: undefined;
cannot reference an identifier before its definition
in module: "/usr/share/racket/pkgs/r5rs-lib/r5rs/main.rkt"
-----------------------------------------------
这里是set-cdr!
的类似失败
...
(module main scheme/base
(require scheme/mpair
racket/undefined
(for-syntax scheme/base syntax/kerncase
"private/r5rs-trans.rkt")
(only-in mzscheme transcript-on transcript-off))
(provide (for-syntax syntax-rules ...
(rename-out [syntax-rules-only #%top]
[syntax-rules-only #%app]
[syntax-rules-only #%datum]))
(rename-out
[mcons cons]
[mcar car]
[mcdr cdr]
[set-mcar! set-car!] ;; --------------------------
[set-mcdr! set-cdr!] ;; <<<<<<<<======== LOOK HERE
[mpair? pair?] ;; --------------------------
[mmap map]
[mfor-each for-each])
= < > <= >= max min + - * /
abs gcd lcm exp log sin cos tan not eq?
call-with-current-continuation make-string
symbol->string string->symbol make-rectangular
exact->inexact inexact->exact number->string string->number
...
#lang sicp
指向仅间接定义#lang sicp
(define foo '(a b))
(set-cdr! foo '(c))
foo
的代码,但在
合适的包装:
Error: struct:exn:fail:contract:variable
set-cdr!: undefined;
cannot reference an identifier before its definition
in module: "/home/rebcabin/.racket/7.2/pkgs/sicp/sicp/main.rkt"
----------------------------------------------------
我深入研究 Implement SICP evaluator using Racket 并找到
set-cdr!
屈服
.... #lang racket (require racket/provide ;; -------------------------------------------- (prefix-in r5rs: r5rs) ;; <<<<<<<<======== PULL IN SET-CDR! ETC. HERE? (rename-in racket [random racket:random])) ;; ------------------------ (provide (filtered-out (λ (name) (regexp-replace #px"^r5rs:" name "")) (except-out (all-from-out r5rs) r5rs:#%module-begin)) (rename-out [module-begin #%module-begin])) (define-syntax (define+provide stx) (syntax-case stx () [(_ (id . args) . body) #'(begin (provide id) (define (id . args) . body))] [(_ id expr) #'(begin (provide id) (define id expr))])) ...
此错误表示问题确实出在引用列表上。我没有
简单的方法可以将eceval中的大引用列表变成(require (only-in (combine-in rnrs/base-6
rnrs/mutable-pairs-6)
set-car!
set-cdr!))
(define foo '(a b))
(set-cdr! foo '(c))
foo
或
Error: struct:exn:fail:contract
set-mcdr!: contract violation
expected: mpair?
given: '(a b)
argument position: 1st
other arguments...:
'(c)
。我尝试过,它非常冗长且容易出错,而且我认为代码
加载eceval扫描和列出的补丁程序,因此它使用其他列表操作。
我走南路后不得不退缩。
也许我错过了一种自动化转换的方法,一个宏,但这是一个 兔子洞较深(我的宏宏方案太旧了。)
所以我被困住了。没有简单或推荐的作品。我想要么(1)知道一个方案实现,它将运行此代码(2)我可以在球拍(3)中实现mlist
和mcons
的某种方式(4) ),或者我只是犯了一个愚蠢的错误,其中一个人很容易修复。
答案 0 :(得分:2)
我尝试过(通过直接运行racket
或通过DrRacket运行它)
#lang sicp
(define foo '(a b))
(set-cdr! foo '(c))
foo
并输出(a c)
。
这也有效:
#lang r5rs
(define foo '(a b))
(set-cdr! foo '(c))
(display foo)
要回答有关SICP的实施问题(我目前正在维护),您正确的认为(prefix-in r5rs: r5rs)
将导入set-cdr!
。
更新:我刚刚安装了Geiser,现在遇到的问题与您C-c C-b
时遇到的问题相同。但是,C-c C-a
可以正常工作。
我个人会使用racket-mode
而不是Geiser。
答案 1 :(得分:0)
Mit-scheme将根据问题中提到的代码加载eceval编译器。在Ubuntu上,mit-scheme加载sudo apt-install mit-scheme
。 geiser package of emacs通过run-mit
查找信息。问题解决了。