@fraczak/k 4.0.2 → 4.0.4

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/README.md CHANGED
@@ -1,14 +1,28 @@
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
- import k from "@fraczak/k";
9
+ ```javascript
10
+ import k from "@fraczak/k"
8
11
 
9
- const fn = k.compile("<.name,.nom,'?'>");
10
- console.log([{name:"x"},{nom:"y"},{}].map(fn));
11
- // returns: [ "x", "y", "?" ]
12
+ const fn = k.compile(` -- complete "pure" k-program
13
+ $ nat = < {} o, nat i >; -- unary natural number encoding
14
+ succ = {() i} $nat; -- increment relation definition
15
+ succ succ succ -- +3 (in the above encoding)
16
+ `);
17
+ const three = {i:{i:{i:{o:{}}}}};
18
+ const six = fn(three);
19
+ console.log(JSON.stringify( six ));
20
+ // {"i":{"i":{"i":{"i":{"i":{"i":{"o":{}}}}}}}}
21
+ ```
22
+
23
+ Working with REPL:
24
+
25
+ [![asciicast](https://asciinema.org/a/UZuFpX4a5CQ47JTQngv253EVv.svg)](https://asciinema.org/a/UZuFpX4a5CQ47JTQngv253EVv)
12
26
 
13
27
  ---
14
28
 
@@ -20,9 +34,11 @@ An example of a _partial function_ is the _projection_, e.g., "`.toto`",
20
34
  which maps an object to its property named `toto`, or it is not defined if
21
35
  the property doesn't exist. E.g.,
22
36
 
23
- 1 .toto :
24
- 2 {"toto": 5, "titi": 10} --> 5
25
- 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
+ ```
26
42
 
27
43
  > Note: The above 3 lines should be read as follows. A `k`-expression
28
44
  > is printed in the first line (before "`:`"). The following lines
@@ -41,25 +57,30 @@ There are three ways of combining functions:
41
57
  1. **composition**: `(f1 f2 ...)`, e.g. `(.toto .titi)` extracts
42
58
  nested field.
43
59
 
44
- (.toto .titi) :
45
- {"toto": {"titi": 10}} --> 10
46
- {"toto": 10 } ... undefined
47
- {} ... undefined
60
+ ```text
61
+ (.toto .titi) :
62
+ {"toto": {"titi": 10}} --> 10
63
+ {"toto": {"other": 8}} ... undefined
64
+ {"other": {}} ... undefined
65
+ ```
48
66
 
49
67
  2. **merge**: `< f1, f2,... >`, e.g., `<.toto, .titi>` extracts field
50
68
  `toto` if present; otherwise extracts `titi`.
51
69
 
52
- <.toto, .titi> :
53
- {"toto": 5, "titi": 10} --> 5
54
- {"titi": 10 } --> 10
55
- {} ... 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
+ ```
56
76
 
57
77
  3. **product**: `{ f1 label1, f2 label2, ...}`, e.g., `{.toto TOTO,
58
- .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.
59
79
 
60
- {.toto TOTO, .titi TITI} :
61
- {"toto": 5, "titi": 10, "x": 3} --> {"TOTO": 5, "TITI": 10}
62
- {"titi": 10 } ... undefined
80
+ ```text
81
+ {.toto TOTO, .titi TITI} :
82
+ {"toto": 5, "titi": 10, "x": 3} --> {"TOTO": 5, "TITI": 10}
83
+ ```
63
84
 
64
85
  ---
65
86
 
@@ -92,46 +113,54 @@ supported.
92
113
  A constant defines a function which ignores its argument and produces
93
114
  the constant value. E.g.:
94
115
 
95
- {123 int, "kScript" str, true bool, null null} :
96
- "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
+ ```
97
120
 
98
121
  Those values, i.e., _strings_, _integers_, _booleans_, and _null_, admit the
99
- projection to the canonicat string representation of the value, e.g.:
100
-
101
- .2 :
102
- 2 --> {}
103
- "2" --> {}
104
- 4 ... undefined
105
- true ... undefined
106
-
107
- .true :
108
- true --> {}
109
- "true" --> {}
110
- 4 ... undefined
111
- "toto" ... undefined
112
-
113
- .null :
114
- null --> {}
115
- "null" --> {}
116
- 4 ... undefined
117
- 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
+ ```
118
148
 
119
149
  #### Vector product
120
150
 
121
- Vector product can be seen as an abbreviation for product whose field
122
- 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.
123
153
  E.g., `{.toto 0, .titi 1, 123 2}` can be written as
124
154
  `[.toto, .titi, 123]`.
125
155
 
126
- [.toto, .titi, 12] :
127
- {"toto": 5, "titi": 10 } --> [5, 10, 12]
128
-
129
- .1 :
130
- ["A","B","C"] --> "B"
131
- ["a"] ... undefined
156
+ ```text
157
+ [.toto, .titi, 12] :
158
+ {"toto": 5, "titi": 10 } --> [5, 10, 12]
132
159
 
133
- The vector notation is introduced to satisfy JSON syntax and, for example,
134
- is not supported in _code derivation_ (explained below).
160
+ . 2 :
161
+ ["A","B","C"] --> "C"
162
+ ["a"] ... undefined
163
+ ```
135
164
 
136
165
  ---
137
166
 
@@ -164,7 +193,7 @@ is not supported in _code derivation_ (explained below).
164
193
 
165
194
  CONCAT:
166
195
  ["a","bc","d"] --> "abcd"
167
- ["a","bc","d"] --> "abcd"
196
+ [] --> ""
168
197
 
169
198
  - `toJSON` and `fromJSON` -- conversion to and from JSON strings
170
199
 
@@ -173,8 +202,6 @@ is not supported in _code derivation_ (explained below).
173
202
 
174
203
  fromJSON:
175
204
  "{\"a\":12}" --> {"a":12}
176
- "2.12" --> 2.12
177
- "[1,2.11,0.3e-32]" --> [1,2.11,3e-33]
178
205
 
179
206
  - other predefined parial functions are: `DIV`, `FDIV`, `CONS`,
180
207
  `SNOC`, `toVEC`, `toDateMsec`, `toDateStr`, and `_log!`.
@@ -183,24 +210,47 @@ is not supported in _code derivation_ (explained below).
183
210
 
184
211
  ### Function and code (i.e., _type_) definitions
185
212
 
186
- dec = [(),-1] PLUS;
187
- max = <SNOC [.car, .cdr max] <GT.0, .1>, .0> ;
188
- 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
+ ```
189
220
 
190
221
  ### Codes (schemas, i.e., _types_)
191
222
 
192
- _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.:
193
224
 
225
+ ```k-repl
226
+ $ nat = < nat 1, {} 0 >;
227
+ $ pair = { nat x, nat y };
194
228
 
195
- $nat = <nat 1, {} 0>;
196
- $pair = {nat x, nat y};
229
+ suc = { $ nat 1 };
230
+ add = $ pair <{.x.1 x, .y suc y} add, .y>;
231
+ ```
197
232
 
198
- suc = {$nat 1};
199
- 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 `$`.
200
235
 
201
236
  Two codes are considered equal when they are isomorphic (preserving
202
237
  union/product and field names). E.g., `$pair`, `${nat y, nat x}`, and
203
- `${<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
+ ```
204
254
 
205
255
  #### Basic extension codes
206
256
 
@@ -209,26 +259,33 @@ there are three predefined types: `int`, `bool`, and `string`. A
209
259
  vector product code can also be defined by `[ codeExp ]`. All members
210
260
  of the vector are the same code. E.g.,
211
261
 
212
- $intVector = [ int ];
213
- $boolVector = [ bool ];
214
- $tree = [ tree ];
262
+ ```k-repl
263
+ $ intVector = [ int ];
264
+ $ boolVector = [ bool ];
265
+ $ tree = [ tree ];
266
+ ```
215
267
 
216
268
  ### Code derivation and Patterns
217
269
 
218
270
  Intuitively, a _pattern_ represents some set of contraints on
219
271
  codes. For example, expression `.toto` is a projection from a value of
220
- a product or a union with field `toto`. Therefore, expression `.toto`
272
+ a product or a union code with field `toto`. Therefore, expression `.toto`
221
273
  introduces two patterns `p_i` and `p_o` (for input and output codes,
222
274
  respectively); `p_o` imposes no constraint on code, however `p_i` is a
223
275
  product or union code with field `toto` leading to a code fulfilling
224
- `p_o`, i.e., something like `< ? toto, ... >` or `{ ? toto, ... }`.
225
-
226
- .toto
227
- 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
+ ```
228
285
 
229
286
  In a more complex expression each (occurrence of) subexpression will
230
287
  introduce some new patterns.
231
- For example, concider `<.toto, ()>`:
288
+ For example, concider ` rel = <.toto, ()>; `.
232
289
 
233
290
  < .toto , () >
234
291
  p1 p2 p3 p4 p5 p6
@@ -238,28 +295,27 @@ and `p6` is the pattern for the output. We can deduce that patterns
238
295
  (`p1`, `p2`, `p4`) defines the same code, as well as (`p6`, `p5`, `p3`),
239
296
  because union combines partial functions with the same input and output codes.
240
297
  Identity, `()`, implies that (`p4`, `p5`) define the
241
- same code. That means that in our expression, we deal with only one
242
- code, `c`, product or union, with field `toto` of type `c`, i.e.,
243
-
244
- $c = < c toto, ... >;
245
-
246
- or
247
-
248
- $c = { c toto, ... };
249
-
250
- Since the product code pattern (i.e., latter case) doesn't admmit any
251
- (finite) value, we conclude that the code `c` is a union (i.e.,
252
- 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
+ ```
253
307
 
254
308
  For a given `kScript`, code derivation (as any static analysis) can
255
309
  fail, indicating that the script is invalid. In some other cases the
256
310
  code derivation can succeed even to the point of reducig every pattern
257
311
  to a single code making the program fully annotated by codes.
258
312
 
259
- 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.
260
316
 
261
- ```k
262
- tree_pattern = ?<(...) leaf, {T left, T right} tree> = T;
317
+ ```k-repl
318
+ treePattern = ?<(...) leaf, {T left, T right} tree> = T;
263
319
  ```
264
320
 
265
321
  ---
@@ -267,13 +323,13 @@ The language `k` supports _type patterns_, which is used for type inference, how
267
323
  ### List comprehension
268
324
 
269
325
  A vector can be "open" by PIPE (`|`) operator so the following partial function is applied to
270
- 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",
271
327
  i.e., turn into a regular vector using `CARET` (`^`) operator. E.g.:
272
328
 
273
329
  ```k
274
330
  | .x ^ :
275
- [{x:12}, {x:8,y:10}, {y:98}] --> [12,8]
276
- [1,2,3] --> []
331
+ [{x:12}, {x:8}, {y:98}] --> [12,8]
332
+ ["a","x","b","x"] --> [{},{}]
277
333
  ```
278
334
 
279
335
  The PIPE operator can be used for defining the Cartesian product:
@@ -314,8 +370,8 @@ times value `x` appears in the list. (see `Examples/list-comprehension.k` for a
314
370
  1. projection:
315
371
 
316
372
  .x
317
- ."field name"
318
- .4
373
+ . "field name"
374
+ (. 4)
319
375
 
320
376
  The function is defined if its argument "has" the field.
321
377
 
@@ -358,11 +414,11 @@ times value `x` appears in the list. (see `Examples/list-comprehension.k` for a
358
414
  Another example could be finding the biggest (max) value in a vector:
359
415
 
360
416
  max = <
361
- SNOC # [x0, x1, x2, ...] --> {x0 car, [x1, x2, ...] cdr}
362
- [.car, .cdr max] # [x0, [x1, x2, ...]] --> [x0, max(x1,x2,...)], i.e., recursive call
363
- <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,...)
364
420
  , # when SNOC is not defined, i.e., if the input vector has one element:
365
- .0 # [x0] --> x0
421
+ .0 # [x0] --> x0
366
422
  >;
367
423
  max
368
424
 
@@ -448,16 +504,16 @@ For example:
448
504
 
449
505
  > k -k test.k
450
506
 
451
- 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
452
508
 
453
- > k -k test.k my-objects.json
509
+ > k -k test.k my-objects.jsonl
454
510
  {"x&y":"x=432 & y=123"}
455
511
  {"x&y":"only x=987"}
456
512
  {"x&y":"no x nor y"}
457
513
 
458
514
  where:
459
515
 
460
- > cat my-objects.json
516
+ > cat my-objects.jsonl
461
517
  ####################################################
462
518
  # empty lines and lines starting with # are ignored
463
519
  {"y": 123, "x": 432,"others": "..."}
@@ -469,40 +525,28 @@ For example:
469
525
 
470
526
  ### Short comparaison with `jq` tutorial examples: <https://stedolan.github.io/jq/tutorial/>
471
527
 
472
- 1.
473
- curl 'https://api.github.com/repositories/5101141/commits?per_page=5' | jq '.'
474
- curl 'https://api.github.com/repositories/5101141/commits?per_page=5' | k '()' -1
475
- 2.
476
- curl 'https://api.github.com/repositories/5101141/commits?per_page=5' | jq '.[0]'
477
- curl 'https://api.github.com/repositories/5101141/commits?per_page=5' | k '.0' -1
478
- 3.
479
- jq '.[0] | {message: .commit.message, name: .commit.committer.name}'
480
- k '.0 {.commit.message message, .commit.committer.name name}' -1
481
- 4. note: `k`-expression defines a partial function yielding a single json object, i.e., as far as `k` is concerned,
482
- examples 4 and 5 of the `jq` tutorial are equivalent.
483
- 5.
484
- jq '[.[] | {message: .commit.message, name: .commit.committer.name}]'
485
- k '| .commit {.message message, .committer.name name} ^' -1
486
- 6.
487
- jq '[.[] | {message: .commit.message, name: .commit.committer.name, parents: [.parents[].html_url]}]'
488
- 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)
489
529
 
490
530
  ---
491
531
 
492
532
  ## k-REPL (Read-Evaluate-Print Loop)
493
533
 
494
- Also there is a REPL, `k-repl` (`./node_modules/.bin/k-repl`), which acts like a toy
495
- shell for the language. E.g.:
496
-
497
- > ./node_modules/.bin/k-repl
498
- {'a' a, 'b' b} toJSON
499
- => "{\"a\":\"a\",\"b\":\"b\"}"
500
- {"a" a} toJSON fromJSON
501
- => {"a": "a"}
502
- inc = [(),1] PLUS; 1 inc inc
503
- => 3
504
- inc inc inc inc
505
- => 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
+ ```
506
550
 
507
551
  ---
508
552