Ok,  I have a new interface for comment now.
There is an important tutorial lesson here so please read carefully.
Seem that "abstract types" are not documented so please read!

///////
open class Future
{

  private interface future_private_t[T] { 
    doget: 1 -> T;
    fetched: 1 -> bool;
    fetch: 1 -> 0;
  }

  type future_t[T] = new future_private_t[T];

  private object future_impl[T] (e:1->T) implements future_private_t[T] = {
    var ch = mk_schannel[T]();
    spawn_fthread { write (ch,#e); };
    var x:T;
    var flag = false;
    method fun fetched() => flag;
    method proc fetch() {
      x = read ch;
      flag = true;
    }
    method fun doget() => x;
  };

  ctor[T] future_t[T] (e:1->T) => _make_future_t (future_impl e);
  fun future[T] (e:1->T) => future_t e;
 
  inline gen get[T](fut:future_t[T]):T = { 
    if not #((_repr_ fut).fetched) call (_repr_ fut).fetch; 
    return #((_repr_ fut).doget); 
  }

  fun apply[T] (x:future_t[T], a:unit) => get x;
}

var x = future { 42 };
println$ x.get;

// More nasty test.

var ch = mk_schannel[int]();
var y = future { var k = read ch; return k; };
spawn_fthread { write (ch, 77); };
println$ y.get;

println$ #x, #y;

//#(x.fetch); // fails ..
/////////////////


The last line is there to check you cannot access the private methods
of a future. Simply making the interface private DOES NOT WORK.
This prevents you naming the type, it does not prevent you using type.
In particular an interface is a record type, and you can access the
components of that type with projection functions. 

In fact record type CANNOT be made private no matter what,
because they're structural types: only nominal types can be private.
[Obviously! Its the name you make private!]

The workaround I have used here i to use an abstract type.
This is created by

        type abstract = new concrete;

Within the class containing this definition, you can convert from
abstract to concrete with the _repr_ operator, and from concrete
to abstract with the _make_abstract operator (the type name
prefixed by _make_). 

These operators do nothing, they're compile time only privacy conversions. 
They're only available for the abstract type in the class that defines it. 
Outside the class you cannot use _repr_ or _make_.

This facility does not deny access to the concrete type, it simply
prevents converting between the concrete and abstract types
with the _repr_ and _make_ operators. If the concrete type
is a nominal type, and it is private, then encapsulation is assured.

In this example, that isn't the case. The name of the interface type
is private but it's just a name. So it is possible to break the abstraction.

This could be prevented by wrapping the record type in a struct,
though I'm not sure its worth the effort.

It make be fun to add some syntax:

        future x = { 42 }; // var x = future { 42 };

or even 

        future x { .... }

the latter of which makes it look like a new kind of function.
The down side of that is that it hides the fact a future is an ordinary
value that can be passed around, and in particular you can put one
in a var or a val (your choice). Or you can use one anonymously.

Finally note, I see no reason for the future function, just change
the type to future instead of future_t and the constructor should
suffice.

BTW: I have still to put in the "NULL out the schannel" bit.


--
john skaller
skal...@users.sourceforge.net
http://felix-lang.org




------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to