user2276280
user2276280

Reputation: 601

Getting #<undef> back when calling a scheme function

I have the following code in Scheme:

(define (processExpression lst)
     (define operand (car lst))
     (define operator1 (cadr lst))
     (define operator2 (caddr lst))

     (if (list? operand) 
          (begin
             (display "Invalid syntax! Erroring out!")
             (quit)
         )
      )

      (if (and (number? operator1) (number? operator2))
          ;The list was of the form (operand c1 c2)
          (simplePrefix lst)
      )

     (if (and (list? operator1) (number? operator2))
          (begin
             (list operand operator2 (processExpression operator1))     
         )
     )
   )

  (define (simplePrefix lst)

       (let (
         (operand (car lst))
         (operator1 (cadr lst))
         (operator2 (caddr lst)))

         (list operator1 operand operator2)
     )

  )

 (display "Please enter a valid s-expression")
 (let ((input (read)))
     (display (simplePrefix input))
 )

This code takes and s-expression and converts it based on some rules. One rule should be that the expression (+ (+ 1 2) 2) should return (+ 2 (1 + 2)).

Currently when I call this code with that expression I get back the result "#undef>" but I have no idea why. The code should call the simplePrefix function on the (+ 1 2) part of the expression and return (1 + 2) but it does not. Does anyone understand why?

Upvotes: 0

Views: 1136

Answers (2)

molbdnilo
molbdnilo

Reputation: 66441

The expression

(if condition result)

is not equivalent to

if condition
   return result

in other languages.
It doesn't return a value, it has a value. If the condition is false, that value is undefined.
If it is followed by other expressions in a sequence, the value is ignored and the following expressions are evaluated.

The result of evaluating a function application is the value of the last expression in the function's body

(define (foo) 
  (if (= 1 1)
      "one is one")
  "I am still here")


> (foo)
"I am still here"

These two added together lead to the error you're experiencing.

Upvotes: 0

Joshua Taylor
Joshua Taylor

Reputation: 85883

The value of

(if condition
   something)

is undefined if condition is false, because there's no else part in the if form. In the R5RS version of Scheme, this is stated (emphasis added):

4.1.5 Conditionals

syntax: (if <test> <consequent> <alternate>)
syntax: (if <test> <consequent>)
Syntax: <Test>, <consequent>, and <alternate> may be arbitrary expressions.

Semantics: An if expression is evaluated as follows: first, <test> is evaluated. If it yields a true value (see section 6.3.1), then <consequent> is evaluated and its value(s) is(are) returned. Otherwise <alternate> is evaluated and its value(s) is(are) returned. If <test> yields a false value and no <alternate> is specified, then the result of the expression is unspecified.

(if (> 3 2) 'yes 'no)                   ===>  yes
(if (> 2 3) 'yes 'no)                   ===>  no
(if (> 3 2)
    (- 3 2)
    (+ 3 2))                            ===>  1

Some Scheme-like languages (e.g., Racket) will actually warn you if you try this:

Welcome to Racket v6.1.
> (if #t
    (display "hello"))
stdin::1: if: missing an "else" expression
  in: (if #t (display "hello"))
  context...:

In Common Lisp, the else part is optional, and defined to be nil if not provided:

This is SBCL 1.2.4.58-96f645d, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
* (if t
    (print 'hello))

HELLO 
HELLO
* (if nil
    (print 'hello))

NIL

Upvotes: 2

Related Questions