3 ms·
> If I want to override a function that a lot of other folks use, I can just redefine that function. That's possible and easy using Common Lisp packages. Just
by wtbob 12y ago
> If I want to override a function that a lot of other folks use, I can just redefine that function.
That's possible and easy using Common Lisp packages. Just use DEFUN with the symbol naming that function, and anyone using that function will now use the new name.
> Similarly, if I want to find all of the places that this method is used, a very simple textual search works.
That doesn't work, but a symbol-based search will.
> That last really needs underscoring for some of us. You want to try your hand at writing an emacs extension? Simply start defining stuff in the scratch buffer.
CL is not so great at that, but for other reasons.
- taeric 12y agoThe first case intrigues me. Are you saying that if a package A has a symbol Foo, and another package B has a symbol Foo, how would I override only package B's? Same for the second scenario? Isn't the symbol Foo essentially shadowed, depending on the package?
- wtbob 12y agoThe first case, that of overriding a function in another package, is really easy: CL-USER> (defpackage #:foo (:use #:cl)) #<PACKAGE "FOO"> CL-USER> (in-package #:foo) #<PACKAGE "FOO"> FOO> (defun func () 1) FUNC FOO> (export 'func) T FOO> (defpackage #:bar (:use #:cl #:foo)) #<PACKAGE "BAR"> FOO> (in-package #:bar) #<PACKAGE "BAR"> BAR> (func) 1 BAR> (defpackage #:baz (:use #:cl)) #<PACKAGE "BAZ"> BAR> (foo:func) 1 BAR> (defun foo:func () 2) STYLE-WARNING: redefining FOO:FUNC in DEFUN FUNC BAR> (func) 2 BAR> (in-package #:bar) #<PACKAGE "BAR"> BAR> (func) 2 BAR> (in-package #:foo) #<PACKAGE "FOO"> FOO> (func) 2 Notice how package FOO defined a function FUNC, which package BAR used without the package prefix (because it :USEs FOO), while package BAZ DEFUNed FOO:FUNC, redefining it everywhere. > Are you saying that if a package A has a symbol Foo, and another package B has a symbol Foo, how would I override only package B's? Easily: A:FOO and B:FOO are completely different symbols (unless B imports A or vice-versa). Setting `(symbol-value a:foo)` has no effect at all on `(symbol-value b:foo)`. If package C imports package A, then C:FOO and A:FOO are the same symbol. If C needs to import both A, but wants to use its own FOO, then it can shadow FOO, which means it would import all the exported symbols of A, except for FOO. IF C wanted to import both A and B, then a correctable error would be signaled; in a typical implementation the corrections would include: using A:FOO in preference to B:FOO; using B:FOO in preference to A:FOO; and aborting the attempt. The only thing not portably possible to my knowledge is to rename a symbol in an importing package, e.g. making C:FOO2 be an alias for A:FOO. If one thinks about what a symbol is, that makes sense. What would `(symbol-name c:foo2)` be in that case? All this, BTW, is why I am so keen on Common Lisp as opposed to Scheme: it really is an industrial-strength Lisp. They standardized a lot of stuff twenty years (and three days!) ago, after a lot of thought. Yeah, there's some compatibility cruft, but it's generally not a big deal (and can mostly be hidden, if one wanted to create a MODERN-LISP package).
- taeric 12y agoOk, I think that make sense. Basically, importing it lets you refer to the symbol in an abbreviated way. But it is always that symbol. If there was some odd case where you wanted every ??:FOO to be overridden, it would be tougher. (No, I am not trying to make a case for that scenario. Just making sure I understand.) And I understand what you are saying about CL being nice. I'm currently going through Land of Lisp and it is interesting to see how many things are covered. Granted, even scheme has this, to an extent. Reading SICP feels like reading a book on what was going to rise and fall in programming in the years to come. Regardless, Thanks!