Skip to content

Commit d3ece55

Browse files
committed
Drop support for deep key paths from @lookup
Now that `@index` exists, expressions like `:a.b` can be modeled as a `@lookup` followed by an `@index`. This helps to simplify `@lookup`'s implementation.
1 parent 80d5402 commit d3ece55

File tree

8 files changed

+171
-195
lines changed

8 files changed

+171
-195
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ Data can be referenced from other places in the program using lookups, like
9191
}
9292
```
9393

94-
You can drill down into the properties of looked-up values:
94+
You can index into the properties of looked-up values:
9595

9696
```
9797
{
@@ -100,7 +100,7 @@ You can drill down into the properties of looked-up values:
100100
greeting: "Hello, World!"
101101
}
102102
}
103-
greeting: :deeply.nested.greeting // or :{deeply nested greeting}
103+
greeting: :deeply.nested.greeting
104104
}
105105
```
106106

src/end-to-end.test.ts

Lines changed: 16 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ testCases(endToEnd, code => code)('end-to-end tests', [
2828
['{overwritten,0:a,c}', either.makeRight({ 0: 'a', 1: 'c' })],
2929
['{@check type:true value:true}', either.makeRight('true')],
3030
['{a:A b:{@lookup {a}}}', either.makeRight({ a: 'A', b: 'A' })],
31-
['{a:A b: :{a}}', either.makeRight({ a: 'A', b: 'A' })],
31+
['{a:A b: :a}', either.makeRight({ a: 'A', b: 'A' })],
3232
['{a:A {@lookup {a}}}', either.makeRight({ a: 'A', 0: 'A' })],
33-
['{a:A :{a}}', either.makeRight({ a: 'A', 0: 'A' })],
33+
['{a:A :a}', either.makeRight({ a: 'A', 0: 'A' })],
3434
['{ a: (a => :a)(A) }', either.makeRight({ a: 'A' })],
3535
['{ a: ( a => :a )( A ) }', either.makeRight({ a: 'A' })],
3636
['(a => :a)(A)', either.makeRight('A')],
@@ -116,7 +116,7 @@ testCases(endToEnd, code => code)('end-to-end tests', [
116116
either.makeRight('output'),
117117
],
118118
[':match({ a: A })({ tag: a, value: {} })', either.makeRight('A')],
119-
[':{atom prepend}(a)(b)', either.makeRight('ab')],
119+
[':atom.prepend(a)(b)', either.makeRight('ab')],
120120
[':flow({ :atom.append(a) :atom.append(b) })(z)', either.makeRight('zab')],
121121
[
122122
`{
@@ -126,7 +126,7 @@ testCases(endToEnd, code => code)('end-to-end tests', [
126126
0:@runtime
127127
function:{
128128
0:@apply
129-
function:{0:@lookup query:{0:object 1:lookup}}
129+
function:{0:@index object:{0:@lookup query:{0:object}} query:{0:lookup}}
130130
argument:"key which does not exist in runtime context"
131131
}
132132
}
@@ -138,63 +138,17 @@ testCases(endToEnd, code => code)('end-to-end tests', [
138138
],
139139
[
140140
`{@runtime
141-
:{object lookup}("key which does not exist in runtime context")
141+
:object.lookup("key which does not exist in runtime context")
142142
}`,
143143
either.makeRight({ tag: 'none', value: {} }),
144144
],
145-
[
146-
`{@runtime
147-
{@apply
148-
{@lookup { flow }}
149-
{
150-
{@apply
151-
{@lookup { object lookup }}
152-
environment
153-
}
154-
{@apply
155-
{@lookup { match }}
156-
{
157-
none: "environment does not exist"
158-
some: {@apply
159-
{@lookup { flow }}
160-
{
161-
{@apply
162-
{@lookup { object lookup }}
163-
lookup
164-
}
165-
{@apply
166-
{@lookup { match }}
167-
{
168-
none: "environment.lookup does not exist"
169-
some: {@apply
170-
{@lookup { apply }}
171-
PATH
172-
}
173-
}
174-
}
175-
}
176-
}
177-
}
178-
}
179-
}
180-
}
181-
}`,
182-
output => {
183-
if (either.isLeft(output)) {
184-
assert.fail(output.value.message)
185-
}
186-
assert(typeof output.value === 'object')
187-
assert.deepEqual(output.value['tag'], 'some')
188-
assert.deepEqual(typeof output.value['value'], 'string')
189-
},
190-
],
191145
[
192146
`{@runtime {@apply :flow {
193-
{@apply :{object lookup} environment}
147+
{@apply :object.lookup environment}
194148
{@apply :match {
195149
none: "environment does not exist"
196150
some: {@apply :flow {
197-
{@apply :{object lookup} lookup}
151+
{@apply :object.lookup lookup}
198152
{@apply :match {
199153
none: "environment.lookup does not exist"
200154
some: {@apply :apply PATH}
@@ -213,11 +167,11 @@ testCases(endToEnd, code => code)('end-to-end tests', [
213167
],
214168
[
215169
`{@runtime :flow({
216-
:{object lookup}(environment)
170+
:object.lookup(environment)
217171
:match({
218172
none: "environment does not exist"
219173
some: :flow({
220-
:{object lookup}(lookup)
174+
:object.lookup(lookup)
221175
:match({
222176
none: "environment.lookup does not exist"
223177
some: :apply(PATH)
@@ -287,4 +241,11 @@ testCases(endToEnd, code => code)('end-to-end tests', [
287241
)`,
288242
either.makeRight('3'),
289243
],
244+
[
245+
`{
246+
true: true
247+
false: :boolean.not(:true)
248+
}`,
249+
either.makeRight({ true: 'true', false: 'false' }),
250+
],
290251
])

src/language/compiling/compiler.test.ts

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,25 @@ testCases(compile, input => `compiling \`${JSON.stringify(input)}\``)(
2020
[
2121
{
2222
true1: ['@check', true, ['@lookup', ['identity']]],
23-
true2: ['@apply', ['@lookup', ['boolean', 'not']], false],
23+
true2: ['@apply', ['@index', ['@lookup', ['boolean']], ['not']], false],
2424
true3: [
2525
'@apply',
2626
[
2727
'@apply',
2828
['@lookup', ['flow']],
2929
[
30-
['@lookup', ['boolean', 'not']],
31-
['@lookup', ['boolean', 'not']],
30+
['@index', ['@lookup', ['boolean']], ['not']],
31+
['@index', ['@lookup', ['boolean']], ['not']],
3232
],
3333
],
3434
true,
3535
],
36-
false1: ['@check', false, ['@lookup', ['boolean', 'is']]],
37-
false2: ['@apply', ['@lookup', ['boolean', 'is']], 'not a boolean'],
36+
false1: ['@check', false, ['@index', ['@lookup', ['boolean']], ['is']]],
37+
false2: [
38+
'@apply',
39+
['@index', ['@lookup', ['boolean']], ['is']],
40+
'not a boolean',
41+
],
3842
false3: [
3943
'@apply',
4044
[
@@ -45,11 +49,11 @@ testCases(compile, input => `compiling \`${JSON.stringify(input)}\``)(
4549
'@apply',
4650
['@lookup', ['flow']],
4751
[
48-
['@lookup', ['boolean', 'not']],
49-
['@lookup', ['boolean', 'not']],
52+
['@index', ['@lookup', ['boolean']], ['not']],
53+
['@index', ['@lookup', ['boolean']], ['not']],
5054
],
5155
],
52-
['@lookup', ['boolean', 'not']],
56+
['@index', ['@lookup', ['boolean']], ['not']],
5357
],
5458
],
5559
true,
@@ -82,12 +86,12 @@ testCases(compile, input => `compiling \`${JSON.stringify(input)}\``)(
8286
}),
8387
],
8488
[
85-
['@check', 'not a boolean', ['@lookup', ['boolean', 'is']]],
89+
['@check', 'not a boolean', ['@index', ['@lookup', ['boolean']], ['is']]],
8690
output => assert(either.isLeft(output)),
8791
],
8892
[['@lookup', ['compose']], output => assert(either.isLeft(output))],
8993
[
90-
['@runtime', ['@lookup', ['boolean', 'not']]],
94+
['@runtime', ['@index', ['@lookup', ['boolean']], ['not']]],
9195
output => {
9296
assert(either.isLeft(output))
9397
assert(output.value.kind === 'typeMismatch')
@@ -96,7 +100,11 @@ testCases(compile, input => `compiling \`${JSON.stringify(input)}\``)(
96100
[
97101
[
98102
'@runtime',
99-
['@apply', ['@lookup', ['identity']], ['@lookup', ['boolean', 'not']]],
103+
[
104+
'@apply',
105+
['@lookup', ['identity']],
106+
['@index', ['@lookup', ['boolean']], ['not']],
107+
],
100108
],
101109
output => {
102110
assert(either.isLeft(output))
@@ -134,8 +142,8 @@ testCases(compile, input => `compiling \`${JSON.stringify(input)}\``)(
134142
'@apply',
135143
['@lookup', ['flow']],
136144
[
137-
['@lookup', ['boolean', 'not']],
138-
['@lookup', ['boolean', 'not']],
145+
['@index', ['@lookup', ['boolean']], ['not']],
146+
['@index', ['@lookup', ['boolean']], ['not']],
139147
],
140148
],
141149
],
@@ -149,15 +157,23 @@ testCases(compile, input => `compiling \`${JSON.stringify(input)}\``)(
149157
0: '@runtime',
150158
function: {
151159
0: '@apply',
152-
function: { 0: '@lookup', query: { 0: 'object', 1: 'lookup' } },
160+
function: {
161+
0: '@index',
162+
object: { 0: '@lookup', query: { 0: 'object' } },
163+
query: { 0: 'lookup' },
164+
},
153165
argument: 'key which does not exist in runtime context',
154166
},
155167
},
156168
success({
157169
0: '@runtime',
158170
function: {
159171
0: '@apply',
160-
function: { 0: '@lookup', query: { 0: 'object', 1: 'lookup' } },
172+
function: {
173+
0: '@index',
174+
object: { 0: '@lookup', query: { 0: 'object' } },
175+
query: { 0: 'lookup' },
176+
},
161177
argument: 'key which does not exist in runtime context',
162178
},
163179
}),

src/language/compiling/semantics.test.ts

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -239,22 +239,6 @@ elaborationSuite('@lookup', [
239239
},
240240
}),
241241
],
242-
[
243-
{
244-
a: 'A',
245-
b: {
246-
a: { nested: 'nested A' },
247-
b: { 0: '@lookup', query: { 0: 'a', 1: 'nested' } },
248-
},
249-
},
250-
success({
251-
a: 'A',
252-
b: {
253-
a: { nested: 'nested A' },
254-
b: 'nested A',
255-
},
256-
}),
257-
],
258242
[
259243
{
260244
foo: 'bar',
@@ -279,27 +263,33 @@ elaborationSuite('@lookup', [
279263
// lexical scoping
280264
[
281265
{
282-
a: { b: 'C' },
266+
a: 'C',
283267
b: {
284-
c: { 0: '@lookup', query: { 0: 'a', 1: 'b' } },
268+
c: { 0: '@lookup', query: { 0: 'a' } },
285269
},
286270
},
287271
success({
288-
a: { b: 'C' },
272+
a: 'C',
289273
b: {
290274
c: 'C',
291275
},
292276
}),
293277
],
294278
[
295279
{
296-
a: { b: 'C' },
280+
a: 'C',
297281
b: {
298-
a: {}, // this `a` should be referenced
299-
c: { 0: '@lookup', query: { 0: 'a', 1: 'b' } },
282+
a: 'other C', // this `a` should be referenced
283+
c: { 0: '@lookup', query: { 0: 'a' } },
300284
},
301285
},
302-
output => assert(either.isLeft(output)),
286+
success({
287+
a: 'C',
288+
b: {
289+
a: 'other C',
290+
c: 'other C',
291+
},
292+
}),
303293
],
304294
])
305295

@@ -367,7 +357,11 @@ elaborationSuite('@apply', [
367357
1: 'x',
368358
2: {
369359
0: '@apply',
370-
function: { 0: '@lookup', 1: { 0: 'boolean', 1: 'not' } },
360+
function: {
361+
0: '@index',
362+
1: { 0: '@lookup', 1: { 0: 'boolean' } },
363+
2: { 0: 'not' },
364+
},
371365
argument: { 0: '@lookup', 1: 'x' },
372366
},
373367
},
@@ -381,7 +375,11 @@ elaborationSuite('@apply', [
381375
function: {
382376
0: '@function',
383377
1: 'x',
384-
2: { 0: '@lookup', 1: { 0: 'x', 1: 'a' } },
378+
2: {
379+
0: '@index',
380+
1: { 0: '@lookup', 1: { 0: 'x' } },
381+
2: { 0: 'a' },
382+
},
385383
},
386384
argument: { a: 'it works' },
387385
},

0 commit comments

Comments
 (0)