--- Marc Portier <[EMAIL PROTECTED]> wrote:
Tim,

your postings on the list urged me to get some deeper into this
specially on the 'cyclic' stress on the building process brought
in by the class/new stuff and specially how that clashes with the
'private final' mantra I've been chanting :-)

obvious observation is that the cyclic stuff will prevent us from doing any 'final' declaration on the pointer from 'new' to it's 'class'...

I found a solution that allows a true 'final' declaration!


Problem:
  If we create an instance of A before B exists, then when B is created
  it is too late to set the reference to B in the 'final' member of A.
  Of course there is no problem setting the reference to A in the 'final'
  member variable of B, because A already exists.  The cyclic problem is
  that there is no order in which to create A and B such that each can
  hold a 'final' reference to the other.
Solution:
  If we could split the timing of the creation of the object A or B from
  the initialization of the 'final' member variables the cyclic problem
  would vanish.  This can be done by initializing the 'final' member
  variable in a constructor.  Some sample code may make this clearer:

  class Sample {
      private final Sample child;
      public Sample(Builder builder, Sample child, String otherConfigData) {
          if (child != null) {
              this.child = child;
          } else {
              this.child = builder.getChild(this, "someChildId");
          }
          // Use otherConfigData to finish setting up object
      }
  }

class Builder {
public Sample build() {
// Because the value 'null' is passed in place of an
// actual child reference, we know that the constructor
// for this object will call this builder's getChild
// method. We will continue building from there.
Sample sample = new Sample(this, null, "Some config data");
}
public Sample getChild(Sample parent, String childId) {
// The parent object (think object A in the example)
// has been created by this point, but its constructor
// will not finish processing until this method returns
// the requested child reference.
// If we now happen to build object B, from the example,
// we have a reference to object A ready to pass as the
// child object parameter to the constructor that builds
// object B. After object B is built, this method can
// use a return statement to pass the reference to object
// B back to the constructor of the parent that requested
// it (object A). Problem solved, compiler happy :)
}
}
Application of this solution to the building of cyclic bindings and
definitions is trivial and is left as an exercise for the reader ;)


WDYT?

good idea, two observations though

1/ this would make the builders stateful, so we probably will need some different type of classes like 'prototype' or something (could be inner class of the builder).
Overall this pretty much resembles the copy-constructor idea, but by creating the prototype and it's derived into different classes you _can_ get everything final...



2/ but there is a more essential issue I think, 'order' of definition is only one thing (for that we could just do a DOM-search to look ahead in the definition file, remember?)
However, you spent quite some time explaining me that binding and definition graphs could get cyclic (ie no longer straight top-down trees) by using the 'union' (to be called: 'choice')


class (x) --> union --> new (x)
                   \--> other stuff...

in which case there really is a chicken and egg problem:

chicken class-x will wait to be constructed untill all it's children are known, as will sub-chicken 'union', so to relieve the 'we are all waiting each other' we need to be able to create the egg new-x in some 'dummy way' with a non-final ref to be filled-in later once class-x is actually done


--Tim Larson

<PS> Marc, I'm still mentally working through your responses and will
eventually give a point-by-point reply.  I'm not sure what my
timetable looks like right now, though.  As a quick note, neither

no pro, I'm quite busy myself...


"class" nor "new" currently wrap any namespacing around the widget
definitions that are retrieved from the class via "new".  That is:
  <wd:class id="asdf">
    <wd:widget id="qwerty"/>
  </wd:class>
  <wd:new id="asdf">
is functionally equivalent to:
  <wd:widget id="qwerty"/>
and *not* to:
  <wd:some-wrapper-widget-or-element id="asdf">
    <wd:widget id="qwerty"/>
  </wd:some-wrapper-widget-or-element>

(How) does this affect your proposals?


actually it kinda offers extra arguments to my reasoning:

1/ to me this sounds like the use of @id on new and class was fraudulous:
what I mean is: it is abusing that field in the implementation classes, but with utterly different semantics: not to be mapped onto actual request-parameter-names, but rather a type-def/type-ref mechanism


2/ the elements new and class are just decorating around whatever is inside them: so why not use attributes in stead, those are more suited for the decorating job... the actual elements in the wd:file then all map onto actual types, while two introduced attributes (I would propose @type-def and @type-ref would take over the define/reuse goal of 'class' and 'new')

so in your above example, the new equivalent syntax for
>   <wd:class id="asdf">
>     <wd:widget id="qwerty"/>
>   </wd:class>

would become
<wd:widget id="qwerty" type-def="asdf" />

if you need namespacing you would need the 'struct' (for which group would be a more sensible name indeed) concept...
if it needs to be reused or not is in a different dimension, and to be done by adding an optional type-def attribute:


<wd:struct id="group-name" type-def="asdf">
  ... his members here
</wd:struct>


on the reuse-side there is some extra argumentation for this approach by the introduction of the 'deriving'


if we don't do deriving then
- reuse can be with a generic wd:widget wrapper:
  <wd:widget type-ref="adsf"> (in stead of wd:new, so no big win)

if we do provide it, then
- the (see copy-constructor idea) define-reuse widgets will need to match so depending on the wd:TYPE that was used for the type-def, you would need a matching wd:TYPE for reuse, supposing you had a struct, and you want to derive to reuse and add a field:
<wd:struct type-ref="asdf>
.. more children here
</wd:struct>


hm, that last sample makes me think we should maybe change @type-ref to @type-base... but before getting in those details , we should allign on the concepts first...


so, wdyt? -marc=

</PS>

--Tim Larson


__________________________________ Do you Yahoo!? Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes http://hotjobs.sweepstakes.yahoo.com/signingbonus


--
Marc Portier                            http://outerthought.org/
Outerthought - Open Source, Java & XML Competence Support Center
Read my weblog at                http://blogs.cocoondev.org/mpo/
[EMAIL PROTECTED]                              [EMAIL PROTECTED]



Reply via email to