2 summary:: referentially transparent proxy object
3 categories:: Libraries>JITLib>Environments
4 related:: Classes/Fdef, Overviews/JITLib
7 A Maybe object can contain either nil or some other object, and allows to construct calculations without knowing this other object yet. If the calculation fails, due to a loop or a not yet defined object, Maybe returns nil.
9 The name strong::Maybe:: stems from the programming language Haskell, where it represents a somewhat similar entity. See also: link::Classes/Fdef::
29 return or set the contained object
32 set the contained object or return the source, or the value of the contained object, if it is a Maybe. If there is a recursion, return nil.
35 return the value, or the value of the contained object, if it is a Maybe. This method allows recursion, so that recursive calcualtions can be made.
37 method::doesNotUnderstand
38 (called by any message that Maybe doesn't understand.)
40 returns a composition function that, when evaluated, returns the value.
43 a.respondsTo(\flop) // false: Maybe constructs a placeholder instead
46 a.value = [1, 2, [2, 3]];
47 b.value; // => [ [ 1, 2, 2 ], [ 1, 2, 3 ] ]
53 // the following examples use a LazyEnvir with a Maybe as a proxy class.
54 // instead of writing a = Maybe.new; a.value = something;
55 // one can simply write ~a = something.
56 // the Maybe is implictly created for you.
62 p.linkDoc; // here: connect to current doc only.
69 ~c = ~a union: ~b; // union of the two sets (note that the shortcut | does not work here.).
70 ~d = ~a sect: ~b; // intersection of a and b
71 ~c.postcs;""; // post the whole construction
73 ~c.value; // Set[ 4, 0, 5, 7 ]
74 ~d.value; // Set[ 4, 5 ]
75 ~b = Set[4, 5, 13, 0];
77 ~d.value; // Set[ 4, 0, 5 ]
78 ~b.source.add(~w); // add another placeholder
79 ~c.value; // it is part of the union.
80 ~d.value; // but not part of the intersection
86 ~c = ~a.putAll(~b) // provisionally put everything into the placholder
88 ~a = (note: [1, 2, 4]);
97 ~b = Pseq([5, ~a, ~a + 10], inf);
98 ~b.value.asStream.nextN(10);
101 ~a = Prand([100, 200]);
102 ~b.value.asStream.nextN(10);
107 //////////////// deep recursion
109 // with normal functions:
110 f = { |x| if(x <= 1) { 1 } { x * f.(x - 1) } };
114 ~faculty = { |x| if(x == 1) { 1 } { x * ~faculty.(x - 1) } };
115 ~faculty.(12) // doesn't work (=> nil). here we _do_ want recursion ...
117 // for explicit recursion use "apply"
118 ~faculty = { |x| if(x == 1) { 1 } { x * ~faculty.apply(x - 1) } };
121 /*// safety (not yet implemented)
122 Maybe.maxDepth = 1e2; // higher depth is risky..
123 ~faculty = { |x| x * ~faculty.apply(x - 1) }; // infinite recursion
126 Maybe.maxDepth = nil; // unsafe again.*/
129 //////////////// recursion prevention tests
151 // function evaluation and argument passing
156 ~a.value(~c); // => nil
158 ~a.value(~b); // => 2002
161 (~a + 1).value(~b); // 2003
162 (~a + 1).value(~x); // [ 603, 1003 ]
163 (~a + 1).value({ 8 }); // binary op func.
164 (~a + 1).value({ 5 + 3 }).value // 11
166 ~a = { |x| x + 2 + ~b };
170 ~a = { |x| x + 2 + ~c }; // ~c is undefined.
171 ~a.value(8); // => nil
173 ~c = 100; // define ~c
175 ~a.value(8); // now returns a value.
177 ~c = ~b; // now recursion?
179 ~a.value(8); // caught recursion => nil
181 ~c = { 100.rand }; // ~c is a function
187 ~a.value(8); // ~c is a recursion with ~a => nil
190 // function composition
192 ~v = ~a <> ~a <> ~a; // same as: { ~a.(~a.(~a)) }
196 ~v.value(0); // transparent. => 6
198 // {|x| x }.valueEnvir // doesn't work with current implementation of Function:valueEnvir
201 // calculations with functions:
203 ~a = { |ff| { ff = ff + 1; ~c + ff + 2 + ~c } };
205 ~x.value; // return 11, 12, 13...
209 ~x.value; // return 214, 215 ...
212 // binary op functions:
214 ~a = { |ff| { [600, 800] } + { ff + 2 + ~c } };
217 ~x.value; // return [ 610, 810 ]
219 ~c = { [10, -10].rand };
220 ~x.value; // return random between [ 610..620, 800..810 ]