I do this sort of thing a lot, and I'm tired of looking at concatenate 'string everywhere. So I thought it'd be nice to have something with a short name, like strcat (at least I didn't call it StrCat. Would str-cat be more Lispy?) I want the name short, because that helps keep the code small and avoid having to have excess carriage returns everywhere
> I do this sort of thing a lot, and I'm tired of looking at concatenate > 'string everywhere. So I thought it'd be nice to have something with > a short name, like strcat (at least I didn't call it StrCat. Would > str-cat be more Lispy?) I want the name short, because that helps > keep the code small and avoid having to have excess carriage returns > everywhere
Personally I would name it STRING-CONCAT or some such, but that's only me and I'm having a lot of trouble fitting my code into 80 columns. :)
>I do this sort of thing a lot, and I'm tired of looking at concatenate >'string everywhere. So I thought it'd be nice to have something with >a short name, like strcat (at least I didn't call it StrCat. Would >str-cat be more Lispy?) I want the name short, because that helps >keep the code small and avoid having to have excess carriage returns >everywhere
Well, short names in general are not very Lispy. Except for some of the primitives that are used extremely frequently (DEFUN, CAR, CONS), most Lisp functions are words spelled out in full. In Zetalisp this function was called STRING-APPEND.
-- Barry Margolin, bar...@genuity.net Genuity, Woburn, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
* rif <r...@mit.edu> | I can concatenate strings using | | (concatenate 'string "foo" (a-string-returning-function) "baz")) | | I do this sort of thing a lot,
But that should have told you something. You should perhaps look into Common Lisp's support for string-streams.
-- Erik Naggum, Oslo, Norway
Act from reason, and failure makes you rethink and study harder. Act from faith, and failure makes you blame someone and push harder.
It's not the most efficient way of doing this, but...
> I do this sort of thing a lot, and I'm tired of looking at concatenate > 'string everywhere.
... you're obviously not concerned with efficiency. That, or you have yet to discover WITH-OUTPUT-TO-STRING.
> So I thought it'd be nice to have something with a short name, like > strcat (at least I didn't call it StrCat. Would str-cat be more > Lispy?) I want the name short, because that helps keep the code > small and avoid having to have excess carriage returns everywhere
Using abbreviations in global names is generally considered a bad thing. Notice how few CL functions use them ... and those are only the old ones, before the lesson was learned.
-- /|_ .-----------------------. ,' .\ / | No to Imperialist war | ,--' _,' | Wage class war! | / / `-----------------------' ( -. | | ) | (`-. '--.) `. )----'
-- Barry Margolin, bar...@genuity.net Genuity, Woburn, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
t...@apocalypse.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
> Using abbreviations in global names is generally considered a bad > thing. Notice how few CL functions use them ... and those are only
But conversely, CL is a language which encourages you to create your own domain-specific language on top of it, and perhaps it's reasonable when creating a language that the shorter words should correspond to the most often-used concepts.
After all, it seems on the whole, a bit pointless to create an alternative to (concatenate 'string ...) on the grounds that it's excessively long, unless the replacement is going to be significantly shorter.
(That said, I agree with the other comments here that string-streams are probably a better idea in this case anyway)
What an interesting coincidence. I was noticing how much (concatenate 'string ..., was repeating in my code. I have been doing a lot of string processing lately. I wrote this very thing today, and wondered what the community would think about it. If it was considered bad style, etc ... my macro was called s+
Thank you for posting this question rif! And thank you everyone who offered your thoughts and advice about this.
> I do this sort of thing a lot, and I'm tired of looking at concatenate > 'string everywhere. So I thought it'd be nice to have something with > a short name, like strcat (at least I didn't call it StrCat. Would > str-cat be more Lispy?) I want the name short, because that helps > keep the code small and avoid having to have excess carriage returns > everywhere
> If you are not familiar with APPLY, check out CLtL2 or CLHS, since > both do a far better at explaining its use than I am able to.
> Hope that helps!
> Richard.
> P.S. Personally I would leave it as a macro, since you're not doing > anything but rewriting the way a function is called.
It is better to use functions when you can, because functions are far more flexible than macros: you can apply, funcall, reduce, map, and generally pass them around. If you want to avoid the overhead of the function call, instead of using a macro use an inline function, as Jochen points out.
-- ; Matthew Danish <mdan...@andrew.cmu.edu> ; OpenPGP public key: C24B6010 on keyring.debian.org ; Signed or encrypted mail welcome. ; "There is no dark side of the moon really; matter of fact, it's all dark."
> > If you are not familiar with APPLY, check out CLtL2 or CLHS, since > > both do a far better at explaining its use than I am able to.
> > Hope that helps!
> > Richard.
> > P.S. Personally I would leave it as a macro, since you're not doing > > anything but rewriting the way a function is called.
> It is better to use functions when you can, because functions are far > more flexible than macros: you can apply, funcall, reduce, map, and > generally pass them around. If you want to avoid the overhead of the > function call, instead of using a macro use an inline function, as > Jochen points out.
I think a good general rule of thumb is if it is evaluating all its arguments, it is not a macro. ie (defmacro strcat (@rest strings) `(concatenate 'string ,strings))
Barry Margolin <bar...@genuity.net> writes: > In article <xcvd6p77okj....@apocalypse.OCF.Berkeley.EDU>, > Thomas F. Burdick <t...@apocalypse.OCF.Berkeley.EDU> wrote: > >rif <r...@mit.edu> writes:
> Shouldn't it be (apply #'curry #'(lambda ...) (rest args))?
Oops, that's what I get for coding directly in my post. The actual CURRY-LEFT and CURRY-RIGHT functions (and accompanying compiler macros) I use are a little less obvious, and I was just trying to get the point across.
> BTW, the way this definition reuses variable and function names reminds me > of the old PL/I joke:
> IF IF = IF > THEN THEN = THEN; > ELSE ELSE = ELSE;
> Let's hear it for languages without reserved words! :)
Between my working on compiler stuff, and the CL interpreter I recently wrote (in debugging, but coming in a public and liberally licenced form soon), I'm slightly worried that I'm more comfortable with two namespaces and tight scoping than most people. I noticed that over the last year or two, I've been doing even more of this than I used to.
> (That said, I agree with the other comments here that string-streams > are probably a better idea in this case anyway)
So I investigated a bit, and it seems to me (please correct me if I'm wrong) that string-streams are the right solution if what I'm doing is building up a single string using a large number of concatenate operations. In my situation, what's actually happening is that once or twice per function (in many functions), I need to take a base file name and add an extension to the filename (not always the same extnsions(s)), so I don't thing that string-streams help here.
rif <r...@mit.edu> writes: > In my situation, what's actually happening is that once > or twice per function (in many functions), I need to take a base file > name and add an extension to the filename (not always the same > extnsions(s)), so I don't thing that string-streams help here.
Hmm - maybe you should start to think in terms of pathnames instead? That will absolutely not make your code very compact to begin with, but it might be more appropriate. Maybe you should really use something like:
* rif wrote: >> > So I investigated a bit, and it seems to me (please correct me if I'm > wrong) that string-streams are the right solution if what I'm doing is > building up a single string using a large number of concatenate > operations. In my situation, what's actually happening is that once > or twice per function (in many functions), I need to take a base file > name and add an extension to the filename (not always the same > extnsions(s)), so I don't thing that string-streams help here.
If you're doing stuff with pathnames, then you should use pathnames, not strings!
(defun typify-pathname (pathname type) (make-pathname :type type :defaults pathname))
* rif <r...@mit.edu> | In my situation, what's actually happening is that once or twice per | function (in many functions), I need to take a base file name and add an | extension to the filename (not always the same extnsions(s)), so I don't | thing that string-streams help here.
Then your next exercise would be to investigate pathnames and their manipulation functions. Sorry about the string-streams detour.
-- Erik Naggum, Oslo, Norway
Act from reason, and failure makes you rethink and study harder. Act from faith, and failure makes you blame someone and push harder.
t...@apocalypse.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
> ... you're obviously not concerned with efficiency. That, or you have > yet to discover WITH-OUTPUT-TO-STRING.
It has been our experience that the overhead to setup a string stream for output can be quite high, at least in some implementations. It isn't clear that using such a form will be more efficient than doing string concatentation.
The string output formalism is convenient, however, if you already have print functions that do what you want, or if the parts of the code that add parts to the final string are widely scattered, with a lot of processing or decision making in between.
-- Thomas A. Russ, USC/Information Sciences Institute t...@isi.edu
* Thomas A. Russ | It has been our experience that the overhead to setup a string stream for | output can be quite high, at least in some implementations.
Please report this is as a performance-related deficiency to the vendor. Even more, /please/ do not discourage people from using features just because some vendors have not yet given priority to performance. Doing so causes the language we can depend on to shrink as vendors ignore the parts of the standard they do not "like" and think people should not use.
-- Erik Naggum, Oslo, Norway
Act from reason, and failure makes you rethink and study harder. Act from faith, and failure makes you blame someone and push harder.
> t...@apocalypse.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
> > ... you're obviously not concerned with efficiency. That, or you have > > yet to discover WITH-OUTPUT-TO-STRING.
> It has been our experience that the overhead to setup a string stream > for output can be quite high, at least in some implementations. It > isn't clear that using such a form will be more efficient than doing > string concatentation.
Hmm, I just checked with CMUCL, OpenMCL, and CLISP. On the latter two, using string streams is clearly faster. CMUCL is slower, but, as Erik noted, I consider that to be a bug (now that I noticed). I would argue that it *should* be more efficient, though, since you're giving the compiler more information about what you're up to.
> The string output formalism is convenient, however, if you already have > print functions that do what you want, or if the parts of the code that > add parts to the final string are widely scattered, with a lot of > processing or decision making in between.
It's definately an interface that encourages doing things the right way, so even on CMUCL, I would reccommend using it unless you've actually determined string-streams to be the source of a performance problem.
-- /|_ .-----------------------. ,' .\ / | No to Imperialist war | ,--' _,' | Wage class war! | / / `-----------------------' ( -. | | ) | (`-. '--.) `. )----'
> Using abbreviations in global names is generally considered a bad > thing. Notice how few CL functions use them ... and those are only > the old ones, before the lesson was learned.
I take it that you're not very in with Paul Graham's macro: abbreviate
>>>>> On 16 Nov 2002 23:39:51 -0800, Vijay L ("Vijay") writes:
Vijay> t...@apocalypse.OCF.Berkeley.EDU (Thomas F. Burdick) wrote in message <news:xcvd6p77okj.fsf@apocalypse.OCF.Berkeley.EDU>... >> Using abbreviations in global names is generally considered a bad >> thing. Notice how few CL functions use them ... and those are only >> the old ones, before the lesson was learned. >> Vijay> I take it that you're not very in with Paul Graham's macro: abbreviate
Vijay> which is used to, as the name suggests, abbreviate long named Vijay> functions and macros such as:
Vijay> (abbreviate mvbind multiple-value-bind)
Vijay> I find MVBIND far easier to use (except in indenting, but I use Vijay> editor:setup-indent, so even that problem is solved) than Vijay> MULTIPLE-VALUE-BIND
If your problem is that you don't like to type long names, why not use the abbreviation facility that is built into your editor? For example, in Emacs, you can make the string "mvb" automatically expand into "multiple-value-bind". You don't have to type the long string, but also nobody who comes along looking at your code later on has to figure out what your random abbreviation means.