From: ·············@gmail.com
Subject: "Essential lisp utilities": where are they?
Date: 
Message-ID: <0e2efdd9-58fc-4ddd-931d-ffbf4d238741@c2g2000pra.googlegroups.com>
Hello,

I recall seeing a library of "essential lisp utilities", but I just
spent a better part of an hour going through cliki, my bookmarks,
installed libraries, and the web, and other than suspects such as
trivial-features, and cannot find it.

The reason is that I just wrote a little macro with-dir
(defmacro with-dir ((new-dir) &body body)
  `(let ((old-dir (ext:cd)))
;;     (format t "will move to ~a~%" ,new-dir)
     (ext:cd ,new-dir)
;;     (format t "current dir ~a~%" (ext:cd))
     ,@body
     (ext:cd old-dir)))

that I use on clisp(on cygwin+windows) but I suspect a more robust and
universal one exists somewhere, perhaps in the "essential lisp
utilities".

So, where is that beast?

Thanks,

Mirko

From: ·············@gmail.com
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <9419cccb-5681-400e-a021-b1b4a5fd9b08@p10g2000prf.googlegroups.com>
On Oct 31, 9:44 am, ·············@gmail.com wrote:
> Hello,
>
> I recall seeing a library of "essential lisp utilities", but I just
> spent a better part of an hour going through cliki, my bookmarks,
> installed libraries, and the web, and other than suspects such as
> trivial-features, and cannot find it.
>
> The reason is that I just wrote a little macro with-dir
> (defmacro with-dir ((new-dir) &body body)
>   `(let ((old-dir (ext:cd)))
> ;;     (format t "will move to ~a~%" ,new-dir)
>      (ext:cd ,new-dir)
> ;;     (format t "current dir ~a~%" (ext:cd))
>      ,@body
>      (ext:cd old-dir)))
>
> that I use on clisp(on cygwin+windows) but I suspect a more robust and
> universal one exists somewhere, perhaps in the "essential lisp
> utilities".
>
> So, where is that beast?
>
> Thanks,
>
> Mirko

Um, cl-utilities?

Mirko (the other twin)
From: William James
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <gef3ds$ank$1@aioe.org>
·············@gmail.com wrote:

> Hello,
> 
> I recall seeing a library of "essential lisp utilities", but I just
> spent a better part of an hour going through cliki, my bookmarks,
> installed libraries, and the web, and other than suspects such as
> trivial-features, and cannot find it.
> 
> The reason is that I just wrote a little macro with-dir
> (defmacro with-dir ((new-dir) &body body)
>   `(let ((old-dir (ext:cd)))
> ;;     (format t "will move to ~a~%" ,new-dir)
>      (ext:cd ,new-dir)
> ;;     (format t "current dir ~a~%" (ext:cd))
>      ,@body
>      (ext:cd old-dir)))

A macro isn't needed for this.

Ruby:

def with_dir new_dir
  old_dir = Dir.getwd
  Dir.chdir new_dir
  yield
  Dir.chdir old_dir
end

p Dir.getwd
with_dir( ".." ){ p Dir.getwd }
p Dir.getwd
From: ·············@gmail.com
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <bb4fa691-3318-499f-a1c2-09373ffa958b@a3g2000prm.googlegroups.com>
On Oct 31, 10:06 am, "William James" <·········@yahoo.com> wrote:
> ·············@gmail.com wrote:
> > Hello,
>
> > I recall seeing a library of "essential lisp utilities", but I just
> > spent a better part of an hour going through cliki, my bookmarks,
> > installed libraries, and the web, and other than suspects such as
> > trivial-features, and cannot find it.
>
> > The reason is that I just wrote a little macro with-dir
> > (defmacro with-dir ((new-dir) &body body)
> >   `(let ((old-dir (ext:cd)))
> > ;;     (format t "will move to ~a~%" ,new-dir)
> >      (ext:cd ,new-dir)
> > ;;     (format t "current dir ~a~%" (ext:cd))
> >      ,@body
> >      (ext:cd old-dir)))
>
> A macro isn't needed for this.
>
> Ruby:
>
> def with_dir new_dir
>   old_dir = Dir.getwd
>   Dir.chdir new_dir
>   yield
>   Dir.chdir old_dir
> end
>
> p Dir.getwd
> with_dir( ".." ){ p Dir.getwd }
> p Dir.getwd

Um, that really was of no help:
- did not answer my question, or improve my answer
- did not even remotely convince me to look into Ruby, which would
entail to a) learn it & b) redo everything I did so far.
From: ······@gmail.com
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <431f2216-420d-4992-8828-a39c489dab48@z6g2000pre.googlegroups.com>
On Oct 31, 8:07 am, Andreas Davour <·······@updateLIKE.uu.HELLse>
wrote:
> "William James" <·········@yahoo.com> writes:
> > ·············@gmail.com wrote:
>
> >> Hello,
>
> >> I recall seeing a library of "essential lisp utilities", but I just
> >> spent a better part of an hour going through cliki, my bookmarks,
> >> installed libraries, and the web, and other than suspects such as
> >> trivial-features, and cannot find it.
>
> >> The reason is that I just wrote a little macro with-dir
> >> (defmacro with-dir ((new-dir) &body body)
> >>   `(let ((old-dir (ext:cd)))
> >> ;;     (format t "will move to ~a~%" ,new-dir)
> >>      (ext:cd ,new-dir)
> >> ;;     (format t "current dir ~a~%" (ext:cd))
> >>      ,@body
> >>      (ext:cd old-dir)))
>
> > A macro isn't needed for this.
>
> > Ruby:
>
> > def with_dir new_dir
> >   old_dir = Dir.getwd
> >   Dir.chdir new_dir
> >   yield
> >   Dir.chdir old_dir
> > end
>
> > p Dir.getwd
> > with_dir( ".." ){ p Dir.getwd }
> > p Dir.getwd
>
> William, to post a solution to a problem in a comp.lang.* group in
> another language than the one the group is set up to discuss is counter
> productive and rude. Please don't.

I disagree. In fact, to be strict, his post is relevant in showing
macros are not necessary to the original question, while your poste is
off-topic.

Newsgroups got lots tech geekers like you that makes it suffer.

Further readings:

• Cross-posting & Language Factions
http://xahlee.org/Netiquette_dir/cross-post.html

plain text version follows:
----------------------
Cross-posting & Language Factions

Xah Lee, 2007-03-29

(The following article is originally cross-posted on 2007-04-16 to the
folowing newsgroups: comp.lang.perl.misc, comp.lang.python,
comp.lang.lisp, comp.lang.java.programmer, comp.lang.functional.)

Dear tech geekers,

In the past year i have crossed-posted (e.g. recently What are OOP's
Jargons and Complexities, Is laziness a programer's virtue?, On Java's
Interface (the meaning of interface in computer programing), there are
some controversy, and lots of off-topic and careless following.

I think there are few things today's tech geekers should remind
themselves:

• If you deem something off-topic to “your” newsgroup, and want to
tech-geek by changing the “follow-up group”, start with yourself.
Please do not cross-post yourself, and tweak the follow-up, and
proudly proclaim that you changed the follow-up as a benign gesture.

• Please remind yourself what is on-topic and off-topic. Unless you
are the authority of a online forum, otherwise, netiquette discussion,
policing, are off-topic in general, and only tend to worsen the
forum's quality. This issue is realized in newsgroup communities as
early as early 1990s.

• The facility of cross-posting is a good thing as a progress of
communication technology, and the action of cross-posting is a good
thing with respect to communication. What the common tech-geekers's
sensitivity to cross-posting are due to this collective's lack of
understanding of social aspects of communication. Cross-posting isn't
a problem. The problem is the power-struggling male nature and
defensiveness in propagating the tongues of a tech geeker's own.

Tech-geeker's behavior towards cross-posting over the years did
nothing to enhance the content quality of newsgroups, but engendered
among computing language factions incommunicado, and aided in the
proliferation of unnecessary re-invention (e.g. the likes of Perl,
PHP, Python, Ruby that are essentially the same) and stagnation (e.g.
the lisp camp with their above-it attitude).

If you are a programer of X and is learning Y or wondering about Y,
please do cross-post it. If your article is relevant to X, Y, and Z,
please cross post it. If you are really anti-cross-posting, please use
a online forum that is more specialized with controlled communication,
such as mailing lists, developer's blogs, and website-based forums.

I hope that the computing newsgroups will revive to its ancient nature
of verdant cross communication of quality content, as opposed to
today's rampant messages focused on political in-fighting, mutual
sneering, closed-mindedness, and careless postings.

References:

Tech Geekers versus Spammers

Netiquette Guidelines, 1995, by S Hambridge. (RFC 1855)
http://tools.ietf.org/html/rfc1855

  Xah
∑ http://xahlee.org/

☄
From: Pascal Bourguignon
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <490bb373$0$9221$426a74cc@news.free.fr>
······@gmail.com wrote:
> I disagree. In fact, to be strict, his post is relevant in showing
> macros are not necessary to the original question, while your poste is
> off-topic.

For the innocent bystander who doesn't already know that xahlee is a 
nut, macros are very necessary to the original question, to abstract 
away the boiler plate that lambda would be without:

(do-with-dir "some-dir"       (lambda () (something-to-do)     ))
(do-with-dir "some-other-dir" (lambda () (something-else-to-do)))
;; always the same -----------^^^^^^^^^^^----------------------^

This is explained in SICP, along with the other kinds of abstraction.

-- 
__Pascal Bourguignon__
http://www.informatimago.com
From: ······@gmail.com
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <065a20f8-268f-4f8a-84b0-1ed6fd0059ad@c36g2000prc.googlegroups.com>
On Oct 31, 5:40 pm, Pascal Bourguignon <····@informatimago.com> wrote:
> ······@gmail.com wrote:
> > I disagree. In fact, to be strict, his post is relevant in showing
> > macros are not necessary to the original question, while your poste is
> > off-topic.
>
> For the innocent bystander who doesn't already know that xahlee is a
> nut, macros are very necessary to the original question, to abstract
> away the boiler plate that lambda would be without:
>
> (do-with-dir "some-dir"       (lambda () (something-to-do)     ))
> (do-with-dir "some-other-dir" (lambda () (something-else-to-do)))
> ;; always the same -----------^^^^^^^^^^^----------------------^
>
> This is explained in SICP, along with the other kinds of abstraction.

Dear Pascal Bourguignon moron,

The issue of my previous post was about against persecuting different
opinions. It is not about, whether William James's Ruby code does or
does not supercede the macros feature of lisp.

On the issue of macros, please note, that it is one of lisp features
that gets lispers giddy, where you can see large amounts of posts
about macros every week. Note that, when a macro system is well
designed and extensive to incorporate pattern matching facilities, the
language becomes a term rewriting system, which is what Mathematica
is.

See also:

http://documents.wolfram.com/mathematica/Built-inFunctions/Programming/PatternMatching/

http://en.wikipedia.org/wiki/Pattern_matching

http://en.wikipedia.org/wiki/Rewriting

http://en.wikipedia.org/wiki/Mathematica

  Xah
∑ http://xahlee.org/

☄
From: budden
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <122b9770-bbe1-40ef-b428-9d03a62625b4@b31g2000prb.googlegroups.com>
Hi there.

By the way,
I'm interested in a situation with general purpose utility libraries
for CL. I used cllib, but it seems it is not fashionable today.
We have much smaller cl-utilities today instead. Also we have some
other small utility packages. What happened to cllib? Is it dead
and if it is, why? What is the right solution today?
From: Tobias C. Rittweiler
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <87d4h3kixw.fsf@freebits.de>
budden <········@mtu-net.ru> writes:

> Hi there.
>
> By the way,
> I'm interested in a situation with general purpose utility libraries
> for CL. I used cllib, but it seems it is not fashionable today.
> We have much smaller cl-utilities today instead. Also we have some
> other small utility packages. What happened to cllib? Is it dead
> and if it is, why? What is the right solution today?

Alexandria is the utility library du jour.

  -T.
From: budden
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <f1198932-7d40-4f3e-8c39-4be5d157c3e5@r15g2000prh.googlegroups.com>
> Alexandria is the utility library du jour.
Hmm, it just incomparably smaller than cllib. Could someone explain
what is wrong with cllib itself?
From: William James
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <gegkld$nnt$1@aioe.org>
William James wrote:

> ·············@gmail.com wrote:
> 
> > Hello,
> > 
> > I recall seeing a library of "essential lisp utilities", but I just
> > spent a better part of an hour going through cliki, my bookmarks,
> > installed libraries, and the web, and other than suspects such as
> > trivial-features, and cannot find it.
> > 
> > The reason is that I just wrote a little macro with-dir
> > (defmacro with-dir ((new-dir) &body body)
> >   `(let ((old-dir (ext:cd)))
> > ;;     (format t "will move to ~a~%" ,new-dir)
> >      (ext:cd ,new-dir)
> > ;;     (format t "current dir ~a~%" (ext:cd))
> >      ,@body
> >      (ext:cd old-dir)))
> 
> A macro isn't needed for this.
> 
> Ruby:
> 
> def with_dir new_dir
>   old_dir = Dir.getwd
>   Dir.chdir new_dir
>   yield
>   Dir.chdir old_dir
> end
> 
> p Dir.getwd
> with_dir( ".." ){ p Dir.getwd }
> p Dir.getwd

The handling of the code-block can be more explicit.

def with_dir new_dir, &block
  old_dir = Dir.getwd
  Dir.chdir new_dir
  block.call
  Dir.chdir old_dir
end

p Dir.getwd
with_dir( ".." ){ p Dir.getwd }
with_dir( ".." ) do
  p Dir.getwd
end
p Dir.getwd
From: Jochen Schmidt
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <d574c851-62dc-48ba-9f47-ef42d7faf076@i20g2000prf.googlegroups.com>
On 31 Okt., 15:06, "William James" <·········@yahoo.com> wrote:
> ·············@gmail.com wrote:
> > Hello,
>
> > I recall seeing a library of "essential lisp utilities", but I just
> > spent a better part of an hour going through cliki, my bookmarks,
> > installed libraries, and the web, and other than suspects such as
> > trivial-features, and cannot find it.
>
> > The reason is that I just wrote a little macro with-dir
> > (defmacro with-dir ((new-dir) &body body)
> >   `(let ((old-dir (ext:cd)))
> > ;;     (format t "will move to ~a~%" ,new-dir)
> >      (ext:cd ,new-dir)
> > ;;     (format t "current dir ~a~%" (ext:cd))
> >      ,@body
> >      (ext:cd old-dir)))
>
> A macro isn't needed for this.

You're wrong.

>
> Ruby:
>
> def with_dir new_dir
>   old_dir = Dir.getwd
>   Dir.chdir new_dir
>   yield
>   Dir.chdir old_dir
> end
>
> p Dir.getwd
> with_dir( ".." ){ p Dir.getwd }
> p Dir.getwd

The need for macros is encoded in a special case syntax for blocks
implemented in the Ruby interpreter. The programmer has no chance to
change this syntax like with the different kinds of macros in Common
Lisp.

ciao,
Jochen
From: D Herring
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <gehvaa$dmv$1@aioe.org>
William James wrote:
> ·············@gmail.com wrote:
>> I recall seeing a library of "essential lisp utilities", but I just
>> spent a better part of an hour going through cliki, my bookmarks,
>> installed libraries, and the web, and other than suspects such as
>> trivial-features, and cannot find it.
>>
>> The reason is that I just wrote a little macro with-dir
...
> A macro isn't needed for this.
> 
> Ruby:
> 
> def with_dir new_dir
>   old_dir = Dir.getwd
>   Dir.chdir new_dir
>   yield
>   Dir.chdir old_dir
> end
> 
> p Dir.getwd
> with_dir( ".." ){ p Dir.getwd }
> p Dir.getwd

True; same thing in lisp.  But the OP didn't want to use a functional 
style; he wanted to inline the code.  Hence the need for macros.

Your Ruby code translates into lisp that looks something like

(defun with-dir (new-dir f)
   (let ((old-dir (ext:cd)))
     (ext:cd new-dir)
     (unwind-protect
       (funcall f)
       (ext:cd old-dir))))

(ext:cd)
(with-dir new-dir (lambda () (print (ext:cd))))
(ext:cd)

[untested]

- Daniel
From: Mark Wooding
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <slrnghg7rr.kqp.mdw@metalzone.distorted.org.uk>
D Herring <········@at.tentpost.dot.com> wrote:

>> def with_dir new_dir
>>   old_dir = Dir.getwd
>>   Dir.chdir new_dir
>>   yield
>>   Dir.chdir old_dir
>> end
>
> Your Ruby code translates into lisp that looks something like
>
> (defun with-dir (new-dir f)
>    (let ((old-dir (ext:cd)))
>      (ext:cd new-dir)
>      (unwind-protect
>        (funcall f)
>        (ext:cd old-dir))))

I don't believe that the Ruby code does the equivalent of the Lisp
UNWIND-PROTECT.  I'd say that this was a defect in the Ruby (and the
earlier example Lisp code).

-- [mdw]
From: D Herring
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <gfapl5$2rr$1@aioe.org>
Mark Wooding wrote:
> D Herring <········@at.tentpost.dot.com> wrote:
> 
>>> def with_dir new_dir
>>>   old_dir = Dir.getwd
>>>   Dir.chdir new_dir
>>>   yield
>>>   Dir.chdir old_dir
>>> end
>> Your Ruby code translates into lisp that looks something like
>>
>> (defun with-dir (new-dir f)
>>    (let ((old-dir (ext:cd)))
>>      (ext:cd new-dir)
>>      (unwind-protect
>>        (funcall f)
>>        (ext:cd old-dir))))
> 
> I don't believe that the Ruby code does the equivalent of the Lisp
> UNWIND-PROTECT.  I'd say that this was a defect in the Ruby (and the
> earlier example Lisp code).

I wasn't sure of Ruby's semantics wrt yield.

If we weren't talking shell commands, the Lisp would be even simpler:

(defun with-dir (new-dir f)
   (let ((*default-pathname-defaults* new-dir))
     (funcall f)))

- Daniel
From: budden
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <a66ebf40-3f42-4ac6-a921-3db2a3e9f212@c22g2000prc.googlegroups.com>
Is that GNU license which is wrong with cllib?
From: D Herring
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <gfbdea$9r3$1@aioe.org>
budden wrote:
> Is that GNU license which is wrong with cllib?

Maybe -- it does hinder commercial adoption.

I'm not sure anything's wrong with cllib; but active development seems 
to have stalled a couple years ago.  Other projects have picked up in 
its place.

- Daniel
From: Kenny
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <49196721$0$20300$607ed4bc@cv.net>
D Herring wrote:
> budden wrote:
> 
>> Is that GNU license which is wrong with cllib?
> 
> 
> Maybe -- it does hinder commercial adoption.

What part of viral do you not understand? It also hinders adoption by 
anyone offering a library with an LGPL or BSD or MIT or any free as in 
the meaning of the word license, unless said offerer wants to join the 
GPL programme which apparently few do.

kzo
From: budden
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <23567ee5-ad22-40ad-89b9-9102a8cfb29c@i18g2000prf.googlegroups.com>
And one more question that is related to the topic.

Is there a lib which would do the following (very simple) things for a
strings:

- search and replace a subsequence with other subsequence;
- replace a subsequence with other sequence without limitations of
equal length as in cl:replace
- get last n elements of a subsequence
- trim a sequence with a predicate or element bag
- pad a sequence to a given length with an element from left or right
- add strings in a shorter way than (concatenate 'string a b)

These are very simple functions which are included in most modern
scripting languages. Yes, I know all this can be implemented easily by
myself. But it is strange that I was unable to find a library where
all the functions are present.
Having a _standard_ library of that kind would be nice for this could
make reading other's code easier.
From: Kenny
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <491ac99a$0$20280$607ed4bc@cv.net>
budden wrote:
> And one more question that is related to the topic.
> 
> Is there a lib which would do the following (very simple) things for a
> strings:
> 
> - search and replace a subsequence with other subsequence;
> - replace a subsequence with other sequence without limitations of
> equal length as in cl:replace
> - get last n elements of a subsequence
> - trim a sequence with a predicate or element bag
> - pad a sequence to a given length with an element from left or right
> - add strings in a shorter way than (concatenate 'string a b)
> 
> These are very simple functions which are included in most modern
> scripting languages. Yes, I know all this can be implemented easily by
> myself.

Hint.

> But it is strange that I was unable to find a library where
> all the functions are present.

So you are saying the language is too small? A language should have the 
union of the specific sequence functions all programmers expect? Yeah, 
can you believe God stopped at 94 elements?!

> Having a _standard_ library of that kind would be nice for this could
> make reading other's code easier.

Now you are just making things up.

hth, kt
From: Pascal J. Bourguignon
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <7cskpxgk21.fsf@pbourguignon.anevia.com>
budden <········@mtu-net.ru> writes:

> And one more question that is related to the topic.
>
> Is there a lib which would do the following (very simple) things for a
> strings:
>
> - search and replace a subsequence with other subsequence;

(search #(1 2 3) #(a b c 1 2 3 d e f)) --> 3
(let ((v (vector 1 2 3 4 5 6)))
   (replace v #(-1 -2 -3) :start1 2)
   v) --> #(1 2 -1 -2 -3 6)


> - replace a subsequence with other sequence without limitations of
> equal length as in cl:replace

Isn't that rather trivial to implement?

> - get last n elements of a subsequence

There are a lot of untold assumptions in your question.

(let ((sequence #(1 2 3 4 5 6 7 8))
                   (start 2)
                   (end   6)
                   (n     2))
               (coerce (last (coerce (subseq sequence start end) 'list)  n)
                       (first (type-of sequence)))) --> #(5 6)

> - trim a sequence with a predicate or element bag

(string-trim #(#\a #\b) "aabbaaccddaabbccddaabbaabb") --> "ccddaabbccdd"

For the rest, what are you, lazy?


> - pad a sequence to a given length with an element from left or right

(let ((sequence #(1 2 3 4 5))
      (padding 0)
      (total-length 20))
  (values (concatenate (first (type-of sequence)) 
                       (make-list (- total-length (length sequence)) :initial-element padding)
                       sequence)
          (concatenate (first (type-of sequence)) 
                       sequence
                       (make-list (- total-length (length sequence)) :initial-element padding))))
-->
#(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5) ;
#(1 2 3 4 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)


> - add strings in a shorter way than (concatenate 'string a b)

(declaim (inline !))
(defun ! (&rest strings) (apply (function concatenate) 'string  strings))
(! "abc" "def" "ghi") --> "abcdefghi"


> These are very simple functions which are included in most modern
> scripting languages. Yes, I know all this can be implemented easily by
> myself. But it is strange that I was unable to find a library where
> all the functions are present.

You are lying, as demonstrated above these features are directly
implemented in the COMMON-LISP package, you don't need any fucking
library to do this kind of thing.

Now, in you so called "scripting language", do you have any library to
implement an expert system with a RETE algorithm, like LISA?


> Having a _standard_ library of that kind would be nice for this could
> make reading other's code easier.

Is there any STANDARD library to implement an AI in your scripting language?


-- 
__Pascal Bourguignon__
From: budden
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <0ce314d4-41b4-4245-b23f-1f6c6dbf4f62@d36g2000prf.googlegroups.com>
Hmmm.

Pascal, you didn't answer my question. Instead of that, you said that
I lie. You are certainly wrong in that and I'd like you to apologize.

I did not ask about _how_ to add a strings. Why did you waste your
time writing a bad code instead of answering in a short to what I did
ask? Your code is bad, because it conses too much. Certainly, it is
not for a production. Replace code covers only one (not interesting)
case - where replacing sequence is of the same length. I can educate
you - there are several functions named like subst-seq, substitute-
subseq or nsubst-seq in popular libraries such as cllib or cl-
utilities. I expected that more trivial functions are in some other
well-known library too.

I didn't even ask why should I bother myself writing such a functions.
I ask why should I bother myself learning new _names_ for that
functions every time I open new code for studying. E.g., I use str+
for adding string designators. Someone use ! What would we do if we
begin working under common project? I am reluctant to learn new name
for adding strings instead of my str+.

> So you are saying the language is too small?
Kenny, is there a difference between a language and a library?

But now ok, stop. You give no help, you offend me, you take my time
writing an answers.
I need no more answers on this matter (but I still wait for apology).
From: Kenny
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <491b32d5$0$20290$607ed4bc@cv.net>
budden wrote:
> Hmmm.
> 
> Pascal, you didn't answer my question. Instead of that, you said that
> I lie. You are certainly wrong in that and I'd like you to apologize.

You might have better luck after he erases your hard drive.

> 
> I did not ask about _how_ to add a strings. Why did you waste your
> time writing a bad code instead of answering in a short to what I did
> ask? Your code is bad, because it conses too much. Certainly, it is
> not for a production. Replace code covers only one (not interesting)
> case - where replacing sequence is of the same length. I can educate
> you - there are several functions named like subst-seq, substitute-
> subseq or nsubst-seq in popular libraries such as cllib or cl-
> utilities. I expected that more trivial functions are in some other
> well-known library too.
> 
> I didn't even ask why should I bother myself writing such a functions.
> I ask why should I bother myself learning new _names_ for that
> functions every time I open new code for studying. E.g., I use str+
> for adding string designators. Someone use ! What would we do if we
> begin working under common project? I am reluctant to learn new name
> for adding strings instead of my str+.
> 
> 
>>So you are saying the language is too small?
> 
> Kenny, is there a difference between a language and a library?
> 
> But now ok, stop. You give no help, you offend me, you take my time
> writing an answers.

Somebody just defined Usenet. No, wait, I give great help. You just have 
to read between the lines. But actually I forget who you are, I have 
been beating my head against Dojo that undocument POS... YUI here I 
come! Where was I?

> I need no more answers on this matter (but I still wait for apology).

Sorry.

kenny
From: Pascal J. Bourguignon
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <87iqqs1u50.fsf@hubble.informatimago.com>
budden <········@mtu-net.ru> writes:

> Hmmm.
>
> Pascal, you didn't answer my question. Instead of that, you said that
> I lie. You are certainly wrong in that and I'd like you to apologize.
>
> I did not ask about _how_ to add a strings. Why did you waste your
> time writing a bad code instead of answering in a short to what I did
> ask? Your code is bad, because it conses too much. Certainly, it is
> not for a production. Replace code covers only one (not interesting)
> case - where replacing sequence is of the same length. I can educate
> you - there are several functions named like subst-seq, substitute-
> subseq or nsubst-seq in popular libraries such as cllib or cl-
> utilities. I expected that more trivial functions are in some other
> well-known library too.
>
> I didn't even ask why should I bother myself writing such a functions.
> I ask why should I bother myself learning new _names_ for that
> functions every time I open new code for studying. E.g., I use str+
> for adding string designators. Someone use ! What would we do if we
> begin working under common project? I am reluctant to learn new name
> for adding strings instead of my str+.

In real code, you write (concatenate 'string ...) so you can be read
by all CL programmers.

In real code, you don't concatenate strings.
In real code, you try to be efficient so you avoid copying strings.

In real code, you don't replace subsequences of different length either.
In real code, you try to avoid bugs, so you don't mutate your structures.


>> So you are saying the language is too small?
> Kenny, is there a difference between a language and a library?
>
> But now ok, stop. You give no help, you offend me, you take my time
> writing an answers.
> I need no more answers on this matter (but I still wait for apology).

As a certain word in my answer may give you the hint, I also felt
offended by your message, because you asked to have "library"
functions to realize features that are already present in CL itself.
I didn't implement library functions,  I showed you how a single CL
function or at most the combination of two basic CL functions was all
you needed to implement what you wanted.

What would be the point of defining a library of 404496 new names for
mere 2-function compositions?

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

READ THIS BEFORE OPENING PACKAGE: According to certain suggested
versions of the Grand Unified Theory, the primary particles
constituting this product may decay to nothingness within the next
four hundred million years.
From: budden
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <91d7e92b-d77b-46bb-b7ea-fed86f2c8033@q26g2000prq.googlegroups.com>
Hi there
  Kenny, you didn't offend me, apology request was directed to Pascal
only.
But (as usual) it is hard for me to understand you. I don't know what
does "somebody just defined Usenet"
mean and how is it related to the topic. While I know what every
separate word means...

  Pascal, I have no comments on what you say...
From: budden
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <33930367-dbbe-4607-a370-83eaff268850@o4g2000pra.googlegroups.com>
Hmm, now I got the comments.

All this is very strange.

Pascal, you wrote that no such a library is required while you did
that library yourself.

Here it is:
http://darcs.informatimago.com/darcs/public/lisp/common-lisp/string.lisp

Yet it is under GPL and it still misses the "right" function which
might be defined as

(defun sequence-last (sequence &optional (n 1))
  "Returns last n (default 1) elements of sequence as a new fresh
sequence of the same type. Err if n>length(sequence)"
  (let1 start (- (length sequence) n)
    (subseq sequence start)))

Earlier, we talked about altering lisp package system. You have a
complete lisp reader
implemented here:
http://darcs.informatimago.com/darcs/public/lisp/common-lisp/reader.lisp

Having a portable lisp reader implemented in lisp itself is likely to
solve task for 90%, as it supplies every character reader in the
readtable required for modifying a reader. You didn't give me a hint
that I might use that reader to implement my package system fixes.

Moreover, I see you tried to do some fixes of package system for
yourself (I can't find out if they
really work)
http://darcs.informatimago.com/darcs/public/lisp/common-lisp/package.lisp

;;;;        - allow to specify packages refered to (used) while not
;;;;          importing ("inheriting") any of it symbols; (:USE
package)
(I found nothing in a source which would indicate that this feature
really works, but it is declared in a comments).

You might share your experience, but you didn't

This all is very strange...
From: Kenny
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <491c08a5$0$14275$607ed4bc@cv.net>
budden wrote:
> Hmm, now I got the comments.
> 
> All this is very strange.
> 
> Pascal, you wrote that no such a library is required while you did
> that library yourself.
> 
> Here it is:
> http://darcs.informatimago.com/darcs/public/lisp/common-lisp/string.lisp
> 
> Yet it is under GPL and it still misses the "right" function which
> might be defined as
> 
> (defun sequence-last (sequence &optional (n 1))
>   "Returns last n (default 1) elements of sequence as a new fresh
> sequence of the same type. Err if n>length(sequence)"
>   (let1 start (- (length sequence) n)
>     (subseq sequence start)))
> 
> Earlier, we talked about altering lisp package system. You have a
> complete lisp reader
> implemented here:
> http://darcs.informatimago.com/darcs/public/lisp/common-lisp/reader.lisp
> 
> Having a portable lisp reader implemented in lisp itself is likely to
> solve task for 90%, as it supplies every character reader in the
> readtable required for modifying a reader. You didn't give me a hint
> that I might use that reader to implement my package system fixes.
> 
> Moreover, I see you tried to do some fixes of package system for
> yourself (I can't find out if they
> really work)
> http://darcs.informatimago.com/darcs/public/lisp/common-lisp/package.lisp
> 
> ;;;;        - allow to specify packages refered to (used) while not
> ;;;;          importing ("inheriting") any of it symbols; (:USE
> package)
> (I found nothing in a source which would indicate that this feature
> really works, but it is declared in a comments).
> 
> You might share your experience, but you didn't
> 
> This all is very strange...

Pascal is another professional c.l.l ball-buster who happens also to 
Actually Programs Computers(tm), which is why he will never be 
considered a True Lisper. Same advice as for me: turn down the gain on 
your antenna and left as an exercise is learning from the nutjobs on 
this NG...oh, ok: the best way to do that is to get off Usenet, get into 
a Lisp IDE, write some code, get stuck, come back here and ask for advice.

You'll be amazed.

hth,kxo
From: Pascal J. Bourguignon
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <7c7i77sxgj.fsf@pbourguignon.anevia.com>
budden <········@mtu-net.ru> writes:

> Hmm, now I got the comments.
>
> All this is very strange.
>
> Pascal, you wrote that no such a library is required while you did
> that library yourself.
>
> Here it is:
> http://darcs.informatimago.com/darcs/public/lisp/common-lisp/string.lisp
>
> Yet it is under GPL and it still misses the "right" function which
> might be defined as
>
> (defun sequence-last (sequence &optional (n 1))
>   "Returns last n (default 1) elements of sequence as a new fresh
> sequence of the same type. Err if n>length(sequence)"
>   (let1 start (- (length sequence) n)
>     (subseq sequence start)))


Sequences are either lists or vectors.

Notice that for lists, there is already a function LAST that does what you want:

(last '(1 2 3 4 5 6) 3) --> (4 5 6)

and for sequences, of course there is (subseq seq (- (length seq) n)).
The question is this: 

   Is it really necessary to define a library function sequence-last
   combining SUBSEQ, - and LENGTH?  Isn't (subseq seq (- (length seq) n))
   already sufficiently clear an idiom?


The big problem, is that even if you put such a function in a library
yourself, you won't be using it most of the time, because it is easier
to write (subseq seq (- (length seq) n)) than to search what library
contains the function, to load it, to import the symbol and to use it.


To be worthwhile, your library function must be significantly more complex.



> Earlier, we talked about altering lisp package system. You have a
> complete lisp reader
> implemented here:
> http://darcs.informatimago.com/darcs/public/lisp/common-lisp/reader.lisp
>
> Having a portable lisp reader implemented in lisp itself is likely to
> solve task for 90%, as it supplies every character reader in the
> readtable required for modifying a reader. You didn't give me a hint
> that I might use that reader to implement my package system fixes.


Here, we have a different problem.  I shouldn't have had to write this
package.   I could have done something else, I could have patched a
few implementations to add the hooks that are needed, and defined the
API in a CDR.  I choosed to write instead this package for
educationnal purposes (mainly mine), as a possible component of new
implementations, and eventually, as a "canonical" implementation for a
CDR.  Indeed, I would suggest other implementors to add the same hooks
too.


As for your namespace merging problem, indeed you could use the
READTABLE-PARSE-TOKEN hook to implement what you wanted. 

Since I think that the current behavior is better, I didn't follow
that thread very closely and indeed didn't suggest a solution, leaving
it up to the others to convince you that it wasn't such a good idea.
Sorry.


> Moreover, I see you tried to do some fixes of package system for
> yourself (I can't find out if they
> really work)
> http://darcs.informatimago.com/darcs/public/lisp/common-lisp/package.lisp
>
> ;;;;        - allow to specify packages refered to (used) while not
> ;;;;          importing ("inheriting") any of it symbols; (:USE
> package)
> (I found nothing in a source which would indicate that this feature
> really works, but it is declared in a comments).
>
> You might share your experience, but you didn't
>
> This all is very strange...


Actually, this is only a "declaration", for these package references,
nothing is done.  The rest of the code just use qualified symbols.
The purpose was to have to read only one form at the beginning of a
source file to know what dependencies may exist, without reading the
whole source.



This DEFINE-PACKAGE macro is now obsolete, and I should remove it.

As an example, have a look at:
 http://darcs.informatimago.com/lisp/common-lisp/aliases.lisp

Now I use a DECLAIM form to declare a declaration named
ALSO-USE-PACKAGES, and to declare the packages that are used, either
by qualified symbols, or dynamically.  It's followed by a standard
DEFPACKAGE form.

I've got in make-depends.lisp code that process the DECLAIM and
DEFPACKAGE form to build an asd file, while reading the source file
with all precautions.





I'm sorry this year and next, I don't have all the time I'd want to
devote to lisp development and cll support.  This may explain some
iffy participation.

-- 
__Pascal Bourguignon__
From: Thomas A. Russ
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <ymiiqqr5dee.fsf@blackcat.isi.edu>
budden <········@mtu-net.ru> writes:

> Yet it is under GPL and it still misses the "right" function which
> might be defined as
> 
> (defun sequence-last (sequence &optional (n 1))
>   "Returns last n (default 1) elements of sequence as a new fresh
> sequence of the same type. Err if n>length(sequence)"
>   (let1 start (- (length sequence) n)
>     (subseq sequence start)))

It's not missing.  It already exists in Common Lisp.  It's called LAST.
It is defined exactly as your function here.

Perhaps you would get a less frosty reception here if you would

 1)  First actually learn what's in Common Lisp before complaining about
     what's missing from it.
 2)  Not be quite so haughty when replying to people who are actually
     trying to help you.


-- 
Thomas A. Russ,  USC/Information Sciences Institute
I've given up.  Welcome to my kill file.
From: Kaz Kylheku
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <20081113191614.51@gmail.com>
On 2008-11-14, Thomas A. Russ <···@sevak.isi.edu> wrote:
> budden <········@mtu-net.ru> writes:
>
>> Yet it is under GPL and it still misses the "right" function which
>> might be defined as
>> 
>> (defun sequence-last (sequence &optional (n 1))
>>   "Returns last n (default 1) elements of sequence as a new fresh
>> sequence of the same type. Err if n>length(sequence)"
>>   (let1 start (- (length sequence) n)
>>     (subseq sequence start)))
>
> It's not missing.  It already exists in Common Lisp.  It's called LAST.
> It is defined exactly as your function here.

Not quite; LAST works only on lists.

Here is an implementation not based on SUBSEQ. Since LAST returns
a list that may share substructure with the original list, the same
can be done in the vector case:

(defun sequence-last (seq &optional (n 1))
  (etypecase seq
    (list (last seq n))
    (vector (let* ((len (length seq))
                   (pos (max 0 (- len n)))
		   (tail (make-array `(,(- len pos)) 
		                     :element-type (array-element-type seq)
		                     :displaced-to seq
				     :displaced-index-offset pos)))
	       tail))))


Actually, a generic slice extractor that works on sequences, uses
Python array indexing (i.e. negative means from end), and which 
doesn't copy data would be quite handy. It should be robust in overflow cases:
obtaining the last 4 items of a length 3 sequence should just return the
sequence, the same way that (third nil) returns nil.
From: Kenny
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <491cf614$0$4913$607ed4bc@cv.net>
Kaz Kylheku wrote:
> On 2008-11-14, Thomas A. Russ <···@sevak.isi.edu> wrote:
> 
>>budden <········@mtu-net.ru> writes:
>>
>>
>>>Yet it is under GPL and it still misses the "right" function which
>>>might be defined as
>>>
>>>(defun sequence-last (sequence &optional (n 1))
>>>  "Returns last n (default 1) elements of sequence as a new fresh
>>>sequence of the same type. Err if n>length(sequence)"
>>>  (let1 start (- (length sequence) n)
>>>    (subseq sequence start)))
>>
>>It's not missing.  It already exists in Common Lisp.  It's called LAST.
>>It is defined exactly as your function here.
> 
> 
> Not quite; LAST works only on lists.

<sigh> So one day we want to do it and we say oh golly great add-on and 
we write last-seq and then we need it again in eight months and of 
course have no recollection we wrote last-seq eight months earlier and 
we Just Code It using the builtins not stopping to say oh golly because 
by now we have been thru this a dozen times and know we will just forget 
it is there and get on with out work which differentiates us from the 
Buddenites who have no work to do other than to annoy newsgroups with 
their preaching.

TISLHFYP.

kzo
From: budden
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <2676a383-0f99-463e-9fb3-ce673c35cdc9@l33g2000pri.googlegroups.com>
> I've given up.  Welcome to my kill file.
It seems like you can't teach me a lisp, Thomas. You simply do not
know lisp. Either you don't know how the last works
(let ((lst '(a s d f))) (eq (last lst 3) (cdr lst))) ==> t
Or you don't know the difference between a list and a sequence.
(last "asdf") ==> error
All this is trivial and you now proved your incompetence before all
the worlds eyes. Please don't waste your time teaching me a life. I
didn't ask that at all. Farewell.

> and then we need it again in eight months
Likely this might happen (and it used to happen to me, too). But it is
mostly a bad organization of a mind. Developer should always care
about code reuse. Writing everything costs. Some string functions are
not so trivial (take a look at PHP string library). And, I never might
forget that I wrote "right" function as I started programming with
Clipper, then get to Pascal/SQL. And as I always had a handy set of
string functions, I can never forget that "right" function is missing.
It looks like losing a screwdriver somewhere in a workshop: you never
fill comfortable until you find it back. One more reason - I am clever
and lazy. I dislike writing stupid things again and again. It is
easier to write them once and organize them into a reusable lib.

> differentiates us from the Buddenites who have no work to do
Did you see my last paste? BTW, it is a happy time now when I am able
to use lisp for a job. But it will be over too soon...

> I've got in make-depends.lisp code that process the DECLAIM and
DEFPACKAGE form to build an asd file, while reading the source file
with all precautions.

Thanks, Pascal, now I got the idea. It is not what I want - I prefer
to use lisp as a kind of OS - it is simply always running and when I
restart it, I load everything I have. So I don't need to specify which
packages to load.
Yesterday I implemented "use-packages" aka "see-packages" but it can't
read quasiquotation and vectors. It turned out to be surprisingly
easy, but seems that more pieces of actual lisp reader are to be
brough in. And that is why I am so evil to poor Thomas.

Kaz, thanks. Repeating myself, I don't need a code. I asked for a lib.
Presence of "right" function is only a sign of a style which I would
like to see. I said about scripting languages without a goal of
humbling a lisp, but only to specify more exactly what I'm looking
for. Btw i think that python indexing is dangerous. I think ideal
subseq would have a signature like that

(subseqh ; h stands for hairy
  seq
  &key start
  end
  len  ; specify a length instead of indices
  from-end ; count from end
  circular ; wrap around
  type ; specify output sequence type
  [ mutate ; can someone find a better name for that?
             { :modify ; may modify toplevel list structure/displace
vector
             | :share  ; may share toplevel list structure/displace
vector
             | nil   ; do not share toplevel structure
             | deep-copy-function ; copier for deep copying
            } ]
  )

This would be a deserving level of generality. It might be slow, but
inlining/compiler macros might help. Anyway, scripting languages are
slower at a factor of ten.
From: budden
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <1b4527e5-198d-40bc-a52c-3baee40eea4a@v22g2000pro.googlegroups.com>
(let ((old-dir (gensym))) ...)
Using cl-utilities:with-gensyms for that is much more fair:
(with-gensyms (old-dir) ...)
From: Kenny
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <491d6ae1$0$4918$607ed4bc@cv.net>
budden wrote:
> Likely this might happen (and it used to happen to me, too). But it is
> mostly a bad organization of a mind. Developer should always care
> about code reuse. Writing everything costs. 

No, you missed my point. It comes up too rarely to develop mindshare, 
and is too easily tossed off as a subseq.

As for code reuse, I find it cuts into LOC/day stat.

kxo
From: budden
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <85557ba3-ec1b-4c3b-bf9c-eb3503697e92@i24g2000prf.googlegroups.com>
> No, you missed my point. It comes up too rarely to develop mindshare,
> and is too easily tossed off as a subseq.
I don't know what is a mindshare.

> As for code reuse, I find it cuts into LOC/day stat.
Hmm. I see Java MP tools are better than the lisp ones as they
generate source. Lisp macros generate
the source on the fly and it can't be accounted. Would be a great idea
to map macroexpand over a forms in a file
and save it :)
Happily, I was never paid for lines :)
From: Kenny
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <491c071d$0$14302$607ed4bc@cv.net>
budden wrote:
> Hi there
>   Kenny, you didn't offend me, apology request was directed to Pascal
> only.
> But (as usual) it is hard for me to understand you. I don't know what
> does "somebody just defined Usenet"
> mean and how is it related to the topic. While I know what every
> separate word means...

Sorry! I will try to be more literal in the future. I clown around a lot 
on Usenet so the trick is to ignore me 90% of the time and keep your 
eyes open for when I announce Xello or something like that (only it 
looks as if YUI has heard I am an easy target and wants to kick my butt 
all weekend, so it might be closer to two weeks on that).

kzo
From: ··················@gmail.com
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <7b93e91e-91f9-491c-a7ac-686e4df959b8@h23g2000prf.googlegroups.com>
On Oct 31, 8:44 am, ·············@gmail.com wrote:
> Hello,
>
> I recall seeing a library of "essential lisp utilities", but I just
> spent a better part of an hour going through cliki, my bookmarks,
> installed libraries, and the web, and other than suspects such as
> trivial-features, and cannot find it.
>
> The reason is that I just wrote a little macro with-dir
> (defmacro with-dir ((new-dir) &body body)
>   `(let ((old-dir (ext:cd)))
> ;;     (format t "will move to ~a~%" ,new-dir)
>      (ext:cd ,new-dir)
> ;;     (format t "current dir ~a~%" (ext:cd))
>      ,@body
>      (ext:cd old-dir)))
>
> that I use on clisp(on cygwin+windows) but I suspect a more robust and
> universal one exists somewhere, perhaps in the "essential lisp
> utilities".
>
> So, where is that beast?
>
> Thanks,
>
> Mirko

(defmacro with-dir ((new-dir) &body body)
 (let ((old-dir (gensym)))
  `(let ((,old-dir (ext:cd)))
;;     (format t "will move to ~a~%" ,new-dir)
     (ext:cd ,new-dir)
;;     (format t "current dir ~a~%" (ext:cd))
     ,@body
     (ext:cd ,old-dir))))

Need to worry about what happens if someone has defined a variable
'old-dir' previously in the program.
From: ··················@gmail.com
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <28cb3c94-8f17-48e3-89f2-b931dd8458e5@k24g2000pri.googlegroups.com>
On Nov 14, 1:46 am, ··················@gmail.com wrote:
> On Oct 31, 8:44 am, ·············@gmail.com wrote:
>
>
>
> > Hello,
>
> > I recall seeing a library of "essential lisp utilities", but I just
> > spent a better part of an hour going through cliki, my bookmarks,
> > installed libraries, and the web, and other than suspects such as
> > trivial-features, and cannot find it.
>
> > The reason is that I just wrote a little macro with-dir
> > (defmacro with-dir ((new-dir) &body body)
> >   `(let ((old-dir (ext:cd)))
> > ;;     (format t "will move to ~a~%" ,new-dir)
> >      (ext:cd ,new-dir)
> > ;;     (format t "current dir ~a~%" (ext:cd))
> >      ,@body
> >      (ext:cd old-dir)))
>
> > that I use on clisp(on cygwin+windows) but I suspect a more robust and
> > universal one exists somewhere, perhaps in the "essential lisp
> > utilities".
>
> > So, where is that beast?
>
> > Thanks,
>
> > Mirko
>
> (defmacro with-dir ((new-dir) &body body)
>  (let ((old-dir (gensym)))
>   `(let ((,old-dir (ext:cd)))
> ;;     (format t "will move to ~a~%" ,new-dir)
>      (ext:cd ,new-dir)
> ;;     (format t "current dir ~a~%" (ext:cd))
>      ,@body
>      (ext:cd ,old-dir))))
>
> Need to worry about what happens if someone has defined a variable
> 'old-dir' previously in the program.

Untested, (didn't use an emacs editor either) but you get the idea.
From: Pascal J. Bourguignon
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <7cr65er6it.fsf@pbourguignon.anevia.com>
··················@gmail.com writes:
>
> (defmacro with-dir ((new-dir) &body body)
>  (let ((old-dir (gensym)))
>   `(let ((,old-dir (ext:cd)))
> ;;     (format t "will move to ~a~%" ,new-dir)
>      (ext:cd ,new-dir)
> ;;     (format t "current dir ~a~%" (ext:cd))
>      ,@body
>      (ext:cd ,old-dir))))
>
> Need to worry about what happens if someone has defined a variable
> 'old-dir' previously in the program.

No, there's no need.  At least not in a conforming implementation,
with a conforming program.

Either old-dir has been declared dynamic (which is unlikely if you've
followed the convention of naming dynamic variables with *stars*), in
which case old-dir is being bound dynamically, but since the macro
calls only Common Lisp functions such as CL:LIST, CL:CONS, CL:APPEND,
etc, and OLD-DIR cannot come from CL or SYSTEM (since we're
considering a conforming program) there's no legal way  that its
binding could influence these functions.  

Or old-dir has not been declared dynamic, in which case  it's a
lexical binding, and there's absolutely no consequences of what
old-dir may be used for in the rest of the program.


For a more general case, if you're unsure of the status the symbols
you have at hand, you can always unintern them to use your own:

(eval-when (:compile-toplevel :load-toplevel :execute) 
   (unintern 'old-dir))
(defmacro with-dir ...
  (let ((old-dir ...))  ; this one is yours, and no other body of 
     ...))              ; code can have set it up against you.



-- 
__Pascal Bourguignon__
From: budden
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <3330bfae-23b4-4251-8923-34f0cce39764@i18g2000prf.googlegroups.com>
> For a more general case, if you're unsure of the status the symbols
you have at hand, you can always unintern them to use your own.

This is not needed here: old-dir is bound lexically.
From: Pascal J. Bourguignon
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <7cmyg2qmmy.fsf@pbourguignon.anevia.com>
budden <········@gmail.com> writes:

>> For a more general case, if you're unsure of the status the symbols
> you have at hand, you can always unintern them to use your own.
>
> This is not needed here: old-dir is bound lexically.

How do you know that?

(defvar old-dir nil)

...

-- 
__Pascal Bourguignon__
From: budden
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <845b4317-6948-4050-afc3-d8f86f3226eb@o40g2000prn.googlegroups.com>
> > This is not needed here: old-dir is bound lexically.
> (defvar old-dir nil)
I was wrong, sorry.
From: ··················@gmail.com
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <cf84f91d-1875-437e-88c2-aaf0c3398ba5@i20g2000prf.googlegroups.com>
On Nov 14, 4:39 am, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> ··················@gmail.com writes:
>
> > (defmacro with-dir ((new-dir) &body body)
> >  (let ((old-dir (gensym)))
> >   `(let ((,old-dir (ext:cd)))
> > ;;     (format t "will move to ~a~%" ,new-dir)
> >      (ext:cd ,new-dir)
> > ;;     (format t "current dir ~a~%" (ext:cd))
> >      ,@body
> >      (ext:cd ,old-dir))))
>
> > Need to worry about what happens if someone has defined a variable
> > 'old-dir' previously in the program.
>
> No, there's no need.  At least not in a conforming implementation,
> with a conforming program.
>
> Either old-dir has been declared dynamic (which is unlikely if you've
> followed the convention of naming dynamic variables with *stars*), in
> which case old-dir is being bound dynamically, but since the macro
> calls only Common Lisp functions such as CL:LIST, CL:CONS, CL:APPEND,
> etc, and OLD-DIR cannot come from CL or SYSTEM (since we're
> considering a conforming program) there's no legal way  that its
> binding could influence these functions.  
>
> Or old-dir has not been declared dynamic, in which case  it's a
> lexical binding, and there's absolutely no consequences of what
> old-dir may be used for in the rest of the program.
>
> For a more general case, if you're unsure of the status the symbols
> you have at hand, you can always unintern them to use your own:
>
> (eval-when (:compile-toplevel :load-toplevel :execute)
>    (unintern 'old-dir))
> (defmacro with-dir ...
>   (let ((old-dir ...))  ; this one is yours, and no other body of
>      ...))              ; code can have set it up against you.
>
> --
> __Pascal Bourguignon__

-------------------------------------------------------------------
 (defmacro with-change-dir (new-dir &body body)
  `(let ((old-dir (cd)))
     (cd ,new-dir)
     ,@body
     (cd old-dir)
     ))

CL-USER 6 : 2 >  (let ((old-dir (pathname "C:\\foo\\")))
    (with-change-dir (pathname "C:\\bar\\")
      (print old-dir)))

#P"P:/"
#P"P:/"

(defmacro with-change-dir2 (new-dir &body body)
  (let ((old-dir (gensym)))
  `(let ((,old-dir (cd)))
     (cd ,new-dir)
     ,@body
     (cd ,old-dir)
     )))

CL-USER 8 : 2 >  (let ((old-dir (pathname "C:\\foo\\")))
    (with-change-dir2 (pathname "C:\\bar\\")
      (print old-dir)))

#P"C:/foo/"
#P"P:/"
----------------------------------------------------------------
See the difference? (first is print, second is the return from cd)

This is using Lispworks...
From: Pascal J. Bourguignon
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <87ej1dmkmh.fsf@hubble.informatimago.com>
··················@gmail.com writes:

> On Nov 14, 4:39�am, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> ··················@gmail.com writes:
>>
>> > (defmacro with-dir ((new-dir) &body body)
>> > �(let ((old-dir (gensym)))
>> > � `(let ((,old-dir (ext:cd)))
>> > ;; � � (format t "will move to ~a~%" ,new-dir)
>> > � � �(ext:cd ,new-dir)
>> > ;; � � (format t "current dir ~a~%" (ext:cd))
>> > � � �,@body
>> > � � �(ext:cd ,old-dir))))
>>
>> > Need to worry about what happens if someone has defined a variable
>> > 'old-dir' previously in the program.
>>
>> No, there's no need. �At least not in a conforming implementation,
>> with a conforming program.
>>
>> Either old-dir has been declared dynamic (which is unlikely if you've
>> followed the convention of naming dynamic variables with *stars*), in
>> which case old-dir is being bound dynamically, but since the macro
>> calls only Common Lisp functions such as CL:LIST, CL:CONS, CL:APPEND,
>> etc, and OLD-DIR cannot come from CL or SYSTEM (since we're
>> considering a conforming program) there's no legal way �that its
>> binding could influence these functions. �
>>
>> Or old-dir has not been declared dynamic, in which case �it's a
>> lexical binding, and there's absolutely no consequences of what
>> old-dir may be used for in the rest of the program.
>>
>> For a more general case, if you're unsure of the status the symbols
>> you have at hand, you can always unintern them to use your own:
>>
>> (eval-when (:compile-toplevel :load-toplevel :execute)
>> � �(unintern 'old-dir))
>> (defmacro with-dir ...
>> � (let ((old-dir ...)) �; this one is yours, and no other body of
>> � � �...)) � � � � � � �; code can have set it up against you.
>>
>> --
>> __Pascal Bourguignon__
>
> -------------------------------------------------------------------
>  (defmacro with-change-dir (new-dir &body body)
>   `(let ((old-dir (cd)))
>      (cd ,new-dir)
>      ,@body
>      (cd old-dir)
>      ))
>
> CL-USER 6 : 2 >  (let ((old-dir (pathname "C:\\foo\\")))
>     (with-change-dir (pathname "C:\\bar\\")
>       (print old-dir)))
>
> #P"P:/"
> #P"P:/"
>
> (defmacro with-change-dir2 (new-dir &body body)
>   (let ((old-dir (gensym)))
>   `(let ((,old-dir (cd)))
>      (cd ,new-dir)
>      ,@body
>      (cd ,old-dir)
>      )))
>
> CL-USER 8 : 2 >  (let ((old-dir (pathname "C:\\foo\\")))
>     (with-change-dir2 (pathname "C:\\bar\\")
>       (print old-dir)))
>
> #P"C:/foo/"
> #P"P:/"
> ----------------------------------------------------------------
> See the difference? (first is print, second is the return from cd)
>
> This is using Lispworks...

Of course, but see how the fact that defining old-dir around
with-change-dir or with-change-dir2 doesn't impact in any way the
behavior of these macros.

On the other hand, and again, of course,  what changes, is what happen
if you make reference _inside_ the body to a variable named old-dir.
But this is totally irrelevant to the fact that there is or there is
not a binding to old-dir surrounding the calls to these macros.

The fact that old-dir refers to the saved directory in the body of
with-change-dir may be a specification of that macro.  For example,
LOOP-FINISH is a function that is bound only in the scope of the body
of LOOP:


C/USER[15]> (loop-finish)

*** - (LOOP-FINISH) is possible only from within LOOP
The following restarts are available:
ABORT          :R1      ABORT
C/Break 1 USER[16]> :q
C/USER[17]> (loop :do (print 'hi) (when (zerop (random 2)) (loop-finish)))

HI 
HI 
HI 
NIL
C/USER[18]> 


Since you wrote with-change-dir without a single character of
documentation, we can only take itsource as specification, bug for
bug, and you cannot expect anything else than what it does, bug for
bug.


But it's true that it's bad style to leave stuff internal to the macro
leak down to the body.  If that's intended, you'd better add a
parameter to the macro, the name of a variable that will be defined to
the benefit of the body:

(defmacro with-changed-dir ((dir-var new-dir) &body body)
  (let ((actual-saved-dir-var (gensym)))
    `(let* ((,actual-saved-dir-var (cd))
            (,dir-var ,actual-saved-dir-var))
       (cd ,new-dir) 
       (unwind-protect (progn ,@body)
         (cd ,actual-saved-dir-var)))))


C/USER[37]> (with-changed-dir (old-dir #P"/tmp/")
               (list old-dir (cd)))
(#P"/home/pjb/" #P"/tmp/")

Note that you should also prepare for non-local exits from body with unwind.


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

READ THIS BEFORE OPENING PACKAGE: According to certain suggested
versions of the Grand Unified Theory, the primary particles
constituting this product may decay to nothingness within the next
four hundred million years.
From: Kaz Kylheku
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <20081114100616.453@gmail.com>
On 2008-11-14, Pascal J. Bourguignon <···@informatimago.com> wrote:
> ··················@gmail.com writes:
>>
>> (defmacro with-dir ((new-dir) &body body)
>>  (let ((old-dir (gensym)))
>>   `(let ((,old-dir (ext:cd)))
>> ;;     (format t "will move to ~a~%" ,new-dir)
>>      (ext:cd ,new-dir)
>> ;;     (format t "current dir ~a~%" (ext:cd))
>>      ,@body
>>      (ext:cd ,old-dir))))
>>
>> Need to worry about what happens if someone has defined a variable
>> 'old-dir' previously in the program.
>
> No, there's no need.  At least not in a conforming implementation,
> with a conforming program.

I think anonymous' concern is over the previous verson which doesn't have the
gensym, leaving the inserted forms exposed to a binding of OLD-DIR.
From: ··················@gmail.com
Subject: Re: "Essential lisp utilities": where are they?
Date: 
Message-ID: <5f1adbfa-2031-4d77-b69e-ad4bd06ce25e@r37g2000prr.googlegroups.com>
On Nov 14, 1:11 pm, Kaz Kylheku <········@gmail.com> wrote:
> On 2008-11-14, Pascal J. Bourguignon <····@informatimago.com> wrote:
>
>
>
> > ··················@gmail.com writes:
>
> >> (defmacro with-dir ((new-dir) &body body)
> >>  (let ((old-dir (gensym)))
> >>   `(let ((,old-dir (ext:cd)))
> >> ;;     (format t "will move to ~a~%" ,new-dir)
> >>      (ext:cd ,new-dir)
> >> ;;     (format t "current dir ~a~%" (ext:cd))
> >>      ,@body
> >>      (ext:cd ,old-dir))))
>
> >> Need to worry about what happens if someone has defined a variable
> >> 'old-dir' previously in the program.
>
> > No, there's no need.  At least not in a conforming implementation,
> > with a conforming program.
>
> I think anonymous' concern is over the previous verson which doesn't have the
> gensym, leaving the inserted forms exposed to a binding of OLD-DIR.

Sorry if I was unclear.