├── .editorconfig ├── LICENSE ├── README.md ├── examples ├── euclidean.ks.lua ├── fibonacci.ks.lua ├── fizzbuzz-generator.ks.lua ├── hello-world.ks.coffee ├── jsvu.ks.lua ├── readme.md ├── sleep.ks.lua ├── tsetlin-machine.ks.lua └── vue3-component.ks.vue └── transpiled ├── block.js ├── collection-composition.js ├── collection-delegation.js ├── defer.js ├── loop.js ├── module.js ├── operators.js ├── symbol.js ├── ternary.js └── with.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 4 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kesh { } 2 | 3 |

 

4 |

heyiya-if symbol

5 |

 

6 | 7 | > A long, long time from now, in the wake of what will no longer be called JavaScript, 8 | > might be going to have existed a programming language called _kesh_. 9 | 10 | **kesh** is a simple high-level programming language that hasn't been made. Its syntax is a superset of [na](https://github.com/kesh-lang/na). 11 | 12 | ```lua 13 | kesh 2025 14 | 15 | -- prototype 16 | #person: [ -- type definition 17 | name: #text -- type annotation 18 | age: #number 19 | speak(): "Hi, I'm { @name }." -- literal method (type inference) 20 | ] 21 | 22 | -- instance 23 | joe: #person [ -- new collection that delegates to #person 24 | name: 'Joe' 25 | age: 27 26 | ] 27 | 28 | -- function 29 | greet: ([name, age]: #person) -> { -- typed function (argument unpacking) 30 | name: name if age > 12 else 'kid' -- block-scoped declaration (param masking) 31 | "Hey, { name }!" -- the last evaluated expression is returned 32 | } 33 | 34 | joe.speak() --> "Hi, I'm Joe." 35 | 36 | greet joe --> "Hey, Joe!" 37 | ``` 38 | 39 | See the [Documentation](https://github.com/kesh-lang/kesh/wiki/Documentation) for more. 40 | 41 | Nothing is written in stone. Feedback and contributions are always welcome! 42 | 43 | [heyiya-if symbol](https://commons.wikimedia.org/wiki/File:Double_spirale.svg) is [CC0](https://creativecommons.org/publicdomain/zero/1.0/). Original by [Margaret Chodos-Irvine](https://chodos-irvine.com/) for [Ursula Le Guin](https://www.ursulakleguin.com/)'s novel about [the Kesh](https://www.ursulakleguin.com/kesh-music), [Always Coming Home](https://www.ursulakleguin.com/always-coming-home-book). 44 | -------------------------------------------------------------------------------- /examples/euclidean.ks.lua: -------------------------------------------------------------------------------- 1 | [abs]: import Math 2 | 3 | gcd: (a, b) -> 4 | a: abs(a) 5 | b: abs(b) 6 | a if b = 0 else gcd(b, a rem b) 7 | 8 | [gcd] 9 | -------------------------------------------------------------------------------- /examples/fibonacci.ks.lua: -------------------------------------------------------------------------------- 1 | -- tail recursion 2 | fib: (n) -> n if n < 2 else fib(n - 1) + fib(n - 2) 3 | 4 | -- memoized 5 | fib-memoized: (n, memo ? *[]) -> 6 | if memo.(n)? then memo.(n) 7 | else if n < 2 then n 8 | else set memo.(n): fib-memoized(n - 1, memo) + fib-memoized(n - 2, memo) 9 | 10 | [fib, fib-memoized] 11 | -------------------------------------------------------------------------------- /examples/fizzbuzz-generator.ks.lua: -------------------------------------------------------------------------------- 1 | -- silly example to demonstrate the generator and imperative loop extensions 2 | 3 | fizzbuzz: (n) \-> 4 | loop each 1..n as i 5 | yield "FizzBuzz" if i mod 15 = 0 6 | else "Fizz" if i mod 3 = 0 7 | else "Buzz" if i mod 5 = 0 8 | else i 9 | 10 | loop each fizzbuzz(100) as result 11 | print result 12 | -------------------------------------------------------------------------------- /examples/hello-world.ks.coffee: -------------------------------------------------------------------------------- 1 | print 'Hello, world!' 2 | -------------------------------------------------------------------------------- /examples/jsvu.ks.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env kesh-node 2 | 3 | -- original: https://raw.githubusercontent.com/GoogleChromeLabs/jsvu/main/cli.js 4 | 5 | os: require 'os' 6 | 7 | inquirer: require 'inquirer' 8 | update-notifier: require 'update-notifier' 9 | 10 | pkg: require './package.json' 11 | log: require './shared/log.js' 12 | [ get-status, set-status ]: require './shared/status.js' 13 | 14 | get-platform: () -> 15 | match os.platform() { 'darwin' -> 'mac', 'win32' -> 'win', _ -> 'linux' } 16 | 17 | os-choices: [ 18 | [ name: 'macOS 64-bit', value: 'mac64' ] 19 | [ name: 'macOS M1 64-bit', value: 'mac64arm' ] 20 | [ name: 'Linux 32-bit', value: 'linux32' ] 21 | [ name: 'Linux 64-bit', value: 'linux64' ] 22 | [ name: 'Windows 32-bit', value: 'win32' ] 23 | [ name: 'Windows 64-bit', value: 'win64' ] 24 | ] 25 | 26 | guess-os: () -> 27 | platform: get-platform() 28 | if platform = 'mac' then return 'mac64arm' if os.arch() = 'arm64' else 'mac64' 29 | 30 | -- Note: `os.arch()` returns the architecture of the Node.js process 31 | -- which does not necessarily correspond to the system architecture. 32 | -- Still, if the user runs a 64-bit version of Node.js, it’s safe to 33 | -- assume the underlying architecture is 64-bit as well. 34 | -- https://github.com/nodejs/node/issues/17036 35 | arch: '64' if os.arch().includes('64') else '32' 36 | 37 | "{ platform }{ arch }" 38 | 39 | prompt-os: () -> 40 | inquirer.prompt [ 41 | name: 'step' 42 | type: 'list' 43 | message: 'What is your operating system?' 44 | choices: os-choices 45 | default: guess-os() 46 | ] 47 | 48 | engine-choices: [ 49 | [ 50 | name: 'Chakra/ChakraCore' 51 | value: 'chakra' 52 | checked: true 53 | ] 54 | [ 55 | name: 'GraalJS' 56 | value: 'graaljs' 57 | checked: true 58 | ] 59 | [ 60 | name: 'Hermes' 61 | value: 'hermes' 62 | checked: true 63 | ] 64 | [ 65 | name: 'JavaScriptCore' 66 | value: 'javascriptcore' 67 | checked: true 68 | ] 69 | [ 70 | name: 'QuickJS' 71 | value: 'quickjs' 72 | checked: true 73 | ] 74 | [ 75 | name: 'SpiderMonkey' 76 | value: 'spidermonkey' 77 | checked: true 78 | ] 79 | [ 80 | name: 'V8' 81 | value: 'v8' 82 | checked: true 83 | ] 84 | [ 85 | name: 'V8 debug' 86 | value: 'v8-debug' 87 | checked: false 88 | ] 89 | [ 90 | name: 'XS' 91 | value: 'xs' 92 | checked: true 93 | ] 94 | ] 95 | 96 | prompt-engines: () -> 97 | inquirer.prompt [ 98 | name: 'step' 99 | type: 'checkbox' 100 | message: 'Which JavaScript engines would you like to install?' 101 | choices: engine-choices 102 | ] 103 | 104 | (async () \-> 105 | 106 | log.banner(pkg.version) 107 | 108 | -- Warn if an update is available. 109 | update-notifier([ pkg ]).notify() 110 | 111 | -- Read the user configuration + CLI arguments, and prompt for any missing info. 112 | status: get-status() 113 | 114 | args: process.argv.slice(2) 115 | 116 | loop each args as arg 117 | if arg.starts-with('--os=') 118 | os: arg.split('=').1 119 | set status.os: guess-os() if os = 'default' else os 120 | 121 | else if arg.starts-with('--engines=') 122 | engines-arg: arg.split('=').1 123 | engines: if engines-arg = 'all' 124 | then engine-choices 125 | .filter((engine) -> engine.checked) 126 | .map((engine) -> engine.value) 127 | else engines-arg.split(',') 128 | set status.engines: engines 129 | 130 | else if arg.includes('@') 131 | set status.(engine, version): arg.split('@') 132 | 133 | else 134 | wants-help: arg = '--help' or arg = '-h' 135 | if not wants-help then print.error "\nUnrecognized argument: { JSON.stringify(arg) }\n" 136 | 137 | print '[@]' 138 | print "[--os=\{{ os-choices.map((os) -> os.value).join(',') },default\}]" 139 | print "[--engines=\{{ engine-choices.map((os) -> os.value).join(',') }\},…]" 140 | 141 | print "\nComplete documentation is online:" 142 | print 'https://github.com/GoogleChromeLabs/jsvu#readme' 143 | return 144 | 145 | if status.os is #none 146 | set status.os: (await prompt-os()).step 147 | set-status(status) 148 | else 149 | log.success("Read OS from config: { status.os }") 150 | 151 | -- The user provided a specific engine + version, e.g. `jsvu v8@7.2`. 152 | if status.engine? and status.version? 153 | [ engine, version ]: status 154 | log.success("Read engine + version from CLI argument: { engine } v{ version }") 155 | install-specific-engine-version: require './shared/install-specific-version.js' 156 | await install-specific-engine-version [ require("./engines/{ engine }/index.js")..., status ] 157 | return 158 | 159 | -- The user wants to install or update engines, but we don’t know which ones. 160 | if status.engines is #none or status.engines.length = 0 161 | set status.engines: (await prompt-engines()).step 162 | if status.engines.length = 0 then log.failure('No JavaScript engines selected. Nothing to do…') 163 | set-status(status) 164 | else 165 | log.success("Read engines from config: { status.engines.join(', ') }") 166 | 167 | -- Install the desired JavaScript engines. 168 | update-engine: require './shared/engine.js' 169 | loop each status.engines as engine 170 | await update-engine [ status, require("./engines/{ engine }/index.js")... ] 171 | 172 | )() 173 | -------------------------------------------------------------------------------- /examples/readme.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | Some of these examples are direct translations from TypeScript/JavaScript code, and therefore not idiomatic kesh code. 4 | 5 | They may also contain outdated syntax. 6 | -------------------------------------------------------------------------------- /examples/sleep.ks.lua: -------------------------------------------------------------------------------- 1 | sleep: async (seconds) -> 2 | Promise (resolve) -> 3 | set-timeout(resolve, seconds * 1000ms) 4 | 5 | print 'Hold up' 6 | await sleep 1s 7 | print 'Hey!' 8 | -------------------------------------------------------------------------------- /examples/tsetlin-machine.ks.lua: -------------------------------------------------------------------------------- 1 | -- original: https://raw.githubusercontent.com/anon767/TsetlinMachine/master/tsetlin.js 2 | 3 | [ floor, random ]: import Math 4 | 5 | new-machine: [ num-classes, num-clauses, num-features, num-states, s, threshold ] -> 6 | let ta-state: array[] 7 | let clause-sign: array[] 8 | 9 | let clause-count: Array(num-classes).fill(0) 10 | let clause-output: Array(num-clauses).fill(0) 11 | let class-sum: Array(num-classes).fill(0) 12 | let feedback-to-clauses: Array(num-clauses).fill(0) 13 | 14 | init-ta-state: () \-> 15 | loop each 0 ..< num-clauses as i 16 | set ta-state.(i): array[] 17 | loop each 0 ..< num-features as j 18 | set ta-state.(i).(j): array[] 19 | set ta-state.(i).(j).0: if floor(random()) then num-states else num-states + 1 20 | set ta-state.(i).(j).1: if floor(random()) then num-states else num-states + 1 21 | 22 | init-clause-signs: () \-> 23 | loop each 0 ..< num-classes as i 24 | set clause-sign.(i): array[] 25 | loop each 0 ..< (num-clauses / num-classes) as j 26 | set clause-sign.(i).(j): array[] 27 | set clause-sign.(i).(j).0: 0 28 | set clause-sign.(i).(j).1: 0 29 | 30 | init-clause-count: () \-> 31 | loop each 0 ..< num-classes as i 32 | loop each 0 ..< floor(num-clauses / num-classes) as j 33 | set clause-sign.(i).( clause-count.(i) ).0: i * (num-clauses / num-classes) + j 34 | if j rem 2 = 0 35 | set clause-sign.(i).( clause-count.(i) ).1: 1 36 | else 37 | set clause-sign.(i).( clause-count.(i) ).1: -1 38 | increment clause-count.(i) 39 | 40 | action: (state) -> if state <= num-states then 0 else 1 41 | 42 | calc-clause-output: (x, predict ? 0) \-> 43 | loop each 0 ..< num-clauses as j 44 | set clause-output.(j): 1 45 | let all-exclude: 1 46 | loop each 0 ..< num-features as k 47 | action-include: action ta-state.(j).(k).0 48 | action-include-neg: action ta-state.(j).(k).1 49 | if action-include = 1 or action-include-neg = 1 50 | set all-exclude: 0 51 | if (action-include = 1 and x.(k) = 0) or (action-include-neg = 1 and x.(k) = 1) 52 | set clause-output.(j): 0 53 | break 54 | if predict = 1 and all-exclude = 1 55 | set clause-output.(j): 0 56 | 57 | sum-up-class-votes: () \-> 58 | loop each 0 ..< num-classes as target-class 59 | set class-sum.(target-class): 0 60 | loop each 0 ..< clause-count.(target-class) as j 61 | set class-sum.(target-class): _ 62 | + (clause-output.( clause-sign.(target-class).(j).0 ) 63 | * clause-sign.(target-class).(j).1) 64 | if class-sum.(target-class) > threshold 65 | set class-sum.(target-class): threshold 66 | else if class-sum.(target-class) < -threshold 67 | set class-sum.(target-class): -threshold 68 | 69 | predict: (x) -> 70 | calc-clause-output(x, 1) 71 | sum-up-class-votes() 72 | let max-class-sum: class-sum.0 73 | let max-class: 0 74 | loop each 1 ..< num-classes as target-class 75 | if max-class-sum < class-sum.(target-class) 76 | set max-class-sum: class-sum.(target-class) 77 | set max-class: target-class 78 | max-class 79 | 80 | update: (x, target-class) \-> 81 | -- Randomly pick one of the other classes, for pairwise learning of class output 82 | let negative-target-class: floor(num-classes * (1.0 - 1e-15) * random()) 83 | loop while negative-target-class = target-class 84 | set negative-target-class: floor(num-classes * (1.0 - 1e-15) * random()) 85 | -- Calculate Clause Output 86 | calc-clause-output(x) 87 | -- sum up clause votes 88 | sum-up-class-votes() 89 | -- calculate Feedback to Clauses 90 | 91 | loop each 0 ..< num-clauses as j -- init feedback to clauses 92 | set feedback-to-clauses.(j): 0 93 | 94 | loop each 0 ..< clause-count.(target-class) as j 95 | if random() > (1.0 / threshold * 2) * (threshold - class-sum.(target-class)) 96 | continue 97 | 98 | if clause-sign.(target-class).(j).1 > 0 99 | increment feedback-to-clauses.( clause-sign.(target-class).(j).0 ) 100 | else if clause-sign.(target-class).(j).1 < 0 101 | decrement feedback-to-clauses.( clause-sign.(target-class).(j).0 ) 102 | 103 | loop each 0 ..< clause-count.(negative-target-class) as j 104 | if random() > (1.0 / threshold * 2) * (threshold + class-sum.(negative-target-class)) 105 | continue 106 | 107 | if clause-sign.(negative-target-class).(j).1 > 0 108 | decrement feedback-to-clauses.( clause-sign.(negative-target-class).(j).0 ) 109 | else if clause-sign.(negative-target-class).(j).1 < 0) 110 | increment feedback-to-clauses.( clause-sign.(negative-target-class).(j).0 ) 111 | 112 | -- Train individual Automata 113 | loop each 0 ..< num-clauses as j 114 | if feedback-to-clauses.(j) > 0 115 | -- Type I Feedback (Combats False Negatives) 116 | if clause-output.(j) = 0 117 | loop each 0 ..< num-features as k 118 | if random() <= 1.0 / s 119 | if ta-state.(j).(k).0 > 1 120 | decrement ta-state.(j).(k).0 121 | if random() <= 1.0 / s 122 | if ta-state.(j).(k).1 > 1 123 | decrement ta-state.(j).(k).1 124 | else if clause-output.(j) = 1 125 | loop each 0 ..< num-features as k 126 | if x.(k) = 1 127 | if random() <= (s - 1) / s 128 | if ta-state.(j).(k).0 < num-states * 2 129 | increment ta-state.(j).(k).0 130 | if random() <= 1.0 / s 131 | if ta-state.(j).(k).1 > 1 132 | decrement ta-state.(j).(k).1 133 | else if x.(k) = 0 134 | if random() <= (s - 1) / s 135 | if ta-state.(j).(k).1 < num-states * 2 136 | increment ta-state.(j).(k).1 137 | if random() <= 1.0 / s 138 | if ta-state.(j).(k).0 > 1 139 | decrement ta-state.(j).(k).0 140 | else if feedback-to-clauses.(j) < 0 141 | -- Type II Feedback (Combats False Positives) 142 | if clause-output.(j) = 1 143 | loop each 0 ..< num-features as k 144 | let action-include: action ta-state.(j).(k).0 145 | let action-include-negated: action ta-state.(j).(k).1 146 | if x.(k) = 0 147 | if action-include = 0 and ta-state.(j).(k).0 < num-states * 2 148 | increment ta-state.(j).(k).0 149 | else if x.(k) = 1 150 | if action-include-negated = 0 and ta-state.(j).(k).1 < num-states * 2 151 | increment ta-state.(j).(k).1 152 | 153 | evaluate: (x, y) -> 154 | let errors: 0 155 | loop each 0 ..< x.length as l 156 | if predict x.(l) ≠ y.(l) then increment errors 157 | 1.0 - errors / x.length 158 | 159 | init-ta-state() 160 | init-clause-signs() 161 | init-clause-count() 162 | 163 | [ predict, update, evaluate ] 164 | 165 | [ new-machine ] 166 | -------------------------------------------------------------------------------- /examples/vue3-component.ks.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 26 | -------------------------------------------------------------------------------- /transpiled/block.js: -------------------------------------------------------------------------------- 1 | // https://github.com/kesh-lang/kesh/wiki/Documentation#blocks 2 | 3 | const a = 1 4 | const answer = (() => { 5 | const a = 20 6 | const b = 22 7 | return a + b 8 | })() 9 | 10 | answer // 42 11 | a // 1 12 | b // ReferenceError: b is not defined 13 | -------------------------------------------------------------------------------- /transpiled/collection-composition.js: -------------------------------------------------------------------------------- 1 | // https://github.com/kesh-lang/kesh/wiki/Documentation#composition 2 | 3 | const newPerson = (spec) => { 4 | const { name = 'Anonymous' } = spec // unpacked field from spec 5 | const aHuman = human(spec) // private field (composition) 6 | 7 | const say = (words) => { 8 | aHuman.speak(`${ name } says: ${ words }`) // no this 9 | } 10 | 11 | return Object.freeze({ name, say }) // public fields returned from function 12 | } 13 | 14 | const joe = newPerson(Object.freeze({ 15 | name: 'Joe', 16 | })) 17 | 18 | joe 19 | // Object { name: "Joe", say: say(words) } 20 | 21 | joe.say("Hi!") 22 | // "Joe says: Hi!" 23 | -------------------------------------------------------------------------------- /transpiled/collection-delegation.js: -------------------------------------------------------------------------------- 1 | // https://github.com/kesh-lang/kesh/wiki/Documentation#delegation 2 | 3 | const primate = Object.freeze({ 4 | tail: true, 5 | }) 6 | 7 | const human = Object.freeze(Object.create(primate, { // delegation 8 | tail: { value: false }, // overridden value 9 | walks: { value: true }, 10 | talks: { value: true }, 11 | })) 12 | 13 | const joe = Object.freeze(Object.create(human, { // delegation 14 | name: { value: 'Joe' }, 15 | })) 16 | 17 | // these objects are immutable: 18 | joe.name = 'Joey' 19 | joe.age = 27 20 | joe 21 | // Object { name: "Joe", tail: false, walks: true, talks: true } 22 | -------------------------------------------------------------------------------- /transpiled/defer.js: -------------------------------------------------------------------------------- 1 | // https://github.com/kesh-lang/kesh/wiki/Extensions#defer 2 | 3 | const count = () => { 4 | const $defer = [] 5 | console.log('counting') 6 | 7 | for (const number of [1, 2, 3]) { 8 | $defer.unshift(() => console.log(number)) 9 | } 10 | 11 | const $return = console.log('done') 12 | $defer.forEach(fn => fn()) 13 | return $return 14 | } 15 | 16 | count() 17 | 18 | // "counting" 19 | // "done" 20 | // 3 21 | // 2 22 | // 1 23 | -------------------------------------------------------------------------------- /transpiled/loop.js: -------------------------------------------------------------------------------- 1 | // https://github.com/kesh-lang/kesh/wiki/Extensions#imperative-loops 2 | 3 | // infinite loop 4 | while (true) { 5 | await client.listen() 6 | } 7 | 8 | // repeat a block x times 9 | for (let i = 0; i < 3; ++i) { 10 | console.log("hey") 11 | } 12 | 13 | // loop over an iterable's elements 14 | for (const number of $range(1, 10)) { 15 | if ($mod(number, 3) === 0) continue 16 | console.log(number) 17 | } 18 | 19 | // loop over a collection's own enumerable fields 20 | for ([player, points] of score) { 21 | console.log(`${player.name}: ${points} points`) 22 | } 23 | 24 | // traditional while loop 25 | while (everything === 'ok') { 26 | console.log("It's all good") 27 | } 28 | 29 | // untraditional until loop 30 | while (!done) { 31 | // todo: process something 32 | if (nothingToDo) done = true 33 | } 34 | 35 | // traditional for loop 36 | for (let i = 0; i < 9; ++i) { 37 | console.log(i) 38 | } 39 | -------------------------------------------------------------------------------- /transpiled/module.js: -------------------------------------------------------------------------------- 1 | // https://github.com/kesh-lang/kesh/wiki/Documentation#modules 2 | 3 | // https://github.com/kesh-lang/kesh/wiki/Documentation#exports 4 | 5 | const answer = 42 6 | const query = () => answer 7 | 8 | export Object.freeze({ answer, query }) 9 | 10 | 11 | // https://github.com/kesh-lang/kesh/wiki/Documentation#imports 12 | 13 | import merge from 'lodash.merge' 14 | 15 | import { query } from 'oracle.kesh' 16 | 17 | query('What is the answer to the ultimate question of life, the universe, and everything?') 18 | // 42 19 | -------------------------------------------------------------------------------- /transpiled/operators.js: -------------------------------------------------------------------------------- 1 | // https://github.com/kesh-lang/kesh/wiki/Documentation#operators 2 | 3 | // answer = 42 4 | answer === 42 5 | 6 | // answer /= '42' 7 | answer !== '42' 8 | 9 | // answer ~= '42' 10 | answer == '42' 11 | 12 | // answer ~≠ '42' 13 | answer != '42' 14 | 15 | // not true 16 | !true 17 | 18 | // true and false 19 | true && false 20 | 21 | // true or false 22 | true || false 23 | 24 | // truthy: [] 25 | // if ~truthy then print 'It is truthy' 26 | const truthy = {} 27 | if (truthy) console.log('It is truthy') 28 | 29 | // if page.title? and page.author? 30 | if (page.title !== undefined && page.author !== undefined) {} 31 | 32 | // title: page.title ? 'Default title' 33 | const title = page.title ?? 'Default title' 34 | 35 | // spread: [items..., item] 36 | const spread = { ...items, item } 37 | 38 | // rest: (...arguments) -> print arguments 39 | const rest = (...arguments) => console.log(arguments) 40 | 41 | // [age as years-old]: ada 42 | const { age: yearsOld } = ada 43 | 44 | // 4 + #number '2' 45 | 4 + Number('2') 46 | 47 | // joe inherits primate 48 | Object.prototype.isPrototypeOf.call(primate, joe) 49 | inherits(primate, joe) // function version 50 | 51 | // joe is-a human 52 | Reflect.getPrototypeOf(joe) === human 53 | isA(human, joe) // function version 54 | 55 | // answer is #number 56 | typeof answer === 'number' 57 | is('number', answer) // function version 58 | 59 | // answer isnt #text 60 | typeof answer !== 'string' 61 | isnt('string', answer) // function version 62 | 63 | // people has joe 64 | has(joe, people) // only as a function 65 | 66 | 67 | // rudimentary implementation of has function 68 | function has(val, col) { 69 | if (Array.isArray(col)) { 70 | return col.includes(val) 71 | } 72 | else if (col instanceof Set || col instanceof Map) { 73 | return col.has(val) 74 | } 75 | else { 76 | return Reflect.has(col, val) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /transpiled/symbol.js: -------------------------------------------------------------------------------- 1 | // https://github.com/kesh-lang/kesh/wiki/Documentation#hidden-fields 2 | // https://github.com/kesh-lang/kesh/wiki/Documentation#computed-keys 3 | // https://github.com/kesh-lang/kesh/wiki/Documentation#field-access 4 | 5 | // secret: @('hidden talent') 6 | const secret = Symbol('hidden talent') // secret symbol 7 | 8 | // person: object[ name: 'Joe', @cool: true, { secret }: 'I can moonwalk!' ] 9 | const person = Object.freeze({ 10 | name: 'Joe', 11 | [Symbol.for('cool')]: true, 12 | [secret]: "I can moonwalk!", 13 | }) 14 | 15 | // keys person 16 | keys(person) 17 | // Array [ "name" ] 18 | 19 | // person.@cool 20 | person[Symbol.for('cool')] 21 | // true 22 | 23 | // person.{ secret } 24 | person[secret] 25 | // "I can moonwalk!" 26 | 27 | 28 | keys = (collection) => { 29 | const keys = [] 30 | for (const key in collection) { 31 | keys.push(key) 32 | } 33 | return keys 34 | } 35 | -------------------------------------------------------------------------------- /transpiled/ternary.js: -------------------------------------------------------------------------------- 1 | // https://github.com/kesh-lang/kesh/wiki/Documentation#conditionals 2 | 3 | const inline = age < 13 ? 'kid' : age < 20 ? 'teenager' : 'adult' 4 | const ternary = age < 13 ? 'kid' : age < 20 ? 'teenager' : 'adult' 5 | -------------------------------------------------------------------------------- /transpiled/with.js: -------------------------------------------------------------------------------- 1 | // https://github.com/kesh-lang/kesh/wiki/Extensions#with 2 | 3 | const open = async function*(path) { 4 | const file = await fs.open(path) 5 | console.log("file opened") 6 | 7 | yield file 8 | 9 | file.close() 10 | console.log("file closed") 11 | } 12 | 13 | for await (const file of open("./hello.txt")) { 14 | console.log(file.contents) 15 | } 16 | --------------------------------------------------------------------------------