From: Mike
Subject: Working on learning lisp
Date: 
Message-ID: <gk10ie$ge9$1@news.motzarella.org>
My chosen learning project has me stumped at the moment. I have this code

(defun split-string (string &optional (separators " ,-"))
  "Splits STRING into a list of substrings (which is returned)
  separated by the characters in the sequence SEPARATORS.  Empty
  substrings aren't collected."
  (flet ((make-collector ()
                         (make-array 0
                                     :adjustable t
                                     :fill-pointer t
                                     :element-type #+:lispworks 'lw:simple-char
                                     #-:lispworks 'character)))
    (loop with collector = (make-collector)
          for char across string
          for counter downfrom (1- (length string))
          when (find char separators :test #'char=)
          when (plusp (length collector))
          collect collector
          and do (setq collector (make-collector)) end
          else
          do (vector-push-extend char collector)
          and when (zerop counter)
          collect collector)))
(print (split-string "<html><body></body></html>" "<"))

=>

("html>" "body>" "/body>" "/html>")

I'm trying to understand the defun above to modify the code to
include the leading '<' in the returned list. Every place I've
haphazardly placed a (setq counter (1- counter)) (assuming that
counter is an index for a substr(3)) doesn't work.

Someone, please explain what the extended loop code is doing and
how I can modify the code to include the '<'.

(I copied the code from http://common-lisp.net/~loliveira/ediware/drakma/util.lisp)

Thanks

Mike

From: Raffael Cavallaro
Subject: Re: Working on learning lisp
Date: 
Message-ID: <2009010620524211272-raffaelcavallaro@pasespamsilvousplaitmaccom>
On 2009-01-06 20:29:51 -0500, Mike <·····@mikee.ath.cx> said:

> I'm trying to understand the defun above to modify the code to
> include the leading '<' in the returned list.

If you look at the first line of (defun split-string ... you'll see 
that it takes an optional separators parameter. Your call to it:

(print (split-string "<html><body></body></html>" "<"))

includes a separarators string, namely "<"

It is in the nature of splitting a string on a separator that the 
separator, by definition, is not part of the split strings. IOW, the 
counter is not the issue - you're trying to include a separator in the 
split strings themselves. If you look at your input string, its 
elements are split by "><". If we try this:

CL-USER 121 > (split-string "<html><body></body></html>" "><")

("html" "body" "/body" "/html")

we get the elements without the angle brackets. All you need to do is 
wrap each returned string in angle brackets:

CL-USER 123 > (loop for elt in (split-string "<html><body></body></html>" "><")
                collect (concatenate 'string "<" elt ">"))
("<html>" "<body>" "</body>" "</html>")

which is, I believe, what you want.

-- 
Raffael Cavallaro, Ph.D.
From: Mike
Subject: Re: Working on learning lisp
Date: 
Message-ID: <gk12bm$452$1@news.motzarella.org>
On 2009-01-07, Raffael Cavallaro <················@pas.espam.s.il.vous.plait.mac.com> wrote:
> On 2009-01-06 20:29:51 -0500, Mike <·····@mikee.ath.cx> said:
>
>> I'm trying to understand the defun above to modify the code to
>> include the leading '<' in the returned list.
>
> If you look at the first line of (defun split-string ... you'll see 
> that it takes an optional separators parameter. Your call to it:
>
> (print (split-string "<html><body></body></html>" "<"))
>
> includes a separarators string, namely "<"
>
> It is in the nature of splitting a string on a separator that the 
> separator, by definition, is not part of the split strings. IOW, the 
> counter is not the issue - you're trying to include a separator in the 
> split strings themselves. If you look at your input string, its 
> elements are split by "><". If we try this:
>
> CL-USER 121 > (split-string "<html><body></body></html>" "><")
>
> ("html" "body" "/body" "/html")
>
> we get the elements without the angle brackets. All you need to do is 
> wrap each returned string in angle brackets:
>
> CL-USER 123 > (loop for elt in (split-string "<html><body></body></html>" "><")
>                 collect (concatenate 'string "<" elt ">"))
> ("<html>" "<body>" "</body>" "</html>")
>
> which is, I believe, what you want.
>

Duh, just add the '<' back instead of try to modify the code. Thanks.
That's a better solution that what I tried. The example string does
have the '><' pattern. In the actual data pulled over HTTP I don't
expect to follow that pattern so literally.

Mike
From: William James
Subject: Re: Working on learning lisp
Date: 
Message-ID: <gk1r7902scf@enews4.newsguy.com>
Mike wrote:

> My chosen learning project has me stumped at the moment. I have this
> code
> 
> (defun split-string (string &optional (separators " ,-"))
>   "Splits STRING into a list of substrings (which is returned)
>   separated by the characters in the sequence SEPARATORS.  Empty
>   substrings aren't collected."
>   (flet ((make-collector ()
>                          (make-array 0
>                                      :adjustable t
>                                      :fill-pointer t
>                                      :element-type #+:lispworks
> 'lw:simple-char                                      #-:lispworks
> 'character)))     (loop with collector = (make-collector)
>           for char across string
>           for counter downfrom (1- (length string))
>           when (find char separators :test #'char=)
>           when (plusp (length collector))
>           collect collector
>           and do (setq collector (make-collector)) end
>           else
>           do (vector-push-extend char collector)
>           and when (zerop counter)
>           collect collector)))
> (print (split-string "<html><body></body></html>" "<"))
> 
> =>
> 
> ("html>" "body>" "/body>" "/html>")
> 
> I'm trying to understand the defun above to modify the code to
> include the leading '<' in the returned list. Every place I've
> haphazardly placed a (setq counter (1- counter)) (assuming that
> counter is an index for a substr(3)) doesn't work.
> 
> Someone, please explain what the extended loop code is doing and
> how I can modify the code to include the '<'.


Ruby:

"<html><body></body></html>".split( /(?=<)/ )
    ==>["<html>", "<body>", "</body>", "</html>"]
From: =?ISO-8859-15?Q?Andr=E9_Thieme?=
Subject: Re: Working on learning lisp
Date: 
Message-ID: <gk39b4$cdc$1@news.motzarella.org>
William James schrieb:

> Ruby:
> 
> "<html><body></body></html>".split( /(?=<)/ )
>     ==>["<html>", "<body>", "</body>", "</html>"]

In Lisp it is the same:
(split "<html><body></body></html>" "(?=<)")


But what I find funny is that you, the guy who accuses others to cheat,
is now cheating himself. You do this basically every time when you try
to outperform Lisp with Ruby.
You change the task. The goal was not to just call split.
Of course, when doing so simple things like these even Comal/Ruby can
be as concise as Lisp. But you constantly lose, because I usually
provide Lisp code that outperforms your Com.. Ruby.
You get 3 points for not giving up. Just keep trying. The day might come
where you can reply to a posting, do what the posting asked for, and at
the same moment outproduce Lisp.


Andr�
-- 
From: Kaz Kylheku
Subject: Re: Working on learning lisp
Date: 
Message-ID: <20090113033700.123@gmail.com>
On 2009-01-07, André Thieme <······························@justmail.de> wrote:
> William James schrieb:
>
>> Ruby:
>> 
>> "<html><body></body></html>".split( /(?=<)/ )
>>     ==>["<html>", "<body>", "</body>", "</html>"]
>
> In Lisp it is the same:
> (split "<html><body></body></html>" "(?=<)")
>
>
> But what I find funny is that you, the guy who accuses others to cheat,
> is now cheating himself. You do this basically every time when you try
> to outperform Lisp with Ruby.
> You change the task. 

William James consistently shows a disregard for even the coarse points of a
requirement specification, never mind any fine details. It's literally as if
his newsreader drops every other word.  Someone like that should be properly
regarded as unemployable in the software business.
From: William James
Subject: Re: Working on learning lisp
Date: 
Message-ID: <gnsvob0fbu@enews5.newsguy.com>
Andr� Thieme wrote:

> William James schrieb:
> 
> > Ruby:
> > 
> > "<html><body></body></html>".split( /(?=<)/ )
> >    ==>["<html>", "<body>", "</body>", "</html>"]
> 
> In Lisp it is the same:
> (split "<html><body></body></html>" "(?=<)")

Wrong.

user=> (split "<html><body></body></html>" "(?=<)")
java.lang.Exception: Unable to resolve symbol: split in this context

Don't ever post untested code.

user=> (vec (.split "<html><body></body></html>" "(?=<)"))
["" "<html>" "<body>" "</body>" "</html>"]

Wrong again.  The first element is an empty string.  That's
not what the man wanted.



> 
> 
> But what I find funny is that you, the guy who accuses others to cheat,
> is now cheating himself.

Wrong again.

 You do this basically every time when you try
> to outperform Lisp with Ruby.

Wrong again.

> You change the task.

Wrong again.

>                       The goal was not to just call split.

He wanted to split on "<" and to include the "<" in the
resulting substrings.  That exactly what the Ruby does.


> Of course, when doing so simple things like these even Comal/Ruby can
> be as concise as Lisp. But you constantly lose,

Wrong again.

>                       because I usually
> provide Lisp code that outperforms your Com.. Ruby.

Your code outperforms nothing.  It doesn't perform at all.
After your botched code is repaired, it produces incorrect
output.  You lose again.  And you can produce half-way
decent code only when you are copying my Ruby code.


> You get 3 points for not giving up. Just keep trying. The day might come
> where you can reply to a posting, do what the posting asked for, and at
> the same moment outproduce Lisp.

Usually, you find it so difficult to process the provided data
that you have to replace it with simplified data that you can
handle.  Cheating and lying are as natural as breathing to you.
You probably don't realize that you are doing it.
Perhaps if you dropped programming and took up a hobby for
which you had a modicum of talent, your character would improve.
From: Marco Antoniotti
Subject: Re: Working on learning lisp
Date: 
Message-ID: <bacf2481-d2de-4127-ada6-e6f05559ede2@o11g2000yql.googlegroups.com>
On Feb 23, 2:56 am, "William James" <·········@yahoo.com> wrote:
> André Thieme wrote:
> > William James schrieb:
>
> > > Ruby:
>
> > > "<html><body></body></html>".split( /(?=<)/ )
> > >    ==>["<html>", "<body>", "</body>", "</html>"]
>
> > In Lisp it is the same:
> > (split "<html><body></body></html>" "(?=<)")
>
> Wrong.
>
> user=> (split "<html><body></body></html>" "(?=<)")
> java.lang.Exception: Unable to resolve symbol: split in this context
>
> Don't ever post untested code.
>
> user=> (vec (.split "<html><body></body></html>" "(?=<)"))
> ["" "<html>" "<body>" "</body>" "</html>"]
>
> Wrong again.  The first element is an empty string.  That's
> not what the man wanted.
>
>
>
> > But what I find funny is that you, the guy who accuses others to cheat,
> > is now cheating himself.
>
> Wrong again.
>
>  You do this basically every time when you try
>
> > to outperform Lisp with Ruby.
>
> Wrong again.
>
> > You change the task.
>
> Wrong again.
>
> >                       The goal was not to just call split.
>
> He wanted to split on "<" and to include the "<" in the
> resulting substrings.  That exactly what the Ruby does.
>
> > Of course, when doing so simple things like these even Comal/Ruby can
> > be as concise as Lisp. But you constantly lose,
>
> Wrong again.
>
> >                       because I usually
> > provide Lisp code that outperforms your Com.. Ruby.
>
> Your code outperforms nothing.  It doesn't perform at all.
> After your botched code is repaired, it produces incorrect
> output.  You lose again.  And you can produce half-way
> decent code only when you are copying my Ruby code.
>
> > You get 3 points for not giving up. Just keep trying. The day might come
> > where you can reply to a posting, do what the posting asked for, and at
> > the same moment outproduce Lisp.
>
> Usually, you find it so difficult to process the provided data
> that you have to replace it with simplified data that you can
> handle.  Cheating and lying are as natural as breathing to you.
> You probably don't realize that you are doing it.
> Perhaps if you dropped programming and took up a hobby for
> which you had a modicum of talent, your character would improve.

You find it difficult to write a Ruby module that does lazy
calling. :)  We are still waiting...

Cheers
--
Marco
From: John Thingstad
Subject: Re: Working on learning lisp
Date: 
Message-ID: <op.upshz519ut4oq5@pandora.alfanett.no>
P� Mon, 23 Feb 2009 02:56:27 +0100, skrev William James  
<·········@yahoo.com>:

> Andr� Thieme wrote:
>
>> William James schrieb:
>>
>> > Ruby:
>> >
>> > "<html><body></body></html>".split( /(?=<)/ )
>> >    ==>["<html>", "<body>", "</body>", "</html>"]
>>
>> In Lisp it is the same:
>> (split "<html><body></body></html>" "(?=<)")
>
> Wrong.
>
> user=> (split "<html><body></body></html>" "(?=<)")
> java.lang.Exception: Unable to resolve symbol: split in this context
>
> Don't ever post untested code.
>
> user=> (vec (.split "<html><body></body></html>" "(?=<)"))
> ["" "<html>" "<body>" "</body>" "</html>"]
>
> Wrong again.  The first element is an empty string.  That's
> not what the man wanted.
>
>
>

CL-USER 4 > (cl-ppcre:split "(?=<)" "<html><body></body></html>")
("<html>" "<body>" "</body>" "</html>")



--------------
John Thingstad
From: John Thingstad
Subject: Re: Working on learning lisp
Date: 
Message-ID: <op.undr5oufut4oq5@pandora.alfanett.no>
P� Wed, 07 Jan 2009 02:29:51 +0100, skrev Mike <·····@mikee.ath.cx>:

> My chosen learning project has me stumped at the moment. I have this code
>
> (defun split-string (string &optional (separators " ,-"))
>   "Splits STRING into a list of substrings (which is returned)
>   separated by the characters in the sequence SEPARATORS.  Empty
>   substrings aren't collected."
>   (flet ((make-collector ()
>                          (make-array 0
>                                      :adjustable t
>                                      :fill-pointer t
>                                      :element-type #+:lispworks  
> 'lw:simple-char
>                                      #-:lispworks 'character)))
>     (loop with collector = (make-collector)
>           for char across string
>           for counter downfrom (1- (length string))
>           when (find char separators :test #'char=)
>           when (plusp (length collector))
>           collect collector
>           and do (setq collector (make-collector)) end
>           else
>           do (vector-push-extend char collector)
>           and when (zerop counter)
>           collect collector)))
> (print (split-string "<html><body></body></html>" "<"))
>
> =>
>
> ("html>" "body>" "/body>" "/html>")
>
> I'm trying to understand the defun above to modify the code to
> include the leading '<' in the returned list. Every place I've
> haphazardly placed a (setq counter (1- counter)) (assuming that
> counter is an index for a substr(3)) doesn't work.
>
> Someone, please explain what the extended loop code is doing and
> how I can modify the code to include the '<'.
>
> (I copied the code from  
> http://common-lisp.net/~loliveira/ediware/drakma/util.lisp)
>
> Thanks
>
> Mike

This is a common problem. Get the split-sequence extension from  
http://www.cl-user.net/asp/libs/split-sequence

--------------
John Thingstad
From: Rainer Joswig
Subject: Re: Working on learning lisp
Date: 
Message-ID: <joswig-C5AD64.15561307012009@news-europe.giganews.com>
In article <············@news.motzarella.org>,
 Mike <·····@mikee.ath.cx> wrote:

> My chosen learning project has me stumped at the moment. I have this code
> 
> (defun split-string (string &optional (separators " ,-"))
>   "Splits STRING into a list of substrings (which is returned)
>   separated by the characters in the sequence SEPARATORS.  Empty
>   substrings aren't collected."
>   (flet ((make-collector ()
>                          (make-array 0
>                                      :adjustable t
>                                      :fill-pointer t
>                                      :element-type #+:lispworks 'lw:simple-char
>                                      #-:lispworks 'character)))
>     (loop with collector = (make-collector)
>           for char across string
>           for counter downfrom (1- (length string))
>           when (find char separators :test #'char=)
>           when (plusp (length collector))
>           collect collector
>           and do (setq collector (make-collector)) end
>           else
>           do (vector-push-extend char collector)
>           and when (zerop counter)
>           collect collector)))
> (print (split-string "<html><body></body></html>" "<"))
> 
> =>
> 
> ("html>" "body>" "/body>" "/html>")
> 
> I'm trying to understand the defun above to modify the code to
> include the leading '<' in the returned list. Every place I've
> haphazardly placed a (setq counter (1- counter)) (assuming that
> counter is an index for a substr(3)) doesn't work.
> 
> Someone, please explain what the extended loop code is doing and
> how I can modify the code to include the '<'.
> 
> (I copied the code from http://common-lisp.net/~loliveira/ediware/drakma/util.lisp)
> 
> Thanks
> 
> Mike

You need to push the separator character onto the collector.
There is a simple way to modify it by adding the VECTOR-PUSH-EXTEND
in two places. One is after the creation of a new collector
via MAKE-COLLECTOR. The second place needs to be if no new
collector is created. Example:

(defun split-string (string &optional (separators " ,-"))
  "Splits STRING into a list of substrings (which is returned)
  separated by the characters in the sequence SEPARATORS.  Empty
  substrings aren't collected."
  (flet ((make-collector ()
                         (make-array 0
                                     :adjustable t
                                     :fill-pointer t
                                     :element-type #+:lispworks 'lw:simple-char
                                     #-:lispworks 'character)))
    (loop with collector = (make-collector)
          for char across string
          for counter downfrom (1- (length string))
          when (find char separators :test #'char=)
             when (plusp (length collector))
             collect collector
             and do (setq collector (make-collector))
                    (vector-push-extend char collector)
             else do (vector-push-extend char collector) end
          else
          do (vector-push-extend char collector)
          and when (zerop counter) collect collector)))

Using LispWorks:

CL-USER 30 > (split-string "<html><body></body></html>" "<")
("<html>" "<body>" "</body>" "</html>")


My changes are largely untested, but it should give an idea.

-- 
http://lispm.dyndns.org/