smalltalk-tng
view r3/test-new-syntax.tng @ 323:454c18798969
merger
| author | Tony Garnock-Jones <tonygarnockjones@gmail.com> |
|---|---|
| date | Tue Feb 07 11:34:20 2012 -0500 (3 months ago) |
| parents | 57613e42d98d |
| children |
line source
1 "Basic idea: all symbols are really variables. They're bound to their
2 underpinning GUID objects. Quoting isn't needed to get literals - it's
3 just convention. Identifiers are not symbols."
5 define map [
6 (_ +f): [(+lp [Hd: +h Tl: +t]) : [Hd: f h Tl: lp t]
7 (+lp x) : x]
8 ];;
10 define map [
11 \+f: [(+lp [First: +h Rest: +t] : [First: f h Tl: lp t])
12 \+x: x]]
14 [(_ +x): x]
15 [\+x: x]
16 \+x: x
17 [\+x: x-1]
18 \Nil: Nil
19 [Hd: +h Tl: +t]:[Hd: f h Tl: map f t]
21 let diff r1 r2 =
22 let collect [First: +fieldName Rest: +rest] diffs =
23 let v1 = r1 At: fieldName IfAbsent: Absent,
24 v2 = r2 At: fieldName IfAbsent: Absent,
25 collect1 +type +old +new =
26 collect rest [First: [fieldName, type, old, new] Rest: diffs]
27 in cond ((v1 == v2) -> collect rest differences,
28 (v1 == Absent) -> collect1 Added [] v2,
29 (v2 == Absent) -> collect1 Removed v1 [],
30 True -> collect1 Changed v1 v2)
31 collect [] +diffs = diffs
32 in
33 (r1 Class == r2 Class) && collect (r1 Class FieldNames) []
34 ;;
36 let diff r1 r2 =
37 (r1 Class == r2 Class) &&
38 filterMap [\+fieldName:
39 let v1 = r1 At: fieldName IfAbsent: Absent,
40 v2 = r2 At: fieldName IfAbsent: Absent
41 in cond [(v1 == v2) -> Nothing,
42 (v1 == Absent) -> [Just: [fieldName, Added, [], v2]]
43 (v2 == Absent) -> [Just: [fieldName, Removed, v1, []]],
44 True -> [Just: [fieldName, Changed, v1, v2]]]]
45 (r1 Class FieldNames);;
47 "
48 let +a +b = c in d ...
49 -->
50 [\+a: d ...] [(+a +b): c]
52 let +v = w in x ...
53 -->
54 [\+v: x ...] w
55 "
57 let +diff +r1 +r2 = (r1 Class == r2 Class) &&
58 filterMap [\+fieldName:
59 let +v1 = r1 At: fieldName IfAbsent: Absent,
60 +v2 = r2 At: fieldName IfAbsent: Absent
61 in cond [(v1 == v2) -> Nothing,
62 (v1 == Absent) -> [Just: [fieldName, Added, [], v2]]
63 (v2 == Absent) -> [Just: [fieldName, Removed, v1, []]],
64 True -> [Just: [fieldName, Changed, v1, v2]]]]
65 (r1 Class FieldNames)
66 ;;
68 let filterMap +fn = [
69 (+loop [First: +f Rest: +r]): maybe (loop r) id (fn f)
70 (+loop x): x
71 ];;
73 "
74 Major changes:
75 - identifiers evaluate to the symbol with the same spelling when otherwise unbound
76 - order matters in subsequent pattern clauses. Why did I have it the other way?
77 --> for optional keyword arguments, I think.
78 - you can have expressions in patterns, too. This includes identifier references.
79 What kind of scoping should apply?
80 - since you can have naked identifiers as variable references in patterns, you need
81 some way of introducing a binding occurrence of an identifier. This is, tentatively,
82 spelled +var.
83 - Traits. +, /, @, -
84 - letrec is primitive, since this is a lazy language
86 {} is underused. Could it be used for monad, or letrec syntax?
88 Should we autocurry? (Probably.)
90 _ in value-context means 'top' - ie something that doesn't match
91 anything else. _ in binding-context means 'discard'/'bottom' -
92 something that matches anything. Actually that's not quite right. You
93 can still see _ as equivalent to [], since if it's supplied as a
94 value, the only pattern that matches it is [] - and [] as a pattern
95 matches any object.
97 Since . is free now, perhaps use it for apply operator? What should
98 its precedence and associativity be?
100 "
103 (define (+diff +r1 +r2)
104 (let ((+collect ((First: +fieldName Rest: +rest):
105 (+diffs:
106 (let ((+v1 (r1 At: fieldName IfAbsent: Absent))
107 (+v2 (r2 At: fieldName IfAbsent: Absent))
108 (+collect1 ((+type +old +new):
109 (collect rest ([fieldName type old new] :: diffs)))))
110 (cond
111 ((v1 == v2) collect rest differences)
112 ((v1 == Absent) collect1 Added () v2)
113 ((v2 == Absent) collect1 Removed v1 ())
114 (else collect1 Changed v1 v2))))
115 (): (+diffs: diffs))))
116 ((r1 Class == r2 Class) && collect (r1 Class FieldNames) ())))
118 (define (+diff +r1 +r2)
119 ((r1 Class == r2 Class) &&
120 (filterMap (+fieldName:
121 (let ((+v1 (r1 At: fieldName IfAbsent: Absent))
122 (+v2 (r2 At: fieldName IfAbsent: Absent)))
123 (cond
124 ((v1 == v2) Nothing)
125 ((v1 == Absent) Just: [fieldName Added () v2])
126 ((v2 == Absent) Just: [fieldName Removed v1 ()])
127 (else Just: [fieldName Changed v1 v2]))))
128 (r1 Class FieldNames))))
130 (define (+filterMap +fn)
131 ((First: +f Rest: +r): maybe (self r) (+v: v :: self r) id (fn f)
132 +x: x))
134 "
135 ThiNG-expressions should be constructed like S-expressions: right-associatively.
136 Adjacency and dot, just like sexps, should be equivalent to the reader.
137 "
139 {} Length == 0
140 {1} Length == 1
143 define [diff .r1 .r2]:
144 ((r1 Class == r2 Class) &&
145 filterMap [[_ .fieldName]:
146 (.v1 <- r1 At: fieldName IfAbsent: Absent,
147 .v2 <- r2 At: fieldName IfAbsent: Absent,
148 cond [(v1 == v2) -> Nothing,
149 (v1 == Absent) -> Just: [fieldName, Added, [], v2],
150 (v2 == Absent) -> Just: [fieldName, Removed, v1, []],
151 True -> Just: [fieldName, Changed, v1, v2]])]
152 (r1 Class FieldNames)
153 ;;
155 define diff [[_ r1@_ r2@_]:
156 ((r1 Class == r2 Class) &&
157 filterMap [[_ fieldName@_]:
158 v1@_ <- r1 At: fieldName IfAbsent: Absent,
159 v2@_ <- r2 At: fieldName IfAbsent: Absent,
160 cond [(v1 == v2) -> Nothing,
161 (v1 == Absent) -> Just: [fieldName, Added, [], v2],
162 (v
164 let +diff +r1 +r2 = (r1 Class == r2 Class) &&
165 filterMap [\+fieldName:
166 let +v1 = r1 At: fieldName IfAbsent: Absent,
167 +v2 = r2 At: fieldName IfAbsent: Absent
168 in cond [(v1 == v2) -> Nothing,
169 (v1 == Absent) -> [Just: [fieldName, Added, [], v2]]
170 (v2 == Absent) -> [Just: [fieldName, Removed, v1, []]],
171 True -> [Just: [fieldName, Changed, v1, v2]]]]
172 (r1 Class FieldNames)
173 ;;
