From: Federico Hernandez-Pueschel
Subject: Function called from the Listener or from another function
Date: 
Message-ID: <349508ee.21987289@news.tu-darmstadt.de>
Hi,

is there a way to determine if a function was called direct in the toploop
(listener) or was called from another function?

I want to control what the function returns; say e.g. if called from the
toploop (listener) it should return 'foo, if called from another function
it should return 'bar.

Greetings

Federico

From: Kent M Pitman
Subject: Re: Function called from the Listener or from another function
Date: 
Message-ID: <sfwk9dbn19v.fsf@world.std.com>
········@hrzpub.tu-darmstadt.de (Federico Hernandez-Pueschel) writes:

> is there a way to determine if a function was called direct in the toploop
> (listener) or was called from another function?

No, not really.  And there are philosophical problems with assuming
there is a meaning to the concept of "toploop" since if Lisp is your
language all the way down to the microcode (e.g., as on a Lisp
machine) there is no real "top".  There is just program on top of
program on top of program on top of ...

Also, making it return something different at toplevel than in other
places makes debugging REALLY hard in some cases.

> I want to control what the function returns; say e.g. if called from the
> toploop (listener) it should return 'foo, if called from another function
> it should return 'bar.

The wisdom of the ages is that at this point I should ask this question:

  What are you REALLY trying to do?

(Usually when people ask odd little questions like this, they are
trying to accomplish something utterly different and if one can get at
that real purpose one can bypass the strange question altogether.)
From: Hrvoje Niksic
Subject: Re: Function called from the Listener or from another function
Date: 
Message-ID: <kign2i7botn.fsf@jagor.srce.hr>
Kent M Pitman <······@world.std.com> writes:

> > I want to control what the function returns; say e.g. if called from the
> > toploop (listener) it should return 'foo, if called from another function
> > it should return 'bar.
> 
> The wisdom of the ages is that at this point I should ask this question:
> 
>   What are you REALLY trying to do?

Maybe Federico wants to achieve a concept similar to Emacs'
"interactive" function-calling.  For instance, a function may behave
differently when called via

  (function ARGS ...)

than when you type:

  M-x function

However, in Emacs, this difference does not exist on the Lisp level,
because typing `M-x function' is equivalent to evaluating:

  (call-interactively 'function ARGS ...)

where ARGS are divined from the function's interactive specs.  In an
interactively called function, `interactivep' will return non-nil.


Judging on experience from Emacs, there *is* use in distinguishing
whether a function has been called interactively or noninteractively,
but checking whether it has been evaluated from the listener
definitely sounds like the wrong thing to do.

-- 
Hrvoje Niksic <·······@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
Then...  his face does a complete change of expression.  It goes from
a "Vengeance is mine" expression, to a "What the fuck" blank look.
From: Federico Hernandez-Pueschel
Subject: Re: Re: Function called from the Listener or from another function
Date: 
Message-ID: <34948420.53529893@news.tu-darmstadt.de>
Hi,

On 11 Dec 1997 21:35:32 +0100, Hrvoje Niksic <·······@srce.hr> wrote:
>Maybe Federico wants to achieve a concept similar to Emacs'
>"interactive" function-calling.  For instance, a function may behave
>differently when called via
Something like that, yes.

>Judging on experience from Emacs, there *is* use in distinguishing
>whether a function has been called interactively or noninteractively,
I can second that.

>but checking whether it has been evaluated from the listener
>definitely sounds like the wrong thing to do.
What would be the best way to obtain a similar functionality?

Greetings 

Federico
From: Howard R. Stearns
Subject: Re: Function called from the Listener or from another function
Date: 
Message-ID: <34915DCA.1DB2@elwood.com>
How about using the variable named "-", which ANSI defines as follows:
  The value of - is the form that is currently being evaluated by the
  Lisp read-eval-print loop. 

Simplistically, one might define a function with &rest args, and then
check that the car of "-" was the correct function, and the cdr was
equal to the list of actual arguments.  

I think a better idea would be to define the utility in question as a
macro with an &whole argument, and then check that the this form is EQ
to -.  This assumes that EVAL never gratuitously copies the form being
evaluated, and possibly other details that in theory are implementation
dependent, but which I suspect don't vary much in practice.

Federico Hernandez-Pueschel wrote:
> 
> Hi,
> 
> On 11 Dec 1997 21:35:32 +0100, Hrvoje Niksic <·······@srce.hr> wrote:
> >Maybe Federico wants to achieve a concept similar to Emacs'
> >"interactive" function-calling.  For instance, a function may behave
> >differently when called via
> Something like that, yes.
> 
> >Judging on experience from Emacs, there *is* use in distinguishing
> >whether a function has been called interactively or noninteractively,
> I can second that.
> 
> >but checking whether it has been evaluated from the listener
> >definitely sounds like the wrong thing to do.
> What would be the best way to obtain a similar functionality?
> 
> Greetings
> 
> Federico
From: Kent M Pitman
Subject: Re: Function called from the Listener or from another function
Date: 
Message-ID: <sfwk9daij7y.fsf@world.std.com>
"Howard R. Stearns" <······@elwood.com> writes:

> How about using the variable named "-", which ANSI defines as follows:
>   The value of - is the form that is currently being evaluated by the
>   Lisp read-eval-print loop. 

Oh how I dreaded someone raising this.  It's a truly bad idea for "-" to
be used because there is no guarantee that a function will be called from
within a read eval print loop at all.  For example, if you spawn a function
into a new process of its own, it will not have "-" bound because there will
be no human to type there.  (perhaps the process is intended to start
such a loop, but then it will do the bindings itself--they don't come
pre-done).

Further, doesn't deal with what happens in (foo (bar ..)).  Is bar being
called from top level?  It can't be determined lexically.  Consider:
 (defun baz (a b) (bar a b))
In this case, - will contain (foo (baz x y)) and only by re-evaluating
(baz ...) or by doing lots of code-introspection (halting problem alert)
can you find out if bar gets involved.  And you also have to worry about
re-macorexpansions.  What about
 (defmacro phu (&rest args) `(foo ,@args))
and - = (phu 1 2)
The problems go on and on if you use -.  As I say, I used to use it
myself a lot in the Maclisp days and it always led to heartache.

-, *, **, ***, +, ++, +++, /, //, and /// as variables are only
correctly used by a human being typing interactively or by programmatic
Lisp teaching programs trying to heuristically suggest corrections.
(Just my opinion.)  

Even if you can find an expression like
 ((lambda (x) (format t "~&~S => ~S~%" (cadr -) x)) (* 3 4))
that yields cool output, you have to notice it won't work in a file load
or editor buffer evaluation.  It's best if you have such a need to do
a structural thing like
 (let ((form '(* 3 4)))
   (format t "~&~S => ~S~%" form (eval form)))
or if you can't use eval for some reason,
 (format t "~&~S => ~S~%" '#1=(* 3 4) #1#)
which is at least reliable in all the Lisp evaluators and compilers.
From: Howard R. Stearns
Subject: Re: Function called from the Listener or from another function
Date: 
Message-ID: <3491C147.7A7E@elwood.com>
Federico Hernandez-Pueschel wrote:
> 
> Hi,
> 
> On 11 Dec 1997 21:35:32 +0100, Hrvoje Niksic <·······@srce.hr> wrote:
> >Maybe Federico wants to achieve a concept similar to Emacs'
> >"interactive" function-calling.  For instance, a function may behave
> >differently when called via
> Something like that, yes.
> 
> >Judging on experience from Emacs, there *is* use in distinguishing
> >whether a function has been called interactively or noninteractively,
> I can second that.
> 
> >but checking whether it has been evaluated from the listener
> >definitely sounds like the wrong thing to do.
> What would be the best way to obtain a similar functionality?
> 
> Greetings
> 
> Federico

Hmmm.  I'm not advocating general use of "-" in programs, but in a
specific situation, described above.  My reading of the above is that
the programmer wishes to know whether a single function was called
interactively from top level.  That is, whether the form entered at top
level was a cons beginning with some symbol.  (Maybe I've
misunderstood?)

It is my understanding that this is PRECISELY what cl:- is defined to be
bound to, where neither I nor the standard have bothered to define what
is meant by the "top level".  If the implemenation provides some
definition of a top level for which cl:- is not bound to the current
form being evaluated by that top level, then the implementation is out
of compliance.

Being more speculative, and increasinly unsure of my ground, imagine
that an implementation defined a mechanism by which one could invoke
multiple top level REPLs in different threads.  (See my separate
speculations in the "Standardized, customizable REPL" thread.)  My
reading of the spec is that as long as this mechanism was defined to
provide a "top level" listener, the implementation would be required to
ensure that within the same thread in which the customized REPL was
running, cl:- would have to be bound to the form being evaluated by it.
(I'm assuming one REPL per thread.)

Conversely, if an implementation only provides one REPL and no mechanism
for defining new ones, then cl:- must be bound in all threads.

The middle ground, where there is no REPL in the current thread, is
certainly "undefined".  I suppose on might want per-thread globals that
can inherit from other threads, but that's another story.

Anyway, remember that the problem is framed by analogy to emacs, where I
believe calling something at the top level means 
  M-x function-name arg1 arg2 ...
and not 
  M-x some-other-function function-name arg1 arg2 ...
end-of-argument-marker-for-function-name arg-2-for-some-other-function
....

Therefore, I think we can define (bar 1) to not be considered called at
top-level when cl:- is (foo (bar 1) 4).



Kent M Pitman wrote:
> 
> "Howard R. Stearns" <······@elwood.com> writes:
> 
> > How about using the variable named "-", which ANSI defines as follows:
> >   The value of - is the form that is currently being evaluated by the
> >   Lisp read-eval-print loop.
> 
> Oh how I dreaded someone raising this.  It's a truly bad idea for "-" to
> be used because there is no guarantee that a function will be called from
> within a read eval print loop at all.  For example, if you spawn a function
> into a new process of its own, it will not have "-" bound because there will
> be no human to type there.  (perhaps the process is intended to start
> such a loop, but then it will do the bindings itself--they don't come
> pre-done).
> 
> Further, doesn't deal with what happens in (foo (bar ..)).  Is bar being
> called from top level?  It can't be determined lexically.  Consider:
>  (defun baz (a b) (bar a b))
> In this case, - will contain (foo (baz x y)) and only by re-evaluating
> (baz ...) or by doing lots of code-introspection (halting problem alert)
> can you find out if bar gets involved.  And you also have to worry about
> re-macorexpansions.  What about
>  (defmacro phu (&rest args) `(foo ,@args))
> and - = (phu 1 2)
> The problems go on and on if you use -.  As I say, I used to use it
> myself a lot in the Maclisp days and it always led to heartache.
> 
> -, *, **, ***, +, ++, +++, /, //, and /// as variables are only
> correctly used by a human being typing interactively or by programmatic
> Lisp teaching programs trying to heuristically suggest corrections.
> (Just my opinion.)
> 
> Even if you can find an expression like
>  ((lambda (x) (format t "~&~S => ~S~%" (cadr -) x)) (* 3 4))
> that yields cool output, you have to notice it won't work in a file load
> or editor buffer evaluation.  It's best if you have such a need to do
> a structural thing like
>  (let ((form '(* 3 4)))
>    (format t "~&~S => ~S~%" form (eval form)))
> or if you can't use eval for some reason,
>  (format t "~&~S => ~S~%" '#1=(* 3 4) #1#)
> which is at least reliable in all the Lisp evaluators and compilers.
From: Federico Hernandez-Pueschel
Subject: Re: Re: Function called from the Listener or from another function
Date: 
Message-ID: <3497c67d.27053255@news.tu-darmstadt.de>
Hi,

On Fri, 12 Dec 1997 16:57:11 -0600, "Howard R. Stearns" <······@elwood.com>
wrote:
>Hmmm.  I'm not advocating general use of "-" in programs, but in a
>specific situation, described above.  My reading of the above is that
>the programmer wishes to know whether a single function was called
>interactively from top level.  That is, whether the form entered at top
>level was a cons beginning with some symbol.  (Maybe I've
>misunderstood?)
No, you are quite right. The programs will be invoked from a REPL. The
output of some functions are, as they will be input for other functions,
not really readable for humans. But for didactic reasons I (or the user)
should also be able to read this output when we invoke this function from
the toplevel.

So it can be guaranteed, that there is a REPL. And it seems interesting to
use cl:-. I really forgot about that variable, thinking of another variable
or function to detect a call from the toploop.

Some quick tests here showed that using cl:- will work and be sufficient.
So for the time being I will just check the car of cl:- against the name of
the function and decide upon this check what to return.

Later on I will follow Kent's idea of the custom evaluator. It would be
nice to solve "the maintenance problem" of such a cust-eval during the
development phase of a project.

Seasons Greetings

Federico
From: Kent M Pitman
Subject: Re: Function called from the Listener or from another function
Date: 
Message-ID: <sfwoh2mnkvj.fsf@world.std.com>
"Howard R. Stearns" <······@elwood.com> writes:

> It is my understanding that this is PRECISELY what cl:- is defined to be
> bound to, where neither I nor the standard have bothered to define what
> is meant by the "top level".  If the implemenation provides some
> definition of a top level for which cl:- is not bound to the current
> form being evaluated by that top level, then the implementation is out
> of compliance.

Nope.  This is too strong, I think.  I'm extremely conservative about
saying that an implementation is non-compliant.  Again, this goes back to
the first meting of X3J13 which I recently expounded about under another
thread in which someone from then-X3 (it has another name now, btw, it's
formally called NCITS and pronounced "insights") spoke to us about how
lawsuits have happened when "experts" have accused language implementations
that purport to conform of being non-conforming.  It is wiser, we were
counselled, to give as broad a latitude as possible in the case of an
ambiguity, and I certainly see lots of reason for latitude in this case.

Nowhere that I know of does it say that a read eval print loop is
required by Lisp.  Various things are forced of the read eval print
loop, but a delivery-only Lisp would be a commercially viable product
and it's really up to the consumer, I think, to decide if that's ok.
I think that was the intent of the committee anyway, even if it's not
spelled out.

Further, a compliant implementation (which includes most
implementations I'm familiar with) is permitted to launch processes
with no REPL.  These are not required to bind - to any particular
value.  (The spec says it's got a value, but it doesn't say what it
is, and in my experience it's usually NIL.)  I'd actually advise
anyone using the variable named "-" in a program to boundp test it
first just to be sure, although I'd advise any implementor to globally
assign it to NIL just to avoid the need for that.  That kind of split
advice is common in cases of lack of specificity.

BTW: Note that this is implied in discussion of the ABORT restart,
which implies that there might be non-interactive contexts where there
is no command level.  This supports my belief that the committee did
believe in non-interactive lisps.

I'll queue this issue on my private list of things to be clarified
if/when a next round standard comes up for discussion.

> Being more speculative, and increasinly unsure of my ground, imagine
> that an implementation defined a mechanism by which one could invoke
> multiple top level REPLs in different threads.  (See my separate
> speculations in the "Standardized, customizable REPL" thread.)  My
> reading of the spec is that as long as this mechanism was defined to
> provide a "top level" listener, the implementation would be required to
> ensure that within the same thread in which the customized REPL was
> running, cl:- would have to be bound to the form being evaluated by it.
> (I'm assuming one REPL per thread.)

Yes.  A thread that runs a REPL should bind -, but again: a thread
need not run a REPL.

> Conversely, if an implementation only provides one REPL and no mechanism
> for defining new ones, then cl:- must be bound in all threads.

Probably.  I'd encourage implementors to think this way.  But I'd also
encourage programmers to program defensively. :-)

> The middle ground, where there is no REPL in the current thread, is
> certainly "undefined".  I suppose on might want per-thread globals that
> can inherit from other threads, but that's another story.

Well, the spec says the value is "implementation-dependent".  My personal
hope is that people would read this to mean "there is a value and that
value is implementation-dependent".  As a matter of practice, we would
have used the word "undefined" rather than "implementation-dependent" had
we meant to imply otherwise.  But I agree that leaving wriggle room is good
and so while I'm not content to agree that it is `certainly "undefined"'  I'm
willing to agree that it is `effectively "undefined"' :-)
 
> Anyway, remember that the problem is framed by analogy to emacs, where I
> believe calling something at the top level means 
>   M-x function-name arg1 arg2 ...
> and not 
>   M-x some-other-function function-name arg1 arg2 ...
> end-of-argument-marker-for-function-name arg-2-for-some-other-function
> ....
> 
> Therefore, I think we can define (bar 1) to not be considered called at
> top-level when cl:- is (foo (bar 1) 4).

You can indeed.  Absolutely.  But figuring out how to implement that is tough.
My simple try using a *outermost* variable got confused because both FOO and
BAR are called as if side-by-side, not nested.  If you do a conversion to
continuation passing sytle, it's easier to see:
 ((lambda (x) (foo x 4)) (bar 1))

Now it's easier to see that (foo x 4) and (bar 1) are really equals in
top-ness.  And it might even be argued that the bar call is more outer
than the foo call.  What is correct is not a matter for philosophers
(who will argue forever) but Federico (who presumably has a specific
intent in mind).
From: Barry Margolin
Subject: Re: Re: Function called from the Listener or from another function
Date: 
Message-ID: <66sbgh$c9o@tools.bbnplanet.com>
In article <·················@news.tu-darmstadt.de>,
Federico Hernandez-Pueschel <········@hrzpub.tu-darmstadt.de> wrote:
>What would be the best way to obtain a similar functionality?

The simplest way is to define two functions, one intended to be called by
hand from the listener, and another intended for use in programs.  The
first one would probably call the second one to do most of its work.

For instance, one reason you might want to have a function behave
differently when called interactively is to prevent it from returning a
value which is likely to be a huge data structure.  So you might define:

(defun foo-internal (...)
  ...)

(defun foo (...)
  (foo-internal ...)
  nil)

The nice thing about this is that you can still call foo-internal from the
listener if you want (e.g. when debugging, you might want to see that huge
data structure).

I can recall many times typing (progn (...) nil) just so I wouldn't have to
see the return value of the function I was testing (especially when the
function's purpose is to print something, so the return value is the same
thing it just printed).

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
Support the anti-spam movement; see <http://www.cauce.org/>
Please don't send technical questions directly to me, post them to newsgroups.
From: Federico Hernandez-Pueschel
Subject: Re: Re: Function called from the Listener or from another function
Date: 
Message-ID: <3493aeb8.20966665@news.tu-darmstadt.de>
Hi,

On Fri, 12 Dec 1997 21:48:18 GMT, Barry Margolin <······@bbnplanet.com>
wrote:
>The simplest way is to define two functions, one intended to be called by
>hand from the listener, and another intended for use in programs.  The
>first one would probably call the second one to do most of its work.
On some occasions I am allready doing this. But then I have two functions
which do the "same". I wanted to avoid this with putting some
"intelligence" into the function and let the function decide what to
return.

>I can recall many times typing (progn (...) nil) just so I wouldn't have to
>see the return value of the function I was testing (especially when the
>function's purpose is to print something, so the return value is the same
>thing it just printed).
Sounds familiar to me. ;-)

Greetings Federico
From: Kent M Pitman
Subject: Re: Re: Function called from the Listener or from another function
Date: 
Message-ID: <sfwpvn2nlxt.fsf@world.std.com>
Barry Margolin <······@bbnplanet.com> writes:

> I can recall many times typing (progn (...) nil) just so I wouldn't have to
> see the return value of the function I was testing.

Heh. I do (setq foo (...) bar nil) a lot for the same reason.
From: Kent M Pitman
Subject: Re: Function called from the Listener or from another function
Date: 
Message-ID: <sfwpvn3oy6f.fsf@world.std.com>
Hrvoje Niksic <·······@srce.hr> writes:

> However, in Emacs, this difference does not exist on the Lisp level,
> because typing `M-x function' is equivalent to evaluating:
> 
>   (call-interactively 'function ARGS ...)

I agree one could impose a structurally different interface on things
and solve the problem that way.  Symbolics Genera did a similar thing
with the command loop by allowing one to define new "commands" (with
command-line syntax, rather than function calling syntax).

Looking back at the history, it seems surprising to me that there's
not a way to customize the reader and printer function in CL since I
think some implementations offer this option and it would have been an
obvious thing to have standardized once-upon-a-time.  More recently,
standards work has moved slightly away from specifying too much detail
of the interface, so it's less surprising that we haven't repaired the
problem.

One could imagine writing:

 (defun custom-repl (&key (print #'print)
			  (eval  #'eval)
			  (read  #'read)
			  (name "custom read-eval-print loop"))
   (with-simple-restart (nil "Exit ~A." name)
     (loop (with-simple-restart (abort "Return to ~A." name)
	     (multiple-value-call #'(lambda (&rest values)
				      (declare (dynamic-extent values))
				      (mapc print values)
				      nil)
		(funcall eval (funcall read)))))))

And then entering a context that customized any of the reader, evaluator,
or printer for top-level.

I got private mail in which Federico said that computationally it would
suffice to put a (view-top-level xxx) wrapper around his outermost call
but that it was effectively tedious.  An alternative would be a custom
evaluator or printer which knew to watch for various xxx's and put the
wrapper around automatically.  I guess that's my best suggestion.

I could also suggest something like changing the problem from "toplevel"
to "outermost" which is easier to compute.  e.g.,

 (defvar *outermost* t)

 (defun foo (&rest args)
   (if *outermost* 
       (wrap-for-user (let ((*outermost* nil)) (apply #'foo args)))
       (apply #'(lambda (...real bvl...) ...real body...) args)))

But if (foo (foo..)...)
happens then you have the problem that the arg evaluation thinks it's
at top level and returns a wrapped item that becomes an arg to FOO.
The same would happen with mutually recursive functions. e.g., I 
"naively" tried:

 (defvar *outermost* t)
 (defun wrap-for-user (x) `(wrapped ,x))
 (defmacro my-define (name bvl &body forms)
   (let ((args (gensym "ARGS")))
     `(defun ,name (&rest ,args)
        (if *outermost*
	    (wrap-for-user (let ((*outermost* nil)) (apply #',name ,args)))
	    (apply #'(lambda ,bvl ,@forms) ,args)))))

and then

 (my-define foo (a b) (+ a b))
 (my-define bar (a b) (- a b))

and did

 (foo 1 2) => (wrapped 3) ;so far so good
 (bar (foo 1 2) (foo 2 3))
 Error: In - of ((WRAPPED 3) (WRAPPED 5)) arguments should be of type NUMBER.

Oops.  (I thought about removing the above example once I discovered
it buggy but I thought it might comfort some people to watch me screw
up... nobody's perfect, after all.)  To repair this we might make
these be more special-form-like, which eliminates the possibility of
accessing #'foo (which works only for functions and not for macros).
That means you can't apply, funcall, or map functions defined in this way.

 (defvar *outermost* t)
 (defun wrap-for-user (x) `(wrapped ,x))
 (defmacro my-define (name bvl &body forms)
   (let ((temp (gensym "TEMP")))
     `(progn (setf (get ',name 'my-define) #'(lambda ,bvl ,@forms))
	     (defmacro ,name (&rest args)
	       `(flet ((do-it () (funcall (get ',',name 'my-define) ,@args)))
		  (declare (dynamic-extent #'do-it))
                  (if *outermost* 
	              (wrap-for-user (let ((*outermost* nil)) (do-it)))
	              (do-it))))
	     ',name)))

and then (again):

 (my-define foo (a b) (+ a b))
 (my-define bar (a b) (- a b))

and finally:

 (foo 1 2) => (WRAPPED 3)
 (bar (foo 1 2) (foo 2 3)) => (WRAPPED -2)

So there are many ways you can do it, but basically SOMEBODY somewhere has to be
responsible for putting the wrapper on because there is nothing that is busy
noticing whether you're at top-level.

You're on your own from here.
From: Howard R. Stearns
Subject: Standardized, customizable REPL (was Re: Function called from the Listener or from another function)
Date: 
Message-ID: <349161A2.3075@elwood.com>
IMHO, specifying the details of the Read-Eval-Print-Loop is too
confining for a language standard, but I DO think it would be nice to
have a reference implementation which people can more-or-less count on.  

I've often thought that it ought to be possible to define a subset of
CLIM that covers presentations, command tables, and application frames
-- none of which would have anything to do with graphics, sheets, media,
ports, output recording, etc.  

Given this, it would be nice if there were a reference implementation of
a repl application frame and of invoke-debugger that used this frame.
This could then be CLOS customized to define specialized application
top-levels, debuggers, inspectors, steppers, etc.

Is this a dumb idea?  Has anyone pursued this?  How close was Genera to
this? Maybe the free-clim people might want to start with this?  

Kent M Pitman wrote:
> ...
> I agree one could impose a structurally different interface on things
> and solve the problem that way.  Symbolics Genera did a similar thing
> with the command loop by allowing one to define new "commands" (with
> command-line syntax, rather than function calling syntax).
> 
> Looking back at the history, it seems surprising to me that there's
> not a way to customize the reader and printer function in CL since I
> think some implementations offer this option and it would have been an
> obvious thing to have standardized once-upon-a-time.  More recently,
> standards work has moved slightly away from specifying too much detail
> of the interface, so it's less surprising that we haven't repaired the
> problem.
> 
> One could imagine writing:
> 
>  (defun custom-repl (&key (print #'print)
>                           (eval  #'eval)
>                           (read  #'read)
>                           (name "custom read-eval-print loop"))
>    (with-simple-restart (nil "Exit ~A." name)
>      (loop (with-simple-restart (abort "Return to ~A." name)
>              (multiple-value-call #'(lambda (&rest values)
>                                       (declare (dynamic-extent values))
>                                       (mapc print values)
>                                       nil)
>                 (funcall eval (funcall read)))))))
> 
> And then entering a context that customized any of the reader, evaluator,
> or printer for top-level.
> ...
From: Federico Hernandez-Pueschel
Subject: Re: Function called from the Listener or from another function
Date: 
Message-ID: <3496b45e.22413023@news.tu-darmstadt.de>
Hi,

On Fri, 12 Dec 1997 06:47:20 GMT, Kent M Pitman <······@world.std.com>
wrote:
> An alternative would be a custom evaluator or printer which knew 
> to watch for various xxx's and put the wrapper around automatically.  
Interesting idea. 

One could do the following (not optimized):
The custom evaluator checks the function to evaluate against a table which
contains all functions to check and their wrapper functions. If the
cust-eval finds the function, it retrievs the the wrapper function and
applies it to the original function. A new written function that needs a
wrapper could insert itself and the wrapper function into the table.

> (I thought about removing the above example once I discovered
> it buggy but I thought it might comfort some people to watch me screw
> up... nobody's perfect, after all.) 
 :-))

>You're on your own from here.
I am thinking of doing some work on your first idea.

Seasons Greetings

Federico
From: Tim Bradshaw
Subject: Re: Function called from the Listener or from another function
Date: 
Message-ID: <ey3ra7iflz0.fsf@todday.aiai.ed.ac.uk>
* Hrvoje Niksic wrote:


> Judging on experience from Emacs, there *is* use in distinguishing
> whether a function has been called interactively or noninteractively,
> but checking whether it has been evaluated from the listener
> definitely sounds like the wrong thing to do.

Actually I found that kind of thing quite useful at points.  I wrote a
little debugger for elk (a scheme dialect) which checked whether the
error was happening from an interactive toploop, and if so how far
down the stack it was.  If it was very close to the top of the stack
it would just print a message and return to the toploop, rather than
crank up the debugger.  The idea was that if I typed: `(car 1)' I just
wanted it to print a message and stop, but if I said
`(run-huge-program-wich-has-a-bug-way-down-inside-somewhere)' I wanted
the debugger (except I didn't if it was running from a script). I
think the xerox D machines did something similar, which is where I got
the idea for my elk debugger from.

So both things are useful to know I think.  OTOH I don't think that CL
should standardise such a thing (even a stack-depth test between two
points would make all sorts of constraining assumptions).


--tim
From: Bryant Brandon
Subject: Re: Function called from the Listener or from another function
Date: 
Message-ID: <46285080402CFAD7.ADB0CA2A5632D683.C304491DA7A9CD20@library-proxy.airnews.net>
In article <···············@todday.aiai.ed.ac.uk>, Tim Bradshaw
<···@aiai.ed.ac.uk> wrote:

[...]

>Actually I found that kind of thing quite useful at points.  I wrote a
>little debugger for elk

   This reminds me of a poem I once saw on the internet.

Elk are large.
In herds they run
Accross the road.
Don't hit one.

B.B.       --Contributing nothing of worth.
From: Erik Naggum
Subject: Re: Function called from the Listener or from another function
Date: 
Message-ID: <3090936459477164@naggum.no>
* Hrvoje Niksic
| Judging on experience from Emacs, there *is* use in distinguishing
| whether a function has been called interactively or noninteractively,
| but checking whether it has been evaluated from the listener
| definitely sounds like the wrong thing to do.

Emacs exports its Lisp call stack.  `interactivep' actually walks up the
call stack and looks for a call frame with `call-interactively' in it,
skipping only a few known call frames on the way.  if it finds it, the
function is deemed "interactive".

if your Lisp has a debugger that can print backtraces, it has a way to
locate call frames.  if you can also use it, you can do the same job as
Emacs' `interactive-p': look for a particular function you expect to mean
"interactive" in the backtrace.

there are many other ways to distinguish between an interactive call and a
normal call, but they generally require changes in the caller.  this is
most easily solved by writing one's own top-level loop, which is not all
that hard.

in any case, I miss the ability in Common Lisp to obtain the function
object corresponding to the running function.  in Emacs, this is (almost)
achievable through (backtrace-frame 0).

#\Erik
-- 
If you think this year is number 97,  |  Help fight MULE in GNU Emacs 20!
_you_ are not "Year 2000 Compliant".  |  http://sourcery.naggum.no/emacs/