Re: Joe-E

"Steven R. Brandt" <[email protected]>
Newsgroups gmane.comp.lang.e.general
Message-ID <[email protected]>
After a little thought, I believe I have an acceptable solution for the 
problem. In case it is of use, here's what I did to implement a 
powerless list class:

public class PowerlessList<T> {
     private final Holder data;
     public final PowerlessList<T> tail;
     public final int size;

     @SuppressWarnings(value = "unchecked")
     public T getHead() { return (T)data.get(); }

     public PowerlessList() {
         tail = null;
         data = null;
         size = 0;
     }
     public PowerlessList(T data,PowerlessList<T> tail) {
         this.data = Holder.create(data);
         this.tail = tail;
         this.size = tail.size+1;
     }

     public PowerlessList<T> push(T data) {
         return new PowerlessList<T>(data,this);
     }

     public T get(int n) {
         PowerlessList<T> p = this;
         while(n > 0) {
             p = p.tail;
             n--;
         }
         return p.getHead();
     }
}

The key is the holder class. It is able to hold a String, Integer, etc. 
Essentially, it turns the check from a compile-time to a run-time check, 
and allows me to use either String or Powerless. Of course, the whole 
thing might die with a bad type error, so it's a trade-off.

import org.joe_e.Powerless;

public abstract class Holder implements Powerless {
     public abstract Object get();
     public static Holder create(final Object o) {
         if(o instanceof String) {
             final String s = (String)o;
             return new Holder() {
                 public Object get() {
                     return s;
                 }
             };
         } else if(o instanceof Powerless) {
             final Powerless p = (Powerless)o;
             return new Holder() {
                 public Object get() {
                     return p;
                 }
             };
         } else if(o instanceof Number) {
             final Number n = (Number)o;
             return new Holder() {
                 public Object get() {
                     return n;
                 }
             };
         } else if(o instanceof Boolean) {
             final Boolean b = (Boolean)o;
             return new Holder() {
                 public Object get() {
                     return b;
                 }
             };
         } else if(o instanceof Character) {
             final Character c = (Character)o;
             return new Holder() {
                 public Object get() {
                     return c;
                 }
             };
         }
         throw new Error("bad type");
     }
}

The basic problem, I think, is that Powerless is a marker interface. If 
it were an attribute instead, then I think things would be nicer. We 
could have a compile-time check, and we could eliminate the ugliness and 
inefficiency of the Holder solution I have used above.

@Powerless
public class Foo<T> {
     T t;
     Foo(T t) { this.t = t; }
     public static void main(String[] args) {
        Foo<String> foo = ...;
        Foo<NonPowerlessType> bar = ...; // Joe-E could flag this as an 
error
     }
}

Maybe you could consider this for a future version?

Cheers,
Steve

On 04/29/2010 02:52 AM, David Wagner wrote:
> Steven R. Brandt wrote:
>    
>> I'm trying to build a powerless container, PowerlessMap. I have gotten
>> to the point where I follow all the rules and everything compiles.
>>
>> However, Joe-E says that I have to declare the key and value of the map
>> to be powerless, i.e.
>>
>> public class PowerlessMap<K extends Powerless, V extends Powerless>  { ... }
>>
>> This means that I can't make a PowerlessMap<String,String>  as String
>> does not extends Powerless. I can make a holder for String that
>> extends Powerless, and I can use that--but that's very clunky. What
>> should I be doing?
>>      
> Thanks for trying out Joe-E, and sorry about the frustration!
>
> You don't include the full source of your PowerlessMap, but I can guess
> what the issue is.  I'm guessing your PowerlessMap class is declared to
> implement Powerless [1], and has a field whose declared type is K or V.
> The Joe-E static verifier insists that all fields of any class declared
> Powerless must themselves be Powerless as well (see the documentation
> for org.joe_e.Powerless), which is why you need to declare in the type
> signature that K and V extend Powerless.  That indeed leads to the
> consequence that you describe.
>
> I know of no good solution for this.  (Maybe Adrian or Tyler know
> something I've overlooking.)  What I mean is, I know of no good way
> to build a PowerlessMap that does what you want, in Joe-E code.
>
> We ran into the same issue when building array classes (ConstArray,
> ImmutableArray, PowerlessArray, etc.).  What we did there was to write
> trusted code, in Java, and add it to the Joe-E library.  The Joe-E library
> contains some trusted Java code we have written, which would not pass
> the Joe-E static verifier, but which was written and reviewed by us very
> carefully to ensure that it nonetheless is safe, opens no security holes,
> and complies with capability rules.  The Joe-E library is exempt from
> static verification.
>
> I suspect the best solution is going to be to do the same thing we
> did for ImmutableArray and PowerlessArray: write a trusted library in
> Java, review it very carefully, and include it in the Joe-E library.
> You'll have to spend some time poring over that code, as it's pretty
> tricky code.  (You'll notice that it uses reflection to dynamically
> check that all elements are of the expected type, rather than using
> the static type system; this is how a PowerlessArray can be used to
> store both user classes that are declared Powerless as well as
> library classes that are honorarily Powerless, like String.)
>
> Ideally, the goal is that Joe-E would provide a rich enough set of
> libraries that you never have to run into this problem in application
> code.  In practice, Joe-E is a research project and does not have as
> rich a set of libraries as we would like, so you may need to extend
> our libraries.  If you do, you might consider submitting your code for
> inclusion in the Joe-E system.
>
>
> Alternatively, if you're willing to use a mutable map, you could consider
> LinkedHashMap.
>
>
> P.S. One concern I can imagine you might have: I can imagine you might
> be concerned that if you can't express something simple like this
> in Joe-E, what good is it?  Is Joe-E too restrictive?  Well, I think
> that's a fair concern, though I think it may not be as bad as it seems
> at first.  I think collection classes are probably a special case:
> it's non-trivial to write collection classes that are genericized,
> enable code to take advantage of Joe-E's Immutable/Powerless/...
> marker interfaces to the maximum extent possible, and also handle
> honorarily Immutable/Powerless/... legacy classes (like String) well.
> However I'm not sure this issue will come up much in application code,
> once you have a good collection library.  At present, Joe-E's collection
> library is almost certainly overly minimalistic and insufficiently
> expressive; this seems like something that should be fixable with some
> engineering effort (but without fundamental changes to the language).
>
>
>
> Footnote 1: Did you mean the following type signature?
>
> public class PowerlessMap<K extends Powerless, V extends Powerless>  implements Powerless { ... }
> _______________________________________________
> e-lang mailing list
> [email protected]
> http://www.eros-os.org/mailman/listinfo/e-lang
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.