From: Jacek Generowicz
Subject: backquote-like syntax for building strings.
Date: 
Message-ID: <tyfr895or9o.fsf@pcepsft001.cern.ch>
I would like to have some mechanism, similar to backquote, for
composing text. IOW, something that allows me to write strings, with
some way of escaping to lisp.

I knocked together a prototype, but it seems really horrible and flaky:

(defmacro build-text (stream string)
  "A backquote-like syntax for constructing text. Use #\$' to evaluate
what follows as a lisp form. Whitespace is preserved; use #\' to
terminate the form if you want to suppress the terminating space."
  (flet ((read-form-and-string (string)
	   "Reads a form and a string for STRING, preserving whitespace between them."
	   (let ((length (length string)))
	     (multiple-value-bind (form position) (read-from-string string t nil :start 1)
	       (when (and (< position length) (char= (aref string position) #\'))
		 (incf position))
	       (when (member (aref string (1- position)) '(#\Space #\Newline) :test #'char=)
		 (decf position))
	     (values form (subseq string position))))))
    (let* ((chopped 
	    (loop with l = (1- (length string))
		  with bottom = 0
		  for top from 0 to (1- (length string))
		  when (char= #\$ (aref string top))
		  collect (subseq string bottom top)
		  when (char= #\$ (aref string top))
		  do (setq bottom top)
		  when (= top l) collect (subseq string bottom)))
	   (first (first chopped))
	   (rest (rest chopped)))
      `(progn
	(format ,stream ,first)
	,@(mapcar (lambda (s)
		    (multiple-value-bind (form string) (read-form-and-string s)
		      `(format ,stream "~a~a" ,form ,string)))
		  rest)))))

Any suggestions how this idea could be developed ?


[Aside:

Is there a way of doing what is intended here:

(loop ...
  when test (progn 
              collect something ; collect meaningless inside progn
              something-else))

without resorting to this:

(loop ...
  when test collect something
  when test do something-else)

]

From: Zachary Beane
Subject: Re: backquote-like syntax for building strings.
Date: 
Message-ID: <slrnb7c2q2.bna.xach@localhost.localdomain>
In article <···············@pcepsft001.cern.ch>, Jacek Generowicz
wrote:
> [Aside:
> 
> Is there a way of doing what is intended here:
> 
> (loop ...
>   when test (progn 
>               collect something ; collect meaningless inside progn
>               something-else))
> 
> without resorting to this:
> 
> (loop ...
>   when test collect something
>   when test do something-else)
> 
> ]

Taken literally, it seems you could do something like this:

   (loop ...
     when test collect (prog1
			 something
			 something-else))

But it seems you could also do this:

   (loop ...
     when test collect (progn
			 something-else
			 something))

Zach
From: Kaz Kylheku
Subject: Re: backquote-like syntax for building strings.
Date: 
Message-ID: <cf333042.0303171602.a6a14c2@posting.google.com>
Jacek Generowicz <················@cern.ch> wrote in message news:<···············@pcepsft001.cern.ch>...
> I would like to have some mechanism, similar to backquote, for
> composing text. IOW, something that allows me to write strings, with
> some way of escaping to lisp.

Such things already exist in numerous incarnations.

For example, take a look at http://www.cliki.net/Scribble
From: Jacek Generowicz
Subject: Re: backquote-like syntax for building strings.
Date: 
Message-ID: <tyf1y15q49n.fsf@lxplus085.cern.ch>
Jacek Generowicz <················@cern.ch> writes:

> I would like to have some mechanism, similar to backquote, for
> composing text. IOW, something that allows me to write strings, with
> some way of escaping to lisp.

Hmm, I guess that in terms of mileage for effort, the following is the
way to go:

(defmacro build-text (stream &rest forms)
  `(progn
    ,@(mapcar (lambda (f)
		(if (stringp f)
		    `(format ,stream ,f)
		    `(format ,stream "~a" ,f)))
	      forms)))


(build-text t "1 + 2 = " (+ 1 2) "
sqrt(3) = " (sqrt 3))

=>

1 + 2 = 3
sqrt(3) = 1.7320508
From: Raymond Wiker
Subject: Re: backquote-like syntax for building strings.
Date: 
Message-ID: <86el552g1v.fsf@raw.grenland.fast.no>
Jacek Generowicz <················@cern.ch> writes:

> Jacek Generowicz <················@cern.ch> writes:
> 
> > I would like to have some mechanism, similar to backquote, for
> > composing text. IOW, something that allows me to write strings, with
> > some way of escaping to lisp.
> 
> Hmm, I guess that in terms of mileage for effort, the following is the
> way to go:
> 
> (defmacro build-text (stream &rest forms)
>   `(progn
>     ,@(mapcar (lambda (f)
> 		(if (stringp f)
> 		    `(format ,stream ,f)
> 		    `(format ,stream "~a" ,f)))
> 	      forms)))

        Small nit: you shouldn't use format for writing out a string
in this way... what happens if the string contains ~a (or other
formatting specifications). write-string, perhaps?

        Also, mapcar should not be used by this, as you're not really
interested in a list of return values from format :-)


-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: Gareth McCaughan
Subject: Re: backquote-like syntax for building strings.
Date: 
Message-ID: <slrnb7dt3p.pbu.Gareth.McCaughan@g.local>
Raymond Wiker wrote:

>  Jacek Generowicz <················@cern.ch> writes:
...
> > Hmm, I guess that in terms of mileage for effort, the following is the
> > way to go:
> > 
> > (defmacro build-text (stream &rest forms)
> >   `(progn
> >     ,@(mapcar (lambda (f)
> > 		(if (stringp f)
> > 		    `(format ,stream ,f)
> > 		    `(format ,stream "~a" ,f)))
> > 	      forms)))
>  
>          Small nit: you shouldn't use format for writing out a string
>  in this way...
[etc]

(defun build-text (stream &rest things)
  (format stream "~{~A~}" things))

seems perfectly adequate to me. Am I missing something?

-- 
Gareth McCaughan  ················@pobox.com
.sig under construc
From: Jacek Generowicz
Subject: Re: backquote-like syntax for building strings.
Date: 
Message-ID: <tyffzpkn1rr.fsf@pcepsft001.cern.ch>
Gareth McCaughan <················@pobox.com> writes:

> (defun build-text (stream &rest things)
>   (format stream "~{~A~}" things))
> 
> seems perfectly adequate to me. Am I missing something?

Nothing besides my stupidity.

Thanks.
From: Jochen Schmidt
Subject: Re: backquote-like syntax for building strings.
Date: 
Message-ID: <b56qik$mti$05$1@news.t-online.com>
Raymond Wiker wrote:
>         Also, mapcar should not be used by this, as you're not really
> interested in a list of return values from format :-)
 
Have I overseen something? Isn't the mapcar used to collect the (FORMAT ...)
forms which are then spliced into the progn?

ciao,
Jochen
 
From: Raymond Wiker
Subject: Re: backquote-like syntax for building strings.
Date: 
Message-ID: <864r612d7x.fsf@raw.grenland.fast.no>
Jochen Schmidt <···@dataheaven.de> writes:

> Raymond Wiker wrote:
> >         Also, mapcar should not be used by this, as you're not really
> > interested in a list of return values from format :-)
>  
> Have I overseen something? Isn't the mapcar used to collect the (FORMAT ...)
> forms which are then spliced into the progn?

        No. Mea culpa.

-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: Johan Ur Riise
Subject: Re: backquote-like syntax for building strings.
Date: 
Message-ID: <873cljr5ga.fsf@egg.riise-data.net>
Raymond Wiker <·············@fast.no> writes:

> Jochen Schmidt <···@dataheaven.de> writes:
> 
> > Raymond Wiker wrote:
> > >         Also, mapcar should not be used by this, as you're not really
> > > interested in a list of return values from format :-)
> >  
> > Have I overseen something? Isn't the mapcar used to collect the (FORMAT ...)
> > forms which are then spliced into the progn?
Only if you use (format nil ...)
-- 
Hilsen
Johan Ur Riise
From: Jeremy Yallop
Subject: Re: backquote-like syntax for building strings.
Date: 
Message-ID: <b59oo7$27dhbg$1@ID-114079.news.dfncis.de>
Johan Ur Riise wrote:
>> Jochen Schmidt <···@dataheaven.de> writes:
>> 
>> > Raymond Wiker wrote:
>> > >         Also, mapcar should not be used by this, as you're not really
>> > > interested in a list of return values from format :-)
>> >  
>> > Have I overseen something? Isn't the mapcar used to collect the (FORMAT ...)
>> > forms which are then spliced into the progn?
> Only if you use (format nil ...)

It's not the results of the format forms that are collected, but the
forms themselves:

   [13]> (macroexpand '(build-text t "t" t #\t))
   (PROGN (FORMAT T "t") (FORMAT T "~a" T) (FORMAT T "~a" #\t)) ;
   T

Jeremy.
From: Pascal Costanza
Subject: Re: backquote-like syntax for building strings.
Date: 
Message-ID: <costanza-E0651B.18573917032003@news.netcologne.de>
In article <···············@pcepsft001.cern.ch>,
 Jacek Generowicz <················@cern.ch> wrote:

> I would like to have some mechanism, similar to backquote, for
> composing text. IOW, something that allows me to write strings, with
> some way of escaping to lisp.
> 
> I knocked together a prototype, but it seems really horrible and flaky:
> 
> (defmacro build-text (stream string)
[...]

Wouldn't it be simpler to implement something like that as a 
modification of the readtable?


Just brainstorming...


Pascal

-- 
"If I could explain it, I wouldn't be able to do it."
A.M.McKenzie
From: Arthur Lemmens
Subject: Re: backquote-like syntax for building strings.
Date: 
Message-ID: <3E76259E.945CC267@xs4all.nl>
Jacek Generowicz wrote:

> Is there a way of doing what is intended here:
> 
> (loop ...
>   when test (progn
>               collect something ; collect meaningless inside progn
>               something-else))
> 
> without resorting to this:
> 
> (loop ...
>   when test collect something
>   when test do something-else)

Yes. You can use:

(loop ...
      when test collect something and do something-else)

 --
Arthur Lemmens
From: Joerg Hoehle
Subject: Re: backquote-like syntax for building strings.
Date: 
Message-ID: <ufzpjtwz2.fsf@dont.t-systems.UCE.spam.no.com>
Arthur Lemmens <········@xs4all.nl> writes:
> Jacek Generowicz wrote:
> > Is there a way of doing what is intended here:
> > 
> > (loop ...
> >   when test (progn
> >               collect something ; collect meaningless inside progn
> >               something-else))
> > 
> > without resorting to this:
> > (loop ...
> >   when test collect something
> >   when test do something-else)
> 
> Yes. You can use:
> (loop ...
>       when test collect something and do something-else)

Another possibility is to use some form of the (non-standard)
WITH-COLLECT or COLLECTING macros. There have been implementations of
that posted to this list, and I believe there's one in Cliki as well
Here's an entry in Cliki that I once wrote:
http://www.cliki.net/COLLECTING

WITH-COLLECT is particularly useful with nested loops, inside closures
or whatever. It does not depend on LOOP.

Regards,
	Jorg Hohle
Telekom/T-Systems Technology Center