smalltalk-tng
view r3/SyntaxNotes @ 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 | 604988e365e5 |
| children |
line source
1 -*- outline -*-
3 * Basics, Revised Yet Again
5 The question is how to deal with currying, and reconciling the
6 difference between send syntax and pattern-match syntax. A chain of sends might
7 look like any of:
9 r1 Class FieldNames
10 r1 IfTrue: v1 IfFalse: v2
11 dict Lookup: key [IfPresent: .v]: v IfAbsent: 123
12 v1 == v2
13 v1, v2, v3
15 A method clause:
16 .m@[.self Lookup: .aKey]: ((self HasKey: aKey) IfTrue: (m IfPresent: (self At: aKey)) IfFalse: (m IfAbsent))
18 The other problem is centralised dispatch (by the interpreter and
19 current context) vs. distinguished-receiver ST80-style dispatch.
21 I guess it comes down to the shape of messages constructed by dispatch
22 syntax. With a central dispatcher, we get
24 [0: [0: r1 1: Class] 1: FieldNames]
25 [0: r1 IfTrue: v1 IfFalse: v2]
26 [0: dict Lookup: key [IfPresent: .v]: v IfAbsent: 123]
27 [0: [0: (==) 1: v1] 1: v2]
28 [0: v1 1: v2 2: v3 Length: 3]
30 Corresponding patterns could be
32 [.self Class]: ...
33 [.self FieldNames]: ...
35 Hmm, essentially, when a pattern fails to match, it calls resend! So
36 if we had a high-priority pattern [.self Class FieldNames] matching
37 against [foo Class SomethingElse] we''d see the [foo Class] match the
38 [.self Class], resulting in [[_ FieldNames]: ... _: resend] or
39 similar. This, when sent [(itself) SomethingElse], would backtrack to
40 matching against some other receiver for [.self Class], if any.
42 [.self IfTrue: .vt IfFalse: .vf]
43 [.self Lookup: .aKey]
45 "This next one is tricky:"
46 m@[.self Lookup: .aKey [IfPresent: _]: _ IfAbsent: _]
47 "Note in the above that the first _ is a value, ie. top!"
48 "(rather than a pattern ie. bottom)"
50 [.val == .other]
51 [.v1, .v2, .v3]
53 Perhaps remove (,,) syntax? Maybe it could be sugar for list/stream
54 construction? For instance:
56 (v1, v2, v3) ==> (v1 . (v2 . (v3 . Nil)))
57 [.v1, .v2, .v3] ==> [.v1 . [.v2 . [.v3 . Nil]]]
58 ==> [(.) .v1 ((.) .v2 ((.) .v3 Nil))]
59 decurrying ==>
60 [0: (.) 1: ...? "difficulty."
62 Maybe keyword syntax instead:
64 (v1, v2, v3) ==> (First: v1 Rest: (First: v2 Rest: (First: v3 Rest: Nil)))
65 [v1, v2, v3] ==> [First: v1 Rest: [First: v2 Rest: [First: v3 Rest: Nil]]]
66 [.v1, .v2, .v3] ==> [First: .v1 Rest: [First: .v2 Rest: [First: .v3 Rest: Nil]]]
68 That''s better. It makes sense, too, since once (,,) is no longer
69 tupling, the only n-ary syntax we have is the pattern/value
70 syntax. Binary operators turn into curried application, which is
71 tricky to pattern-match.
73 Shit, there's another tricky case: the difference between [x] and x;
74 or, more properly, between (x) and x.
76 (x) ==> (First: x Rest: Nil)
77 x ==> x
79 Wrong! So, we need some kind of marker in the syntax. Unless... what
80 if we reinterpret (,) as a stream-cons operator rather than a
81 stream-separation operator?
83 (This, incidentally, is where python's (x,) syntax comes in.)
85 (1, 2, 3) --> (First: 1 Rest: (First: 2 Rest: 3))
86 (1, 2, 3, [])
88 Yuck. What about a right-associative flipped application operator (snoc)?
90 1, 2, 3 <==> ((,) ((,) 3 2) 1)
92 Read them as begin?
94 (begin x y z) ==
95 (begin (begin x y) z) ==
96 (begin x (begin y z)) ==
97 (begin (begin x) (begin y) (begin z)) == etc.
99 (x, y, z) ==
100 ((x, y), z) ==
101 (x, (y, z)) ==
102 ((x), (y), (z)) == etc.
104 That's better. So, (,) becomes an n-ary tupling syntax again, in a
105 way.
107 [x, y, z] ==
108 [[x, y], z] == ... Hmm. Not so pretty here?
110 Actually, there's also a problem with scoping rules, if begin is used
111 like a let* or a letrec: What does ((.a <- b, c), a) mean?
113 * Basics
115 pattern: value pattern: value ... (fun (pattern value) ...)
116 value, value, value, ... (tuple value ...)
117 value value (adj value value)
119 ( value ) ; grouping
120 [ value ] (quunquote value)
121 #[ value ] (quasiquote value)
122 #( value ) (unquote value)
123 . value (quote value)
125 atom ; symbols
126 'another atom' ; symbols
127 literal ; literal object sugar (strings, ints)
128 ; unit, nothing at all
130 "a comment" ; comments
132 TODO: Bit syntax!
134 * Tuples, Records and Functions
136 [] is both the empty quoted tuple and the empty quoted function.
138 Tuples are sugar for functions with integer patterns! Like this:
139 (x, y, z) <==> (.length: 3 0: x 1: y 2: z)
141 (... or something. The ".length: 3" could instead be ".tuple: .tuple",
142 as an "interface marker" of some kind)
144 The empty tuple/function is "unit".
146 * Interpretation
148 Non-quoted tuples are sugar for monadic sequencing, that is /bind/
149 operations.
151 Non-quoted functions are messages sent to the ambient.
153 Non-quoted adjacency is function application == message send.
155 Non-quoted symbols are variable references.
157 Non-quoted literals are self-evaluating.
159 * Quoting
161 ** Quote
163 ** Quasiquote and unquote
165 ** Quunquote
