home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 14 Text / 14-Text.zip / SOM-QA.ZIP / SOM-QA.TXT
Text File  |  1992-09-23  |  37KB  |  797 lines

  1. Questions and answers about SOM
  2.  
  3.  
  4. 1.1:  Are there plans for debugging SOM objects?
  5.  
  6. response date:  5/30/92
  7.  
  8.  Although SOM objects are in general multi-lingual (i.e., the instance
  9.  variables and method procedures encapsulated by an object may be
  10.  implemented by different languages), the newly introduced instance
  11.  variables and methods for each derived class of SOM objects are always
  12.  implemented by a single language, and the API for class creation can
  13.  include specification of this language.  Thus, the information necessary
  14.  to invoke the correct debugger for tracing through individual methods can
  15.  be made available.  This suggests the possibility of providing a
  16.  framework within which different debuggers can be dynamically called to
  17.  trace method calls as execution proceeds.
  18.  
  19.  Currently, we use C language debuggers for debugging SOM classes
  20.  implemented using C. As they become available, we may use C++ debuggers
  21.  for SOM classes implemented using C++.
  22.  
  23.  
  24. 1.2:  Does SOM support garbage collection?
  25.  
  26. response date: 5/30/92
  27.  
  28.  This is an area of some importance, and we may work on this in the
  29.  future.
  30.  
  31.  Garbage collection in a multi-language environment is a hard problem,
  32.  though.  Even the single language case is not straightforward; take the
  33.  problem of automatic garbage collection for C language programs, for
  34.  example.
  35.  
  36.  But it is possible that enhancements to the current SOM API might be able
  37.  to provide information upon which a GC capability could be based.
  38.  
  39.  
  40. 1.3:  If SOM doesn't provide GC, then is there SOM support for freeing
  41. objects when multiple threads have access to them?
  42.  
  43. response date: 5/30/92
  44.  
  45.  A service or thread that creates an object (which is given to others but
  46.  which may later be "deleted") has the responsibility of defining an
  47.  appropriate protocol for client registration to support the object's use.
  48.  SOM doesn't provide any specific support for this.  Critical regions, for
  49.  example, are provided by the usual operating system interfaces; not
  50.  through any primitive SOM objects or classes.
  51.  
  52.  It should be possible to provide such facilities through SOM classes,
  53.  allowing inheritance to provide uniform support of protocols.  Although
  54.  such classes are not provided by the basic SOM runtime, they can be
  55.  provided as application frameworks.
  56.  
  57.  
  58. 1.4:  What are the Costs/Benefits of runtime class objects?
  59.  
  60. response date: 5/30/92
  61.  
  62.  The cost is minimal, since there will be only one class object, no matter
  63.  how many of its instances exist.
  64.  
  65.  The benefits are great, since the class object can respond dynamically to
  66.  requests concerning object and class information that is only known at
  67.  runtime.  In addition, specializations of SOMClass can create metaclasses
  68.  that provide additional facilities, or override SOMClass methods to
  69.  provide tailored behavior for classes of objects.
  70.  
  71.  Since class objects are created at runtime, it is even possible to
  72.  support adaptable systems in which the desired classes of objects may be
  73.  discovered or may change as the system evolves.  In advanced, interactive
  74.  systems, the ability to create "new" kinds of objects in response to
  75.  changing circumstances can be useful.
  76.  
  77.  
  78. 1.5:  What are the Costs/Benefits of always requiring derivation from
  79. SOMObject class?
  80.  
  81. response date: 5/30/92
  82.  
  83.  There is no cost, since SOMObject introduces no instance variables.
  84.  
  85.  But there are many benefits, since this allows us to provide important
  86.  functionality for all SOM objects.
  87.  
  88.  As an example of useful functionality, every SOM object knows its class,
  89.  and can return its class object.  Also, SOMObject methods allow
  90.  introducing defaults for routines (like dumpSelf) that can be specialized
  91.  by individual classes.  There are other, deeper examples as well, related
  92.  to support for dynamic method dispatching.
  93.  
  94.  
  95. 1.6:  What SOM Class libraries are there?
  96.  
  97. response date: 5/30/92
  98.  
  99.  Currently the Workplace Shell and the SOM run-time classes are
  100.  available for use on OS/2.  Various additional class libraries are
  101.  planned for the future that cover topics such as replication,
  102.  persistance, event management, GUI, CORBA Interface Repository,
  103.  foundation classes, etc.
  104.  
  105.  
  106. 2.1:  What are the SOM method resolution mechanisms?
  107.  
  108. response date: 5/30/92
  109.  
  110.  Offset resolution is based on knowing a SOM object type that includes the
  111.  desired method, and using this knowledge to access a corresponding
  112.  "method token" from a global data structure.  The object and the method
  113.  token are passed to somResolve (the SOM procedure for offset method
  114.  resolution), and the appropriate procedure pointer is returned.  This
  115.  pointer is then used to invoke the procedure and perform the method.
  116.  Language bindings based on static information declared using OIDL are
  117.  used to hide the details of this procedure.
  118.  
  119.  Name resolution is based on knowing the arguments for a desired method.
  120.  The method name is passed to the somFindMethod method of the object's
  121.  class object, and the result is the appropriate procedure pointer.  Name
  122.  resolution is available for any SOM object, irrespective of its class.
  123.  This is because offset resolution can be used on any object to find it's
  124.  class object (the somGetClass method is in the SOMObject type), and can
  125.  then be used on the resulting class object to do name resolution (the
  126.  somFindMethod is in the SOMClass type).
  127.  
  128.  The two methods above assume that it is possible to statically construct
  129.  within a program a procedure call that applies the "resolved" procedure
  130.  pointer to the appropriate arguments -- either explicitly, within code
  131.  written by the programmer, or implicitly, within "language bindings."  If
  132.  the programming language does not support procedure pointers, or the
  133.  appropriate arguments are not known until runtime, then dispatch
  134.  resolution can be used.
  135.  
  136.  Dispatch resolution accepts as parameters a method name and a
  137.  dynamically constructed argument list (class objects can be used to
  138.  discover what the appropriate arguments for a method call are), and is
  139.  available as an offset method call on all objects (since the dispatch
  140.  methods are included in the SOMObject type).
  141.  
  142.  The different kinds of method resolution techniques thus correspond to
  143.  successively greater uncertainty about the class of an object and the
  144.  methods it supports.
  145.  
  146.  In the case of offset resolution, we have an OIDL declaration for a class
  147.  that includes the desired method.
  148.  
  149.  In the case of name resolution, we don't have a static type for the
  150.  object more specific than, often, SOMObject.  But knowing only this type,
  151.  we are able to use offset resolution to access the object's class, check
  152.  whether the object supports a desired method (whose arguments we know),
  153.  and then call the appropriate procedure.
  154.  
  155.  In the case of dispatch resolution, we can't use offset resolution
  156.  because we don't have an appropriate type for the object, and we can't
  157.  use name resolution because we don't know what the appropriate arguments
  158.  are.  But, as described above, the information required for dispatch
  159.  resolution is always available dynamically.
  160.  
  161. response date: 5/30/92
  162.  
  163.  Name Resolution method :
  164.  
  165.  SOMClass has a method called "somFindMethod".  By using this interface it
  166.  is possible to get a method pointer if the object supports the specified
  167.  method.  This method pointer can be used to make a dynamic method call.
  168.  It is a useful mechanism for optimization.  Another application is that
  169.  if the only information about the method call is its signature, we could
  170.  use this to make the method call.
  171.  
  172.  Dispatch Resolution :
  173.  
  174.  This mechanism in SOM is created to support dynamic languages.  SOMObject
  175.  provides "somDispatch" interfaces which can be overridden by providing
  176.  dynamic-language supported "somDispatch" routines.  "somDispatch"
  177.  interfaces accepts a variable argument list for the method parameters.
  178.  Dynamic languages can construct a variable argument list and use this
  179.  interface to send messages to SOM objects.  (we use this mechanism to
  180.  support subclassing of SOM classes in OREXX, Object-Oriented REXX, and
  181.  vice versa)
  182.  
  183.  Example program:
  184.  ================
  185.  
  186.  student.csc file:
  187.  =================
  188.  
  189.   include <somobj.sc>
  190.  
  191.   class:
  192.     Student;
  193.  
  194.   -- "Student" class provides a base class to generate more specialized
  195.   -- students like "GraduateStudent" and "UnderGraduateStudent".
  196.   -- Some of the methods like "printStudentInfo" and "getStudentType"
  197.   -- must be overridden in the subclasses.
  198.  
  199.   parent:
  200.     SOMObject;
  201.  
  202.   data:
  203.     char  idU16e;      /* student id */
  204.     char  nameU32e;    /* student name */
  205.  
  206.   methods:
  207.     override  somInit;
  208.  
  209.     void  setUpStudent(char *id, char *name);
  210.     -- sets up a new student.
  211.  
  212.     void  printStudentInfo();
  213.     -- prints the student information.
  214.  
  215.     char  *getStudentType();
  216.     -- returns the student type.
  217.  
  218.     char  *getStudentId();
  219.     -- returns the student id.
  220.  
  221.  student.c file:
  222.  ===============
  223.  
  224.   #define Student_Class_Source
  225.   #include "student.ih"
  226.  
  227.   SOM_Scope void   SOMLINK somInit(Student *somSelf)
  228.   {
  229.       StudentData *somThis = StudentGetData(somSelf);
  230.       parent_somInit(somSelf);
  231.       _idU0e = _nameU0e = ' ';
  232.   }
  233.  
  234.   SOM_Scope void   SOMLINK setUpStudent(Student *somSelf,
  235.                                         char *id, char *name)
  236.   {
  237.       StudentData *somThis = StudentGetData(somSelf);
  238.       strcpy(_id, id);
  239.       strcpy(_name, name);
  240.   }
  241.  
  242.   SOM_Scope void   SOMLINK printStudentInfo(Student *somSelf)
  243.   {
  244.       StudentData *somThis = StudentGetData(somSelf);
  245.       printf("   Id         : %s 0, _id);
  246.       printf("    Name       : %s 0, _name);
  247.       printf("    Type       : %s 0, _getStudentType(somSelf));
  248.   }
  249.  
  250.   SOM_Scope char *  SOMLINK getStudentType(Student *somSelf)
  251.   {
  252.       StudentData *somThis = StudentGetData(somSelf);
  253.       static char *type = "student";
  254.       return (type);
  255.   }
  256.  
  257.   SOM_Scope char *  SOMLINK getStudentId(Student *somSelf)
  258.   {
  259.       StudentData *somThis = StudentGetData(somSelf);
  260.       return (_id);
  261.   }
  262.  
  263.  Client program:
  264.  ===============
  265.  
  266.   #include "student.h"
  267.  
  268.   sendMessage(char *method, SOMObject *target,  char  *str1,  char
  269.   *str2)
  270.   {
  271.       somMethodProc *methodPtr;
  272.  
  273.       _somFindMethod(_somGetClass(target),
  274.           somIdFromString(method), &methodPtr);
  275.       (*methodPtr)(target,str1, str2);
  276.   }
  277.  
  278.   dispatchMessage(char *method, SOMObject *target, ...)
  279.   {
  280.     va_list ap;
  281.     va_start(ap, target);
  282.     SOMObject_somDispatchV(target, somIdFromString(method), "", ap);
  283.     va_end(ap);
  284.   }
  285.  
  286.   main()
  287.   {
  288.      Student *student1 = StudentNew();
  289.      Student *student2 = StudentNew();
  290.      Student *student3 = StudentNew();
  291.  
  292.      _setUpStudent(student1, "599600", "David Brown");
  293.      sendMessage("setUpStudent", student2, "120045", "Janet Smith");
  294.      dispatchMessage("setUpStudent", student3, "789001", "Maria Somer");
  295.      _printStudentInfo(student1);
  296.      _printStudentInfo(student2);
  297.      _printStudentInfo(student3);
  298.   }
  299.  
  300.  Output from this program:
  301.  =========================
  302.  
  303.      Id         : 599600
  304.      Name       : David Brown
  305.      Type       : student
  306.  
  307.      Id         : 120045
  308.      Name       : Janet Smith
  309.      Type       : student
  310.  
  311.      Id         : 789001
  312.      Name       : Maria Somer
  313.      Type       : student
  314.  
  315.  
  316. 2.2:  What might language bindings for C++ look like?  Because SOM seems
  317. to omit a large subset of C++ constructs, it seems that C++ bindings
  318. may be little more than the current C bindings, save maybe the hassle of
  319. dealing with the 'this' pointer.  Is this true?  Will I have to give up
  320. exception handling, templates, default method arguments, operator
  321. overloading, etc..??  Will I just be basically coding in C, but compiling
  322. with C++?  If these kinds of features will be available under the C++
  323. support, will I have to use convoluted macros, or will I be able to code
  324. using the C++ semantics?  If a construct is supported under one SOM
  325. language binding, will all other language bindings also have to support
  326. it?  Why not make the SOM OIDL a superset of the functions provided by
  327. the popular OO languages, with some neat SOM bonus features?
  328.  
  329. response date: 5/30/92
  330.  
  331.  SOM is not a programming language, and does not attempted to support all
  332.  of the features of all object-oriented languages.  This is probably
  333.  impossible and self-contradictory.  SOM does provide an extremely
  334.  flexible and powerful framework for advanced object-oriented systems
  335.  development.  The central focus and contribution of SOM is support for
  336.  binary distribution of language-neutral class libraries.  In contrast,
  337.  language-centric class libraries are limited in utility (they are useful
  338.  only from a single language), and require publication of source code
  339.  (different compilers for the same object-oriented language cannot be
  340.  guaranteed to use the same object layouts in memory, so a binary class
  341.  library produced by one compiler will generally be useless to
  342.  applications developed with a different compiler).  SOM solves these
  343.  problems.
  344.  
  345.  In general, we don't expect that SOM will be used to implement all of the
  346.  objects and classes important to an application.  Many objects created
  347.  and used by an application will be strictly internal to that
  348.  application's implementation -- with no need for being accessed by
  349.  multiple languages or applications.  Perhaps these internal objects will
  350.  be SOM objects (in those cases where a SOM class library provides useful
  351.  functionality), or perhaps they will be objects provided by some other
  352.  class library (e.g., a Smalltalk or C++ class library), depending on the
  353.  language used to program the application.
  354.  
  355.  Only objects whose implementation is to be provided or used by
  356.  non-object-oriented programming languages, or objects intended to be
  357.  useful across application and language boundaries with upwards binary
  358.  compatability need to be SOM objects.  We believe such objects can be
  359.  valuable; supporting such objects is SOM's objective.
  360.  
  361.  ---
  362.  
  363.  The purpose of C++ bindings for SOM would be to make it easy for a C++
  364.  programmer to use SOM objects, and to make it easy for a C++ programmer
  365.  to define new SOM object classes.
  366.  
  367.  There are many ways of accomplishing these two goals.  We have identified
  368.  at least three different approaches to C++ bindings, which may be
  369.  characterized as follows:  (1) Instantiable (2) Subclassable (3)
  370.  Compiler-Supported
  371.  
  372.  Instantiable is based on in-line expansion of C++ method calls into SOM
  373.  offset resolution method calls.  The approach requires no C++ instance
  374.  data, since the pointer to a C++ object that "wraps" a SOM object IS the
  375.  pointer to the wrapped SOM object.
  376.  
  377.  Subclassable is based on C++ instance data that holds a pointer to a
  378.  wrapped SOM object, and uses a C++ virtual function table.
  379.  
  380.  Either approach could be supported by a special C++ compiler front-end,
  381.  which would provide the corresponding functionality, while optimizing
  382.  performance.
  383.  
  384.  What are the functionalities associated with (1) and (2) ?
  385.  
  386.  With (1), Instantiable:
  387.  
  388.  All SOM objects (including class objects) are available to a C++
  389.  programmer as C++ objects of a corresponding C++ class.  Such SOM objects
  390.  can be created using the C++ "new" operation on the C++ class name.  The
  391.  SOM class hierarchy is faithfully mirrored in the C++ class hierarchy.
  392.  As a result, the C++ compiler provides static typechecking for SOM object
  393.  use.  A C++ programmer using the SOM bindings to access SOM objects thus
  394.  has access to all of C++ in his code.  (The important qualification here
  395.  is the use of the word "object" instead of the word "class" -- see the
  396.  next paragraph).
  397.  
  398.  If it is desired to implement an OIDL-specified class using C++, an OIDL
  399.  specification for the desired SOM class is provided as input to the SOM
  400.  compiler, and C++ implementation bindings for the class are generated and
  401.  used by the C++ programmer.  The C++ programmer uses (unrestricted) C++
  402.  code to implement procedures supporting the newly-introduced methods of
  403.  the class.  Thus, individual C++ procedures (not C++ methods) are defined
  404.  to support the methods introduced and overridden by the OIDL- specified
  405.  class.
  406.  
  407.  Of course, using "this" within such procedures is meaningless.  The C++
  408.  methods in which "this" is used contain the (inline) SOM offset
  409.  resolution method calls that are used to invoke the supporting
  410.  procedures.  The primary difference from the C implementation bindings is
  411.  that the new class can introduce C++ instance variables (including C++
  412.  objects), and the method procedures used to implement new and overridden
  413.  methods can make use of local C++ variables (again, including C++
  414.  objects).
  415.  
  416.  Thus, subclassing is done in OIDL -- not C++ -- and all parent classes
  417.  must themselves be SOM classes.  The C++ classes that mirror SOM classes,
  418.  and whose instances are actually SOM objects, cannot be subclassed in
  419.  C++.  Only the mirrored SOM classes themselves can be subclassed (using
  420.  OIDL and some choice of implementation bindings).
  421.  
  422.  With (2), Subclassable:
  423.  
  424.  As with the Instantiable approach, SOM objects (including classes) are
  425.  available to a C++ programmer as an instance of a C++ class, and the SOM
  426.  class hierarchy is faithfully mirrored in the C++ class hierarchy.  As a
  427.  result, the C++ compiler provides static typechecking for SOM object use.
  428.  
  429.  But subclassing can now be done in C++.  A C++ subclass can be derived
  430.  (in C++) from the C++ representative of a SOM class, and can introduce
  431.  new instance variables and methods, and override inherited methods.  This
  432.  allows a new C++ class to be derived from both C++ and SOM classes.
  433.  
  434.  Unfortunately, using language bindings to allow C++ to override inherited
  435.  SOM methods and pass C++ objects as arguments to SOM methods introduces
  436.  performance penalties.  Some of these can be avoided in a
  437.  compiler-supported approach.
  438.  
  439.  Using a dual approach, C++ classes can be made available as SOM class,
  440.  through an interface that provides the SOM benefits.  Again, there are
  441.  performance tradeoffs.
  442.  
  443.  
  444. 2.3:  How about inter-process method calls?
  445.  
  446. response date: 5/30/92
  447.  
  448.  This capability is planned.  Currently, SOM can be used with shared
  449.  memory for this purpose (this is not a supported capability, but some
  450.  users are doing it).  But SOM is being enhanced to support the CORBA
  451.  standards for object method invocation in a distributed open system
  452.  environment.  As an initial step in this directions, we will be
  453.  supporting calls across address spaces on a single machine.  Also,
  454.  classes being developed as class libraries may provide automated support
  455.  for replicated objects across address spaces (i.e., one "logical" object;
  456.  many "physical" copies).
  457.  
  458.  
  459. 2.4:  Will SOM and the WPS be supported on multiple platforms (other
  460. than AIX)?
  461.  
  462. response date: 6/1/92
  463.  
  464.  We're working on getting SOM available on AIX.  As for the WPS, we don't
  465.  know if there are plans or a desire to put it on AIX.  As for other
  466.  platforms for SOM, there don't appear to be any technical barriers.
  467.  
  468.  
  469. 2.5:  What does it take for another language to be supported under SOM?
  470. Once a language is supported, does this mean that any standard compiler
  471. for that language will do?
  472.  
  473. response date: 5/30/92
  474.  
  475.  To allow a given language to use and define class of SOM objects, we
  476.  decide how to map the types and objects of SOM into this other language.
  477.  There may be many ways to do this; we decide on one, and then write
  478.  emitters that automate the process.  Then all that is needed is a
  479.  standard compiler for the language, plus use of the emitters to produce
  480.  SOM class bindings.  This has currently been done for C and C++.  We are
  481.  working on other languages as well.
  482.  
  483.  The above approach assumes that it is possible to make use of the SOM API
  484.  from within the language for which bindings are desired.  The SOM API was
  485.  designed with the desire to require as little as possible for its use.
  486.  The SOM API basically requires the ability to make external procedure
  487.  calls using system-defined linkage, and the ablity to construct simple
  488.  data structures in memory.
  489.  
  490.  Where these capabilities are available at the language level, SOM
  491.  bindings can be source level; where they are not, SOM bindings will
  492.  require compiler support, in addition to any source-level bindings that
  493.  might be used.
  494.  
  495.  
  496. 2.6:  How does SOM implement language independence?
  497.  
  498. response date: 5/30/92
  499.  
  500.  Discussion of language independence in SOM ultimately relates to the
  501.  ability of different languages to use SOM objects and define new SOM
  502.  classes (which, really, is simply a use of SOM objects).
  503.  
  504.  It is not SOM's most direct purpose to allow C++ programmers to invoke
  505.  virtual functions on Smalltalk objects, or allow C++ to subclass
  506.  Smalltalk classes.  SOM does allow both C++ and Smalltalk (as well as
  507.  other languages) to use SOM objects and to implement new classes of SOM
  508.  objects by inheriting and enhancing the implementation of other classes
  509.  of SOM objects.  As a result of this capability, SOM does reduce an order
  510.  n-squared interface problem to an order n interface problem.  In
  511.  addition, SOM does provide facilities that are useful in this reguard.
  512.  
  513.  Multi-language capability is a primary objective for SOM.  Achieving this
  514.  objective has influenced SOM's design in many ways, so there is no single
  515.  answer to this question.  As we produce new language bindings for SOM, we
  516.  are likely to iterate the SOM design (while maintaining binary capability
  517.  with previous versions) to provide better support for this.
  518.  
  519.  The SOM API for invoking methods on SOM objects is ultimately based on
  520.  calls to external procedures defined by the SOM runtime, a small set of
  521.  simple types (including pointers to data and pointers to procedures) and
  522.  few simple data structures.  Any languages with these capabilities can
  523.  use SOM directly.  Where these facilities are not available directly at
  524.  the language level, it is possible they might be provided by "helper
  525.  functions," provided by a compiler-specific procedure library, or they
  526.  might be directly supported by compiler modifications.
  527.  
  528.  When a given language is used to implement a new SOM class, the instance
  529.  variables that are introduced, and the procedures used to support
  530.  introduced and overridden methods need not be useful (or comprehensible)
  531.  to the languages used to implement subsequently derived classes.  This is
  532.  one reason why SOM does not allow inherited access to instance variables.
  533.  As a result, multi-language objects are possible, in which instance
  534.  variables and method procedures are contributed by different programming
  535.  languages.  When a method is invoked on a SOM object, the appropriate
  536.  procedure is called, and this procedure then can directly access only
  537.  those instance variables that were introduced by the class the procedure
  538.  supports.
  539.  
  540.  For obvious reasons, we have initially focused on the cases in which the
  541.  SOM API is useful without compiler-specific support.  But as interest in
  542.  SOM grows, it is likely that we will also be investigating other
  543.  possibilities.  Due to the simplicity of the SOM API, compiler
  544.  modifications necessary for its support should be straightforward.  For
  545.  example, a compiler vendor for a non- object-oriented language without
  546.  the ability to directly use the SOM API might consider the ability to use
  547.  SOM objects a strategic advantage worth the small effort involved in
  548.  providing this capability through compiler modifications.
  549.  
  550.  
  551. 3.1:  Is there a problem when two unrelated classes introduce methods of
  552. the same name, and a client code wants to deal with objects of both
  553. classes?  What if the methods take a different number of arguments?
  554.  
  555. response date: 6/10/92
  556.  
  557.  This would not a problem at all with C++ bindings (since C++ classes
  558.  provide method scoping).  The C bindings for SOM, however, are based on
  559.  macros, so method "collision" in this case, as a result of different
  560.  macros being #included into C source that deals with different classes of
  561.  objects, is something that can happen.  When this does happen, however,
  562.  it is not a serious problem (it is an annoyance, and the following
  563.  describes how to deal with it).
  564.  
  565.  In the C bindings, corresponding to any given method on a SOM object are
  566.  two different invocation macros:  a "short" form in which the macro name
  567.  contains only the method name (e.g., _foo for the method foo); and a
  568.  "long" form, in which the macro name includes both the class that
  569.  introduced the method and, in addition, the method name.  Certainly, if
  570.  class A and class B both define a foo method, and some client code
  571.  includes both A.h and B.h, then the short forms of the macros will
  572.  "collide."  This is will result in either warning messages or error
  573.  messages -- depending on the particular C compiler being used.  For
  574.  example, assume that the foo method available on A instances was
  575.  introduced by the class, Z, an ancestor of A, and that the foo method
  576.  available on B instances was introduced by the class, B. Then the
  577.  following code should be used.
  578.  
  579.   #include "A.h"
  580.   #undef _foo
  581.   #include "B.h"
  582.   #undef _foo
  583.  
  584.   void test(A *a, B *b)
  585.   {
  586.     Z_foo(a);    /* instead of _foo(a) */
  587.     B_foo(b,12); /* instead of _foo(b,12) */
  588.   }
  589.  
  590.  The only important thing is this:  if you see a warning that a method
  591.  invocation macro has been redefined, then it is absolutely essential that
  592.  the long form of the method invocation macros be used.  Note that in the
  593.  above example, the methods take different numbers of arguments, as in
  594.  your question.  The #undef's prevent the warning (or error) messages, and
  595.  also prevent accidental use of the short form.
  596.  
  597.  Again Note:  The C++ bindings would not have this problem, because
  598.  they would not be based on macros, but, instead, inline C++ method
  599.  expansions.
  600.  
  601.  
  602. 3.2:  Why do the usage bindings for a class automatically include usage
  603. bindings for its parent (which, in turn include the usage bindings for
  604. its parent, and so on until SOMObject is reached)?  The result is that
  605. if a client includes the usage bindings for a given class, then the
  606. usage bindings for all of that class's ancestors are included as well.
  607.  
  608. response date: 6/10/92
  609.  
  610.  First off, this should not be a surprise to anyone familiar with C++,
  611.  since any client of a C++ class must include the class's structure
  612.  definition, and defining a class's structure can only be done after
  613.  defining the structure of the parent classes.  So a very similar sort of
  614.  chaining effect occurs in within any code that uses a C++ class.
  615.  
  616.  Why is it necessary in SOM, though?
  617.  
  618.  As in C++, it is required for implementing inheritance of interface.  The
  619.  method invocation macros that support the methods introduced by any given
  620.  class initially appear in the usage bindings for the introducing class,
  621.  and these must be "inherited" by the usage bindings for classes derived
  622.  from this class.  Also, to actually accomplish a static method call
  623.  ultimately requires to evaluate an expression that accesses the ClassData
  624.  structure of the class that introduced the method.  And this data
  625.  structure is defined in the usage bindings for the introducing class.
  626.  If, for example, the usage bindings for SOMObject were not included by
  627.  some derived class's usage bindings, then none of the methods introduced
  628.  by SOMObject would be available statically on instances of the derived
  629.  class.
  630.  
  631.  
  632. 3.3:  Why isn't access to data inherited?
  633.  
  634. response date: 6/10/92
  635.  
  636.  First it is necessary to understand that the SOM API does allow direct
  637.  (uninterpreted, offset-based) access to the instance variables of SOM
  638.  objects.  As a matter of policy, however, the usage bindings for SOM
  639.  classes do not automatically provide an interface to this capability.
  640.  Some reasons for this explained below.  However, the SOM API is always
  641.  available directly to users, so direct access to instance variables is
  642.  possible if an application is willing to suffer the consequences:
  643.  changes in implementation of the class whose introduced instance
  644.  variables are accessed may require recompilation of the application's
  645.  source code.  Within tightly-coupled "friend" classes, this may be
  646.  reasonable.
  647.  
  648.  SOM simply doesn't provide this facility as a default.  Instead, SOM
  649.  provides a machanism whereby a SOM class developer decides which instance
  650.  variables introduced by that class should be visible to clients, and for
  651.  these instance variables (and only these) is an interface provided by the
  652.  usage bindings for that class.
  653.  
  654.  The following are two reasons for our approach.
  655.  
  656.  (1) SOM is intended to support arbitrary languages, allowing a subclass
  657.  to be implemented independently of the language(s) used to implement its
  658.  ancestor classes.  Typically, a class C implemented using language X will
  659.  introduce instance variables to support its methods.  Now, lets say that
  660.  language Y is now used to implement a subclass of C named S. S will also
  661.  introduce instance variables in support of its methods.  Certainly, the
  662.  code that implements these methods should have direct access to the
  663.  instance variables that were introduced for its support.  But there is no
  664.  reason whatsoever to expect that the instance variables that make sense
  665.  to language X (used in support of C's method procedures) will also make
  666.  sense to language Y (used in support of S's method procedures).  Given
  667.  SOM's desire to support multi-language objects, there seems very little
  668.  reason for believing that inherited access to instance variables
  669.  introduced by ancestor classes makes sense in general.  Thus, the
  670.  procedures that implement methods introduced by a class have direct
  671.  access only to those instance variables introduced by the class.
  672.  
  673.  (2) There is another reason related to binary compatibility.  SOM's
  674.  objective is that changing the implementation for a class of objects
  675.  should not require re-compiling any code that depends on this class.
  676.  Code that depends on a class includes both client code, and code that
  677.  implements subclasses.  Now, if the code that implements a subclass were
  678.  allowed direct access to inherited instance variables, this code would
  679.  certainly require recompilation (and more likely, redesign) when
  680.  implementation of an ancestor class changes.  SOM does provide access
  681.  mechanisms for instance variables, but the decision to "publish" an
  682.  instance variable for access by others is a decision of the class
  683.  implementor -- not the class user.  So the class implementor knows what
  684.  portions of the implementation others could depend on, and what portions
  685.  can be changed without concern for users.  As mentioned above, it is
  686.  possible to defeat approach, but it must be done with knowledge of the
  687.  SOM API -- the language bindings (which hide the API) don't provide
  688.  direct support for it.
  689.  
  690.  
  691. 3.4:  Is the interface to published methods a macro or a function.
  692.  
  693. response date: 6/10/92
  694.  
  695.  Just as with access to instance data, access to the procedure that
  696.  supports a given method is based on a function call.  The two situations
  697.  are very similar.  To access data (using the SOM API directly), one calls
  698.  somDataResolve passing an object and a data token.  To access the
  699.  procedure that supports a method, one calls somResolve passing an object
  700.  and a method token.  Both data and method tokens can be thought of as
  701.  "logical" offsets.  They provide a very fast way of accessing the desired
  702.  information, and are statically available via usage bindings.  As with
  703.  data access, usage bindings try to hide the details.  In the C bindings,
  704.  this is done with a macro; in the C++ bindings, this may be done by
  705.  defining C++ methods as expanded inline.  The result is the same, since
  706.  the same function call is compiled inline in both cases.
  707.  
  708.  In drastic contrast, name lookup first requires getting the class of the
  709.  object, and then invoking methods on the class to get a method token.
  710.  This is rather more expensive than simply retrieving a method token from
  711.  a known, globally available location (which is what the usage bindings do
  712.  for static method invocations).  Once the method token is available,
  713.  somResolve is used to return a pointer to the procedure that supports the
  714.  desired method on the object.
  715.  
  716.  
  717. 3.5:  There is a problem with the _<class-name>New macro.  Unlike the
  718. <class-name>New macro (note no underscore prefix).  Using the first may
  719. create errors, since it assumes that the class object exists.
  720.  
  721. response date: 6/10/92
  722.  
  723.  The underscore form of the macro is certainly not intended for use by
  724.  class clients.  It is defined within the usage bindings solely to support
  725.  the non-underscore form, which is the (only) form documented in the SOM
  726.  user's guide.  This could cause a problem, though, since the short form
  727.  for method invocation starts with an underscore, and a SOM user thus
  728.  might forget and use the underscore when requesting instance creation.
  729.  This has been been fixed.  (I.e., the underscore form of the macro is no
  730.  longer defined defined.)  In general, the macro-based C usage bindings
  731.  are open to a number of similar criticisms.  The C++ bindings would not
  732.  suffer from this problem, since they would not be macro-based.
  733.  
  734.  
  735. 4.1:  Is there a version of SOM that is OMG (CORBA) compliant?
  736.  
  737. response date: 6/12/92
  738.  
  739.  We are currently working upon a CORBA compliant version of SOM.  This
  740.  will include an IDL compiler (with suitable enhancements to accept SOM
  741.  Class Implementation details) and all SOM runtime classes in IDL.
  742.  
  743.  
  744. 5.1:  For example, if I had a "C++ binding" for the workplace shell
  745. classes, what might a C++ programmer write in order to subclass
  746. "WPAbstract"?
  747.  
  748. response date: 6/30/92
  749.  
  750.  Instantiable
  751.  ============
  752.  
  753.  First of all, with the "Instantiable" approach, it is not necessary to
  754.  have a C++ binding for WPAbstract in order to implement a subclass of
  755.  WPAbstract using C++.  All that is needed is an OIDL class description
  756.  (e.g., the .sc file) for WPAbstract.
  757.  
  758.  Assuming that the .sc file for WPAbstract is available, a C++ programmer
  759.  would (1) use OIDL to declare a new SOM class whose parent is WPAbstract,
  760.  (2) generate Instantiable C++ implementation bindings for the resulting
  761.  subclass, and (3) fill out the resulting default method procedure
  762.  templates for overridden and newly-introduced methods with C++ code.  As
  763.  can be seen, this is essentially the same approach used for the C
  764.  implementation bindings.
  765.  
  766.  How is this different from using C implementation bindings to implement a
  767.  new subclass of WPAbstract?  The two primary differences are that the
  768.  instance variables introduced by the new subclass can include C++
  769.  objects, and the method procedures used by the C++ programmer to
  770.  implement the overridden and newly introduced methods for the new class
  771.  can make use of local variables that are C++ objects.
  772.  
  773.  Of course, C++ usage bindings for a SOM class should be a great
  774.  improvement over the C usage bindings, since the C++ usage bindings can
  775.  be based on inline method expansion instead of macros, resulting in
  776.  the elimination of any macro "collision" problems of the C bindings.
  777.  Also a C++ compiler could then type check SOM object usage.
  778.  
  779.  Subclassable
  780.  ============
  781.  
  782.  With the Subclassable approach, a C++ programmer would use a C++ class
  783.  representing the SOM class WPAbstract (provided by the Subclassable C++
  784.  bindings for WPAbstract) as a base class for declaring and defining (in
  785.  C++ -- not OIDL) a new derived C++ class whose parent is the C++ class
  786.  provided by the C++ usage bindings for WPAbstract.  This new derived C++
  787.  class is not a SOM class.  However, if it is desired to publish this new
  788.  subclass as a SOM class (thereby making it available and useful to
  789.  languages other than C++), then it is possible to do this -- using
  790.  essentially the same technique as was used to create the Subclassable C++
  791.  bindings for WPAbstract.
  792.  
  793.  The Subclassable bindings would be more complex and present additional
  794.  execution-time tradeoffs.  We have created prototype emitters to
  795.  demonstrate that the process of generating these bindings can be
  796.  automated, and we are currently evaluating tradeoffs.
  797.