tags:

views:

128

answers:

3

In Scheme, how can I make use of the define/lambda shorthand for nested lambda expressions within my define?

For example given the following procedure...

(define add
  (lambda (num1 num2)
    (+ num1 num2)))

One can shorten it to this:

(define (add num1 num2)
  (+ num1 num2))


However, how can I shorten the following function similarly ?

(define makeOperator
  (lambda (operator)
    (lambda (num1 num2)
      (operator num1 num2))))

;example useage - equivalent to (* 3 4):
((makeOperator *) 3 4)
+5  A: 
(define (makeOperator operator)
  (lambda (num1 num2)
    (operator num1 num2)))

The second lambda can not be shortened.

Well you could shorten it to (define (makeOperator operator) operator), if you don't want to enforce that the returned function takes exactly two arguments.

sepp2k
Thanks - I'll +1 you once my vote limit resets :). http://www.scheme.com/tspl2d/start.html#g1642 - if you scroll down a bit, the author seems to be talking about some kind of dot syntax for shortening defines. Any idea what he's talking about?
Cam
@incrediman: Yes, he's talking about `(define (f . xs) ...)` which will allow you to call f with an arbitrary number of arguments (e.g. `(f 1 2 3 4 5)`) and `xs` will be a list containing those arguments.
sepp2k
Ahhh. Gotcha - thanks. That's actually quite useful itself, so I'm glad I asked :)
Cam
+1  A: 

Contrary to the above answer, the second lambda can use the shorthand define notation:

(define (makeOperator operator)
  (define (foo num1 num2)
    (operator num1 num2))
  foo)
Eli Barzilay
It's not really the same thing. In my simpler shorthand, no extra variables are declared, but here you're declaring foo. So while it does use the define syntax, it is not really shorthand. Plus it's longer than the lambda version by sepp2k. /end relatively uneducated opinion
Cam
(a) I didn't say that it's shorter -- only that it uses the *shorthand* `define` form which is what you asked about; (b) your question was whether it's possible to use this notation for an internal `lambda` -- obviously, this would come with an extra name because that's exactly what `define` does: there's no way to use it without a name.
Eli Barzilay
Oh, and BTW, if your goal is to just make it short, then as sepp2k said you can use `(define (makeOperator operator) operator)`, and if you really want to go all the way: `(define makeOperator values)` is roughly the same.
Eli Barzilay
@Eli: I think he might have been looking for something like `(define ((makeOperator operator) num1 num2) operator num1 num2)`, i.e. curried function definition, which does not exist in scheme (but could probably be implemented with a macro).
sepp2k
@sepp2k: Yes, that's what I was looking for - thanks. @Eli: On second thought this actually does answer my question fairly well, even though it's not exactly what I was looking for, so +1. Also I do realize that my trivial example can be simplified :) Thanks.
Cam
@incrediman: Yeah, I though it would help to clarify the difference. Also, I suspect that the curried definition that sepp2k mentioned (and Michal made into an answer) is closer to what you'd want -- *but* if you're at that level of getting to know the language, it's best to avoid it for now. It will only make things confusing. (And you can easily get back to it when you're more fluent.)
Eli Barzilay
+3  A: 

Some implementations of Scheme -- like Guile (tested with version 1.8) and MIT Scheme -- provide the following shorthand notation:

(define ((foo x) y) (+ x y))

(foo 5)
; => procedure
((foo 5) 3)
; => 8

I believe this notation is used quite a lot in Structure and Interpretation of Classical Mechanics.

Michał Marczyk