I'm in the process of learning Scheme. During an exercise (trying to find a specific value in a registry). When running this bit of code, I get the error message:
application: not a procedure;
expected a procedure that can be applied to arguments
given: (342 "Bike" piece 250)
arguments...: [none]
The code in question:
(define get-post
(lambda (post varunr)
(define find-post
(lambda (post)
(cond (null? post) (display "Errormessage-For-User")
(member varunr (car (car post)))(car post)
(else (find-post (cdr post))))))
find-post (post))) ;; <--- Here's the error message
Thanks for any help you can provide.
Try this:
(define get-post
(lambda (post varunr)
(define find-post
(lambda (post)
(cond ((null? post) (display "Errormessage-For-User"))
((member varunr (car (car post))) (car post))
(else (find-post (cdr post))))))
(find-post post)))
Remember: in Scheme functions are called like this: (f x), not like this: f(x). And in a cond expression, each pair of condition/expression must be surrounded by (). You have to be careful where you put those parentheses, use your IDE's syntax highlighting and formatting capabilities to avoid errors like these.
Related
I have this scheme function that I'm supposed to run lists of integers on but I have no idea what the error means. The error states: "if: expected a question and two answers, but found 4 parts in: (if(null? list) '() (cons (+ 1 (car list)) (f(cdr list)))). What is missing from this function and what on earth does '() do? Thanks! I've never used Scheme before.
(define (f list)
(if (null? list)
’()
(cons (+ 1 (car list)) (f (cdr list)))))
The character you are using to quote the empty list is the right quotation mark ’, U+2019. Your code works fine if you use the ascii apostrophe ', U+0027
(define (f list)
(if (null? list)
'()
(cons (+ 1 (car list)) (f (cdr list)))))
You used the wrong quote (maybe a copy paste error?).
Use ' not ’.
I'm currently studying Scheme with The Little Schemer and ran into an odd trouble.
Here is my code:
(define rember
(lambda (a lat)
((if (null? lat)
'()
(cond
((eq? a (car lat)) (cdr lat))
(else (rember a (cdr lat))))))))
(rember 'aaa '(bbb aaa))
I used an "if" instead of "cond" in the textbook. When returning from the tail-recursion, it shows this error:
application: not a procedure;
expected a procedure that can be applied to arguments
given: '()
arguments...: [none]
I guess this is because it treats '() in the if-statement as a function and the return value of the tail-recursion as its argument. But since the book doesn't give me so many details about the language, could you explain this a bit for me? (e.g. Is this in fact some kind of language feature? Is there any way that I can stick to "if" in this piece of code? And when can I use "if" safely?)
Thanks.
You have an extra set of parentheses around your if. This
((if (null? lat)
'()
(cond
((eq? a (car lat)) (cdr lat))
(else (rember a (cdr lat))))))
should be this:
(if (null? lat)
'()
(cond
((eq? a (car lat)) (cdr lat))
(else (rember a (cdr lat)))))
Those extra parentheses tell Scheme that you want to call the result of the if like a function, so you get the error saying that '() isn't a function.
I've been reading through chapter 5 of sicp and have gotten stuck on a piece of code--namely, the assembler presented in 5.2. This is what it looks like:
(define (extract-labels text receive)
(if (null? text)
(receive '() '())
(extract-labels (cdr text)
(lambda (insts labels)
(let ((next-inst (car text)))
(if (symbol? next-inst)
(receive insts
(cons (make-label-entry next-inst insts)
labels))
(receive (cons (make-instruction next-inst) insts)
lables)))))))
Isn't the lambda only going to be called when the text is null? So how can we ask for the car of 'text' then?
EDIT
Thanks for the answers, but I'm still not seeing it. If the text is not null, doesn't extract-lables call itself recursively, until the text is null? In which case how can we call the car of it?
The lambda gets the appropriate scope: at the time the lambda is defined text is not null, so calling car text works fine.
if takes up to three arguments: a condition, a if-true (then) expression, and an if-false (else) expression. The indentation is all weird, so it looks wrong.
It should appear as
(define (extract-labels text receive)
(if (null? text)
(receive '() '())
(extract-labels (cdr text)
(lambda (insts labels)
(let ((next-inst (car text)))
(if (symbol? next-inst)
(receive insts
(cons (make-label-entry next-inst insts)
labels))
(receive (cons (make-instruction next-inst) insts)
labels)))))))
Observe that the result of the expression is (receive '() '()) if text is null and (extract-labels ...) otherwise.
In Scheme or Racket is it possible to detect the caller of a function?
For example, I can write a function to test if a list is a list of atoms as follows:
(define atom? (lambda (x) (and (not (pair? x)) (not (empty? x)))))
(define lat? (lambda (l)
(define latt?
(lambda (l)
(cond
((null? l) #t)
((atom? (car l)) (latt? (cdr l)))
(else #f))))
(if (null? l) #f (latt? l))))
but instead of the above, is there a function like "called-by" to do something like this:
(define lat?
(lambda (l)
(cond
((and (null? l) (called-by "lat?")) #t)
((atom? (car l)) (lat? (cdr l)))
(else #f))))
The usual way to do this is to add some argument to the function, or make a loop via an internal definition as you did. Other than that, there is no reliable way to find out the caller of a function.
But in your case, it seems like a good lack of feature -- using it for the above problem is pretty bad. There's nothing wrong with the internal helper version. (It's also quite similar to any other language.)
Finally, I'd expect (lat? null) to return #t since it is a list that has only atoms as elements.
(define every-aux
(lambda(status predicate lst)
(cond((null? lst) status)
((cond((equal? (predicate (car lst)) #t)
(set! status #t)
(every-aux status predicate (cdr lst)))
(else (set! status #f) status))))))
Above Procedure returns void if predicate does not match with every element in lst?
It does not have any problem is returning #t though if predicate matches every element of lst.
Changing the last line to
(else (set! status #f) status))))))
to
(else (set! status "#f") status))))))
returns "#f" so procedure is correct.
How I can force scheme to return #f explicitly instead of just void?
Your code is very messy:
You have a cond inside another, but cond is intended for multiple tests/results.
There is no reason to have that status modified -- Scheme uses call-by-value, so this is likely not doing whatever you think it does.
Specifically, there is no reason to use (else (set! status #f) status) -- you could just return #f directly.
The actual reason for your confusion is the weird cond nesting -- the second cond is actually used as a test, so if you make it (the inner cond) return #f, then the whole test of the outer cond is getting #f, which means that it (the outer cond) didn't get any true result, and resorts to returning an unspecified value (and if this is Racket, then that value is shown as #<void>). So if you flatten the two conds into one, your problem will go away.
Finally, if you're having problems at such a level, then you should consider using some textbook to familiarize yourself with the language. Specifically HtDP is intended to give you an easy path into getting familiar with the syntax.
#Eli Barzilay
After some I deliberation I could see the solution. Thanks for the pointers.
(define every?
(lambda (predicate list)
(if(null? list) "Empty List not allowed."
(every-aux? predicate list))))
(define every-aux?
(lambda (predicate lst)
(cond ((null? lst) #t)
((equal? (predicate (car lst)) #t) (every-aux? predicate (cdr lst)))
(else #f))))