Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: Stefan Monnier Newsgroups: comp.lang.lisp Subject: Re: Local/temporary methods in CLOS Date: Tue, 11 Mar 2025 18:02:05 -0400 Organization: A noiseless patient Spider Lines: 39 Message-ID: References: <20250311140945.99@kylheku.com> MIME-Version: 1.0 Content-Type: text/plain Injection-Date: Tue, 11 Mar 2025 23:02:06 +0100 (CET) Injection-Info: dont-email.me; posting-host="12429b145adf428d02c277d62269e161"; logging-data="2294887"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18bzss9SV8qpdX/mkyAGTdtcKtTWDTzrck=" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:JD8D8FOcv9doKGCYaq9EkrIoywQ= sha1:JpnM/sVgotOs+D0kUTSV451APs4= Bytes: 2615 >> I need some way to define "local" methods, which can override >> temporarily "global" methods and obey some kind of dynamic scoping rule. > > I feel that your requirements may be somewhere in the locus of > Pastal Costanza's work, like ContextL. > > https://github.com/pcostanza/contextl > > Also see Costanza's paper "Dynamically Scoped Functions as the > Essence of AOP" [2003]. Thanks! That's a nice solution, and the underlying implementation technique makes a lot of sense (it refines the manual solution I've been playing with). >> Assuming I'm not the first to feel such a need, what are usual >> approaches to try and provide that kind of behavior? > > Since in Common Lisp we don't have dynamically scoped functions, only > variables, the straightforward thing, without using anyone's framework, > would be to use special variables to hold certain functions of interest, > and funcall them. (That can be wrapped or macroed over.) > > (defun overridable-fun (&rest args) > (apply *overridable-fun* args)) > > (let ((*overridable-fun* (lambda (...) ...))) > (overridable-fun 42)) For dynamically-scoped local functions, that's indeed what I typically use (or alternatively, I simply pass that function explicitly down the stack), but my question is for the case where I want to do it for methods, i.e. for "part" of a function (I guess I could simulate it by overriding with a function that tests the args' type and delegates to the old function, but then I get a kind of "linear-time" dispatch if there are N local methods, which I'd rather avoid). Stefan