views:

220

answers:

2

I'm trying to make a truth-table generator for a digital electronics course because that's how I have fun in my spare time and don't judge me.

Anywho, I figured I'd have a hash with the string equivalent of operators as keys, and the Scheme procedures that correspond to those operators as values.

E.g.

(define  operator-table #hash(("+" . or)
                              ("*" . and)))

So I could do something like

(lambda (a b) ((hash-ref operator-table (string-ref input-str i)) a b))

Now I realize the above probably won't work right, but as it is I can't even tinker with it until I get it right, because apparently and and or are special in Scheme. At the REPL, if I type in not it replies #<procedure:not>. But if I give it and or or, it says and: bad syntax in: and. Is there a procedure version of and I can use? Or do I have to make one with lambda? Or am I missing something entirely?

The only reason I didn't just go with lambda from the get-go is that I don't want to lose the variable-arity abilities of the builtin and [I can do (and #t #f) as well as (and #t #f #f #t #f #t)].

+3  A: 

Yep, they can't be procedures because Scheme (like most languages) is an "eager" language -- every argument to a procedure gets evaluated before the procedure takes control (receiving the argument values). and and or need to "short-circuit" -- stop argument evaluation as soon as the final result is known -- so they can't be regular procedures/functions in any eager language ("lazy" languages, such as Haskell -- where each argument is evaluated only if, when and as needed -- are a very different breed, and don't need this "regular function" versus "special form" distinction... but, alas, Scheme just isn't one of those!).

Alex Martelli
Some notes:1. PLT Scheme is not like any scheme -- specifically, it includes a "lazy" scheme dialect, where `and` and `or` and `if` are plain functions.2. It is *wrong* to say that lazy languages don't need this distinction -- there are certainly cases where a lazy language needs special forms -- for example, `where` in Haskell is still not a function. In addition, if you want any kind of "strict" operator (as is included in Haskell) then this operator itself must be a special form too!
Eli Barzilay
Aha! That makes sense! I didn't consider short-circuiting
leo-the-manic
+5  A: 

If you want to use a function form of and and or (with the limitation that they will not short-circuit) and not lose the variable arity property, then you can easily do so:

(define (and* . xs) (andmap values xs))
(define (or*  . xs) (ormap values xs))

(values is the idiomatic identity function in (PLT) Scheme.)

Eli Barzilay