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
[email protected]
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/felix-language