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