functionalscript 0.0.307 → 0.0.311

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/LANGUAGE.md CHANGED
@@ -13,7 +13,7 @@ const result = thirdPartyModule.someFunction('hello')
13
13
  ## 2. Packages
14
14
 
15
15
  FunctionalScript uses a `package.json` file to define a package. This file is compatible with [Node.js `package.json`](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/).
16
- The prefered way to refence dependencies is to use a GitHub URL. These dependencies in a `package.json` file could look like this,
16
+ The preferred way to reference dependencies is to use a GitHub URL. These dependencies in a `package.json` file could look like this,
17
17
 
18
18
  ```json
19
19
  {
@@ -33,7 +33,7 @@ npm install -S github:functionalscript/functionalscript
33
33
 
34
34
  ## 3. Module Structure
35
35
 
36
- A module is a file with the `.js` extention. It contains three parts: references to other modules, definitions, and exports. For example
36
+ A module is a file with the `.js` extension. It contains three parts: references to other modules, definitions, and exports. For example
37
37
 
38
38
  `./first.js`
39
39
  ```js
@@ -81,7 +81,7 @@ const localFile = require('../some-directory/some-file.js')
81
81
 
82
82
  ## 5. Definitions
83
83
 
84
- The format of defintions is `const NAME = EXPRESSION`, where the `EXPRESSION` is a subset of [JavaScript expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators).
84
+ The format of definitions is `const NAME = EXPRESSION`, where the `EXPRESSION` is a subset of [JavaScript expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators).
85
85
 
86
86
  ```js
87
87
  const myConst = 42
@@ -139,7 +139,7 @@ Expressions could fall under these categories:
139
139
  - Relations Operators: `in`, `instanceof`.
140
140
  - Member Operators: `.`, `[]`.
141
141
 
142
- Note: the `.` member operator has prohibitted property names, such as `constructor` and `push`. To access such properties, it's recommeded to use the [Object.getOwnPropertyDescriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor) function.
142
+ Note: the `.` member operator has prohibited property names, such as `constructor` and `push`. To access such properties, it's recommended to use the [Object.getOwnPropertyDescriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor) function.
143
143
 
144
144
  ## 8. Arrow Functions
145
145
 
@@ -167,7 +167,7 @@ const f = x => {
167
167
 
168
168
  ## 9. Statements
169
169
 
170
- `{ A_LIST_OF_STATEMENTS }` is one or many statements seperated by the newline control character. One of these statements mentioned earlier was [definition](#5-Definitions), also known as a [const](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) statement. The other statements are described below.
170
+ `{ A_LIST_OF_STATEMENTS }` is one or many statements separated by the newline control character. One of these statements mentioned earlier was [definition](#5-Definitions), also known as a [const](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) statement. The other statements are described below.
171
171
 
172
172
  ### 9.1. Let
173
173
 
@@ -197,7 +197,7 @@ const f = () => x // < invalid
197
197
 
198
198
  ### 9.5. Throw
199
199
 
200
- [Throw](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw). FunctionalScript allows to throw exceptions but it doesn't catch them. You should only be using Statement throw in non-recoverable situations. It could be compared to [panic in Rust](https://doc.rust-lang.org/std/macro.panic.html).
200
+ [Throw](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw). FunctionalScript allows to throw exceptions, but the language has no ability to catch them. You should only be using Statement throw in non-recoverable situations. Throwing an exception could be compared to [panic in Rust](https://doc.rust-lang.org/std/macro.panic.html).
201
201
 
202
202
  ### 9.6. While
203
203
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # FunctionalScript
2
2
 
3
- FunctionalScript is a pure functional programming language and a strict subset of
3
+ FunctionalScript is a purely functional programming language and a strict subset of
4
4
  [ECMAScript](https://en.wikipedia.org/wiki/ECMAScript)/[JavaScript](https://en.wikipedia.org/wiki/JavaScript). It's inspired by
5
5
 
6
6
  - [JSON](https://en.wikipedia.org/wiki/JSON) as a subset of JavaScript. JSON is also a subset of FunctionalScript.
@@ -16,6 +16,14 @@ Create a new FunctionalScript repository on GitHub [here](https://github.com/fun
16
16
  In FunctionalScript:
17
17
 
18
18
  - Any module is a valid JavaScript module. No additional build steps are required.
19
- - Code should not have [side-effects](https://en.wikipedia.org/wiki/Side_effect_(computer_science)). Any JavaScript statement, expression, or function which has a side effect is not allowed in FunctionalScript. There are no exceptions to this rule, such as `unsafe` code which can be found in Rust, C#, and other languages.
20
- - A module can't depend on non FunctionalScript module.
21
- - It also has no standard library, only a safe subset of standard JavaScript API can be used without referencing other modules.
19
+ - Code should not have [side-effects](https://en.wikipedia.org/wiki/Side_effect_(computer_science)). Any JavaScript statement, expression, or function which has a side effect is not allowed in FunctionalScript. There are no exceptions to this rule, such as `unsafe` code, which can be found in Rust, C#, and other languages.
20
+ - A module can't depend on a non FunctionalScript module.
21
+ - It also has no standard library. Only a safe subset of standard JavaScript API can be used without referencing other modules.
22
+
23
+ ## Applications
24
+
25
+ FunctionalScript code can be used
26
+
27
+ - in any JavaScript/TypeScript application,
28
+ - as a JSON with expressions,
29
+ - as a query language.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.307",
3
+ "version": "0.0.311",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/test.js CHANGED
@@ -11,6 +11,7 @@ require('./commonjs/package/dependencies/test')
11
11
  require('./commonjs/package/test')
12
12
  require('./commonjs/path/test')
13
13
  require('./types/function/compare/test')
14
+ require('./types/stringSet/test')
14
15
 
15
16
  /** @type {() => never} */
16
17
  const assert = () => { throw 'assert' }
@@ -44,10 +44,8 @@ const array = require('../../array')
44
44
  */
45
45
 
46
46
  /** @type {<T>(item: PathItem<T>) => _.Node<T>} */
47
- const child = item => {
48
- /** @typedef {typeof item extends PathItem<infer T> ? T : never} T */
49
- return /** @type {_.Node<T>} */(item[1][item[0]])
50
- }
47
+ const child = item =>
48
+ /** @type {typeof item extends PathItem<infer T> ? _.Node<T> : never} */(item[1][item[0]])
51
49
 
52
50
  /**
53
51
  * @template T
@@ -98,6 +96,14 @@ const find = c => {
98
96
  return f(undefined)
99
97
  }
100
98
 
99
+ /** @type {<T>(first: First<T>) => boolean} */
100
+ const isFound = first => {
101
+ switch (first[0]) {
102
+ case 1: case 3: { return true }
103
+ default: { return false }
104
+ }
105
+ }
106
+
101
107
  /** @type {<T>(first: First<T>) => T | undefined} */
102
108
  const value = first => {
103
109
  switch (first[0]) {
@@ -123,4 +129,6 @@ module.exports = {
123
129
  find,
124
130
  /** @readonly */
125
131
  value,
126
- }
132
+ /** @readonly */
133
+ isFound,
134
+ }
@@ -1,4 +1,5 @@
1
1
  const seq = require('../list')
2
+ const option = require('../option')
2
3
 
3
4
  /**
4
5
  * @template T
@@ -48,24 +49,29 @@ const seq = require('../list')
48
49
  * @typedef { Leaf1<T> | Leaf2<T> | Branch3<T> | Branch5<T>} Node
49
50
  */
50
51
 
52
+ /**
53
+ * @template T
54
+ * @typedef {Node<T> | undefined} Tree
55
+ */
56
+
51
57
  /** @type {<T>(node: Node<T>) => seq.Thunk<T>} */
52
- const values = node => () => {
58
+ const nodeValues = node => () => {
53
59
  switch (node.length) {
54
60
  case 1: case 2: { return node }
55
61
  case 3: {
56
62
  return seq.flat([
57
- values(node[0]),
63
+ nodeValues(node[0]),
58
64
  [node[1]],
59
- values(node[2])
65
+ nodeValues(node[2])
60
66
  ])
61
67
  }
62
68
  default: {
63
69
  return seq.flat([
64
- values(node[0]),
70
+ nodeValues(node[0]),
65
71
  [node[1]],
66
- values(node[2]),
72
+ nodeValues(node[2]),
67
73
  [node[3]],
68
- values(node[4])
74
+ nodeValues(node[4])
69
75
  ])
70
76
  }
71
77
  }
@@ -81,6 +87,9 @@ const values = node => () => {
81
87
  * @typedef { readonly[...Branch5<T>, T, Node<T>] } Branch7
82
88
  */
83
89
 
90
+ /** @type {<T>(tree: Tree<T>) => seq.List<T>} */
91
+ const values = option.map(nodeValues)
92
+
84
93
  module.exports = {
85
94
  /** @readonly */
86
95
  values,
@@ -1,9 +1,9 @@
1
1
  const _ = require('..')
2
- const { todo } = require('../../../dev')
3
2
  const cmp = require('../../function/compare')
4
3
  const find = require('../find')
5
4
  const list = require('../../list')
6
5
  const array = require('../../array')
6
+ const option = require('../../option')
7
7
 
8
8
  /**
9
9
  * @template T
@@ -118,8 +118,8 @@ const reduce = list.reduce(reduceX([reduceValue0, reduceValue2]))
118
118
 
119
119
  const initReduce = reduceX([initValue0, initValue1])
120
120
 
121
- /** @type {<T>(c: cmp.Compare<T>) => (node: _.Node<T>) => undefined | _.Node<T>} */
122
- const remove = c => node => {
121
+ /** @type {<T>(c: cmp.Compare<T>) => (node: _.Node<T>) => _.Tree<T>} */
122
+ const nodeRemove = c => node => {
123
123
  /** @typedef {typeof c extends cmp.Compare<infer T> ? T : never} T */
124
124
  /** @type {() => undefined | RemovePath<T>} */
125
125
  const f = () => {
@@ -159,7 +159,12 @@ const remove = c => node => {
159
159
  return result.length === 1 ? result[0] : result
160
160
  }
161
161
 
162
+ /** @type {<T>(c: cmp.Compare<T>) => (tree: _.Tree<T>) => _.Tree<T>} */
163
+ const remove = c => option.map(nodeRemove(c))
164
+
162
165
  module.exports = {
166
+ /** @readonly */
167
+ nodeRemove,
163
168
  /** @readonly */
164
169
  remove,
165
- }
170
+ }
@@ -9,7 +9,7 @@ const { sort } = require('../../object')
9
9
  const set = node => value => s.set(stringCmp(value))(value)(node)
10
10
 
11
11
  /** @type {(node: btree.Node<string>) => (value: string) => btree.Node<string> | undefined} */
12
- const remove = node => value => _.remove(stringCmp(value))(node)
12
+ const remove = node => value => _.nodeRemove(stringCmp(value))(node)
13
13
 
14
14
  const jsonStr = json.stringify(sort)
15
15
 
@@ -36,7 +36,7 @@ const reduce = a => i => {
36
36
  }
37
37
 
38
38
  /** @type {<T>(c: cmp.Compare<T>) => (value: T) => (node: _.Node<T>) => _.Node<T>} */
39
- const set = c => value => node => {
39
+ const nodeSet = c => value => node => {
40
40
  const { first, tail } = find.find(c)(node)
41
41
  /** @typedef {typeof value} T */
42
42
  /** @type {() => Bracnh1To3<T>} */
@@ -87,7 +87,10 @@ const set = c => value => node => {
87
87
  return r.length === 1 ? r[0] : r
88
88
  }
89
89
 
90
+ /** @type {<T>(c: cmp.Compare<T>) => (value: T) => (tree: _.Tree<T>) => _.Node<T>} */
91
+ const set = c => value => tree => tree === undefined ? [value] : nodeSet(c)(value)(tree)
92
+
90
93
  module.exports = {
91
94
  /** @readonly */
92
95
  set,
93
- }
96
+ }
@@ -1,22 +1,27 @@
1
- /**
1
+ /**
2
2
  * @template I
3
3
  * @template O
4
- * @typedef {(_: I) => O} Func
4
+ * @typedef {(_: I) => O} Func
5
5
  */
6
6
 
7
- /**
7
+ /**
8
8
  * Postfix Compose function.
9
9
  *
10
- * @type {<I, X>(g: Func<I, X>) => <O>(f: Func<X, O>) => Func<I, O>}
10
+ * @type {<I, X>(g: Func<I, X>) => <O>(f: Func<X, O>) => Func<I, O>}
11
11
  */
12
12
  const compose = g => f => x => f(g(x))
13
13
 
14
14
  /** @type {<T>(value: T) => T} */
15
15
  const identity = value => value
16
16
 
17
+ /** @type {<A, B, C>(f: (a: A) => (b: B) => C) => (b: B) => (a: A) => C} */
18
+ const flip = f => b => a => f(a)(b)
19
+
17
20
  module.exports = {
18
21
  /** @readonly */
19
22
  identity,
20
23
  /** @readonly */
21
24
  compose,
25
+ /** @reeadonly */
26
+ flip,
22
27
  }
@@ -1,24 +1,15 @@
1
- const option = require("../option")
2
1
  const btree = require('../btree')
3
2
  const { values } = require("../btree")
4
3
  const find = require('../btree/find')
5
4
  const s = require('../btree/set')
6
- const compare = require("../function/compare")
7
- const { stringCmp } = require("../function/compare")
8
- const list = require("../list")
5
+ const compare = require('../function/compare')
6
+ const { stringCmp } = require('../function/compare')
7
+ const list = require('../list')
8
+ const btRemove = require('../btree/remove')
9
+ const { flip } = require('../function')
9
10
 
10
11
  /** @typedef {compare.Sign} Sign */
11
12
 
12
- /**
13
- * @template T
14
- * @typedef {btree.Leaf1<T>} Leaf1
15
- */
16
-
17
- /**
18
- * @template T
19
- * @typedef {btree.Node<T>} TNode
20
- */
21
-
22
13
  /**
23
14
  * @template T
24
15
  * @typedef {compare.Compare<T>} Cmp
@@ -31,7 +22,7 @@ const list = require("../list")
31
22
 
32
23
  /**
33
24
  * @template T
34
- * @typedef {undefined|TNode<Entry<T>>} Map
25
+ * @typedef {btree.Tree<Entry<T>>} Map
35
26
  */
36
27
 
37
28
  /** @type {(a: string) => <T>(b: Entry<T>) => Sign} */
@@ -44,25 +35,20 @@ const at = name => map => {
44
35
  return result === undefined ? undefined : result[1]
45
36
  }
46
37
 
38
+ /** @type {<T>(entry: Entry<T>) => (map: Map<T>) => Map<T>} */
39
+ const setEntry = entry => s.set(keyCmp(entry[0]))(entry)
40
+
47
41
  /** @type {(name: string) => <T>(value: T) => (map: Map<T>) => Map<T>} */
48
- const set = name => value => map => {
49
- /** @type {Entry<typeof value>} */
50
- const entry = [name, value]
51
- if (map === undefined) { return [entry] }
52
- return s.set(keyCmp(name))(entry)(map)
53
- }
42
+ const set = name => value => setEntry([name, value])
54
43
 
55
44
  /** @type {<T>(map: Map<T>) => list.List<Entry<T>>} */
56
- const entries = map => map === undefined ? undefined : values(map)
57
-
58
- /** @type {<T>(map: Map<T>) => (entry: Entry<T>) => Map<T>} */
59
- const setOp = map => ([name, value]) => set(name)(value)(map)
45
+ const entries = values
60
46
 
61
47
  /** @type {<T>(entries: list.List<Entry<T>>) => Map<T>} */
62
- const fromEntries = entries => {
63
- /** @typedef {typeof entries extends list.List<Entry<infer T>> ? T : never} T */
64
- return list.reduce(setOp)(/** @type {Map<T>} */(undefined))(entries)
65
- }
48
+ const fromEntries = list.reduce(flip(setEntry))(undefined)
49
+
50
+ /** @type {(name: string) => <T>(map: Map<T>) => Map<T>} */
51
+ const remove = name => btRemove.remove(keyCmp(name))
66
52
 
67
53
  module.exports = {
68
54
  /** @readonly */
@@ -75,4 +61,6 @@ module.exports = {
75
61
  entries,
76
62
  /** @readonly */
77
63
  fromEntries,
64
+ /** @readonly */
65
+ remove,
78
66
  }
package/types/map/test.js CHANGED
@@ -1,4 +1,4 @@
1
- const { at, set, empty, entries } = require('.')
1
+ const { at, set, empty, entries, remove } = require('.')
2
2
  const seq = require('../list')
3
3
 
4
4
  {
@@ -38,6 +38,8 @@ const seq = require('../list')
38
38
  if (at('x')(m) !== undefined) { throw 'error' }
39
39
 
40
40
  // console.log(Array.from(m.entries()))
41
+ m = remove('Hello world!')(m)
42
+ if (at('Hello world!')(m) !== undefined) { throw m }
41
43
  }
42
44
 
43
45
  {
@@ -0,0 +1,36 @@
1
+ const btree = require('../btree')
2
+ const find = require('../btree/find')
3
+ const btSet = require('../btree/set')
4
+ const btRemove = require('../btree/remove')
5
+ const { stringCmp } = require("../function/compare")
6
+ const list = require('../list')
7
+ const { flip, compose } = require('../function')
8
+
9
+ /** @typedef {btree.Tree<string>} StringSet */
10
+
11
+ /** @type {(value: string) => (set: StringSet) => boolean} */
12
+ const contains = value => s => s !== undefined && find.isFound(find.find(stringCmp(value))(s).first)
13
+
14
+ /** @type {(value: string) => (s: StringSet) => StringSet} */
15
+ const set = value => btSet.set(stringCmp(value))(value)
16
+
17
+ /** @type {(s: StringSet) => list.List<string>} */
18
+ const values = btree.values
19
+
20
+ const fromValues = list.reduce(flip(set))(undefined)
21
+
22
+ /** @type {(value: string) => (s: StringSet) => StringSet} */
23
+ const remove = compose(stringCmp)(btRemove.remove)
24
+
25
+ module.exports = {
26
+ /** @readonly */
27
+ contains,
28
+ /** @readonly */
29
+ set,
30
+ /** @readonly */
31
+ values,
32
+ /** @readonly */
33
+ fromValues,
34
+ /** @readonly */
35
+ remove,
36
+ }
@@ -0,0 +1,33 @@
1
+ const _ = require('.')
2
+
3
+ {
4
+ const r = _.set('hello')(undefined)
5
+ if (!_.contains('hello')(r)) { throw r }
6
+ if (_.contains('hello1')(r)) { throw r }
7
+ }
8
+
9
+ {
10
+ let r = _.set('hello')(undefined)
11
+ r = _.set('world')(r)
12
+ r = _.set('HELLO')(r)
13
+ r = _.set('WORLD!')(r)
14
+ if (!_.contains('hello')(r)) { throw r }
15
+ if (_.contains('hello1')(r)) { throw r }
16
+ if (!_.contains('HELLO')(r)) { throw r }
17
+ if (_.contains('WORLD')(r)) { throw r }
18
+ if (!_.contains('world')(r)) { throw r }
19
+ if (_.contains('world!')(r)) { throw r }
20
+ if (!_.contains('WORLD!')(r)) { throw r }
21
+ //
22
+ r = _.remove('hello')(r)
23
+ if (_.contains('hello')(r)) { throw r }
24
+ if (!_.contains('world')(r)) { throw r }
25
+ r = _.remove('world')(r)
26
+ if (_.contains('world')(r)) { throw r }
27
+ if (!_.contains('HELLO')(r)) { throw r }
28
+ r = _.remove('HELLO')(r)
29
+ if (_.contains('HELLO')(r)) { throw r }
30
+ if (!_.contains('WORLD!')(r)) { throw r }
31
+ r = _.remove('WORLD!')(r)
32
+ if (r !== undefined) { throw r }
33
+ }