🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: net.lang.lisp
Article #725

Re: call/cc and proper tail recursion

#725
From: harrison
Date: Sat, 01 Nov 1986 02:08
33 lines
2676 bytes

	I read the reference you suggested, and think I understand how this
works now.  call/cc simply copies the stack into the heap; if a frame
representing a tail-recursive call is 'caught' by a call to call/cc, it will
be copied into the heap before the next call is made.  Barring an invocation
of call/cc (no doubt the perversity in my example is rare), only one frame's
worth of locations are allocated for the bindings of the local vars of the
tail-recursive function.
	This implementation of call/cc surprises me.  To quote from
"The Implementation of PC Scheme", by D. H. Bartley and John C. Jensen, p 88,

	When CALL-WITH-CURRENT-CONTINUATION is invoked, the stack is copied
	into the heap to make a continuation object.  To reduce the worst-case
	cost of this copying and to permit arbitrary growth of the stack,
	a small buffer is used to hold the topmost stack frames.  When
	this buffer overflows, all frames but the currently active one are
	copied into a continuation object in the heap.

It would seem that most stack frames would end up on the heap, especially if
either the buffer is small, or call/cc is used heavily.  Given that, why not
allocate all frames on the heap to start with?  Having done so directly,
call/cc becomes dirt cheap, as a continuation may be represented merely by a
pointer to a 'stack' frame and a code pointer.  Likewise, closure formation
would be dirt cheap, requiring only a code pointer and a lexical parent pointer
(a static link, as they call it in compilers for algol-ish languages).
We would have to garbage collect the entire stack, but if we have to do
(nearly) that anyway, why not make closure formation and call/cc cheap?
(We could still perform tail recursion 'properly', except in the event that a
closure was created which caught a local variable of the tail-recursive
function, such that the closure could out-live the stack frame of that
function, or call/cc was used as per my example.  In those cases, we could make
a normal recursive call instead of a properly tail-recursive one.)
Technical Details
Message-ID: <20000019@uicsrd>
Path: arc1-ca.pugleaf.net!utzoo!mnetor!seismo!rutgers!clyde!cbatt!ihnp4!inuxc!pur-ee!uiucdcs!uiucuxc!uicsrd!harrison
References: <20000003@uicsrd>

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!utzoo!mnetor!seismo!rutgers!clyde!cbatt!ihnp4!inuxc!pur-ee!uiucdcs!uiucuxc!uicsrd!harrison
From: harrison@uicsrd.CSRD.UIUC.EDU
Newsgroups: net.lang.lisp
Subject: Re: call/cc and proper tail recursion
Message-ID: <20000019@uicsrd>
Date: Fri, 31-Oct-86 21:08:00 EST
Article-I.D.: uicsrd.20000019
Posted: Fri Oct 31 21:08:00 1986
Date-Received: Tue, 4-Nov-86 03:20:56 EST
References: <20000003@uicsrd>
Lines: 33
Nf-ID: #R:uicsrd:20000003:uicsrd:20000019:000:2043
Nf-From: uicsrd.CSRD.UIUC.EDU!harrison    Oct 31 20:08:00 1986