Evaluating a list of booleans? - scheme

I've got a list that I want to evaluate the truth of, but (unless I'm missing some built-in aspect of Racket/Scheme) I need to convert it to a Boolean to do that.
For example, I have
'(#t and #f)
I need
(function '(#t and #f)) ;in order to return...
>#f
I've tried (eval '(and #t #f) but get this error message:
and: unbound identifier;
also, no #%app syntax transformer is bound in: and
I have code in place that converts '(#t and #f) into '(and #t #f) so that shouldn't be an issue, as far as I'm aware.
(define (Evaluate-WFF lst)
(match lst
((list a b c)
(list (reorg b)
(reorg a)
(reorg c)))
(_ lst)))
When I try to eval from this, I get the error message stated earlier.

Depending on what language you're using you might need to provide a namespace, as per the docs. In #lang racket this is how to do it:
(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))
(eval '(and #t #f) ns)
=> #f

Related

Problems about Scheme with postfix

Here is my code about postfix in scheme:
(define (stackupdate e s)
(if (number? e)
(cons e s)
(cons (eval '(e (car s) (cadr s))) (cddr s))))
(define (postfixhelper lst s)
(if (null? lst)
(car s)
(postfixhelper (cdr lst) (stackupdate (car lst) s))))
(define (postfix list)
(postfixhelper list '()))
(postfix '(1 2 +))
But when I tried to run it, the compiler said it takes wrong. I tried to check it, but still can't find why it is wrong. Does anyone can help me? Thanks so much!
And this is what the compiler said:
e: unbound identifier;
also, no #%app syntax transformer is bound in: e
eval never has any information about variables that some how are defined in the same scope as it is used. Thus e and s does not exist. Usually eval is the wrong solution, but if you are to use eval try doing it as as little as you can:
;; Use eval to get the global procedure
;; from the host scheme
(define (symbol->proc sym)
(eval sym))
Now instead of (eval '(e (car s) (cadr s))) you do ((symbol->proc e) (car s) (cadr s)). Now you should try (postfix '(1 2 pair?))
I've made many interpreters and none of them used eval. Here is what I would have done most of the time:
;; Usually you know what operators are supported
;; so you can map their symbol with a procedure
(define (symbol->proc sym)
(case sym
[(+) +]
[(hyp) (lambda (k1 k2) (sqrt (+ (* k1 k1) (* k2 k2))))]
[else (error "No such operation" sym)]))
This fixes the (postfix '(1 2 pair?)) problem. A thing that I see in your code is that you always assume two arguments. But how would you do a double? eg something that just doubles the one argument. In this case symbol->proc could return more information:
(define (symbol->op sym)
(case sym
[(+) (cons + 2)]
[(double) (cons (lambda (v) (* v v)) 1)]
[else (error "No such operation" sym)]))
(define op-proc car)
(define op-arity cdr)
And in your code you could do this if it's not a number:
(let* ([op (symbol->op e)]
[proc (op-proc op)]
[arity (op-arity op)])
(cons (apply proc (take s arity)
(drop s arity)))
take and drop are not R5RS, but they are simple to create.

Nested Scheme Functions Not Returning Properly

I have created a function that can determine if a character is in a list. While it works fine by itself, it does not work properly when called by another function which is suppose to compare the elements of a list to several key words. I have also tried using the functions memq, memv, and member, but they fail as well. I would like to know what it is that is causing my program to not return #t and where I went wrong.
(define in?
(lambda (y xs)
(if (memq y xs) #t #f)))
(define det?
(lambda (xs)
(if (in? 'a xs) #t)
(if (in? 'an xs) #t)
(if (in? 'the xs) #t #f)))
There's no such thing (*1) as an explicit return statement in Scheme; a procedure just returns the value of the last expression. Chris has shown you alternatives with cond and correct, 2-armed ifs.
If you find yourself with conditionals returning #t and #f there's usually a more elegant alternative using boolean logic, in this case:
(define det?
(lambda (xs)
(or (in? 'a xs)
(in? 'an xs)
(in? 'the xs))))
and in? could be expressed as
(define in?
(lambda (y xs)
(and (memq y xs) #t)))
(*1) I was lying, of course. You can have this effet using call/cc or any variation thereof. It's an advanced subject and not appropriate for your situiation, but to give you a glimpse of what it would like:
(define det?
(lambda (xs)
(call/cc
(lambda (return)
(when (in? 'a xs) (return #t))
(when (in? 'an xs) (return #t))
(when (in? 'the xs) (return #t))
#f))))
Note that I use when, not if, since they are still one-armed conditions.
Your use of if is incorrect; only the last if actually does anything. (To help prevent these kinds of errors, Racket bans the use of one-armed if expressions.) Perhaps you would like to use cond instead?
(define (det? xs)
(cond ((in? 'a xs) #t)
((in? 'an xs) #t)
((in? 'the xs) #t)
(else #f)))
This macro-expands to the following ifs:
(if (in? 'a xs)
#t
(if (in? 'an xs)
#t
(if (in? 'the xs)
#t
#f)))
Notice how that's different from your series of if expressions.

Scheme Argument Checker Error-handling

I'm fairly new to Scheme programming and was wondering how I can add some error checkers in this program. I would like it to check if the user types in more than one parameter and if the user does I would like it to say that its an error.
(define (thirds lst)
(cond ((or (null? lst) (null? (cdr lst))) lst)
((null? (cddr lst)) (list (car lst)))
(else (cons (car lst)
(thirds (cdddr lst))))))
The Scheme interpreter should check this automatically. You only need to do your own checking of the number of arguments if you define the procedure to take spread arguments, i.e.
(define (thirds . args)
...)
You would normally only do this if the procedure takes a variable number of arguments. For procedures with static arguments, just list them in the definition and let the interpreter do the checking for you.
If you really want to detect this yourself, you can do:
(define (thirds . args)
(if (= (length args) 1)
(let ((lst (car args)))
(cond ... ; all the rest of your code
))
(display "Oh that's an error")))
So, using your definition of thirds in #!racket (the language) and trying to use it like this:
(thirds '(a b c) '(d e f))
thirds: arity mismatch;
the expected number of arguments does not match the given number
expected: 1
given: 2
arguments...:
'(a b c)
'(d e f)
context...:
/usr/share/racket/collects/racket/private/misc.rkt:87:7
As you can see all computation stops since I have given a one argument procedure two arguments. It's a contract violation and it throws an exception.
It's perfectly possible to make handlers:
(with-handlers ([exn:fail:contract?
(λ (e) (displayln "got a contract error"))])
(thirds '(1 2 3) '(4 5 6)))
; prints "got a contract error"

How to check if a list contains only #t

I was trying with the following code in racket and MIT scheme, surprise me that the compiler throw err
(foldr and #t '(#t #t #f))
Is there any way to use reduce/fold way to check if a list contains only true or false?
I know a lambda can do the job, but it really make we wonder why this is not a valid code.
I remember I can do it in Haskell.....
TIA.
and is a macro, so it doesn't have a value by itself. Specifically, it short-circuits evaluation, and using it as you tried to will not make any sense. For that reason, Racket has andmap which you can use in such cases. (Other implementations have similar functionality under different names -- for example, srfi-1 uses every.)
And is a macro and can not be used as a function. Put it in a function:
(foldr (lambda (a b) (and a b)) #t '(#t #t #f))
This works in guile:
(primitive-eval (cons 'and '(#t #f)))
One thing that might be off is that in Racket and Scheme, true values are anything other than #f. Since your question asks for booleans, the following will be more discriminating:
#lang racket
(define (boolean-true? x) (eq? x #t))
(define (only-contains-#t? l)
(andmap boolean-true? l))
For example,
> (only-contains-#t? '())
#t
> (only-contains-#t? '(#t #t #t))
#t
> (only-contains-#t? '(#t #t true))
#f

Using AND with the apply function in Scheme

Why doesn't the following work?
(apply and (list #t #t #f))
While the following works just fine.
(apply + (list 1 3 2))
This seems to be the case in both R5RS and R6RS?
and isn't a normal function because it will only evaluate as few arguments as it needs, to know whether the result is true or false. For example, if the first argument is false, then no matter what the other arguments are, the result has to be false so it won't evaluate the other arguments. If and were a normal function, all of its arguments would be evaluated first, so and was made a special keyword which is why it cannot be passed as a variable.
(define and-l (lambda x
(if (null? x)
#t
(if (car x) (apply and-l (cdr x)) #f))))
pleas notice that this is lambda variadic!
apply example (and-l #t #t #f)
or you can use it via apply procedure(as was asked)
for example (apply and-l (list #t #t #f))
both options are ok...
and is actually a macro, whose definition is outlined in R5RS chapter 4. The notation "library syntax" on that page really means it is implemented as a macro.
Section 7.3, Derived expression types gives a possible definition of the and macro:
(define-syntax and
(syntax-rules ()
((and) #t)
((and test) test)
((and test1 test2 ...)
(if test1 (and test2 ...) #f))))
Given this defintion, it is not possible to use and as a function argument to apply.
In the Scheme dialect MIT/GNU Scheme, you can use the function boolean/and instead of the special form and.
(apply boolean/and (list #t #t #f)) ;Value: #f
Also, for the record, I couldn’t find any equivalent function in Guile Scheme’s procedure index.
(Other answers have already explained why the special form and won’t work, and shown how to write your own replacement function if there isn’t already such a function in your dialect.)
If you REALLY wanted to have a function pointer to a function that does and, and you don't mind behavior different than the "real" and, then this would work:
(define and-l (lambda (a b) (and a b)))
Which you can apply like this:
(apply and-l (list #t #f))
The two caveats are:
All of the args get evaluated, in violation of the definition of and, which should have shortcutting behavior.
Only two arguments are allowed.
I've stumbled across the same problem and found an elegant solution in Racket.
Since the problem is that "and" is a macro and not a function in order to prevent the evaluation of all its arguments, I've read a little on "lazy racket" and found that "and" is a function in that language. So I came up with the following solution where I just import the lazy and as "lazy-and":
#lang racket
(require (only-in lazy [and lazy-and]))
(define (mm)
(map number? '(1 2 3)))
(printf "~a -> ~a\n" (mm) (apply lazy-and (mm)))
which yields
(#t #t #t) -> #t
try this:
(define list-and (lambda (args) (and (car args) (list-and (cdr args)))))
then you can use apply to list-and!
You could also use
(define (andApply lBoo)
(if (not (car lBoo)) #f
(if (= 1(length lBoo)) (car lBoo)
(andApply (cdr lBoo)))))
I also bump into this problem playing with PLT-Scheme 372, I have digged into the behavior of and-syntax, and figure out the follow code which works just as if one would intuitively expect (apply and lst) to return, but I haven't done exaustive test.
(define (list-and lst)
(cond
((null? lst) '())
((not (pair? lst)) (and lst))
((eq? (length lst) 1) (car lst))
(else
(and (car lst)
(list-and (cdr lst))))
)
)
Welcome to DrScheme, version 372 [3m].
Language: Textual (MzScheme, includes R5RS).
> (eq? (and '()) (list-and '()))
#t
> (eq? (and '#f) (list-and (list '#f)))
#t
> (eq? (and 'a) (list-and (list 'a)))
#t
> (eq? (and 'a 'b) (list-and (list 'a 'b)))
#t
> (eq? (and 'a 'b '()) (list-and (list 'a 'b '())))
#t
> (eq? (and 'a 'b '#t) (list-and (list 'a 'b '#t)))
#t
> (eq? (and 'a 'b '#f) (list-and (list 'a 'b '#f)))
#t
I've also figured out another mind-trapping workaround. I call it mind-trapping because at first I don't know how to turn it into a function... Here it is (only a demo of my intuitive idea):
Welcome to DrScheme, version 372 [3m].
Language: Textual (MzScheme, includes R5RS).
> (eval (cons 'and (list ''#f ''#f ''#t)))
#f
> (eval (cons 'and (list ''a ''b ''c)))
c
But later I asked a question and got the answer here: Is it possible to generate (quote (quote var)) or ''var dynamically? . With this answer one can easily turn the above idea into a function.
(define (my-quote lst)
(map (lambda (x) `'',x) lst))
(cons 'and (my-quote (list 'a 'b 'c)))
=> '(and ''a ''b ''c)

Resources