5
(foldr + 0 '(1 2 3 4))

returns 10 which is what I expect, but

(foldr and false '(true true false))

gives me the error

and: expected an open parenthesis before and, but found none

foldr takes a function (which takes two parameters, since I have one list), and a base case, and a list(s). I expect my second line of code to return true if the list has more than zero booleans and they are all true, and that is how I thought it would work. But apparently not.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
newprogrammer
  • 2,514
  • 2
  • 28
  • 46

2 Answers2

8

And is a special form and won't work with foldr, which is expecting a procedure as its second argument. Try this instead:

(foldr (lambda (x y) (and x y)) #t '(#t #t #f)) ;#t as base case

Another alternative for this particular case would be using andmap:

(andmap identity '(#t #t #f))
Ron F
  • 37
  • 6
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • Well, I am using Racket, and that line of code still gives me the error: "and: question result is not true or false: 'false". – newprogrammer Mar 14 '12 at 00:44
  • That second one gives me the error "andmap: expected a boolean from identity (the function given to andmap), but received 'true". Maybe it's something to do with the fact that I'm using Racket, not Scheme – newprogrammer Mar 14 '12 at 00:46
  • I'm using racket, too and it works for me. What language are you using? – Óscar López Mar 14 '12 at 00:46
  • 1
    Try changing all `true` occurrences for `#t` and `false` for `#f` and see if it works – Óscar López Mar 14 '12 at 00:47
  • 1
    @newprogrammer: `'false` and `#f` are two different things. `#t` and `#f` are the boolean values that and seeks. In #lang racket, both `(and #t #f)` and `(and #f #t)` return `#f`, but `(and 'true 'false)` returns `'false` while `(and 'false 'true)` returns `'true`. – ccoakley Mar 14 '12 at 00:49
  • Hey, the first example you gave works now! I was using DrRacket, Advanced Student. Thanks! – newprogrammer Mar 14 '12 at 00:49
  • @newprogrammer I edited my code. Initially I didn't see the problem because in my language `false` is defined as `#f` and `true` as `#t`, but apparently that's not the case in your environment – Óscar López Mar 14 '12 at 00:51
  • @ccoakley: (and 'true 'false) gives me the error "and: question result is not true or false: 'true". I'm not sure what it means to type 'true, with the apostrophe, rather than true, and I've never seen #t and #f before. – newprogrammer Mar 14 '12 at 00:52
  • `'true` is a _symbol_, whereas `true` is (or should be) the same as `#t`, the logical value for true. – Óscar López Mar 14 '12 at 00:55
  • If that is the case, I am wondering why I need to use `#t` and `#f` right now, as I've always used `true` and `false` without issue. Hmm – newprogrammer Mar 14 '12 at 00:57
  • @newprogrammer: that's an issue of which #lang you are using. In #lang racket, the and special form is a little looser in its data type requirements. `'true` is just a symbol. In your list `'(true true false)`, you were providing a list of three symbols. Note that without quoting, true and false should work. so you could have used `(foldr (lambda (x y) (and x y)) false (list true true false))` – ccoakley Mar 14 '12 at 00:58
  • I thought `'(true true false)` would be a list of booleans, and `'('true 'true' false)` would be a list of symbols. After all, `'(1 2 3)` is a list of numbers, not a list of symbols. Edit: Well, your function works, without the whole `#t` and `#f` thing, so I guess it must be turning them into symbols. – newprogrammer Mar 14 '12 at 00:59
  • It's related to the way the quotation is being evaluated. For instance, this works fine with Advanced Student: `(foldr (lambda (x y) (and x y)) false (list true true false))` – Óscar López Mar 14 '12 at 01:03
  • @newprogrammer: sorry, the rules on quoting are a bit confusing at first (note, there's no symbol `'2`, only the number 2). You'll get used to it. – ccoakley Mar 14 '12 at 01:08
  • 1
    @ron-f for `or` it would be `#f`, not `#t` like it is for `and`. – Will Ness Jan 18 '19 at 11:09
0

In a Scheme system, and is typically defined as a macro or special form and not as a procedure, which is why it doesn't work:

#;1> +
#<procedure C_plus>
#;2> and

Error: unbound variable: and
Will Ness
  • 70,110
  • 9
  • 98
  • 181
Justin Ethier
  • 131,333
  • 52
  • 229
  • 284