From: Brett Kelly
Subject: function to split a string into a list of characters
Date: 
Message-ID: <pan.2003.07.19.03.50.25.701653@sourcereview.net>
this is what i'm after:

i want "brett" to be come ('b','r','e','t','t') (or however that would
look).  

is there a builtin CLisp function that does this?

thanks!

Brett
 

From: Kenny Tilton
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <3F18C20E.4050403@nyc.rr.com>
Brett Kelly wrote:
> this is what i'm after:
> 
> i want "brett" to be come ('b','r','e','t','t') (or however that would
> look).  
> 
> is there a builtin CLisp function that does this?

CELLO(2): (coerce "brett" 'list)
(#\b #\r #\e #\t #\t)

So:

1. no commas between the list elements

2. characters are #\b, not 'b'

btw, CLisp is the name of one particular implementation of Common Lisp, 
or CL when abbreviated.


-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Everything is a cell." -- Alan Kay
From: Coby Beck
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <bfb1le$2fra$1@otis.netspace.net.au>
"Kenny Tilton" <·······@nyc.rr.com> wrote in message
·····················@nyc.rr.com...
>
>
> Brett Kelly wrote:
> > this is what i'm after:
> >
> > i want "brett" to be come ('b','r','e','t','t') (or however that would
> > look).
> >
> > is there a builtin CLisp function that does this?
>
> CELLO(2): (coerce "brett" 'list)
> (#\b #\r #\e #\t #\t)
>
> So:
>
> 1. no commas between the list elements
>
> 2. characters are #\b, not 'b'

Or if you do want it this way, try:

CL-USER 1 > (mapcar 'string (coerce "brett" 'list))
("b" "r" "e" "t" "t")


-- 
Coby Beck
(remove #\Space "coby 101 @ big pond . com")
From: Rainer Joswig
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <joswig-701E6E.15482519072003@news.fu-berlin.de>
In article <·············@otis.netspace.net.au>,
 "Coby Beck" <·····@mercury.bc.ca> wrote:

> "Kenny Tilton" <·······@nyc.rr.com> wrote in message
> ·····················@nyc.rr.com...
> >
> >
> > Brett Kelly wrote:
> > > this is what i'm after:
> > >
> > > i want "brett" to be come ('b','r','e','t','t') (or however that would
> > > look).
> > >
> > > is there a builtin CLisp function that does this?
> >
> > CELLO(2): (coerce "brett" 'list)
> > (#\b #\r #\e #\t #\t)
> >
> > So:
> >
> > 1. no commas between the list elements
> >
> > 2. characters are #\b, not 'b'
> 
> Or if you do want it this way, try:
> 
> CL-USER 1 > (mapcar 'string (coerce "brett" 'list))
> ("b" "r" "e" "t" "t")

(map 'list #'string "brett")
From: Erik Winkels
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <874r1hnjhw.fsf@xs4all.nl>
Rainer Joswig <······@lispmachine.de> wrote:
>
> In article <·············@otis.netspace.net.au>,
> "Coby Beck" <·····@mercury.bc.ca> wrote:
>
>> "Kenny Tilton" <·······@nyc.rr.com> wrote in message
>> ·····················@nyc.rr.com...
>>>
>>> Brett Kelly wrote:
>>>>
>>>> i want "brett" to be come ('b','r','e','t','t')
>>>
>>> CELLO(2): (coerce "brett" 'list)
>>> (#\b #\r #\e #\t #\t)
>> 
>> CL-USER 1 > (mapcar 'string (coerce "brett" 'list))
>> ("b" "r" "e" "t" "t")
> 
> (map 'list #'string "brett")

God, I love these threads...
From: Frederic Brunel
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <lahe5er9nk.fsf@buzz.in-fusio.com>
Rainer Joswig <······@lispmachine.de> writes:

> In article <·············@otis.netspace.net.au>,
>  "Coby Beck" <·····@mercury.bc.ca> wrote:
>
>> "Kenny Tilton" <·······@nyc.rr.com> wrote in message
>> ·····················@nyc.rr.com...
>> >
>> >
>> > Brett Kelly wrote:
>> > > this is what i'm after:
>> > >
>> > > i want "brett" to be come ('b','r','e','t','t') (or however that would
>> > > look).
>> > >
>> > > is there a builtin CLisp function that does this?
>> >
>> > CELLO(2): (coerce "brett" 'list)
>> > (#\b #\r #\e #\t #\t)
>> >
>> > So:
>> >
>> > 1. no commas between the list elements
>> >
>> > 2. characters are #\b, not 'b'
>> 
>> Or if you do want it this way, try:
>> 
>> CL-USER 1 > (mapcar 'string (coerce "brett" 'list))
>> ("b" "r" "e" "t" "t")
>
> (map 'list #'string "brett")

  or 

  (loop for c across "brett" collect (string c))

  just for fun... 

-- 
Frederic Brunel
Senior Software Engineer
In-Fusio - Mobile Game Connections
From: Kenny Tilton
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <3F1D3DDD.7080602@nyc.rr.com>
Frederic Brunel wrote:
> Rainer Joswig <······@lispmachine.de> writes:
> 
> 
>>In article <·············@otis.netspace.net.au>,
>> "Coby Beck" <·····@mercury.bc.ca> wrote:
>>
>>
>>>"Kenny Tilton" <·······@nyc.rr.com> wrote in message
>>>·····················@nyc.rr.com...
>>>
>>>>
>>>>Brett Kelly wrote:
>>>>
>>>>>this is what i'm after:
>>>>>
>>>>>i want "brett" to be come ('b','r','e','t','t') (or however that would
>>>>>look).
>>>>>
>>>>>is there a builtin CLisp function that does this?
>>>>
>>>>CELLO(2): (coerce "brett" 'list)
>>>>(#\b #\r #\e #\t #\t)
>>>>
>>>>So:
>>>>
>>>>1. no commas between the list elements
>>>>
>>>>2. characters are #\b, not 'b'
>>>
>>>Or if you do want it this way, try:
>>>
>>>CL-USER 1 > (mapcar 'string (coerce "brett" 'list))
>>>("b" "r" "e" "t" "t")
>>
>>(map 'list #'string "brett")
> 
> 
>   or 
> 
>   (loop for c across "brett" collect (string c))
> 
>   just for fun... 
> 

good one, but you and many others have ignored the OP's spec, which was 
to get a list of characters. no reason we should take his choice of 
words literally, except he did offer 'b' 'r' 'e' etc, and tho my C is a 
little rusty, IIRC 'b' is syntactic sugar for the ascii value of the 
letter b, and certainly not for a pointer to the string "b".

so, conforming to OP's spec:

     (loop for c across "brett" collect c)

<g>


-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Everything is a cell." -- Alan Kay
From: Eric Smith
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <ceb68bd9.0307221112.7b181a5c@posting.google.com>
Kenny Tilton <·······@nyc.rr.com> wrote in message news:<················@nyc.rr.com>...

> good one, but you and many others have ignored the OP's spec,

They interpreted 'b' as "b" because they didn't
recognize it as c.  But that just shows that we
should never rely on specs as written, but always
work with the customer to keep things clear.

We need to understand what is really wanted, not
just what is presented.  Maybe he knows how to write
programs that work with lists, and he wants to convert
text to lists so he will know how to write progams to
work with it.

In that case, we could also help by pointing out that
it's not hard to work with text directly.  E.g.

; (rm1 "abc" 0) ==> "bc"      (rm1 "tea" 1) ==> "ta"
(defun rm1 (seq which)
  (remove-if #'true seq :start which :end (1+ which)))

; (consword #\a "bc") ==> "abc"
(defun consword (char word)
  (concatenate 'string (string char) word))

; (anagrams "ah") ==> ("ah" "ha")
(defun anagrams (word)
  (if (= (length word) 1) (list word)
    (loop as x across word
          as i upfrom 0
          as subword = (rm1 word i)
          nconc (loop as y in (anagrams subword)
                      collect (consword x y)))))
From: Kenny Tilton
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <3F1D90C0.6010206@nyc.rr.com>
Eric Smith wrote:
> Kenny Tilton <·······@nyc.rr.com> wrote in message news:<················@nyc.rr.com>...
> 
> 
>>good one, but you and many others have ignored the OP's spec,
> 
> 
> They interpreted 'b' as "b" because they didn't
> recognize it as c.  But that just shows that we
> should never rely on specs as written, but always
> work with the customer to keep things clear.
> 
> We need to understand what is really wanted, not
> just what is presented.  Maybe he knows how to write
> programs that work with lists, and he wants to convert
> text to lists so he will know how to write progams to
> work with it.
> 
> In that case, we could also help by pointing out that
> it's not hard to work with text directly.  

Right, I forgot about that. Someone (you?) did ask early on why a list 
was wanted. Classic hardware store dialogue, no matter what I ask for 
the good ones ask, "what do you want it for?" I often end up with 
something better than I asked for.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Everything is a cell." -- Alan Kay
From: ··········@YahooGroups.Com
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <REM-2003jul25-001@Yahoo.Com>
{{Date: Tue, 22 Jul 2003 13:34:10 GMT
  From: Kenny Tilton <·······@nyc.rr.com>
  but you and many others have ignored the OP's spec, which was to get
  a list of characters. no reason we should take his choice of words
  literally, except he did offer 'b' 'r' 'e' etc, and tho my C is a
  little rusty, IIRC 'b' is syntactic sugar for the ascii value of the
  letter b, and certainly not for a pointer to the string "b".}}

Good point. In C the character datatype is merely an 8-bit integer
internally, not a typed pseudopointer that can be distinguished from
the right half of short integer. So it's not clear whether 'b' from C
should be mapped to the ASCII value of the character or the
character-object, but definitely it shouldn't be mapped to an address
constant pointing at the first byte of a string, or a LISP pointer to a
LISP string i.e. vector-of-characters. So either of these is a correct
answer:
  (map 'list #'identity "brett") ==> (#\b #\r #\e #\t #\t)
  (map 'list #'char-code "brett") ==> (98 114 101 116 116)
The first can also be done as (coerce "brett" 'list), but that's a
special case you have to learn, whereas map is a general utility that
serves many purposes. Coerce by itself is generally useful, but the
semantics of all the special cases need to be learned one by one, which
work and which don't work, and when they work what the result is, for
example, can anybody but a CL geek predict the result of all these
without looking in the spec:
  (coerce "26" 'number)
  (coerce 'foo 'keyword)
  (coerce 3.5 'integer)
  (coerce 3.5 'long-float)
  (coerce 3.5 'complex)
  (coerce 3 'float)
  (coerce 32 'character)
  (coerce "A" 'character)
  (coerce 'A 'character)
  (coerce :A 'character)
  (coerce #\A 'string)
  (coerce #\A 'symbol)
  (coerce #C(3.5 0.0) 'real)
  (coerce 3.5 'rational)
  (coerce 1/3 'float)
  (coerce 5 'rational)
Point: Which work and which don't seems to follow no rhyme nor reason.
My advice is not to use coerce at all most of the time.
For example, if you want the first character of the print-name of a
symbol to be converted to the ASCII value of that character, say this:
  (char-code (elt (symbol-name 'A) 0))
Or if you remember that char is the same as elt except it's faster
because it works only with strings, use that instead if you choose.

I personally prefer to use format for all output of text, rather than
try to remember what prin1 and prin2 and princ and print do.

By the way, I may have mentionned somewhere that all data types in CL
except symbol and standard pair (CONS actually, but I hate that jargon
for the data type) are literal constants, in that EVAL of them yields a
result EQ to the original (except for numbers and character objects
which sometimes are EQL but not EQ, but that's good enough for the
following puzzle). So an interesting puzzle is how to setup those two
data types to evaluate to themselves, EQ not just EQUAL. For symbols
it's easy:
  (setq foo 'foo)
so now foo evaluates to foo. Or if you want something not interned, so
the value-loop you set up won't be changed by something else, you can
do this:
  (let ((g (gensym))) (set g g))
For CONS of course they have to be LISTs for EVAL not to barf, so the
trick is to find some kind of function-call or special-form or
macro-call that will evaluate to be EQ to the original, after
appropriate set-up. You could of course do this:
  (let ((form (list 'quote nil))) (rplaca (cdr form) form) form)
The result returned from that expression evaluates to itself, but has a
serious problem. Trying to print it out crashes CMUCL so badly it does
a core-dump!! Here's something I've come up with that works without
that problem:
  (let ((g (gensym))) (set g (list 'symbol-value (list 'quote g))))

ObHack: A nifty way to hide lower levels of a data structure without
having to change *print-level* is to embed uninterned symbols whose
value cell contains the rest of the structure below that point.
You can even make the print-name of each symbol indicate in a general
way what's below there. I used this method when building a tree of
ProxHash 15-vectors for purpose of using dynamic programming to find
the nearest vector to any probe vector.
From: Kalle Olavi Niemitalo
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <87d6fyyhyw.fsf@Astalo.kon.iki.fi>
··········@YahooGroups.Com writes:

> By the way, I may have mentionned somewhere that all data types in CL
> except symbol and standard pair (CONS actually, but I hate that jargon
> for the data type) are literal constants, in that EVAL of them yields a
> result EQ to the original (except for numbers and character objects
> which sometimes are EQL but not EQ, but that's good enough for the
> following puzzle).

This is also said at CLHS section 3.1.2.1.3, Self-Evaluating Objects.

However, CMUCL and SBCL have a SYSTEM-AREA-POINTER type whose
instances evaluate to themselves in EVAL but make the compiler
signal an error if they appear as forms.

> For CONS of course they have to be LISTs for EVAL not to barf, so the
> trick is to find some kind of function-call or special-form or
> macro-call that will evaluate to be EQ to the original, after
> appropriate set-up.

How about:

  (defmacro whole (&whole whole &rest rest)
    (declare (ignore rest))
    `',whole)

Then (whole . anything) will evaluate to itself (even if it isn't
a proper list).  The result was EQ in my tests but I'm not sure
that's guaranteed, especially if the compiler is involved.

> You could of course do this:
>   (let ((form (list 'quote nil))) (rplaca (cdr form) form) form)
> The result returned from that expression evaluates to itself, but has a
> serious problem. Trying to print it out crashes CMUCL so badly it does
> a core-dump!!

If you (setq *print-circle* t) then it prints as #1='#1# just fine.
From: Kent M Pitman
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <sfwispq4oa4.fsf@shell01.TheWorld.com>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> ··········@YahooGroups.Com writes:
> 
> > By the way, I may have mentionned somewhere that all data types in CL
> > except symbol and standard pair (CONS actually, but I hate that jargon
> > for the data type) are literal constants, in that EVAL of them yields a
> > result EQ to the original (except for numbers and character objects
> > which sometimes are EQL but not EQ, but that's good enough for the
> > following puzzle).
> 
> This is also said at CLHS section 3.1.2.1.3, Self-Evaluating Objects.
> 
> However, CMUCL and SBCL have a SYSTEM-AREA-POINTER type whose
> instances evaluate to themselves in EVAL but make the compiler
> signal an error if they appear as forms.

Well, and I'd claim this doesn't violate CLHS if there are no advertised
functions that yield these objects to a user of the CL implementation as
an otherwise conforming implementation (i.e., not doing system programming
that already depends on system-dependent stuff and isn't conforming anyway).
In such case, this effectively is just an implementation trick intended 
to add error checking to the fact that these pointers should not be escaping
into user code, and is not really a semantic issue per se.

> > For CONS of course they have to be LISTs for EVAL not to barf, so the
> > trick is to find some kind of function-call or special-form or
> > macro-call that will evaluate to be EQ to the original, after
> > appropriate set-up.
> 
> How about:
> 
>   (defmacro whole (&whole whole &rest rest)
>     (declare (ignore rest))
>     `',whole)
> 
> Then (whole . anything) will evaluate to itself (even if it isn't
> a proper list).  The result was EQ in my tests but I'm not sure
> that's guaranteed, especially if the compiler is involved.

You mean "file compiler".  The "compiler" also implies the COMPILE
function, which has no problem about such things.  The problem isn't
compiling at all; even if compilation were not involved, the problem
is that when you write something to a file and rebuild it, you have
two probably-different address spaces involved and you have to explain
what equality means in a way that does not depend on pointerness,
which is not meaningful in that context unless you have an address
space model that is independent of the image (which you could, for
example, if you had a fully database-based or other persistent memory
store, for example).  CL addresses these issues through the notion of
"similarity".  See 3.2.4 (Literal Objects in Compiled Files).
From: ··········@YahooGroups.Com
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <REM-2003jul31-004@Yahoo.Com>
{{Date: Fri, 25 Jul 2003 14:16:23 +0300
  From: Kalle Olavi Niemitalo <···@iki.fi>
  How about:
    (defmacro whole (&whole whole &rest rest)
      (declare (ignore rest))
      `',whole)
  Then (whole . anything) will evaluate to itself (even if it isn't a
  proper list).}}

Aha, longer setup than my answer, but shorter structure that evaluates
to self. So if we allow macros, your answer is shortest. (We can
shorten yours to making a macro called w instead of whole, so then (w)
is the shortest-printing evaluate-to-self object among standard-pair
objects, which I'll take as your true best answer.)

So if we disallow defining your own macros, but allow system built-in
macros and special forms as well as functions, and allow setup as I
did, any better answer then mine except for the one that requires
setting *print-circle*?

Of course if we disallow any kind of set-up, I wonder if there's any EQ
answer at all? The application of lambda expression to itself to CONS
up two copies of the lambda expression, the standard textbook example,
is only EQUAL, not EQ, although in that case the original expression as
read in is a match rather than something built in memory as with my
example. (Slightly different riddles force very different answers.)
From: Janis Dzerins
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <twk3ch2n8pe.fsf@gulbis.latnet.lv>
Brett Kelly <······@sourcereview.net> writes:

> this is what i'm after:
> 
> i want "brett" to be come ('b','r','e','t','t') (or however that would
> look).  
> 
> is there a builtin CLisp function that does this?

(coerce "brett" 'list)
=> (#\f #\o #\o)

That's a list of characters.  But are you sure you need it if you even
don't know what a list of characters looks like?

-- 
Janis Dzerins

  If million people say a stupid thing, it's still a stupid thing.
From: Christophe Rhodes
Subject: Re: function to split a string into a list of characters
Date: 
Message-ID: <squ19irg8y.fsf@lambda.jcn.srcf.net>
Janis Dzerins <·····@latnet.lv> writes:

> (coerce "brett" 'list)
> => (#\f #\o #\o)

I think your lisp needs a bit of regression testing ;-)

Christophe
-- 
http://www-jcsu.jesus.cam.ac.uk/~csr21/       +44 1223 510 299/+44 7729 383 757
(set-pprint-dispatch 'number (lambda (s o) (declare (special b)) (format s b)))
(defvar b "~&Just another Lisp hacker~%")    (pprint #36rJesusCollegeCambridge)