-2

I have the following function

(defun testIf (n)
  (if (<= n 0) t)
  print "Hello World")

My issue is when I test (testIf -1), it returns "Hello World". Therefore I am wondering why the if was completely ignored. Keep in mind, I just want an if in this program, no else chain. Any help would be appreciated.

To clear up confusion I am attempting to do something similar to this in lisp(as java has data types I had to compensate for this in this example)

public int testIf(n)
{
    if(n <= 0)
        return 5;

    System.out.println("Hello "World");
    return 0;
}

testIf(-1);

In Java the 5 would be returned and the next line would never be read..

Elias Mårtenson
  • 3,820
  • 23
  • 32
JmanxC
  • 377
  • 2
  • 16
  • Have you look at the Lisp documentation for how to do an "if" statement? – lurker Jun 15 '16 at 00:34
  • Yes I have and it indicates you can do (if "test expression" "then expression") – JmanxC Jun 15 '16 at 00:35
  • This is common lisp I am using LispWorks – JmanxC Jun 15 '16 at 00:44
  • Why don't you just use the opposite condition, and choose the condition in which you want to print rather than the one that you don't want to print? `(if (> n 0) (print "Hello World"))` – lurker Jun 15 '16 at 00:44
  • This is a test procedure to try out what I have indicated in java(see edited question). I wish to have a function that receives any input, if its <=0 then return something, else I just want to continue with a bunch of different expressions(thus no else is needed). – JmanxC Jun 15 '16 at 00:56
  • 1
    `(return-from testIf 5)` will return a 5 from your function. If there's too much other stuff after that, it could be an indication that the code needs restructuring into smaller chunks. – lurker Jun 15 '16 at 00:56
  • Your last java example could be written `(if (plusp n) (prog1 0 (print "Hello World")) 5)`. – coredump Jun 15 '16 at 06:30

2 Answers2

3

The IF is not ignored; its return value is just discarded, because there is another form after it. A function returns the value(s) from the last form of the body. Consider this function

(defun foo ()
  1
  2)

Would you expect that to return 1? Of course not. That would be completely counterintuitive. An IF is just a form like any other, so why would its result be returned in your function?

You could use RETURN-FROM to do an early return from the function:

(defun test-if (n)
  (when (<= n 0) ; You should use WHEN instead of IF when there's no else-branch.
    (return-from test-if t))
  (print "Hello World"))

However, in most situations that is not idiomatic. Remember that Lisp is a very different language from Java and you should not try to write Java in Lisp. It's better to just put the PRINT in the else-branch. If the else-branch has multiple forms, you can use COND instead:

(defun test-if (n)
  (cond ((<= n 0) t)
        (t (print "Hello World")
           :foo
           :bar
           :quux)))
jkiiski
  • 8,206
  • 2
  • 28
  • 44
0

In java the 5 would be returned and the next line would never be read..

jkiiski's answer correctly explains the behavior, but it's worth pointing out that the Lisp code you wrote is not like the Java code that you wrote. If you wanted to translate the Java code literally, you'd do:

(defun testIf (n)
  (if (<= n 0)
    (return-from testIf 5))
  (print "Hello World")
  (return-from testIf 0))

which does return 5 when n is less or equal to 0.

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353