From: Nicolas Neuss on 23 Mar 2010 06:02 Eli Barzilay <eli(a)barzilay.org> writes: > The reason I pointed at CLOS as being a potential problem is related > to types, but goes beyond that: it is the fact that generic functions > are being extended via side-effects which complicates both having it > live in peace with a typechecker as well as other components. To get > a feeling of the general problem, consider the fact that if you have > this > > (defmethod foo ((x string)) 'x) > > in one file, and this > > (defmethod foo ((x string)) 'y) > > in another, then the order in which you load the two files becomes > important. IMO, this is the single biggest wart that I didn't address > in Swindle. (And I don't know of a way to address it.) Here I would be satisfied with something the warning: Warning: Redefining METHOD FOO (STRING) in file "A.lisp" Reasoning: Usually this is a problem you will want to avoid. OTOH, forbidding it completely is too restrictive: for example, it is necessary for patching functions where you cannot (or do not want to) change the source code itself. Nicolas [*] BTW, this is exactly what SBCL and probably many other implementations are doing: Looking at my current SLIME session I see: redefining DATABASE-GET-TYPE-SPECIFIER (#<EQL-SPECIALIZER {1002AEBA41}> #<BUILT-IN-CLASS T> #<BUILT-IN-CLASS T> #<EQL-SPECIALIZER {1002AEBDE1}>) in DEFMETHOD
From: joswig on 23 Mar 2010 06:06 On 23 Mrz., 11:02, Nicolas Neuss <lastn...(a)kit.edu> wrote: > Eli Barzilay <e...(a)barzilay.org> writes: > > The reason I pointed at CLOS as being a potential problem is related > > to types, but goes beyond that: it is the fact that generic functions > > are being extended via side-effects which complicates both having it > > live in peace with a typechecker as well as other components. To get > > a feeling of the general problem, consider the fact that if you have > > this > > > (defmethod foo ((x string)) 'x) > > > in one file, and this > > > (defmethod foo ((x string)) 'y) > > > in another, then the order in which you load the two files becomes > > important. IMO, this is the single biggest wart that I didn't address > > in Swindle. (And I don't know of a way to address it.) > > Here I would be satisfied with something the warning: > > Warning: Redefining METHOD FOO (STRING) in file "A.lisp" > > Reasoning: Usually this is a problem you will want to avoid. OTOH, > forbidding it completely is too restrictive: for example, it is > necessary for patching functions where you cannot (or do not want to) > change the source code itself. > > Nicolas > > [*] BTW, this is exactly what SBCL and probably many other > implementations are doing: Looking at my current SLIME session I see: > > redefining DATABASE-GET-TYPE-SPECIFIER > (#<EQL-SPECIALIZER {1002AEBA41}> > #<BUILT-IN-CLASS T> > #<BUILT-IN-CLASS T> > #<EQL-SPECIALIZER {1002AEBDE1}>) in DEFMETHOD He says 'extension', but shows redefinition. His example is 'nonsense'. Think about the problem of 'extension' instead.
From: Eli Barzilay on 23 Mar 2010 06:48 Nicolas Neuss <lastname(a)kit.edu> writes: > Eli Barzilay <eli(a)barzilay.org> writes: > >> The reason I pointed at CLOS as being a potential problem is >> related to types, but goes beyond that: it is the fact that generic >> functions are being extended via side-effects which complicates >> both having it live in peace with a typechecker as well as other >> components. To get a feeling of the general problem, consider the >> fact that if you have this >> >> (defmethod foo ((x string)) 'x) >> >> in one file, and this >> >> (defmethod foo ((x string)) 'y) >> >> in another, then the order in which you load the two files becomes >> important. IMO, this is the single biggest wart that I didn't >> address in Swindle. (And I don't know of a way to address it.) > > Here I would be satisfied with something the warning: > > Warning: Redefining METHOD FOO (STRING) in file "A.lisp" Yes, that's the sane thing to do -- but the fact that generic functions are accumulated via side-effects remains. "joswig(a)corporate-world.lisp.de" <joswig(a)lisp.de> writes: > He says 'extension', but shows redefinition. His example is > 'nonsense'. That depends on your definition of "definition". If it means creating a binding, then there is no redefinition happening there. If it means determining what a specific function does -- or more generally changing what value a variable contains -- then yes this is redefinition, just like any other (incf *foo*). The wart that I'm referring to is exactly this side effect -- and that (and consequences like order-of-loading dependencies) remains whatever your definitions are. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life!
From: joswig on 23 Mar 2010 07:45 On 23 Mrz., 11:48, Eli Barzilay <e...(a)barzilay.org> wrote: > "jos...(a)corporate-world.lisp.de" <jos...(a)lisp.de> writes: > > He says 'extension', but shows redefinition. His example is > > 'nonsense'. > > That depends on your definition of "definition". If it means creating > a binding, then there is no redefinition happening there. If it means > determining what a specific function does -- or more generally > changing what value a variable contains -- then yes this is > redefinition, just like any other (incf *foo*). The wart that I'm > referring to is exactly this side effect -- and that (and consequences > like order-of-loading dependencies) remains whatever your definitions > are. Just disallow REDEFINITION of methods. Done. But that will not solve the EXTENSION problem: (defmethod foo (x) 3) .... (foo (make-instance 'bar)) -> 3 (defmethod foo ((x bar)) 4) (foo (make-instance 'bar)) -> 4 Above the generic function is extended with a new method. Just disallow individual definitions of methods. Define all methods in the DEFGENERIC. Problem solved. But then in CLOS and CL in general, side effects are everywhere, and are not 'warts'. They would have been warts if the language designers had tried to remove side effects and failed in some places. But they haven't even tried to remove side effects in general. That things compute differently based on the at anyone time known definitions and that at different times different definitions can be active is also nothing special and has nothing to do with files and loading. Common Lisp provides REMOVE-METHOD and ADD-METHOD. Any program can construct methods at runtime or remove them from a generic function - at runtime.
From: Eli Barzilay on 23 Mar 2010 08:52
"joswig(a)corporate-world.lisp.de" <joswig(a)lisp.de> writes: > On 23 Mrz., 11:48, Eli Barzilay <e...(a)barzilay.org> wrote: > >> "jos...(a)corporate-world.lisp.de" <jos...(a)lisp.de> writes: >> > He says 'extension', but shows redefinition. His example is >> > 'nonsense'. >> >> That depends on your definition of "definition". If it means >> creating a binding, then there is no redefinition happening >> there. If it means determining what a specific function does -- or >> more generally changing what value a variable contains -- then yes >> this is redefinition, just like any other (incf *foo*). The wart >> that I'm referring to is exactly this side effect -- and that (and >> consequences like order-of-loading dependencies) remains whatever >> your definitions are. > > Just disallow REDEFINITION of methods. Done. *sigh* > But then in CLOS and CL in general, side effects are everywhere, and > are not 'warts'. Yes, side effects are everywhere -- in all practical languages. Even in Haskell. But side effects are >>> IN MY OPINION <<< warts regardless of the language -- and *I* consider it an even bigger wart if you have side effects that lead to dependencies on the order of loading code. Because of this, *I* consider it a problem when an object system forces me to get into this swamp (barring non-solutions like "Just disallow individual definitions of methods"). This does *not* mean that if I'd design a language from scratch I'd try to remove side effects, but it does mean that *I* try to avoid such dependencies, and that *I* believe that avoiding such dependencies *if* possible and practical makes *MY* code more robust. But of course *YOUR* opinion is different. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! |