smalltalk-tng
view r3/experiment.tng @ 323:454c18798969
merger
| author | Tony Garnock-Jones <tonygarnockjones@gmail.com> |
|---|---|
| date | Tue Feb 07 11:34:20 2012 -0500 (3 months ago) |
| parents | |
| children |
line source
1 "How does one *undefine* a bunch of behaviour?
2 One possibility: delegate to the empty object, causing a DNU"
4 define [
5 #map -> [(map f) -> [#nil -> #nil
6 [#hd -> x #tl -> xs] -> [#hd -> (f x) #tl -> (map f xs)]]]
8 map: [(map f) -> [nil: #nil
9 [hd: x tl: xs] -> [hd: (f x) tl: (map f xs)]]]
11 (#map f) -> [#nil -> #nil
12 [hd: x tl: xs] -> [hd: (f x) tl: (#map f xs)]]
14 (map f #nil) -> #nil
15 (map f [hd: x tl: xs]) -> [hd: (f x) tl: (#map f xs)]
17 "The thing at the head of these messages is bound to 0 - so (msg 0) is 'self'"
18 (#nil map: f) -> #nil
19 ([hd: x tl: xs] map: f) -> [hd: f x tl: (xs map: f)]
21 (#nil #map -> f) -> #nil
22 ([#hd -> x #tl -> xs] #map -> f) -> [#hd -> f x #tl -> (xs #map -> f)]
24 (#nil #map->f) -> #nil
25 ([#hd->x #tl->xs] #map->f) -> [#hd -> f x #tl -> (xs #map->f)]
27 (#nil #map f) -> #nil
28 ([#hd: x #tl: xs] #map f) -> [#hd: f x #tl: (xs #map f)]
30 "Dot is quote"
31 (.nil.map f): .nil
32 ([.hd: x .tl: xs].map f): [.hd: f x .tl: xs.map f]
34 "Problem: x .map f - the .map is a generic-send, the f is a specific-send"
35 "Specific-send is going to be rare, perhaps?"
36 "Syntax for it? x .map @ f"
38 "Alternative is to require messages to be bound, to either a generic-function
39 or a regular lambda"
41 "Another alternative is to rearrange the order of arguments"
42 "(The implicit receiver is the /subject/)"
43 (.map f .nil): .nil
44 (.map f [.hd: x .tl: xs]): [.hd: f x .tl: map f xs]
46 "Desugared, the above reads:"
47 .map: [f: [.nil: .nil
48 [.hd: x .tl: xs]: [.hd f x .tl: map f xs]]]
50 "Yet another option is to make it a head-n-ary message (with the '0' argument)"
51 (.nil .map: f): .nil
52 ([.hd: x .tl: xs] .map: f): [.hd: f x .tl: (xs.map: f)]
54 "Desugared:"
55 (0: .nil .map: f): .nil
56 (0: [.hd: x .tl: xs] .map: f): [.hd f x .tl: (xs.map: f)]
58 "So far, so good. What about, for the sugared/curried form, lifting the quote-requirement
59 on the function operator position?"
60 (map f .nil): .nil
61 (map f [.hd: x .tl: xs]): [.hd: f x .tl: map f xs]
62 "No good: if we want to be able to curry regular functions, we'll need some way
63 of matching literals in LHS pos. This drop-the-quote-requirement only works
64 for the global context object."
65 ];;
67 (arg.hd)
68 (arg.tl)
70 "a pattern:" [(a b): _]
71 "-->" (arg (a b))
73 define fold-left [
74 kons: [knil: [.nil : knil
75 [.hd: h .tl: t] : (fold-left kons (kons h knil) t)]]
76 ];;
78 define fold-left [
79 kons: [lp knil: [.nil: knil
80 [.hd: h .tl: t]: lp (kons h knil) t]]
81 ];;
83 "Using the Curry sugar"
84 define (fold-left kons) [lp
85 (knil .nil): knil
86 (knil [.hd: h .tl: t]): lp (kons h knil) t
87 ];;
89 "Variant"
90 define fold-left [
91 kons: [lp (knil .nil): knil
92 (knil [.hd: h .tl: t]): lp (kons h knil) t]
93 ];;
95 map [x: x + 1] ([1, 2, 3] asList);;
97 "Oo! You can use the named-self syntax to get hold of the context!"
98 "Er, degenerate cases notwithstanding"
99 let [here] in ...
101 "DAMN letrec is a problem piece of syntax"
102 letrec: [(.map f .nil): .nil
103 (.map f [.hd: h .tl: t]): [.hd: f h .tl: map f t]
104 .toList: [[]: .nil
105 [h ; t]: [.hd: h .tl: toList t]]] "yikes"
106 in: map [x: x] (toList [1 2 3])
107 ;;
109 map [x: x + 1] (toList [1 2 3]);;
111 "To lift something:" {lifted} <- val
112 "To drop something:" val <- {lifted}
114 "iota"
115 define (..) [
116 start: [.inf+: [loop x: [.first: x .rest: loop (x + 1)]] start
117 .inf-: [loop x: [.first: x .rest: loop (x - 1)]] start
118 end: (let op = (.if: start > end .then: (+) .else: (-)),
119 [loop x: (.if: x = end
120 .then: .end
121 .else: [.first: x .rest: loop (op x 1)])] start)]
122 ];;
124 "What if, for messages sent implicitly to the context, we allow quoteless
125 literals, to get simpler-looking selectors?"
126 define (..) [
127 start: [.inf+: [loop x: [.first: x .rest: loop (x + 1)]] start
128 .inf-: [loop x: [.first: x .rest: loop (x - 1)]] start
129 end: (let op = (if: start > end then: (+) else: (-)),
130 [loop x: (if: x = end
131 then: .end
132 else: [.first: x .rest: loop (op x 1)])] start)]
133 ];;
135 "Now, Smalltalk-style conditionals, using head-n-ary syntax:"
136 define (..) [
137 start: [.inf+: [loop x: [.first: x .rest: loop (x + 1)]] start
138 .inf-: [loop x: [.first: x .rest: loop (x - 1)]] start
139 end: (let op = (start > end ifTrue: (+) ifFalse: (-)),
140 [loop x: (x = end
141 ifTrue: .end
142 ifFalse: [.first: x .rest: loop (op x 1)])] start)]
143 ];;
145 "Curried: doesn't quite work because of the need to quote the operator"
146 define [
147 (start .. .inf+): [loop x: [.first: x .rest: loop (x + 1)]] start
148 (start .. .inf-): [loop x: [.first: x .rest: loop (x - 1)]] start
149 (start .. end): (let op = (start > end ifTrue: (+) ifFalse: (-)),
150 [loop x: (x = end
151 ifTrue: .end
152 ifFalse: [.first: x .rest: loop (op x 1)])] start)
153 ];;
155 define ($) [f: f];;
156 "
157 f $ a
158 --> ($) f a
159 --> f a
160 "
163 "
164 let pat = val,
165 body
166 -->
167 [pat: body] val
169 ... which makes the scoping clear. (It's like let in scheme.)
171 letrec pat = val,
172 body
173 -->
174 well nothing really. It has to be primitive?
175 What about trying a named-let variant?
177 let loop (x = start): [.first: x .rest: loop (x + 1)]
179 Yuck.
180 "
