I am trying to make a list in Scheme like this: (list 'quote 'a) and I expect the output to be (quote a) but the interpreter excutes the quote and the output is: 'a
How can I write the code to get the expected output?
That's as it ought to be, since the expression 'a is an abbreviation for the list (quote a), and the interpreter's printer is using that shorthand for its output. You should note that if you tell the interpreter to evaluate 'a, it prints out a unadorned with an apostrophe.
If you try taking out the parts of (list 'quote 'a), you would see that you have exactly the list you expected to get:
> (car (list 'quote 'a))
quote
> (cadr (list 'quote 'a))
a
So in summary, you are getting the expected output, just not the expected representation. If you truly demand that you get as output (quote a), then you have to look into your interpreter's documentation to see if that's supported. Or you might have to write your own procedure to print out lists.
Which implementation are you using. Changing how the REPL prints out sexps depends on your implementation of scheme, and if the implementation supports writing out sexps in an expanded form.
Related
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.
Suppose I have a list of arguments args and a macro/syntax f that takes a variable number of arguments. How do I apply f to args? Apparently apply doesn't work here.
For example, suppose I have a list of values bs and I want to know if they're all true, so I try (apply and bs) but I get the error "and: bad syntax". The workaround I came up with is (eval `(and . ,bs)) but I'm wondering if there is some standard way to achieve this sort of thing.
Update
A bunch of possible duplicates have been suggested, but most of them are just about the and example. This suggested question seems to be the same as mine, but the answer there is not very helpful: it basically says "don't do this!".
So maybe the point is that in practice this "apply + macro" question only comes up for macros like and and or, and there is no useful general question? I certainly ran into this issue with and, and don't have much Scheme experience, certainly no other examples of this phenomenon.
This is an XY problem. Macros are part of the syntax of the language: they're not functions and you can't apply them to arguments. Conceptually, macros are like functions which map source code to other source code, and which are called at compile time, not run time: trying to use them at run time is a category error. (In Common Lisp macros are, quite literally, functions which map source code to other source code: in Scheme I'm not quite so clear about that).
So if you have a list and you want to know if all its elements are true, you call a function on the list to do that.
It's easy to write such a function:
(define (all-true? things)
(cond [(null? things)
#t]
[(first things)
(all-true? (rest things))]
[else #f]))
However Racket provides a more general function: andmap: (andmap identity things) will either return false if one of things is not true, or it will return the value of the last thing in the list (or #t if the list is empty). (andmap (lambda (x) (and (integer? x) (even? x))) ...) will tell you if all the elements in a list are even integers, for instance.
There is also every which comes from SRFI 1 and which you can use in Racket after (require srfi/1). It is mostly (exactly?) the same as andmap.
One thing people sometimes try to do (and which you seem to be tempted to do) is to use eval. It may not be immediately clear how awful the eval 'solution; is. It is awful because
it doesn't, in fact, work at all;
insofar as it does work it prevents any kind of compilation and optimisation;
last but not least, it's a pathway to code injection attacks.
Let's see how bad it is. Start with this:
> (let ([args '(#t #t #f)])
(eval `(and ,#args)))
#f
OK, that looks good, right? Well, what if I have a list which is (a a a b): none of the elements in that are false, so, let's try that:
> (let ([args '(a a b)])
(eval `(and ,#args)))
; a: undefined;
; cannot reference an identifier before its definition
Oh, well, can I fix that?
> (let ([args '(a a b)]
[a 1] [b 2])
(eval `(and ,#args)))
; a: undefined;
; cannot reference an identifier before its definition
No, I can't. To make that work, I'd need this:
> (define a 1)
> (define b 2)
> (let ([args '(a a b)])
(eval `(and ,#args)))
2
or this
> (let ([args '('a 'a 'b)])
(eval `(and ,#args)))
'b
Yes, those are quotes inside the quoted list.
So that's horrible: the only two cases it's going to work for is where everything is either defined at the top level as eval has no access to the lexical scope where it is called, or a literal within the object which may already be a literal as it is here, because everything is now getting evaluated twice.
So that's just horrible. To make things worse, eval evaluates Scheme source code. So forget about compiling, performance, or any of that good stuff: it's all gone (maybe if you have a JIT compiler, maybe it might not be so awful).
Oh, yes, and eval evaluates Scheme source code, and it evaluates all of it.
So I have this convenient list:
(define args
'((begin (delete-all-my-files)
(publish-all-my-passwords-on-the-internet)
(give-all-my-money-to-tfb)
#t)
(launch-all-the-nuclear-missiles)))
It's just a list of lists of symbols and #t, right? So
> (eval `(and #,args)
; Error: you are not authorized to launch all the missiles
; (but all your files are gone, your passwords are now public,
; and tfb thanks you for your kind donation of all your money)
Oops.
It would be nice to be able to say, if I have a list that I want to check some property of that doing so would not send all my money to some person on the internet. Indeed, it would be nice to know that checking the property of the list would simply halt, at all. But if I use eval I can't know that: checking that every element of the list is (evaluates to) true may simply never terminate, or may launch nuclear weapons, and I can generally never know in advance whether it will terminate, or whether it will launch nuclear weapons. That's an ... undesirable property.
At the very least I would need to do something like this to heavily restrict what can appear in the list:
(define (safely-and-list l)
(for ([e (in-list l)])
(unless
(or (number? e)
(boolean? e))
(error 'safely-and-list "bad list")))
(eval `(and ,#l)))
But ... wait: I've just checked every element of the list: why didn't I just, you know, check they were all true then?
This is why eval is never the right solution for this problem. The thing eval is the right solution for is, well, evaluating Scheme. If you want to write some program that reads user input and evaluates, it, well, eval is good for that:
(define (repl (exit 'exit))
(display "feed me> ")
(flush-output)
(let ([r (read)])
(unless (eqv? r exit)
(writeln (eval r))
(repl exit))))
But if you think you want to apply a macro to some arguments then you almost certainly have an XY problem: you want to do something else, and you likely don't understand macros.
Does anyone have a suggestion on how i can check if variable x is bound or not?
I want to differ between unbound variables and symbols for example but the symbol? predicate is not good here because (symbol? x) give me an error.
i deal only with unbound variables!
i'll give you an example:
(pattern-rule
`(car ,(?'expr))
(lambda (expr) `,(car (fold expr))))
this code is part of a folder procedure which is part of a parser.
the returned evaluation on (fold '(car (cons '1 '2))) is '1
the returned evaluation on (fold '(car x)) should be (car x) (i mean, the string (car x))
but i can't figure out how to do this part!
I understand that you are writing your own parser? If so, you need to have an explicit representation of the environment. Each time you encounter a binding construct such as lambda or let, you add the bound variables to the environment. When you need to found out if a variable is bound or not, you look it up in the environment - if it is present, then it is bound, if not it is undbound.
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'
I was going through htdp and found this somewhere in the beginning :-
Explain why the following sentences are illegal definitions:
1. (define (f 'x) x)
However, it works fine in racket:
> (define (f 'x) x)
> (f 'a)
3
> (define a 5)
> (f a)
3
Obviously, I'm missing something ... what, exactly ?
Short answer: you should not be using the full "#lang racket" language. The teaching languages strip out the potentially confusing advanced features of the language that you're encountering.
In this case, your definition is being interpreted as a function called f with an optional argument called quote whose default value is provided by 'x'.
Set the language level to Beginning Student, and you'll get a much more reasonable answer.
This line does not work for me in Racket: (define (f 'x) x). The error reported is define: not an identifier for procedure argument in: (quote x).
What language are you using? did you try to run the above line in the interaction window?