Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[LISP Beginner] Recursion Problem

8 views
Skip to first unread message

Ingo Rohlfs

unread,
Nov 11, 2001, 9:16:24 AM11/11/01
to
(defun get-elements (text_seq)
(if (null (length text_seq))
NIL
(let ((arg (subseq text_seq 0 (position #\Space text_seq ))))
(if (numberp (position #\Space text_seq))
(cons arg (get-elements (subseq text_seq
(+ (position #\Space text_seq) 1))))
(cons arg text_seq)))))

This code is intendet to seperate a string at Spaces an put the elements in
a list but it doesnt work as it supposed to be !
Everytime i get a dottet duplicate of the last element of the sequenz


What I'm doing wrong ?

Ingo

JP Massar

unread,
Nov 11, 2001, 11:00:23 AM11/11/01
to

The last line of your function is the problem. See if you can figure
it out from this hint.

Also, you are evaluating (position #\Space text_seq) three times, when
you could evaluate it once. Use LET* to put it in a variable before
ARG.

Also, most Lisp programmers use '-', not '_', as a separator within a
symbol. E.g., 'text-seq', not 'text_seq'.


Martti Halminen

unread,
Nov 11, 2001, 11:06:12 AM11/11/01
to

Your problem is the case with no spaces in text_seq: then arg is the
same as text_seq, so what your last form does is (cons "str" "str"). You
should try it with (cons arg nil).

- A little misconception here, too: (length text_seq) returns either a
number or causes an error when given a non-sequence, so testing it with
(null ...) isn't very useful. Were you thinking about ZEROP, perhaps? Or
something like ignore-errors if you can't guarantee this will only get
called with sequences?

a little rewriting for readability:

(defun get-elements2 (text_seq)
(if (null text_seq)
NIL
(let* ((pos (position #\Space text_seq ))
(arg (subseq text_seq 0 pos)))
(if (numberp pos)
(cons arg (get-elements (subseq text_seq (1+ pos))))
(list text_seq)))))

--

Erik Naggum

unread,
Nov 11, 2001, 2:44:00 PM11/11/01
to
* Ingo Rohlfs <iro...@irohlfs.de>
| What I'm doing wrong?

Basically, using recursion for this problem, which is only confusing
yourself and wasting a lot of space. This is a shot with a _much_ more
powerful technique, iteration, using loop, which is very good for this
kind of problem. (Some would tell you that since it is possible to get
lost in loop, you should not even try it. Ignore them and trust your own
ability to recognize when you are about to get lost. The same is true of
recursion, when you get lost in it, it is unsuited for the task. Some
people, especially those overexposed to Scheme, never seem to grasp this.)

(defun get-elements (sequence)
(loop
for start = 0 then (1+ end)
for end = (position #\Space sequence :start start)
collect (subseq sequence start end)
until (not end)))

///
--
Norway is now run by a priest from the fundamentalist Christian People's
Party, the fifth largest party representing one eighth of the electorate.
--
Carrying a Swiss Army pocket knife in Oslo, Norway, is a criminal offense.

Kent M Pitman

unread,
Nov 11, 2001, 3:19:37 PM11/11/01
to
Erik Naggum <er...@naggum.net> writes:

> (defun get-elements (sequence)
> (loop
> for start = 0 then (1+ end)
> for end = (position #\Space sequence :start start)
> collect (subseq sequence start end)
> until (not end)))

Or

(defun get-elements (sequence)
(loop with len = (length sequence)


for start = 0 then (1+ end)
for end = (position #\Space sequence :start start)

unless (eql start (or end len))


collect (subseq sequence start end)
until (not end)))

which is more tolerant of strings like " foo bar baz ".

ingo....@sit.fraunhofer.de

unread,
Nov 11, 2001, 5:04:35 PM11/11/01
to

Thanks for all ! You helped me very well.
Also i have learned to think more in LISP than in C

I solved my problem and some others too.

Thank you to all


Greetings
Ingo

0 new messages