conjure-js 0.0.1

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.
Files changed (80) hide show
  1. package/conjure +0 -0
  2. package/dist/assets/codicon-ngg6Pgfi.ttf +0 -0
  3. package/dist/assets/editor.worker-CdQrwHl8.js +26 -0
  4. package/dist/assets/main-A7ZMId9A.css +1 -0
  5. package/dist/assets/main-CmI-7epE.js +3137 -0
  6. package/dist/index.html +195 -0
  7. package/dist/vite.svg +1 -0
  8. package/package.json +68 -0
  9. package/src/bin/__fixtures__/smoke/app/lib.clj +4 -0
  10. package/src/bin/__fixtures__/smoke/app/main.clj +4 -0
  11. package/src/bin/__fixtures__/smoke/repl-smoke.ts +12 -0
  12. package/src/bin/bencode.ts +205 -0
  13. package/src/bin/cli.ts +250 -0
  14. package/src/bin/nrepl-utils.ts +59 -0
  15. package/src/bin/nrepl.ts +393 -0
  16. package/src/bin/version.ts +4 -0
  17. package/src/clojure/core.clj +620 -0
  18. package/src/clojure/core.clj.d.ts +189 -0
  19. package/src/clojure/demo/math.clj +16 -0
  20. package/src/clojure/demo/math.clj.d.ts +4 -0
  21. package/src/clojure/demo.clj +42 -0
  22. package/src/clojure/demo.clj.d.ts +0 -0
  23. package/src/clojure/generated/builtin-namespace-registry.ts +14 -0
  24. package/src/clojure/generated/clojure-core-source.ts +623 -0
  25. package/src/clojure/generated/clojure-string-source.ts +196 -0
  26. package/src/clojure/string.clj +192 -0
  27. package/src/clojure/string.clj.d.ts +25 -0
  28. package/src/core/assertions.ts +134 -0
  29. package/src/core/conversions.ts +108 -0
  30. package/src/core/core-env.ts +58 -0
  31. package/src/core/env.ts +78 -0
  32. package/src/core/errors.ts +39 -0
  33. package/src/core/evaluator/apply.ts +114 -0
  34. package/src/core/evaluator/arity.ts +174 -0
  35. package/src/core/evaluator/collections.ts +25 -0
  36. package/src/core/evaluator/destructure.ts +247 -0
  37. package/src/core/evaluator/dispatch.ts +73 -0
  38. package/src/core/evaluator/evaluate.ts +100 -0
  39. package/src/core/evaluator/expand.ts +79 -0
  40. package/src/core/evaluator/index.ts +72 -0
  41. package/src/core/evaluator/quasiquote.ts +87 -0
  42. package/src/core/evaluator/recur-check.ts +109 -0
  43. package/src/core/evaluator/special-forms.ts +517 -0
  44. package/src/core/factories.ts +155 -0
  45. package/src/core/gensym.ts +9 -0
  46. package/src/core/index.ts +76 -0
  47. package/src/core/positions.ts +38 -0
  48. package/src/core/printer.ts +86 -0
  49. package/src/core/reader.ts +559 -0
  50. package/src/core/scanners.ts +93 -0
  51. package/src/core/session.ts +610 -0
  52. package/src/core/stdlib/arithmetic.ts +361 -0
  53. package/src/core/stdlib/atoms.ts +88 -0
  54. package/src/core/stdlib/collections.ts +784 -0
  55. package/src/core/stdlib/errors.ts +81 -0
  56. package/src/core/stdlib/hof.ts +307 -0
  57. package/src/core/stdlib/meta.ts +48 -0
  58. package/src/core/stdlib/predicates.ts +240 -0
  59. package/src/core/stdlib/regex.ts +238 -0
  60. package/src/core/stdlib/strings.ts +311 -0
  61. package/src/core/stdlib/transducers.ts +256 -0
  62. package/src/core/stdlib/utils.ts +287 -0
  63. package/src/core/tokenizer.ts +437 -0
  64. package/src/core/transformations.ts +75 -0
  65. package/src/core/types.ts +258 -0
  66. package/src/main.ts +1 -0
  67. package/src/monaco-esm.d.ts +7 -0
  68. package/src/playground/clojure-tokens.ts +67 -0
  69. package/src/playground/editor.worker.ts +5 -0
  70. package/src/playground/find-form.ts +138 -0
  71. package/src/playground/playground.ts +342 -0
  72. package/src/playground/samples/00-welcome.clj +385 -0
  73. package/src/playground/samples/01-collections.clj +191 -0
  74. package/src/playground/samples/02-higher-order-functions.clj +215 -0
  75. package/src/playground/samples/03-destructuring.clj +194 -0
  76. package/src/playground/samples/04-strings-and-regex.clj +202 -0
  77. package/src/playground/samples/05-error-handling.clj +212 -0
  78. package/src/repl/repl.ts +116 -0
  79. package/tsconfig.build.json +10 -0
  80. package/tsconfig.json +31 -0
@@ -0,0 +1,81 @@
1
+ import { CljThrownSignal, EvaluationError } from '../errors'
2
+ import { cljKeyword, cljMap, cljNativeFunction, cljNil, withDoc } from '../factories'
3
+ import { isKeyword, isMap } from '../assertions'
4
+ import type { CljValue } from '../types'
5
+
6
+ export const errorFunctions = {
7
+ throw: withDoc(
8
+ cljNativeFunction('throw', (...args: CljValue[]) => {
9
+ if (args.length !== 1) {
10
+ throw new EvaluationError(
11
+ `throw requires exactly 1 argument, got ${args.length}`,
12
+ { args }
13
+ )
14
+ }
15
+ throw new CljThrownSignal(args[0])
16
+ }),
17
+ 'Throws a value as an exception. The value may be any CljValue; maps are idiomatic.',
18
+ [['value']]
19
+ ),
20
+
21
+ 'ex-info': withDoc(
22
+ cljNativeFunction('ex-info', (...args: CljValue[]) => {
23
+ if (args.length < 2) {
24
+ throw new EvaluationError(
25
+ `ex-info requires at least 2 arguments, got ${args.length}`,
26
+ { args }
27
+ )
28
+ }
29
+ const [msg, data, cause] = args
30
+ if (msg.kind !== 'string') {
31
+ throw new EvaluationError(
32
+ 'ex-info: first argument must be a string',
33
+ { msg }
34
+ )
35
+ }
36
+ const entries: [CljValue, CljValue][] = [
37
+ [cljKeyword(':message'), msg],
38
+ [cljKeyword(':data'), data],
39
+ ]
40
+ if (cause !== undefined) {
41
+ entries.push([cljKeyword(':cause'), cause])
42
+ }
43
+ return cljMap(entries)
44
+ }),
45
+ 'Creates an error map with :message and :data keys. Optionally accepts a :cause.',
46
+ [['msg', 'data'], ['msg', 'data', 'cause']]
47
+ ),
48
+
49
+ 'ex-message': withDoc(
50
+ cljNativeFunction('ex-message', (...args: CljValue[]) => {
51
+ const [e] = args
52
+ if (!isMap(e)) return cljNil()
53
+ const entry = e.entries.find(([k]) => isKeyword(k) && k.name === ':message')
54
+ return entry ? entry[1] : cljNil()
55
+ }),
56
+ 'Returns the :message of an error map, or nil.',
57
+ [['e']]
58
+ ),
59
+
60
+ 'ex-data': withDoc(
61
+ cljNativeFunction('ex-data', (...args: CljValue[]) => {
62
+ const [e] = args
63
+ if (!isMap(e)) return cljNil()
64
+ const entry = e.entries.find(([k]) => isKeyword(k) && k.name === ':data')
65
+ return entry ? entry[1] : cljNil()
66
+ }),
67
+ 'Returns the :data map of an error map, or nil.',
68
+ [['e']]
69
+ ),
70
+
71
+ 'ex-cause': withDoc(
72
+ cljNativeFunction('ex-cause', (...args: CljValue[]) => {
73
+ const [e] = args
74
+ if (!isMap(e)) return cljNil()
75
+ const entry = e.entries.find(([k]) => isKeyword(k) && k.name === ':cause')
76
+ return entry ? entry[1] : cljNil()
77
+ }),
78
+ 'Returns the :cause of an error map, or nil.',
79
+ [['e']]
80
+ ),
81
+ }
@@ -0,0 +1,307 @@
1
+ // Higher-order functions: map, filter, reduce, apply, partial, comp,
2
+ // map-indexed, identity
3
+ import {
4
+ isAFunction,
5
+ isCallable,
6
+ isNil,
7
+ isReduced,
8
+ isSeqable,
9
+ } from '../assertions'
10
+ import { EvaluationError } from '../errors'
11
+ import {
12
+ cljNativeFunction,
13
+ cljNativeFunctionWithContext,
14
+ withDoc,
15
+ } from '../factories'
16
+ import { printString } from '../printer'
17
+ import { toSeq } from '../transformations'
18
+ import type { CljValue, Env, EvaluationContext } from '../types'
19
+
20
+ export const hofFunctions: Record<string, CljValue> = {
21
+ // map: cljNativeFunctionWithContext(
22
+ // 'map',
23
+ // (
24
+ // ctx: EvaluationContext,
25
+ // fn: CljValue | undefined,
26
+ // collection: CljValue | undefined
27
+ // ): CljValue => {
28
+ // if (fn === undefined) {
29
+ // throw new EvaluationError(
30
+ // `map expects a function as first argument, got nil`,
31
+ // { fn }
32
+ // )
33
+ // }
34
+ // if (!isAFunction(fn)) {
35
+ // throw new EvaluationError(
36
+ // `map expects a function as first argument, got ${printString(fn)}`,
37
+ // { fn }
38
+ // )
39
+ // }
40
+ // if (collection === undefined) {
41
+ // return cljNil()
42
+ // }
43
+ // if (!isCollection(collection)) {
44
+ // throw new EvaluationError(
45
+ // `map expects a collection, got ${printString(collection)}`,
46
+ // { collection }
47
+ // )
48
+ // }
49
+
50
+ // const wrap = isVector(collection) ? cljVector : cljList
51
+ // return wrap(
52
+ // toSeq(collection).map((item) => ctx.applyFunction(fn, [item]))
53
+ // )
54
+ // }
55
+ // ),
56
+ // filter: cljNativeFunctionWithContext(
57
+ // 'filter',
58
+ // (
59
+ // ctx: EvaluationContext,
60
+ // fn: CljValue | undefined,
61
+ // collection: CljValue | undefined
62
+ // ): CljValue => {
63
+ // if (fn === undefined) {
64
+ // throw new EvaluationError(
65
+ // `filter expects a function as first argument, got nil`,
66
+ // { fn }
67
+ // )
68
+ // }
69
+ // if (!isAFunction(fn)) {
70
+ // throw new EvaluationError(
71
+ // `filter expects a function as first argument, got ${printString(fn)}`,
72
+ // { fn }
73
+ // )
74
+ // }
75
+ // if (collection === undefined) {
76
+ // return cljNil()
77
+ // }
78
+ // if (!isCollection(collection)) {
79
+ // throw new EvaluationError(
80
+ // `filter expects a collection, got ${printString(collection)}`,
81
+ // { collection }
82
+ // )
83
+ // }
84
+
85
+ // const wrap = isVector(collection) ? cljVector : cljList
86
+ // return wrap(
87
+ // toSeq(collection).filter((item) =>
88
+ // isTruthy(ctx.applyFunction(fn, [item]))
89
+ // )
90
+ // )
91
+ // }
92
+ // ),
93
+ reduce: withDoc(
94
+ cljNativeFunctionWithContext(
95
+ 'reduce',
96
+ (
97
+ ctx: EvaluationContext,
98
+ callEnv: Env,
99
+ fn: CljValue,
100
+ ...rest: CljValue[]
101
+ ) => {
102
+ if (fn === undefined || !isAFunction(fn)) {
103
+ throw new EvaluationError(
104
+ `reduce expects a function as first argument${fn !== undefined ? `, got ${printString(fn)}` : ''}`,
105
+ { fn }
106
+ )
107
+ }
108
+ if (rest.length === 0 || rest.length > 2) {
109
+ throw new EvaluationError(
110
+ 'reduce expects 2 or 3 arguments: (reduce f coll) or (reduce f init coll)',
111
+ { fn }
112
+ )
113
+ }
114
+
115
+ const hasInit = rest.length === 2
116
+ const init: CljValue | undefined = hasInit ? rest[0] : undefined
117
+ const collection = hasInit ? rest[1] : rest[0]
118
+
119
+ // nil is treated as an empty collection (matches Clojure semantics)
120
+ if (collection.kind === 'nil') {
121
+ if (!hasInit) {
122
+ throw new EvaluationError(
123
+ 'reduce called on empty collection with no initial value',
124
+ { fn }
125
+ )
126
+ }
127
+ return init!
128
+ }
129
+
130
+ if (!isSeqable(collection)) {
131
+ throw new EvaluationError(
132
+ `reduce expects a collection or string, got ${printString(collection)}`,
133
+ { collection }
134
+ )
135
+ }
136
+
137
+ const items = toSeq(collection)
138
+
139
+ if (!hasInit) {
140
+ if (items.length === 0) {
141
+ throw new EvaluationError(
142
+ 'reduce called on empty collection with no initial value',
143
+ { fn }
144
+ )
145
+ }
146
+ if (items.length === 1) return items[0]
147
+ let acc = items[0]
148
+ for (let i = 1; i < items.length; i++) {
149
+ const result = ctx.applyFunction(fn, [acc, items[i]], callEnv)
150
+ if (isReduced(result)) return result.value
151
+ acc = result
152
+ }
153
+ return acc
154
+ }
155
+
156
+ let acc = init!
157
+ for (const item of items) {
158
+ const result = ctx.applyFunction(fn, [acc, item], callEnv)
159
+ if (isReduced(result)) return result.value
160
+ acc = result
161
+ }
162
+ return acc
163
+ }
164
+ ),
165
+ 'Reduces a collection to a single value by iteratively applying f. (reduce f coll) or (reduce f init coll).',
166
+ [
167
+ ['f', 'coll'],
168
+ ['f', 'val', 'coll'],
169
+ ]
170
+ ),
171
+
172
+ apply: withDoc(
173
+ cljNativeFunctionWithContext(
174
+ 'apply',
175
+ (
176
+ ctx: EvaluationContext,
177
+ callEnv: Env,
178
+ fn: CljValue | undefined,
179
+ ...rest: CljValue[]
180
+ ) => {
181
+ if (fn === undefined || !isCallable(fn)) {
182
+ throw new EvaluationError(
183
+ `apply expects a callable as first argument${fn !== undefined ? `, got ${printString(fn)}` : ''}`,
184
+ { fn }
185
+ )
186
+ }
187
+ if (rest.length === 0) {
188
+ throw new EvaluationError('apply expects at least 2 arguments', {
189
+ fn,
190
+ })
191
+ }
192
+ const lastArg = rest[rest.length - 1]
193
+ if (!isNil(lastArg) && !isSeqable(lastArg)) {
194
+ throw new EvaluationError(
195
+ `apply expects a collection or string as last argument, got ${printString(lastArg)}`,
196
+ { lastArg }
197
+ )
198
+ }
199
+
200
+ const args = [
201
+ ...rest.slice(0, -1),
202
+ ...(isNil(lastArg) ? [] : toSeq(lastArg)),
203
+ ]
204
+ return ctx.applyCallable(fn, args, callEnv)
205
+ }
206
+ ),
207
+ 'Calls f with the elements of the last argument (a collection) as its arguments, optionally prepended by fixed args.',
208
+ [
209
+ ['f', 'args'],
210
+ ['f', '&', 'args'],
211
+ ]
212
+ ),
213
+
214
+ partial: withDoc(
215
+ cljNativeFunction('partial', (fn: CljValue, ...preArgs: CljValue[]) => {
216
+ if (fn === undefined || !isCallable(fn)) {
217
+ throw new EvaluationError(
218
+ `partial expects a callable as first argument${fn !== undefined ? `, got ${printString(fn)}` : ''}`,
219
+ { fn }
220
+ )
221
+ }
222
+ const capturedFn = fn
223
+ return cljNativeFunctionWithContext(
224
+ 'partial',
225
+ (ctx: EvaluationContext, callEnv: Env, ...moreArgs: CljValue[]) => {
226
+ return ctx.applyCallable(
227
+ capturedFn,
228
+ [...preArgs, ...moreArgs],
229
+ callEnv
230
+ )
231
+ }
232
+ )
233
+ }),
234
+ 'Returns a function that calls f with pre-applied args prepended to any additional arguments.',
235
+ [['f', '&', 'args']]
236
+ ),
237
+
238
+ comp: withDoc(
239
+ cljNativeFunction('comp', (...fns: CljValue[]) => {
240
+ if (fns.length === 0) {
241
+ return cljNativeFunction('identity', (x: CljValue) => x)
242
+ }
243
+ if (fns.some((f) => !isCallable(f))) {
244
+ throw new EvaluationError(
245
+ 'comp expects functions or other callable values (keywords, maps)',
246
+ { fns }
247
+ )
248
+ }
249
+ const capturedFns = fns
250
+ return cljNativeFunctionWithContext(
251
+ 'composed',
252
+ (ctx: EvaluationContext, callEnv: Env, ...args: CljValue[]) => {
253
+ let result = ctx.applyCallable(
254
+ capturedFns[capturedFns.length - 1],
255
+ args,
256
+ callEnv
257
+ )
258
+ for (let i = capturedFns.length - 2; i >= 0; i--) {
259
+ result = ctx.applyCallable(capturedFns[i], [result], callEnv)
260
+ }
261
+ return result
262
+ }
263
+ )
264
+ }),
265
+ 'Returns the composition of fns, applied right-to-left. (comp f g) is equivalent to (fn [x] (f (g x))). Accepts any callable: functions, keywords, and maps.',
266
+ [[], ['f'], ['f', 'g'], ['f', 'g', '&', 'fns']]
267
+ ),
268
+
269
+ // 'map-indexed': cljNativeFunctionWithContext(
270
+ // 'map-indexed',
271
+ // (ctx: EvaluationContext, fn: CljValue, coll: CljValue): CljValue => {
272
+ // if (fn === undefined || !isAFunction(fn)) {
273
+ // throw new EvaluationError(
274
+ // `map-indexed expects a function as first argument${fn !== undefined ? `, got ${printString(fn)}` : ''}`,
275
+ // { fn }
276
+ // )
277
+ // }
278
+ // if (coll === undefined || !isCollection(coll)) {
279
+ // throw new EvaluationError(
280
+ // `map-indexed expects a collection as second argument${coll !== undefined ? `, got ${printString(coll)}` : ''}`,
281
+ // { coll }
282
+ // )
283
+ // }
284
+ // const items = toSeq(coll)
285
+ // const wrap = isVector(coll) ? cljVector : cljList
286
+ // return wrap(
287
+ // items.map((item, idx) =>
288
+ // ctx.applyFunction(fn as CljFunction | CljNativeFunction, [
289
+ // cljNumber(idx),
290
+ // item,
291
+ // ])
292
+ // )
293
+ // )
294
+ // }
295
+ // ),
296
+
297
+ identity: withDoc(
298
+ cljNativeFunction('identity', (x: CljValue) => {
299
+ if (x === undefined) {
300
+ throw new EvaluationError('identity expects one argument', {})
301
+ }
302
+ return x
303
+ }),
304
+ 'Returns its single argument unchanged.',
305
+ [['x']]
306
+ ),
307
+ }
@@ -0,0 +1,48 @@
1
+ // Metadata: with-meta, meta
2
+ import { EvaluationError } from '../errors'
3
+ import { cljNativeFunction, cljNil, withDoc } from '../factories'
4
+ import { printString } from '../printer'
5
+ import type { CljMap, CljValue } from '../types'
6
+
7
+ export const metaFunctions: Record<string, CljValue> = {
8
+ meta: withDoc(
9
+ cljNativeFunction('meta', (val: CljValue) => {
10
+ if (val === undefined) {
11
+ throw new EvaluationError('meta expects one argument', {})
12
+ }
13
+ if (val.kind === 'function' || val.kind === 'native-function') {
14
+ return val.meta ?? cljNil()
15
+ }
16
+ return cljNil()
17
+ }),
18
+ 'Returns the metadata map of a value, or nil if the value has no metadata.',
19
+ [['val']]
20
+ ),
21
+
22
+ 'with-meta': withDoc(
23
+ cljNativeFunction('with-meta', (val: CljValue, m: CljValue) => {
24
+ if (val === undefined) {
25
+ throw new EvaluationError('with-meta expects two arguments', {})
26
+ }
27
+ if (m === undefined) {
28
+ throw new EvaluationError('with-meta expects two arguments', {})
29
+ }
30
+ if (m.kind !== 'map' && m.kind !== 'nil') {
31
+ throw new EvaluationError(
32
+ `with-meta expects a map as second argument, got ${printString(m)}`,
33
+ { m }
34
+ )
35
+ }
36
+ if (val.kind !== 'function' && val.kind !== 'native-function') {
37
+ throw new EvaluationError(
38
+ `with-meta only supports functions, got ${printString(val)}`,
39
+ { val }
40
+ )
41
+ }
42
+ const meta = m.kind === 'nil' ? undefined : (m as CljMap)
43
+ return { ...val, meta }
44
+ }),
45
+ 'Returns a new value with the metadata map m applied to val.',
46
+ [['val', 'm']]
47
+ ),
48
+ }
@@ -0,0 +1,240 @@
1
+ // Predicates & logical: nil?, true?, false?, truthy?, falsy?, not, not=,
2
+ // number?, string?, boolean?, vector?, list?, map?, keyword?, symbol?, fn?,
3
+ // coll?, some, every?
4
+ import {
5
+ isAFunction,
6
+ isCollection,
7
+ isEqual,
8
+ isFalsy,
9
+ isKeyword,
10
+ isSeqable,
11
+ isSymbol,
12
+ isTruthy,
13
+ isList,
14
+ isVector,
15
+ isMap,
16
+ } from '../assertions'
17
+ import { applyFunction } from '../evaluator'
18
+ import { EvaluationError } from '../errors'
19
+ import { cljBoolean, cljNativeFunction, cljNil, withDoc } from '../factories'
20
+ import { printString } from '../printer'
21
+ import { toSeq } from '../transformations'
22
+ import type { CljValue } from '../types'
23
+
24
+ export const predicateFunctions: Record<string, CljValue> = {
25
+ 'nil?': withDoc(
26
+ cljNativeFunction('nil?', (arg: CljValue) => {
27
+ return cljBoolean(arg.kind === 'nil')
28
+ }),
29
+ 'Returns true if the value is nil, false otherwise.',
30
+ [['arg']]
31
+ ),
32
+ 'true?': withDoc(
33
+ cljNativeFunction('true?', (arg: CljValue) => {
34
+ // returns true if the value is a boolean and true
35
+ if (arg.kind !== 'boolean') {
36
+ return cljBoolean(false)
37
+ }
38
+ return cljBoolean(arg.value === true)
39
+ }),
40
+ 'Returns true if the value is a boolean and true, false otherwise.',
41
+ [['arg']]
42
+ ),
43
+ 'false?': withDoc(
44
+ cljNativeFunction('false?', (arg: CljValue) => {
45
+ // returns true if the value is a boolean and false
46
+ if (arg.kind !== 'boolean') {
47
+ return cljBoolean(false)
48
+ }
49
+ return cljBoolean(arg.value === false)
50
+ }),
51
+ 'Returns true if the value is a boolean and false, false otherwise.',
52
+ [['arg']]
53
+ ),
54
+ 'truthy?': withDoc(
55
+ cljNativeFunction('truthy?', (arg: CljValue) => {
56
+ return cljBoolean(isTruthy(arg))
57
+ }),
58
+ 'Returns true if the value is not nil or false, false otherwise.',
59
+ [['arg']]
60
+ ),
61
+ 'falsy?': withDoc(
62
+ cljNativeFunction('falsy?', (arg: CljValue) => {
63
+ return cljBoolean(isFalsy(arg))
64
+ }),
65
+ 'Returns true if the value is nil or false, false otherwise.',
66
+ [['arg']]
67
+ ),
68
+ // not: withDoc(
69
+ // cljNativeFunction('not', (arg: CljValue) => {
70
+ // return cljBoolean(!isTruthy(arg))
71
+ // }),
72
+ // 'Returns the negation of the truthiness of the value.',
73
+ // [['arg']]
74
+ // ),
75
+ 'not=': withDoc(
76
+ cljNativeFunction('not=', (...vals: CljValue[]) => {
77
+ if (vals.length < 2) {
78
+ throw new EvaluationError('not= expects at least two arguments', {
79
+ args: vals,
80
+ })
81
+ }
82
+ for (let i = 1; i < vals.length; i++) {
83
+ if (!isEqual(vals[i], vals[i - 1])) {
84
+ return cljBoolean(true)
85
+ }
86
+ }
87
+ return cljBoolean(false)
88
+ }),
89
+ 'Returns true if any two adjacent arguments are not equal, false otherwise.',
90
+ [['&', 'vals']]
91
+ ),
92
+ 'number?': withDoc(
93
+ cljNativeFunction('number?', (x: CljValue) =>
94
+ cljBoolean(x !== undefined && x.kind === 'number')
95
+ ),
96
+ 'Returns true if the value is a number, false otherwise.',
97
+ [['x']]
98
+ ),
99
+
100
+ 'string?': withDoc(
101
+ cljNativeFunction('string?', (x: CljValue) =>
102
+ cljBoolean(x !== undefined && x.kind === 'string')
103
+ ),
104
+ 'Returns true if the value is a string, false otherwise.',
105
+ [['x']]
106
+ ),
107
+
108
+ 'boolean?': withDoc(
109
+ cljNativeFunction('boolean?', (x: CljValue) =>
110
+ cljBoolean(x !== undefined && x.kind === 'boolean')
111
+ ),
112
+ 'Returns true if the value is a boolean, false otherwise.',
113
+ [['x']]
114
+ ),
115
+
116
+ 'vector?': withDoc(
117
+ cljNativeFunction('vector?', (x: CljValue) =>
118
+ cljBoolean(x !== undefined && isVector(x))
119
+ ),
120
+ 'Returns true if the value is a vector, false otherwise.',
121
+ [['x']]
122
+ ),
123
+
124
+ 'list?': withDoc(
125
+ cljNativeFunction('list?', (x: CljValue) =>
126
+ cljBoolean(x !== undefined && isList(x))
127
+ ),
128
+ 'Returns true if the value is a list, false otherwise.',
129
+ [['x']]
130
+ ),
131
+
132
+ 'map?': withDoc(
133
+ cljNativeFunction('map?', (x: CljValue) =>
134
+ cljBoolean(x !== undefined && isMap(x))
135
+ ),
136
+ 'Returns true if the value is a map, false otherwise.',
137
+ [['x']]
138
+ ),
139
+
140
+ 'keyword?': withDoc(
141
+ cljNativeFunction('keyword?', (x: CljValue) =>
142
+ cljBoolean(x !== undefined && isKeyword(x))
143
+ ),
144
+ 'Returns true if the value is a keyword, false otherwise.',
145
+ [['x']]
146
+ ),
147
+
148
+ 'qualified-keyword?': withDoc(
149
+ cljNativeFunction('qualified-keyword?', (x: CljValue) =>
150
+ cljBoolean(x !== undefined && isKeyword(x) && x.name.includes('/'))
151
+ ),
152
+ 'Returns true if the value is a qualified keyword, false otherwise.',
153
+ [['x']]
154
+ ),
155
+
156
+ 'symbol?': withDoc(
157
+ cljNativeFunction('symbol?', (x: CljValue) =>
158
+ cljBoolean(x !== undefined && isSymbol(x))
159
+ ),
160
+ 'Returns true if the value is a symbol, false otherwise.',
161
+ [['x']]
162
+ ),
163
+
164
+ 'qualified-symbol?': withDoc(
165
+ cljNativeFunction('qualified-symbol?', (x: CljValue) =>
166
+ cljBoolean(x !== undefined && isSymbol(x) && x.name.includes('/'))
167
+ ),
168
+ 'Returns true if the value is a qualified symbol, false otherwise.',
169
+ [['x']]
170
+ ),
171
+
172
+ 'fn?': withDoc(
173
+ cljNativeFunction('fn?', (x: CljValue) =>
174
+ cljBoolean(x !== undefined && isAFunction(x))
175
+ ),
176
+ 'Returns true if the value is a function, false otherwise.',
177
+ [['x']]
178
+ ),
179
+
180
+ 'coll?': withDoc(
181
+ cljNativeFunction('coll?', (x: CljValue) =>
182
+ cljBoolean(x !== undefined && isCollection(x))
183
+ ),
184
+ 'Returns true if the value is a collection, false otherwise.',
185
+ [['x']]
186
+ ),
187
+ some: withDoc(
188
+ cljNativeFunction('some', (pred: CljValue, coll: CljValue): CljValue => {
189
+ if (pred === undefined || !isAFunction(pred)) {
190
+ throw new EvaluationError(
191
+ `some expects a function as first argument${pred !== undefined ? `, got ${printString(pred)}` : ''}`,
192
+ { pred }
193
+ )
194
+ }
195
+ if (coll === undefined) {
196
+ return cljNil()
197
+ }
198
+ if (!isSeqable(coll)) {
199
+ throw new EvaluationError(
200
+ `some expects a collection or string as second argument, got ${printString(coll)}`,
201
+ { coll }
202
+ )
203
+ }
204
+ for (const item of toSeq(coll)) {
205
+ const result = applyFunction(pred, [item])
206
+ if (isTruthy(result)) {
207
+ return result
208
+ }
209
+ }
210
+ return cljNil()
211
+ }),
212
+ 'Returns the first truthy result of applying pred to each item in coll, or nil if no item satisfies pred.',
213
+ [['pred', 'coll']]
214
+ ),
215
+
216
+ 'every?': withDoc(
217
+ cljNativeFunction('every?', (pred: CljValue, coll: CljValue): CljValue => {
218
+ if (pred === undefined || !isAFunction(pred)) {
219
+ throw new EvaluationError(
220
+ `every? expects a function as first argument${pred !== undefined ? `, got ${printString(pred)}` : ''}`,
221
+ { pred }
222
+ )
223
+ }
224
+ if (coll === undefined || !isSeqable(coll)) {
225
+ throw new EvaluationError(
226
+ `every? expects a collection or string as second argument${coll !== undefined ? `, got ${printString(coll)}` : ''}`,
227
+ { coll }
228
+ )
229
+ }
230
+ for (const item of toSeq(coll)) {
231
+ if (isFalsy(applyFunction(pred, [item]))) {
232
+ return cljBoolean(false)
233
+ }
234
+ }
235
+ return cljBoolean(true)
236
+ }),
237
+ 'Returns true if all items in coll satisfy pred, false otherwise.',
238
+ [['pred', 'coll']]
239
+ ),
240
+ }