smalltalk-tng

view etng-r1/test3.tng @ 321:c4a0718c2d3c

Sketch of dependencies
author Tony Garnock-Jones <tonygarnockjones@gmail.com>
date Sat Oct 08 15:36:03 2011 -0400 (7 months ago)
parents 85a2a4f498cd
children
line source
1 ---------------------------------------------------------------------------
2 -- Alternative 4: first-class messages, in <angle brackets>. Not quite
3 -- objects, because sends (message object) reduce to (object message),
4 -- and obviously (object object) reduces normally, but (message message)
5 -- is an error."
7 -- Here, .foo has no protocol at all, not even the implicit visitor
8 -- protocol (.foo bar) --> (bar .foo) used earlier. Atoms are thus
9 -- totally inert - they're just simple tags with no behaviour. Messages,
10 -- on the other hand, have the meaning <x y z> --> {r -> r x y z} except
11 -- that the x,y,z is evaluated before being closed over - so more like
12 -- <x y z> --> let (x1,y1,z1) = (x,y,z); {r -> r x1 y1 z1}.
14 -- Hey, that's neat - <> is the identity object!
15 -- and <+ 2> is different from (2 +)...
17 -- Using <> in a pattern causes a visitor-probe to be sent to the object
18 -- being matched. Obviously, it has to be expecting such a probe, so
19 -- data objects (ie algebraic data type instances, as opposed to
20 -- functions or other kinds of receiver) should be coded with
21 -- visitor-DNU-behaviour,
23 -- {...; visitor -> visitor .thisIsWhatIam (someArg, otherArg)}
25 -- Note that the sends to the visitor must occur in tail position. (What
26 -- happens if they're not?)
28 -- A visitor-probe for the pattern <.foo bar> looks like
30 -- { .foo bar -> ...continuation of matching...;
31 -- _ -> ...backtrack to next clause... }
33 -- So the case below, {acc, <.s:empty> -> acc;
34 -- acc, <.s:next(f, r)> -> loop(fn(f, acc), r)},
35 -- 'expands' to a match tree like
36 -- - match tuple
37 -- - length 2
38 -- - element 0: accept any, bind to 'acc'
39 -- - element 1: visitor-probe {
40 -- .s:empty -> run continuation 'acc'
41 -- .s:next -> - match tuple
42 -- - length 2
43 -- - element 0: ...
45 -- What happens when there are two visitors in a tuple?
47 -- {<.s:empty>, <.s:empty> -> .bothEmpty;
48 -- _, <.s:empty> -> .secondEmpty;
49 -- <.s:empty>, _ -> .firstEmpty;
50 -- _, _ -> .neitherEmpty}
52 -- It basically needs to backtrack. It should sort the branches
53 -- appropriately before building the match tree:
55 -- {<.s:empty>, <.s:empty> -> .bothEmpty;
56 -- <.s:empty>, _ -> .firstEmpty;
57 -- _, <.s:empty> -> .secondEmpty;
58 -- _, _ -> .neitherEmpty}
60 -- (and I'm thinking of the more general case here, where you might fail
61 -- to match in the second element of the tuple, necessitating a
62 -- backtrack out of the match in the first element. Something like {(1,
63 -- 2) -> .a; (_, _) -> .b} when presented with (1, 3).)
65 namespace s = "http://eighty-twenty.org/etng/r1/ns/stream#";
66 define s:cons(f,r) = s:StreamOperations / <.s:next(f, r)>;
67 define s:nil = s:StreamOperations / <.s:empty>;
69 define s:StreamOperations = [
70 .s:foldl acc fn -> <(acc, self)> [acc, <.s:empty> -> acc;
71 acc, <.s:next(f, r)> -> self(fn(f, acc), r)];
72 .s:foldr acc fn -> <self> [<.s:empty> = acc;
73 <.s:next(f, r)> -> fn(f, self(r))];
74 .s:do fn -> <self> [<.s:empty> = .:ok;
75 <.s:next(f, r)> -> do fn(f); self(r)];
77 .s:inject -> self.s:foldl;
78 ];
80 [1, 2, 3].s:do println;
81 [1, 2, 3].s:inject 0 {acc, each -> acc + each}; -- 6
82 [1, 2, 3].s:inject 0 (binop +) -- 6
83 [1, 2, 3].s:map (1 +) -- [2, 3, 4]
84 [1, 2, 3].s:map <+ 2> -- [3, 4, 5]
85 [1, 2, 3].s:map .:negated -- an error
86 [1, 2, 3].s:map <.:negated> -- [-1, -2, -3]
88 -- [a, b, c] is shorthand for stream:cons(a, stream:cons(b, stream:cons(c, stream:nil)))
89 -- [a, b | c] is shorthand for stream:cons(a, stream:cons(b, c))
90 -- [| c] is thus 'shorthand' (longhand??) for c
91 -- [a, b, c | ] is equivalent to [a, b, c]
92 -- thus [|] is the empty stream, stream:nil
93 -- When used in patterns, these shorthands are expanded into appropriate visitors.
94 -- Reserving '|' in this way gives us a nice hook for stream comprehensions later on.
95 [ x || x <- [1, 2, 3, 4], x.number:isEven ]
97 java:set myObj.field (newValue);
98 myObj.field;
99 myObj.method(argument);
101 -- Is it a good idea to treat everything as a tuple, with most values
102 -- being tuples of length 1?
104 -- Simultaneous binding: pat#pat