Re: Issue with run or fill
Thanks Alex! It makes sense now. Normally, I would use a superclass but it's in the context of a component system so there's no inheritance (just polymorphism). --Kevin On Wed, Jun 22, 2022 at 8:12 AM Alexander Burger wrote: > Hi Kevin, > > > I'm wondering why this is not running as expected? > > > > (for @Cls '(+A +B) > > (run > > (fill > > '((class @Cls) > > (println 'define '@Cls) # prints: "define +A", then "define +B" > > (dm c> () (println (type This) 'default)) > > .. > > (extend +B) > > (dm c> () (println (type This) 'extended)) # prints: "c> +B redefined" > > It is because 'dm' stores the whole method definition as it is, i.e. > (c> NIL (println ...)), without doing an extra copy. > > If later called again with another definition for the same message, it > modifies > the existing definition destructively. > > Normally this is not a problem, as the definitions are read from a source > file > and are thus fresh in each definition. > > In the above 'for' loop, the method entry (c> NIL (println ...)) is > re-used, so > that both classes point to the same cell. Then, when you redefine 'c>' in > '+B' > you also modify it in '+A' as a side effect. > > > To avoid this behavior, you can call > >(undef 'c> '+B) > > before redefining 'c>' in '+B'. > > Or, even better, use a common superclass which defines 'c>', > and then override it in '+B'. > > ☺/ A!ex > > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe >
Re: Issue with run or fill
Hi Kevin, > I'm wondering why this is not running as expected? > > (for @Cls '(+A +B) > (run > (fill > '((class @Cls) > (println 'define '@Cls) # prints: "define +A", then "define +B" > (dm c> () (println (type This) 'default)) > .. > (extend +B) > (dm c> () (println (type This) 'extended)) # prints: "c> +B redefined" It is because 'dm' stores the whole method definition as it is, i.e. (c> NIL (println ...)), without doing an extra copy. If later called again with another definition for the same message, it modifies the existing definition destructively. Normally this is not a problem, as the definitions are read from a source file and are thus fresh in each definition. In the above 'for' loop, the method entry (c> NIL (println ...)) is re-used, so that both classes point to the same cell. Then, when you redefine 'c>' in '+B' you also modify it in '+A' as a side effect. To avoid this behavior, you can call (undef 'c> '+B) before redefining 'c>' in '+B'. Or, even better, use a common superclass which defines 'c>', and then override it in '+B'. ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Issue with run or fill
Hello, I'm wondering why this is not running as expected? (for @Cls '(+A +B) (run (fill '((class @Cls) (println 'define '@Cls) # prints: "define +A", then "define +B" (dm c> () (println (type This) 'default)) (c> (new '(+A))) # prints: "(+A) default" - correct (extend +B) (dm c> () (println (type This) 'extended)) # prints: "c> +B redefined" (c> (new '(+B))) # prints: "(+B) extended" - correct (c> (new '(+A))) # prints: "(+A) extended" - incorrect It appears, extending +B extends +A also. --Kevin