DrRacket не запускает функцию Аккермана из упражнения SICP 1.10

Недавно я начал читать SICP и делать упражнения в книге. Я установил обе схемы mit в командной строке и, немного поработав с ней, наткнулся на DrRacket и установил компоненты SICP из http://www.neilvandyke.org/racket-sicp/

все работало нормально, пока я не пришел к Упражнению 1.10, и когда я написал функцию, как написано в книге:

(define (A x y)
  (cond ((= y 0) 0)
        ((= x 0) (* 2 y))
        ((= y 1) 2)
        (else (A (- x 1)
                 (A x (- y 1))))))

а затем запустите код с помощью cmd + R, затем, когда я вызываю это из repl, так что:

> (A 1 10)

я получаю ошибку

A: undefined;
cannot reference an identifier before its definition

Однако тот же код работает на версии, установленной из командной строки. Что здесь происходит? Что-то сломалось в реализации mit-схемы DrRacket или я что-то не так делаю?

Я использую DrRacket версии 6.1.1(m3) на Mac OS X Yosemite.

Любая помощь будет принята с благодарностью, спасибо!


person akaralar    schedule 05.12.2014    source источник


Ответы (3)


Язык SICP пытается заставить примеры из книги работать непосредственно на языке, но вокруг скрываются ошибки. Все версии Scheme до R6RS нечувствительны к регистру, что означает, что вы можете написать это и заставить его работать нормально:

(define (test a)
  (+ A a)) ; A and a are the same

(TEST 5) ; ==> 10

Я полагаю, что автор основывал свою работу на языковой реализации #!r5rs в Racket, которая наиболее близка к версии, использованной в книге. Он также нечувствителен к регистру, как и SICP. Однако кажется, что окно взаимодействия работает по-разному для обоих языков. Кажется, что он ожидает, что каждый идентификатор, определенный в окне определений, будет называться так, как если бы он был определен в нижнем регистре, и что окно взаимодействий не нечувствительно к регистру. Таким образом, вы получите сообщение об ошибке, если переместите (TEST 5) в окна взаимодействия:

> (TEST 5)
. . TEST: undefined;
 cannot reference an identifier before its definition

Код и взаимодействия считываются различными функциями синтаксического анализатора в синтаксическом анализаторе языкового модуля. Очевидно, они сделали синтаксис нечувствительным к регистру, но чтение по-прежнему чувствительно к регистру. Вы можете проверить это, введя (read) и набрав TeSt, он напечатает TeSt, а не test. Если вы сделали (define x 'TeSt) в окне определений и оценили x в окне взаимодействий, он напечатает test. Racket делает его нечувствительным к регистру, изменяя каждый идентификатор на нижний регистр. Поскольку это есть как в R5RS, так и в SICP, я ожидаю, что SICP будет основан на R5RS и что ошибка унаследована. Вы можете исправить это двумя способами. Один из них — всегда использовать идентификаторы нижнего регистра. Вы будете следовать соглашению, и это не повредит, если вы перейдете к отчетам Scheme, чувствительным к регистру. Альтернативой является добавление одной строки в любом месте окна определений:

(#%require r5rs/init) ; fix interactions window

После того, как вы нажмете RUN, окно взаимодействия станет нечувствительным к регистру, как и должно быть для ранней схемы.

> (TEST 5)
10
>

Удачного взлома!

person Sylwester    schedule 10.12.2014

fwiw, я попытался вызвать (a 1 10), и это сработало, хотя я определил функцию как A.. Я не знаю, почему это так, но я приму любой ответ, который более подробно описывает эту проблему.. помечая это как ответ для у кого такая же проблема..

person akaralar    schedule 05.12.2014
comment
R5RS и более ранние версии нечувствительны к регистру. (eq? 'a 'A) ;=> #t - person Sylwester; 06.12.2014
comment
@Sylwester, ты можешь написать это как ответ, чтобы я мог отметить это так? Благодарность! - person akaralar; 11.12.2014

область «Определения» чувствительна к регистру, а область «Взаимодействия» — нет.

person Csxy    schedule 06.12.2014