Loading ...
Sorry, an error occurred while loading the content.
 

Re: Adding method slots dynamically

Expand Messages
  • baltasarq
    Hi, there ! ... I don t understand why you need a mirror object in order to add/delete/modify(?) methods or attributes (I suppose you need the same trick for
    Message 1 of 11 , Aug 14, 2005
      Hi, there !

      --- In self-interest@yahoogroups.com, Jecel Assumpcao Jr
      <jecel@m...> wrote:
      > First you need a mirror on the object you are interested in:
      > You can create a mirror on a method from a string:
      >
      > (reflect: myObj) at: 'selector:And:' PutContents:
      > ('| :arg1. :arg2. tmp <- 9 | (arg1*arg2)+tmp' parseObjectBody)

      I don't understand why you need a mirror object in order to
      add/delete/modify(?) methods or attributes (I suppose you need the
      same trick for attributes).

      What's the role of the mirror, here ? Is it related to preformance ?

      Thank you in advance,

      Baltasar
    • Jecel Assumpcao Jr
      ... It isn t a performance issue at all, but rather a matter of good object oriented design. The paper I mentioned last month goes into details about why
      Message 2 of 11 , Aug 16, 2005
        "baltasarq" wrote:
        > --- In self-interest@yahoogroups.com, Jecel Assumpcao Jr
        > <jecel@m...> wrote:
        > > First you need a mirror on the object you are interested in:
        > > You can create a mirror on a method from a string:
        > >
        > > (reflect: myObj) at: 'selector:And:' PutContents:
        > > ('| :arg1. :arg2. tmp <- 9 | (arg1*arg2)+tmp' parseObjectBody)
        >
        > I don't understand why you need a mirror object in order to
        > add/delete/modify(?) methods or attributes (I suppose you need the
        > same trick for attributes).
        >
        > What's the role of the mirror, here ? Is it related to preformance ?

        It isn't a performance issue at all, but rather a matter of good object
        oriented design. The paper I mentioned last month goes into details
        about why mirrors are a good idea (http://bracha.org/mirrors.pdf) but
        here is a short answer:

        Every object you create is "about" something. You might create an object
        called "circle" that is about circles on the screen, for example. It
        should know things like its diameter, its center and perhaps stuff about
        its border and interior color. The more we can make ourselfves believe
        that this actually is a circle, the better it will be to work with it.

        Another context might require different things from our object: a
        debugger or program editor might want to know things like the number of
        slots it has, how many bytes it takes up in RAM and so on. An obvious
        solution is to add methods to this object (and probably every single
        object in the system as well!) so these applications can do their job.
        The problem with this is that the new behavior isn't at all circle-like.
        We are ruining the "this object is a circle" illusion (which we call the
        base-level programming domain) by mixing a "this object is a bunch of
        slots" illusion (which we call the meta-level programming domain).

        An alternative design is to separate the meta-level stuff into a helper
        object. Since meta-level programming which changes the implementation
        level is called "reflection" we will name this helper object a "mirror".
        This separation allows a circle to be pure again - all it knows about is
        circleness. The mirror is also pretty close to pure, knowing only about
        reflection. Another advantage of this organization is that just a few
        kinds or mirrors are enough to deal with all objects in Self.

        -- Jecel
      • jbgarcia@uvigo.es
        Hi, Jecel ! Thank you for your answer. ... I ve browsed the article and I ve also read your answer. Though there isn t anything wrong in Mirrors for me, I am
        Message 3 of 11 , Aug 17, 2005
          Hi, Jecel !

          Thank you for your answer.


          > > What's the role of the mirror, here ? Is it related to preformance ?
          >
          > It isn't a performance issue at all, but rather a matter of good object
          > oriented design. The paper I mentioned last month goes into details
          > about why mirrors are a good idea (http://bracha.org/mirrors.pdf) but
          > here is a short answer:

          I've browsed the article and I've also read your answer. Though there isn't
          anything wrong in Mirrors for me, I am not totally convinced about them.

          If you don't have mirrors, then the functionalty related to reflection (i.e. the
          set of methods which actually add methods or attributes, etc.) will be in the
          "Object" or however the root of inheritance is named. I suppose this the way
          Smalltalk does it, this is the way Java implements it, and anyway it is the way
          I am implementing it in Zero ( http://trevinca.ei.uvigo.es/~jgarcia/TO/zero/ ).
          The only "bad thing" is that it makes the "Object" object to be quite "big", in
          terms of number of methods.

          > Every object you create is "about" something. You might create an object
          > called "circle" that is about circles on the screen, for example. It
          > should know things like its diameter, its center and perhaps stuff about
          > its border and interior color. The more we can make ourselfves believe
          > that this actually is a circle, the better it will be to work with it.

          However, it will always have more functionality than the circle concept has. For
          example, you could create another circle sending the message "copy". In order
          to follow the path of pureness suggested by the concept of mirrors, perhaps the
          copy method should exist in another object of the library, the "factory" object
          or something.

          So, instead of doing:

          myCircle = Circle.copy()

          you could do:

          myCircle = Factory.copy( Circle )

          Or something like that.

          > Another advantage of this organization is that just a few
          > kinds or mirrors are enough to deal with all objects in Self.

          A few kinds of mirrors ? Sorry, I don't understand. Why not a single Mirror
          object ?

          Salud !

          Baltasar



          --oOo-----------------------------------------------------------------oOo--

          Servicio de acceso ó correo electrónico vía web da Universidade de Vigo
          Servicio de acceso al correo electrónico vía web de la Universidad de Vigo

          Servicios Informáticos [ http://si.uvigo.es ]
          Universidade de Vigo [ http://www.uvigo.es ]

          URL: https://correoweb.uvigo.es
        • Jecel Assumpcao Jr
          Baltasar, ... I have adopted a different solution for Neo Smalltalk, so I can certainly understand that no everybody likes this solution. ... In Self you can
          Message 4 of 11 , Aug 17, 2005
            Baltasar,

            > I've browsed the article and I've also read your answer. Though there isn't
            > anything wrong in Mirrors for me, I am not totally convinced about them.

            I have adopted a different solution for Neo Smalltalk, so I can
            certainly understand that no everybody likes this solution.

            > If you don't have mirrors, then the functionalty related to reflection (i.e. the
            > set of methods which actually add methods or attributes, etc.) will be in the
            > "Object" or however the root of inheritance is named. I suppose this the way
            > Smalltalk does it, this is the way Java implements it, and anyway it is the way
            > I am implementing it in Zero ( http://trevinca.ei.uvigo.es/~jgarcia/TO/zero/ ).
            > The only "bad thing" is that it makes the "Object" object to be quite "big", in
            > terms of number of methods.

            In Self you can have objects like

            (| count <- 1. inc = (count: count + 1) |)

            which does not inherit from some global "Object". In fact, it is a good
            idea to use such objects whenever possible and only make them inherit
            from "traits oddball" or "traits clonable" when they really need it to
            do their job. This is the "principal of least authority" from the
            security guys applied to object design.

            > However, it will always have more functionality than the circle concept has. For
            > example, you could create another circle sending the message "copy". In order
            > to follow the path of pureness suggested by the concept of mirrors, perhaps the
            > copy method should exist in another object of the library, the "factory" object
            > or something.
            >
            > So, instead of doing:
            >
            > myCircle = Circle.copy()
            >
            > you could do:
            >
            > myCircle = Factory.copy( Circle )
            >
            > Or something like that.

            Very true - you can consider cloning to be meta-level behavior and want
            to put that into a separate object. A mirror would be a good place for
            this. Of course, in the real world there are objects that can copy
            themselves without external help such as biological cells.

            Two advantages of the "copying is domain behavior" design used in Self
            are that this is a very frequent operation so making it more lightweight
            will improve performance and that having each object control this allows
            the separation of "oddball" objects from "clonable" ones.

            > A few kinds of mirrors ? Sorry, I don't understand. Why not a single Mirror
            > object ?

            Some objects only have named slots, others (vectors) have indexed
            fields, others (methods and blocks) have code and others (small integers
            and floats) have non standard encodings. So you probably want to
            implement a method like 'slotNames' differently for the mirrors of each
            different kind.

            -- Jecel
          • jbgarcia@uvigo.es
            Hi, Jecel ! ... Could please explain your approach ? Or just paste some links ... ... Well, yes, that s an interesting point. Salud ! Baltasar
            Message 5 of 11 , Aug 18, 2005
              Hi, Jecel !

              > > I've browsed the article and I've also read your answer. Though there
              > isn't
              > > anything wrong in Mirrors for me, I am not totally convinced about them.
              >
              > I have adopted a different solution for Neo Smalltalk, so I can
              > certainly understand that no everybody likes this solution.

              Could please explain your approach ? Or just paste some links ...

              > In Self you can have objects like
              >
              > (| count <- 1. inc = (count: count + 1) |)
              >
              > which does not inherit from some global "Object". In fact, it is a good
              > idea to use such objects whenever possible and only make them inherit
              > from "traits oddball" or "traits clonable" when they really need it to
              > do their job. This is the "principal of least authority" from the
              > security guys applied to object design.

              Well, yes, that's an interesting point.

              Salud !

              Baltasar


              --oOo-----------------------------------------------------------------oOo--

              Servicio de acceso ó correo electrónico vía web da Universidade de Vigo
              Servicio de acceso al correo electrónico vía web de la Universidad de Vigo

              Servicios Informáticos [ http://si.uvigo.es ]
              Universidade de Vigo [ http://www.uvigo.es ]

              URL: https://correoweb.uvigo.es
            • Toby Ovod-Everett
              ... Placing all of the mirror slots into a generic Object object also introduces the possibility of name collision should one desire to add additional
              Message 6 of 11 , Aug 18, 2005
                On Wed, Aug 17, 2005 at 12:47:39PM +0200, jbgarcia@... wrote:
                >
                > Hi, Jecel !
                >
                > Thank you for your answer.
                >
                >
                > > > What's the role of the mirror, here ? Is it related to preformance ?
                > >
                > > It isn't a performance issue at all, but rather a matter of good object
                > > oriented design. The paper I mentioned last month goes into details
                > > about why mirrors are a good idea (http://bracha.org/mirrors.pdf) but
                > > here is a short answer:
                >
                > I've browsed the article and I've also read your answer. Though there isn't
                > anything wrong in Mirrors for me, I am not totally convinced about them.
                >
                > If you don't have mirrors, then the functionalty related to reflection (i.e. the
                > set of methods which actually add methods or attributes, etc.) will be in the
                > "Object" or however the root of inheritance is named. I suppose this the way
                > Smalltalk does it, this is the way Java implements it, and anyway it is the way
                > I am implementing it in Zero ( http://trevinca.ei.uvigo.es/~jgarcia/TO/zero/ ).
                > The only "bad thing" is that it makes the "Object" object to be quite "big", in
                > terms of number of methods.

                Placing all of the mirror slots into a generic "Object" object also introduces
                the possibility of name collision should one desire to add additional
                functionality to the mirror down the road. Isolating the reflective behavior
                into a mirror object has the benefit of creating a new namespace that is, in
                effect, named "reflect ".

                Having co-implemented Self-like behavior in Perl (see Class::Prototyped), it
                was a big sigh of relief to move all of the mirror behavior into a mirror
                object, for it meant I could add behavior to my heart's content without
                worrying about the potential for namespace collisions/occlusions.

                --Toby Ovod-Everett
              • Toby Ovod-Everett
                ... In addition, by putting copying in the domain, one makes it easier to override the copying behavior. It is rare that an object designer would want to
                Message 7 of 11 , Aug 18, 2005
                  On Wed, Aug 17, 2005 at 12:43:59PM -0300, Jecel Assumpcao Jr wrote:
                  > Two advantages of the "copying is domain behavior" design used in Self
                  > are that this is a very frequent operation so making it more lightweight
                  > will improve performance and that having each object control this allows
                  > the separation of "oddball" objects from "clonable" ones.

                  In addition, by putting copying in the domain, one makes it easier to override
                  the copying behavior. It is rare that an object designer would want to
                  override the behavior of addSlots, for instance. It is not that rare that a
                  designer would want to override the behavior of clone, on the other hand.
                  Yes, if one puts clone in the mirror, one can still override the behavior of
                  clone by overriding the behavior of reflect so that it returns an modified
                  mirror that overrides clone on it's behalf, but that is a convoluted approach
                  to implementing a common design pattern.

                  The most common reason to override clone is a need to retain a count or a list
                  of every object of a given "class".

                  --Toby Ovod-Everett
                • Jecel Assumpcao Jr
                  Toby Ovod-Everett wrote on Thu, 18 Aug 2005 06:45:02 -0800 ... This is a very good point. ... Yes, and a similar argument can be made for putting printString
                  Message 8 of 11 , Aug 18, 2005
                    Toby Ovod-Everett wrote on Thu, 18 Aug 2005 06:45:02 -0800
                    > In addition, by putting copying in the domain, one makes it easier to override
                    > the copying behavior. It is rare that an object designer would want to
                    > override the behavior of addSlots, for instance. It is not that rare that a
                    > designer would want to override the behavior of clone, on the other hand.

                    This is a very good point.

                    > Yes, if one puts clone in the mirror, one can still override the behavior of
                    > clone by overriding the behavior of reflect so that it returns an modified
                    > mirror that overrides clone on it's behalf, but that is a convoluted approach
                    > to implementing a common design pattern.

                    Yes, and a similar argument can be made for putting "printString" in the
                    objects themselves even though it is also a very meta operation. If you
                    need a different mirror of every object you might as well include that
                    stuff in the object.

                    > The most common reason to override clone is a need to retain a count or a list
                    > of every object of a given "class".

                    Another reason is to control how deep the copying should be. The raw
                    clone operation is what is called shallowCopy in Smalltalk. Sometimes
                    you don't want to share subparts with the original but want to copy
                    those too. This makes coming up with a generic copying framework
                    complicated and is related to the problems of saving a single object to
                    a file and reading it back in. It is easier if the objects at least help
                    with part of the job.

                    -- Jecel
                  • Jecel Assumpcao Jr
                    Baltasar, ... Just the reflection is a special viewpoint approach suggested in the Us paper (still available online, as Reinout Heeck kindly corrected me
                    Message 9 of 11 , Aug 18, 2005
                      Baltasar,

                      > > I have adopted a different solution for Neo Smalltalk, so I can
                      > > certainly understand that no everybody likes this solution.
                      >
                      > Could please explain your approach ? Or just paste some links ...

                      Just the "reflection is a special viewpoint" approach suggested in the
                      Us paper (still available online, as Reinout Heeck kindly corrected me
                      about a month ago: http://citeseer.ist.psu.edu/smith96simple.html).

                      When you deal with an object in most contexts it will be missing all the
                      meta-level methods, but when you switch to a special viewpoint then it
                      will seem as if an extra set of methods have been added to the object
                      (overriding any methods with the same names that the object might have
                      already have) and you can do debugging and programming environment kinds
                      of things with it.

                      Personally I find the mirror approach cleaner. But I have had
                      discussions with several programmers who had difficulty understanding
                      the indirection in that design and my system is supposed to be suitable
                      for children.

                      -- Jecel
                    Your message has been successfully submitted and would be delivered to recipients shortly.