Generational Interfaces

Discussion in 'Python' started by Carl Banks, Jan 26, 2008.

  1. Carl Banks

    Carl Banks Guest

    While thinking about generational garbage collection, the thought of
    generational interfaces occurred to me. I'd thought I'd run it by you
    guys. I'm curious if there are any examples of this out there.

    I've opined on this chat room before that interfaces are more often
    cumbersome than helpful, especially in the early stages of a project
    where lots of refactoring is (or ought to be) happening. But as
    projects mature, interfaces do too, and that made me think interfaces
    could be generated automatically by monitoring the software over time.

    As an example, say I'm writing a flight simulator, and I have a
    abstract base class Airplane, that I want to have an interface
    someday, but I don't know what it is yet. So I define an

    AirplaneInterface = InterfaceTracker("Airplane")

    What this does is to open a sort of persistent database called
    Airplane (details aren't important now). The database tracks all
    objects that claim to implement the interface.

    So say the first airplane is a Piper Cherokee. I'd write a class like
    this:

    class PiperCherokeeX1(object):
    wingspan = 52.2
    wingchord = 7.9
    ...
    def __init__(self):
    self.x = 0.0
    self.y = 0.0
    self.z = 0.0
    ...
    set_up_initial_state()
    ...
    AirplaneInterface.report(self)
    def move_stick(self,dx,dy):
    ...
    def move_thottle(self,ds):
    ...
    def move_rudder_pedals(self,ddr):
    ...
    def camera_matrix(self):
    return self._quat_to_matrix(self.q0,self.q1,self.q2,self.q3)
    def step(self,dt):
    ...

    The key here is the call to AirplaneInterface.report() at the end of
    __init__; this tells the interface tracker that, as of this call, this
    object is implementing the Aircraft interface.

    At this point, the interface tracker notes that PiperCherokeeX1 object
    has certain methods (move_stick, move_throttle, etc), certain class
    attributes, and certain instance attributes. And that's all it does--
    at first. It just writes information into the database.

    As time passes, and development continues, methods and data are added,
    changed, reconfigured. For instance, I might split up move_stick()
    into move_stick_x() and move_stick_y() for some reason. Then I might
    get rid of these functions altogether in favor of a
    move_control(self,n,dx). And so on. I add more classes that
    implement the Aircraft interface, too. They look almost nothing like
    the original interface.

    However, through all that, the class attribute "wingspan" remains
    there. Until one day when the project is quite mature I add a new
    class, say Airbus380, that fails to define "wingspan". When this
    class calls AirplaneInterface.report(), it raises an
    InterfaceException.

    Basically, the InterfaceTracker decides, after some threshold of
    nearly universal usage of a certain method or attribute, that it has
    become a required part of the interface and starts raising exceptions
    when it's not there.

    Make sense? Details can vary, but that's the basic idea. In this
    way, you can combine some of the openness that helps in early
    development, but also have some of the benefits of stricter typing
    when things mature and turn out to be pretty strictly useful, without
    much effort.

    Thoughts? (Surely someone's thought to do this before.)


    Carl Banks
     
    Carl Banks, Jan 26, 2008
    #1
    1. Advertising

  2. Carl Banks

    Paul Rubin Guest

    Carl Banks <> writes:
    > AirplaneInterface = InterfaceTracker("Airplane")
    > ...
    > set_up_initial_state()
    > ...
    > AirplaneInterface.report(self)


    > Thoughts? (Surely someone's thought to do this before.)


    A decorator might express the idea a little more naturally.

    Also, I'd say the interface tracker really should be told explicitly
    when something is part of the interface and when it's specific to a
    particular class implementing the interface. It shouldn't try to
    guess this based on some operation appearing in more than one class.
    Maybe there's some operation done on all jet planes and on no
    propeller planes, that shouldn't be part of the top level airplane
    interface.
     
    Paul Rubin, Jan 26, 2008
    #2
    1. Advertising

  3. Carl Banks

    Carl Banks Guest

    On Jan 26, 12:32 am, Paul Rubin <http://> wrote:
    > Carl Banks <> writes:
    > > AirplaneInterface = InterfaceTracker("Airplane")
    > > ...
    > > set_up_initial_state()
    > > ...
    > > AirplaneInterface.report(self)
    > > Thoughts? (Surely someone's thought to do this before.)

    >
    > A decorator might express the idea a little more naturally.


    Details. I didn't thoroughly map out the whole system in my head or
    anything.


    > Also, I'd say the interface tracker really should be told explicitly
    > when something is part of the interface and when it's specific to a
    > particular class implementing the interface. It shouldn't try to
    > guess this based on some operation appearing in more than one class.


    Well, that kind of defeats the purpose, doesn't it?

    If you're going to all that trouble, it's probably not too much more
    trouble to just manually specify the whole interface and be done with
    it. Anyways you don't always know what's going to end up as part of
    the interface in early stages.

    It goes without saying there should be ways to manually override the
    interface tracker's decision, but that falls more into the category
    "So your interface tracker has guessed wrong".


    > Maybe there's some operation done on all jet planes and on no
    > propeller planes, that shouldn't be part of the top level airplane
    > interface.


    Well, then the interface tracker would see that some member (say,
    "set_mixture") exists on some objects and not others, and would
    consider it not part of the interface. Only members that are defined
    universally or nearly universally would be considered part of the
    interface.

    Now if you're concerned that you could implement a bunch of prop
    planes, and then suddenly you throw a jet in there and it breaks
    everything, there's a simple solution: convert the AirplaneInterface
    to PropAirplaneInterface. (Yeah, suck it up and replace it
    everywhere. If you haven't implemented any jets you shouldn't have
    released the damn thing yet.) Create a new JetAirplaneInterface
    tracker and (if useful) define Airplane as the union of the two.

    Obviously something like this could get really intelligent--it could
    perhaps work out the difference between props and jets itself (using,
    say, statistical correlation). I bet there are some high-end code
    analysis tools for various languages that do stuff like that. (But I
    doubt many of them factor time into it; my idea was to incorporate
    time into it somehow. Something does not become part of an interface
    until it's universally used AND has been around for awhile.)


    Carl Banks
     
    Carl Banks, Jan 26, 2008
    #3
  4. Carl Banks

    Paddy Guest

    On Jan 26, 5:03 am, Carl Banks <> wrote:
    > While thinking about generational garbage collection, the thought of
    > generational interfaces occurred to me. I'd thought I'd run it by you
    > guys. I'm curious if there are any examples of this out there.
    >
    > I've opined on this chat room before that interfaces are more often
    > cumbersome than helpful, especially in the early stages of a project
    > where lots of refactoring is (or ought to be) happening. But as
    > projects mature, interfaces do too, and that made me think interfaces
    > could be generated automatically by monitoring the software over time.
    >
    > As an example, say I'm writing a flight simulator, and I have a
    > abstract base class Airplane, that I want to have an interface
    > someday, but I don't know what it is yet. So I define an
    >
    > AirplaneInterface = InterfaceTracker("Airplane")
    >
    > What this does is to open a sort of persistent database called
    > Airplane (details aren't important now). The database tracks all
    > objects that claim to implement the interface.
    >
    > So say the first airplane is a Piper Cherokee. I'd write a class like
    > this:
    >
    > class PiperCherokeeX1(object):
    > wingspan = 52.2
    > wingchord = 7.9
    > ...
    > def __init__(self):
    > self.x = 0.0
    > self.y = 0.0
    > self.z = 0.0
    > ...
    > set_up_initial_state()
    > ...
    > AirplaneInterface.report(self)
    > def move_stick(self,dx,dy):
    > ...
    > def move_thottle(self,ds):
    > ...
    > def move_rudder_pedals(self,ddr):
    > ...
    > def camera_matrix(self):
    > return self._quat_to_matrix(self.q0,self.q1,self.q2,self.q3)
    > def step(self,dt):
    > ...
    >
    > The key here is the call to AirplaneInterface.report() at the end of
    > __init__; this tells the interface tracker that, as of this call, this
    > object is implementing the Aircraft interface.
    >
    > At this point, the interface tracker notes that PiperCherokeeX1 object
    > has certain methods (move_stick, move_throttle, etc), certain class
    > attributes, and certain instance attributes. And that's all it does--
    > at first. It just writes information into the database.
    >
    > As time passes, and development continues, methods and data are added,
    > changed, reconfigured. For instance, I might split up move_stick()
    > into move_stick_x() and move_stick_y() for some reason. Then I might
    > get rid of these functions altogether in favor of a
    > move_control(self,n,dx). And so on. I add more classes that
    > implement the Aircraft interface, too. They look almost nothing like
    > the original interface.
    >
    > However, through all that, the class attribute "wingspan" remains
    > there. Until one day when the project is quite mature I add a new
    > class, say Airbus380, that fails to define "wingspan". When this
    > class calls AirplaneInterface.report(), it raises an
    > InterfaceException.
    >
    > Basically, the InterfaceTracker decides, after some threshold of
    > nearly universal usage of a certain method or attribute, that it has
    > become a required part of the interface and starts raising exceptions
    > when it's not there.
    >
    > Make sense? Details can vary, but that's the basic idea. In this
    > way, you can combine some of the openness that helps in early
    > development, but also have some of the benefits of stricter typing
    > when things mature and turn out to be pretty strictly useful, without
    > much effort.
    >
    > Thoughts? (Surely someone's thought to do this before.)
    >
    > Carl Banks


    I thought a major use of an interface is to allow separate development
    that comes together at the interface. If so then such fluid interface
    changing would scupper separate development.

    - Paddy.
     
    Paddy, Jan 26, 2008
    #4
  5. Carl Banks

    Carl Banks Guest

    On Jan 26, 3:04 am, Paddy <> wrote:
    > I thought a major use of an interface is to allow separate development
    > that comes together at the interface. If so then such fluid interface
    > changing would scupper separate development.



    Yes, this wouldn't be appropriate for that particular use.


    Carl Banks
     
    Carl Banks, Jan 26, 2008
    #5
  6. Carl Banks

    Guest

    I think they can be called "soft interfaces" or "heuristic
    interfaces", it's an example of machine learning. I think it's not
    easy to apply such idea to a statically typed language, but probably
    it can be done on Java. I presume in the future GUI will learn more
    about the usage patterns of their users, data structures of long-
    running programs will adapt to their average usage in each specific
    point of the program, and maybe class interfaces too will become
    smarter, as you say :)
    I think your idea can be implemented in Python too, so you just have
    to try to use it in some project of yours developed with some Agile
    programming style, so you can tell us if it's nice to use :)

    Bye,
    bearophile
     
    , Jan 26, 2008
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. shade
    Replies:
    1
    Views:
    1,676
  2. William F. Robertson, Jr.

    C# interfaces

    William F. Robertson, Jr., Jul 2, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    470
    [Gauthier]
    Jul 3, 2003
  3. Ollie
    Replies:
    0
    Views:
    372
    Ollie
    Sep 9, 2003
  4. Arvind
    Replies:
    14
    Views:
    557
    Frank Chang
    Aug 26, 2005
  5. Borked Pseudo Mailed

    Interest in generational GC for Python

    Borked Pseudo Mailed, Apr 19, 2009, in forum: Python
    Replies:
    3
    Views:
    215
    Martin v. Löwis
    Apr 20, 2009
Loading...

Share This Page