From: Stephen Ramsay
Subject: string interpolation (newbie)
Date: 
Message-ID: <RZ%Ne.30672$XM3.94@bignews5.bellsouth.net>
As far as I can tell, Common Lisp doesn't have the (native) ability to
interpolate strings.  There's a nice library out there that lets you do
something like:

#?"Hello, and welcome to ${string}" 

But being new to this language, I suppose I'd prefer to use the native
idiom.

What is that idiom?  Concatenation?  Can someone give me a quick
example?

Steve

-- 
Stephen Ramsay
web: http://cantor.english.uga.edu/

From: R. Mattes
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <pan.2005.08.20.14.44.45.283538@mh-freiburg.de>
On Sun, 21 Aug 2005 14:13:05 +0000, Stephen Ramsay wrote:

> 
> 
> As far as I can tell, Common Lisp doesn't have the (native) ability to
> interpolate strings.  There's a nice library out there that lets you do
> something like:
> 
> #?"Hello, and welcome to ${string}" 
> 
> But being new to this language, I suppose I'd prefer to use the native
> idiom.
> 
> What is that idiom?  Concatenation?  Can someone give me a quick
> example?

What about format?

 (format NIL "Hello and welcome to ~A" string)

 Cheers Ralf Mattes
From: Stephen Ramsay
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <Gp0Oe.30677$XM3.23609@bignews5.bellsouth.net>
On 2005-08-20, R. Mattes <··@mh-freiburg.de> wrote:
> On Sun, 21 Aug 2005 14:13:05 +0000, Stephen Ramsay wrote:
>> What is that idiom?  Concatenation?  Can someone give me a quick
>> example?
>
> What about format?
>
>  (format NIL "Hello and welcome to ~A" string)

Wow.  Cool.  I hadn't thought of that at all.  I suppose format can be
conceived as a general purpose string manipulator . . .

But what exactly am I doing when I use NIL where one might normally use t or
stream?  How does the function get evaluated?

Steve


-- 
Stephen Ramsay
web: http://cantor.english.uga.edu/
From: Peter Seibel
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <m2u0hjut2m.fsf@gigamonkeys.com>
Stephen Ramsay <·······@uga.edu> writes:

> On 2005-08-20, R. Mattes <··@mh-freiburg.de> wrote:
>> On Sun, 21 Aug 2005 14:13:05 +0000, Stephen Ramsay wrote:
>>> What is that idiom?  Concatenation?  Can someone give me a quick
>>> example?
>>
>> What about format?
>>
>>  (format NIL "Hello and welcome to ~A" string)
>
> Wow.  Cool.  I hadn't thought of that at all.  I suppose format can be
> conceived as a general purpose string manipulator . . .

Note that you can also pass an adjustable string with a fill-pointer
as the first argument to FORMAT:

    CL-USER> (let ((s (make-array 10 :adjustable t :fill-pointer 0 :element-type 'character)))
               (format s "one~%")
               (format s "two: ~d~%" 2)
               (let ((x 3)) (format s "three: ~d~%" x))
               s)
    "one
    two: 2
    three: 3
    "

Thought it's not clear that that's ever a win over simply:

  (with-output-to-string (s)
    (format s "one~%")
    (format s "two: ~d~%" 2)
    (let ((x 3)) (format s "three: ~d~%" x)))

I suppose if you wanted to stuff some stuff in a string and return it
to someone who could stuff more stuff in it, etc. it might be handy.

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Stephen Ramsay
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <RD4Oe.44125$rp.40860@bignews1.bellsouth.net>
On 2005-08-21, Peter Seibel <·····@gigamonkeys.com> wrote:
> Note that you can also pass an adjustable string with a fill-pointer
> as the first argument to FORMAT:
>
>     CL-USER> (let ((s (make-array 10 :adjustable t :fill-pointer 0 :element-type 'character)))
>                (format s "one~%")
>                (format s "two: ~d~%" 2)
>                (let ((x 3)) (format s "three: ~d~%" x))
>                s)
>     "one
>     two: 2
>     three: 3

Further proof that if there's a way to think it, there's probably a way
to do it in CL ;)

Steve


-- 
Stephen Ramsay
web: http://cantor.english.uga.edu/
From: Harald Hanche-Olsen
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <pcoy86vpb3r.fsf@shuttle.math.ntnu.no>
+ Stephen Ramsay <·······@uga.edu>:

| >  (format NIL "Hello and welcome to ~A" string)
| 
| Wow.  Cool.  I hadn't thought of that at all.  I suppose format can be
| conceived as a general purpose string manipulator . . .
| 
| But what exactly am I doing when I use NIL where one might normally
| use t or stream?  How does the function get evaluated?

It sounds like you're worrying about how this is implemented.
It might be implemented by something like

  (with-output-to-string (s)
    (format s "Hello and welcome to ~A" string))

but then it might not.  Worry instead about what it is specified to
do:  Instead of sending formatted output to a stream, (format nil ...)
collects all the characters that would be sent to the stream and uses
them to build a string instead.  The more general construct
with-output-to-string does the same thing.  Both come in handy from
time to time.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: Stephen Ramsay
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <1Q1Oe.30809$XM3.3209@bignews5.bellsouth.net>
On 2005-08-21, Harald Hanche-Olsen <······@math.ntnu.no> wrote:
>| But what exactly am I doing when I use NIL where one might normally
>| use t or stream?  How does the function get evaluated?
>
> It sounds like you're worrying about how this is implemented.
> It might be implemented by something like
>
>   (with-output-to-string (s)
>     (format s "Hello and welcome to ~A" string))
>
> but then it might not.  Worry instead about what it is specified to
> do:

I suppose I am wondering about that (I've never used a language that
made me so curious about how it works), but I guess I was really just
trying understand why "nil" is the destination parameter that creates
this effect (the empty list, right?).  It seems like I'm saying "Take
the side-effect of format and make it the return value."  That's a very
useful thing, in any event.

Thanks to one and all for the explanation.

Steve

-- 
Stephen Ramsay
web: http://cantor.english.uga.edu/
From: Harald Hanche-Olsen
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <pco4q9j7z8c.fsf@shuttle.math.ntnu.no>
+ Stephen Ramsay <·······@uga.edu>:

| but I guess I was really just trying understand why "nil" is the
| destination parameter that creates this effect (the empty list,
| right?).

NIL has more roles than the empty list.  It is also the false value.
In the same vein, T is the generic true value, although any value
other than NIL is considered true.  And in addition, both NIL and T
are self-evaluating symbols.  They are occasionally used for other
special purposes, and this is just one of those occasions.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: Kent M Pitman
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <uy86ue843.fsf@nhplace.com>
Harald Hanche-Olsen <······@math.ntnu.no> writes:

> + Stephen Ramsay <·······@uga.edu>:
> 
> | but I guess I was really just trying understand why "nil" is the
> | destination parameter that creates this effect (the empty list,
> | right?).
> 
> NIL has more roles than the empty list.  It is also the false value.
> In the same vein, T is the generic true value, although any value
> other than NIL is considered true.  And in addition, both NIL and T
> are self-evaluating symbols.  They are occasionally used for other
> special purposes, and this is just one of those occasions.

For example, see the definition of "stream designator" in CLHS...
http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#stream_designator

Btw, you can also think of NIL as operating in its 'false' role here in that
(format nil ...) was chosen, I believe, to give the sense of
"FORMAT--to a stream? No, to no stream, thank you. Just format it and return
the result without sending it to a stream."
From: Stephen Ramsay
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <BAkOe.31843$XM3.29595@bignews5.bellsouth.net>
On 2005-08-22, Kent M Pitman <······@nhplace.com> wrote:
> Harald Hanche-Olsen <······@math.ntnu.no> writes:
>
>> + Stephen Ramsay <·······@uga.edu>:
>> 
>> | but I guess I was really just trying understand why "nil" is the
>> | destination parameter that creates this effect (the empty list,
>> | right?).
>> 
>> NIL has more roles than the empty list.  It is also the false value.
>> In the same vein, T is the generic true value, although any value
>> other than NIL is considered true.  And in addition, both NIL and T
>> are self-evaluating symbols.  They are occasionally used for other
>> special purposes, and this is just one of those occasions.
>
> For example, see the definition of "stream designator" in CLHS...
> http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#stream_designator
>
> Btw, you can also think of NIL as operating in its 'false' role here in that
> (format nil ...) was chosen, I believe, to give the sense of
> "FORMAT--to a stream? No, to no stream, thank you. Just format it and return
> the result without sending it to a stream."

Ah, that makes sense.

Steve

-- 
Stephen Ramsay
web: http://cantor.english.uga.edu/
From: Pedro Kröger
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <1124635411.487410.137150@g14g2000cwa.googlegroups.com>
Stephen Ramsay wrote:
> What is that idiom?  Concatenation?  Can someone give me a quick
> example?

I like to use FORMAT (like Mattes showed), but you may want to know you
can concatenat strings with string-concat:

(string-concat "Hello, and welcome to " string)

Pedro Kröger
From: JP Massar
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <499hg1duhkaesd061rd21lin95a030lv5n@4ax.com>
On 21 Aug 2005 07:43:31 -0700, "Pedro Kr�ger" <············@gmail.com>
wrote:

 
>I like to use FORMAT (like Mattes showed), but you may want to know you
>can concatenat strings with string-concat:
>
>(string-concat "Hello, and welcome to " string)
>
 
Not in standard Common Lisp.  No such function exists.  However

(concatenate 'string "Goodbye, and thanks for all the" string)

works

The lack of a non-verbose way of concatenating strings is an easily
remedied yet anazingly annoying flaw in Common Lisp.
From: Pedro Kröger
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <1124641525.657099.149050@o13g2000cwo.googlegroups.com>
JP Massar wrote:
> Not in standard Common Lisp.  No such function exists.  However

You're right. It's a Clisp extension.

Pedro Kröger
From: Alberto Riva
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <f9adne-TC6U3KZXeRVn-vg@rcn.net>
JP Massar wrote:
> 
> The lack of a non-verbose way of concatenating strings is an easily
> remedied yet anazingly annoying flaw in Common Lisp.

(defun strcat (&rest strings)
   (apply #'concatenate 'string strings))

or

(defun strcat (&rest strings)
   (with-output-to-string (out)
     (dolist (s strings)
       (princ s out))))

This second version is probably more expensive, but also works for 
non-strings.

Alberto
From: Alexander Schreiber
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <slrndghjdd.jgp.als@mordor.angband.thangorodrim.de>
JP Massar <······@alum.mit.edu> wrote:
> On 21 Aug 2005 07:43:31 -0700, "Pedro Kr�ger" <············@gmail.com>
> wrote:
>
>  
>>I like to use FORMAT (like Mattes showed), but you may want to know you
>>can concatenat strings with string-concat:
>>
>>(string-concat "Hello, and welcome to " string)
>>
>  
> Not in standard Common Lisp.  No such function exists.  However
>
> (concatenate 'string "Goodbye, and thanks for all the" string)
>
> works
>
> The lack of a non-verbose way of concatenating strings is an easily
> remedied yet anazingly annoying flaw in Common Lisp.

That's not really a problem: the above construct gets turned into a
simple macro so you can use (str-concat "Hello, Mr. " wos-name).

Regards,
       Alex.
-- 
"Opportunity is missed by most people because it is dressed in overalls and
 looks like work."                                      -- Thomas A. Edison
From: Alan Crowe
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <86irxym8xq.fsf@cawtech.freeserve.co.uk>
Steve asked:
> Can someone give me a quick example?

* (let ((name "Alan")
	(city "Edinburgh"))
    (concatenate 'string
		 "My name is "name" and I live in "city"."))

"My name is Alan and I live in Edinburgh."

CL looks really slick here, as though you can interpolate the value
of a variable into a string simply by quoting it.

What is actually happening is rather cruder.

double-quote is a single character macro, so the second
double-quote of `"My name is "' tells the reader that the
string is finished and it should start building a new token
without being prompted to do so by white space.

double-quote is also a terminating macro (unlike #) so
the double-quote in `name"' tells the reader that it must
both finish building the previous token, NAME, and start on
building a string.

--
Alan
From: Stephen Ramsay
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <tCkOe.31849$XM3.26757@bignews5.bellsouth.net>
On 2005-08-22, Alan Crowe <····@cawtech.freeserve.co.uk> wrote:
> Steve asked:
>> Can someone give me a quick example?
>
> * (let ((name "Alan")
> 	(city "Edinburgh"))
>     (concatenate 'string
> 		 "My name is "name" and I live in "city"."))
>
> "My name is Alan and I live in Edinburgh."
>
> CL looks really slick here, as though you can interpolate the value
> of a variable into a string simply by quoting it.
>
> What is actually happening is rather cruder.

Is this more or less idiomatic, or would you say (format . . .) is the
more common way to go about it?

From the responses, I get the feeling it's the latter . . .

Steve

-- 
Stephen Ramsay
web: http://cantor.english.uga.edu/
From: Alan Crowe
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <86irxy2atn.fsf@cawtech.freeserve.co.uk>
Steve wonders
> Is this more or less idiomatic, or would you say 
> (format . . .) is the more common way to go about it?

I would recommend format.

The example I posted looks cute, but only works when the
variables contain sequences of characters so it is pretty
useless really. Sorry.

I think that interpolation is always going to clunk because
your code is subject to a three way pull.

1)You want the string in the source code to have roughly the
same spacing as the string you are tring to create

2)You want to put the code that generates the objects that
you interpolate right into the string in the place that they
belong, which knocks the string out of shape.

3)You want to put the formatting instructions in there too

The design of format makes certain choices:

The formatting instructions go in the string. They are
cryptic, in an attempt to keep them short, so that they
don't mess up the spacing of the string too badly.

The object-generating forms tag along after the string,
which is really just giving up.

I've played about writing an interpolation macro

Code
----
(eval-when (:compile-toplevel :load-toplevel :execute)
  (defun reformat (instruction)
    (destructuring-bind (name form format-string)
                        instruction
      (list name `(format nil ,format-string ,form)))))

(defmacro with-interpolation (instructions &rest elements)
  `(let ,(mapcar #'reformat instructions)
     (concatenate 'string ,@elements)))

Example
-------
(with-interpolation
	((num (exp -1) "~10,4F")
	 (name (second '(joe fred bill)) "~:(~A~)"))
	"Tell "name" it took "num" seconds.")

=> "Tell Fred it took     0.3679 seconds." 

So I've managed to group each format instruction with the
form that generates the object that it formats. That is
good.  But at the cost of introducing intermediate names,
num and name. That is bad. Worse, the cryptic nature of
format strings doesn't make sense in this context. Why try
to keep them short, when they aren't inside the template
string spoiling the spacing?

I stick with my initial recommendation of format.

I enjoy tinkering and coming up with general purpose
enhancements to Common Lisp, but actually, Common Lisp is
already an excellent general purpose language, and my
general purpose "enhancements" never stand the test of time
and experience. 

If you are writing a large program then things are
different. You can leverage the fact that you need to do
certain things, but not others, design appropriate special
purpose enhancements, and win big.
--
Alan Crowe
Edinburgh
Scotland
From: Stephen Ramsay
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <I2GOe.10854$ZD4.6212@bignews3.bellsouth.net>
On 2005-08-22, Alan Crowe <····@cawtech.freeserve.co.uk> wrote:
> So I've managed to group each format instruction with the
> form that generates the object that it formats. That is
> good.  But at the cost of introducing intermediate names,
> num and name. That is bad. Worse, the cryptic nature of
> format strings doesn't make sense in this context. Why try
> to keep them short, when they aren't inside the template
> string spoiling the spacing?

Format certainly seems like the more apt way to go (certainly in my
code, which is doing something fairly simple).  

Pretty awesome bit of code though (I mean yours, not mine ;)

> I enjoy tinkering and coming up with general purpose
> enhancements to Common Lisp, but actually, Common Lisp is
> already an excellent general purpose language, and my
> general purpose "enhancements" never stand the test of time
> and experience. 

Well, that is true of most languages, I think.

One thing I'm finding about Lisp, though, is that it tends not to punish
you for creating clever abstractions.  When you start to abstract things
to a high level in C++ or Java, you tend to get unreadable code (ever
try doing kung fu with the Java reflection mechanism?).  When I try to
aim for a high level of abstraction is Lisp, I tend to get code that is
both readable and concise.  That, I think, is positively amazing.

Of course, I have no doubt that it's possible to write unreadable,
obfuscated Lisp.  Few languages make this impossible.  Still, Lisp seems
to let you go alot farther.

Thanks again to one and all.

Steve

-- 
Stephen Ramsay
web: http://cantor.english.uga.edu/
From: Marco Antoniotti
Subject: Re: string interpolation (newbie)
Date: 
Message-ID: <VmqOe.59$DJ5.69487@typhoon.nyu.edu>
Many people have already pointed you in the direction of the various 
FORMAT and WITH-OUTPUT-TO-STRING.

If you did a search for CL-INTERPOL you'll get to a library that does 
what you want.

Cheers
--
Marco





Stephen Ramsay wrote:
> As far as I can tell, Common Lisp doesn't have the (native) ability to
> interpolate strings.  There's a nice library out there that lets you do
> something like:
> 
> #?"Hello, and welcome to ${string}" 
> 
> But being new to this language, I suppose I'd prefer to use the native
> idiom.
> 
> What is that idiom?  Concatenation?  Can someone give me a quick
> example?
> 
> Steve
>