Re: Question about call-next-method
"David McClain (as dbm at refined-audiometrics dot com)" <[email protected]>
| Newsgroups | gmane.lisp.lispworks.general |
|---|---|
| Message-ID | <[email protected]> |
I presume you mean “Scheme Calling Convention” is your notion of CPS? > On Nov 18, 2025, at 07:42, Edward Kiser (as edkiser at gmail dot com) <[email protected]> wrote: > > At this point I'm just trying to populate my Scheme's initial > environment with some useful functions. > > I already have a "procedure" wrapper that works with plain Lisp > functions (and with generic methods if they follow the plain Lisp > calling convention). So I can easily call Lisp functions from Scheme. > > However, I think it would be useful to be able to have an abstract > CLOS class, some concrete descendants implemented in Lisp, and also a > function in Scheme that would take Scheme procedures as arguments and > generate a descendant implemented in Scheme. The generated descendants > would all be an instance of the same CLOS class, a "forwarder" class. > In order for this to work, all the generic functions would have to > implement (or be adaptable to) the Scheme calling convention. > > So for example I could have a "scheme-iterator" class, a > "scheme-list-iterator" implemented in Lisp, but also a > "scheme-forwarding-iterator" which would forward all the iteration > functions to Scheme procedures. Then I could have a "make-iterator" > function in Scheme that took a bunch of procedures as arguments, and > created a forwarding iterator which would forward the iterator > functions like "has-next?" and "get-next" to those procedures. > > Then I could have a "for-each" syntax in Scheme that would work with > any iterator. (It would probably be a macro that expands to "let > loop".) > > On Tue, Nov 18, 2025 at 8:09 AM David McClain > <[email protected]> wrote: >> >> Hi Ed, >> >> I sometimes write Scheme-like systems for myself… What is the connection you see between Scheme and CLOS Methods? Can you elucidate? >> >> >> >>> On Nov 17, 2025, at 10:34, Edward Kiser (as edkiser at gmail dot com) <[email protected]> wrote: >>> >>> I wouldn't generally write a program that would modify its own generic >>> functions while it was running. However, it's possible that I might >>> modify a generic function during debugging. >>> >>> My conceptual model has been that a function consists of a blob of >>> machine code and an associated "stack frame format." When you >>> recompile a function, the compiler creates a new blob (which might >>> have a new stack frame format), resets the name to point to the new >>> blob, and then leaves the old blob to be garbage collected. But the >>> old blob cannot be garbage-collected until it is no longer being >>> used. So if the old version of the function has a call in progress, >>> there is still a live stack frame associated with the old blob, and >>> only the old blob would know how to unwind that stack frame, so the >>> stack frame should refer to its blob of code (directly, not by name), >>> and that should prevent the old blob from being garbage-collected >>> until all of its instances have returned. >>> >>> The same general approach would work if you were storing call frames >>> on the heap instead of the stack. >>> >>> If the compiler encounters multiple "lambda" forms it would have to >>> produce multiple blobs. Every time the lambda form runs, it captures >>> the variables and creates a new procedure which associates the >>> captured variables with the blob. So there can be multiple procedures >>> with the same blob of code but different variable captures. >>> >>> I would expect CLOS to follow that "immutable blob" approach as >>> well. "Define-method-combination" creates a form which is presumably >>> passed to the compiler, so it would inherit the compiler's >>> behavior. So modifying the function would only affect new calls and >>> would not affect existing calls. >>> >>> (Or at least that's the conceptual model I've been working with... it >>> has served me well so far...) >>> >>> Even if CLOS does create immutable blobs, though, my original question >>> is one of whether the behavior of "call-next-method" is determined by >>> the heap or the stack. If it's the stack, the behavior will be popped >>> off when the generic function returns, and in that case the generic >>> function cannot expect to capture "call-next-method" for later. >>> >>> I've read that some people have used CLOS to write Scheme >>> implementations, and so I thought CLOS implementers would have found >>> it useful to be able to define CLOS generic functions that could be >>> called from Scheme and therefore would have to adhere to the Scheme's >>> calling convention (e.g. continuation-passing style). Of course CPS >>> allows call/cc and all the trouble that implies. >>> >>> On Sun, Nov 16, 2025 at 3:24 PM Bradford Miller <[email protected]> wrote: >>>> >>>> One of the things I specifically have in mind is the idea of “supercompilation” where you optimize a function for future use while running it based on monitoring its execution. Another idea is to compile (or finish compiling) a function after the arguments are known, which may eliminate or simplify much of the internal code. If that happens to affect internal loops, one can get a substantial reduction in constant factors that lead to significant run-time gains, even in the face of the overhead of running the compiler itself. (Of course, that would generally only apply to higher exponent polynomial complexity algorithms, NP-Hard functions, etc. depending on the actual size of the input). >>>> >>>> These, of course, are not new concepts (the REFAL language that first explored supercompilation dates to the 1970s). However, I’m not aware of anyone trying to apply these concepts to domain-specific applications of Lisp. >>>> >>>> On Nov 16, 2025, at 1:16 PM, Tim Bradshaw (as tfb at cley dot com) <[email protected]> wrote: >>>> >>>> On 16 Nov 2025, at 17:30, Bradford Miller (as gorbag at icloud dot com) <[email protected]> wrote: >>>> >>>> >>>> One can already redefine common functions in the middle of a program and use them unless their calls were compiled >>>> >>>> >>>> Try to read what I wrote. I'll quote it here: >>>> >>>> Still less should the behaviour of programs which might add, redefine or remove methods to a generic function while it is being called be defined. >>>> >>>> >>>> Do you see the bit I have now emphasized above? So what you are asking or is not 'redefining functions and using them': it is redefining functions that are in the process of being called and then expecting that the new definition takes effect for that call. >>>> >>>> (Redefinition of ordinary functions is in fact allowed not 'unless they were compiled', but unless their callers were in the same file or they're declared inline.). >>>> >>>> >>> >>> _______________________________________________ >>> Lisp Hug - the mailing list for LispWorks users >>> [email protected] >>> http://www.lispworks.com/support/lisp-hug.html >> > > _______________________________________________ > Lisp Hug - the mailing list for LispWorks users > [email protected] > http://www.lispworks.com/support/lisp-hug.html _______________________________________________ Lisp Hug - the mailing list for LispWorks users [email protected] http://www.lispworks.com/support/lisp-hug.html