Unable to use eval on user input in Racket - scheme

I'm currently learning Scheme (using Racket), but one of the challenges I'm coming upon is trying to execute the following bit of code, which is meant to execute Racket code from user input using eval:
(display (eval (read)))
Here's some of the weird behavior I've observed so far:
(display (eval (read))) in the definition window prompts for keyboard input, as expected, when the definitions are run. However, providing the input
((lambda (x) (+ x 1)) 1)
gives the error
?: function application is not allowed;
no #%app syntax transformer is bound in: ((lambda (x) (+ x 1)) 1)
On the other hand, using (display ((eval (read)) 1)) and providing input
(lambda (x) (+ x 1))
returns the error
lambda: unbound identifier;
also, no #%app syntax transformer is bound in: lambda
However, running (display (eval (read))) and providing ((lambda (x) (+ x 1)) 1) in the console pane, as opposed to the definitions pane, prints out 2, as expected.
What is the reason for this behavior?

It looks like you don't have the namespace set up. If you're running (eval (read)) within a file, it doesn't work because the current-namespace is set to an empty namespace by default. You can set up a namespace with racket/base in it by doing (current-namespace (make-base-namespace)) first:
#lang racket
(current-namespace (make-base-namespace))
(println (eval (read)))
Running this program and giving it the input ((lambda (x) (+ x 1)) 1) results in it printing 2.
The reason it worked in the interactions window (item 3 of your weird-behavior list), is that in the interactions window, the current-namespace parameter is set to the namespace of the file.
This is not true for the definitions window, the main program, so you have to set the current-namespace yourself, or pass a namespace in as a second argument to eval:
#lang racket
(define ns (make-base-namespace))
(println (eval (read) ns))

Racket, the software package, has support for both R5RS and R6RS and will probably get support for R7RS. The software also has several non standard languages in its own Racket language family that has much in common with Scheme but is not Scheme. Alex has made an excellent answer for that language so I though I'd add information about Scheme since you write you're learning Scheme which is not the same as learning Racket when it comes some corner cases including eval.
eval is a procedure which has had breaking changes between the different Scheme reports since it became mandatory in R5RS. Here are some examples from different versions of the standard:
#!r6rs
(import (rnrs)
(rnrs eval))
(display (eval '((lambda (x) (+ x 1)) 1)
(environment '(rnrs))))
; ==> undefined, prints 2
The slightly older but still in common used R5RS:
#!r5rs
(display (eval '((lambda (x) (+ x 1)) 1)
(scheme-report-environment 5)))
; ==> undefined, prints 2
The to come R7RS which only has it's small version ratified so far:
#!r7rs
(import (scheme)
(scheme eval))
(display (eval '((lambda (x) (+ x 1)) 1)
(environment '(scheme))))
; ==> undefined, prints 2

Related

Why doesn't my program produce any output?

I am looking to write a Scheme function numofatoms that determines the number of elements in a list.
For example, (numOfSymbols '((1 3) 7 (4 (5 2) ) ) should return 6.
What I have so far:
;(1 3) 7 (4(5 2)) the list
(define (numofatoms lst) ;defining a numofatoms function
(define (flatten x) ;defining a flatten function
(cond ((null? x) '())
((pair? x) (append (flatten (car x)) (flatten (cdr x))))
(else (list x))))
(length (flatten lst)))
(numofatoms '((1 3) 7 (4(5 2)))); calling the function
After defining numofatoms and flatten I don't see any errors but the program is not working. It doesn't produce any outputs.
The posted code works fine if you load it and call numofatoms from the REPL. I presume that OP is either calling load from the REPL or running the code as a script from the command-line, and when either of these is done OP sees no output. The REPL evaluates and prints results (hence the P), but when you load code that isn't necessarily what happens.
When an expression is evaluated in the REPL, the value to which the expression evaluates is printed. There may be an expectation that the value of the final expression in a file will be printed when the file is loaded into the REPL, but that expectation will not be rewarded.
The load procedure is not standardized for R6RS; here it is implementation-specific, and the particulars depend upon the implementation. For Chez Scheme, load returns an unspecified value, so there should be no expectation of seeing anything useful when a file is successfully loaded.
Both R5RS and R7RS have load procedures described in the standards, but both leave it unspecified whether the results of evaluating the expressions in a file are printed.
The details of any script mechanism for Scheme programs is entirely dependent upon the implementation. But, when you run a script from the command-line your are not in a REPL, so again there should be no expectation that the results of evaluating various forms in the file will be printed to the terminal window.
If you want a Scheme file or script to print something, you have to make it do that. If the final line of the posted file is changed to (display (numofatoms '((1 3) 7 (4(5 2))))) (newline), the program will display the result of calling numofatoms whenever it is run.

Debugging #lang sicp in DrRacket

I am happily using DrRacket with the inbuilt SICP language (https://docs.racket-lang.org/sicp-manual/SICP_Language.html) to work through SICP.
However, I'm unable to use the DrRacket debugger with the SICP language.
A simple test example,
#lang racket
(define (test x)
(* x x))
(test (test (test 2)))
debugs happily, and I can step through and see 'x' being updated etc.
However, using the SICP language as follows
#lang sicp
(define (test x)
(* x x))
(test (test (test 2)))
results in an error:
Library/Racket/7.5/pkgs/sicp/sicp/main.rkt:67:32: ?: cannot bind from tainted syntax in: (quote #%kernel)
Does anyone know what the problem might be? I've not really had to use the debugging yet, but I would quite like knowing that it's there if I do want to use it.

How to use check-expect in Racket

I am trying to use the check-expect function in scheme but I keep being told its an unbound identifier for check-expect. Isn't check-expect a function I can use already? Below is my code:
#lang racket
(define contains (lambda (item list*)
(if (equal? list* '())
#f
(if (equal? item (car list*))
#t
(contains item (cdr list*))))))
(define z (list 1 2 3))
(define q (list 4 5 6))
(define p (list "apple" "orange" "carrot"))
(check-expect (contains 1 z) #t)
Old question, but answer for the googlers:
You can (require test-engine/racket-tests), which defines check-expect.
Note that, unlike BSL, you'll have to run the tests with (test).
check-expect is not technically built into scheme or Racket automatically.
Note that you are using #lang racket. That is the professional Racket language, and that language expects you to know and state explicitly what libraries to import. It will not auto-import them for you.
(Now, you could require a unit testing library; there is one that comes with the Racket standard library.)
But if you are just starting to learn programming, it makes much more sense to use one of the teaching languages within Racket.
For the code you're using above, I suspect you'll probably want this instead. Start DrRacket and choose "Beginner Student Language" from the "How to Design Programs" submenu in the "Language" menu.
See http://www.ccs.neu.edu/home/matthias/HtDP2e/prologue.html for more details.
I've managed to come up with this workaround:
At the top of the file (but after #lang racket) added a line
(require rackunit)
Instead of (check-expect) I've used
(check-equal? (member? "a" (list "b" "a")) #f )
Unlike in check-expect, tests must be added after the function definitions.
If the checks are successful, there is no output. Only when a tests fails, the output looks like this:
--------------------
FAILURE
name: check-equal?
actual: #f
expected: #t
expression: (check-equal? #f (member? "a" (list "b" "a")))
message: "test"
More Info: RackUnit documentation
I took a class using DrRacket and looked at the first assignment in Terminal (Mac).
The line in this file, automatically added by DrRacket, which made check-expect available is:
#reader(lib "htdp-beginner-reader.ss" "lang")((modname basic) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f)))
As a side note, I wanted to try a Racket program without DrRacket. Just to test, I decided to do (+ 1 2). To get it to work, my file looks like this:
#! /Applications/Racket\ v6.2.1/bin/racket
#lang racket
(+ 1 2)
I run it in Terminal like this:
racket test.rkt
I put this in .bash_profile:
alias racket='/Applications/Racket\ v6.2.1/bin/racket'

Scheme: What is the difference between define and let when used with continutation

I'm wondering the difference between the two following code:
(define cont2 #f)
(call/cc (lambda (k) (set! cont2 k)))
(display "*")
(cont2 #f)
and
(let [(cont #f)]
(call/cc (lambda (k) (set! cont k)))
(display "*")
(cont #f))
In my opinion, the correct behavior of these two programs should be printing '*' infinitely.
However, the first one only prints one '*' and exits,
while the second one gives the correct behavior.
So I'm confused. Is there something special done with define
or the continuation is not what I thought - all the following programs until the end of the program, it seems to have a boundary or something.
Another guess is that the top-level of environment is special treated, like this:
(define (test)
(define cont2 #f)
(call/cc (lambda (k) (set! cont2 k)))
(display "*")
(cont2 #f))
(test)
This works, but why?
Thank you for your help!
In Racket, each top-level expression is wrapped with a prompt.
Since call/cc only "captures the current continuation up to the nearest prompt", in your first example, none of the other top-level expressions are captured, so applying cont2 to #f results in just #f.
Also, wrapping the first example in begin won't change things since a top-level begin implicitly splices its contents as if they were top-level expressions.
When you are at the top-level, the continuation of (notice the prompt character '>'):
> (call/cc (lambda (k) (set! cont2 k)))
is the top-level read-eval-print-loop. That is, in your first code snippet you enter the expressions one-by-one, going back to the top-level after each. If instead you did:
(begin
(define cont3 #f)
...
(cont3 #f))
you'd get infinite '*'s (because you got back to top-level only at the completion of the begin). Your third code snippet is an instance of this; you get infinite '*'s because the continuation isn't the top-level loop.
It's not only in your opinion. If your doing this in an R5RS or R6RS both not behaving the same is a violation of the report. In racket (the r5rs implementation) it probably is violating since I did test their plt-r5rs and it clearly doesn't loop forever.
#lang racket (the default language of the implementation racket) doesn't conform to any standard so, like perl5, how it behaves is the specification. Their documentation writes a lot about prompt tags which reduces the scope of a continuation.
There are arguments against call/cc that comes to mind when reading this question. I think the interesting part is:
It is telling that call/cc as implemented in real Scheme systems never
captures the whole continuation anyway: Many Scheme systems put
implicit control delimiter around REPL or threads. These implicit
delimiters are easily noticeable: for example, in Petite Chez or
Scheme48, the code
(let ((k0 #f))
(call/cc (lambda (k) (set! k0 k)))
(display 0)
(k0 #f))
prints the unending stream of zeros. If we put each operation on its
own line (evaluated by its own REPL):
(define k0 #f)
(call/cc (lambda (k) (set! k0 k)))
(display 0)
(k0 #f)
the output is mere 0 #f.
I'm not sure if I'm against call/cc as a primitive (I believe your tools should give you the possibility to shoot yourself in the foot). I feel I might change my mind after writing a Scheme compiler though so I'll come back to this when I have.
This also works, don't ask me why. (Call/cc just blows my mind)
(define cont2 #f)
((lambda ()
(call/cc (lambda (k) (set! cont2 k)))
(display "*")
(cont2 #f)))
In your test define the three lines are within an implicit begin struction that you call together that is invoked at the top level. In my version I've just made an anonymous thunk to which invokes itself. In your first define of cont2, your define is just creating a placeholder for the value, and your function calls after aren't linked together within and environment,

What exactly is the purpose of syntax objects in scheme?

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.

Resources