@fraczak/k 4.0.3 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/BIG_PICTURE.md CHANGED
@@ -25,8 +25,10 @@ Types are defined by two constructs:
25
25
 
26
26
  Given a finite (possibly empty) set of types `t1, t2, ..., tn` and a set of pairwise different tags (labels) `l1, l2, ..., ln`,
27
27
 
28
- - by `{ t1 l1, t2 l2, ..., tn ln }`, we define a _product type_ with exactly `n` projection functions `.l1`, `.l2`, `...`, `.ln`,
29
- mapping a value of type `{t1 l1, t2 l2, ..., tn ln}` into a value of type `t1`, `t2`, `...`, `tn`, respectively.
28
+ - by `{ t1 l1, t2 l2, ..., tn ln }`, we define a _product type_ with exactly `n`
29
+ _projection_ functions: `.l1`, `.l2`, `...`, `.ln`.
30
+ Each projection function is mapping a value of type `{t1 l1, t2 l2, ..., tn ln}`
31
+ into a value of type `t1`, `t2`, `...`, `tn`, respectively.
30
32
  - by `< t1 l1, t2 l2, ..., tn ln >`, we define a _union type_ with exactly `n` projection functions `.l1`, `.l2`, `...`, `.ln`,
31
33
  mapping a value of type `<t1 l1, t2 l2, ..., tn ln>` into a value of type `t1`, `t2`, `...`, `tn`, respectively.
32
34
 
@@ -38,8 +40,8 @@ Some properties of these types:
38
40
 
39
41
  1. Singleton product and singleton union types, `{ t label }` and `< t label >`, are equivalent as they have
40
42
  the same set of values (and the same projection function `.label`). That's why, we not allow singleton product nor
41
- singleton union types in the syntax of the language. The other benefit is that we will be able to use the same systax
42
- for values of both product and union types, interpretting every singleton product-like value, e.g., `{ a_value label }`,
43
+ singleton union types in the syntax of the language. The other benefit is that we will be able to use the same syntax
44
+ for writing out values of both product and union types, interpretting every singleton product-like value, e.g., `{ a_value label }`,
43
45
  as a union type value (a variant).
44
46
  2. The empty product type `{}` has a single value, called the _unit_ and also denoted by `{}`, which has no fields.
45
47
  3. The empty union type `<>` has no values.
@@ -50,7 +52,7 @@ A _partial function_ is a function that is not defined for every value of its do
50
52
 
51
53
  There are three ways of combining partial functions:
52
54
 
53
- 1. __Composition__: we write a composition of `f` and `g` as `(f g)`, meaning that if `f` is defined on valye `x` producing `y`,
55
+ 1. __Composition__: we write a composition of `f` and `g` as `(f g)`, meaning that if `f` is defined on value `x` producing `y`,
54
56
  and `g` is defined on value `y` producing `z`, then `(f g)` is defined on value `x` producing `z`.
55
57
  2. __Union__: we write `< f1, f2 >` for a union of two functions `f1` and `f2`, meaning that
56
58
  if `f1` is defined on value `x` producing `y`, then `< f1, f2 >`
@@ -59,7 +61,7 @@ There are three ways of combining partial functions:
59
61
  are both defined on value `x` producing `y1` and `y2`, respectively, then `{f1 lab1, f2 lab2 }`
60
62
  is defined on value `x` producing `{y1 lab1, y2 lab2}`. Otherwise, `{f1 lab1, f2 lab2 }` is not defined for `x`.
61
63
 
62
- Actually, all of the above operations take any number of arguments, not only two. For example,
64
+ Actually, composition, union, and product combine any number of partial functions, not only two. For example,
63
65
  empty composition, `()`, defines the identity function.
64
66
 
65
67
  ### Program
@@ -78,16 +80,21 @@ type_label_list ::= /* empty */ | ( type_expression label_name ',' ) + type_expr
78
80
  type_expression ::= type_name | type
79
81
 
80
82
  function_definition ::= function_name '=' expression ';'
81
- expression ::= projection | typing | composition | union | product | function_name
83
+ expression ::= projection | typing | filter | composition | union | product | function_name
82
84
  projection ::= '.' label_name
83
- typing ::= '$' tape_expression
85
+ typing ::= '$' type_expression
86
+ filter ::= '?' filter_expression
87
+ filter_expression ::= $ type_expression | filter_name
88
+ | '{' filter_label_list '}' | '<' filter_label_list '>' | '(' filter_label_list ')'
89
+ | filter_expression '=' filter_name
90
+ filter_label_list ::= /* empty */ | ( filter_expression label_name ',' ) * filter_expression label
84
91
  composition ::= '(' expression * ')'
85
92
  union ::= '<' (expression ',') + expression '>'
86
93
  product ::= '{' expression_label_list '}'
87
94
  expression_label_list ::= /* empty */ | ( expression label_name ',' ) * expression label
88
95
  ```
89
96
 
90
- We assume that the `type_name`, `function_name`, and `label_name` are identifiers (strings) such that:
97
+ We assume that in a `kernel-core` program the `type_name`, `function_name`, and `label_name` are identifiers (strings) such that:
91
98
 
92
99
  1. All defined type names are distinct.
93
100
  2. All defined function names are distinct.
@@ -97,6 +104,7 @@ The `typing` expression acts as a type annotation and can be seen as a 'filter',
97
104
  function defined only for the values of the corresponding type.
98
105
 
99
106
  That's it.
107
+
100
108
  No `builtin` types, no `if` statement, no `loop`, no `throw`, no _closure_, no _annotations_, and no macros.
101
109
  Just types and partial functions.
102
110
 
@@ -104,22 +112,22 @@ Just types and partial functions.
104
112
 
105
113
  All type names are replaced by the hash of their canonical representation.
106
114
 
107
- We will also replace the function name by the hash of the normalized unfolded definition of the function.
108
- Obviously, two different definitions of the same function may have different hashes.
115
+ We replace the function name by the hash of the normalized definition of the function as provided by the program defining the function.
116
+ Obviously, a function may have many different definitions so the hash-based names are not canonical. By using hash-based function names we avoid the problem of name clashes when bringing together many `kernel-core` programs.
109
117
 
110
- This approach solves the problem of modules and imports and opens the door to a universal
118
+ This approach solves the problem of modules, imports, etc., and opens the door to a universal
111
119
  registry of types (schemas) and functions.
112
120
 
113
121
  ## Typing and Polymorphism (codes and filters/patterns)
114
122
 
115
- Abstract Syntax Tree of a program after parsing consists of a dictionary of _type definitions_,
123
+ Abstract Syntax Tree of a program consists of a dictionary of _type definitions_,
116
124
  a dictionary of _function definitions_, and the final _main expression_.
117
125
 
118
126
  In principle, the initial form of the Abstract Syntax Tree, _raw_ AST, is enough to evaluate
119
127
  the program on an input.
120
128
 
121
129
  Our objective however is to compute canonicals representations for types and normalized
122
- representations for functions, so they could be effectively reused.
130
+ representations for functions, so they could be reused.
123
131
 
124
132
  The normalization steps are:
125
133
 
@@ -127,7 +135,7 @@ The normalization steps are:
127
135
  as well as type expressions used in _function definitions_ and the _main expression_.
128
136
  2. Annotate the expressions with types or type patterns; every node of the AST is annotated with a pair of type patterns.
129
137
  3. Turn the _singleton_ type patterns into types and add them to the _type graph_. Go to (2) unless no change.
130
- 4. Normalize the function definitions by rewriting them as the fix-point of a single equation.
138
+
131
139
 
132
140
  ### Example
133
141
 
@@ -169,7 +177,7 @@ and a type `byte` as a product, for simplicity, of four `bit`s.
169
177
  Functions `bit0`, `bit1`, and `zero` are "constant polymorphic functions", meaning:
170
178
 
171
179
  - constant: if defined, they always return exactly the same value;
172
- - polymorphic: they are defined for more than one pair of input and output type: functions
180
+ - polymorphic: they are defined for more than one pair of input and output types: functions
173
181
  `bit0` and `bit1` are of type `?X -> $bit`, and `zero` is of type `?X -> $byte`, where `?X`
174
182
  denotes an unconstrained type pattern, also denoted as `?(...)`.
175
183
 
@@ -186,15 +194,15 @@ with following constraints:
186
194
  > `?( V i, ...)`;
187
195
  - `V` is unconstrained, denoted by `(...)`;
188
196
 
189
- We could write it as: `?($byte byte, ((...) i, ...) overflown, ...)`.
197
+ We can write it as: `?($byte byte, ((...) i, ...) overflown, ...)`.
190
198
 
191
199
  The target type `${ byte byte, bit overflown }` was derived from pattern `?{ $byte byte, $bit overflown }`.
192
- Such a pettern is called _singleton pattern_ as only one type fits the pattern.
200
+ Such a pattern is called _singleton pattern_, as only one type fits the pattern.
193
201
 
194
202
  ## Universal Schema Registry
195
203
 
196
204
  Since the normalization process for types is fast and deterministic, we can build a universal
197
- schema registry that will store all invented types.
205
+ schema registry that will store all invented types.
198
206
  The registry will be a key-value store, where the key is the hash of the normalized type,
199
207
  and the value is the normalized type itself.
200
208
 
@@ -203,8 +211,7 @@ definition and stored in the similar key-value store.
203
211
 
204
212
  Non-polymorphic functions can be easily indexed by the hashes of their input and output types
205
213
  so that we can quickly find the function we need.
206
- Searching for polymorphic functions is more complicated, as we need to find the function
207
- whose input and output type patterns fit given types.
214
+ Indexing polymorphic functions seems complicated (TODO).
208
215
 
209
216
  ## Serialization and Compilation
210
217
 
package/README.md CHANGED
@@ -1,10 +1,12 @@
1
1
  # k-language
2
2
 
3
- npm install '@fraczak/k'
3
+ ```sh
4
+ npm i '@fraczak/k'
5
+ ```
4
6
 
5
7
  From javascript:
6
8
 
7
- ```js
9
+ ```javascript
8
10
  import k from "@fraczak/k"
9
11
 
10
12
  const fn = k.compile(` -- complete "pure" k-program
@@ -16,39 +18,11 @@ const three = {i:{i:{i:{o:{}}}}};
16
18
  const six = fn(three);
17
19
  console.log(JSON.stringify( six ));
18
20
  // {"i":{"i":{"i":{"i":{"i":{"i":{"o":{}}}}}}}}
19
-
20
21
  ```
21
22
 
22
23
  Working with REPL:
23
24
 
24
- ```
25
- $ k-repl
26
- Very! experimental repl shell for 'k-language'...
27
- --c print aliased codes
28
- --C code print 'code' definition
29
- --r print relations
30
- --R rel print 'rel' definition with type patterns
31
- --p (--pp) pretty-print last value
32
- --s (--g) reg store (get) the current value in (from) register 'reg'
33
- --regs print register names
34
- --l file.k load 'file.k'
35
- > -- DEMO: comments start with '--', like this line \
36
- -- Code (type) definitions: ` $ code-name = code-expression ;` \
37
- $ unit = { } ; -- empty product code \
38
- $ bits = <unit _, bits 0, bits 1>; -- union, 3 variants tagged: _, 0, 1 \
39
- -- Now, we will define relations: ` name = expression ; ` \
40
- empty = {{} _} ; -- alternative JSON-like syntax {_: {}} allowed \
41
- _001 = {0: {0: {1: empty}}}; -- in JSON-like syntax \
42
- reverse_ = < -- priority merge \
43
- {.in.0 in, {.out 0} out} reverse_, \
44
- {.in.1 in, {.out 1} out} reverse_, \
45
- .out >; \
46
- reverse = {() in, empty out} reverse_ ; \
47
- _001 reverse -- run the expression (composition of 2 relations)
48
- --> {"1":{"0":{"0":{"_":{}}}}}
49
- > toStr = < .0 ["0",toStr] CONCAT, .1 ["1",toStr] CONCAT, "" >; toStr
50
- --> "100"
51
- ```
25
+ [![asciicast](https://asciinema.org/a/UZuFpX4a5CQ47JTQngv253EVv.svg)](https://asciinema.org/a/UZuFpX4a5CQ47JTQngv253EVv)
52
26
 
53
27
  ---
54
28
 
@@ -60,9 +34,11 @@ An example of a _partial function_ is the _projection_, e.g., "`.toto`",
60
34
  which maps an object to its property named `toto`, or it is not defined if
61
35
  the property doesn't exist. E.g.,
62
36
 
63
- 1 .toto :
64
- 2 {"toto": 5, "titi": 10} --> 5
65
- 3 {"titi": 10} ... undefined // it is not a value!
37
+ ```text
38
+ 1 .toto :
39
+ 2 {"toto": 5, "titi": 10} --> 5
40
+ 3 {"titi": 10} ... undefined // it is not a value!
41
+ ```
66
42
 
67
43
  > Note: The above 3 lines should be read as follows. A `k`-expression
68
44
  > is printed in the first line (before "`:`"). The following lines
@@ -81,25 +57,30 @@ There are three ways of combining functions:
81
57
  1. **composition**: `(f1 f2 ...)`, e.g. `(.toto .titi)` extracts
82
58
  nested field.
83
59
 
84
- (.toto .titi) :
85
- {"toto": {"titi": 10}} --> 10
86
- {"toto": 10 } ... undefined
87
- {} ... undefined
60
+ ```text
61
+ (.toto .titi) :
62
+ {"toto": {"titi": 10}} --> 10
63
+ {"toto": {"other": 8}} ... undefined
64
+ {"other": {}} ... undefined
65
+ ```
88
66
 
89
67
  2. **merge**: `< f1, f2,... >`, e.g., `<.toto, .titi>` extracts field
90
68
  `toto` if present; otherwise extracts `titi`.
91
69
 
92
- <.toto, .titi> :
93
- {"toto": 5, "titi": 10} --> 5
94
- {"titi": 10 } --> 10
95
- {} ... undefined
70
+ ```text
71
+ < .x.y, .z.y > :
72
+ {"x":{"y": 5}, "z": {"y":10}} --> 5
73
+ {"x":{"o":{}}, "z": {"y":10}} --> 10
74
+ {"x":{"o":{}}, "z": {"o":{}}} ... undefined
75
+ ```
96
76
 
97
77
  3. **product**: `{ f1 label1, f2 label2, ...}`, e.g., `{.toto TOTO,
98
- .titi TITI}` extracts two fields and builds a record out of them.
78
+ .titi TITI}` extracts two fields and builds a record out of them.
99
79
 
100
- {.toto TOTO, .titi TITI} :
101
- {"toto": 5, "titi": 10, "x": 3} --> {"TOTO": 5, "TITI": 10}
102
- {"titi": 10 } ... undefined
80
+ ```text
81
+ {.toto TOTO, .titi TITI} :
82
+ {"toto": 5, "titi": 10, "x": 3} --> {"TOTO": 5, "TITI": 10}
83
+ ```
103
84
 
104
85
  ---
105
86
 
@@ -132,46 +113,54 @@ supported.
132
113
  A constant defines a function which ignores its argument and produces
133
114
  the constant value. E.g.:
134
115
 
135
- {123 int, "kScript" str, true bool, null null} :
136
- "any" --> {"int":123,"str":"kScript","bool":true,"null":null}
116
+ ```text
117
+ {123 int, "kScript" str, true bool, null null} :
118
+ "any" --> {"int":123,"str":"kScript","bool":true,"null":null}
119
+ ```
137
120
 
138
121
  Those values, i.e., _strings_, _integers_, _booleans_, and _null_, admit the
139
- projection to the canonicat string representation of the value, e.g.:
140
-
141
- .2 :
142
- 2 --> {}
143
- "2" --> {}
144
- 4 ... undefined
145
- true ... undefined
146
-
147
- .true :
148
- true --> {}
149
- "true" --> {}
150
- 4 ... undefined
151
- "toto" ... undefined
152
-
153
- .null :
154
- null --> {}
155
- "null" --> {}
156
- 4 ... undefined
157
- false ... undefined
122
+ projection, via (`.`), to the canonical string representation of the value, e.g.:
123
+
124
+ ```text
125
+ ."a string" :
126
+ "a string" --> {}
127
+ "other" ... undefined
128
+ 11 ... undefined
129
+ null ... undefined
130
+ .2 :
131
+ 2 --> {}
132
+ "2" --> {}
133
+ 4 ... undefined
134
+ true ... undefined
135
+
136
+ .true :
137
+ true --> {}
138
+ "true" --> {}
139
+ 4 ... undefined
140
+ "toto" ... undefined
141
+
142
+ .null :
143
+ null --> {}
144
+ "null" --> {}
145
+ 4 ... undefined
146
+ false ... undefined
147
+ ```
158
148
 
159
149
  #### Vector product
160
150
 
161
- Vector product can be seen as an abbreviation for product whose field
162
- names are integers starting from zero.
151
+ Vector product can be seen as an abbreviation for product whose all fields
152
+ have the same type, and the filed names are integers starting from zero.
163
153
  E.g., `{.toto 0, .titi 1, 123 2}` can be written as
164
154
  `[.toto, .titi, 123]`.
165
155
 
166
- [.toto, .titi, 12] :
167
- {"toto": 5, "titi": 10 } --> [5, 10, 12]
168
-
169
- .1 :
170
- ["A","B","C"] --> "B"
171
- ["a"] ... undefined
156
+ ```text
157
+ [.toto, .titi, 12] :
158
+ {"toto": 5, "titi": 10 } --> [5, 10, 12]
172
159
 
173
- The vector notation is introduced to satisfy JSON syntax and, for example,
174
- is not supported in _code derivation_ (explained below).
160
+ . 2 :
161
+ ["A","B","C"] --> "C"
162
+ ["a"] ... undefined
163
+ ```
175
164
 
176
165
  ---
177
166
 
@@ -204,7 +193,7 @@ is not supported in _code derivation_ (explained below).
204
193
 
205
194
  CONCAT:
206
195
  ["a","bc","d"] --> "abcd"
207
- ["a","bc","d"] --> "abcd"
196
+ [] --> ""
208
197
 
209
198
  - `toJSON` and `fromJSON` -- conversion to and from JSON strings
210
199
 
@@ -213,8 +202,6 @@ is not supported in _code derivation_ (explained below).
213
202
 
214
203
  fromJSON:
215
204
  "{\"a\":12}" --> {"a":12}
216
- "2.12" --> 2.12
217
- "[1,2.11,0.3e-32]" --> [1,2.11,3e-33]
218
205
 
219
206
  - other predefined parial functions are: `DIV`, `FDIV`, `CONS`,
220
207
  `SNOC`, `toVEC`, `toDateMsec`, `toDateStr`, and `_log!`.
@@ -223,24 +210,47 @@ is not supported in _code derivation_ (explained below).
223
210
 
224
211
  ### Function and code (i.e., _type_) definitions
225
212
 
226
- dec = [(),-1] PLUS;
227
- max = <SNOC [.car, .cdr max] <GT.0, .1>, .0> ;
228
- factorial = < [(),0] GT .0 [dec factorial, ()] TIMES, 1 >;
213
+ ```k-repl
214
+ dec = [(),-1] PLUS;
215
+ max = <SNOC [.car, .cdr max] <GT.0, .1>, .0> ;
216
+ factorial = < [(),0] GT .0 [dec factorial, ()] TIMES, 1 >;
217
+ 6 factorial
218
+ --> 720
219
+ ```
229
220
 
230
221
  ### Codes (schemas, i.e., _types_)
231
222
 
232
- _Codes_ (prefixed by `$`) can be defined by tagged union and product. E.g.:
223
+ _Codes_ can be defined by tagged union and product. E.g.:
233
224
 
225
+ ```k-repl
226
+ $ nat = < nat 1, {} 0 >;
227
+ $ pair = { nat x, nat y };
234
228
 
235
- $nat = <nat 1, {} 0>;
236
- $pair = {nat x, nat y};
229
+ suc = { $ nat 1 };
230
+ add = $ pair <{.x.1 x, .y suc y} add, .y>;
231
+ ```
237
232
 
238
- suc = {$nat 1};
239
- add = $pair <{.x.1 x, .y suc y} add, .y>;
233
+ Code definition statement starts with `$`.
234
+ Also, any code expression occurrig within a `k`-expression is prefixed by `$`.
240
235
 
241
236
  Two codes are considered equal when they are isomorphic (preserving
242
237
  union/product and field names). E.g., `$pair`, `${nat y, nat x}`, and
243
- `${<nat 1, {} 0> x, nat y}` are all equal.
238
+ `${<nat 1, {} 0> x, nat y}` are all equivalent and corresponds its cannonical form
239
+ `$C0={C1"x",C1"y"};$C1=<C2"0",C1"1">;$C2={};`.
240
+
241
+ Try in `k-repl`:
242
+
243
+ ```k-repl
244
+ > $ nat = < nat 1, {} 0 >; \
245
+ $ pair = { nat x, nat y };
246
+ --> {}
247
+ > --C pair
248
+ $ IxLVRLECv = {BADJOX x, BADJOX y}; -- $C0={C1"x",C1"y"};$C1=<C2"0",C1"1">;$C2={};
249
+ $ myCode = {<nat 1, {} 0> x, nat y};
250
+ --> {}
251
+ > --C myCode
252
+ $ IxLVRLECv = {BADJOX x, BADJOX y}; -- $C0={C1"x",C1"y"};$C1=<C2"0",C1"1">;$C2={};
253
+ ```
244
254
 
245
255
  #### Basic extension codes
246
256
 
@@ -249,26 +259,33 @@ there are three predefined types: `int`, `bool`, and `string`. A
249
259
  vector product code can also be defined by `[ codeExp ]`. All members
250
260
  of the vector are the same code. E.g.,
251
261
 
252
- $intVector = [ int ];
253
- $boolVector = [ bool ];
254
- $tree = [ tree ];
262
+ ```k-repl
263
+ $ intVector = [ int ];
264
+ $ boolVector = [ bool ];
265
+ $ tree = [ tree ];
266
+ ```
255
267
 
256
268
  ### Code derivation and Patterns
257
269
 
258
270
  Intuitively, a _pattern_ represents some set of contraints on
259
271
  codes. For example, expression `.toto` is a projection from a value of
260
- a product or a union with field `toto`. Therefore, expression `.toto`
272
+ a product or a union code with field `toto`. Therefore, expression `.toto`
261
273
  introduces two patterns `p_i` and `p_o` (for input and output codes,
262
274
  respectively); `p_o` imposes no constraint on code, however `p_i` is a
263
275
  product or union code with field `toto` leading to a code fulfilling
264
- `p_o`, i.e., something like `< ? toto, ... >` or `{ ? toto, ... }`.
265
-
266
- .toto
267
- p_i p_o
276
+ `p_o`, which will be denoted by:
277
+
278
+ ```k-repl
279
+ > toto = .toto;
280
+ --> {}
281
+ > --R toto
282
+ toto : ?(X0 toto, ...) --> ?X0
283
+ toto = .toto;
284
+ ```
268
285
 
269
286
  In a more complex expression each (occurrence of) subexpression will
270
287
  introduce some new patterns.
271
- For example, concider `<.toto, ()>`:
288
+ For example, concider ` rel = <.toto, ()>; `.
272
289
 
273
290
  < .toto , () >
274
291
  p1 p2 p3 p4 p5 p6
@@ -278,28 +295,27 @@ and `p6` is the pattern for the output. We can deduce that patterns
278
295
  (`p1`, `p2`, `p4`) defines the same code, as well as (`p6`, `p5`, `p3`),
279
296
  because union combines partial functions with the same input and output codes.
280
297
  Identity, `()`, implies that (`p4`, `p5`) define the
281
- same code. That means that in our expression, we deal with only one
282
- code, `c`, product or union, with field `toto` of type `c`, i.e.,
283
-
284
- $c = < c toto, ... >;
285
-
286
- or
287
-
288
- $c = { c toto, ... };
289
-
290
- Since the product code pattern (i.e., latter case) doesn't admmit any
291
- (finite) value, we conclude that the code `c` is a union (i.e.,
292
- former case).
298
+ same code. In `k-repl`:
299
+
300
+ ```k-repl
301
+ > rel = < .toto, () >;
302
+ --> {}
303
+ > --R rel
304
+ rel : ?(X0 toto, ...)=X0 --> ?X0
305
+ rel = <.toto, ()>;
306
+ ```
293
307
 
294
308
  For a given `kScript`, code derivation (as any static analysis) can
295
309
  fail, indicating that the script is invalid. In some other cases the
296
310
  code derivation can succeed even to the point of reducig every pattern
297
311
  to a single code making the program fully annotated by codes.
298
312
 
299
- The language `k` supports _type patterns_, which is used for type inference, however the patterns are not concidered in the evaluation of the program.
313
+ The language `k` supports _type patterns_, which is used for code
314
+ derivation, however the patterns are not concidered in the
315
+ evaluation of the program.
300
316
 
301
- ```k
302
- tree_pattern = ?<(...) leaf, {T left, T right} tree> = T;
317
+ ```k-repl
318
+ treePattern = ?<(...) leaf, {T left, T right} tree> = T;
303
319
  ```
304
320
 
305
321
  ---
@@ -307,13 +323,13 @@ The language `k` supports _type patterns_, which is used for type inference, how
307
323
  ### List comprehension
308
324
 
309
325
  A vector can be "open" by PIPE (`|`) operator so the following partial function is applied to
310
- each element of the vector one by one, yielding another open value. An open value can be "closed",
326
+ each element of the vector, yielding another open value. An open value can be "closed",
311
327
  i.e., turn into a regular vector using `CARET` (`^`) operator. E.g.:
312
328
 
313
329
  ```k
314
330
  | .x ^ :
315
- [{x:12}, {x:8,y:10}, {y:98}] --> [12,8]
316
- [1,2,3] --> []
331
+ [{x:12}, {x:8}, {y:98}] --> [12,8]
332
+ ["a","x","b","x"] --> [{},{}]
317
333
  ```
318
334
 
319
335
  The PIPE operator can be used for defining the Cartesian product:
@@ -354,8 +370,8 @@ times value `x` appears in the list. (see `Examples/list-comprehension.k` for a
354
370
  1. projection:
355
371
 
356
372
  .x
357
- ."field name"
358
- .4
373
+ . "field name"
374
+ (. 4)
359
375
 
360
376
  The function is defined if its argument "has" the field.
361
377
 
@@ -398,11 +414,11 @@ times value `x` appears in the list. (see `Examples/list-comprehension.k` for a
398
414
  Another example could be finding the biggest (max) value in a vector:
399
415
 
400
416
  max = <
401
- SNOC # [x0, x1, x2, ...] --> {x0 car, [x1, x2, ...] cdr}
402
- [.car, .cdr max] # [x0, [x1, x2, ...]] --> [x0, max(x1,x2,...)], i.e., recursive call
403
- <GT .0, .1> # if x0 > max(x1,x2,...) then x0 else max(x1,x2,...)
417
+ SNOC # [x0, x1, x2, ...] --> {x0 car, [x1, x2, ...] cdr}
418
+ [.car, .cdr max] # {car:x0, cdr:[x1, x2, ...]} --> [x0, max(x1,x2,...)], recursive call
419
+ <GT .0, .1> # if x0 > max(x1,x2,...) then x0 else max(x1,x2,...)
404
420
  , # when SNOC is not defined, i.e., if the input vector has one element:
405
- .0 # [x0] --> x0
421
+ .0 # [x0] --> x0
406
422
  >;
407
423
  max
408
424
 
@@ -488,16 +504,16 @@ For example:
488
504
 
489
505
  > k -k test.k
490
506
 
491
- If we want to read `json` objects from a file, e.g., `my-objects.json`, we do
507
+ If we want to read `json` objects from a file, e.g., `my-objects.jsonl`, we do
492
508
 
493
- > k -k test.k my-objects.json
509
+ > k -k test.k my-objects.jsonl
494
510
  {"x&y":"x=432 & y=123"}
495
511
  {"x&y":"only x=987"}
496
512
  {"x&y":"no x nor y"}
497
513
 
498
514
  where:
499
515
 
500
- > cat my-objects.json
516
+ > cat my-objects.jsonl
501
517
  ####################################################
502
518
  # empty lines and lines starting with # are ignored
503
519
  {"y": 123, "x": 432,"others": "..."}
@@ -509,40 +525,28 @@ For example:
509
525
 
510
526
  ### Short comparaison with `jq` tutorial examples: <https://stedolan.github.io/jq/tutorial/>
511
527
 
512
- 1.
513
- curl 'https://api.github.com/repositories/5101141/commits?per_page=5' | jq '.'
514
- curl 'https://api.github.com/repositories/5101141/commits?per_page=5' | k '()' -1
515
- 2.
516
- curl 'https://api.github.com/repositories/5101141/commits?per_page=5' | jq '.[0]'
517
- curl 'https://api.github.com/repositories/5101141/commits?per_page=5' | k '.0' -1
518
- 3.
519
- jq '.[0] | {message: .commit.message, name: .commit.committer.name}'
520
- k '.0 {.commit.message message, .commit.committer.name name}' -1
521
- 4. note: `k`-expression defines a partial function yielding a single json object, i.e., as far as `k` is concerned,
522
- examples 4 and 5 of the `jq` tutorial are equivalent.
523
- 5.
524
- jq '[.[] | {message: .commit.message, name: .commit.committer.name}]'
525
- k '| .commit {.message message, .committer.name name} ^' -1
526
- 6.
527
- jq '[.[] | {message: .commit.message, name: .commit.committer.name, parents: [.parents[].html_url]}]'
528
- k '| {.commit.message message, .commit.committer.name name, .parents | .html_url ^ parents} ^' -1
528
+ [![asciicast](https://asciinema.org/a/ItH7nkc5CwFOopH8Fsr23oCWj.svg)](https://asciinema.org/a/ItH7nkc5CwFOopH8Fsr23oCWj)
529
529
 
530
530
  ---
531
531
 
532
532
  ## k-REPL (Read-Evaluate-Print Loop)
533
533
 
534
- Also there is a REPL, `k-repl` (`./node_modules/.bin/k-repl`), which acts like a toy
535
- shell for the language. E.g.:
536
-
537
- > ./node_modules/.bin/k-repl
538
- {'a' a, 'b' b} toJSON
539
- => "{\"a\":\"a\",\"b\":\"b\"}"
540
- {"a" a} toJSON fromJSON
541
- => {"a": "a"}
542
- inc = [(),1] PLUS; 1 inc inc
543
- => 3
544
- inc inc inc inc
545
- => 7
534
+ Also there is a REPL, `k-repl` (`./node_modules/.bin/k-repl`),
535
+ which acts like a toy shell for the language.
536
+
537
+ ```k-repl
538
+ $ k-repl
539
+ Very! experimental repl shell for 'k-language'...
540
+ --c print aliased codes
541
+ --C code print 'code' definition
542
+ --r print relations
543
+ --R rel print 'rel' definition with type patterns
544
+ --p (--pp) pretty-print last value
545
+ --s (--g) reg store (get) the current value in (from) register 'reg'
546
+ --regs print register names
547
+ --l file.k load 'file.k'
548
+ >
549
+ ```
546
550
 
547
551
  ---
548
552
 
package/TODO.md ADDED
@@ -0,0 +1,18 @@
1
+ # To do list for canonical names
2
+
3
+ - [ ] Write a script to search for conflicting names
4
+ - [ ] Export a relation. i.e., rewrite it as a list of all
5
+ dependency definitions using canonical names
6
+ - [ ] Find a way of adding 'comments' or some way of 'tagging' the definitions
7
+ - [X] The definitions should be simplied by removing useless filters
8
+ - [X] Definitions, which are just aliases to non built-in rels should not introduce a new canonical name
9
+ - [ ] Can we inline some references w/o changing the canonical name?
10
+
11
+ ## Simplification rules
12
+
13
+ It seems to me that after calculating input and output patterns, all
14
+ filters and code expressions could be replaced by just input and output
15
+ filters corresponding to the patterns. [DONE]
16
+
17
+ The filer variables have to be renamed for normalization if they take part of
18
+ the canonical name calculation. [DONE]
package/TYPING.md CHANGED
@@ -360,6 +360,6 @@ Repeat the procedure until the type pattern graph is not changing anymore.
360
360
  - [X] Redefine built-in CONS and SNOC to allign with no support for non-homogeneous lists
361
361
  - [X] Integrate filters into typePatters (execution is not affected)
362
362
  - [/] better type error repporting - the info exists in the pattern parent tree ... in progress
363
- - [ ] Introduce a space/time bounds for type derivation
363
+ - [X] Introduce a space/time bounds for type derivation
364
364
  - [ ] Check for loops, e.g., `$x = < x f, ...>`, `$x = [x]`, `$x = {x f, ...}` -- this
365
- looks a little arbitrary, but maybe this is actually an important part
365
+ looks a little arbitrary, but maybe this is actually an important part