[cap-talk] Last Call for ref_send API 1.0

Tyler Close tyler.close at gmail.com
Tue Apr 3 22:49:48 CDT 2007


Hi David,

Thank you for the continued effort. I really appreciate it.

Responses inline below.

On 4/2/07, David Wagner <daw at cs.berkeley.edu> wrote:
> ... or because they only affect the
> org.joe_e* libraries, so they may not be important now, but I wanted
> to write them down while they were fresh in my mind.

We should identify the org.joe_e.* interfaces that Adrian is unwilling
to let people depend on and I'll remove them from the ref_send 1.0
distribution. I'ld like to put together a distribution that people can
start coding to without worrying that the rug will be pulled out from
under them.

I think the barest minimum ref_send requires is org.joe.*,
org.joe_e.reflection.Reflection.{allowed, invoke, peel, proxy}

The next piece of the Waterken Server I'll have ready for distribution
is the HTTP client/server implementation. This code further depends on
org.joe_e.file.* and org.joe_e.charset.*.

After that, the remoting library depends on the rest of the Joe-E API.

I put these APIs under org.joe_e since they can't be implemented by
Joe-E code, but are dependencies of Joe-E code. I suppose I could also
create my own trusted Java library to hold these APIs, rather than
bundle them all in org.joe_e. Is that preferable?

> org.ref_send:
>
> Record: The Javadoc calls this "A pass-by-construction object.", but
> I think you mean "An allegedly pass-by-construction object." -- is that
> correct?  (Nothing enforces that this Record instances are indeed
> pass-by-construction; it's up to the programmer to manually respect
> the semantics of pass-by-construction objects.  Recipients of a Record
> object should not rely upon it to be pass-by-construction.)
>
> @cacheable: Do you mean "an allegedly cacheable property"?

The above statements are correct, but they're also correct for all
interfaces that are not the special org.joe_e.* verified interfaces.
Do we want to adopt the "allegedly" convention when documenting all
Joe-E interfaces?

> org.ref_send.promise:
>
> Given the comments in Var's Javadoc, would it be useful to provide
> a class that acts as a sensory facet to a Var (or other mutable Volatile)
> that only provides authority to read the Volatile?  Something like:
>
>     public final class VolatileFacet<T> implements Volatile<T> {
>         private final Volatile ref;
>         public VolatileFacet(T value) { ref = value; }
>         public T cast() { return ref.cast(); }
>     }
>
> Then the suspect code mentioned in Var's Javadoc could be conveniently
> re-written as follows, if the intent was to provide only read-only access
> to the balance:
>
>     public Volatile<Integer> getBalance() {
>         return new VolatileFacet(balance);
>     }
>
> I don't know if "VolatileFacet" is the best name.  Of course, adding
> such a class is a backwards-compatible change, so doesn't need to be
> done now.

I thought about doing something like the above but decided to put it
off until later since I don't have any code that needs such a facet
and, as you say, it's something that can be added without breaking
compatibility. Procrastination has served me well in the past, so I'm
going to stick to that plan.

> Resolved: The Javadoc for ref() doesn't say whether the caller can rely
> upon the return value to be a trustworthy Resolved promise that resolves
> to "value" (the argument to ref()).

Good catch. I'll update the Javadoc to indicate the returned promise
can be relied upon.

> I have no idea what detach() is doing, so it is hard for me to know
> whether this is the best name.  At a minimum, it needs to be documented
> better.  (For instance, how does it differ from ref()?)  Do I get to
> reserve the right to gripe about detach()'s name once I understand what
> it is doing? :-)

The detach() method is closely related to the List implementation you
ask about further down. The detach() method provides a hook that the
orthogonal persistence implementation picks up on. detach() returns a
promise that defers deserialization of the target object until the
cast() method of the promise is called. Applications use this method
to break up a large object graph so that only the parts needed for the
current operation get deserialized. For example, the List
implementation stores each element in the list in a detach()'ed
promise. As a result, you can pop() the first element of a list
without loading the whole list into memory.

> Eventual: The Javadoc at the top is very, very nice.

Thanks, though MarkM deserves a good deal of the credit here. This
text is basically just a rework of a passage from his dissertation.

> I don't understand what ready() is doing, or what is meant by
> "the underlying reference implementation".  What is a "reference
> implementation"?  Does it mean some sample implementation that the
> ref-send library provides?

Yes. An eventual reference is just a Java proxy wrapped around one of
the reference implementations documented in org.ref_send.promise. To
register a when block on the reference, you need to peel off the Java
proxy to get at the underlying reference implementation. The ready()
method implements this peeling. The return is guaranteed to be
anything. I named this method "ready" so that the line:

    x = foo_.bar();
    _.when(ready(x), new Do...

would read as "when x is ready, do ...", meaning when the bar()
invocation has been completed, do the following on its return value.
I'll try to come up with better Javadoc for this method.

> I didn't understand the Javadoc for cast(), what cast() is doing,
> what the purpose of the "expected" argument is for, or what proxy
> the Javadoc is referring to.  Would more explanation help?  Would an
> example help?

Hmmm... I'll take another crack at the Javadoc for this. cast()
creates an eventual reference given the type to implement and the
reference implementation.

> The documentation should probably specify what is meant by an
> "allowed proxy type", or link/refer to the appropriate specification
> in the Java class library documentation.

It does link to the specification. It links to
org.joe_e.reflection.Reflection.allowed.

> org.ref_send.promise.eventual.Loop: Ok, I admit I may not know how
> to parse Java generics correctly.  Does the name "Task", in the defn
> of the Loop interface, refer to a generic type parameter, or does it
> refer to org.ref_send.promise.Task?  I'm guessing it is the former.
> If so, that is incredibly confusing.  Standard Java convention is to use
> one-letter capital letters for generic type parameters.  It's even worse
> to make the name of a generic type parameter be the same as the name of
> a public class/interface defined elsewhere in your API.  I suggest that
> you change the defn of Loop to either
>
>     public interface
>     Loop<T extends Closure<Void,?>> extends Closure<T,Void> {
>         Void post(T closure);
>     }
>
> or to
>
>     import org.ref_send.promise.Task;
>
>     public interface
>     Loop extends Closure<Task,Void> {
>         Void post(Task task);
>     }
>
> according to your intent.  I'm guessing you intended the former, so the
> change should be backwards-compatible, but please check for yourself.

You correctly guessed my intent. I left this potential confusion in
there because either way of reading it is perfectly fine. If you think
you can only pass in a org.ref_send.promise.Task, that's fine. I was
thinking that the first definition you propose above could leave
someone who doesn't understand generics at a loss for what kind of
argument they are supposed to provide. The extends syntax is sort of
an advanced feature of Java generics. The current definition at least
suggests something that will work. It's only confusing to someone who
knows a fair bit about Java generics, and they can likely cope, as you
did.

> org.joe_e.Keeper: The name "Keeper" doesn't mean anything to me.
> It sounds like a generic concept, but org.joe_e.Keeper is used for a
> very narrow purpose.  It would be a shame to take up a name that might
> profitably be better used for something else, and it might be nice if
> the name here was more evocative.  How about "ErrorHandler"?

The name "Keeper" comes from either Dean or Norm I think. One of them
created this pattern of having a central piece of code that gets first
shot at handling errors. The name we use here is not so important
since it's not something application writers will interact with. The
interface only gets used by infrastructure code like the Waterken
Server. I'll defer to Adrian for naming this interface.

> org.joe_e.crypto.AES: Out of curiousity, why does this need to be in
> the org.joe_e namespace?  Is AES something that pure Joe-E code cannot
> implement?  Or is this an optimized implementation that uses native
> methods or something?

If you've got a pure Joe-E implementation of AES, I'll gladly use it
and deprecate this API. Otherwise, I need this API to safely wrap the
javax.crypto implementation.

> org.joe_e.file.Filesystem:
>
> list() shouldn't throw NullPointerException when the argument isn't a
> directory.  Use some other exception.  Only throw NullPointerException
> when the argument is null.  I guess this is not a backwards-compatible
> change, so it needs to be done now.

OK.

> name() should document that the "child" argument must be a single
> filename component, not a relative path.  For instance, "../foo" or
> "foo/bar" are right out.

OK.

> vet() should document whether it is intended to be applied to a single
> filename component, a relative path, and/or an absolute path.  Also,
> I couldn't extract what the second sentence in the Javadoc for vet()
> is trying to convey, though I suspect it is related.

Yup, that second sentence was trying to convey exactly what you want
it to convey. I'll change it to use the phrasing you use above.

> org.joe_e.reflection.Reflection: I have reservations about the semantics
> of some of the methods.  I feel like it would be beneficial to have
> more discussion before it is ready to be inserted into a Joe-E library
> which Joe-E promises to support forever.  Your choices may be fine for
> users of ref-send, but for what goes into Joe-E libraries, I think the
> question has to be about what is right for all Joe-E users.

Well, obviously it's my belief that this API will work well for all Joe-E users.

We could delay dealing with this issue for another few weeks, until I
finish making the bug fixes to the remoting library. For the ref_send
1.0 release, I only need the methods listed at the start of this
email. Are you fine with those?

> org.ref_send.list.List: I'm curious about why you named the method
> "getSize()" rather than "size()", as the latter seems to be the standard
> name used by the Java collections classes.

Bah, breaking their own naming conventions. They defined the getter
convention, and I follow it in the remoting library to determine what
methods should be invoked with a GET vs a POST. getSize() should be a
GET.

>  Have you considered making
> this implement java.util.List?

No. Disaster of an API.

>  I suspect you have and decided it was
> overkill.  Also, remind me some day to ask you why you added this class
> rather than, say, java.util.LinkedList.

Discussed earlier in this email.

> org.ref_send.promise.{curry,test}.*: I didn't look at any of this.
> (I got tired.)

Thanks for all the work.

Tyler

-- 
The web-calculus is the union of REST and capability-based security:
http://www.waterken.com/dev/Web/

Name your trusted sites to distinguish them from phishing sites.
https://addons.mozilla.org/firefox/957/


More information about the cap-talk mailing list