Scheme and Racket do not protect special forms, so it's possible to redefine them. Just purely out of curiosity, is there a way to get back special forms after they have been overwritten?
Example situation:
$ racket
Welcome to Racket v6.11.
> (define define 1)
> (+ define define)
2
> (define x 3) ; How to get the original 'define' back?
; x: undefined;
; cannot reference undefined identifier
; [,bt for context]
>
If I redefine a special form, is there a way to get back the special form?
Specifically in the REPL, where definition overriding is possible, you can simply (require (only-in racket/base define)) to get define back.
Welcome to Racket v7.3.
> (define define 1)
> (+ define define)
2
> (require (only-in racket/base define))
> (define x 3)
> x
3
For Racket files/modules, a simple answer is that once you make a top-level definition, you can't redefine it. However, you can still (require (only-in racket/base [define racket:define])) (rename define from racket/base as racket:define), and then use racket:define instead. Also note that while you can't redefine a top-level definition, you can shadow it, so you can use define in the body of (let-syntax ([define (make-rename-transformer #'racket:define)]) ...) for instance.
But note that in Racket, you can override #%module-begin which has a complete control of your file/module, so you can use this feature to create a new language that allows you to redefine top-level definitions, though at that point you are no longer using the "real" Racket.
Related
I was wondering if you're allowed to call another program you made to do work in a new program you are about to make in scheme, or would I have to copy and paste all the code from the previous program, though I can do this and make my life simple, I'm wondering if there is a more sophisticated elegant way to import in scheme r5rs.
;; Here is an example of what I mean
;; for example I have a file name add.scm which adds 2 numbers
;; now I want to make a new function that squares the numbers
;;is there a way I can do something like this
#lang add.scm as add
;;and use it here like so
(define (square x)
(* x x))
(square add)
;;where add already returns a value
This may seem like a silly piece of code, but this is the best pesudo code I can give, if the example needs more editing to understand please let me know, thank you.
If I understand your question, you have this module named add.scm:
;; add.scm
#lang racket
(+ 5 7) ;; prints 12 when run
and you want to write a new module that gets the value that the add.scm module prints out, bind it to a variable, and use it in a computation, like this:
;; square.scm
#lang racket
(??? add ??? "add.scm" ???) ;; bind `add` to "value" of "add.scm" module
(* add add) ;; prints 144 when run
No, there is no easy way to do that. It's possible, by using dynamic-require or a subprocess to run the module, capturing the output and then reading it to get the value, but that's an awful, complicated, brittle way to do things.
In Racket, a better approach would be for add.rkt to define and export a variable and have a main submodule that prints the value:
;; add.rkt
#lang racket
(provide x)
(define x (+ 5 7))
(module+ main
x)
Then you can use (require "add.rkt") from another module to get x to use in computations, and if you run add.rkt as a program (for example, with racket add.rkt), then it prints the value.
Racket (which has #lang as in the question, and module/provide/require as explained in another answer) is not Scheme (let alone R5RS).
In R6RS Scheme, Scheme source can be divided between library files and top-level programs
If the file add-library.scm contains:
(library (add-library)
(export add)
(import (rnrs))
(define add (+ 5 7)) )
and add-toplevel.scm contains:
(import (add-library))
(define (square x)
(* x x))
(display (square add))
Then:
$ scheme
> (load "add-toplevel.scm")
144
>
Scheme and Racket do not protect special forms, so it's possible to redefine them. Just purely out of curiosity, is there a way to get back special forms after they have been overwritten?
Example situation:
$ racket
Welcome to Racket v6.11.
> (define define 1)
> (+ define define)
2
> (define x 3) ; How to get the original 'define' back?
; x: undefined;
; cannot reference undefined identifier
; [,bt for context]
>
If I redefine a special form, is there a way to get back the special form?
Specifically in the REPL, where definition overriding is possible, you can simply (require (only-in racket/base define)) to get define back.
Welcome to Racket v7.3.
> (define define 1)
> (+ define define)
2
> (require (only-in racket/base define))
> (define x 3)
> x
3
For Racket files/modules, a simple answer is that once you make a top-level definition, you can't redefine it. However, you can still (require (only-in racket/base [define racket:define])) (rename define from racket/base as racket:define), and then use racket:define instead. Also note that while you can't redefine a top-level definition, you can shadow it, so you can use define in the body of (let-syntax ([define (make-rename-transformer #'racket:define)]) ...) for instance.
But note that in Racket, you can override #%module-begin which has a complete control of your file/module, so you can use this feature to create a new language that allows you to redefine top-level definitions, though at that point you are no longer using the "real" Racket.
The Typed Racket reference indicates that it's possible to use with-type to created “typed regions” within untyped code.
The with-type form allows for localized Typed Racket regions in otherwise untyped code.
It’s a little unclear how to actually use this, though. Obviously, using such a feature needs to take place within an untyped module using #lang racket or something similar. How should the with-type binding be imported?
A naïve attempt is just to require Typed Racket, but this causes failures with how TR overwrites existing syntactic forms.
(require typed/racket)
(struct point (x y)) ; complains about missing type annotations
Trying to use only-in to simply require with-type and nothing else sort of works, but then none of the required type bindings (such as Number or ->) exist.
It seems like the only way to do this would be to manually use only-in to import only the things that I need, but this feels laborious. I could also use prefix-in, but then of course everything would be scattered with prefixes.
Is there a recommended way of doing this, or is this feature somewhat deprecated?
I don't know the fundamental answer. A guess is that it's the sort of thing that would be useful when writing macros, as opposed to code you'd write directly?
A practical idea: You can use local-require to limit the "contamination" of the TR require. And you can flip to using except-in if that's less work then only-in.
For instance this example from the docs get close, but gives a weird error presumably because it's using TR's quote:
#lang racket/base
(let ([x 'hello])
(local-require typed/racket)
(with-type
#:result String
#:freevars ([x String])
(string-append x ", world")))
; /tmp/so.rkt:7:21: quote: identifier used out of context
; in: quote
Excluding that with except-in gives the desired error:
(let ([x 'hello])
(local-require (except-in typed/racket quote))
(with-type
#:result String
#:freevars ([x String])
(string-append x ", world")))
; x: broke its contract
; promised: String
; produced: 'hello
; in: String
; contract from: /tmp/so.rkt
; blaming: /tmp/so.rkt
; (assuming the contract is correct)
; at: /tmp/so.rkt:14.17
But yeah. This is just fiddling with the edges and not getting to the heart of it.
I would just use except-in (or perhaps rename-in) to avoid the few identifiers that don't work in both typed and untyped programs. Like this modification of Greg's program:
#lang racket/base
(require (except-in typed/racket struct))
(struct point (x y))
(let ([x 'hello])
(with-type
#:result String
#:freevars ([x String])
(string-append x ", world")))
I am trying to write a small scheme-like language in python, in order to try to better understand scheme.
The problem is that I am stuck on syntax objects. I cannot implement them because I do not really understand what they are for and how they work.
To try to understand them, I played around a bit with syntax objects in DrRacket.
From what I've been able to find, evaluating #'(+ 2 3) is no different from evaluating '(+ 2 3), except in the case that there is a lexical + variable shadowing the one in the top-level namespace, in which case (eval '(+ 2 3)) still returns 5, but (eval #'(+ 2 3)) just throws an error.
For example:
(define (top-sym)
'(+ 2 3))
(define (top-stx)
#'(+ 2 3))
(define (shadow-sym)
(define + *)
'(+ 2 3))
(define (shadow-stx)
(define + *)
#'(+ 2 3))
(eval (top-sym)), (eval (top-stx)), and (eval (shadow-sym)) all return 5, while (eval (shadow-stx)) throws an error. None of them return 6.
If I didn't know better, I would think that the only thing that's special about syntax objects (aside from the trivial fact that they store the location of the code for better error reporting) is that they throw an error under certain circumstances where their symbol counterparts would have returned a potentially unwanted value.
If the story were that simple, there would be no real advantage to using syntax objects over regular lists and symbols.
So my question is: What am I missing about syntax objects that makes them so special?
Syntax objects are the repository for lexical context for the underlying Racket compiler. Concretely, when we enter program like:
#lang racket/base
(* 3 4)
The compiler receives a syntax object representing the entire content of that program. Here's an example to let us see what that syntax object looks like:
#lang racket/base
(define example-program
(open-input-string
"
#lang racket/base
(* 3 4)
"))
(read-accept-reader #t)
(define thingy (read-syntax 'the-test-program example-program))
(print thingy) (newline)
(syntax? thingy)
Note that the * in the program has a compile-time representation as a syntax object within thingy. And at the moment, the * in thingy has no idea where it comes from: it has no binding information yet. It's during the process of expansion, during compilation, that the compiler associates * as a reference to the * of #lang racket/base.
We can see this more easily if we interact with things at compile time. (Note: I am deliberately avoiding talking about eval because I want to avoid mixing up discussion of what happens during compile-time vs. run-time.)
Here is an example to let us inspect more of what these syntax objects do:
#lang racket/base
(require (for-syntax racket/base))
;; This macro is only meant to let us see what the compiler is dealing with
;; at compile time.
(define-syntax (at-compile-time stx)
(syntax-case stx ()
[(_ expr)
(let ()
(define the-expr #'expr)
(printf "I see the expression is: ~s\n" the-expr)
;; Ultimately, as a macro, we must return back a rewrite of
;; the input. Let's just return the expr:
the-expr)]))
(at-compile-time (* 3 4))
We'll use a macro here, at-compile-time, to let us inspect the state of things during compilation. If you run this program in DrRacket, you will see that DrRacket first compiles the program, and then runs it. As it compiles the program, when it sees uses of at-compile-time, the compiler will invoke our macro.
So at compile-time, we'll see something like:
I see the expression is: #<syntax:20:17 (* 3 4)>
Let's revise the program a little bit, and see if we can inspect the identifier-binding of identifiers:
#lang racket/base
(require (for-syntax racket/base))
(define-syntax (at-compile-time stx)
(syntax-case stx ()
[(_ expr)
(let ()
(define the-expr #'expr)
(printf "I see the expression is: ~s\n" the-expr)
(when (identifier? the-expr)
(printf "The identifier binding is: ~s\n" (identifier-binding the-expr)))
the-expr)]))
((at-compile-time *) 3 4)
(let ([* +])
((at-compile-time *) 3 4))
If we run this program in DrRacket, we'll see the following output:
I see the expression is: #<syntax:21:18 *>
The identifier binding is: (#<module-path-index> * #<module-path-index> * 0 0 0)
I see the expression is: #<syntax:24:20 *>
The identifier binding is: lexical
12
7
(By the way: why do we see the output from at-compile-time up front? Because compilation is done entirely before runtime! If we pre-compile the program and save the bytecode by using raco make, we would not see the compiler being invoked when we run the program.)
By the time the compiler reaches the uses of at-compile-time, it knows to associate the appropriate lexical binding information to identifiers. When we inspect the identifier-binding in the first case, the compiler knows that it's associated to a particular module (in this case, #lang racket/base, which is what that module-path-index business is about). But in the second case, it knows that it's a lexical binding: the compiler already walked through the (let ([* +]) ...), and so it knows that uses of * refer back to the binding set up by the let.
The Racket compiler uses syntax objects to communicate that kind of binding information to clients, such as our macros.
Trying to use eval to inspect this sort of stuff is fraught with issues: the binding information in the syntax objects might not be relevant, because by the time we evaluate the syntax objects, their bindings might refer to things that don't exist! That's fundamentally the reason you were seeing errors in your experiments.
Still, here is one example that shows the difference between s-expressions and syntax objects:
#lang racket/base
(module mod1 racket/base
(provide x)
(define x #'(* 3 4)))
(module mod2 racket/base
(define * +) ;; Override!
(provide x)
(define x #'(* 3 4)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require (prefix-in m1: (submod "." mod1))
(prefix-in m2: (submod "." mod2)))
(displayln m1:x)
(displayln (syntax->datum m1:x))
(eval m1:x)
(displayln m2:x)
(displayln (syntax->datum m2:x))
(eval m2:x)
This example is carefully constructed so that the contents of the syntax objects refer only to module-bound things, which will exist at the time we use eval. If we were to change the example slightly,
(module broken-mod2 racket/base
(provide x)
(define x
(let ([* +])
#'(* 3 4))))
then things break horribly when we try to eval the x that comes out of broken-mod2, since the syntax object is referring to a lexical binding that doesn't exist by the time we eval. eval is a difficult beast.
I'm working on a simple game using Racket (homework assignment). The requirements instruct me to create a computer player named random which utilizes the default random number generator.
This snippet of code illustrates my issue:
(define (random)
(random (10))) ; should be random number call
I'm used to the C convention for namespaces:
std::string
Does Racket offer anything along those lines?
Thanks
You can use prefix-in to prefix the exports of the standard library with some namespacing prefix. For example:
#lang racket
(require (prefix-in std:: racket))
(define (* x)
(std::* x x))
shows that we can shadow the bindings from #lang racket, but still get at them through the prefixed identifiers.
Traditionally, the prefixes that people use are a little simpler, like:
#lang racket
(require (prefix-in r: racket))
(define (* x)
(r:* x x))