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

weird loop

6 views
Skip to first unread message

Knut Olav Bøhmer

unread,
Nov 20, 2002, 5:15:48 AM11/20/02
to

Hello everyone,

I tried to run this under CMUCL, but it would not use my splitchar
variable. Then I changed the code to not use the variable, but just
split on #\Space, and it worked.

Does anyone have any suggestion on why it does not work.

Is there anyway to make the loop use collect in stead of pushing it on
a list the way i do?

(defun splitloop (string splitchar)
(with-open-stream (output (make-string-output-stream))
(let ((splitwords))
(loop for c across string
do (case c
(splitchar (push (get-output-stream-string output) splitwords)) ; on this line
(t (write-char c output)))
finally (push (get-output-stream-string output) splitwords))
(nreverse splitwords))))


PS:
the reson for making this function is to learn lisp. I have also made
a split-function which use recursion, and i'm going to do some
benchmark on them.

--
Knut Olav Böhmer
_ _
/ / (_)__ __ ____ __
/ /__/ / _ \/ // /\ \/ / ... The choice of a
/____/_/_//_/\.,_/ /_/\.\ GNU generation

An ideal world is left as an exercise to the reader. (Paul Graham)

Frode Vatvedt Fjeld

unread,
Nov 20, 2002, 5:28:25 AM11/20/02
to
"Knut Olav Bøhmer" <kn...@linpro.no> writes:

> (defun splitloop (string splitchar)
> (with-open-stream (output (make-string-output-stream))

Look up with-output-to-string.

> do (case c
> (splitchar (push (get-output-stream-string output) splitwords))

> (t (write-char c output)))

The keys of a case-form are not evaluated, so here you are comparing
the variable c with the symbol splitchar. Replace it with a cond and
something like char=, and it will work.

--
Frode Vatvedt Fjeld

Knut Olav Bøhmer

unread,
Nov 20, 2002, 6:01:28 AM11/20/02
to
* Frode Vatvedt Fjeld

> "Knut Olav Bøhmer" <kn...@linpro.no> writes:
>
> > (defun splitloop (string splitchar)
> > (with-open-stream (output (make-string-output-stream))
>
> Look up with-output-to-string.

I did long time ago. I think it said something about
get-output-stream-string had undefined result on it.

> > do (case c
> > (splitchar (push (get-output-stream-string output) splitwords))
> > (t (write-char c output)))
>
> The keys of a case-form are not evaluated, so here you are comparing
> the variable c with the symbol splitchar. Replace it with a cond and
> something like char=, and it will work.

It's not possible to force an evaluation some how? Anyway it's
probably not the meaning. cond will do. I'll do some benchmark on that
too.

Erik Naggum

unread,
Nov 20, 2002, 6:10:19 AM11/20/02
to
* "Knut Olav Bøhmer" <kn...@linpro.no>

| I did long time ago. I think it said something about
| get-output-stream-string had undefined result on it.

Please check up on the documentation again.

| It's not possible to force an evaluation some how?

Well, the macro `case´ and its siblings are intended for compile-time
optimization, such that constant dispatch-tables that should cause a
single instruction to select a case may be employed.

--
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.

Frode Vatvedt Fjeld

unread,
Nov 20, 2002, 6:10:19 AM11/20/02
to
"Knut Olav Bøhmer" <kn...@linpro.no> writes:

> It's not possible to force an evaluation some how?

No.

--
Frode Vatvedt Fjeld

Pascal Costanza

unread,
Nov 20, 2002, 7:23:18 AM11/20/02
to
Frode Vatvedt Fjeld wrote:
> "Knut Olav Bøhmer" <kn...@linpro.no> writes:
>
>
>>It's not possible to force an evaluation some how?
>
>
> No.

You can do the following.

(case key
(#.expr1 (...))
(#.expr2 (...)))

#. evaluates the subsequent expression at read time. However, this only
works when the expressions (expr1, expr2) are constants or special
variables, for example.


Pascal

--
Pascal Costanza University of Bonn
mailto:cost...@web.de Institute of Computer Science III
http://www.pascalcostanza.de Römerstr. 164, D-53117 Bonn (Germany)

Matthew Danish

unread,
Nov 20, 2002, 8:05:36 AM11/20/02
to
Here's an implementation using LOOP in all its glory (well, not all):

(defun splitloop (string splitchar)
(with-output-to-string (output)


(loop for c across string

if (char= splitchar c)
collect (get-output-stream-string output) into splitwords
else do (write-char c output)
finally (return-from splitloop
(nconc splitwords
(list (get-output-stream-string output)))))))

I can't think of a better way to do the ``finally'' bit, so it's not
algorithmically more efficient than what you had.

This code removes the issue of having to traverse the list at the end,
but doesn't use LOOP's COLLECT:

(defun splitloop2 (string splitchar)
(let (splitwords last)
(flet ((add-word (word)
(if (null last)
(setf splitwords (list word)
last splitwords)
(setf (rest last) (list word)
last (rest last)))))
(with-output-to-string (output)


(loop for c across string

if (char= splitchar c)
do (add-word (get-output-stream-string output))
else do (write-char c output)
finally (add-word (get-output-stream-string output))))
splitwords)))

The ADD-WORD function could be part of a more general macro for doing this
sort of collection:

(defun splitloop3 (string splitchar)
(with-collection-function (add-word)
(with-output-to-string (output)


(loop for c across string

if (char= splitchar c)
do (add-word (get-output-stream-string output))
else do (write-char c output)
finally (add-word (get-output-stream-string output))))))

You could try implementing WITH-COLLECTION-FUNCTION as a simple exercise.

--
; Matthew Danish <mda...@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."

Knut Olav Bøhmer

unread,
Nov 20, 2002, 8:49:04 AM11/20/02
to

* 17: Frode Vatvedt Fjeld
> Look up with-output-to-string.


* "Knut Olav Bøhmer" <kn...@linpro.no>
> | I did long time ago. I think it said something about
> | get-output-stream-string had undefined result on it.

* Erik Naggum


> Please check up on the documentation again.

/me looking:
---------------------------------
Function GET-OUTPUT-STREAM-STRING

Exceptional Situations:

The consequences are undefined if string-output-stream is a stream
that was not produced by make-string-output-stream.

The consequences are undefined if string-output-stream was created
implicitly by with-output-to-string or format.
---------------------------------
/me still not sure.

consequences means the result of running the function?

* Erik Naggum


> | It's not possible to force an evaluation some how?
>
> Well, the macro `case´ and its siblings are intended for compile-time
> optimization, such that constant dispatch-tables that should cause a
> single instruction to select a case may be employed.

Ok, i'll try that too, just too see the benchmark. I'll have to wait
until I get home though.

Arthur Lemmens

unread,
Nov 20, 2002, 9:33:59 AM11/20/02
to

Knut Olav Bøhmer wrote:

> (defun splitloop (string splitchar)

You may be interested in the function SPLIT-SEQUENCE (or is it PARTITION-
SEQUENCE? I forgot which name they settled on), which was developed
in comp.lang.lisp a while ago. It does the same kind of thing that you're
trying to do, but in a more general way.

Arthur Lemmens

Knut Olav Bøhmer

unread,
Nov 20, 2002, 11:21:20 AM11/20/02
to
* Knut Olav Bøhmer

> * 17: Frode Vatvedt Fjeld
> > Look up with-output-to-string.
>
>
> * "Knut Olav Bøhmer" <kn...@linpro.no>
> > | I did long time ago. I think it said something about
> > | get-output-stream-string had undefined result on it.
>
> * Erik Naggum
> > Please check up on the documentation again.
>
> /me looking:
> ---------------------------------
> Function GET-OUTPUT-STREAM-STRING
>
> Exceptional Situations:
>
> The consequences are undefined if string-output-stream is a stream
> that was not produced by make-string-output-stream.
>
> The consequences are undefined if string-output-stream was created
> implicitly by with-output-to-string or format.
> ---------------------------------
> /me still not sure.
>
> consequences means the result of running the function?

Sorry for being annoying, but did I understand the hyperspec
correctly? I thought that since you guys said it should work, that I
had misunderstood something.

When I start with a new programming language, I don't have so much
confidens and trust in what I understand. fex when I read perldoc I
have completely trust in that I understand the documentation. I will
probably get that trust in the hyperspec in a while too. Maybe that is
one of my weaknesses.

Frode Vatvedt Fjeld

unread,
Nov 20, 2002, 11:46:17 AM11/20/02
to
"Knut Olav Bøhmer" <kn...@linpro.no> writes:

> Sorry for being annoying, but did I understand the hyperspec
> correctly? I thought that since you guys said it should work, that I
> had misunderstood something.

I think you understood it correctly. When I asked you to look up
with-output-to-string, I hadn't noticed you using
get-output-stream-string.

--
Frode Vatvedt Fjeld

0 new messages