From: ········@bayou.uh.edu
Subject: Modifiable parameters?
Date: 
Message-ID: <5doasq$ul1@Masala.CC.UH.EDU>
Hey all.

Currently, most of the Lisp code that I write is under Emacs,
which has a limited recursion depth so I can't use functional
programming techniques :(.  So, now I'm working on some code
and I find that the most convenient way to continue is to modify
the parameters to a function that I'm writing. 

I checked out some tutorials but didn't find much.  The only
thing I found was the set function, and doing the following
under Emacs seemed to work (this isn't the function I'm writing
BTW :)):

(defun fn (x)
  (set x some-value))

(setq p 100)
(fn 'p)  ;; This changes the value of p

Now, I'm just wondering is this the proper way of doing things?
Is there a better way of doing it?  The thought of manipulating
symbols like that has some warning bells ringing in the back
of my head, but I could use some advice from those more experienced
than I.

Thanks.


--
Cya,
Ahmed

Wanna grow
Up to be,
be a Debaser!
	"Debaser" by the Pixies

From: William Paul Vrotney
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <vrotneyE5F59K.H4y@netcom.com>
In article <··········@Masala.CC.UH.EDU> ········@Bayou.UH.EDU
(········@bayou.uh.edu) writes:

> 
> (defun fn (x)
>   (set x some-value))
> 
> (setq p 100)
> (fn 'p)  ;; This changes the value of p
> 
> Now, I'm just wondering is this the proper way of doing things?
> Is there a better way of doing it?  The thought of manipulating
> symbols like that has some warning bells ringing in the back
> of my head, but I could use some advice from those more experienced
> than I.
> 

No problem, this is proper.  'set' is very useful for writing programs that
interpret Lisp code which may be what you are doing.  For example, you
mentioned Emacs, the function M-x set-variable would need to use 'set' to
set a variable name that you give it.  Your head ringing was due to the fact
that rarely do Lisp programmers have to use either 'set' or 'eval' but
sometimes it is either necessary or more straightforward.

-- 

William P. Vrotney - ·······@netcom.com
From: Carl L. Gay
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <CGAY.97Feb11021919@politix.cs.uoregon.edu>
   From: ········@Bayou.UH.EDU (········@bayou.uh.edu)
   Date: 11 Feb 1997 03:39:29 GMT

   William Paul Vrotney (·······@netcom.com) wrote:

   : (········@bayou.uh.edu) writes:
   : No problem, this is proper.  'set' is very useful for writing programs that
   : interpret Lisp code which may be what you are doing.  For example, you
   : mentioned Emacs, the function M-x set-variable would need to use 'set' to
   : set a variable name that you give it.  Your head ringing was due to the fact
   : that rarely do Lisp programmers have to use either 'set' or 'eval' but
   : sometimes it is either necessary or more straightforward.

   *Nod*.  Normally I wouldn't use set, setq, setf, or any looping
   constructs, but rather a functional style of programming, but
   since Emacs has a rather limited recursion depth, I find that I'm
   forced to use imperative programming techniques.  Nontheless even
   using that paradigm Lisp shines.

   Thanks a ton for the info.  I'm really happy that I gave Lisp a
   second try.  It's great having a language which is both flexible
   and has a nice juicy library of functions.  Very often it seems
   that you only get one or the other.

The elided code:
> (defun fn (x)
>   (set x some-value))
> 
> (setq p 100)
> (fn 'p)  ;; This changes the value of p

Um, this may be proper in some sense but it sure sets bells ringing in
my head too.  I can think of at least two reasons why I wouldn't use
this method:
  - It pollutes the top-level namespace with what should really be
    local variables.  Someone's liable to mess with them.
  - Using SET will make the reader think something more complicated is
    going on and there's a good reason for using it.  There isn't, and
    there isn't.
  - There's a simple, relatively clean workaround:
    (defun fn (x)
      (setcar x some-value))
    (fn (list 100))
    Or, if you do this a lot, define a CONTAINER abstract data type so
    you can among other things distinguish your container from another
    list. 

 2.5 reasons.

-Carl
From: Carl L. Gay
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <CGAY.97Feb11024406@politix.cs.uoregon.edu>
   From: ········@Bayou.UH.EDU (········@bayou.uh.edu)
   Date: 11 Feb 1997 03:39:29 GMT

   William Paul Vrotney (·······@netcom.com) wrote:

   : (········@bayou.uh.edu) writes:
   : No problem, this is proper.  'set' is very useful for writing programs that
   : interpret Lisp code which may be what you are doing.  For example, you
   : mentioned Emacs, the function M-x set-variable would need to use 'set' to
   : set a variable name that you give it.  Your head ringing was due to the fact
   : that rarely do Lisp programmers have to use either 'set' or 'eval' but
   : sometimes it is either necessary or more straightforward.

   *Nod*.  Normally I wouldn't use set, setq, setf, or any looping
   constructs, but rather a functional style of programming, but
   since Emacs has a rather limited recursion depth, I find that I'm
   forced to use imperative programming techniques.  Nontheless even
   using that paradigm Lisp shines.

   Thanks a ton for the info.  I'm really happy that I gave Lisp a
   second try.  It's great having a language which is both flexible
   and has a nice juicy library of functions.  Very often it seems
   that you only get one or the other.

[I wrote the following before I realized you weren't necessarily
defining p at top-level.  Here it is anyway, for what it's worth...]

The elided code:
> (defun fn (x)
>   (set x some-value))
> 
> (setq p 100)
> (fn 'p)  ;; This changes the value of p

Um, this may be proper in some sense but it sure sets bells ringing in
my head too.  I can think of at least two reasons why I wouldn't use
this method:
  - It pollutes the top-level namespace with what should really be
    local variables.  Someone's liable to mess with them.
  - Using SET will make the reader think something more complicated is
    going on and there's a good reason for using it.  There isn't, and
    there isn't.
  - There's a simple, relatively clean workaround:
    (defun fn (x)
      (setcar x some-value))
    (fn (list 100))
    Or, if you do this a lot, define a CONTAINER abstract data type so
    you can among other things distinguish your container from another
    list. 

 2.5 reasons.

-Carl
From: ········@bayou.uh.edu
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <5dr6mm$i6o@Masala.CC.UH.EDU>
Carl L. Gay (····@politix.cs.uoregon.edu) wrote:

[Snip]

: [I wrote the following before I realized you weren't necessarily
: defining p at top-level.  Here it is anyway, for what it's worth...]

: The elided code:
: > (defun fn (x)
: >   (set x some-value))
: > 
: > (setq p 100)
: > (fn 'p)  ;; This changes the value of p

: Um, this may be proper in some sense but it sure sets bells ringing in
: my head too.  I can think of at least two reasons why I wouldn't use
: this method:
:   - It pollutes the top-level namespace with what should really be
:     local variables.  Someone's liable to mess with them.
:   - Using SET will make the reader think something more complicated is
:     going on and there's a good reason for using it.  There isn't, and
:     there isn't.

Also trying to pass it on to another function is pure agony.
For instance I tried the following:

(defun f (x)
  (g x))

(defun g (x)
  (set x 10))

(setq n 100)
(f 'n)

The quoting scheme collapsed when I hit g since I was passing
a variable.  I realized that I had to find a far better way.


:   - There's a simple, relatively clean workaround:
:     (defun fn (x)
:       (setcar x some-value))
:     (fn (list 100))
      ^^^^^^^^^^^^^^^

Shouldn't the above be (fn (list some-var)) where some-var has
been previously defined?  We are trying to modify the argument
so passing a literal won't do.

I did make the appropriate substitution, but it didn't work.


:     Or, if you do this a lot, define a CONTAINER abstract data type so
:     you can among other things distinguish your container from another
:     list. 

Wouldn't there be an easier way?  I mean setq modifies its parameters
and that's all I'm trying to do.  Ie:

(f x)  ;; I want x to change like it would in (setq x 100)



:  2.5 reasons.

:)

Thanks for the help.


: -Carl


--
Cya,
Ahmed

Brains for dinner, brains for lunch
Brains for breakfast, brains for brunch
Brains at every single meal
Why can't we have some guts?
	"Brain Eaters" by the Misfits
From: ········@bayou.uh.edu
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <5doplh$utv@Masala.CC.UH.EDU>
William Paul Vrotney (·······@netcom.com) wrote:

: In article <··········@Masala.CC.UH.EDU> ········@Bayou.UH.EDU
: (········@bayou.uh.edu) writes:

[Snip]

: No problem, this is proper.  'set' is very useful for writing programs that
: interpret Lisp code which may be what you are doing.  For example, you
: mentioned Emacs, the function M-x set-variable would need to use 'set' to
: set a variable name that you give it.  Your head ringing was due to the fact
: that rarely do Lisp programmers have to use either 'set' or 'eval' but
: sometimes it is either necessary or more straightforward.

*Nod*.  Normally I wouldn't use set, setq, setf, or any looping
constructs, but rather a functional style of programming, but
since Emacs has a rather limited recursion depth, I find that I'm
forced to use imperative programming techniques.  Nontheless even
using that paradigm Lisp shines.

Thanks a ton for the info.  I'm really happy that I gave Lisp a
second try.  It's great having a language which is both flexible
and has a nice juicy library of functions.  Very often it seems
that you only get one or the other.

Thanks again.


: -- 

: William P. Vrotney - ·······@netcom.com

--
Cya,
Ahmed

In the name of God they left you to die,
Religious wars -- there's no reason why they left you to die.
	"Religious Wars" by the [Sub][hum][ans]
From: Carl L. Gay
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <CGAY.97Feb11232823@plastix.cs.uoregon.edu>
   From: ········@Bayou.UH.EDU (········@bayou.uh.edu)
   Date: 12 Feb 1997 01:34:14 GMT

   Also trying to pass it on to another function is pure agony.
   For instance I tried the following:

   (defun f (x)
     (g x))

   (defun g (x)
     (set x 10))

   (setq n 100)
   (f 'n)

   The quoting scheme collapsed when I hit g since I was passing
   a variable.  I realized that I had to find a far better way.

I'm not sure I understand what you mean.  The above seems to work
fine.  You're passing the symbol N, not a variable.

   :   - There's a simple, relatively clean workaround:
   :     (defun fn (x)
   :       (setcar x some-value))
   :     (fn (list 100))
	 ^^^^^^^^^^^^^^^

   Shouldn't the above be (fn (list some-var)) where some-var has
   been previously defined?  We are trying to modify the argument
   so passing a literal won't do.

Well that was just for illustration.  Presumably you'd want to look at
the value after calling fn:

(let ((foo (list my-var)))
  (fn foo)
  (do-something (car foo)))

   :     Or, if you do this a lot, define a CONTAINER abstract data type so
   :     you can among other things distinguish your container from another
   :     list. 

   Wouldn't there be an easier way?  I mean setq modifies its parameters
   and that's all I'm trying to do.  Ie:

   (f x)  ;; I want x to change like it would in (setq x 100)

You could try setting max-lisp-eval-depth higher.
From: ········@bayou.uh.edu
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <5dthtk$5g1@Masala.CC.UH.EDU>
Carl L. Gay (····@plastix.cs.uoregon.edu) wrote:

:    From: ········@Bayou.UH.EDU (········@bayou.uh.edu)
:    Date: 12 Feb 1997 01:34:14 GMT

[Snip]

:    The quoting scheme collapsed when I hit g since I was passing
:    a variable.  I realized that I had to find a far better way.

: I'm not sure I understand what you mean.  The above seems to work
: fine.  You're passing the symbol N, not a variable.

Well it's a moot point now since I found something that can
do the trick -- macros.  How I forgot about them I can
only speculate.  Thanks for the assistance.


[Snip]


:    Wouldn't there be an easier way?  I mean setq modifies its parameters
:    and that's all I'm trying to do.  Ie:

:    (f x)  ;; I want x to change like it would in (setq x 100)

: You could try setting max-lisp-eval-depth higher.

I did that (to enable some appreciable amount of recursion).
I believe the maximum is around 600, which while not bad
isn't enough to make me use it in scenarios where I don't
know how many recursions I'll get into (it would be nice
if Emacs also did some tail recursion optimization).

Thanks again for the help.


--
Cya,
Ahmed

And I know she must think I'm screwed,
That I'm only interested in food,
But when I looked deep into her eyes,
I wanted more than a burger and fries.
	"Burger King Queen" by the Queers
From: Erik Naggum
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <3064830257628640@naggum.no>
* Carl L. Gay
| You could try setting max-lisp-eval-depth higher.

* ········@Bayou.UH.EDU
| I did that (to enable some appreciable amount of recursion).  I believe
| the maximum is around 600, which while not bad isn't enough to make me
| use it in scenarios where I don't know how many recursions I'll get into
| (it would be nice if Emacs also did some tail recursion optimization).

I'm getting a bit annoyed by these continued references to deficiencies in
Emacs that are really just deficiencies in your ability or willingness to
read the Emacs Lisp manual.  I have already answered the implied question
"can I make Emacs more friendly towards recursion, and if so how" in your
incessant and incorrect complaints that "Emacs doesn't allow recursion"
with references to `max-lisp-eval-depth' and `max-specpdl-size', but lots
of people out there will still believe your misguided complaints.  _please_
be more willing to ask for help and less willing to complain.

you "believe" there is a small maximum.  I _know_ there isn't.  you hit the
600 limit because that's what `max-specpdl-size' is set to and you probably
had one let-binding in your recursive function.  increase the value of this
variable to some obscenely large value and watch Emacs hit some hard limit
and die, instead.  again, it is more friendly of Emacs to complain than to
crash, and it crashes because being able to respond when you're out of
stack space may not be very expensive, but handling the situation cleanly
usually is.  to illustrate this point: watch what various Lisps do when
they exhaust their memory -- clean recovery is not usually an option.
Emacs has taken great pains to survive a "memory outage" when the user
creates too many or too large buffers, by allocating a "memory reserve"
that it uses when it suggests that you save all buffers and kill and
restart Emacs.  something similar is not undoable with stack space, but is
much harder to make work right.  unlimited recursion depth also allocates
system stack space that is not typically returned to the operating system
when the stack unwinds.  this is a frequent cause of the very large Lisp
images that people complain about.

#\Erik
-- 
my other car is a cdr
From: Chris Bitmead
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <BITMEADC.97Feb17163446@Alcatel.com.au>
In article <··········@Masala.CC.UH.EDU> ········@Bayou.UH.EDU (········@bayou.uh.edu) writes:

>Hey all.
>
>Currently, most of the Lisp code that I write is under Emacs,
>which has a limited recursion depth so I can't use functional
>programming techniques :(.  So, now I'm working on some code
>and I find that the most convenient way to continue is to modify
>the parameters to a function that I'm writing. 

Are you saying Elisp isn't tail recursive? Would anyone like to tell
us why not? It's not hard to implement surely?
From: Tim Bradshaw
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <ey3ohdfjxap.fsf@staffa.aiai.ed.ac.uk>
* Chris Bitmead wrote:

> Are you saying Elisp isn't tail recursive? Would anyone like to tell
> us why not? It's not hard to implement surely?

Elisp does not do tail call elimination.  Although you could handle
some cases of self-tail-call elimination in a language with dynamic
scope (like elisp), I can't see how to do the general case.  Consider
this:

    (defun foo (x)
      (bar (+ x 1)))

    (defun bar (y)
      (+ x y))

    (foo 1)


This is legal in Elisp.  But since bar can refer to x, bound in foo,
you really need foo's stack frame still to exist inside bar, so the
binding can be looked up.  And even if bar doesn't use x free, some
function it calls may do, and foo has no way of knowing what such
functions may be.  So it's very hard to compile this as a jump, or if
you do compile it as a jump, you still have to keep all the old
bindings around to restore when you exit bar, so you just need a stack
of bindings somewhere even if not a call stack.

Does anyone know if it is possible to to general tail call elimination
(or even to do it in a useful set of cases) in a language with dynamic
scope?

--tim
From: Barry Margolin
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <5ejfa2$3et@pasilla.bbnplanet.com>
In article <···············@staffa.aiai.ed.ac.uk>,
Tim Bradshaw  <···@aiai.ed.ac.uk> wrote:
>Does anyone know if it is possible to to general tail call elimination
>(or even to do it in a useful set of cases) in a language with dynamic
>scope?

Implementations of dynamic scoping typically have two stacks: the call
stack and the special binding stack (the "specpdl").  A tail call can reuse
the current call stack frame, but leaves the special binding stack intact.
The special binding stack is only unwound during a return.
-- 
Barry Margolin
BBN Corporation, Cambridge, MA
······@bbnplanet.com
(BBN customers, call (800) 632-7638 option 1 for support)
From: Barry Margolin
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <5f0gkm$1ir@tools.bbnplanet.com>
In article <······················@alcatel.com.au>,
Chris Bitmead <·············@Alcatel.com.au> wrote:
>I think tail-call elimination within the same function scope would be
>quite sufficient. Doesn't elisp support even this?

The details of implementing tail-call elimination are the same whether it's
a calling itself or another function.

If you're referring to optimizing away the indirection through the symbol's
function cell in directly recursive functions, that's completely
different.  And it results in incompatible changes to semantics to the
language.  In particular, consider how the "advise" macro works; it does
something like:

(setq *saved-function* (symbol-function 'name))
(setf (symbol-function 'name)
  '(lambda args ... (apply *saved-function* args) ...))

If self-calls didn't go through the function binding, the advice wouldn't
affect the recursive invocations.
-- 
Barry Margolin
BBN Corporation, Cambridge, MA
······@bbnplanet.com
(BBN customers, call (800) 632-7638 option 1 for support)
From: Chris Bitmead
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <BITMEADC.97Feb25094057@Alcatel.com.au>
In article <···············@staffa.aiai.ed.ac.uk> Tim Bradshaw <···@aiai.ed.ac.uk> writes:

>Elisp does not do tail call elimination.  Although you could handle
>some cases of self-tail-call elimination in a language with dynamic
>scope (like elisp), I can't see how to do the general case.  Consider
>this:
>
>    (defun foo (x)
>      (bar (+ x 1)))
>
>    (defun bar (y)
>      (+ x y))
>
>    (foo 1)

I think tail-call elimination within the same function scope would be
quite sufficient. Doesn't elisp support even this?


-- 
---------------------------------------------------------------
| Chris Bitmead.....................................9690 5727 |
| ·············@Alcatel.com.au............................... |
---------------------------------------------------------------
The fact that it works is immaterial.
                -- L. Ogborn
From: Erik Naggum
Subject: Re: Modifiable parameters?
Date: 
Message-ID: <3065818685453445@naggum.no>
* Chris Bitmead
| I think tail-call elimination within the same function scope would be
| quite sufficient.  Doesn't elisp support even this?

how many times do you need to be given the same answer before you realize
that if _you_ want it and it isn't implemented, _you_ can do it?

to reiterate the same answer you got last time: the Emacs Lisp compiler
does not do tail call merging.  period.

#\Erik
-- 
if you think big enough, you never have to do it