From: Jeff
Subject: Troubles extending a string...
Date: 
Message-ID: <cgg35a$rb2@odah37.prod.google.com>
Is there any way to append a string onto another string without using
CONCATENATE? The problem I am having is that I'm building a string,
character by character, using VECTOR-PUSH-EXTEND. However, this process
is recursive:


(defun build-string ()
(let ((s1 (create-adjustable-string-vector)))
(if (check-for-recursion)
(let ((s2 (build-string)))
(---> want to append s2 to s1 here <---))
s1)))


The algorithm (of course) is a little more complicated than this. My
initial attempt was to use CONCATENATE and just set 's1' to the return
value, but this fails later on, as the string returned by CONCATENATE
doesn't appear to be adjustable any more. Is there a way to append a
string in-place?

Thanks!

Jeff

From: Matthew Danish
Subject: Re: Troubles extending a string...
Date: 
Message-ID: <20040824203643.GI8087@mapcar.org>
On Tue, Aug 24, 2004 at 11:58:50AM -0700, Jeff wrote:
> Is there a way to append a string in-place?

WITH-OUTPUT-TO-STRING may be what you want, but also consider that
FORMAT can extend an adjustable string if you supply it as the first
argument.

-- 
;;;; Matthew Danish -- user: mrd domain: cmu.edu
;;;; OpenPGP public key: C24B6010 on keyring.debian.org
From: Peter Seibel
Subject: Re: Troubles extending a string...
Date: 
Message-ID: <m3k6vop89z.fsf@javamonkey.com>
Matthew Danish <·······@andrew.cmu.edu> writes:

> On Tue, Aug 24, 2004 at 11:58:50AM -0700, Jeff wrote:
>> Is there a way to append a string in-place?
>
> WITH-OUTPUT-TO-STRING may be what you want, but also consider that
> FORMAT can extend an adjustable string if you supply it as the first
> argument.

Well I'll be darned! I never noticed that option. Nice.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Jeff
Subject: Re: Troubles extending a string...
Date: 
Message-ID: <9DPWc.84017$TI1.41531@attbi_s52>
Matthew Danish wrote:

> On Tue, Aug 24, 2004 at 11:58:50AM -0700, Jeff wrote:
> > Is there a way to append a string in-place?
> 
> WITH-OUTPUT-TO-STRING may be what you want, but also consider that
> FORMAT can extend an adjustable string if you supply it as the first
> argument.

Learn something new every day! That did it for me, and beautifully,
too! Thank you very much for pointing that out!

Jeff
From: Peter Seibel
Subject: Re: Troubles extending a string...
Date: 
Message-ID: <m3oel0pasp.fsf@javamonkey.com>
"Jeff" <···@insightbb.com> writes:

> Is there any way to append a string onto another string without using
> CONCATENATE? The problem I am having is that I'm building a string,
> character by character, using VECTOR-PUSH-EXTEND. However, this process
> is recursive:
>
>
> (defun build-string ()
> (let ((s1 (create-adjustable-string-vector)))
> (if (check-for-recursion)
> (let ((s2 (build-string)))
> (---> want to append s2 to s1 here <---))
> s1)))
>
>
> The algorithm (of course) is a little more complicated than this. My
> initial attempt was to use CONCATENATE and just set 's1' to the return
> value, but this fails later on, as the string returned by CONCATENATE
> doesn't appear to be adjustable any more. Is there a way to append a
> string in-place?

Unless I've forgotten something, not directly. However it's easy
enough to write a VECTOR-APPEND that uses ADJUST-ARRAY, FILL-POINTER,
and REPLACE to do what you want:

  (defun vector-append (v1 v2)
    (assert (adjustable-array-p v1))
    (assert (ignore-errors (fill-pointer v1)))
    (let ((orig-length (length v1))
          (new-length (+ (length v1) (length v2))))
      (adjust-array v1 new-length)
      (setf (fill-pointer v1) new-length)
      (replace v1 v2 :start1 orig-length))
    v1)

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Björn Lindberg
Subject: Re: Troubles extending a string...
Date: 
Message-ID: <hcsy8k4bb54.fsf@my.nada.kth.se>
"Jeff" <···@insightbb.com> writes:

> Is there any way to append a string onto another string without using
> CONCATENATE? The problem I am having is that I'm building a string,
> character by character, using VECTOR-PUSH-EXTEND. However, this process
> is recursive:
> 
> 
> (defun build-string ()
> (let ((s1 (create-adjustable-string-vector)))
> (if (check-for-recursion)
> (let ((s2 (build-string)))
> (---> want to append s2 to s1 here <---))
> s1)))
> 
> 
> The algorithm (of course) is a little more complicated than this. My
> initial attempt was to use CONCATENATE and just set 's1' to the return
> value, but this fails later on, as the string returned by CONCATENATE
> doesn't appear to be adjustable any more. Is there a way to append a
> string in-place?

Perhaps you could use with-output-to-string; something like:

(defun build-string ()
  (with-output-to-string (s)
    (labels ((inner () ; to make the stream available through the recursion
               (write-string "foo" s)
               ...
               (inner)
               ...))
      (inner))))


Bj�rn
From: Pascal Bourguignon
Subject: Re: Troubles extending a string...
Date: 
Message-ID: <87acwkxq59.fsf@thalassa.informatimago.com>
"Jeff" <···@insightbb.com> writes:

> Is there any way to append a string onto another string without using
> CONCATENATE? The problem I am having is that I'm building a string,
> character by character, using VECTOR-PUSH-EXTEND. However, this process
> is recursive:
> 
> 
> (defun build-string ()
> (let ((s1 (create-adjustable-string-vector)))
> (if (check-for-recursion)
> (let ((s2 (build-string)))
> (---> want to append s2 to s1 here <---))
> s1)))
> 
> 
> The algorithm (of course) is a little more complicated than this. My
> initial attempt was to use CONCATENATE and just set 's1' to the return
> value, but this fails later on, as the string returned by CONCATENATE
> doesn't appear to be adjustable any more. Is there a way to append a
> string in-place?

Some would advice with-output-to-string. I don't know if it's
efficient in all implementations (I would not expect it, with all the
stream layers...), but at least in clisp it's rather fast because it's
a "primitive".

If you can compute the length of the result at the beginning, you can
allocate the result string then fill it with:

     (REPLACE result part :START1 current-pos)
     (INCF current-pos (LENGTH part))


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we.
From: Harald Hanche-Olsen
Subject: Re: Troubles extending a string...
Date: 
Message-ID: <pcohdqsuwqa.fsf@shuttle.math.ntnu.no>
+ "Jeff" <···@insightbb.com>:

| Is there any way to append a string onto another string without using
| CONCATENATE? The problem I am having is that I'm building a string,
| character by character, using VECTOR-PUSH-EXTEND. However, this process
| is recursive:
| 
| 
| (defun build-string ()
| (let ((s1 (create-adjustable-string-vector)))
| (if (check-for-recursion)
| (let ((s2 (build-string)))
| (---> want to append s2 to s1 here <---))
| s1)))

Ugh, that looks like Fortran to me (except for the lack of six spaces
in front of every line).  Surely you meant to say

(defun build-string ()
  (let ((s1 (create-adjustable-string-vector)))
    (if (check-for-recursion)
	(let ((s2 (build-string)))
	  (---> want to append s2 to s1 here <---))
	s1)))

Whatever.  Using with-output-to-string has already been suggested, and
it is in fact an excellent suggestion.  Another is to write a simple
helper function like this:

(defun vector-push-vector-extend (source target)
  (loop for thing across source do
	(vector-push-extend thing target))
  ;; return value, for ease of testing:
  target)

and then call (vector-push-vector-extend s2 s1) in the inner parts of
your loop.

-- 
* 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: Jeff
Subject: Re: Troubles extending a string...
Date: 
Message-ID: <ECPWc.84014$TI1.59343@attbi_s52>
Harald Hanche-Olsen wrote:

> + "Jeff" <···@insightbb.com>:
> 
> >  Is there any way to append a string onto another string without
> > using  CONCATENATE? The problem I am having is that I'm building a
> > string,  character by character, using VECTOR-PUSH-EXTEND. However,
> > this process  is recursive:
> >  
> >  
> >  (defun build-string ()
> >  (let ((s1 (create-adjustable-string-vector)))
> >  (if (check-for-recursion)
> >  (let ((s2 (build-string)))
> | (---> want to append s2 to s1 here <---))
> >  s1)))
> 
> Ugh, that looks like Fortran to me (except for the lack of six spaces
> in front of every line).  Surely you meant to say
>   [code snipped]

Yes, unfortunately Google doesn't like to keep formatting. So, unless
I'm at home, that's how it comes out -- which is why I try and keep the
code very simple.

Jeff