Re: Newbie lisp problem: string to list of strings separated by space
- From: Yossarian <yossarian@xxxxxxxxxxx>
- Date: Fri, 31 Mar 2006 17:20:37 +0200
Alan Crowe wrote:
Yossarian <yossarian@xxxxxxxxxxx> writes:
Hi,
I am trying to write a very simple function that accepts a string as input, and that returns a list of strings as output, having a seperate list item for every substring without a space.
Example:
input = "something very odd"
output = ("something" "very" "odd")
I tried to do this with the following function, but I can't understand why it is not working.
(defun parse(a)
(setq pos (or (position #\space a) -1) )
(cond ((= pos -1) (list a))
((> pos -1) (append
(parse (subseq a 0 pos))
(parse (subseq a (+ pos 1) (length a)))))))
Any comment is welcome!
Your design is basically correct but inefficient.
First you need to make pos a local variable
(let ((pos ..... some number of closing parens
(cond ....
^
|
`---- notice the indentation
Your editor will indent your code for you. In emacs its
ctrl-alt-h to set the region to the enclosing defun and
crtl-alt-\ to adjust the indentation.
If this makes it line up
(let ((pos ... (cond
you have one too many closing parentheses on the previous line
The other way to check is to position the cursor at the end
of the init forms
Position cursor here
|
|
V
(let ((pos ....))
^ ^
| |
These two get highlighted as the matching parentheses
In emacs you enable this with meta-x show-paren-mode
Next point is that the position function is carefully
designed to return either the position or Common Lisp's
false value, NIL, with the intention that the value is
directly usable as a boolean. Maybe I should say that the
other way round, Common Lisp's if operator is carefully
designed so that all numbers, including 0, count as
true. Thus the value returned by position is directly usable
as a boolean
(let ((pos ...))
(if pos
(code for when position is a number)
(code for when position is false)))
(append
(parse (subseq a 0 pos))
(parse (subseq a (+ pos 1) (length a))))
This could be
(cons
(subseq a 0 pos)
(parse (...as before...)))
Position finds the first matching item, so there is no need
to re-parse the leading subsequence.
The end argument to subseq is optional. You could just say
(subseq a (+ pos 1))
and that would also copy all the way to the end.
This brings up the efficiency issue. If there are many
separators the code copies the remaining characters many
times, so the run time is quadratic in the length of the
string when it ought to be linear.
The simplest solution is to add a numerical start argument
to parse, and use the :start key-word for position.
New programming languages often have annoying gaps.
Common Lisp was a unification effort, intended to unify
various previous dialects of Lisp. The upside is that Common
Lisp was an "old" language even when it was "new". The gaps
had all been discovered by programmers working on previous
dialects and Common Lisp ensured that they were all filled.
The ????-side is that it is a big language that combines
lots of useful features. Look at the examples that have been
posted using the LOOP macro.
That presents a problem to the autodidact. If you just
plunge in you are likely to spread yourself too thinly over
many different features and become frustrated. It is
probably best to follow a systematic tutorial. Graham's ANSI
Common Lisp is highly regarded as fast paced tutorial for
those already familiar with programming. (It is the book I
read to learn Common Lisp) It will be interesting to see if
Peter Seibel's impressive Practical Common Lisp
http://www.gigamonkeys.com/book/functions.html
suplants it.
Alan Crowe
Edinburgh
Scotland
Thanks a lot! That's what I call a valuable answer! ... think you showed some essential properties of functional programming, and Common Lisp in particular. I didn't realize that indentation could be that important.
I indeed plan to read Graham's book, which seems to be "the" common lisp book. I used Haskell some years ago, and was to optimistic in the idea that it wouldn't take that much time to do some elementary stuff in lisp. I know better now ...
regards,
wouter
.
- References:
- Newbie lisp problem: string to list of strings separated by space
- From: Yossarian
- Re: Newbie lisp problem: string to list of strings separated by space
- From: Alan Crowe
- Newbie lisp problem: string to list of strings separated by space
- Prev by Date: Re: What language will be used to write the first self aware program?
- Next by Date: Re: Common Lisp implementations are still multiple times slower than C
- Previous by thread: Re: Newbie lisp problem: string to list of strings separated by space
- Next by thread: learning lisp
- Index(es):
Relevant Pages
|