Search code examples
functionlambdaschemechicken-scheme

nested lambda in scheme


I'm trying to define a function in scheme that prints a message when called, followed by a newline. To do this I've attempted to use nested lambda like this:

(define message 
    (lambda (msg)
        (lambda (newL) 
            (newline)
        )
    (display msg))  
)

However, when I do this, and call the function like:

(message "#f")

it only prints the #f, and does not create a newline. If I reverse the lambda orders in the function and swap the position of the newL and msg lambda's, then it only prints a newline and doesn't display the message!

The function is called in this block of code:

(define (permute upList)
    (if (null? upList)
        (message "#f")
         ;permutation code
    )
)    

The error message received when not using nested lambda's is as follows:

Error: call of non-procedure: #

    Call history:

    <syntax>          (permute (quote ()))
    <syntax>          (quote ())
    <syntax>          (##core#quote ())
    <eval>    (permute (quote ()))
    <eval>    [permute] (null? upList)
    <eval>    [permute] (message "#f")
    <eval>    [message] ((display msg) (newline))
    <eval>    [message] (display msg)
    <eval>    [message] (newline)   <--

Any help would be appreciated.


Solution

  • In this code, you only create a procedure object, which is then immediately discarded:

    (define message 
      (lambda (msg)
        (lambda (newL) 
          (newline))
        (display msg)))
    

    It's like doing:

    (define message 
      (lambda (msg)
        1234
        (display msg)))
    

    The 1234 here is evaluated, but the value is completely ignored.

    If you have a procedure and you want to call it immediately, you have to wrap in an extra set of parentheses (because in Scheme, in general, parens represent application):

    (define message 
      (lambda (msg)
        ((lambda (newL) 
           (newline)) #f)
        (display msg)))
    

    But, as others have pointed out, there's no need to create a nested lambda in this case. Plus, the procedure ignores its argument anyway, which is why I had to invent an argument to pass; I used #f because that's the typical "don't care" value. You can just do:

    (define message 
      (lambda (msg)
        (newline)
        (display msg)))