From: Knut Olav Bøhmer
Subject: weird loop
Date: 
Message-ID: <ujpn0o4v963.fsf@perl.linpro.no>
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)

From: Matthew Danish
Subject: Re: weird loop
Date: 
Message-ID: <20021120080536.R19796@lain.cheme.cmu.edu>
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 <·······@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."
From: Frode Vatvedt Fjeld
Subject: Re: weird loop
Date: 
Message-ID: <2h65us8rhy.fsf@vserver.cs.uit.no>
"Knut Olav B�hmer" <·····@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
From: Knut Olav Bøhmer
Subject: Re: weird loop
Date: 
Message-ID: <ujpisysv71z.fsf@perl.linpro.no>
* Frode Vatvedt Fjeld
> "Knut Olav B�hmer" <·····@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.

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

An ideal world is left as an exercise to the reader. (Paul Graham)
From: Erik Naggum
Subject: Re: weird loop
Date: 
Message-ID: <3246779419850506@naggum.no>
* "Knut Olav B�hmer" <·····@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.
From: Knut Olav Bøhmer
Subject: Re: weird loop
Date: 
Message-ID: <ujpel9guzan.fsf@perl.linpro.no>
* 17: Frode Vatvedt Fjeld 
> Look up with-output-to-string.


* "Knut Olav B�hmer" <·····@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.

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

An ideal world is left as an exercise to the reader. (Paul Graham)
From: Knut Olav Bøhmer
Subject: Re: weird loop
Date: 
Message-ID: <ujpadk4us8v.fsf@perl.linpro.no>
* Knut Olav B�hmer
> * 17: Frode Vatvedt Fjeld 
> > Look up with-output-to-string.
> 
> 
> * "Knut Olav B�hmer" <·····@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.

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

An ideal world is left as an exercise to the reader. (Paul Graham)
From: Frode Vatvedt Fjeld
Subject: Re: weird loop
Date: 
Message-ID: <2hd6p06vfq.fsf@vserver.cs.uit.no>
"Knut Olav B�hmer" <·····@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
From: Frode Vatvedt Fjeld
Subject: Re: weird loop
Date: 
Message-ID: <2h1y5g8pk4.fsf@vserver.cs.uit.no>
"Knut Olav B�hmer" <·····@linpro.no> writes:

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

No.

-- 
Frode Vatvedt Fjeld
From: Pascal Costanza
Subject: Re: weird loop
Date: 
Message-ID: <3DDB7EB6.4090303@web.de>
Frode Vatvedt Fjeld wrote:
> "Knut Olav B�hmer" <·····@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
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Arthur Lemmens
Subject: Re: weird loop
Date: 
Message-ID: <3DDB9D57.974FAAA7@xs4all.nl>
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