-2

I am trying to create a lisp code that reads 2 integers and outputs all numbers between the two. my current code is

(defun range (x y)
  (if (< x y)
      x
      (1+ (range(x y))))

the code compiles and runs but only outputs "1".

uselpa
  • 18,732
  • 2
  • 34
  • 52
Matt
  • 57
  • 1
  • 6
  • 1
    'the code compiles'. How can it be compiled? It's not possible. It has two syntax errors. It's missing a parenthesis and `(range (x y))` is not a legal Lisp expression. – Rainer Joswig Aug 20 '16 at 09:56
  • @RainerJoswig If you add a closing parens to this, then CLISP doesn't complain about the code. Assuming that one got lost in the copy-paste operation his statement may indeed be true. – uselpa Aug 20 '16 at 10:03
  • sorry, missed a parenthesis when i typed the question. I'm unsure what you mean how is it not legal? isn't it just bad conventions? – Matt Aug 20 '16 at 10:06
  • @uselpa: CLISP: WARNING: in RANGE in lines 2..5 : RANGE was called with 1 arguments, but it requires 2 arguments. ;; Wrote file /tmp/test.fas The following functions were used but not defined: X – Rainer Joswig Aug 20 '16 at 10:06
  • @Matt: you have defined a function `range` with **two** arguments `x` and `y`. You are calling it with one. The argument expression is also wrong, since `X` is not a function. – Rainer Joswig Aug 20 '16 at 10:07
  • @RainerJoswig Funny, works OK on homebrew OS X version. – uselpa Aug 20 '16 at 10:10
  • @uselpa: did you compile it? Using GNU CLISP 2.49 . – Rainer Joswig Aug 20 '16 at 10:11
  • @RainerJoswig No I didn't. See the update to my answer. The code runs happily. – uselpa Aug 20 '16 at 10:13
  • @uselpa: you may want to test different inputs: (range 5 1) *** - EVAL: undefined function X ---- but anyway, he said he compiled it. – Rainer Joswig Aug 20 '16 at 10:15
  • What do you mean by "output"? A classical `range` would typically not output anything but return a list of numbers. @RainerJoswig It's more likely that the OP managed to evaluate it without errors. When running with `(range 1 anything-above-1)` the first predicate will be true and the result is the first argument. Of course if OP had added what he used to test we would have catched that right away. – Sylwester Aug 20 '16 at 12:10
  • Possible duplicate of [Python's range() analog in Common Lisp](http://stackoverflow.com/questions/13937520/pythons-range-analog-in-common-lisp) – Sylwester Aug 20 '16 at 12:15
  • @Sylwester: if he actually had compiled it, the compiler would have complained. `(compile 'range) WARNING: in RANGE : RANGE was called with 1 arguments, but it requires 2 arguments. WARNING: in RANGE : Function X is not defined` – Rainer Joswig Aug 20 '16 at 18:15
  • @RainerJoswig We agree this is most certaintly not compiled, but the OP thought so. Not all CL implementations does the same when functions are evaluated. SBCL actually compiles and prints out the compilation error right away while others doesn't. A tutorial might not be 100% accurate and might give the wrong idea what evaluating a `defun` form does. – Sylwester Aug 20 '16 at 19:08

1 Answers1

2

Not sure what exactly you want but the closest I could come up with is:

(defun range (x y)
  (when (< x y)
    (print x)
    (range (1+ x) y)))

Testing

CL-USER> (range 3 7)

3 
4 
5 
6 
NIL

Pay attention to

  • indent your code properly
  • use when (or cond or progn ...) if you want to do more than one action after a condition
  • the 1+ is used to increment a parameter, not the complete expression; think of it as a loop variable in a traditional language
  • your variable only becomes 'visible' outside the function if you print it, or add it to a result list.

Also, tag your question common-lisp for better visibility.

EDIT

proof that the original code does run on some instances of CLISP:

Welcome to GNU CLISP 2.49 (2010-07-07) <http://clisp.cons.org/>

[1]> (range 1 5)

*** - EVAL: undefined function RANGE
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead of (FDEFINITION 'RANGE).
RETRY          :R2      Retry
STORE-VALUE    :R3      Input a new value for (FDEFINITION 'RANGE).
ABORT          :R4      Abort main loop
Break 1 [2]>
[3]> (defun range (x y)
  (if (< x y)
      x
      (1+ (range(x y)))))
RANGE
[4]> (range 1 5)
1
[5]>
sds
  • 58,617
  • 29
  • 161
  • 278
uselpa
  • 18,732
  • 2
  • 34
  • 52