From: David Bakhash
Subject: labels/flet for dynamic scope
Date: 
Message-ID: <cxjso5y9sym.fsf@acs5.bu.edu>
Is there a way in CL to have a labels, or flet that creates a temporary
dynamic function, so that if it's called elsewhere, non-lexically, then it
works:

example:

(defun call-an-error () (error "this is an error"))

(labels* ((error (&rest args) nil))
  (call-an-error))

Where executing that would just produce NIL, with no real error being
signaled.  How can one achieve this?

BTW, I don't want to use (setf symbol-function) with an unwind-protect to get
this affect.  I'm hoping that flet/labels has a declaration that will allow
this.

thanks,
dave

From: Kent M Pitman
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <sfwyafqw6ar.fsf@world.std.com>
David Bakhash <·····@bu.edu> writes:

> Is there a way in CL to have a labels, or flet that creates a temporary
> dynamic function, so that if it's called elsewhere, non-lexically, then it
> works:
> 
> example:
> 
> (defun call-an-error () (error "this is an error"))
> 
> (labels* ((error (&rest args) nil))
>   (call-an-error))
> 
> Where executing that would just produce NIL, with no real error being
> signaled.  How can one achieve this?
> 
> BTW, I don't want to use (setf symbol-function) with an unwind-protect to get
> this affect.  I'm hoping that flet/labels has a declaration that will allow
> this.

I believe this is the time one asks:

 What are you REALLY trying to do?
From: Barry Margolin
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <D%jq3.17$34.764@burlma1-snr2>
In article <···············@acs5.bu.edu>, David Bakhash  <·····@bu.edu> wrote:
>Is there a way in CL to have a labels, or flet that creates a temporary
>dynamic function, so that if it's called elsewhere, non-lexically, then it
>works:
>
>example:
>
>(defun call-an-error () (error "this is an error"))
>
>(labels* ((error (&rest args) nil))
>  (call-an-error))
>
>Where executing that would just produce NIL, with no real error being
>signaled.  How can one achieve this?

For the specific case of squashing errors, you may be able to use
IGNORE-ERRORS:

(ignore-errors (call-an-error)) => NIL, #<SIMPLE-ERROR "this is an error">

It's not quite the same, though.  In your version, calling ERROR within
that environment is a no-op -- the call to ERROR returns and the function
continues.  Within IGNORE-ERRORS, signalling an error causes IGNORE-ERRORS
to return immediately.  This is usually what's wanted -- functions that
call ERROR are not generally prepared for it to return; consider:

(defun something ...
  ...
  (when (zerop x)
    (error "X must not be zero."))
  (setq y (/ z x))
  ...)

This code clearly is trying to avoid division by zero, so it would be wrong
for ERROR to return.

>BTW, I don't want to use (setf symbol-function) with an unwind-protect to get
>this affect.  I'm hoping that flet/labels has a declaration that will allow
>this.

(defmacro dynamic-flet ((function-name args &body function-body)
                         &body flet-body)
  `(let ((old-binding (fdefinition ',function-name))) ; WARNING non-hygienic
     (unwind-protect
         (progn (setf (fdefinition ',function-name)
                      (lambda ,args ,@function-body))
                ,@flet-body)
       (setf (fdefinition ',function-name)
             old-binding))))

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, 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.
From: Vassil Nikolov
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <l03130302b3cf987c5f5e@195.138.129.103>
Barry Margolin wrote:                [1999-08-05 17:39 +0000]

  [...]
  > (defmacro dynamic-flet ((function-name args &body function-body)
  >                          &body flet-body)
  >   `(let ((old-binding (fdefinition ',function-name))) ; WARNING non-hygienic
  >      (unwind-protect
  >          (progn (setf (fdefinition ',function-name)
  >                       (lambda ,args ,@function-body))
  >                 ,@flet-body)
  >        (setf (fdefinition ',function-name)
  >              old-binding))))

I think one should also consider calling the function by FUNCALL of
a global (special) variable, and binding that variable dynamically.
I'd prefer that at least in some cases for being more perspicuous^1
and also more robust with respect to multithreading (assuming
the implementation does deep binding).
__________
^1 as to the possibility of `replacing' the function dynamically---
   with such design what one sees (in terms of function being
   called) is not necessarily what one gets

But of course there is no universally best way; as Kent Pitman
noted, the important question is what the actual purpose is in
order to find the best design for the specific case.  (What is
good about Lisp is that it offers a number of ways, each with
its own tradeoffs, so one can take the most appropriate one.)

(It is surely redundant to note that FLET/LABELS do *not*
provide any dynamic function bindings.)


Vassil Nikolov
Permanent forwarding e-mail: ········@poboxes.com
For more: http://www.poboxes.com/vnikolov
  Abaci lignei --- programmatici ferrei.





 Sent via Deja.com http://www.deja.com/
 Share what you know. Learn what you don't.
From: Barry Margolin
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <LGmq3.27$34.766@burlma1-snr2>
In article <·····················@195.138.129.103>,
Vassil Nikolov  <········@poboxes.com> wrote:
>Barry Margolin wrote:                [1999-08-05 17:39 +0000]
>
>  [...]
>  > (defmacro dynamic-flet ((function-name args &body function-body)
>  >                          &body flet-body)
>  >   `(let ((old-binding (fdefinition ',function-name))) ; WARNING non-hygienic
>  >      (unwind-protect
>  >          (progn (setf (fdefinition ',function-name)
>  >                       (lambda ,args ,@function-body))
>  >                 ,@flet-body)
>  >        (setf (fdefinition ',function-name)
>  >              old-binding))))
>
>I think one should also consider calling the function by FUNCALL of
>a global (special) variable, and binding that variable dynamically.
>I'd prefer that at least in some cases for being more perspicuous^1
>and also more robust with respect to multithreading (assuming
>the implementation does deep binding).

That's only feasible if you have control over the code that will be calling
the function.  The impression I got from his example is that this code is
already written and presumably unchangeable, which is why he wants to
change what happens when it calls certain functions.  If you had access to
the source code you could simply remove the call to ERROR, or have it call
a different function that calls ERROR conditionally.

Note one thing about my solution and the ERROR example: the consequences of
redefining built-in functions is not defined in Common Lisp.  A CL
implementation is permitted to generate inline code for built-in functions,
so redefining ERROR might not have any effect.  It could also invoke ERROR
internally, at times that you didn't expect (presumably depending on
internal condition handlers to hide this from you), so redefining ERROR
(even temporarily) could cause unexpected malfunctions.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, 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.
From: David Bakhash
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <cxjpv129bic.fsf@acs5.bu.edu>
Barry Margolin <······@bbnplanet.com> writes:

> That's only feasible if you have control over the code that will be calling
> the function.  The impression I got from his example is that this code is
> already written and presumably unchangeable, which is why he wants to
> change what happens when it calls certain functions.  If you had access to
> the source code you could simply remove the call to ERROR, or have it call
> a different function that calls ERROR conditionally.

that's exactly right.  I was making a call to a function that is provided by
LW.  It was returning an error for an unknown reason, and I wanted a
work-around.  Of course, I didn't have access to the source, so I setf'd the
function definition of 'error to return nil no matter what, and then the
funtion call worked just fine.

Basically, the behavior I wanted was that which happens in Emacs Lisp.  I
wouldn't use it in real code; maybe just at the prompt.  Something like what
Barry wrote would work.  I just wanted to know if there was a standard way
about it.

> Note one thing about my solution and the ERROR example: the consequences of
> redefining built-in functions is not defined in Common Lisp.  A CL
> implementation is permitted to generate inline code for built-in functions,
> so redefining ERROR might not have any effect.  It could also invoke ERROR
> internally, at times that you didn't expect (presumably depending on
> internal condition handlers to hide this from you), so redefining ERROR
> (even temporarily) could cause unexpected malfunctions.

This is really a shame.  I understand that there's a performance issue here,
and why there might therefore be a distinction between built-in functions and
those defined by the user.  But I don't like it.  At the same time, however,
the ability to inline code is important, and I don't know what the compiler
would have to do in order to make inlined code safe when you setf something
like (fdefinition 'error).

Still, I've heard (from Erik Naggum, I think) that ACL doesn't obey the inline
decl.  There must be a reason.

dave
From: R. Matthew Emerson
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <87zp05oqll.fsf@nightfly.apk.net>
David Bakhash <·····@bu.edu> writes:

> 
> This is really a shame.  I understand that there's a performance issue here,
> and why there might therefore be a distinction between built-in functions and
> those defined by the user.  But I don't like it.  At the same time, however,
> the ability to inline code is important, and I don't know what the compiler
> would have to do in order to make inlined code safe when you setf something
> like (fdefinition 'error).
> 
> Still, I've heard (from Erik Naggum, I think) that ACL doesn't obey
> the inline decl.  There must be a reason.

It is true that ACL doesn't pay attention to inline declarations.

ACL *will* inline built-in functions under appropriate optimization
settings when the compiler thinks it's profitable to do so.

In their documentation for ACL, Franz explains:

     We have been asked why the inline declaration is ignored. It is
     not that we believe that inlining user functions does not provide
     any advantages, it is that we believe that there are other
     improvements that will provide more advantages. We had been
     anticipating that the ANSI CL spec would provide more guidance on
     how to implement inlining (by certifying the augment-environment
     function and some other stuff specified in CLtL-2, but ANSI chose
     in the end not to include that in the final spec), so now we
     intend, in some later release, to provide some user-function
     inlining capability.

     Note that inlining is not a unmixed blessing. It increases the
     amount of space used by a function (since both the function
     definition and the block to stick in when the function is inlined
     have to be created and stored) and it makes debugging harder (by
     making the compiled code diverge from the source code). It is
     also prone to subtle errors (on the programmers side) and bugs
     (on our side).

-matt
From: Barry Margolin
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <53oq3.33$34.805@burlma1-snr2>
In article <···············@acs5.bu.edu>, David Bakhash  <·····@bu.edu> wrote:
>Barry Margolin <······@bbnplanet.com> writes:
>
>> That's only feasible if you have control over the code that will be calling
>> the function.  The impression I got from his example is that this code is
>> already written and presumably unchangeable, which is why he wants to
>> change what happens when it calls certain functions.  If you had access to
>> the source code you could simply remove the call to ERROR, or have it call
>> a different function that calls ERROR conditionally.
>
>that's exactly right.  I was making a call to a function that is provided by
>LW.  It was returning an error for an unknown reason, and I wanted a
>work-around.  Of course, I didn't have access to the source, so I setf'd the
>function definition of 'error to return nil no matter what, and then the
>funtion call worked just fine.

As I said earlier, if ERROR is all you're concerned with, use
IGNORE-ERRORS.  You shouldn't need to redefine ERROR when a standard
mechanism is provided.

>Basically, the behavior I wanted was that which happens in Emacs Lisp.  I
>wouldn't use it in real code; maybe just at the prompt.  Something like what
>Barry wrote would work.  I just wanted to know if there was a standard way
>about it.
>
>> Note one thing about my solution and the ERROR example: the consequences of
>> redefining built-in functions is not defined in Common Lisp.  A CL
>> implementation is permitted to generate inline code for built-in functions,
>> so redefining ERROR might not have any effect.  It could also invoke ERROR
>> internally, at times that you didn't expect (presumably depending on
>> internal condition handlers to hide this from you), so redefining ERROR
>> (even temporarily) could cause unexpected malfunctions.
>
>This is really a shame.  I understand that there's a performance issue here,
>and why there might therefore be a distinction between built-in functions and
>those defined by the user.  But I don't like it.  At the same time, however,
>the ability to inline code is important, and I don't know what the compiler
>would have to do in order to make inlined code safe when you setf something
>like (fdefinition 'error).

Inlining is not the only reason to prohibit redefining standard functions.
Imagine the havoc you could create if you redefined something like LIST or
DELETE, which are used extensively in the implementation.  Even if you
think you're redefining them compatibly, it's possible that the
implementation has dependencies on undocumented features that you weren't
aware of (perhaps they've implemented some function so that it never causes
a GC, and call it from places that can't tolerate GC occurring, but your
redefined version doesn't meet that constraint).

When we were writing this section of the standard we considered the
alternative of allowing programmers to redefine standard functions, but
specifying that such redefinitions should have no impact on the behavior of
other functions.  This would effectively require all the standard functions
to be implemented something like:

(defun common-lisp:delete (&rest args)
  (apply #internal:delete args))
(defun common-lisp:cons (car cdr)
  (internal:cons car cdr))

Internally, the implementation would use the versions from the INTERNAL
package, so that redefining functions in the COMMON-LISP package wouldn't
affect them.  We decided not to do this because of all the work that it
would entail for all the implementors, for little benefit.

Had we gone in this direction, your redefinition of ERROR wouldn't work,
either, because the function whose behavior you want to change was provided
by LW, so it would presumably call INTERNAL:ERROR, not COMMON-LISP:ERROR.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, 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.
From: David Bakhash
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <cxjhfmd9dr5.fsf@acs5.bu.edu>
Barry Margolin <······@bbnplanet.com> writes:

> As I said earlier, if ERROR is all you're concerned with, use
> IGNORE-ERRORS.  You shouldn't need to redefine ERROR when a standard
> mechanism is provided.

Barry,

As I thought this was clear, but I dind't go into it in the original post.  So
here goes.

first off, I'm happy I posted, because I learned about some implementation
issues regarding inlining, built-in functions, etc.

still, if you put an ignore-errors around a block of code in which #'error is
called before the code you want executed, then your ignore-errors just won't
work:

(ignore-errors
  (error "this is an error")
  (print "made it this far"))

==> NIL
#<SIMPLE-ERROR 203FEAE4>

In other words, once an error is seen, you exit the block.  I just wanted to
see what would happen if I ignored errors without exiting the block, but just
returned nil for the errors and moved on.  Of course, this was only for test
purposes, and I'd never put it in real code (and I'd expect that it could
crash the system, etc.)

dave
From: Bernhard Pfahringer
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <7ofpbi$1jg8$1@www.univie.ac.at>
In article <···············@acs5.bu.edu>, David Bakhash  <·····@bu.edu> wrote:
>
>still, if you put an ignore-errors around a block of code in which #'error is
>called before the code you want executed, then your ignore-errors just won't
>work:
>
>(ignore-errors
>  (error "this is an error")
>  (print "made it this far"))
>
>==> NIL
>#<SIMPLE-ERROR 203FEAE4>
>
>In other words, once an error is seen, you exit the block.  I just wanted to
>see what would happen if I ignored errors without exiting the block, but just
>returned nil for the errors and moved on.  Of course, this was only for test
>purposes, and I'd never put it in real code (and I'd expect that it could
>crash the system, etc.)

As nobody has mentioned ACL's advice facility before, I thought I mention it:
You can specify code to be run before, after, or around a function call.
In your specific case you could do something like the following (provided
ERROR was not inlined):

USER(18): (excl:advise error :around :really-ignore-error 0
	                  (format t "~&ERROR: ~S~%" excl:arglist))
ERROR
USER(19): (+ 2 'a)
ERROR: (TYPE-ERROR :DATUM A :EXPECTED-TYPE NUMBER :FORMAT-CONTROL
        #(··@<~s: `~s' is not of the expected type ······@>"
          #(EXCL::FORMAT-RUNTIME-LOGICAL-BLOCK EXCL::XP T NIL NIL NIL
            #(··@<~s: `~s' is not of the expected type ······@>"
              EXCL::FORMAT-NOCOLON-S EXCL::&ARG+ 81927
              EXCL::PPRINT-NEWLINE-FILL #\` EXCL::FORMAT-NOCOLON-S EXCL::&ARG+
              163852 EXCL::PPRINT-NEWLINE-FILL 196623
              EXCL::PPRINT-NEWLINE-FILL 245779 EXCL::PPRINT-NEWLINE-FILL
              311318 EXCL::PPRINT-NEWLINE-FILL 360474
              EXCL::PPRINT-NEWLINE-FILL 426019 EXCL::PPRINT-NEWLINE-FILL
              573480 EXCL::PPRINT-NEWLINE-FILL #\` EXCL::FORMAT-NOCOLON-S
              EXCL::&ARG+ #\')
            NIL))
        :FORMAT-ARGUMENTS (EXCL::+_2OP A NUMBER))
NIL
USER(20): (excl:unadvise error :around :really-ignore-error)
ERROR
USER(21): (+ 2 'a)
Error: EXCL::+_2OP: `A' is not of the expected type `NUMBER'
  [condition type: TYPE-ERROR]
[1] USER(22): USER(23): 
USER(23):


-- 
--------------------------------------------------------------------------
Bernhard Pfahringer
Austrian Research Institute for  http://www.ai.univie.ac.at/~bernhard/
Artificial Intelligence          ········@ai.univie.ac.at 
From: Pierre R. Mai
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <871zdg1l7f.fsf@orion.dent.isdn.cs.tu-berlin.de>
········@hummel.ai.univie.ac.at (Bernhard Pfahringer) writes:

> In article <···············@acs5.bu.edu>, David Bakhash  <·····@bu.edu> wrote:
> >
> >still, if you put an ignore-errors around a block of code in which #'error is
> >called before the code you want executed, then your ignore-errors just won't
> >work:
> >
> >(ignore-errors
> >  (error "this is an error")
> >  (print "made it this far"))
> >
> >==> NIL
> >#<SIMPLE-ERROR 203FEAE4>
> >
> >In other words, once an error is seen, you exit the block.  I just wanted to
> >see what would happen if I ignored errors without exiting the block, but just
> >returned nil for the errors and moved on.  Of course, this was only for test
> >purposes, and I'd never put it in real code (and I'd expect that it could
> >crash the system, etc.)
> 
> As nobody has mentioned ACL's advice facility before, I thought I mention it:
> You can specify code to be run before, after, or around a function call.
> In your specific case you could do something like the following (provided
> ERROR was not inlined):

I seem to remember that the specific "problem" he is trying to work
around occurs on LispWorks, and not ACL, but LispWorks has an advice
facility, too, so your advice (no pun intended ;) to use advice still
applies, IMHO.  Much, much better than clobbering your internal error
function...

Regs, Pierre.

-- 
Pierre Mai <····@acm.org>         PGP and GPG keys at your nearest Keyserver
  "One smaller motivation which, in part, stems from altruism is Microsoft-
   bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]
From: Tim Bradshaw
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <ey3aes5q3se.fsf@lostwithiel.tfeb.org>
* David Bakhash wrote:

[ Redefinition of functions in the CL package]

> This is really a shame.  I understand that there's a performance issue here,
> and why there might therefore be a distinction between built-in functions and
> those defined by the user.  But I don't like it.  At the same time, however,
> the ability to inline code is important, and I don't know what the compiler
> would have to do in order to make inlined code safe when you setf something
> like (fdefinition 'error).

Note that, for your own code, it is quite possible to make things work
so that you can redefine `built-in' functions -- you can simply use
the package system to concoct a package which looks-like-CL but is
not.  I've posted my `conduit package' stuff which allows this kind of
thing here in the past (for various stupid reasons involving dead HW
and strange tape formats I don't have it available right now, or I'd
put it up for FTP or something).

Of course, if you don't have the source to the thing for which you are
trying to redefine CL-defined functions you can't do this.  But that's
a *good* thing I think, as it enables people who write systems to be
reasonably sure that the functions they are calling are the functions
that they think they are calling.  I have plenty of code that calls
ERROR in places where if it continued it would be very bad indeed
(along the lines of `delete all your files' bad), so if someone
redefines ERROR it's pretty bad.

This is not to say that I think you should not be redefining ERROR --
if it makes something broken work, and you are happy with the other
possible bad results, that's fine.  I just think that the fact the
standard explicitly says that the consequences are undefined if you do
that is the right thing for it to say.

--tim (who remembers all-to-well the effect of trying to trace PRINT
       on a xerox machine...)
From: Kent M Pitman
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <sfwzp058q8e.fsf@world.std.com>
David Bakhash <·····@bu.edu> writes:

> > Note one thing about my solution and the ERROR example: the consequences of
> > redefining built-in functions is not defined in Common Lisp.  A CL
> > implementation is permitted to generate inline code for built-in functions,
> > so redefining ERROR might not have any effect.  It could also invoke ERROR
> > internally, at times that you didn't expect (presumably depending on
> > internal condition handlers to hide this from you), so redefining ERROR
> > (even temporarily) could cause unexpected malfunctions.
> 
> This is really a shame.  I understand that there's a performance issue here,

There is really no performance issue here.  No one inlines ERROR.
The issue is one of hygiene.  Any system-defined function is shared between
potentially more programs than just yours, and it is just not something 
that you can predict whether someone will find your "helpful change"
really helpful in a multi-application environment.

Further, this used to come up a lot in Maclisp, which had a variable
PRIN1 that you could set to control the system printing of things
in a read-eval-print loop.  If it was its default value (NIL, I think)
the system would use the PRIN1 function.  Otherwise, it would use the hook.
Observing the actual usage patterns, you found a tug-of-war between people
saying "I know what PRIN1 does and I want to override it" and others saying
"I know how you want to override it and I really want that" and others
saying "I know why you don't want me to override it and I want to override
what you're doing" and so on.  The fact is that this problem of redefinition
in the way you're talking about is the classical philosophical puzzle
of the unstoppable force and the impenetrable barrier.  They are great
concepts in principle, but they don't go well together.  Right now, you
are told you can override the definition.  But someone else doesn't
want you to.  Who is right?  The only really right thing is to have the 
system take a definitive position on the matter and not leave it open
to users trying to second-guess each other.

Redefining ERROR is *very* dangerous.  You have no idea under what 
circumstances it will be called or what dire things it might be hiding.
See my examples of ERROR mid-page and remarks about ethics at page bottom 
on p869 of CLTL2 and think about the situation cited in terms of
how it would play out if you redefined this call to ERROR.  System
implementors shouldn't be surprised by users redefining ERROR because
users do all sorts of brazenly wrongheaded things, but users should
not take the fact that system writers should protect themselves as
license that they not protect themselves.  I recall my drivers' ed.
instructor in high school telling us a story about some person who had
the "brilliant" idea that if he drove around at night with his headlights
off, he could sail through stop signs without stopping because then he
could see  the headlights of oncoming cars clearly and if there were no
headlights he would know no one was coming.  We all want to think
we're the only ones doing dangerous things in the world and that we can
count on others to be good.  I dunno.

> and why there might therefore be a distinction between built-in functions and
> those defined by the user.  But I don't like it.

It isn't such a distinction.  The distinction is only between functions
you own and functions you don't.  It's not system/user.  You must be
free to say how your functions work and under what circumstances you
will warrant their correct function.  And others must be free to do the
same.  That's just the golden rule.  It's really prety hard to make a 
credible argument against the golden rule.

> At the same time, however,
> the ability to inline code is important,

but not relevant here.

> 
> Still, I've heard (from Erik Naggum, I think) that ACL doesn't obey 
> the inline decl.  There must be a reason.

The inline declaration gives permission, not a command.  ACL surely
does obey the inline declaration insofar as the inline declaration has
semantics.  The inline declaration can always be ignored.

There may still be some reason, but I don't see what it would have to do
with any of this.
From: David Bakhash
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <cxjg11x9db7.fsf@acs5.bu.edu>
Kent M Pitman <······@world.std.com> writes:

> > I wrote:
> > and why there might therefore be a distinction between built-in functions
> > and those defined by the user.  But I don't like it.

> It isn't such a distinction.  The distinction is only between functions
> you own and functions you don't.  It's not system/user.  You must be

Yes.  After reading the arguments I see things very differently.

> > the ability to inline code is important,
> 
> but not relevant here.

strike that.  it was a tangent.

> The inline declaration gives permission, not a command.  ACL surely
> does obey the inline declaration insofar as the inline declaration has
> semantics.  The inline declaration can always be ignored.
> 
> There may still be some reason, but I don't see what it would have to do
> with any of this.

I read the blurb that someone posted from ACL about why they don't obey the
inline declaration.  I think after reading it, I can see why that choice was
made, and I'm happy it came up.

thanks for the insights,
dave
From: Steve Gonedes
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <m2k8r7u101.fsf@KludgeUnix.com>
Kent M Pitman <······@world.std.com> writes:
 
< Further, this used to come up a lot in Maclisp, which had a variable
< PRIN1 that you could set to control the system printing of things
< in a read-eval-print loop.  If it was its default value (NIL, I think)
< the system would use the PRIN1 function.  Otherwise, it would use the hook.
< Observing the actual usage patterns, you found a tug-of-war between people
< saying "I know what PRIN1 does and I want to override it" and others saying
< "I know how you want to override it and I really want that" and others
< saying "I know why you don't want me to override it and I want to override
< what you're doing" and so on.  The fact is that this problem of redefinition
< in the way you're talking about is the classical philosophical puzzle
< of the unstoppable force and the impenetrable barrier.  They are great
< concepts in principle, but they don't go well together.  Right now, you
< are told you can override the definition.  But someone else doesn't
< want you to.  Who is right?  The only really right thing is to have the 
< system take a definitive position on the matter and not leave it open
< to users trying to second-guess each other.

This reminds me of `chaining interrupts' on the PC when using dos; A
real nightmare.
From: Vassil Nikolov
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <l03130304b3cfbcbfe44f@195.138.129.103>
David Bakhash wrote:                [1999-08-05 17:13 -0400]

  [...]
  > that's exactly right.  I was making a call to a function that is provided by
  > LW.  It was returning an error for an unknown reason, and I wanted a
  > work-around.  Of course, I didn't have access to the source, so I setf'd the
  > function definition of 'error to return nil no matter what, and then the
  > funtion call worked just fine.
  > 
  > Basically, the behavior I wanted was that which happens in Emacs Lisp.  I
  > wouldn't use it in real code; maybe just at the prompt.  Something like what
  > Barry wrote would work.  I just wanted to know if there was a standard way
  > about it.

Since it is specifically about error signalling, can't you set up
an error handler, rather than disable ERROR by brute force?

Setting an error handler is standard (unlike redefining a standard
function which has undefined consequences), allows finer control,
and avoids overriding ERROR blindly which may have disastrous
consequences.

(Obviously you _have_ to use this buggy code---assuming it is
indeed buggy and not signalling an error for legitimate reasons.)

  [...]
  > I don't know what the compiler
  > would have to do in order to make inlined code safe when you setf something
  > like (fdefinition 'error).

The compiler can do nothing unless the programmer says NOTINLINE
(which cannot be ignored).

  > Still, I've heard (from Erik Naggum, I think) that ACL doesn't obey the inline
  > decl.  There must be a reason.

He has also written that ACL does support compiler macros, and they
offer capabilities of similar optimization power, though the mechanism
and the amount of programmer effort is different.


Vassil Nikolov
Permanent forwarding e-mail: ········@poboxes.com
For more: http://www.poboxes.com/vnikolov
  Abaci lignei --- programmatici ferrei.





 Sent via Deja.com http://www.deja.com/
 Share what you know. Learn what you don't.
From: Barry Margolin
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <Mpoq3.35$34.805@burlma1-snr2>
In article <·····················@195.138.129.103>,
Vassil Nikolov  <········@poboxes.com> wrote:
>The compiler can do nothing unless the programmer says NOTINLINE
>(which cannot be ignored).

The programmer has to do that before compiling the caller.  Since the
caller is provided by the implementation, the end user can't do anything to
NOTINLINE its calls.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, 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.
From: Vassil Nikolov
Subject: Re: labels/flet for dynamic scope
Date: 
Message-ID: <l03130303b3cfbaeb7680@195.138.129.103>
Barry Margolin wrote:                [1999-08-05 20:42 +0000]

  [...]
  [I wrote:]
  > >I think one should also consider calling the function by FUNCALL of
  > >a global (special) variable, and binding that variable dynamically.
  [...]
  > 
  > That's only feasible if you have control over the code that will be calling
  > the function.  The impression I got from his example is that this code is
  > already written and presumably unchangeable, which is why he wants to
  > change what happens when it calls certain functions.  If you had access to
  > the source code you could simply remove the call to ERROR, or have it call
  > a different function that calls ERROR conditionally.

Yes, these are two different lines of thought.

As David Bakhash has already written, your impression was in fact
right; but in that case one could also check if the implementation
supports an advice facility.  (I don't know if Harlequin's does, but
would expect so.)  This appears to be just a case for it.

  [...]

By the way, I'd prefer WITH-FUNCTION-DEFINITION or something
like this, rather than DYNAMIC-FLET as this name appears to be
to FLET as LET of special variables is to LET of lexical variables,
and that isn't quite so.


Vassil Nikolov
Permanent forwarding e-mail: ········@poboxes.com
For more: http://www.poboxes.com/vnikolov
  Abaci lignei --- programmatici ferrei.





 Sent via Deja.com http://www.deja.com/
 Share what you know. Learn what you don't.