Search code examples
schemeracketsicp

Getting an unbound identifier 'require' in scheme


I am using Drracket for my project. I am using the language SICP(#lang sicp) for my project. For one of my implementations i require the use of scheme package called (require (planet dyoo/simply-scheme)). Scheme is not recognising require keyword. But if i change my language to #lang racket "require" is recognised as an keyword. My project makes use of set-car! and set-cdr! which is available in sicp language and not in racket. Is there any work around.

Below is some excerpts of my code:

#lang sicp
(require (planet dyoo/simply-scheme))
(define crosscuts 0)

and

(define (move-north steps_to_move)
(set-cdr! current_position ( + (y_coord current_position) steps_to_move)))

Solution

  • First of all, here are things that I want to note:

    1. It's generally better to use #lang racket because #lang sicp is very limited. You can still access set-car! (though it's named set-mcar!). See the documentation at https://docs.racket-lang.org/reference/mpairs.html.
    2. In case you decide to use #lang racket, do you actually need to use mutable data structure? Avoiding mutation is a defining trait of functional programming. And if you really do need mutable data structure, can you use struct with #:mutable instead? It's more Racket-y. See the documentation at https://docs.racket-lang.org/reference/define-struct.html.
    3. This might not be possible, but generally I would avoid using Planet package. Planet is an old package system that is no longer recommended. It looks like there's no simply-scheme in the new package system, however, so you might really need to use Planet here.

    If you really want to use #lang sicp, note the margin note at https://docs.racket-lang.org/sicp-manual/SICP_Language.html

    R5RS has no require to avoid breaking programs that use the name require. #%require is therefore used instead.

    #%require is a much more primitive operation, however. Depending on your require spec, it might or might not be easy to switch from require to #%require.

    So first, try to replace require with #%require and see if it works. If it is, great, you are done.

    But if it errors, then it means your require spec can't be processed by #%require. One possible solution is to use #%require to get require from Racket, so that you can use require to do more complex things.

    (#%require (only racket require))
    (require ....)