Scheme 是否可以更改DrRacket/方案搜索/参考库的顺序?

Scheme 是否可以更改DrRacket/方案搜索/参考库的顺序?,scheme,racket,sicp,Scheme,Racket,Sicp,我按照SICP第3.3.3节的说明创建一个表 这里是code\u 0.scm: ;code_0.scm #lang scheme (require rnrs/base-6) (require rnrs/mutable-pairs-6) (define nil '()) (define (make-table) (list '*table*)) (define (assoc key records) (cond ((null? records) false)

我按照SICP第3.3.3节的说明创建一个表

这里是
code\u 0.scm

;code_0.scm
#lang scheme
(require rnrs/base-6)
(require rnrs/mutable-pairs-6)

(define nil '())

(define (make-table)
  (list '*table*))

(define (assoc key records)
  (cond ((null? records)
         false)
        ((equal? key (caar records))
         (car records))
        (else
         (assoc key (cdr records)))))

(define (insert! key value table)
  (let ((record (assoc key (cdr table))))
    (if record
        (set-cdr! record value)
        (set-cdr! table
                  (cons (cons key value)
                        (cdr table)))))
  'OK)

(define (lookup key table)
  (let ((record (assoc key (cdr table))))
    (if record
        (cdr record)
        false)))


(define table (make-table))

(insert! 0 0 table)
(insert! 1 1 table)
(insert! 2 2 table)
#lang scheme
(require rnrs/base-6)
(require rnrs/mutable-pairs-6)
code\u 0.scm
运行良好,但在成为
code\u 1.scm
的外部参考文件后,情况并非如此:

;code_0.scm
#lang scheme
(require rnrs/base-6)
(require rnrs/mutable-pairs-6)

(define nil '())

(define (make-table)
  (list '*table*))

(define (assoc key records)
  (cond ((null? records)
         false)
        ((equal? key (caar records))
         (car records))
        (else
         (assoc key (cdr records)))))

(define (insert! key value table)
  (let ((record (assoc key (cdr table))))
    (if record
        (set-cdr! record value)
        (set-cdr! table
                  (cons (cons key value)
                        (cdr table)))))
  'OK)

(define (lookup key table)
  (let ((record (assoc key (cdr table))))
    (if record
        (cdr record)
        false)))


(define table (make-table))

(insert! 0 0 table)
(insert! 1 1 table)
(insert! 2 2 table)
#lang scheme
(require rnrs/base-6)
(require rnrs/mutable-pairs-6)
);此时,我在
code\u 0.scm
删除了
#lang方案

;code_1.scm
#lang scheme/load
(load "code_0.scm")

(define table-0 (make-table))
(insert! 0 0 table-0)
(insert! 1 1 table-0)
(insert! 2 2 table-0)
DrRacket中显示错误:

assoc:不是正确的列表:{{0.0}

据我所说,这是因为“assoc”函数已经在Scheme库(或DrRacket库?)中定义了,编译器选择链接标准/系统库,而不是我的

那么,是否可以更改DrRacket/方案搜索/参考库的顺序

如果是,怎么做

如果不是,这是编译器的缺陷还是语言的缺陷


如果我必须构建名称复制函数,除了在“主”文件中实现它之外,还有其他方法可以避免这种情况吗?

在DrRacket中运行您的文件时,我没有发现任何错误。您加载的
文件可能是上一个问题中的旧文件。这是唯一合乎逻辑的结论,因为这里列出的文件中没有一个使用
assoc
,而旧文件使用

把计划和拍子混为一谈是不可取的
#lang scheme
(或
#!scheme
)是
#的旧名称!racket现在可以导入
#中当前的所有符号!球拍
和你的
要求
声明是除此之外的

rnrs
下的库将由R6RS语言使用,因此第一行应该是
#!r6rs
而不是要求您使用
(导入(rnrs基)(rnrs可变对))
。在R6RS中,您可以导入除某些符号之外的其他符号。例如,
(导入(除了(rnrs基本)cons))
不导入
cons
,而是导入其他所有内容。我没有使用
assoc
,因为
(rnrs-base)
中没有
assoc
,也没有
(rnrs-mutable对)
,所以它可能来自
#!方案
#!球拍

如果您计划将词典用作库,可以将其设置为R6RS库并导入,而不是使用
load


还要注意,球拍中也有一个。它基于
#!r5rs
以及本书中的大多数示例也很有效

您看到的错误
assoc:不是一个正确的列表:{{0.0}
需要解释

在Racket语言中,您可以使用
cons
创建不可变对,使用
mcons
创建可变对。通常在Scheme语言
cons
中也会创建不可变的对-但是因为您有行

(require rnrs/base-6)
(require rnrs/mutable-pairs-6)
(require rnrs/base-6)
(require rnrs/mutable-pairs-6)
所有标准列表函数都将替换为创建可变函数的函数

请注意,可变和不可变对是两种完全独立的数据类型,尽管它们都称为对

在系统的某个地方有定义的原语,例如,
prim mcon
prim icons
,它们创建可变和不可变的对。
#lang方案
cons
绑定到
prim mcons
#lang racket
cons
绑定到
prim图标

这对列表上的所有标准函数都有影响。来自rnrs/mutable-pairs-6的
assoc
需要一个由可变对组成的列表,而Racket
assoc
需要一个由不可变对组成的列表。因此出现了错误

你怎么能发现这个?在Racket语言中,您可以同时使用
mcons
cons
标准列表操作创建具有不可变对的列表,打印机使用
(…)
打印它们。可变对用大括号打印
{…}

错误

assoc: not a proper list: {{0 . 0}}
显示带大括号的关联列表。这意味着关联列表是使用可变对在方案中创建的

要解决问题,您需要使用正确的
assoc
。您可以通过添加行来实现这一点

(require rnrs/base-6)
(require rnrs/mutable-pairs-6)
(require rnrs/base-6)
(require rnrs/mutable-pairs-6)
到您的第二个文件

注意:
#lang scheme
语言不是RnRS方案之一,而是Racket在项目更改名称之前使用的方言


注2:为什么球拍一开始就消除了双人球拍的可变性?嗯,在写得很好的方案代码中,很少看到
设置汽车
设置cdr正在使用中。保证一对不会发生变异,可以进行各种优化,使大多数程序运行得更快(对于一个
长度
,可以使用恒定时间来实现)。因此,我们选择将不可变对作为标准,并为那些绝对需要它们的程序保留可变对。

这不是对您的问题的直接回答,而是对 你把自己弄得一团糟最终导致了这个问题, 也会导致其他问题

我将首先简要地解释Racket如何评估模块, 因为这与理解混乱有关。看起来你是 尝试使用“公正方案”,所以你可能对它不太感兴趣 但是你还是应该阅读它来理解你所面临的问题。 (即使你解决了那个问题。)

.rkt
文件的通常情况下,每个文件都在其自身中进行评估 名称空间,该名称空间由来自(1)您使用的
#lang
的绑定填充 指定和(2)您
需要的各种库(=其他模块)
。 所以当你有

#lang foo
(require bar)
从新名称空间开始,从
foo
然后从
bar
添加绑定。万一 在冲突中,
require
绑定将隐藏语言中的冲突, 因此,如果它们都提供了一些函数
f
,那么您的代码 将使用的将是f