freelang-editor 11.7.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.
Files changed (1473) hide show
  1. package/.config/jest.config.js +47 -0
  2. package/.config/jest.fast.config.js +9 -0
  3. package/.config/openapi.yaml +457 -0
  4. package/.config/tsconfig.json +30 -0
  5. package/.github/CODE_OF_CONDUCT.md +176 -0
  6. package/.github/CONTRIBUTING.md +296 -0
  7. package/.github/DISCUSSIONS.md +179 -0
  8. package/.github/ISSUE_TEMPLATE/bug-report.md +44 -0
  9. package/.github/ISSUE_TEMPLATE/feature-request.md +39 -0
  10. package/.github/pull_request_template.md +87 -0
  11. package/.github/workflows/phase-3c-l2-proof.yml +101 -0
  12. package/.github/workflows/phase-c-full-slack.yml +409 -0
  13. package/.github/workflows/phase-c-full.yml +241 -0
  14. package/.github/workflows/phase-c-scan.yml +64 -0
  15. package/.gitmodules +3 -0
  16. package/.tmp.js +3 -0
  17. package/CHANGELOG.md +1182 -0
  18. package/CLAUDE.md +633 -0
  19. package/Dockerfile +3 -0
  20. package/LICENSE +21 -0
  21. package/MISTAKES-COVERAGE.json +115 -0
  22. package/Makefile +95 -0
  23. package/PHASE-F-ROADMAP.md +554 -0
  24. package/README.md +459 -0
  25. package/SELF_HOSTING_CHECKLIST.md +155 -0
  26. package/benchmark-freelang.fl +47 -0
  27. package/benchmark-results.json +37 -0
  28. package/benchmark-simple.fl +38 -0
  29. package/bin/freelang-migrate +310 -0
  30. package/bin/freelang-smart +258 -0
  31. package/bootstrap.js +1134 -0
  32. package/docker-compose.yml +3 -0
  33. package/docs/AI_FRIENDLINESS.md +181 -0
  34. package/docs/AI_LEARNING_PATH.md +542 -0
  35. package/docs/AI_MAINTENANCE.md +153 -0
  36. package/docs/AI_QUICKSTART.md +380 -0
  37. package/docs/AI_REFERENCE.md +559 -0
  38. package/docs/AI_RELIABILITY_GUIDE.md +597 -0
  39. package/docs/AKL_ARCHITECTURE.md +228 -0
  40. package/docs/AKL_P0_KIMDB.md +215 -0
  41. package/docs/API.md +380 -0
  42. package/docs/ARCHITECTURE.md +208 -0
  43. package/docs/CHANGELOG.md +1014 -0
  44. package/docs/CLAUDE.md +991 -0
  45. package/docs/CLAUDE_AI.md +210 -0
  46. package/docs/CODEGEN_IMPROVEMENTS.md +158 -0
  47. package/docs/CODE_OF_CONDUCT.md +337 -0
  48. package/docs/CONTRIBUTING.md +437 -0
  49. package/docs/CRON_AUTOMATION.md +97 -0
  50. package/docs/DEPLOYMENT.md +357 -0
  51. package/docs/DETERMINISM_GUIDE.md +174 -0
  52. package/docs/HUMAN_GUIDE.md +599 -0
  53. package/docs/INDEX.md +199 -0
  54. package/docs/INLINE_TEST_GUIDE.md +231 -0
  55. package/docs/LANGUAGE-FAULTS.md +583 -0
  56. package/docs/LANGUAGE_IMPROVEMENT_REQUESTS.md +187 -0
  57. package/docs/LEARNING.md +257 -0
  58. package/docs/MISTAKES-100.md +52 -0
  59. package/docs/MISTAKES.md +131 -0
  60. package/docs/NAMING_CONVENTIONS.md +158 -0
  61. package/docs/NIGHTLY-MONITORING.md +222 -0
  62. package/docs/OFFICIAL_LANGUAGE.md +249 -0
  63. package/docs/ONBOARDING_1HOUR.md +210 -0
  64. package/docs/PERFORMANCE.md +329 -0
  65. package/docs/PHASE-3C-L2-PROOF-PLAN.md +282 -0
  66. package/docs/PHASE-3C-L2-RESULTS.md +183 -0
  67. package/docs/PHASE-3D-AI-LIBRARY.md +170 -0
  68. package/docs/PHASE-3E-VM-OPTIMIZATION.md +192 -0
  69. package/docs/PHASE-C-CI.md +242 -0
  70. package/docs/PHASE-C-PR-CHECKLIST.md +267 -0
  71. package/docs/PHASE-C-ROADMAP.md +141 -0
  72. package/docs/PHASE-C-SCAN.md +205 -0
  73. package/docs/PHASE-G-ROADMAP.md +228 -0
  74. package/docs/PHASE-X-V11.5-ROADMAP.md +267 -0
  75. package/docs/PHASE4_IMPLEMENTATION_PLAN.md +290 -0
  76. package/docs/PHASE5-COMPLETION.md +186 -0
  77. package/docs/PHASE5-SUMMARY.md +82 -0
  78. package/docs/PLUGIN_GUIDE.md +241 -0
  79. package/docs/PROJECT_OVERVIEW_KO.md +66 -0
  80. package/docs/QUICKSTART.md +160 -0
  81. package/docs/README.md +192 -0
  82. package/docs/RESERVED.md +125 -0
  83. package/docs/ROADMAP.md +191 -0
  84. package/docs/SECURITY.md +518 -0
  85. package/docs/SETUP.md +127 -0
  86. package/docs/SLACK-SETUP.md +190 -0
  87. package/docs/STATE_OF_V11.md +74 -0
  88. package/docs/STDLIB_NAMING_AUDIT.md +154 -0
  89. package/docs/STDLIB_REFERENCE.md +2722 -0
  90. package/docs/STYLE_GUIDE.md +559 -0
  91. package/docs/TASK5-MAP-DESTRUCTURE-DESIGN.md +136 -0
  92. package/docs/TOOLS.md +357 -0
  93. package/docs/TYPE_SYSTEM_GUIDE.md +201 -0
  94. package/docs/UI-PATTERN.md +265 -0
  95. package/docs/V11.5-RULES.md +416 -0
  96. package/docs/V11.6-HARNESS-RULES.md +222 -0
  97. package/docs/V11.6-MULTI-AGENT-PLAN.md +265 -0
  98. package/docs/V11.6-STABILIZATION-PLAN.md +290 -0
  99. package/docs/Y4-2B_DRY_RUN.md +142 -0
  100. package/docs/_classifications.json +882 -0
  101. package/docs/api/stdlib.md +134 -0
  102. package/docs/blog/2026-04-17-v11-ai-first-evolution.md +223 -0
  103. package/docs/blog/2026-04-20-self-hosting-fixedpoint.md +269 -0
  104. package/docs/blog/2026-05-04-mistakes-are-language-faults.md +267 -0
  105. package/docs/blog/2026-05-04-mistakes-coverage-honest.md +170 -0
  106. package/docs/blog/2026-05-04-phase-g-followup-smart-wrapper.md +188 -0
  107. package/docs/blog/2026-05-04-phase-g-mistakes-100.md +269 -0
  108. package/docs/blog/2026-05-04-phase-x-v11.5-launch.md +224 -0
  109. package/docs/blog/2026-05-04-v11.5.0-real-language-change.md +252 -0
  110. package/docs/blog-demo/README.md +44 -0
  111. package/docs/examples/index.md +78 -0
  112. package/docs/examples/todo-app.md +99 -0
  113. package/docs/guide/ai-blocks.md +335 -0
  114. package/docs/guide/basics.md +235 -0
  115. package/docs/guide/frameworks.md +319 -0
  116. package/docs/homepage/README.md +164 -0
  117. package/docs/index.md +183 -0
  118. package/docs/v12-DESIGN.md +214 -0
  119. package/examples/README.md +26 -0
  120. package/examples/browser-test.html +149 -0
  121. package/examples/csv-tool/analyze.fl +222 -0
  122. package/examples/csv-tool/employees.csv +16 -0
  123. package/examples/csv-tool/products.csv +21 -0
  124. package/examples/factorial.fl +9 -0
  125. package/examples/fib30.fl +4 -0
  126. package/examples/hello.fl +2 -0
  127. package/examples/hello.fl.js +3 -0
  128. package/examples/learning-session/01-grade-stats.fl +49 -0
  129. package/examples/learning-session/02-class-stats.fl +52 -0
  130. package/examples/learning-session/03-cart.fl +61 -0
  131. package/examples/learning-session/04-word-freq.fl +57 -0
  132. package/examples/learning-session/05-todo.fl +69 -0
  133. package/examples/learning-session/06-library.fl +76 -0
  134. package/examples/learning-session/07-currency.fl +99 -0
  135. package/examples/learning-session/08-csv-grades.fl +104 -0
  136. package/examples/learning-session/09-calc-repl.fl +92 -0
  137. package/examples/learning-session/10-contacts.fl +109 -0
  138. package/examples/learning-session/11-markdown.fl +107 -0
  139. package/examples/learning-session/12-calendar.fl +87 -0
  140. package/examples/learning-session/13-statistics.fl +123 -0
  141. package/examples/learning-session/14-primes.fl +107 -0
  142. package/examples/learning-session/15-statistics.fl +123 -0
  143. package/examples/learning-session/16-calendar.fl +87 -0
  144. package/examples/learning-session/17-markdown.fl +107 -0
  145. package/examples/learning-session/18-contacts.fl +109 -0
  146. package/examples/learning-session/19-json-serializer.fl +86 -0
  147. package/examples/learning-session/20-template.fl +201 -0
  148. package/examples/learning-session/21-calc-parser.fl +148 -0
  149. package/examples/learning-session/22-table.fl +96 -0
  150. package/examples/patterns/01-map-filter-reduce.fl +50 -0
  151. package/examples/patterns/02-error-handling.fl +51 -0
  152. package/examples/patterns/03-type-validation.fl +57 -0
  153. package/examples/patterns/04-state-management.fl +44 -0
  154. package/examples/patterns/05-api-integration.fl +95 -0
  155. package/examples/patterns/06-database-operations.fl +113 -0
  156. package/examples/patterns/07-string-processing.fl +86 -0
  157. package/examples/patterns/08-data-transformation.fl +92 -0
  158. package/examples/patterns/09-decision-logic.fl +122 -0
  159. package/examples/patterns/10-agent-orchestration.fl +184 -0
  160. package/examples/patterns/README.md +344 -0
  161. package/examples/simple-server.fl +29 -0
  162. package/examples/tables-app.fl +219 -0
  163. package/examples/test-libs.fl +272 -0
  164. package/jest.config.js +4 -0
  165. package/lib/datetime.fl +123 -0
  166. package/lib/http-client.fl +129 -0
  167. package/lib/pipeline.fl +150 -0
  168. package/lib/query.fl +160 -0
  169. package/lib/result.fl +124 -0
  170. package/lib/template.fl +161 -0
  171. package/lib/validate.fl +136 -0
  172. package/package.json +58 -0
  173. package/scripts/ai-eval.js +318 -0
  174. package/scripts/ai-self-verify.js +200 -0
  175. package/scripts/ai-validate.js +302 -0
  176. package/scripts/bench.sh +71 -0
  177. package/scripts/benchmark.js +258 -0
  178. package/scripts/benchmark.sh +99 -0
  179. package/scripts/build-binary.sh +68 -0
  180. package/scripts/build-runtime.sh +46 -0
  181. package/scripts/build-stage1-final.sh +58 -0
  182. package/scripts/build-stage1.sh +119 -0
  183. package/scripts/build-standalone.sh +17 -0
  184. package/scripts/build.js +130 -0
  185. package/scripts/check-let-regressions.js +95 -0
  186. package/scripts/check-parens.py +117 -0
  187. package/scripts/check-ports.sh +49 -0
  188. package/scripts/check-syntax.js +30 -0
  189. package/scripts/cli-extras.js +135 -0
  190. package/scripts/cron-daily-verify.sh +101 -0
  191. package/scripts/deploy.sh +91 -0
  192. package/scripts/dev.sh +37 -0
  193. package/scripts/extract-fl-examples.js +29 -0
  194. package/scripts/extract-runtime-helpers.js +122 -0
  195. package/scripts/fl-compile.sh +14 -0
  196. package/scripts/fl-fixpoint.sh +28 -0
  197. package/scripts/fl-repl.sh +21 -0
  198. package/scripts/fl-run.sh +41 -0
  199. package/scripts/fl-serve.sh +25 -0
  200. package/scripts/fuzz-compiler.js +92 -0
  201. package/scripts/gen-ai-prompt.js +340 -0
  202. package/scripts/gen-fixtures.js +166 -0
  203. package/scripts/gen-mistakes-split.js +199 -0
  204. package/scripts/gen-stdlib-docs.js +69 -0
  205. package/scripts/lint-stdlib-aliases.js +166 -0
  206. package/scripts/measure-baseline.sh +43 -0
  207. package/scripts/property-test.js +885 -0
  208. package/scripts/push-to-gogs.sh +60 -0
  209. package/scripts/regression-scan.js +132 -0
  210. package/scripts/run-jest-shard.sh +85 -0
  211. package/scripts/safe-push.sh +37 -0
  212. package/scripts/scan-fl-tokens.js +170 -0
  213. package/scripts/scan-for-fl-tokens.sh +17 -0
  214. package/scripts/self-diff.sh +95 -0
  215. package/scripts/snapshot-v0.sh +35 -0
  216. package/scripts/test-l2-fixpoint.sh +54 -0
  217. package/scripts/verify-all.sh +130 -0
  218. package/scripts/verify-build-deterministic.sh +110 -0
  219. package/scripts/verify-c7-bootstrap.sh +150 -0
  220. package/scripts/verify-c8-fixed-point-simple.sh +121 -0
  221. package/scripts/verify-c8-fixed-point.sh +133 -0
  222. package/scripts/verify-c9-fuzzing.sh +214 -0
  223. package/scripts/verify-fixed-point-deep.sh +133 -0
  224. package/scripts/verify-fixed-point.sh +65 -0
  225. package/scripts/verify-l2-proof.sh +153 -0
  226. package/scripts/verify-l3-proof.sh +40 -0
  227. package/scripts/verify-mistakes-coverage.js +120 -0
  228. package/scripts/verify-self-host.sh +509 -0
  229. package/self/CHANGELOG.md +964 -0
  230. package/self/COMPILER_REDESIGN_FAILURES.md +59 -0
  231. package/self/INTEGRATION-CHECKLIST.md +113 -0
  232. package/self/README.md +34 -0
  233. package/self/all.fl +1353 -0
  234. package/self/ast.fl +219 -0
  235. package/self/ast.self.js +47 -0
  236. package/self/bench/_bi_json-parse.js +46 -0
  237. package/self/bench/_bi_json-str.js +60 -0
  238. package/self/bench/_bi_list-distinct.js +37 -0
  239. package/self/bench/_bi_list-filter-even.js +56 -0
  240. package/self/bench/_bi_list-first.js +29 -0
  241. package/self/bench/_bi_list-last.js +28 -0
  242. package/self/bench/_bi_list-map-inc.js +41 -0
  243. package/self/bench/_bi_list-range.js +22 -0
  244. package/self/bench/_bi_list-reduce-sum.js +50 -0
  245. package/self/bench/_bi_list-reverse.js +28 -0
  246. package/self/bench/_bi_list-sort.js +35 -0
  247. package/self/bench/_bi_list-take.js +36 -0
  248. package/self/bench/_bi_m-abs.js +24 -0
  249. package/self/bench/_bi_m-floor.js +22 -0
  250. package/self/bench/_bi_m-max.js +26 -0
  251. package/self/bench/_bi_m-min.js +26 -0
  252. package/self/bench/_bi_m-mod.js +21 -0
  253. package/self/bench/_bi_map-has.js +50 -0
  254. package/self/bench/_bi_map-keys.js +50 -0
  255. package/self/bench/_bi_map-values.js +52 -0
  256. package/self/bench/_bi_str-concat.js +36 -0
  257. package/self/bench/_bi_str-contains.js +43 -0
  258. package/self/bench/_bi_str-ends.js +45 -0
  259. package/self/bench/_bi_str-index.js +34 -0
  260. package/self/bench/_bi_str-lower.js +23 -0
  261. package/self/bench/_bi_str-repeat.js +26 -0
  262. package/self/bench/_bi_str-split.js +41 -0
  263. package/self/bench/_bi_str-starts.js +47 -0
  264. package/self/bench/_bi_str-trim.js +26 -0
  265. package/self/bench/_bi_str-upper.js +23 -0
  266. package/self/bench/_bi_t-list.js +24 -0
  267. package/self/bench/_bi_t-null.js +23 -0
  268. package/self/bench/_bi_t-number.js +23 -0
  269. package/self/bench/_bi_t-string.js +25 -0
  270. package/self/bench/_bi_t-typeof.js +25 -0
  271. package/self/bench/_c_parse_probe.fl +426 -0
  272. package/self/bench/_c_parse_probe.js +67 -0
  273. package/self/bench/_codegen_nodrv.fl +751 -0
  274. package/self/bench/_combined2.fl +423 -0
  275. package/self/bench/_combined_arr.fl +422 -0
  276. package/self/bench/_combined_astprobe.fl +429 -0
  277. package/self/bench/_combined_astprobe.js +69 -0
  278. package/self/bench/_combined_cg.fl +424 -0
  279. package/self/bench/_combined_cg.js +64 -0
  280. package/self/bench/_combined_lex.fl +421 -0
  281. package/self/bench/_combined_trace.fl +435 -0
  282. package/self/bench/_combined_trace.js +75 -0
  283. package/self/bench/_ext_abs-neg.js +2 -0
  284. package/self/bench/_ext_and.js +2 -0
  285. package/self/bench/_ext_cond-1.js +2 -0
  286. package/self/bench/_ext_cond-2.js +2 -0
  287. package/self/bench/_ext_do-seq.js +2 -0
  288. package/self/bench/_ext_fact20.js +3 -0
  289. package/self/bench/_ext_fib25.js +3 -0
  290. package/self/bench/_ext_length.js +2 -0
  291. package/self/bench/_ext_let-1d.js +18 -0
  292. package/self/bench/_ext_let-2d.js +2 -0
  293. package/self/bench/_ext_list-sum.js +3 -0
  294. package/self/bench/_ext_math.js +2 -0
  295. package/self/bench/_ext_or.js +2 -0
  296. package/self/bench/_ext_str.js +2 -0
  297. package/self/bench/_fact15.js +2 -0
  298. package/self/bench/_fb_fact15.js +2 -0
  299. package/self/bench/_fb_func-fact.js +2 -0
  300. package/self/bench/_fb_func-multi.js +2 -0
  301. package/self/bench/_fb_func-mutual.js +3 -0
  302. package/self/bench/_fb_func-simple.js +21 -0
  303. package/self/bench/_fib.js +2 -0
  304. package/self/bench/_fn_async-await-seq.js +40 -0
  305. package/self/bench/_fn_async-await.js +3 -0
  306. package/self/bench/_fn_async-print.js +26 -0
  307. package/self/bench/_fn_async-result.js +1 -0
  308. package/self/bench/_fn_call-form.js +24 -0
  309. package/self/bench/_fn_compose.js +37 -0
  310. package/self/bench/_fn_pipe.js +34 -0
  311. package/self/bench/_fn_thread-first-sexpr.js +31 -0
  312. package/self/bench/_fn_thread-first.js +25 -0
  313. package/self/bench/_fn_thread-last.js +31 -0
  314. package/self/bench/_generated.js +35 -0
  315. package/self/bench/_mt_match-default.js +51 -0
  316. package/self/bench/_mt_match-num.js +58 -0
  317. package/self/bench/_mt_match-str.js +56 -0
  318. package/self/bench/_mt_match-var.js +32 -0
  319. package/self/bench/_mt_match-wild.js +36 -0
  320. package/self/bench/_mt_struct-make.js +81 -0
  321. package/self/bench/_mt_struct-tag.js +81 -0
  322. package/self/bench/_probe.fl +1 -0
  323. package/self/bench/_probe2.fl +1 -0
  324. package/self/bench/_probe3.fl +3 -0
  325. package/self/bench/_probe_apply.fl +1 -0
  326. package/self/bench/_probe_args.fl +7 -0
  327. package/self/bench/_probe_arr.fl +7 -0
  328. package/self/bench/_probe_arr2.fl +5 -0
  329. package/self/bench/_probe_block.fl +7 -0
  330. package/self/bench/_probe_call.fl +1 -0
  331. package/self/bench/_probe_cg.fl +27 -0
  332. package/self/bench/_probe_compose.fl +13 -0
  333. package/self/bench/_probe_define.fl +1 -0
  334. package/self/bench/_probe_keys.fl +5 -0
  335. package/self/bench/_probe_length.fl +5 -0
  336. package/self/bench/_probe_lexparse.fl +4 -0
  337. package/self/bench/_probe_loop.fl +12 -0
  338. package/self/bench/_probe_map.fl +8 -0
  339. package/self/bench/_probe_map2.fl +8 -0
  340. package/self/bench/_probe_map3.fl +5 -0
  341. package/self/bench/_probe_mapkeys.fl +5 -0
  342. package/self/bench/_probe_mapv12.fl +1 -0
  343. package/self/bench/_probe_mapv12.js +2 -0
  344. package/self/bench/_probe_match.fl +1 -0
  345. package/self/bench/_probe_match2.fl +1 -0
  346. package/self/bench/_probe_neg.fl +7 -0
  347. package/self/bench/_probe_neg2.fl +3 -0
  348. package/self/bench/_probe_protocol.fl +7 -0
  349. package/self/bench/_probe_self_parse.fl +6 -0
  350. package/self/bench/_probe_struct.fl +1 -0
  351. package/self/bench/_probe_true.fl +3 -0
  352. package/self/bench/_probe_true2.fl +6 -0
  353. package/self/bench/_probe_v12_cg.fl +7 -0
  354. package/self/bench/_probe_v12_extract.fl +8 -0
  355. package/self/bench/_probe_v12_extract.js +7 -0
  356. package/self/bench/_probe_v12_internal.fl +21 -0
  357. package/self/bench/_probe_v12_map_ast.fl +12 -0
  358. package/self/bench/_rs_combo.js +3 -0
  359. package/self/bench/_rs_gcd.js +36 -0
  360. package/self/bench/_rs_grade.js +2 -0
  361. package/self/bench/_rs_mutual-fib.js +2 -0
  362. package/self/bench/_rs_range-sum.js +2 -0
  363. package/self/bench/_rs_sum-10k.js +2 -0
  364. package/self/bench/_rs_sum-5k.js +2 -0
  365. package/self/bench/_sf_loop-fact-10.js +73 -0
  366. package/self/bench/_sf_loop-sum-10k.js +87 -0
  367. package/self/bench/_sf_set-x.js +40 -0
  368. package/self/bench/_sf_throw-catch.js +1 -0
  369. package/self/bench/_sf_while-5.js +62 -0
  370. package/self/bench/_v12_combined.fl +1184 -0
  371. package/self/bench/_v12_extract_test.fl +14 -0
  372. package/self/bench/_v12_extract_test.js +7 -0
  373. package/self/bench/_v12_inspect.js +26 -0
  374. package/self/bench/_v12_inspect_mod.js +137 -0
  375. package/self/bench/_v12_makevartest.fl +8 -0
  376. package/self/bench/_v12_makevartest.js +6 -0
  377. package/self/bench/_v12_parse_probe.fl +9 -0
  378. package/self/bench/_v12_parse_trace.fl +18 -0
  379. package/self/bench/_v12_simple_fn.fl +2 -0
  380. package/self/bench/_v12_simple_fn.js +3 -0
  381. package/self/bench/_v12_trace.fl +2 -0
  382. package/self/bench/_v12_trace.js +3 -0
  383. package/self/bench/collection.js +13 -0
  384. package/self/bench/fib30.fl +4 -0
  385. package/self/bench/final-test.fl +12 -0
  386. package/self/bench/final-test.js +2 -0
  387. package/self/bench/fp1-v12.js +4 -0
  388. package/self/bench/fp1.fl +3 -0
  389. package/self/bench/fp1.fp.js +4 -0
  390. package/self/bench/fp2-v12.js +4 -0
  391. package/self/bench/fp2.fl +3 -0
  392. package/self/bench/fp2.fp.js +4 -0
  393. package/self/bench/fp3-v12.js +8 -0
  394. package/self/bench/fp3.fl +11 -0
  395. package/self/bench/fp3.fp.js +8 -0
  396. package/self/bench/fp4-v12.js +6 -0
  397. package/self/bench/fp4.fl +9 -0
  398. package/self/bench/fp4.fp.js +6 -0
  399. package/self/bench/hello-sample.fl +3 -0
  400. package/self/bench/hello-sample.js +4 -0
  401. package/self/bench/hello.fl +1 -0
  402. package/self/bench/json.js +9 -0
  403. package/self/bench/json1mb.fl +3 -0
  404. package/self/bench/math.js +8 -0
  405. package/self/bench/realworld.fl +17 -0
  406. package/self/bench/realworld.js +8 -0
  407. package/self/bench/regex.js +10 -0
  408. package/self/bench/sample.json +1 -0
  409. package/self/bench/string.js +7 -0
  410. package/self/bench/test-ffi.fl +3 -0
  411. package/self/bench/test-ffi.js +2 -0
  412. package/self/bench/test-hof-advanced.fl +7 -0
  413. package/self/bench/test-hof-advanced.js +2 -0
  414. package/self/bench/test-hof.fl +5 -0
  415. package/self/bench/test-hof.js +2 -0
  416. package/self/bench/test-output.txt +1 -0
  417. package/self/bench/test-phase15-integration.fl +16 -0
  418. package/self/bench/test-phase15-integration.js +3 -0
  419. package/self/bench/test-phase19-complete.fl +24 -0
  420. package/self/bench/test-phase19-complete.js +2 -0
  421. package/self/bench/test-stdlib-codegen.fl +9 -0
  422. package/self/bench/test-stdlib-codegen.js +2 -0
  423. package/self/bench/test-time.fl +8 -0
  424. package/self/bench/test-time.js +2 -0
  425. package/self/bench/time.js +9 -0
  426. package/self/bench/tiny-v12.js +2 -0
  427. package/self/bench/tiny.fl +1 -0
  428. package/self/builtins/core.fl +150 -0
  429. package/self/char-class.fl +45 -0
  430. package/self/codegen-core.fl +733 -0
  431. package/self/codegen-final.fl +135 -0
  432. package/self/codegen.fl +379 -0
  433. package/self/codegen.fl.bak +856 -0
  434. package/self/codegen.self.js +75 -0
  435. package/self/examples/agent-loop.fl +32 -0
  436. package/self/examples/ci-cd-example.fl +114 -0
  437. package/self/examples/cloud-real.fl +134 -0
  438. package/self/examples/docker-example.fl +67 -0
  439. package/self/examples/fullstack-app.fl +330 -0
  440. package/self/examples/k8s-example.fl +91 -0
  441. package/self/examples/microservices.fl +448 -0
  442. package/self/examples/rest-api.fl +253 -0
  443. package/self/examples/style-example.fl +133 -0
  444. package/self/examples/workflow-orchestration.fl +44 -0
  445. package/self/fixtures/eval/add.fl +1 -0
  446. package/self/fixtures/eval/and-sc.fl +1 -0
  447. package/self/fixtures/eval/bool-false.fl +1 -0
  448. package/self/fixtures/eval/bool-true.fl +1 -0
  449. package/self/fixtures/eval/closure.fl +1 -0
  450. package/self/fixtures/eval/cmp-eq.fl +1 -0
  451. package/self/fixtures/eval/cmp-lt.fl +1 -0
  452. package/self/fixtures/eval/cond-first.fl +1 -0
  453. package/self/fixtures/eval/define-fn3.fl +1 -0
  454. package/self/fixtures/eval/define-var.fl +1 -0
  455. package/self/fixtures/eval/defn-bare.fl +1 -0
  456. package/self/fixtures/eval/defn-call.fl +1 -0
  457. package/self/fixtures/eval/div.fl +1 -0
  458. package/self/fixtures/eval/filter-hof.fl +1 -0
  459. package/self/fixtures/eval/floor.fl +1 -0
  460. package/self/fixtures/eval/fn-apply.fl +1 -0
  461. package/self/fixtures/eval/get-idx.fl +1 -0
  462. package/self/fixtures/eval/get-key.fl +1 -0
  463. package/self/fixtures/eval/higher-order.fl +1 -0
  464. package/self/fixtures/eval/let-bare.fl +1 -0
  465. package/self/fixtures/eval/let-flat.fl +1 -0
  466. package/self/fixtures/eval/let-use.fl +1 -0
  467. package/self/fixtures/eval/list-first.fl +1 -0
  468. package/self/fixtures/eval/list-last.fl +1 -0
  469. package/self/fixtures/eval/list-len.fl +1 -0
  470. package/self/fixtures/eval/map-hof.fl +1 -0
  471. package/self/fixtures/eval/mod.fl +1 -0
  472. package/self/fixtures/eval/mul-nested.fl +1 -0
  473. package/self/fixtures/eval/not.fl +1 -0
  474. package/self/fixtures/eval/null-p.fl +1 -0
  475. package/self/fixtures/eval/or-sc.fl +1 -0
  476. package/self/fixtures/eval/pow.fl +1 -0
  477. package/self/fixtures/eval/recursion.fl +1 -0
  478. package/self/fixtures/eval/reduce-hof.fl +1 -0
  479. package/self/fixtures/eval/replace.fl +1 -0
  480. package/self/fixtures/eval/sqrt.fl +1 -0
  481. package/self/fixtures/eval/str-concat.fl +1 -0
  482. package/self/fixtures/eval/str-num.fl +1 -0
  483. package/self/fixtures/eval/sub.fl +1 -0
  484. package/self/fixtures/eval/substring.fl +1 -0
  485. package/self/fixtures/lex/array.fl +1 -0
  486. package/self/fixtures/lex/at-atom.fl +1 -0
  487. package/self/fixtures/lex/block.fl +1 -0
  488. package/self/fixtures/lex/comment.fl +2 -0
  489. package/self/fixtures/lex/deep-array.fl +1 -0
  490. package/self/fixtures/lex/deep-map.fl +1 -0
  491. package/self/fixtures/lex/deep-nest.fl +1 -0
  492. package/self/fixtures/lex/dollar-dot.fl +1 -0
  493. package/self/fixtures/lex/empty-list.fl +1 -0
  494. package/self/fixtures/lex/empty-str.fl +1 -0
  495. package/self/fixtures/lex/empty.fl +1 -0
  496. package/self/fixtures/lex/float.fl +1 -0
  497. package/self/fixtures/lex/hex.fl +1 -0
  498. package/self/fixtures/lex/kebab-sym.fl +1 -0
  499. package/self/fixtures/lex/keyword.fl +1 -0
  500. package/self/fixtures/lex/leading-zero.fl +1 -0
  501. package/self/fixtures/lex/long-num.fl +1 -0
  502. package/self/fixtures/lex/many-args.fl +1 -0
  503. package/self/fixtures/lex/map.fl +1 -0
  504. package/self/fixtures/lex/mixed.fl +1 -0
  505. package/self/fixtures/lex/neg-float.fl +1 -0
  506. package/self/fixtures/lex/negative.fl +1 -0
  507. package/self/fixtures/lex/nested.fl +1 -0
  508. package/self/fixtures/lex/null.fl +1 -0
  509. package/self/fixtures/lex/pipe-op.fl +1 -0
  510. package/self/fixtures/lex/route-like.fl +1 -0
  511. package/self/fixtures/lex/scientific.fl +1 -0
  512. package/self/fixtures/lex/single-num.fl +1 -0
  513. package/self/fixtures/lex/small-sexpr.fl +1 -0
  514. package/self/fixtures/lex/spaces.fl +1 -0
  515. package/self/fixtures/lex/str-quote.fl +1 -0
  516. package/self/fixtures/lex/str-tab.fl +1 -0
  517. package/self/fixtures/lex/string-esc.fl +1 -0
  518. package/self/fixtures/lex/string.fl +1 -0
  519. package/self/fixtures/lex/symbol.fl +1 -0
  520. package/self/fixtures/lex/tabs-nl.fl +3 -0
  521. package/self/fixtures/lex/true-false.fl +1 -0
  522. package/self/fixtures/lex/unicode.fl +1 -0
  523. package/self/fixtures/lex/variable.fl +1 -0
  524. package/self/fixtures/lex/zero.fl +1 -0
  525. package/self/fixtures/parse/and-or.fl +1 -0
  526. package/self/fixtures/parse/array-lit.fl +1 -0
  527. package/self/fixtures/parse/block-func.fl +1 -0
  528. package/self/fixtures/parse/compose.fl +1 -0
  529. package/self/fixtures/parse/cond.fl +1 -0
  530. package/self/fixtures/parse/define-fn.fl +1 -0
  531. package/self/fixtures/parse/define-val.fl +1 -0
  532. package/self/fixtures/parse/defn.fl +1 -0
  533. package/self/fixtures/parse/do-begin.fl +1 -0
  534. package/self/fixtures/parse/dotted.fl +1 -0
  535. package/self/fixtures/parse/empty-fn.fl +1 -0
  536. package/self/fixtures/parse/empty-list.fl +1 -0
  537. package/self/fixtures/parse/fn.fl +1 -0
  538. package/self/fixtures/parse/if-else.fl +1 -0
  539. package/self/fixtures/parse/if-only.fl +1 -0
  540. package/self/fixtures/parse/keyword-arg.fl +1 -0
  541. package/self/fixtures/parse/kw.fl +1 -0
  542. package/self/fixtures/parse/let-1d.fl +1 -0
  543. package/self/fixtures/parse/let-2d.fl +1 -0
  544. package/self/fixtures/parse/let-bare.fl +1 -0
  545. package/self/fixtures/parse/literal-num.fl +1 -0
  546. package/self/fixtures/parse/literal-str.fl +1 -0
  547. package/self/fixtures/parse/loop-recur.fl +1 -0
  548. package/self/fixtures/parse/map-lit.fl +1 -0
  549. package/self/fixtures/parse/match-simple.fl +1 -0
  550. package/self/fixtures/parse/multi-body.fl +1 -0
  551. package/self/fixtures/parse/nested-arr.fl +1 -0
  552. package/self/fixtures/parse/nested-block.fl +1 -0
  553. package/self/fixtures/parse/nested-map.fl +1 -0
  554. package/self/fixtures/parse/nested.fl +1 -0
  555. package/self/fixtures/parse/pipe.fl +1 -0
  556. package/self/fixtures/parse/quote.fl +1 -0
  557. package/self/fixtures/parse/set-bang.fl +1 -0
  558. package/self/fixtures/parse/sexpr.fl +1 -0
  559. package/self/fixtures/parse/str-interp.fl +1 -0
  560. package/self/fixtures/parse/sym.fl +1 -0
  561. package/self/fixtures/parse/thread-first.fl +1 -0
  562. package/self/fixtures/parse/thread-last.fl +1 -0
  563. package/self/fixtures/parse/try-catch.fl +1 -0
  564. package/self/fixtures/parse/var.fl +1 -0
  565. package/self/full-compiler-fixed.fl +1308 -0
  566. package/self/full-compiler-v1-bloated.fl +1298 -0
  567. package/self/full-compiler.fl +1301 -0
  568. package/self/interpreter.fl +351 -0
  569. package/self/lexer.fl +200 -0
  570. package/self/lexer.self.js +30 -0
  571. package/self/main.fl +22 -0
  572. package/self/parser.fl +241 -0
  573. package/self/parser.self.js +33 -0
  574. package/self/runtime/http-server.js +642 -0
  575. package/self/runtime/interpreter.js +30787 -0
  576. package/self/runtime/repl.js +186 -0
  577. package/self/runtime-helpers.ts +282 -0
  578. package/self/scope.fl +80 -0
  579. package/self/scope.self.js +1 -0
  580. package/self/self/bench/_bi_list-distinct.js +2 -0
  581. package/self/self/bench/_bi_list-filter-even.js +2 -0
  582. package/self/self/bench/_bi_list-first.js +2 -0
  583. package/self/self/bench/_bi_list-last.js +2 -0
  584. package/self/self/bench/_bi_list-map-inc.js +2 -0
  585. package/self/self/bench/_bi_list-range.js +2 -0
  586. package/self/self/bench/_bi_list-reduce-sum.js +2 -0
  587. package/self/self/bench/_bi_list-reverse.js +2 -0
  588. package/self/self/bench/_bi_list-sort.js +2 -0
  589. package/self/self/bench/_bi_list-take.js +2 -0
  590. package/self/self/bench/_bi_map-has.js +2 -0
  591. package/self/self/bench/_bi_map-keys.js +2 -0
  592. package/self/self/bench/_bi_map-values.js +2 -0
  593. package/self/self/bench/_bi_str-concat.js +2 -0
  594. package/self/self/bench/_bi_str-contains.js +2 -0
  595. package/self/self/bench/_bi_str-ends.js +2 -0
  596. package/self/self/bench/_bi_str-index.js +2 -0
  597. package/self/self/bench/_bi_str-lower.js +2 -0
  598. package/self/self/bench/_bi_str-repeat.js +2 -0
  599. package/self/self/bench/_bi_str-split.js +2 -0
  600. package/self/self/bench/_bi_str-starts.js +2 -0
  601. package/self/self/bench/_bi_str-trim.js +2 -0
  602. package/self/self/bench/_bi_str-upper.js +2 -0
  603. package/self/self/bench/_ext_abs-neg.js +2 -0
  604. package/self/self/bench/_ext_and.js +2 -0
  605. package/self/self/bench/_ext_cond-1.js +2 -0
  606. package/self/self/bench/_ext_cond-2.js +2 -0
  607. package/self/self/bench/_ext_do-seq.js +2 -0
  608. package/self/self/bench/_ext_fact20.js +3 -0
  609. package/self/self/bench/_ext_fib25.js +3 -0
  610. package/self/self/bench/_ext_length.js +2 -0
  611. package/self/self/bench/_ext_let-1d.js +2 -0
  612. package/self/self/bench/_ext_let-2d.js +2 -0
  613. package/self/self/bench/_ext_list-sum.js +3 -0
  614. package/self/self/bench/_ext_math.js +2 -0
  615. package/self/self/bench/_ext_or.js +2 -0
  616. package/self/self/bench/_ext_str.js +2 -0
  617. package/self/self/bench/_fact15.js +2 -0
  618. package/self/self/bench/_fb_fact15.js +2 -0
  619. package/self/self/bench/_fb_func-fact.js +2 -0
  620. package/self/self/bench/_fb_func-multi.js +2 -0
  621. package/self/self/bench/_fb_func-mutual.js +3 -0
  622. package/self/self/bench/_fb_func-simple.js +2 -0
  623. package/self/self/bench/_fib.js +2 -0
  624. package/self/self/bench/_fn_async-await-seq.js +2 -0
  625. package/self/self/bench/_fn_async-print.js +2 -0
  626. package/self/self/bench/_fn_call-form.js +2 -0
  627. package/self/self/bench/_fn_compose.js +2 -0
  628. package/self/self/bench/_fn_pipe.js +2 -0
  629. package/self/self/bench/_fn_thread-first-sexpr.js +2 -0
  630. package/self/self/bench/_fn_thread-first.js +2 -0
  631. package/self/self/bench/_fn_thread-last.js +2 -0
  632. package/self/self/bench/_generated.js +2 -0
  633. package/self/self/bench/_mt_match-default.js +2 -0
  634. package/self/self/bench/_mt_match-num.js +2 -0
  635. package/self/self/bench/_mt_match-str.js +2 -0
  636. package/self/self/bench/_mt_match-var.js +2 -0
  637. package/self/self/bench/_mt_match-wild.js +2 -0
  638. package/self/self/bench/_mt_struct-make.js +4 -0
  639. package/self/self/bench/_mt_struct-tag.js +4 -0
  640. package/self/self/bench/_rs_combo.js +3 -0
  641. package/self/self/bench/_rs_gcd.js +2 -0
  642. package/self/self/bench/_rs_grade.js +2 -0
  643. package/self/self/bench/_rs_mutual-fib.js +2 -0
  644. package/self/self/bench/_rs_range-sum.js +2 -0
  645. package/self/self/bench/_rs_sum-5k.js +2 -0
  646. package/self/self/bench/_sf_loop-fact-10.js +1 -0
  647. package/self/self/bench/_sf_loop-sum-10k.js +1 -0
  648. package/self/self/bench/_sf_set-x.js +3 -0
  649. package/self/self/bench/_sf_throw-catch.js +1 -0
  650. package/self/self/bench/_sf_while-5.js +3 -0
  651. package/self/stdlib/ai.fl +73 -0
  652. package/self/stdlib/assert.fl +30 -0
  653. package/self/stdlib/async.fl +48 -0
  654. package/self/stdlib/base64.fl +22 -0
  655. package/self/stdlib/binary.fl +30 -0
  656. package/self/stdlib/build.fl +69 -0
  657. package/self/stdlib/collection.fl +37 -0
  658. package/self/stdlib/color.fl +35 -0
  659. package/self/stdlib/crypto-hash.fl +29 -0
  660. package/self/stdlib/crypto.fl +56 -0
  661. package/self/stdlib/data.fl +69 -0
  662. package/self/stdlib/db.fl +53 -0
  663. package/self/stdlib/encoding.fl +49 -0
  664. package/self/stdlib/error.fl +36 -0
  665. package/self/stdlib/feed.fl +86 -0
  666. package/self/stdlib/file.fl +53 -0
  667. package/self/stdlib/format.fl +34 -0
  668. package/self/stdlib/graph.fl +72 -0
  669. package/self/stdlib/hash.fl +32 -0
  670. package/self/stdlib/heap.fl +76 -0
  671. package/self/stdlib/http.fl +47 -0
  672. package/self/stdlib/image.fl +45 -0
  673. package/self/stdlib/json.fl +11 -0
  674. package/self/stdlib/list-extra.fl +32 -0
  675. package/self/stdlib/markdown.fl +59 -0
  676. package/self/stdlib/math-extra.fl +34 -0
  677. package/self/stdlib/math.fl +13 -0
  678. package/self/stdlib/metadata.fl +66 -0
  679. package/self/stdlib/mongodb/bson.fl +21 -0
  680. package/self/stdlib/mongodb/schema.fl +95 -0
  681. package/self/stdlib/mongodb/wire.fl +54 -0
  682. package/self/stdlib/mongodb.fl +172 -0
  683. package/self/stdlib/path.fl +72 -0
  684. package/self/stdlib/plot.fl +56 -0
  685. package/self/stdlib/process.fl +50 -0
  686. package/self/stdlib/queue.fl +65 -0
  687. package/self/stdlib/regex.fl +11 -0
  688. package/self/stdlib/resource.fl +61 -0
  689. package/self/stdlib/search.fl +54 -0
  690. package/self/stdlib/set-extra.fl +35 -0
  691. package/self/stdlib/sort.fl +61 -0
  692. package/self/stdlib/stack.fl +54 -0
  693. package/self/stdlib/stats.fl +110 -0
  694. package/self/stdlib/stream.fl +56 -0
  695. package/self/stdlib/string-extended.fl +25 -0
  696. package/self/stdlib/string-extra.fl +40 -0
  697. package/self/stdlib/string.fl +21 -0
  698. package/self/stdlib/test-helpers.fl +51 -0
  699. package/self/stdlib/test-runner.fl +76 -0
  700. package/self/stdlib/time-extra.fl +27 -0
  701. package/self/stdlib/time.fl +31 -0
  702. package/self/stdlib/tree.fl +57 -0
  703. package/self/stdlib/types.fl +85 -0
  704. package/self/stdlib/url.fl +33 -0
  705. package/self/stdlib/uuid.fl +28 -0
  706. package/self/stdlib/validation.fl +42 -0
  707. package/self/stdlib/vector-math.fl +52 -0
  708. package/self/stdlib/ws.fl +52 -0
  709. package/self/tests/mongodb-phase3.fl +75 -0
  710. package/self/tests/mongodb-wire-phase2.fl +45 -0
  711. package/self/tests/test-ast.fl +36 -0
  712. package/self/tests/test-builtins.fl +340 -0
  713. package/self/tests/test-char-class.fl +29 -0
  714. package/self/tests/test-codegen-builtins.fl +240 -0
  715. package/self/tests/test-codegen-ext.fl +380 -0
  716. package/self/tests/test-codegen-ffi.fl +295 -0
  717. package/self/tests/test-codegen-fn.fl +177 -0
  718. package/self/tests/test-codegen-match.fl +161 -0
  719. package/self/tests/test-codegen-run.fl +252 -0
  720. package/self/tests/test-codegen-sf.fl +262 -0
  721. package/self/tests/test-codegen.fl +260 -0
  722. package/self/tests/test-core-fl.fl +63 -0
  723. package/self/tests/test-forward-decl.fl +5 -0
  724. package/self/tests/test-func-block.fl +4 -0
  725. package/self/tests/test-interp-user-fn.fl +296 -0
  726. package/self/tests/test-interp.fl +225 -0
  727. package/self/tests/test-lexer.fl +162 -0
  728. package/self/tests/test-list-debug.fl +21 -0
  729. package/self/tests/test-mutual-rec.fl +6 -0
  730. package/self/tests/test-parser-debug.fl +35 -0
  731. package/self/tests/test-parser-full-debug.fl +66 -0
  732. package/self/tests/test-parser-lex-debug.fl +107 -0
  733. package/self/tests/test-parser-lex-only.fl +40 -0
  734. package/self/tests/test-parser-simple-debug.fl +35 -0
  735. package/self/tests/test-parser.fl +262 -0
  736. package/self/tests/test-real-stdlib.fl +377 -0
  737. package/self/tests/test-scope.fl +74 -0
  738. package/self/tests/test-selfcompile.fl +325 -0
  739. package/self/tests/test-stdlib.fl +44 -0
  740. package/self/tests/test-tco.fl +16 -0
  741. package/self/tests/test-token.fl +4 -0
  742. package/self/token.fl +38 -0
  743. package/self/token.self.js +8 -0
  744. package/self/v12-driver.fl +16 -0
  745. package/self/verify.fl +39 -0
  746. package/self-evolve/1-observe-ast.fl +28 -0
  747. package/self-evolve/2-inspect-block.fl +35 -0
  748. package/self-evolve/3-full-ast-json.fl +10 -0
  749. package/self-evolve/4-trace-block-fields.fl +23 -0
  750. package/self-evolve/5-analyze-do-ast.fl +29 -0
  751. package/self-evolve/6-test-do-elim-simple.fl +14 -0
  752. package/self-evolve/debug-evaluate.fl +24 -0
  753. package/self-evolve/debug-gen1-const-fold.fl +57 -0
  754. package/self-evolve/debug-map.fl +15 -0
  755. package/self-evolve/debug-optimize-simple.fl +95 -0
  756. package/self-evolve/debug-recursive-map.fl +23 -0
  757. package/self-evolve/logs/gen-0.fl +1658 -0
  758. package/self-evolve/logs/gen-1.fl +1658 -0
  759. package/self-evolve/logs/gen-2.fl +1658 -0
  760. package/self-evolve/logs/speed-gen-0.fl +1423 -0
  761. package/self-evolve/run-semantic-test.js +130 -0
  762. package/self-evolve/test-basic.fl +19 -0
  763. package/self-evolve/test-fold-direct.fl +60 -0
  764. package/self-evolve/test-gen1-simple.fl +67 -0
  765. package/self-evolve/test-optimize-debug.fl +63 -0
  766. package/self-evolve/tmp-test.fl +1 -0
  767. package/self-evolve/v11-analyzer.fl +40 -0
  768. package/self-evolve/v11-benchmark.fl +45 -0
  769. package/self-evolve/v11-evolution-real.fl +45 -0
  770. package/self-evolve/v11-evolution.fl +32 -0
  771. package/self-evolve/v11-gen1-validate.fl +157 -0
  772. package/self-evolve/v11-optimizer-constant-fold.fl +124 -0
  773. package/self-evolve/v11-optimizer-dead-expr.fl +111 -0
  774. package/self-evolve/v11-optimizer-gen1-complete.fl +180 -0
  775. package/self-evolve/v11-optimizer-gen1.fl +68 -0
  776. package/self-evolve/v11-optimizer.fl +56 -0
  777. package/self-evolve/v11-semantic-test.fl +54 -0
  778. package/self-evolve/v11-speed-benchmark.fl +106 -0
  779. package/self-evolve/v11-speed-optimizer.fl +79 -0
  780. package/src/AGENT-DSL.md +527 -0
  781. package/src/CLI-DEPLOYMENT.md +204 -0
  782. package/src/CLI.md +361 -0
  783. package/src/EXPRESS-ADVANCED.md +294 -0
  784. package/src/EXPRESS-AUTH.md +365 -0
  785. package/src/EXPRESS-CACHE.md +409 -0
  786. package/src/EXPRESS-COMPLETE.md +569 -0
  787. package/src/EXPRESS-README.md +121 -0
  788. package/src/EXPRESS-TEST.md +492 -0
  789. package/src/EXPRESS-WEBSOCKET.md +391 -0
  790. package/src/LOGGING-GUIDE.md +354 -0
  791. package/src/STORAGE-GUIDE.md +416 -0
  792. package/src/__tests__/advanced.test.ts +573 -0
  793. package/src/__tests__/ai-library.test.ts +210 -0
  794. package/src/__tests__/build-determinism.test.ts +33 -0
  795. package/src/__tests__/builtins-advanced.test.ts +150 -0
  796. package/src/__tests__/builtins-sanity.test.ts +180 -0
  797. package/src/__tests__/codegen.let.test.ts +81 -0
  798. package/src/__tests__/core.test.ts +188 -0
  799. package/src/__tests__/coverage-boost.test.ts +626 -0
  800. package/src/__tests__/cron-scheduler.test.ts +269 -0
  801. package/src/__tests__/enterprise-blocks.test.ts +63 -0
  802. package/src/__tests__/errors.test.ts +313 -0
  803. package/src/__tests__/integration.test.ts +219 -0
  804. package/src/__tests__/interpreter.test.ts +170 -0
  805. package/src/__tests__/l2-proof.test.ts +78 -0
  806. package/src/__tests__/lexer-parser.test.ts +366 -0
  807. package/src/__tests__/lexer.test.ts +106 -0
  808. package/src/__tests__/mariadb-prepared-statement.test.ts +206 -0
  809. package/src/__tests__/migrate.test.ts +403 -0
  810. package/src/__tests__/mongodb-integration.test.ts.skip +207 -0
  811. package/src/__tests__/mongodb-phase4.test.ts +132 -0
  812. package/src/__tests__/p1-1-parallel-tasks.test.ts +179 -0
  813. package/src/__tests__/p1-2-compensation.test.ts +242 -0
  814. package/src/__tests__/p1-3-distributed.test.ts +160 -0
  815. package/src/__tests__/p1-4-observability.test.ts +161 -0
  816. package/src/__tests__/parser.test.ts +142 -0
  817. package/src/__tests__/phase151-self-evolve.test.ts +161 -0
  818. package/src/__tests__/rate-limiter.test.ts +274 -0
  819. package/src/__tests__/self-hosting.test.ts +174 -0
  820. package/src/__tests__/semantic-preservation.test.ts +207 -0
  821. package/src/__tests__/setup.ts +34 -0
  822. package/src/__tests__/special-forms-advanced.test.ts +106 -0
  823. package/src/__tests__/stdlib-crypto-rsa.test.ts +122 -0
  824. package/src/__tests__/stdlib-f4.test.ts +159 -0
  825. package/src/__tests__/stdlib-helpers.test.ts +128 -0
  826. package/src/__tests__/stdlib-modules.test.ts +161 -0
  827. package/src/__tests__/stdlib-mongodb.test.ts +331 -0
  828. package/src/__tests__/stdlib-new.test.ts +269 -0
  829. package/src/__tests__/stdlib-perf.test.ts +125 -0
  830. package/src/__tests__/stdlib-phase-b.test.ts +249 -0
  831. package/src/__tests__/stdlib.test.ts +163 -0
  832. package/src/__tests__/v12-alpha.test.ts +205 -0
  833. package/src/__tests__/vm-optin.test.ts +141 -0
  834. package/src/__tests__/web-integration.test.ts +1452 -0
  835. package/src/__tests__/weblibs.test.ts +210 -0
  836. package/src/_aliases.json +1123 -0
  837. package/src/_mongodb_helper.js +272 -0
  838. package/src/_stdlib-signatures.json +1 -0
  839. package/src/agent-chain.ts +71 -0
  840. package/src/agent-dsl.fl +168 -0
  841. package/src/agent-example-error-handling.fl +51 -0
  842. package/src/agent-example-sequential.fl +66 -0
  843. package/src/agent-example-state-tracking.fl +70 -0
  844. package/src/agent.ts +393 -0
  845. package/src/align.ts +349 -0
  846. package/src/analogy.ts +78 -0
  847. package/src/ast-helpers.ts +199 -0
  848. package/src/ast.ts +817 -0
  849. package/src/async-runtime.ts +263 -0
  850. package/src/belief.ts +86 -0
  851. package/src/benchmark-self.ts +275 -0
  852. package/src/benchmarks/bench-interpreter.ts +73 -0
  853. package/src/benchmarks/bench-runner.ts +85 -0
  854. package/src/benchmarks/bench-vm.ts +128 -0
  855. package/src/browser-debug-panel.ts +220 -0
  856. package/src/browser-entry.ts +79 -0
  857. package/src/browser-stubs/child-process-stubs.ts +6 -0
  858. package/src/browser-stubs/crypto-stubs.ts +15 -0
  859. package/src/browser-stubs/misc-stubs.ts +4 -0
  860. package/src/browser-stubs/node-stubs.ts +17 -0
  861. package/src/browser-stubs/path-stubs.ts +6 -0
  862. package/src/bytecode.ts +41 -0
  863. package/src/causal.ts +258 -0
  864. package/src/chain-agents.ts +86 -0
  865. package/src/checkpoint.ts +106 -0
  866. package/src/ci-runner.ts +279 -0
  867. package/src/cli.ts +2136 -0
  868. package/src/codegen-js.ts +847 -0
  869. package/src/cognitive.ts +95 -0
  870. package/src/compete.ts +60 -0
  871. package/src/compiler.ts +267 -0
  872. package/src/compose-reason.ts +118 -0
  873. package/src/consensus.ts +109 -0
  874. package/src/context-window.ts +139 -0
  875. package/src/cot.ts +241 -0
  876. package/src/counterfactual.ts +268 -0
  877. package/src/critique.ts +77 -0
  878. package/src/crossover.ts +218 -0
  879. package/src/curiosity.ts +305 -0
  880. package/src/debate.ts +64 -0
  881. package/src/debug-api.ts +92 -0
  882. package/src/debugger.ts +185 -0
  883. package/src/delegate.ts +78 -0
  884. package/src/doc-extractor.ts +255 -0
  885. package/src/doc-renderer.ts +131 -0
  886. package/src/echo-server-demo.fl +17 -0
  887. package/src/error-formatter.ts +369 -0
  888. package/src/error-system.ts +88 -0
  889. package/src/errors.ts +281 -0
  890. package/src/ethics-check.ts +408 -0
  891. package/src/eval-ai-blocks.ts +182 -0
  892. package/src/eval-ai-handlers.ts +132 -0
  893. package/src/eval-builtins-ai.ts +1659 -0
  894. package/src/eval-builtins.ts +5956 -0
  895. package/src/eval-call-function.ts +665 -0
  896. package/src/eval-infra-blocks.ts +450 -0
  897. package/src/eval-module-system.ts +286 -0
  898. package/src/eval-pattern-match.ts +289 -0
  899. package/src/eval-phase150.ts +87 -0
  900. package/src/eval-reasoning-sequence.ts +218 -0
  901. package/src/eval-special-forms.ts +2154 -0
  902. package/src/eval-style-blocks.ts +193 -0
  903. package/src/eval-type-classes.ts +148 -0
  904. package/src/evolve.ts +276 -0
  905. package/src/explain.ts +345 -0
  906. package/src/express-advanced.fl +78 -0
  907. package/src/express-auth.fl +118 -0
  908. package/src/express-cache.fl +118 -0
  909. package/src/express-chat.fl +81 -0
  910. package/src/express-example.fl +67 -0
  911. package/src/express-test.fl +331 -0
  912. package/src/express.fl +92 -0
  913. package/src/fitness.ts +238 -0
  914. package/src/fl-app-demo.fl +19 -0
  915. package/src/fl-files/fl-fmt.fl +29 -0
  916. package/src/fl-files/fl-lint.fl +61 -0
  917. package/src/fl-files/fl-test.fl +52 -0
  918. package/src/fl-http-demo.fl +19 -0
  919. package/src/fl-list-utils.fl +108 -0
  920. package/src/fl-math-lib.fl +14 -0
  921. package/src/fl-sdk.ts +154 -0
  922. package/src/fl-server-demo.fl +74 -0
  923. package/src/fl-str-utils.fl +29 -0
  924. package/src/fl-tutor.ts +126 -0
  925. package/src/formatter.ts +581 -0
  926. package/src/freelang-codegen.fl +904 -0
  927. package/src/freelang-interpreter.fl +483 -0
  928. package/src/freelang-lexer.fl +337 -0
  929. package/src/freelang-parser.fl +349 -0
  930. package/src/freelang-stdlib.fl +246 -0
  931. package/src/freelang-typechecker.fl +422 -0
  932. package/src/freelang-v9-complete.ts +474 -0
  933. package/src/generation.ts +201 -0
  934. package/src/gpt-mini-p3.fl +316 -0
  935. package/src/hot-reload.ts +235 -0
  936. package/src/http-server-runner.ts +89 -0
  937. package/src/hypothesis.ts +62 -0
  938. package/src/immutable.ts +140 -0
  939. package/src/interpreter-context.ts +87 -0
  940. package/src/interpreter-scope.ts +140 -0
  941. package/src/interpreter.ts +2351 -0
  942. package/src/lazy-seq.ts +134 -0
  943. package/src/learned-facts-store.ts +306 -0
  944. package/src/lexer.ts +359 -0
  945. package/src/lint-rules.ts +584 -0
  946. package/src/linter.ts +237 -0
  947. package/src/logger.ts +128 -0
  948. package/src/logging-deterministic.fl +138 -0
  949. package/src/lsp-server.ts +379 -0
  950. package/src/macro-expander.ts +195 -0
  951. package/src/maybe-chain.ts +108 -0
  952. package/src/maybe-type.ts +163 -0
  953. package/src/memory-system.ts +142 -0
  954. package/src/meta-reason.ts +93 -0
  955. package/src/multi-agent-hub.ts +247 -0
  956. package/src/multi-agent.ts +101 -0
  957. package/src/mutate.ts +226 -0
  958. package/src/negotiate.ts +55 -0
  959. package/src/optimizer.ts +277 -0
  960. package/src/orchestrate.ts +154 -0
  961. package/src/package-manager.ts +375 -0
  962. package/src/parser.ts +2722 -0
  963. package/src/peer-review.ts +53 -0
  964. package/src/predict.ts +365 -0
  965. package/src/profiler.ts +150 -0
  966. package/src/prompt-compiler.ts +123 -0
  967. package/src/protocol.ts +114 -0
  968. package/src/prune.ts +195 -0
  969. package/src/quality-loop.ts +105 -0
  970. package/src/rag.ts +81 -0
  971. package/src/reasoning-debugger.ts +122 -0
  972. package/src/refactor-self.ts +362 -0
  973. package/src/reflect.ts +186 -0
  974. package/src/repl.ts +323 -0
  975. package/src/result-type.ts +126 -0
  976. package/src/return-signal.ts +10 -0
  977. package/src/runtime-entry.ts +8 -0
  978. package/src/runtime-helpers.ts +234 -0
  979. package/src/self-evolution-hub.ts +431 -0
  980. package/src/self-improve.ts +107 -0
  981. package/src/source-map.ts +114 -0
  982. package/src/stdlib-agent.js +164 -0
  983. package/src/stdlib-agent.ts +225 -0
  984. package/src/stdlib-ai-native.ts +176 -0
  985. package/src/stdlib-ai-workflow.ts +308 -0
  986. package/src/stdlib-ai.ts +180 -0
  987. package/src/stdlib-async.ts +179 -0
  988. package/src/stdlib-audit.ts +94 -0
  989. package/src/stdlib-auth.ts +196 -0
  990. package/src/stdlib-bits.ts +86 -0
  991. package/src/stdlib-blog.ts +127 -0
  992. package/src/stdlib-browser.ts +239 -0
  993. package/src/stdlib-cache.ts +147 -0
  994. package/src/stdlib-capture-error.ts +183 -0
  995. package/src/stdlib-channel.ts +96 -0
  996. package/src/stdlib-checkpoint.js +109 -0
  997. package/src/stdlib-checkpoint.ts +97 -0
  998. package/src/stdlib-cloud.ts +317 -0
  999. package/src/stdlib-collection.ts +227 -0
  1000. package/src/stdlib-compile.ts +111 -0
  1001. package/src/stdlib-cron.ts +219 -0
  1002. package/src/stdlib-crypto-rsa.ts +82 -0
  1003. package/src/stdlib-crypto.js +203 -0
  1004. package/src/stdlib-crypto.ts +208 -0
  1005. package/src/stdlib-data.ts +614 -0
  1006. package/src/stdlib-db-query.ts +198 -0
  1007. package/src/stdlib-db.ts +185 -0
  1008. package/src/stdlib-distributed.ts +292 -0
  1009. package/src/stdlib-error.ts +90 -0
  1010. package/src/stdlib-fd.ts +130 -0
  1011. package/src/stdlib-feed.ts +171 -0
  1012. package/src/stdlib-file.ts +182 -0
  1013. package/src/stdlib-helpers.ts +273 -0
  1014. package/src/stdlib-http-macro.ts +178 -0
  1015. package/src/stdlib-http-server.ts +1229 -0
  1016. package/src/stdlib-http.ts +405 -0
  1017. package/src/stdlib-image.ts +92 -0
  1018. package/src/stdlib-kebab-aliases.ts +131 -0
  1019. package/src/stdlib-lazy-registry.ts +106 -0
  1020. package/src/stdlib-loader.ts +810 -0
  1021. package/src/stdlib-mail.ts +251 -0
  1022. package/src/stdlib-mariadb.ts +467 -0
  1023. package/src/stdlib-markdown.ts +227 -0
  1024. package/src/stdlib-matrix.ts +170 -0
  1025. package/src/stdlib-middleware.ts +221 -0
  1026. package/src/stdlib-module.ts +178 -0
  1027. package/src/stdlib-mongodb.ts +174 -0
  1028. package/src/stdlib-oci.ts +321 -0
  1029. package/src/stdlib-optional.ts +56 -0
  1030. package/src/stdlib-orm.ts +241 -0
  1031. package/src/stdlib-perf.ts +140 -0
  1032. package/src/stdlib-pg.ts +181 -0
  1033. package/src/stdlib-plot.ts +196 -0
  1034. package/src/stdlib-process.ts +120 -0
  1035. package/src/stdlib-property.ts +157 -0
  1036. package/src/stdlib-pubsub.ts +93 -0
  1037. package/src/stdlib-queue-helpers.ts +92 -0
  1038. package/src/stdlib-registry.ts +78 -0
  1039. package/src/stdlib-resource.ts +553 -0
  1040. package/src/stdlib-rest-crud.ts +146 -0
  1041. package/src/stdlib-service.ts +206 -0
  1042. package/src/stdlib-shell.ts +76 -0
  1043. package/src/stdlib-stats.ts +172 -0
  1044. package/src/stdlib-table.ts +200 -0
  1045. package/src/stdlib-test-enhanced.ts +76 -0
  1046. package/src/stdlib-test.ts +153 -0
  1047. package/src/stdlib-time.js +217 -0
  1048. package/src/stdlib-time.ts +282 -0
  1049. package/src/stdlib-timer.ts +134 -0
  1050. package/src/stdlib-totp.ts +110 -0
  1051. package/src/stdlib-type-predicates.ts +136 -0
  1052. package/src/stdlib-types.ts +107 -0
  1053. package/src/stdlib-validation.ts +248 -0
  1054. package/src/stdlib-verify.ts +181 -0
  1055. package/src/stdlib-webauthn.ts +192 -0
  1056. package/src/stdlib-workflow.js +715 -0
  1057. package/src/stdlib-workflow.ts +950 -0
  1058. package/src/stdlib-ws.ts +333 -0
  1059. package/src/stdlib-wsc.test.ts +122 -0
  1060. package/src/stdlib-wsc.ts +243 -0
  1061. package/src/storage-unified.fl +279 -0
  1062. package/src/streaming.ts +101 -0
  1063. package/src/struct-system.ts +104 -0
  1064. package/src/style-registry.ts +54 -0
  1065. package/src/swarm.ts +89 -0
  1066. package/src/tco.ts +31 -0
  1067. package/src/test-advanced-patterns.ts +211 -0
  1068. package/src/test-ast-debug.ts +20 -0
  1069. package/src/test-ast-helpers.ts +208 -0
  1070. package/src/test-async.ts +406 -0
  1071. package/src/test-bootstrap-self-compile.ts +449 -0
  1072. package/src/test-bootstrap-verification.ts +336 -0
  1073. package/src/test-composition.ts +206 -0
  1074. package/src/test-errors-phase6.ts +166 -0
  1075. package/src/test-extended-monads.ts +313 -0
  1076. package/src/test-field-parsing.ts +135 -0
  1077. package/src/test-first-class-functions.ts +257 -0
  1078. package/src/test-freelang-interpreter.ts +320 -0
  1079. package/src/test-freelang-lexer.ts +306 -0
  1080. package/src/test-freelang-parser.ts +268 -0
  1081. package/src/test-fullstack-core.ts +258 -0
  1082. package/src/test-fullstack-phase7-12.ts +305 -0
  1083. package/src/test-fullstack-practical.ts +338 -0
  1084. package/src/test-integration-stdlib.ts +195 -0
  1085. package/src/test-interpreter-phase6.ts +305 -0
  1086. package/src/test-lexer-comparison.ts +108 -0
  1087. package/src/test-lexer-phase6.ts +271 -0
  1088. package/src/test-modules.ts +325 -0
  1089. package/src/test-monad-laws.ts +383 -0
  1090. package/src/test-monads.ts +197 -0
  1091. package/src/test-p0-checkpoint.ts +304 -0
  1092. package/src/test-p0-conditional.ts +284 -0
  1093. package/src/test-p0-error-handling.ts +231 -0
  1094. package/src/test-p0-error-messages.ts +220 -0
  1095. package/src/test-p1-1-parallel-tasks.js +214 -0
  1096. package/src/test-parser-phase6.ts +222 -0
  1097. package/src/test-performance.ts +206 -0
  1098. package/src/test-phase10-data.ts +259 -0
  1099. package/src/test-phase10-file.ts +216 -0
  1100. package/src/test-phase100-stdlib-ai.ts +343 -0
  1101. package/src/test-phase101-memory.ts +309 -0
  1102. package/src/test-phase102-rag.ts +296 -0
  1103. package/src/test-phase103-multi-agent.ts +418 -0
  1104. package/src/test-phase104-try-reason.ts +459 -0
  1105. package/src/test-phase105-streaming.ts +287 -0
  1106. package/src/test-phase106-quality.ts +397 -0
  1107. package/src/test-phase107-tutor.ts +305 -0
  1108. package/src/test-phase108-debugger.ts +316 -0
  1109. package/src/test-phase109-prompt-compiler.ts +333 -0
  1110. package/src/test-phase11-12-complete.ts +275 -0
  1111. package/src/test-phase11-error.ts +192 -0
  1112. package/src/test-phase110-sdk.ts +320 -0
  1113. package/src/test-phase111-hypothesis.ts +380 -0
  1114. package/src/test-phase112-maybe-chain.ts +313 -0
  1115. package/src/test-phase113-debate.ts +364 -0
  1116. package/src/test-phase114-checkpoint.ts +348 -0
  1117. package/src/test-phase115-meta-reason.ts +277 -0
  1118. package/src/test-phase116-belief.ts +275 -0
  1119. package/src/test-phase117-analogy.ts +325 -0
  1120. package/src/test-phase118-critique.ts +308 -0
  1121. package/src/test-phase119-compose.ts +434 -0
  1122. package/src/test-phase12-http-shell.ts +120 -0
  1123. package/src/test-phase120-cognitive.ts +297 -0
  1124. package/src/test-phase121-consensus.ts +404 -0
  1125. package/src/test-phase122-delegate.ts +411 -0
  1126. package/src/test-phase123-vote.ts +339 -0
  1127. package/src/test-phase124-negotiate.ts +403 -0
  1128. package/src/test-phase125-swarm.ts +321 -0
  1129. package/src/test-phase126-orchestrate.ts +343 -0
  1130. package/src/test-phase127-peer-review.ts +279 -0
  1131. package/src/test-phase128-chain-agents.ts +456 -0
  1132. package/src/test-phase129-compete.ts +256 -0
  1133. package/src/test-phase13-data.ts +223 -0
  1134. package/src/test-phase130-hub.ts +390 -0
  1135. package/src/test-phase131-evolve.ts +536 -0
  1136. package/src/test-phase132-mutate.ts +268 -0
  1137. package/src/test-phase133-crossover.ts +289 -0
  1138. package/src/test-phase134-fitness.ts +306 -0
  1139. package/src/test-phase135-generation.ts +328 -0
  1140. package/src/test-phase136-prune.ts +228 -0
  1141. package/src/test-phase137-refactor-self.ts +354 -0
  1142. package/src/test-phase138-benchmark-self.ts +325 -0
  1143. package/src/test-phase139-version-self.ts +278 -0
  1144. package/src/test-phase14-collection.ts +254 -0
  1145. package/src/test-phase140-self-evolution.ts +410 -0
  1146. package/src/test-phase141-world-model.ts +387 -0
  1147. package/src/test-phase142-causal.ts +384 -0
  1148. package/src/test-phase143-counterfactual.ts +280 -0
  1149. package/src/test-phase144-predict.ts +312 -0
  1150. package/src/test-phase145-explain.ts +287 -0
  1151. package/src/test-phase146-align.ts +439 -0
  1152. package/src/test-phase147-ethics-check.ts +399 -0
  1153. package/src/test-phase148-curiosity.ts +247 -0
  1154. package/src/test-phase149-wisdom.ts +758 -0
  1155. package/src/test-phase15-agent.ts +320 -0
  1156. package/src/test-phase150-complete.ts +481 -0
  1157. package/src/test-phase16-time.ts +292 -0
  1158. package/src/test-phase17-crypto.ts +312 -0
  1159. package/src/test-phase18-integration.ts +429 -0
  1160. package/src/test-phase19-resource.ts +214 -0
  1161. package/src/test-phase20-server-db.ts +160 -0
  1162. package/src/test-phase21-ws-auth-cache-pubsub.ts +212 -0
  1163. package/src/test-phase22-process.ts +166 -0
  1164. package/src/test-phase23-selfhosting.ts +383 -0
  1165. package/src/test-phase24-codegen.ts +236 -0
  1166. package/src/test-phase25-bootstrap.ts +227 -0
  1167. package/src/test-phase26-map-filter-reduce.ts +282 -0
  1168. package/src/test-phase27-stdlib-codegen.ts +325 -0
  1169. package/src/test-phase28-loop-recur.ts +182 -0
  1170. package/src/test-phase29-import.ts +165 -0
  1171. package/src/test-phase3-web-server.ts +234 -0
  1172. package/src/test-phase30-selfcompile.ts +254 -0
  1173. package/src/test-phase31-gen2-lexer.ts +251 -0
  1174. package/src/test-phase33-gen3-bootstrap.ts +323 -0
  1175. package/src/test-phase34-parser-tco.ts +268 -0
  1176. package/src/test-phase35-error-messages.ts +280 -0
  1177. package/src/test-phase36-sourcemap.ts +240 -0
  1178. package/src/test-phase37-variadic.ts +228 -0
  1179. package/src/test-phase38-destructuring.ts +261 -0
  1180. package/src/test-phase39-do-block.ts +288 -0
  1181. package/src/test-phase40-const-fold.ts +249 -0
  1182. package/src/test-phase41-repl.ts +312 -0
  1183. package/src/test-phase42-watch.ts +314 -0
  1184. package/src/test-phase43-format.ts +377 -0
  1185. package/src/test-phase44-check.ts +505 -0
  1186. package/src/test-phase45-interpreter.ts +367 -0
  1187. package/src/test-phase46-match.ts +390 -0
  1188. package/src/test-phase47-file-io.ts +338 -0
  1189. package/src/test-phase48-types.ts +308 -0
  1190. package/src/test-phase49-stdlib.ts +365 -0
  1191. package/src/test-phase5-week1.ts +160 -0
  1192. package/src/test-phase50-fl-server.ts +159 -0
  1193. package/src/test-phase51-transformer.ts +152 -0
  1194. package/src/test-phase52-import.ts +161 -0
  1195. package/src/test-phase53-training.ts +122 -0
  1196. package/src/test-phase54-fl-utils.ts +122 -0
  1197. package/src/test-phase55-http-client.ts +182 -0
  1198. package/src/test-phase56-lexical-scope.ts +230 -0
  1199. package/src/test-phase58-module-refactor.ts +298 -0
  1200. package/src/test-phase59-errors.ts +226 -0
  1201. package/src/test-phase6-compile.ts +227 -0
  1202. package/src/test-phase60-types.ts +457 -0
  1203. package/src/test-phase61-tco.ts +209 -0
  1204. package/src/test-phase63-macros.ts +191 -0
  1205. package/src/test-phase64-protocols.ts +451 -0
  1206. package/src/test-phase65-patterns.ts +301 -0
  1207. package/src/test-phase66-structs.ts +215 -0
  1208. package/src/test-phase67-concurrency.ts +348 -0
  1209. package/src/test-phase68-pipeline.ts +209 -0
  1210. package/src/test-phase69-lazy.ts +237 -0
  1211. package/src/test-phase7-registry.ts +236 -0
  1212. package/src/test-phase70-immutable.ts +488 -0
  1213. package/src/test-phase71-ai-native.ts +252 -0
  1214. package/src/test-phase72-integration.ts +533 -0
  1215. package/src/test-phase73-formatter.ts +361 -0
  1216. package/src/test-phase74-linter.ts +565 -0
  1217. package/src/test-phase75-repl.ts +227 -0
  1218. package/src/test-phase76-testrunner.ts +439 -0
  1219. package/src/test-phase77-doc.ts +416 -0
  1220. package/src/test-phase78-debugger.ts +370 -0
  1221. package/src/test-phase79-watch.ts +224 -0
  1222. package/src/test-phase8-oci.ts +264 -0
  1223. package/src/test-phase80-ci.ts +282 -0
  1224. package/src/test-phase81-pkg.ts +383 -0
  1225. package/src/test-phase82-profiler.ts +336 -0
  1226. package/src/test-phase83-vm.ts +318 -0
  1227. package/src/test-phase84-optimizer.ts +424 -0
  1228. package/src/test-phase85-codegen.ts +380 -0
  1229. package/src/test-phase86-lsp.ts +533 -0
  1230. package/src/test-phase87-packages.ts +277 -0
  1231. package/src/test-phase88-selfhost.ts +412 -0
  1232. package/src/test-phase89-bench.ts +361 -0
  1233. package/src/test-phase9-flnext-v2.ts +372 -0
  1234. package/src/test-phase9-learn.ts +241 -0
  1235. package/src/test-phase9-reasoning.ts +312 -0
  1236. package/src/test-phase9-search.ts +212 -0
  1237. package/src/test-phase90-release.ts +365 -0
  1238. package/src/test-phase91-maybe.ts +257 -0
  1239. package/src/test-phase92-cot.ts +438 -0
  1240. package/src/test-phase93-tot.ts +462 -0
  1241. package/src/test-phase94-reflect.ts +498 -0
  1242. package/src/test-phase95-context.ts +268 -0
  1243. package/src/test-phase96-errors.ts +296 -0
  1244. package/src/test-phase97-tools.ts +344 -0
  1245. package/src/test-phase98-agent.ts +370 -0
  1246. package/src/test-phase99-self-improve.ts +394 -0
  1247. package/src/test-phase9a-websearch.ts +283 -0
  1248. package/src/test-phase9ab-integration.ts +140 -0
  1249. package/src/test-phase9b-persistence.ts +448 -0
  1250. package/src/test-phase9c-conditional.ts +251 -0
  1251. package/src/test-phase9c-extension.ts +270 -0
  1252. package/src/test-phase9c-feedback.ts +263 -0
  1253. package/src/test-phase9c-loop.ts +239 -0
  1254. package/src/test-selfhosting-sh1.ts +41 -0
  1255. package/src/test-selfhosting-sh2.ts +84 -0
  1256. package/src/test-selfhosting-sh3.ts +61 -0
  1257. package/src/test-selfhosting-sh4.ts +65 -0
  1258. package/src/test-type-classes-dispatch.ts +202 -0
  1259. package/src/test-type-classes.ts +320 -0
  1260. package/src/test-type-inference.ts +464 -0
  1261. package/src/test-typeclass-parsing-final.ts +218 -0
  1262. package/src/test-typeclass-parsing.ts +264 -0
  1263. package/src/todo-server-30116.ts +53 -0
  1264. package/src/token.ts +130 -0
  1265. package/src/tool-registry.ts +195 -0
  1266. package/src/tot.ts +258 -0
  1267. package/src/try-reason.ts +109 -0
  1268. package/src/type-check-static.ts +417 -0
  1269. package/src/type-checker.ts +245 -0
  1270. package/src/type-inference.ts +271 -0
  1271. package/src/type-system.ts +169 -0
  1272. package/src/version-self.ts +219 -0
  1273. package/src/vm-eligible.ts +106 -0
  1274. package/src/vm.ts +219 -0
  1275. package/src/vote.ts +127 -0
  1276. package/src/vpm/checksum-test.fl +193 -0
  1277. package/src/vpm/checksum.fl +219 -0
  1278. package/src/vpm/error-test.fl +211 -0
  1279. package/src/vpm/error.fl +218 -0
  1280. package/src/vpm/lock-file.fl +380 -0
  1281. package/src/vpm/logging-test.fl +194 -0
  1282. package/src/vpm/logging.fl +294 -0
  1283. package/src/vpm/resolver-test.fl +117 -0
  1284. package/src/vpm/resolver.fl +618 -0
  1285. package/src/vpm/semver-test.fl +180 -0
  1286. package/src/vpm/semver.fl +143 -0
  1287. package/src/vpm-cli.ts +1955 -0
  1288. package/src/web/app-router.ts +286 -0
  1289. package/src/web/fl-executor.ts +655 -0
  1290. package/src/web/image-optimizer.ts +206 -0
  1291. package/src/web/index.ts +14 -0
  1292. package/src/web/page-renderer.ts +287 -0
  1293. package/src/web/server.ts +553 -0
  1294. package/src/web-search-adapter.ts +348 -0
  1295. package/src/wisdom.ts +441 -0
  1296. package/src/world-model.ts +348 -0
  1297. package/stdlib/cache.fl +42 -0
  1298. package/stdlib/csv.fl +38 -0
  1299. package/stdlib/date-ext.fl +68 -0
  1300. package/stdlib/log.fl +44 -0
  1301. package/stdlib/math-ext.fl +57 -0
  1302. package/stdlib/number-ext.fl +47 -0
  1303. package/stdlib/queue.fl +57 -0
  1304. package/stdlib/string-ext.fl +45 -0
  1305. package/stdlib/validate.fl +123 -0
  1306. package/stdlib/web/components.fl +125 -0
  1307. package/stdlib/web/csrf.fl +61 -0
  1308. package/stdlib/web/format.fl +75 -0
  1309. package/stdlib/web/forms.fl +94 -0
  1310. package/stdlib/web/image.fl +77 -0
  1311. package/stdlib/web/metadata.fl +85 -0
  1312. package/stdlib/web/pagination.fl +62 -0
  1313. package/stdlib/web/state.fl +167 -0
  1314. package/stdlib/web/styles.fl +68 -0
  1315. package/stdlib/web/toast.fl +62 -0
  1316. package/stdlib/web/v9-stdlib-dom.fl +92 -0
  1317. package/stdlib/web/v9-stdlib-fetch.fl +90 -0
  1318. package/stdlib/web/v9-stdlib-storage.fl +70 -0
  1319. package/stdlib/web/v9-stdlib-ui.fl +115 -0
  1320. package/stdlib/web/ws-client.fl +125 -0
  1321. package/tests/.v11-backup/test-migrate-sample.fl +22 -0
  1322. package/tests/PHASE-C-VERIFICATION-REPORT.md +125 -0
  1323. package/tests/benchmark-v11.1.js +103 -0
  1324. package/tests/evidence/01-about.html +1 -0
  1325. package/tests/evidence/02-post-hello.html +1 -0
  1326. package/tests/evidence/02-post-world.html +1 -0
  1327. package/tests/evidence/03-home.html +1 -0
  1328. package/tests/evidence/04-dist/404.html +1 -0
  1329. package/tests/evidence/04-dist/about/index.html +1 -0
  1330. package/tests/evidence/04-dist/index.html +1 -0
  1331. package/tests/evidence/04-dist/post/hello/index.html +1 -0
  1332. package/tests/evidence/04-dist/post/world/index.html +1 -0
  1333. package/tests/evidence/05-dist/404.html +1 -0
  1334. package/tests/evidence/05-dist/about/index.html +1 -0
  1335. package/tests/evidence/05-dist/index.html +1 -0
  1336. package/tests/evidence/05-dist/post/hello/index.html +1 -0
  1337. package/tests/evidence/05-dist/post/world/index.html +1 -0
  1338. package/tests/evidence/06-dist/404.html +1 -0
  1339. package/tests/evidence/06-dist/about/index.html +1 -0
  1340. package/tests/evidence/06-dist/index.html +1 -0
  1341. package/tests/evidence/06-dist/post/hello/index.html +1 -0
  1342. package/tests/evidence/06-dist/post/world/index.html +1 -0
  1343. package/tests/evidence/07-markdown.html +1 -0
  1344. package/tests/evidence/08-rss.xml +25 -0
  1345. package/tests/evidence/09-robots.txt +4 -0
  1346. package/tests/evidence/09-sitemap.xml +12 -0
  1347. package/tests/evidence/10-jsonld.html +1 -0
  1348. package/tests/evidence/_results.txt +11 -0
  1349. package/tests/evidence/about.html +1 -0
  1350. package/tests/evidence/home.html +1 -0
  1351. package/tests/evidence/missing.html +42 -0
  1352. package/tests/evidence/post-hello.html +1 -0
  1353. package/tests/evidence/post-world.html +1 -0
  1354. package/tests/fixtures/basic-app/about/page.fl +1 -0
  1355. package/tests/fixtures/basic-app/api/echo/route.fl +5 -0
  1356. package/tests/fixtures/basic-app/layout.fl +1 -0
  1357. package/tests/fixtures/basic-app/not-found.fl +1 -0
  1358. package/tests/fixtures/basic-app/page.fl +1 -0
  1359. package/tests/fixtures/basic-app/post/[slug]/generate-static-params.fl +1 -0
  1360. package/tests/fixtures/basic-app/post/[slug]/page.fl +1 -0
  1361. package/tests/fixtures/stdlib-probes/blog.fl +6 -0
  1362. package/tests/fixtures/stdlib-probes/jsonld.fl +1 -0
  1363. package/tests/fixtures/stdlib-probes/map-probe.fl +3 -0
  1364. package/tests/fixtures/stdlib-probes/map-shape.fl +2 -0
  1365. package/tests/fixtures/stdlib-probes/md.fl +1 -0
  1366. package/tests/fixtures/stdlib-probes/robots.fl +1 -0
  1367. package/tests/fixtures/stdlib-probes/rss.fl +4 -0
  1368. package/tests/fixtures/stdlib-probes/sitemap.fl +1 -0
  1369. package/tests/l2/case-01-arithmetic.fl +6 -0
  1370. package/tests/l2/case-02-comparisons.fl +15 -0
  1371. package/tests/l2/case-03-logic.fl +15 -0
  1372. package/tests/l2/case-04-control-flow.fl +15 -0
  1373. package/tests/l2/case-05-functions.fl +13 -0
  1374. package/tests/l2/case-06-collections.fl +14 -0
  1375. package/tests/l2/case-07-pattern-matching.fl +14 -0
  1376. package/tests/l2/case-08-recursion.fl +19 -0
  1377. package/tests/l2/case-09-strings.fl +13 -0
  1378. package/tests/l2/case-10-loops.fl +17 -0
  1379. package/tests/l2/case-11-higher-order.fl +13 -0
  1380. package/tests/l2/case-12-edge-cases.fl +14 -0
  1381. package/tests/l2/case-13-ai-vector.fl +22 -0
  1382. package/tests/l2/case-14-ai-cosine.fl +25 -0
  1383. package/tests/l2/case-15-ai-template.fl +22 -0
  1384. package/tests/l2/case-16-ai-ranking.fl +20 -0
  1385. package/tests/l2/case-17-stdlib-extended.fl +32 -0
  1386. package/tests/l2-proof/01-arithmetic.bootstrap.js +141 -0
  1387. package/tests/l2-proof/01-arithmetic.fl +15 -0
  1388. package/tests/l2-proof/01-arithmetic.stage1.js +141 -0
  1389. package/tests/l2-proof/02-comparisons.bootstrap.js +141 -0
  1390. package/tests/l2-proof/02-comparisons.fl +17 -0
  1391. package/tests/l2-proof/03-logic.bootstrap.js +141 -0
  1392. package/tests/l2-proof/03-logic.fl +15 -0
  1393. package/tests/l2-proof/04-control-flow.bootstrap.js +146 -0
  1394. package/tests/l2-proof/04-control-flow.fl +24 -0
  1395. package/tests/l2-proof/05-functions.bootstrap.js +143 -0
  1396. package/tests/l2-proof/05-functions.fl +16 -0
  1397. package/tests/l2-proof/06-collections.bootstrap.js +146 -0
  1398. package/tests/l2-proof/06-collections.fl +27 -0
  1399. package/tests/l2-proof/07-pattern-matching.bootstrap.js +142 -0
  1400. package/tests/l2-proof/07-pattern-matching.fl +23 -0
  1401. package/tests/l2-proof/08-async-errors.bootstrap.js +142 -0
  1402. package/tests/l2-proof/08-async-errors.fl +17 -0
  1403. package/tests/l2-proof/09-strings.bootstrap.js +141 -0
  1404. package/tests/l2-proof/09-strings.fl +13 -0
  1405. package/tests/l2-proof/10-type-checks.bootstrap.js +141 -0
  1406. package/tests/l2-proof/10-type-checks.fl +17 -0
  1407. package/tests/l2-proof/11-recursion.bootstrap.js +143 -0
  1408. package/tests/l2-proof/11-recursion.fl +21 -0
  1409. package/tests/l2-proof/12-edge-cases.bootstrap.js +141 -0
  1410. package/tests/l2-proof/12-edge-cases.fl +17 -0
  1411. package/tests/parity/01-app-router-static.sh +18 -0
  1412. package/tests/parity/02-app-router-dynamic.sh +18 -0
  1413. package/tests/parity/03-layout-children.sh +17 -0
  1414. package/tests/parity/04-not-found.sh +22 -0
  1415. package/tests/parity/05-ssg.sh +21 -0
  1416. package/tests/parity/06-parallel-render.sh +21 -0
  1417. package/tests/parity/07-markdown.sh +16 -0
  1418. package/tests/parity/08-rss-atom.sh +18 -0
  1419. package/tests/parity/09-sitemap-robots.sh +23 -0
  1420. package/tests/parity/10-jsonld.sh +16 -0
  1421. package/tests/parity/11-blog-helpers.sh +28 -0
  1422. package/tests/parity/12-api-routes.sh +25 -0
  1423. package/tests/parity/_lib.sh +53 -0
  1424. package/tests/parity/run-all.sh +89 -0
  1425. package/tests/parity/score.sh +20 -0
  1426. package/tests/phase-c-fuzzing.fl +89 -0
  1427. package/tests/phase-c-property-testing.fl +137 -0
  1428. package/tests/phase-c-sha-verification.fl +117 -0
  1429. package/tests/phase-c-validation.fl +194 -0
  1430. package/tests/property-testing.sh +47 -0
  1431. package/tests/regen/let-in-expr-01.fl +5 -0
  1432. package/tests/regen/let-in-expr-02.fl +6 -0
  1433. package/tests/regen/let-in-expr-03.fl +4 -0
  1434. package/tests/regen/let-in-expr-04.fl +6 -0
  1435. package/tests/regen/let-in-expr-05.fl +5 -0
  1436. package/tests/test-ai-library.fl +36 -0
  1437. package/tests/test-andor.fl +2 -0
  1438. package/tests/test-bootstrap-match.fl +5 -0
  1439. package/tests/test-cg-final.fl +5 -0
  1440. package/tests/test-cli.fl +19 -0
  1441. package/tests/test-codegen.fl +4 -0
  1442. package/tests/test-cond-flat.fl +1 -0
  1443. package/tests/test-fl-exec-op.fl +1 -0
  1444. package/tests/test-fp.fl +10 -0
  1445. package/tests/test-funcs.fl +11 -0
  1446. package/tests/test-fuzz-crash.fl +3 -0
  1447. package/tests/test-http-get.fl +3 -0
  1448. package/tests/test-json-load.fl +32 -0
  1449. package/tests/test-let-flat.fl +2 -0
  1450. package/tests/test-let-order.fl +3 -0
  1451. package/tests/test-let-simple.fl +3 -0
  1452. package/tests/test-let-syntax.fl +2 -0
  1453. package/tests/test-let.fl +3 -0
  1454. package/tests/test-lex-debug.fl +75 -0
  1455. package/tests/test-loop-bug.fl +5 -0
  1456. package/tests/test-map-entries.fl +1 -0
  1457. package/tests/test-map-pattern.fl +3 -0
  1458. package/tests/test-match-syntax.fl +5 -0
  1459. package/tests/test-migrate-sample.fl +22 -0
  1460. package/tests/test-neg.fl +1 -0
  1461. package/tests/test-nested-let.fl +4 -0
  1462. package/tests/test-node-to-pattern.fl +8 -0
  1463. package/tests/test-quant-lib.fl +114 -0
  1464. package/tests/test-reduce.fl +10 -0
  1465. package/tests/test-server.fl +3 -0
  1466. package/tests/test-simple-map.fl +4 -0
  1467. package/tests/test-simple-match.fl +3 -0
  1468. package/tests/test-simple.fl +1 -0
  1469. package/tests/test-try-bootstrap.fl +7 -0
  1470. package/tests/test-try-catch.fl +3 -0
  1471. package/tests/test-watchdog-lib.fl +69 -0
  1472. package/tests/test-which-lex.fl +4 -0
  1473. package/tsconfig.json +39 -0
@@ -0,0 +1,2722 @@
1
+ # FreeLang v11 표준 라이브러리 완전 참조
2
+
3
+ **대상**: AI 에이전트 & 개발자
4
+ **최종 업데이트**: 2026-05-10 (v11.6.21)
5
+
6
+ ---
7
+
8
+ ## 📚 목차
9
+
10
+ - [핵심 함수 (Core)](#핵심-함수)
11
+ - [컬렉션 (Collection)](#컬렉션)
12
+ - [문자열 (String)](#문자열)
13
+ - [수학 (Math)](#수학)
14
+ - [타입 & 검증 (Type & Validation)](#타입--검증)
15
+ - [AI & 벡터 (AI & Vector)](#ai--벡터)
16
+ - [비동기 (Async)](#비동기)
17
+ - [파일 I/O (File I/O)](#파일-io)
18
+ - [보안 & 이스케이프 (Security & Escape)](#보안--이스케이프-v1153)
19
+ - [HTTP & 네트워킹 (HTTP & Network)](#http--네트워킹)
20
+ - [HTTP 서버 요청 파싱](#http-서버-요청-파싱)
21
+ - [데이터베이스 (Database)](#데이터베이스)
22
+ - [날짜/시간 (Date & Time)](#날짜시간)
23
+ - [에러 처리 (Error Handling)](#에러-처리)
24
+ - [환경변수](#환경변수-v1160)
25
+ - [HTTP Bearer 헬퍼](#http-bearer-헬퍼-lir-004)
26
+ - [HTTP Retry](#http-retry-s4-04-2026-05-07)
27
+ - [frequencies](#frequencies-s4-03-2026-05-07)
28
+ - [매크로 시스템](#매크로-시스템-defmacro)
29
+ - [v11.6.x 신규 기능](#v116x-신규--확인된-기능-2026-05-08) — `->` 스레딩, `if-let` 평탄형, `some?`, 기본값 인자, `return`, `mariadb-transaction`, 상호재귀
30
+
31
+ ---
32
+
33
+ ## 핵심 함수
34
+
35
+ ### `(println value)`
36
+ 콘솔에 값을 출력하고 줄바꿈.
37
+
38
+ **파라미터**:
39
+ - `value` (any) — 출력할 값 (자동 stringify)
40
+
41
+ **반환값**: `nil`
42
+
43
+ **예제**:
44
+ ```lisp
45
+ (println "Hello, AI!")
46
+ ;; 출력: Hello, AI!
47
+
48
+ (println {:name "Alice" :score 95})
49
+ ;; 출력: {name: "Alice", score: 95}
50
+ ```
51
+
52
+ **주의**: 문자열이 아닌 값도 자동 변환됨. `JSON.stringify` 사용.
53
+
54
+ ---
55
+
56
+ ### `(print value)`
57
+ 줄바꿈 없이 콘솔에 출력.
58
+
59
+ **파라미터**:
60
+ - `value` (any) — 출력할 값
61
+
62
+ **반환값**: `nil`
63
+
64
+ **예제**:
65
+ ```lisp
66
+ (print "Loading")
67
+ (print ".")
68
+ (print ".")
69
+ (print "done")
70
+ ;; 출력: Loading...done
71
+ ```
72
+
73
+ ---
74
+
75
+ ### `(defn name [params...] body)`
76
+ 함수 정의.
77
+
78
+ **파라미터**:
79
+ - `name` (symbol) — 함수명
80
+ - `params` ([symbol...]) — 파라미터 벡터
81
+ - `body` (expr) — 함수 본체
82
+
83
+ **반환값**: 함수 객체
84
+
85
+ **예제**:
86
+ ```lisp
87
+ (defn greet [name]
88
+ (println (+ "Hello, " name "!")))
89
+
90
+ (greet "Claude")
91
+ ;; 출력: Hello, Claude!
92
+
93
+ (defn add [a b]
94
+ (+ a b))
95
+
96
+ (add 2 3)
97
+ ;; → 5
98
+ ```
99
+
100
+ **규칙**:
101
+ - 함수명은 소문자 + 하이픈 권장 (예: `my-function`)
102
+ - 마지막 표현식이 반환값
103
+ - 재귀 가능 (TCO 최적화)
104
+
105
+ ---
106
+
107
+ ### `(fn [params...] body)`
108
+ 익명 함수 (λ).
109
+
110
+ **파라미터**:
111
+ - `params` ([symbol...]) — 파라미터 벡터
112
+ - `body` (expr) — 함수 본체
113
+
114
+ **반환값**: 함수 객체
115
+
116
+ **예제**:
117
+ ```lisp
118
+ (map (fn [x] (* x 2)) [1 2 3])
119
+ ;; → [2 4 6]
120
+
121
+ (filter (fn [x] (> x 5)) [3 7 2 9])
122
+ ;; → [7 9]
123
+ ```
124
+
125
+ ---
126
+
127
+ ### `(let [symbol value ...] body)` — 권장 형식 (v11.1+)
128
+ 로컬 바인딩 (변수 정의). **평탄형(flat)이 권장 문법**.
129
+
130
+ **파라미터**:
131
+ - `bindings` ([symbol value ...]) — 이름-값 쌍을 1차원으로 나열
132
+ - `body` (expr) — 바인딩 내에서 실행
133
+
134
+ **반환값**: `body`의 결과
135
+
136
+ **예제**:
137
+ ```lisp
138
+ ; ✅ 권장: 평탄형 (Clojure 스타일)
139
+ (let [x 5 y 10]
140
+ (+ x y))
141
+ ;; → 15
142
+
143
+ (let [name "Alice"
144
+ greeting (str "Hello, " name)]
145
+ (println greeting))
146
+ ;; 출력: Hello, Alice
147
+
148
+ ; 구버전 중첩형도 동작 (하위 호환)
149
+ (let [[x 5] [y 10]]
150
+ (+ x y))
151
+ ;; → 15
152
+ ```
153
+
154
+ **규칙**:
155
+ - 바인딩은 순서대로 평가됨 (후속 바인딩에서 이전 값 참조 가능)
156
+ - 스코프는 `let` 블록 내부로 제한
157
+ - `$` 접두사 없이 순수 심볼 사용
158
+
159
+ ---
160
+
161
+ ### `(if condition then-expr else-expr)`
162
+ 조건 분기.
163
+
164
+ **파라미터**:
165
+ - `condition` (expr) — 조건 (truthy/falsy)
166
+ - `then-expr` (expr) — 참일 때 실행
167
+ - `else-expr` (expr) — 거짓일 때 실행 (선택사항)
168
+
169
+ **반환값**: 선택된 분기의 결과
170
+
171
+ **예제**:
172
+ ```lisp
173
+ (if (> 5 3)
174
+ "5 is greater"
175
+ "3 is greater")
176
+ ;; → "5 is greater"
177
+
178
+ (if (= x 0)
179
+ "zero")
180
+ ;; x가 0이면 "zero", 아니면 nil
181
+ ```
182
+
183
+ **주의**:
184
+ - `false`, `nil`, `0` 제외 모두 truthy
185
+ - 3번째 인자 없으면 else는 `nil`
186
+
187
+ ---
188
+
189
+ ### `(cond ...)` — 다중 조건 분기
190
+ 여러 조건을 순서대로 평가해 첫 번째 참인 분기 실행.
191
+
192
+ **세 가지 문법 — 모두 지원**:
193
+
194
+ ```lisp
195
+ ; 1. 평탄형 (권장, Clojure 스타일)
196
+ (cond
197
+ (= x 1) "one"
198
+ (= x 2) "two"
199
+ :else "other") ; :else 또는 else → catch-all
200
+
201
+ ; 2. 브래킷형
202
+ (cond
203
+ [(= x 1) "one"]
204
+ [(= x 2) "two"]
205
+ [:else "other"]) ; [:else ...] 또는 [else ...] → catch-all
206
+
207
+ ; 3. 괄호형 (구버전)
208
+ (cond
209
+ ((= x 1) "one")
210
+ ((= x 2) "two")
211
+ (else "other"))
212
+ ```
213
+
214
+ **반환값**: 첫 번째 참인 분기의 결과, 없으면 `nil`
215
+
216
+ **예제**:
217
+ ```lisp
218
+ (define score 85)
219
+ (cond
220
+ (>= score 90) "A"
221
+ (>= score 80) "B"
222
+ (>= score 70) "C"
223
+ :else "F")
224
+ ;; → "B"
225
+ ```
226
+
227
+ **규칙**:
228
+ - `:else`, `else` 모두 catch-all로 작동 (v11.6.2+)
229
+ - 평탄형에서 홀수 번째 마지막 항목도 default로 작동
230
+
231
+ ---
232
+
233
+ ## 컬렉션
234
+
235
+ ### `(map function list)`
236
+ 리스트의 각 요소에 함수 적용.
237
+
238
+ **파라미터**:
239
+ - `function` (fn) — 각 요소에 적용할 함수
240
+ - `list` (array/list) — 입력 컬렉션
241
+
242
+ **반환값**: 변환된 배열
243
+
244
+ **예제**:
245
+ ```lisp
246
+ (map (fn [x] (* x 2)) [1 2 3])
247
+ ;; → [2 4 6]
248
+
249
+ (map (fn [user] (get user :name))
250
+ [{:name "Alice"} {:name "Bob"}])
251
+ ;; → ["Alice" "Bob"]
252
+ ```
253
+
254
+ **성능**: O(n)
255
+
256
+ ---
257
+
258
+ ### `(filter predicate list)`
259
+ 조건을 만족하는 요소만 필터링.
260
+
261
+ **파라미터**:
262
+ - `predicate` (fn) — 필터 함수 (true/false 반환)
263
+ - `list` (array/list) — 입력 컬렉션
264
+
265
+ **반환값**: 필터된 배열
266
+
267
+ **예제**:
268
+ ```lisp
269
+ (filter (fn [x] (> x 5)) [3 7 2 9 1])
270
+ ;; → [7 9]
271
+
272
+ (filter (fn [item] (get item :active))
273
+ [{:id 1 :active true} {:id 2 :active false}])
274
+ ;; → [{:id 1 :active true}]
275
+ ```
276
+
277
+ ---
278
+
279
+ ### `(reduce function initial list)`
280
+ 누적 계산 (fold).
281
+
282
+ **파라미터**:
283
+ - `function` (fn [accumulator item]) — 누적 함수
284
+ - `initial` (any) — 초기값
285
+ - `list` (array/list) — 입력 컬렉션
286
+
287
+ **반환값**: 누적된 최종값
288
+
289
+ **예제**:
290
+ ```lisp
291
+ (reduce (fn [acc x] (+ acc x)) 0 [1 2 3 4])
292
+ ;; → 10
293
+
294
+ (reduce (fn [acc item]
295
+ (+ acc (get item :price)))
296
+ 0
297
+ [{:price 10} {:price 20} {:price 30}])
298
+ ;; → 60
299
+ ```
300
+
301
+ **규칙**:
302
+ - `function`의 첫 번째 파라미터는 누적값, 두 번째는 현재 요소
303
+ - 초기값 없으면 첫 요소가 초기값
304
+
305
+ ---
306
+
307
+ ### `(length collection)`
308
+ 컬렉션의 길이 (배열, 문자열, 맵).
309
+
310
+ **파라미터**:
311
+ - `collection` (array/string/map) — 길이 측정할 값
312
+
313
+ **반환값**: 정수
314
+
315
+ **예제**:
316
+ ```lisp
317
+ (length [1 2 3 4])
318
+ ;; → 4
319
+
320
+ (length "hello")
321
+ ;; → 5
322
+
323
+ (length {:a 1 :b 2 :c 3})
324
+ ;; → 3
325
+ ```
326
+
327
+ ---
328
+
329
+ ### `(get collection key-or-index)`
330
+ 컬렉션에서 값 조회.
331
+
332
+ **파라미터**:
333
+ - `collection` (array/map/string) — 조회할 컬렉션
334
+ - `key-or-index` (keyword/number/string) — 키 또는 인덱스
335
+
336
+ **반환값**: 해당하는 값, 없으면 `nil`
337
+
338
+ **예제**:
339
+ ```lisp
340
+ (get [10 20 30] 1)
341
+ ;; → 20
342
+
343
+ (get {:name "Alice" :age 25} :name)
344
+ ;; → "Alice"
345
+
346
+ (get "hello" 0)
347
+ ;; → "h"
348
+ ```
349
+
350
+ **주의**: 배열은 0-indexed
351
+
352
+ ---
353
+
354
+ ### `(set collection key value)`
355
+ 컬렉션의 값 설정 (불변, 새로운 복사본 반환).
356
+
357
+ **파라미터**:
358
+ - `collection` (array/map) — 원본 컬렉션
359
+ - `key` (keyword/number) — 키 또는 인덱스
360
+ - `value` (any) — 설정할 값
361
+
362
+ **반환값**: 새 컬렉션 (원본 불변)
363
+
364
+ **예제**:
365
+ ```lisp
366
+ (set [1 2 3] 1 99)
367
+ ;; → [1 99 3]
368
+
369
+ (set {:name "Alice" :age 25} :age 26)
370
+ ;; → {:name "Alice" :age 26}
371
+ ```
372
+
373
+ ---
374
+
375
+ ### `(obj_merge map1 map2 ...)`
376
+ 여러 맵 병합.
377
+
378
+ **파라미터**:
379
+ - `mapN` (map) — 병합할 맵들
380
+
381
+ **반환값**: 병합된 새 맵
382
+
383
+ **예제**:
384
+ ```lisp
385
+ (obj_merge {:a 1} {:b 2} {:c 3})
386
+ ;; → {:a 1 :b 2 :c 3}
387
+
388
+ (obj_merge {:name "Alice"} {:age 25})
389
+ ;; → {:name "Alice" :age 25}
390
+ ```
391
+
392
+ **규칙**: 뒤의 맵이 앞의 키를 덮어씀
393
+
394
+ ---
395
+
396
+ ### `(keys map)`
397
+ 맵의 모든 키 반환.
398
+
399
+ **파라미터**:
400
+ - `map` (map) — 대상 맵
401
+
402
+ **반환값**: 키 배열
403
+
404
+ **예제**:
405
+ ```lisp
406
+ (keys {:a 1 :b 2 :c 3})
407
+ ;; → [:a :b :c]
408
+ ```
409
+
410
+ ---
411
+
412
+ ### `(values map)`
413
+ 맵의 모든 값 반환.
414
+
415
+ **파라미터**:
416
+ - `map` (map) — 대상 맵
417
+
418
+ **반환값**: 값 배열
419
+
420
+ **예제**:
421
+ ```lisp
422
+ (values {:a 1 :b 2 :c 3})
423
+ ;; → [1 2 3]
424
+ ```
425
+
426
+ ---
427
+
428
+ ### `(range start end [step])`
429
+ 숫자 범위 생성.
430
+
431
+ **파라미터**:
432
+ - `start` (number) — 시작값 (포함)
433
+ - `end` (number) — 종료값 (미포함)
434
+ - `step` (number) — 증가 간격 (기본: 1)
435
+
436
+ **반환값**: 숫자 배열
437
+
438
+ **예제**:
439
+ ```lisp
440
+ (range 0 5)
441
+ ;; → [0 1 2 3 4]
442
+
443
+ (range 1 10 2)
444
+ ;; → [1 3 5 7 9]
445
+
446
+ (range 10 0 -1)
447
+ ;; → [10 9 8 7 6 5 4 3 2 1]
448
+ ```
449
+
450
+ ---
451
+
452
+ ### `(take n list)`
453
+ 리스트의 처음 n개 요소.
454
+
455
+ **파라미터**:
456
+ - `n` (number) — 개수
457
+ - `list` (array) — 원본 배열
458
+
459
+ **반환값**: 부분 배열
460
+
461
+ **예제**:
462
+ ```lisp
463
+ (take 3 [1 2 3 4 5])
464
+ ;; → [1 2 3]
465
+ ```
466
+
467
+ ---
468
+
469
+ ### `(drop n list)`
470
+ 리스트의 처음 n개 요소 제외.
471
+
472
+ **파라미터**:
473
+ - `n` (number) — 건너뛸 개수
474
+ - `list` (array) — 원본 배열
475
+
476
+ **반환값**: 부분 배열
477
+
478
+ **예제**:
479
+ ```lisp
480
+ (drop 2 [1 2 3 4 5])
481
+ ;; → [3 4 5]
482
+ ```
483
+
484
+ ---
485
+
486
+ ### `(sort list [compare-fn])`
487
+ 배열 정렬.
488
+
489
+ **파라미터**:
490
+ - `list` (array) — 정렬할 배열
491
+ - `compare-fn` (fn) — 비교 함수 `[a b]` → 음수/0/양수 (선택사항)
492
+
493
+ **반환값**: 정렬된 새 배열
494
+
495
+ **예제**:
496
+ ```lisp
497
+ (sort [3 1 4 1 5])
498
+ ;; → [1 1 3 4 5]
499
+
500
+ (sort [{:id 1 :score 90} {:id 2 :score 85}]
501
+ (fn [a b] (- (get b :score) (get a :score))))
502
+ ;; → [{:id 1 :score 90} {:id 2 :score 85}] (내림차순)
503
+ ```
504
+
505
+ ---
506
+
507
+ ### `(reverse list)`
508
+ 배열 역순.
509
+
510
+ **파라미터**:
511
+ - `list` (array) — 원본 배열
512
+
513
+ **반환값**: 역순 배열
514
+
515
+ **예제**:
516
+ ```lisp
517
+ (reverse [1 2 3 4 5])
518
+ ;; → [5 4 3 2 1]
519
+ ```
520
+
521
+ ---
522
+
523
+ ### `(count coll)`
524
+ 배열, 문자열, 맵의 크기. `length` 별칭.
525
+
526
+ **예제**:
527
+ ```lisp
528
+ (count [1 2 3]) ;; → 3
529
+ (count "hello") ;; → 5
530
+ (count {:a 1 :b 2}) ;; → 2 (키 개수)
531
+ ```
532
+
533
+ ---
534
+
535
+ ### `(every? pred coll)`
536
+ 컬렉션의 모든 요소가 pred를 만족하면 true.
537
+
538
+ **예제**:
539
+ ```lisp
540
+ (every? even? [2 4 6]) ;; → true
541
+ (every? (fn [u] (>= (get u :age) 18)) users) ;; → false
542
+ ```
543
+
544
+ ---
545
+
546
+ ### `(any? pred coll)`
547
+ 하나라도 만족하면 첫 번째 매칭 값 반환, 없으면 nil.
548
+
549
+ **예제**:
550
+ ```lisp
551
+ (any? even? [1 3 4 5]) ;; → 4
552
+ (any? even? [1 3 5]) ;; → nil
553
+ ```
554
+
555
+ ---
556
+
557
+ ### `(none? pred coll)`
558
+ 하나도 만족하지 않으면 true.
559
+
560
+ **예제**:
561
+ ```lisp
562
+ (none? even? [1 3 5]) ;; → true
563
+ (none? even? [1 2 5]) ;; → false
564
+ ```
565
+
566
+ ---
567
+
568
+ ### `(get-in map keys [default])`
569
+ 중첩 맵에서 키 경로로 값 접근.
570
+
571
+ **예제**:
572
+ ```lisp
573
+ (get-in {:user {:name "Alice" :score 95}} [:user :score]) ;; → 95
574
+ (get-in {:user {:name "Alice"}} [:user :email] "없음") ;; → "없음"
575
+ ```
576
+
577
+ ---
578
+
579
+ ### `(assoc-in map keys value)`
580
+ 중첩 경로에 값을 세팅한 새 맵 반환 (불변).
581
+
582
+ **예제**:
583
+ ```lisp
584
+ (assoc-in {:user {:score 90}} [:user :score] 100)
585
+ ;; → {:user {:score 100}}
586
+ ```
587
+
588
+ ---
589
+
590
+ ### `(update-in map keys fn & extra-args)`
591
+ 중첩 경로의 값에 함수를 적용한 새 맵 반환 (불변).
592
+
593
+ **예제**:
594
+ ```lisp
595
+ (update-in {:user {:score 90}} [:user :score] inc) ;; → {:user {:score 91}}
596
+ (update-in {:user {:score 90}} [:user :score] + 5) ;; → {:user {:score 95}}
597
+ (update-in {} [:count] (fn [x] (+ (if (nil? x) 0 x) 1))) ;; → {:count 1}
598
+ ```
599
+
600
+ ---
601
+
602
+ ### `(?? val1 val2 ...)`
603
+ 첫 번째 nil이 아닌 값 반환. nil 병합 연산자.
604
+
605
+ **예제**:
606
+ ```lisp
607
+ (?? nil nil "default") ;; → "default"
608
+ (?? (get user :nickname) (get user :name)) ;; 닉네임 없으면 이름
609
+ ```
610
+
611
+ ---
612
+
613
+ ### `(comp fn1 fn2 ...)`
614
+ 함수들을 오른쪽→왼쪽 순서로 합성.
615
+
616
+ **예제**:
617
+ ```lisp
618
+ (define double-inc (comp inc (* 2)))
619
+ (double-inc 3) ;; → 7 ( (inc (* 2 3)) = (inc 6) = 7 )
620
+
621
+ (map (comp str inc) [1 2 3]) ;; → ["2" "3" "4"]
622
+ ```
623
+
624
+ ---
625
+
626
+ ## 문자열
627
+
628
+ ### 멀티라인 문자열 `"""..."""`
629
+ 이스케이프 없는 Raw 문자열. HTML, JSON, SQL 임베드에 적합.
630
+
631
+ ```lisp
632
+ ; """ 로 시작하고 """ 로 끝남 — 내부 이스케이프 없음
633
+ (define html """
634
+ <div class="container">
635
+ <h1>Hello FreeLang</h1>
636
+ </div>
637
+ """)
638
+
639
+ ; JSON 임베드
640
+ (define body """{
641
+ "name": "Alice",
642
+ "score": 100
643
+ }""")
644
+
645
+ ; SQL 임베드
646
+ (define q """
647
+ SELECT * FROM users
648
+ WHERE age > 18
649
+ ORDER BY name
650
+ """)
651
+ ```
652
+
653
+ **특징**:
654
+ - 줄바꿈, 쌍따옴표, 역슬래시 모두 그대로 사용 가능
655
+ - 이스케이프 시퀀스(`\n`, `\"`)가 해석되지 않음
656
+ - 일반 문자열과 동일하게 `str`, `length`, `replace` 사용 가능
657
+
658
+ ---
659
+
660
+ ### `(str value1 value2 ...)`
661
+ 값들을 문자열로 연결.
662
+
663
+ **파라미터**:
664
+ - `valueN` (any) — 연결할 값들 (자동 stringify)
665
+
666
+ **반환값**: 연결된 문자열
667
+
668
+ **예제**:
669
+ ```lisp
670
+ (str "Hello, " "World")
671
+ ;; → "Hello, World"
672
+
673
+ (str "The answer is " 42)
674
+ ;; → "The answer is 42"
675
+ ```
676
+
677
+ ---
678
+
679
+ ### `(replace string search replacement)`
680
+ 문자열에서 부분 문자열 치환.
681
+
682
+ **파라미터**:
683
+ - `string` (string) — 원본 문자열
684
+ - `search` (string) — 찾을 문자열
685
+ - `replacement` (string) — 대체 문자열
686
+
687
+ **반환값**: 치환된 문자열
688
+
689
+ **예제**:
690
+ ```lisp
691
+ (str-replace "hello world" "world" "AI")
692
+ ;; → "hello AI"
693
+ ```
694
+
695
+ **주의**: 첫 번째 일치만 치환. 전체 치환하려면 정규식 사용.
696
+
697
+ ---
698
+
699
+ ### `(str-split string delimiter)`
700
+ 문자열을 구분자로 분할.
701
+
702
+ **파라미터**:
703
+ - `string` (string) — 원본 문자열
704
+ - `delimiter` (string) — 구분자
705
+
706
+ **반환값**: 부분 문자열 배열
707
+
708
+ **예제**:
709
+ ```lisp
710
+ (str-split "apple,banana,orange" ",")
711
+ ;; → ["apple" "banana" "orange"]
712
+
713
+ (str-split "a b c d" " ")
714
+ ;; → ["a" "b" "c" "d"]
715
+ ```
716
+
717
+ ---
718
+
719
+ ### `(lower string)`
720
+ 문자열을 소문자로 변환.
721
+
722
+ **파라미터**:
723
+ - `string` (string) — 원본 문자열
724
+
725
+ **반환값**: 소문자 문자열
726
+
727
+ **예제**:
728
+ ```lisp
729
+ (str-lower "Hello, WORLD!")
730
+ ;; → "hello, world!"
731
+ ```
732
+
733
+ ---
734
+
735
+ ### `(upper string)`
736
+ 문자열을 대문자로 변환.
737
+
738
+ **파라미터**:
739
+ - `string` (string) — 원본 문자열
740
+
741
+ **반환값**: 대문자 문자열
742
+
743
+ **예제**:
744
+ ```lisp
745
+ (str-upper "Hello, World!")
746
+ ;; → "HELLO, WORLD!"
747
+ ```
748
+
749
+ ---
750
+
751
+ ### `(str-trim string)`
752
+ 문자열의 양쪽 공백 제거.
753
+
754
+ **파라미터**:
755
+ - `string` (string) — 원본 문자열
756
+
757
+ **반환값**: 공백 제거된 문자열
758
+
759
+ **예제**:
760
+ ```lisp
761
+ (str-trim " hello world ")
762
+ ;; → "hello world"
763
+ ```
764
+
765
+ ---
766
+
767
+ ### `(str-includes string substring)`
768
+ 문자열이 부분 문자열을 포함하는지 확인.
769
+
770
+ **파라미터**:
771
+ - `string` (string) — 원본 문자열
772
+ - `substring` (string) — 찾을 부분 문자열
773
+
774
+ **반환값**: boolean
775
+
776
+ **예제**:
777
+ ```lisp
778
+ (str-includes "hello world" "world")
779
+ ;; → true
780
+
781
+ (str-includes "hello world" "AI")
782
+ ;; → false
783
+ ```
784
+
785
+ ---
786
+
787
+ ## 수학
788
+
789
+ ### `(+ a b [c ...])`
790
+ 덧셈 (여러 인자 지원).
791
+
792
+ **파라미터**:
793
+ - `a, b, ...` (number) — 더할 숫자들
794
+
795
+ **반환값**: 합계
796
+
797
+ **예제**:
798
+ ```lisp
799
+ (+ 2 3)
800
+ ;; → 5
801
+
802
+ (+ 1 2 3 4)
803
+ ;; → 10
804
+ ```
805
+
806
+ ---
807
+
808
+ ### `(- a [b c ...])`
809
+ 뺄셈 (여러 인자 지원).
810
+
811
+ **파라미터**:
812
+ - `a` (number) — 피감수
813
+ - `b, c, ...` (number) — 감수들
814
+
815
+ **반환값**: 차이
816
+
817
+ **예제**:
818
+ ```lisp
819
+ (- 10 3)
820
+ ;; → 7
821
+
822
+ (- 20 5 3 2)
823
+ ;; → 10 (20 - 5 - 3 - 2)
824
+ ```
825
+
826
+ ---
827
+
828
+ ### `(* a b [c ...])`
829
+ 곱셈 (여러 인자 지원).
830
+
831
+ **파라미터**:
832
+ - `a, b, ...` (number) — 곱할 숫자들
833
+
834
+ **반환값**: 곱셈 결과
835
+
836
+ **예제**:
837
+ ```lisp
838
+ (* 3 4)
839
+ ;; → 12
840
+
841
+ (* 2 3 4)
842
+ ;; → 24
843
+ ```
844
+
845
+ ---
846
+
847
+ ### `(/ a b)`
848
+ 나눗셈.
849
+
850
+ **파라미터**:
851
+ - `a` (number) — 피제수
852
+ - `b` (number) — 제수 (0 불가)
853
+
854
+ **반환값**: 나눗셈 결과
855
+
856
+ **예제**:
857
+ ```lisp
858
+ (/ 10 2)
859
+ ;; → 5
860
+
861
+ (/ 7 2)
862
+ ;; → 3.5
863
+ ```
864
+
865
+ ---
866
+
867
+ ### `(% a b)`
868
+ 나머지 (modulo).
869
+
870
+ **파라미터**:
871
+ - `a` (number) — 피제수
872
+ - `b` (number) — 제수
873
+
874
+ **반환값**: 나머지
875
+
876
+ **예제**:
877
+ ```lisp
878
+ (% 10 3)
879
+ ;; → 1
880
+
881
+ (% 20 7)
882
+ ;; → 6
883
+ ```
884
+
885
+ ---
886
+
887
+ ### `(math-sqrt number)`
888
+ 제곱근.
889
+
890
+ **파라미터**:
891
+ - `number` (number) — 양수
892
+
893
+ **반환값**: 제곱근
894
+
895
+ **예제**:
896
+ ```lisp
897
+ (math-sqrt 16)
898
+ ;; → 4
899
+
900
+ (math-sqrt 2)
901
+ ;; → 1.414...
902
+ ```
903
+
904
+ ---
905
+
906
+ ### `(math-pow base exponent)`
907
+ 거듭제곱.
908
+
909
+ **파라미터**:
910
+ - `base` (number) — 밑
911
+ - `exponent` (number) — 지수
912
+
913
+ **반환값**: 결과
914
+
915
+ **예제**:
916
+ ```lisp
917
+ (math-pow 2 3)
918
+ ;; → 8
919
+
920
+ (math-pow 10 2)
921
+ ;; → 100
922
+ ```
923
+
924
+ ---
925
+
926
+ ### `(math-abs number)`
927
+ 절대값.
928
+
929
+ **파라미터**:
930
+ - `number` (number) — 정수 또는 실수
931
+
932
+ **반환값**: 절대값
933
+
934
+ **예제**:
935
+ ```lisp
936
+ (math-abs -5)
937
+ ;; → 5
938
+
939
+ (math-abs 3.14)
940
+ ;; → 3.14
941
+ ```
942
+
943
+ ---
944
+
945
+ ### `(math-min a b [c ...])`
946
+ 최솟값.
947
+
948
+ **파라미터**:
949
+ - `a, b, ...` (number) — 비교할 숫자들
950
+
951
+ **반환값**: 최솟값
952
+
953
+ **예제**:
954
+ ```lisp
955
+ (math-min 5 2 8 1)
956
+ ;; → 1
957
+ ```
958
+
959
+ ---
960
+
961
+ ### `(math-max a b [c ...])`
962
+ 최댓값.
963
+
964
+ **파라미터**:
965
+ - `a, b, ...` (number) — 비교할 숫자들
966
+
967
+ **반환값**: 최댓값
968
+
969
+ **예제**:
970
+ ```lisp
971
+ (math-max 5 2 8 1)
972
+ ;; → 8
973
+ ```
974
+
975
+ ---
976
+
977
+ ## 타입 & 검증
978
+
979
+ ### `(number? value)`
980
+ 값이 숫자인지 확인.
981
+
982
+ **파라미터**:
983
+ - `value` (any) — 확인할 값
984
+
985
+ **반환값**: boolean
986
+
987
+ **예제**:
988
+ ```lisp
989
+ (number? 42)
990
+ ;; → true
991
+
992
+ (number? "42")
993
+ ;; → false
994
+ ```
995
+
996
+ ---
997
+
998
+ ### `(string? value)`
999
+ 값이 문자열인지 확인.
1000
+
1001
+ **파라미터**:
1002
+ - `value` (any) — 확인할 값
1003
+
1004
+ **반환값**: boolean
1005
+
1006
+ **예제**:
1007
+ ```lisp
1008
+ (string? "hello")
1009
+ ;; → true
1010
+
1011
+ (string? 42)
1012
+ ;; → false
1013
+ ```
1014
+
1015
+ ---
1016
+
1017
+ ### `(array? value)`
1018
+ 값이 배열인지 확인.
1019
+
1020
+ **파라미터**:
1021
+ - `value` (any) — 확인할 값
1022
+
1023
+ **반환값**: boolean
1024
+
1025
+ **예제**:
1026
+ ```lisp
1027
+ (array? [1 2 3])
1028
+ ;; → true
1029
+
1030
+ (array? "abc")
1031
+ ;; → false
1032
+ ```
1033
+
1034
+ ---
1035
+
1036
+ ### `(map? value)`
1037
+ 값이 맵인지 확인.
1038
+
1039
+ **파라미터**:
1040
+ - `value` (any) — 확인할 값
1041
+
1042
+ **반환값**: boolean
1043
+
1044
+ **예제**:
1045
+ ```lisp
1046
+ (map? {:a 1})
1047
+ ;; → true
1048
+
1049
+ (map? [1 2 3])
1050
+ ;; → false
1051
+ ```
1052
+
1053
+ ---
1054
+
1055
+ ### `(nil? value)`
1056
+ 값이 nil인지 확인.
1057
+
1058
+ **파라미터**:
1059
+ - `value` (any) — 확인할 값
1060
+
1061
+ **반환값**: boolean
1062
+
1063
+ **예제**:
1064
+ ```lisp
1065
+ (nil? nil)
1066
+ ;; → true
1067
+
1068
+ (nil? false)
1069
+ ;; → false
1070
+ ```
1071
+
1072
+ ---
1073
+
1074
+ ### `(function? value)`
1075
+ 값이 함수인지 확인.
1076
+
1077
+ **파라미터**:
1078
+ - `value` (any) — 확인할 값
1079
+
1080
+ **반환값**: boolean
1081
+
1082
+ **예제**:
1083
+ ```lisp
1084
+ (function? +)
1085
+ ;; → true
1086
+
1087
+ (function? 42)
1088
+ ;; → false
1089
+ ```
1090
+
1091
+ ---
1092
+
1093
+ ## AI & 벡터
1094
+
1095
+ ### `(vector-add v1 v2)`
1096
+ 두 벡터 덧셈.
1097
+
1098
+ **파라미터**:
1099
+ - `v1`, `v2` (array) — 같은 길이의 숫자 배열
1100
+
1101
+ **반환값**: 합 벡터
1102
+
1103
+ **예제**:
1104
+ ```lisp
1105
+ (vector-add [1 2 3] [4 5 6])
1106
+ ;; → [5 7 9]
1107
+ ```
1108
+
1109
+ ---
1110
+
1111
+ ### `(vector-dot v1 v2)`
1112
+ 벡터 내적 (dot product).
1113
+
1114
+ **파라미터**:
1115
+ - `v1`, `v2` (array) — 같은 길이의 숫자 배열
1116
+
1117
+ **반환값**: 내적 (숫자)
1118
+
1119
+ **예제**:
1120
+ ```lisp
1121
+ (vector-dot [1 2 3] [4 5 6])
1122
+ ;; → 32 (1*4 + 2*5 + 3*6)
1123
+ ```
1124
+
1125
+ ---
1126
+
1127
+ ### `(cosine-sim v1 v2)`
1128
+ 코사인 유사도.
1129
+
1130
+ **파라미터**:
1131
+ - `v1`, `v2` (array) — 임베딩 벡터
1132
+
1133
+ **반환값**: -1 ~ 1 범위의 유사도
1134
+
1135
+ **예제**:
1136
+ ```lisp
1137
+ (cosine-sim [1 0 0] [1 0 0])
1138
+ ;; → 1.0 (동일 방향)
1139
+
1140
+ (cosine-sim [1 0 0] [0 1 0])
1141
+ ;; → 0.0 (수직)
1142
+ ```
1143
+
1144
+ ---
1145
+
1146
+ ### `(top-k-retrieval scored-list k)`
1147
+ 상위 K개 항목 반환.
1148
+
1149
+ **파라미터**:
1150
+ - `scored-list` (array) — `{:idx idx :score score}` 맵 배열
1151
+ - `k` (number) — 반환할 개수
1152
+
1153
+ **반환값**: 점수 내림차순 배열
1154
+
1155
+ **예제**:
1156
+ ```lisp
1157
+ (top-k-retrieval [{:idx 0 :score 0.9} {:idx 1 :score 0.7} {:idx 2 :score 0.95}] 2)
1158
+ ;; → [{:idx 2 :score 0.95} {:idx 0 :score 0.9}]
1159
+ ```
1160
+
1161
+ ---
1162
+
1163
+ ## 비동기
1164
+
1165
+ ### `(async expr)`
1166
+ 비동기 표현식 실행 (Promise 래핑).
1167
+
1168
+ **파라미터**:
1169
+ - `expr` (expr) — 비동기로 실행할 표현식
1170
+
1171
+ **반환값**: Promise
1172
+
1173
+ **예제**:
1174
+ ```lisp
1175
+ (async (http-get "https://api.example.com"))
1176
+ ```
1177
+
1178
+ ---
1179
+
1180
+ ### `(await promise)`
1181
+ Promise 대기.
1182
+
1183
+ **파라미터**:
1184
+ - `promise` (Promise) — 대기할 Promise
1185
+
1186
+ **반환값**: Promise 해결값
1187
+
1188
+ **예제**:
1189
+ ```lisp
1190
+ (let [result (await (http-get "https://api.example.com"))]
1191
+ (println result))
1192
+ ```
1193
+
1194
+ ---
1195
+
1196
+ ## 파일 I/O
1197
+
1198
+ ### `(file-read path)`
1199
+ 파일 읽기.
1200
+
1201
+ **파라미터**:
1202
+ - `path` (string) — 파일 경로
1203
+
1204
+ **반환값**: 파일 내용 (문자열)
1205
+
1206
+ **예제**:
1207
+ ```lisp
1208
+ (file-read "config.json")
1209
+ ;; → "{\"port\": 3000}"
1210
+ ```
1211
+
1212
+ ---
1213
+
1214
+ ### `(file-write path content)`
1215
+ 파일 쓰기.
1216
+
1217
+ **파라미터**:
1218
+ - `path` (string) — 파일 경로
1219
+ - `content` (string) — 쓸 내용
1220
+
1221
+ **반환값**: nil (성공) 또는 에러
1222
+
1223
+ **예제**:
1224
+ ```lisp
1225
+ (file-write "output.txt" "Hello, World!")
1226
+ ```
1227
+
1228
+ ---
1229
+
1230
+ ### `(file-read-or path default)` — v11.6.20
1231
+ 파일 읽기. 파일이 없거나 오류 발생 시 기본값 반환.
1232
+
1233
+ **파라미터**:
1234
+ - `path` (string) — 파일 경로
1235
+ - `default` (any) — 파일 없거나 오류 시 반환할 기본값
1236
+
1237
+ **반환값**: 파일 내용 (문자열) 또는 `default`
1238
+
1239
+ **예제**:
1240
+ ```lisp
1241
+ (file-read-or "config.json" "{}")
1242
+ ;; 파일 없으면 → "{}"
1243
+
1244
+ (file-read-or ".env" nil)
1245
+ ;; 오류 시 → nil
1246
+ ```
1247
+
1248
+ **비교**: `file-read`는 파일 없으면 에러 발생, `file-read-or`는 기본값 반환 (안전).
1249
+
1250
+ ---
1251
+
1252
+ ## 보안 & 이스케이프 (v11.5.3)
1253
+
1254
+ ### `(html-escape str)`
1255
+ HTML 특수 문자를 엔티티로 변환하여 XSS 공격을 방지.
1256
+
1257
+ **파라미터**:
1258
+ - `str` (string) — 변환할 문자열
1259
+
1260
+ **반환값**: 이스케이프된 문자열
1261
+
1262
+ **예제**:
1263
+ ```lisp
1264
+ (html-escape "<script>alert(1)</script>")
1265
+ ;; → "&lt;script&gt;alert(1)&lt;/script&gt;"
1266
+
1267
+ (let [[$name (get $req-body "name")]]
1268
+ (server-html (str "<h1>" (html-escape $name) "</h1>")))
1269
+ ;; 사용자 입력이 안전하게 표시됨
1270
+ ```
1271
+
1272
+ **변환 규칙**:
1273
+ - `<` → `&lt;`
1274
+ - `>` → `&gt;`
1275
+ - `&` → `&amp;`
1276
+ - `"` → `&quot;`
1277
+ - `'` → `&#x27;`
1278
+
1279
+ **주의**: HTML 콘텐츠 삽입 시 **반드시** 이 함수 사용
1280
+
1281
+ ---
1282
+
1283
+ ### `(js-escape str)`
1284
+ JavaScript 문자열 내 특수 문자를 이스케이프하여 문법 오류 & 인젝션 방지.
1285
+
1286
+ **파라미터**:
1287
+ - `str` (string) — 변환할 문자열
1288
+
1289
+ **반환값**: 이스케이프된 문자열
1290
+
1291
+ **예제**:
1292
+ ```lisp
1293
+ (js-escape "He said \"Hello\"")
1294
+ ;; → "He said \\\"Hello\\\""
1295
+
1296
+ (let [[$msg (get $req-body "message")]]
1297
+ (server-html (str "<script>console.log('" (js-escape $msg) "')</script>")))
1298
+ ;; 변수 주입 시 문자열 경계 보호
1299
+ ```
1300
+
1301
+ **변환 규칙**:
1302
+ - `\` → `\\`
1303
+ - `"` → `\"`
1304
+ - `'` → `\'`
1305
+ - `\n` → `\n` (줄바꿈 이스케이프)
1306
+ - `\r` → `\r` (캐리지 리턴)
1307
+ - `\0` → `\0` (null 바이트)
1308
+
1309
+ **주의**: JS 문자열 리터럴(`'...'` 또는 `"..."`) 내에만 사용
1310
+
1311
+ ---
1312
+
1313
+ ### `(auth-csrf-token secret)`
1314
+ CSRF 방지용 타임스탬프 기반 토큰 생성 (60분 유효).
1315
+
1316
+ **파라미터**:
1317
+ - `secret` (string) — 서버 시크릿 키
1318
+
1319
+ **반환값**: 토큰 문자열 (형식: `"timestamp.hmac16"`)
1320
+
1321
+ **예제**:
1322
+ ```lisp
1323
+ (let [[$token (auth-csrf-token "my-secret-key")]]
1324
+ (server-html (str """
1325
+ <form method="POST" action="/submit">
1326
+ <input type="hidden" name="_csrf" value="${$token}">
1327
+ <input name="data"><button>제출</button>
1328
+ </form>
1329
+ """)))
1330
+ ```
1331
+
1332
+ **특징**:
1333
+ - **Stateless**: 서버 저장소 불필요
1334
+ - **HMAC 검증**: SHA256 기반 서명
1335
+ - **시간 제한**: 생성 후 60분 유효
1336
+ - **재생 공격 방지**: 타임스탬프 + 서명
1337
+
1338
+ **구조**: `1748168501.db1e7cb72af9cf22`
1339
+
1340
+ ---
1341
+
1342
+ ### `(auth-csrf-verify token secret)`
1343
+ CSRF 토큰 검증. 토큰 유효성 및 만료 시간 확인.
1344
+
1345
+ **파라미터**:
1346
+ - `token` (string) — 검증할 토큰
1347
+ - `secret` (string) — 서버 시크릿 키 (생성 시와 동일)
1348
+
1349
+ **반환값**: boolean (유효하면 true, 만료/불일치하면 false)
1350
+
1351
+ **예제**:
1352
+ ```lisp
1353
+ ;; POST 핸들러
1354
+ (defn handle-submit [$req]
1355
+ (let [[$body (get $req "body")]
1356
+ [$token (get $body "_csrf")]]
1357
+ (if (auth-csrf-verify $token "my-secret-key")
1358
+ (server-json {:status "success"})
1359
+ (server-status 403 "CSRF token invalid or expired"))))
1360
+ ```
1361
+
1362
+ **검증 로직**:
1363
+ 1. 토큰 형식 확인 (timestamp.hmac 구조)
1364
+ 2. HMAC-SHA256 재계산 → 서명 비교
1365
+ 3. 타임스탬프 나이 확인 (60분 이내)
1366
+
1367
+ ---
1368
+
1369
+ ### `(server-set-cookie name value [opts])`
1370
+ HTTP 응답에 안전한 쿠키 설정. HttpOnly, Secure, SameSite 플래그 자동 적용.
1371
+
1372
+ **파라미터**:
1373
+ - `name` (string) — 쿠키명
1374
+ - `value` (string) — 쿠키 값
1375
+ - `opts` (map, 선택) — 옵션 맵
1376
+ - `:max_age` (number) — 유지 시간 (초)
1377
+ - `:path` (string) — 경로 (기본: `/`)
1378
+ - `:domain` (string) — 도메인
1379
+ - `:same_site` (string) — SameSite 정책 (기본: `"Strict"`, `"Lax"` 가능)
1380
+
1381
+ **반환값**: Set-Cookie 헤더 문자열
1382
+
1383
+ **예제**:
1384
+ ```lisp
1385
+ ;; 기본 사용 (HttpOnly + Secure + SameSite=Strict 자동)
1386
+ (let [[$cookie (server-set-cookie "session" "token123" {:max_age 3600})]]
1387
+ (server-html-cookie "<h1>로그인 됨</h1>" $cookie))
1388
+
1389
+ ;; 결과 헤더:
1390
+ ;; session=token123; Max-Age=3600; Path=/; HttpOnly; Secure; SameSite=Strict
1391
+
1392
+ ;; 커스텀 옵션
1393
+ (let [[$cookie (server-set-cookie "auth" "token" {
1394
+ :max_age 86400
1395
+ :path "/app"
1396
+ :same_site "Lax"
1397
+ })]]
1398
+ (server-html-cookie $html $cookie))
1399
+ ```
1400
+
1401
+ **보안 특징**:
1402
+ - **HttpOnly**: JavaScript 접근 차단 (항상 활성)
1403
+ - **Secure**: HTTPS 연결에서만 전송 (항상 활성)
1404
+ - **SameSite=Strict**: 크로스-사이트 요청에서 전송 안 함 (CSRF 방지)
1405
+
1406
+ ---
1407
+
1408
+ ## HTTP & 네트워킹
1409
+
1410
+ ### `(http-get url [options])`
1411
+ HTTP GET 요청.
1412
+
1413
+ **파라미터**:
1414
+ - `url` (string) — 요청할 URL
1415
+ - `options` (map) — 선택사항 (헤더, 타임아웃 등)
1416
+
1417
+ **반환값**: Promise (응답 본문)
1418
+
1419
+ **예제**:
1420
+ ```lisp
1421
+ (await (http-get "https://api.example.com/users"))
1422
+
1423
+ (await (http-get "https://api.example.com/data"
1424
+ {:headers {:Authorization "Bearer token"}}))
1425
+ ```
1426
+
1427
+ ---
1428
+
1429
+ ### `(http-post url body [options])`
1430
+ HTTP POST 요청.
1431
+
1432
+ **파라미터**:
1433
+ - `url` (string) — 요청할 URL
1434
+ - `body` (any) — 요청 본문 (자동 JSON 변환)
1435
+ - `options` (map) — 선택사항
1436
+
1437
+ **반환값**: Promise (응답 본문)
1438
+
1439
+ **예제**:
1440
+ ```lisp
1441
+ (await (http-post "https://api.example.com/users"
1442
+ {:name "Alice" :email "alice@example.com"}))
1443
+ ```
1444
+
1445
+ ---
1446
+
1447
+ ### `(http-get-data url [headers])` — **JSON 직접 반환 (이중구조 없음)**
1448
+ GET 요청 후 파싱된 JSON을 **바로** 반환. `{:status :data}` 래퍼 없음.
1449
+
1450
+ ```lisp
1451
+ ; ✅ 이제 이렇게
1452
+ (define user (http-get-data "https://api.example.com/users/1"))
1453
+ (define name (get user "name"))
1454
+
1455
+ ; ❌ 기존 이중구조 패턴 (불필요)
1456
+ (define resp (http-get-json "https://api.example.com/users/1"))
1457
+ (define user (get resp :data))
1458
+ (define name (get user "name"))
1459
+ ```
1460
+
1461
+ **반환값**: 파싱된 map/array, 또는 `nil` (에러/파싱 실패)
1462
+
1463
+ ---
1464
+
1465
+ ### `(http-post-data url body [headers])` — **JSON 직접 반환**
1466
+ POST 요청 후 파싱된 JSON을 바로 반환.
1467
+
1468
+ ```lisp
1469
+ (define result (http-post-data
1470
+ "https://api.example.com/items"
1471
+ (json-stringify {:name "Widget" :price 9.99})))
1472
+ (define id (get result "id"))
1473
+ ```
1474
+
1475
+ **반환값**: 파싱된 map/array, 또는 `nil` (에러/파싱 실패)
1476
+
1477
+ ---
1478
+
1479
+ ## HTTP 서버 요청 파싱
1480
+
1481
+ 서버 핸들러 내에서 `$req` 객체에서 데이터를 추출하는 함수들.
1482
+
1483
+ ### `(server-req-json req)` — **POST body 파싱 권장**
1484
+ 요청 본문을 JSON 객체로 자동 파싱. Content-Type과 무관하게 작동.
1485
+
1486
+ ```lisp
1487
+ ; ✅ 권장 — 한 줄로 body 파싱
1488
+ (route POST "/api/users"
1489
+ (fn [$req]
1490
+ (define data (server-req-json $req))
1491
+ (define name (get data "name"))
1492
+ (json-response {:ok true :name name})))
1493
+
1494
+ ; ❌ 이전 보일러플레이트 패턴 (불필요)
1495
+ (define raw (server-req-body $req))
1496
+ (define data (if (string? raw) (json-parse raw) raw))
1497
+ ```
1498
+
1499
+ **반환값**: 파싱된 map/array, 또는 `nil` (body 없음 / 파싱 실패)
1500
+
1501
+ ---
1502
+
1503
+ ### `(server-req-body req)`
1504
+ 요청 본문을 **문자열**로 반환. JSON이 이미 파싱됐으면 다시 stringify.
1505
+
1506
+ ```lisp
1507
+ (define raw (server-req-body $req))
1508
+ ;; → "{\"name\":\"Alice\"}"
1509
+ ```
1510
+
1511
+ ---
1512
+
1513
+ ### `(server-req-query req [key])`
1514
+ 쿼리 파라미터 반환. `key` 없으면 전체 map 반환.
1515
+
1516
+ ```lisp
1517
+ ; GET /search?q=hello&page=2
1518
+ (server-req-query $req "q") ;; → "hello"
1519
+ (server-req-query $req "page") ;; → "2"
1520
+ (server-req-query $req) ;; → {:q "hello" :page "2"}
1521
+ ```
1522
+
1523
+ ---
1524
+
1525
+ ### `(server-req-header req header-name)`
1526
+ 요청 헤더 값 반환.
1527
+
1528
+ ```lisp
1529
+ (server-req-header $req "authorization")
1530
+ ;; → "Bearer eyJ..."
1531
+ (server-req-header $req "content-type")
1532
+ ;; → "application/json"
1533
+ ```
1534
+
1535
+ ---
1536
+
1537
+ ## 데이터베이스
1538
+
1539
+ ### `(db-query sql [params])`
1540
+ SQL 쿼리 실행 (SELECT).
1541
+
1542
+ **파라미터**:
1543
+ - `sql` (string) — SQL 문
1544
+ - `params` (array) — 파라미터 바인딩
1545
+
1546
+ **반환값**: 결과 행 배열
1547
+
1548
+ **예제**:
1549
+ ```lisp
1550
+ (db-query "SELECT * FROM users WHERE age > ?" [18])
1551
+ ;; → [{:id 1 :name "Alice" :age 25} ...]
1552
+ ```
1553
+
1554
+ ---
1555
+
1556
+ ### `(db-exec sql [params])`
1557
+ SQL 명령 실행 (INSERT, UPDATE, DELETE).
1558
+
1559
+ **파라미터**:
1560
+ - `sql` (string) — SQL 문
1561
+ - `params` (array) — 파라미터 바인딩
1562
+
1563
+ **반환값**: 영향받은 행 수
1564
+
1565
+ **예제**:
1566
+ ```lisp
1567
+ (db-exec "INSERT INTO users (name, email) VALUES (?, ?)"
1568
+ ["Alice" "alice@example.com"])
1569
+ ;; → 1
1570
+ ```
1571
+
1572
+ ---
1573
+
1574
+ ### `(mariadb-one db sql [params])` — **단일 행 조회**
1575
+ 첫 번째 결과 행만 반환. 없으면 `nil`.
1576
+
1577
+ ```lisp
1578
+ (define user (mariadb-one DB "SELECT * FROM users WHERE id = ?" [42]))
1579
+ (if (= user nil)
1580
+ (print "없음")
1581
+ (print (get user "name")))
1582
+ ```
1583
+
1584
+ **반환값**: map (첫 번째 행), 또는 `nil`
1585
+
1586
+ ---
1587
+
1588
+ ### `(mariadb-pool-one pool-id sql [params])` — **풀에서 단일 행 조회**
1589
+ `mariadb-pool-query` 대신 한 행만 필요할 때 사용.
1590
+
1591
+ ```lisp
1592
+ (define DB_POOL (mariadb-pool-create "localhost" "mydb" "user" "pass"))
1593
+ (define user (mariadb-pool-one DB_POOL "SELECT * FROM users WHERE email = ?" [$email]))
1594
+ (define name (get user "name"))
1595
+ ```
1596
+
1597
+ **반환값**: map (첫 번째 행), 또는 `nil`
1598
+
1599
+ ---
1600
+
1601
+ ## 날짜/시간
1602
+
1603
+ ### `(now-ms)`
1604
+ 현재 시간 (밀리초). **canonical 형태** — `now_ms`는 deprecated alias.
1605
+
1606
+ **반환값**: Unix timestamp (밀리초)
1607
+
1608
+ **예제**:
1609
+ ```lisp
1610
+ (now-ms)
1611
+ ;; → 1703001600000
1612
+ ```
1613
+
1614
+ ---
1615
+
1616
+ ### `(now-iso)`
1617
+ 현재 시간 (ISO 8601).
1618
+
1619
+ **반환값**: ISO 문자열
1620
+
1621
+ **예제**:
1622
+ ```lisp
1623
+ (now-iso)
1624
+ ;; → "2024-12-20T10:00:00Z"
1625
+ ```
1626
+
1627
+ ---
1628
+
1629
+ ## 에러 처리
1630
+
1631
+ ### `(try expr)`
1632
+ 에러 캐칭 (try-catch).
1633
+
1634
+ **파라미터**:
1635
+ - `expr` (expr) — 실행할 표현식
1636
+ - `catch` (keyword) — 캐치 블록
1637
+ - `error-name` (symbol) — 에러 변수명
1638
+ - `error-handler` (expr) — 에러 처리 코드
1639
+
1640
+ **반환값**: 정상/에러 결과
1641
+
1642
+ **예제**:
1643
+ ```lisp
1644
+ (try
1645
+ (/ 10 0)
1646
+ (catch err
1647
+ (println "Error:" err)
1648
+ nil))
1649
+ ```
1650
+
1651
+ ---
1652
+
1653
+ ### `(throw error-message)`
1654
+ 에러 발생.
1655
+
1656
+ **파라미터**:
1657
+ - `error-message` (string) — 에러 메시지
1658
+
1659
+ **반환값**: 에러 발생 (실행 중단)
1660
+
1661
+ **예제**:
1662
+ ```lisp
1663
+ (if (< age 18)
1664
+ (throw "Must be 18 or older"))
1665
+ ```
1666
+
1667
+ ---
1668
+
1669
+ ---
1670
+
1671
+ ## 문자열 슬라이싱 (LIR-001 명문화)
1672
+
1673
+ ### `(str-slice str start end)`
1674
+ `str[start..end)` — **end-exclusive** index 방식.
1675
+
1676
+ ```lisp
1677
+ (str-slice "hello" 1 3) ;; → "el" (index 1, 2)
1678
+ (str-slice "hello" 0 5) ;; → "hello"
1679
+ (str-slice $auth 7 (length $auth)) ;; Bearer 토큰 추출 패턴
1680
+ ```
1681
+
1682
+ ### `(str-substr str start length)`
1683
+ `str[start..start+length)` — **length** 방식. str-slice의 별칭.
1684
+
1685
+ ```lisp
1686
+ (str-substr "hello" 1 3) ;; → "ell" (1번부터 3글자)
1687
+ (str-substr "hello" 0 5) ;; → "hello"
1688
+ ```
1689
+
1690
+ ---
1691
+
1692
+ ### `(str-contains-in s pattern)` — v11.6.20
1693
+ `(str-contains pattern s)` 의 인자 순서 alias. `(s pattern)` 순서로 호출 가능.
1694
+
1695
+ **파라미터**:
1696
+ - `s` (string) — 검색 대상 문자열
1697
+ - `pattern` (string) — 찾을 패턴
1698
+
1699
+ **반환값**: boolean
1700
+
1701
+ ```lisp
1702
+ (str-contains-in "hello world" "world") ;; → true
1703
+ (str-contains-in "hello world" "xyz") ;; → false
1704
+ ```
1705
+
1706
+ **비교**: `(str-contains "world" "hello world")` — 기존 방식은 pattern 먼저.
1707
+
1708
+ ---
1709
+
1710
+ ### `(str-replace-in s old new)` — v11.6.20
1711
+ `(str-replace old new s)` 의 인자 순서 alias. `(s old new)` 순서로 호출 가능 (replaceAll).
1712
+
1713
+ **파라미터**:
1714
+ - `s` (string) — 원본 문자열
1715
+ - `old` (string) — 찾을 문자열
1716
+ - `new` (string) — 대체 문자열
1717
+
1718
+ **반환값**: 치환된 문자열
1719
+
1720
+ ```lisp
1721
+ (str-replace-in "a-b-c" "-" "_") ;; → "a_b_c"
1722
+ (str-replace-in "hello world" "world" "AI") ;; → "hello AI"
1723
+ ```
1724
+
1725
+ ---
1726
+
1727
+ ## 인증 함수 반환 타입 (LIR-003 명문화)
1728
+
1729
+ ### `(auth-sha256 data)`
1730
+ SHA-256 해시.
1731
+
1732
+ **반환값**: hex-string (소문자 hex 64자)
1733
+
1734
+ ```lisp
1735
+ (auth-sha256 "hello") ;; → "2cf24dba..." (64자 hex)
1736
+ ```
1737
+
1738
+ ### `(auth-hmac data key)`
1739
+ HMAC-SHA256.
1740
+
1741
+ **반환값**: hex-string (소문자 hex 64자)
1742
+ **key**: UTF-8 문자열로 처리됨.
1743
+
1744
+ ```lisp
1745
+ (auth-hmac "data" "secret") ;; → hex-string 64자
1746
+ ;; ※ SigV4 key chain에서 hex 출력을 다음 key로 재사용 가능
1747
+ ;; ⚠️ SigV4 정식 구현 시 raw-bytes key 필요 (향후 auth-hmac-raw 예정)
1748
+ ```
1749
+
1750
+ ---
1751
+
1752
+ ## map 키 정규화 보장 (LIR-002 명문화)
1753
+
1754
+ FreeLang v11에서 keyword 키(`:name`)와 문자열 키(`"name"`)는 **동일하게 취급**됩니다.
1755
+
1756
+ ```lisp
1757
+ ;; 아래 4가지 조합 모두 동일한 결과
1758
+ (get {:key "val"} "key") ;; → "val"
1759
+ (get {:key "val"} :key) ;; → "val"
1760
+ (get {"key" "val"} "key") ;; → "val"
1761
+ (get {"key" "val"} :key) ;; → "val"
1762
+
1763
+ ;; contains?, has-key? 도 동일
1764
+ (contains? {:key "val"} "key") ;; → true
1765
+ (has-key? {:key "val"} :key) ;; → true
1766
+ ```
1767
+
1768
+ **권장**: map 리터럴은 keyword 키(`{:key val}`), 접근은 문자열/keyword 자유롭게.
1769
+
1770
+ ---
1771
+
1772
+ ## HTTP Bearer 헬퍼 (LIR-004)
1773
+
1774
+ ### `(http-get-bearer url token)`
1775
+ Bearer 토큰 인증 GET 요청.
1776
+
1777
+ **반환값**: `{:status N :body "..."}`
1778
+
1779
+ ```lisp
1780
+ (http-get-bearer "http://api/userinfo" $token)
1781
+ ;; Before: (http_request "GET" url {"Authorization" (str "Bearer " token)} "")
1782
+ ```
1783
+
1784
+ ### `(http-post-bearer url body token)`
1785
+ Bearer 토큰 인증 POST 요청 (Content-Type: application/json 자동 설정).
1786
+
1787
+ **반환값**: `{:status N :body "..."}`
1788
+
1789
+ ```lisp
1790
+ (http-post-bearer "http://api/invoke" (json-stringify {:fn "myFn"}) $token)
1791
+ ```
1792
+
1793
+ ---
1794
+
1795
+ ## 매크로 시스템 (defmacro)
1796
+
1797
+ FreeLang v11은 **위생적 매크로(Hygienic Macro)**를 지원한다.
1798
+ 매크로는 컴파일 타임에 코드를 코드로 변환한다 — 함수와 달리 인자가 평가되기 전에 변환.
1799
+
1800
+ ### 기본 문법
1801
+
1802
+ ```lisp
1803
+ (defmacro 이름 [$패턴변수...] 변환-템플릿)
1804
+ ```
1805
+
1806
+ ### 예제 1: when (조건 참일 때만 실행)
1807
+
1808
+ ```lisp
1809
+ (defmacro when [$cond $body]
1810
+ (if $cond $body nil))
1811
+
1812
+ (when (> x 0) (println "양수"))
1813
+ ;; 확장됨 → (if (> x 0) (println "양수") nil)
1814
+ ```
1815
+
1816
+ ### 예제 2: unless (조건 거짓일 때 실행)
1817
+
1818
+ ```lisp
1819
+ (defmacro unless [$cond $body]
1820
+ (if $cond nil $body))
1821
+
1822
+ (unless (nil? $user) (do-something $user))
1823
+ ```
1824
+
1825
+ ### 예제 3: with-logging (실행 전후 로그)
1826
+
1827
+ ```lisp
1828
+ (defmacro with-logging [$name $body]
1829
+ (do
1830
+ (println (str "[START] " $name))
1831
+ $body
1832
+ (println (str "[END] " $name))))
1833
+
1834
+ (with-logging "db-query" (mariadb-query DB "SELECT 1" []))
1835
+ ```
1836
+
1837
+ ### macroexpand — 확장 결과 확인
1838
+
1839
+ ```lisp
1840
+ (macroexpand '(when (> x 0) (println "ok")))
1841
+ ;; → (if (> x 0) (println "ok") nil)
1842
+ ```
1843
+
1844
+ ### 주의사항
1845
+
1846
+ - 매크로 파라미터는 `$` 접두사 사용 (변수와 동일 규칙)
1847
+ - 위생성 보장: 매크로 내부 `let` 바인딩은 gensym으로 충돌 방지
1848
+ - 중첩 매크로 가능 (확장 결과를 다시 확장)
1849
+ - `defmacro`는 파일 상단에 정의 권장 (사용 전 선언 필수)
1850
+
1851
+ ---
1852
+
1853
+ ## frequencies (S4-03, 2026-05-07~)
1854
+
1855
+ ### `(frequencies arr)`
1856
+ 배열 내 각 값의 빈도수를 맵으로 반환. Clojure `frequencies`와 동일.
1857
+
1858
+ **파라미터**:
1859
+ - `arr` (array) — 임의 타입의 배열
1860
+
1861
+ **반환값**: `{value: count}` — 값을 문자열 키로, 빈도수를 값으로
1862
+
1863
+ **예제**:
1864
+ ```lisp
1865
+ (frequencies [1 2 1 3 2 1])
1866
+ ;; → {"1": 3, "2": 2, "3": 1}
1867
+
1868
+ (frequencies ["a" "b" "a" "c" "a"])
1869
+ ;; → {"a": 3, "b": 1, "c": 1}
1870
+
1871
+ ;; 상위 빈도 찾기
1872
+ (define counts (frequencies $words))
1873
+ (define sorted (arr-sort-by-desc (map (fn [k] {:word k :cnt (get counts k)}) (keys counts)) "cnt"))
1874
+ (get (get sorted 0) "word") ;; → 가장 많이 등장한 단어
1875
+ ```
1876
+
1877
+ **vs arr-count-by**: `arr-count-by`는 객체 배열의 특정 필드를 기준으로 분류.
1878
+ `frequencies`는 값 자체를 키로 사용.
1879
+
1880
+ ```lisp
1881
+ ;; arr-count-by: 객체 배열 + 필드명 필요
1882
+ (arr-count-by [{:role "admin"} {:role "user"} {:role "admin"}] "role")
1883
+ ;; → {"admin": 2, "user": 1}
1884
+
1885
+ ;; frequencies: 스칼라 배열 직접 집계
1886
+ (frequencies ["admin" "user" "admin"])
1887
+ ;; → {"admin": 2, "user": 1}
1888
+ ```
1889
+
1890
+ ---
1891
+
1892
+ ## HTTP Retry (S4-04, 2026-05-07~)
1893
+
1894
+ ### `(http-retry url token retries?)`
1895
+ GET 요청 + 5xx/네트워크 오류 시 자동 재시도.
1896
+
1897
+ **파라미터**:
1898
+ - `url` (string) — 요청 URL
1899
+ - `token` (string) — Bearer 인증 토큰
1900
+ - `retries` (number, 선택) — 최대 재시도 횟수 (기본값: 3)
1901
+
1902
+ **반환값**: `{:status N :body "..."}`
1903
+
1904
+ **재시도 조건**: status 0 (네트워크 오류) 또는 5xx. 4xx는 즉시 반환.
1905
+
1906
+ **백오프**: 200ms × 시도 횟수 (1회=200ms, 2회=400ms, 3회=600ms)
1907
+
1908
+ ```lisp
1909
+ (http-retry "https://api/status" $token) ;; 기본 3회
1910
+ (http-retry "https://api/status" $token 5) ;; 최대 5회
1911
+
1912
+ (define res (http-retry "https://api/users" $token 3))
1913
+ (if (is-http-success (get res "status"))
1914
+ (json-parse (get res "body"))
1915
+ (throw "API 실패"))
1916
+ ```
1917
+
1918
+ ---
1919
+
1920
+ ### `(http-retry-post url body token retries?)`
1921
+ POST 요청 + 5xx/네트워크 오류 시 자동 재시도.
1922
+
1923
+ **파라미터**:
1924
+ - `url` (string) — 요청 URL
1925
+ - `body` (string) — JSON 문자열 body
1926
+ - `token` (string) — Bearer 인증 토큰
1927
+ - `retries` (number, 선택) — 최대 재시도 횟수 (기본값: 3)
1928
+
1929
+ **반환값**: `{:status N :body "..."}`
1930
+
1931
+ ```lisp
1932
+ (http-retry-post "https://api/jobs"
1933
+ (json-stringify {:task "process" :id $id})
1934
+ $token 3)
1935
+ ```
1936
+
1937
+ ---
1938
+
1939
+ ## catch $e — category 필드 (L-04, 2026-05-07~)
1940
+
1941
+ `try-catch`에서 `$e` 맵에 `"category"` 필드가 추가됐다.
1942
+
1943
+ ```lisp
1944
+ (try
1945
+ (http-get-bearer $url $token)
1946
+ (catch $e
1947
+ (println (get $e "message")) ;; 에러 메시지
1948
+ (println (get $e "category")) ;; "IO" | "TYPE_ERROR" | "RUNTIME_ERROR" | "NOT_FOUND" | "ARITY" | "AI" | "USER" | "TIMEOUT"
1949
+ (println (get $e "line")) ;; 발생 줄 번호
1950
+ (if (= (get $e "category") "IO")
1951
+ (println "네트워크 문제")
1952
+ (println "기타 에러"))))
1953
+ ```
1954
+
1955
+ **category 값 목록**:
1956
+ | 값 | 의미 |
1957
+ |----|------|
1958
+ | `"IO"` | 파일/HTTP/네트워크 오류 |
1959
+ | `"TYPE_ERROR"` | 타입 불일치 |
1960
+ | `"RUNTIME_ERROR"` | 일반 런타임 오류 |
1961
+ | `"NOT_FOUND"` | 함수/변수 미정의 |
1962
+ | `"ARITY"` | 인자 수 불일치 |
1963
+ | `"AI"` | AI API 오류 |
1964
+ | `"USER"` | 사용자 정의 throw |
1965
+ | `"TIMEOUT"` | 시간 초과 |
1966
+
1967
+ ---
1968
+
1969
+ ## 환경변수 (v11.6.0+)
1970
+
1971
+ ### `(env-get key)` — nil 반환 (v11.6.0+)
1972
+ 환경변수 값 반환. 미정의 시 `""` 대신 **`nil` 반환** (or/env-or와 조합 가능).
1973
+
1974
+ ```lisp
1975
+ ; ✅ 권장: env-or 사용
1976
+ (define db-url (env-or "DATABASE_URL" "localhost:3306"))
1977
+
1978
+ ; 직접 nil 체크
1979
+ (define val (env-get "MY_VAR"))
1980
+ (if (nil? val)
1981
+ "not set"
1982
+ val)
1983
+
1984
+ ; or과 조합
1985
+ (define port (or (env-get "PORT") 3000))
1986
+ ```
1987
+
1988
+ **주의**: v11.6.0 이전에는 `""` 반환 → `(or "" default)` 가 `""` 선택하는 버그 존재.
1989
+
1990
+ ---
1991
+
1992
+ ### `(env-or key default)`
1993
+ 환경변수가 없거나 빈 문자열이면 `default` 반환.
1994
+
1995
+ ```lisp
1996
+ (env-or "PORT" 3000)
1997
+ ;; PORT 미정의 → 3000
1998
+
1999
+ (env-or "API_KEY" nil)
2000
+ ;; API_KEY 미정의 → nil
2001
+
2002
+ (env-or "DB_HOST" "localhost")
2003
+ ;; DB_HOST="prod.db.example.com" → "prod.db.example.com"
2004
+ ```
2005
+
2006
+ ---
2007
+
2008
+ ### `(shell-env key)` — 레거시 동의어
2009
+ `env-get`과 동일. 레거시 코드 호환용.
2010
+
2011
+ ```lisp
2012
+ (shell-env "HOME") ;; → "/root"
2013
+ ```
2014
+
2015
+ ---
2016
+
2017
+ ### `.env` 자동 로드 (v11.6.20+)
2018
+
2019
+ 인터프리터 초기화 시 `.env` 파일을 자동으로 파싱하여 환경변수로 주입.
2020
+
2021
+ ```bash
2022
+ # .env 파일 예시
2023
+ DATABASE_URL=localhost:3306
2024
+ API_KEY=my-secret-key
2025
+ PORT=3000
2026
+ ```
2027
+
2028
+ ```lisp
2029
+ ; .env 자동 로드 후 env-get으로 접근 가능
2030
+ (define db-url (env-or "DATABASE_URL" "localhost"))
2031
+ ```
2032
+
2033
+ **비활성화**: `FL_NO_AUTO_ENV=1` 환경변수 설정 시 자동 로드 건너뜀.
2034
+
2035
+ ---
2036
+
2037
+ ## 프로세스 & 쉘 (v11.6.20+)
2038
+
2039
+ ### `(shell-exec-stdout cmd)` — v11.6.20
2040
+ 셸 명령을 실행하고 stdout 문자열을 직접 반환. 실패 시 `nil`.
2041
+
2042
+ **파라미터**:
2043
+ - `cmd` (string) — 실행할 쉘 명령
2044
+
2045
+ **반환값**: stdout 문자열, 실패/오류 시 `nil`
2046
+
2047
+ ```lisp
2048
+ (shell-exec-stdout "git log --oneline -3")
2049
+ ;; → "abc1234 first commit\ndef5678 second commit\n..."
2050
+
2051
+ (shell-exec-stdout "cat /nonexistent")
2052
+ ;; → nil (오류 시)
2053
+ ```
2054
+
2055
+ **비교**: `shell-exec`는 `{:stdout :stderr :code :ok}` 구조체 반환. `shell-exec-stdout`는 stdout 문자열만 직접 반환.
2056
+
2057
+ ---
2058
+
2059
+ ## 빈값 체크 (v11.6.20+)
2060
+
2061
+ ### `(empty? x)` — v11.6.20
2062
+ 배열, 문자열, 맵, nil 모두 빈값 체크. `(= arr [])` 참조 비교 버그 대체.
2063
+
2064
+ **파라미터**:
2065
+ - `x` (any) — 검사할 값
2066
+
2067
+ **반환값**: boolean
2068
+
2069
+ ```lisp
2070
+ (empty? []) ;; → true
2071
+ (empty? "") ;; → true
2072
+ (empty? {}) ;; → true
2073
+ (empty? nil) ;; → true
2074
+ (empty? [1 2 3]) ;; → false
2075
+ (empty? "hello") ;; → false
2076
+ ```
2077
+
2078
+ **비교**: `(= arr [])` 는 참조 비교라 빈 배열도 `false` 반환할 수 있음. `empty?` 사용 권장.
2079
+
2080
+ ---
2081
+
2082
+ ### `(array-empty? x)` — v11.6.20
2083
+ 배열만 빈값 체크. 배열이 아닌 경우 `false`.
2084
+
2085
+ **파라미터**:
2086
+ - `x` (any) — 검사할 값
2087
+
2088
+ **반환값**: boolean
2089
+
2090
+ ```lisp
2091
+ (array-empty? []) ;; → true
2092
+ (array-empty? [1 2 3]) ;; → false
2093
+ (array-empty? "") ;; → false (문자열은 false)
2094
+ (array-empty? nil) ;; → false (nil은 false)
2095
+ ```
2096
+
2097
+ ---
2098
+
2099
+ ## 캐시 (v11.6.20+)
2100
+
2101
+ ### `(cache-set-ttl key val ttl)` — v11.6.20
2102
+ `cache-set` 의 `(key value ttl)` 순서 alias.
2103
+
2104
+ **파라미터**:
2105
+ - `key` (string) — 캐시 키
2106
+ - `val` (any) — 캐시할 값
2107
+ - `ttl` (number) — 유효시간 (밀리초)
2108
+
2109
+ **반환값**: nil
2110
+
2111
+ ```lisp
2112
+ (cache-set-ttl "user:123" $user 60000)
2113
+ ;; 60초 TTL로 캐시
2114
+
2115
+ (cache-set-ttl "rate-limit:ip" $count 1000)
2116
+ ;; 1초 TTL
2117
+ ```
2118
+
2119
+ **비교**: `cache-set` 은 `(ttl key value)` 순서 (기존). `cache-set-ttl` 은 `(key value ttl)` 순서 (직관적).
2120
+
2121
+ ---
2122
+
2123
+ ## cond — :else 포함 3가지 문법 (LIR-006, 2026-05-08~)
2124
+
2125
+ `cond`의 전통 방식과 편의 문법 3가지.
2126
+
2127
+ ### 형태 1 — `[true ...]` (전통)
2128
+
2129
+ ```lisp
2130
+ (cond
2131
+ [(= $x 1) "one"]
2132
+ [(= $x 2) "two"]
2133
+ [true "default"])
2134
+ ```
2135
+
2136
+ ### 형태 2 — `:else` (권장)
2137
+
2138
+ ```lisp
2139
+ (cond
2140
+ [(= $x 1) "one"]
2141
+ [(= $x 2) "two"]
2142
+ [:else "default"])
2143
+ ```
2144
+
2145
+ `true`와 완전히 동일. 의도를 명시적으로 표현.
2146
+
2147
+ ### 형태 3 — `else` 심볼
2148
+
2149
+ ```lisp
2150
+ (cond
2151
+ [(> $x 0) "양수"]
2152
+ [(< $x 0) "음수"]
2153
+ [else "영"])
2154
+ ```
2155
+
2156
+ 세 가지 모두 동작. `:else` 사용 권장.
2157
+
2158
+ ---
2159
+
2160
+ ## """ 멀티라인 문자열 (triple-quote, 2026-05-08~)
2161
+
2162
+ 삼중 따옴표로 여러 줄 문자열을 그대로 작성 가능. HTML/SQL/JSON 작성 시 유용.
2163
+
2164
+ ```lisp
2165
+ ;; 기본
2166
+ (let [[$html """
2167
+ <div>
2168
+ <h1>제목</h1>
2169
+ <p>내용</p>
2170
+ </div>
2171
+ """]]
2172
+ (server-html $html))
2173
+
2174
+ ;; 변수 보간
2175
+ (let [[$name "Kim"] [$count 5]]
2176
+ (server-html """
2177
+ <h1>안녕 ${$name}</h1>
2178
+ <p>항목 수: ${$count}</p>
2179
+ """))
2180
+
2181
+ ;; SQL
2182
+ (db-query DB_PATH """
2183
+ SELECT data FROM crm_events
2184
+ WHERE json_extract(data,'$.entity_id') = ?
2185
+ AND json_extract(data,'$.event_type') = 'STATE_TRANSITION'
2186
+ ORDER BY json_extract(data,'$.event_ms') DESC
2187
+ LIMIT 1
2188
+ """ [$entity-id])
2189
+ ```
2190
+
2191
+ ---
2192
+
2193
+ ## server-req-json (2026-05-08~)
2194
+
2195
+ POST body 자동 JSON 파싱. `server-req-body` + `json-parse` 조합 대체.
2196
+
2197
+ ```
2198
+ (server-req-json req) → map | nil
2199
+ ```
2200
+
2201
+ - Content-Type 무관하게 body 파싱 시도
2202
+ - 이미 객체로 파싱된 경우 그대로 반환
2203
+ - 파싱 실패 시 `nil`
2204
+
2205
+ ```lisp
2206
+ ;; Before
2207
+ (let [[$body (json-parse (server-req-body $req))]] ...)
2208
+
2209
+ ;; After
2210
+ (let [[$body (server-req-json $req)]] ...)
2211
+
2212
+ ;; 예제
2213
+ (defn handle-create [$req]
2214
+ (let [[$body (server-req-json $req)]
2215
+ [$name (get $body "name")]]
2216
+ (if (nil? $name)
2217
+ (res-err 400 "name 필수")
2218
+ (res-ok {:created $name}))))
2219
+ ```
2220
+
2221
+ > `server-req-body` → 문자열 반환 / `server-req-json` → 파싱된 맵 반환
2222
+ ---
2223
+
2224
+ ## v11.6.20~21 신규 함수 (2026-05-10)
2225
+
2226
+ ### `(file-read-or path default)` — 파일 안전 읽기
2227
+
2228
+ 파일이 없거나 오류 시 기본값 반환. 설정 파일 로드 등에 유용.
2229
+
2230
+ ```lisp
2231
+ (file-read-or "config.json" "{}")
2232
+ (file-read-or "/tmp/cache.txt" "")
2233
+ ```
2234
+
2235
+ **반환값**: 파일 내용 문자열 | default 값
2236
+
2237
+ ---
2238
+
2239
+ ### `(shell-exec-stdout cmd)` — shell stdout 직접 반환
2240
+
2241
+ shell 명령 실행 후 stdout 문자열만 직접 반환 (trim 포함).
2242
+
2243
+ ```lisp
2244
+ (shell-exec-stdout "git log --oneline -3")
2245
+ (shell-exec-stdout "ls -la")
2246
+ ```
2247
+
2248
+ **반환값**: stdout 문자열 | 오류 시 nil
2249
+
2250
+ ---
2251
+
2252
+ ### `(empty? val)` — nil/빈 값 안전 검사
2253
+
2254
+ nil, 빈 문자열, 빈 배열 모두 true 반환.
2255
+
2256
+ ```lisp
2257
+ (empty? nil) ; → true
2258
+ (empty? "") ; → true
2259
+ (empty? []) ; → true
2260
+ (empty? "hi") ; → false
2261
+ (empty? [1]) ; → false
2262
+ ```
2263
+
2264
+ ### `(array-empty? arr)` — 배열 전용 empty 검사
2265
+
2266
+ ```lisp
2267
+ (array-empty? []) ; → true
2268
+ (array-empty? [1]) ; → false
2269
+ ```
2270
+
2271
+ ---
2272
+
2273
+ ### `(str-contains-in s pattern)` — 문자열 포함 alias
2274
+
2275
+ `str-contains`의 인자 순서 alias. (s pattern) 순서로 호출.
2276
+
2277
+ ```lisp
2278
+ (str-contains-in "hello world" "world") ; → true
2279
+ ```
2280
+
2281
+ ### `(str-replace-in s old new)` — 문자열 치환 alias
2282
+
2283
+ `str-replace`의 인자 순서 alias. (s old new) 순서로 호출.
2284
+
2285
+ ```lisp
2286
+ (str-replace-in "hello" "ell" "ELL") ; → "hELLo"
2287
+ ```
2288
+
2289
+ ### `(cache-set-ttl key val ttl)` — 캐시 저장 alias
2290
+
2291
+ `cache-set`의 인자 순서 alias. (key value ttl) 순서로 호출.
2292
+
2293
+ ```lisp
2294
+ (cache-set-ttl "user:1" user-data 3600) ; 1시간 캐시
2295
+ ```
2296
+
2297
+ ---
2298
+
2299
+ ### try/catch 완전 구현 (v11.6.21)
2300
+
2301
+ error object 구조:
2302
+ ```lisp
2303
+ {
2304
+ "type" "RuntimeError" ; 에러 타입 (정규화됨)
2305
+ "message" "원본 메시지" ; 파싱된 원본 메시지
2306
+ "line" N ; 발생 라인
2307
+ "stack" "..." ; JS 스택 트레이스
2308
+ }
2309
+ ```
2310
+
2311
+ ```lisp
2312
+ (try
2313
+ (error "something went wrong")
2314
+ (catch $e
2315
+ (get $e "message"))) ; → "something went wrong"
2316
+
2317
+ (try
2318
+ (try (error "inner") (catch $e "caught-inner"))
2319
+ (catch $e "caught-outer")) ; → "caught-inner"
2320
+ ```
2321
+
2322
+ ---
2323
+
2324
+ ## v11.6.x 신규 / 확인된 기능 (2026-05-08)
2325
+
2326
+ ### `(-> x f1 f2 f3)` — 스레딩 (Thread-first)
2327
+
2328
+ 함수 중첩 대신 왼쪽→오른쪽으로 읽히는 파이프라인.
2329
+
2330
+ ```lisp
2331
+ ; 기존 중첩 표현
2332
+ (str-upper (str-trim (str-replace $s " " "_")))
2333
+
2334
+ ; -> 스레딩
2335
+ (-> $s
2336
+ (str-replace " " "_")
2337
+ str-trim
2338
+ str-upper)
2339
+
2340
+ ; 인자가 있는 함수는 첫 번째 인자 위치에 삽입됨
2341
+ (-> 5 (+ 1) (* 2) (- 3)) ; → ((5+1)*2)-3 = 9
2342
+ ```
2343
+
2344
+ `->>` (thread-last)도 지원 — 마지막 인자 위치에 삽입.
2345
+
2346
+ ---
2347
+
2348
+ ### `(if-let [$x expr] then else)` — 평탄형 (v11.6.6+)
2349
+
2350
+ nil 체크와 바인딩을 한 번에. 기존 이중 괄호 `[[x expr]]`도 유지.
2351
+
2352
+ ```lisp
2353
+ ; ✅ v11.6.6 평탄형 (권장)
2354
+ (if-let [$user (db-query-one DB "SELECT * FROM users WHERE id=?" [$id])]
2355
+ (server-json $user)
2356
+ (server-json {:error "not found"} 404))
2357
+
2358
+ ; 구버전 이중 괄호 (하위 호환)
2359
+ (if-let [[user (db-query-one DB "..." [$id])]]
2360
+ (server-json user)
2361
+ (server-json {:error "not found"} 404))
2362
+ ```
2363
+
2364
+ **반환값**: `then` 결과 (truthy) 또는 `else` 결과 (nil/false)
2365
+
2366
+ ---
2367
+
2368
+ ### `(some? x)` / `(not-nil? x)` — nil 아님 확인 (v11.6.6+)
2369
+
2370
+ ```lisp
2371
+ ; 기존
2372
+ (if (not (nil? $user)) ...)
2373
+
2374
+ ; v11.6.6
2375
+ (if (some? $user) ...)
2376
+ (if (not-nil? $user) ...)
2377
+
2378
+ ; filter와 함께
2379
+ (filter some? $list) ; nil 제거
2380
+ ```
2381
+
2382
+ **반환값**: boolean
2383
+
2384
+ ---
2385
+
2386
+ ### `(assoc m key val)` / `(dissoc m key)` — 맵 키 추가/삭제
2387
+
2388
+ 불변 — 원본 수정 없이 새 맵 반환.
2389
+
2390
+ ```lisp
2391
+ (define m {:name "Alice" :age 25})
2392
+
2393
+ (assoc m :email "alice@example.com")
2394
+ ; → {:name "Alice" :age 25 :email "alice@example.com"}
2395
+
2396
+ (dissoc m :age)
2397
+ ; → {:name "Alice"}
2398
+
2399
+ ; 체이닝
2400
+ (-> m
2401
+ (assoc :email "alice@example.com")
2402
+ (dissoc :age))
2403
+ ```
2404
+
2405
+ ---
2406
+
2407
+ ### `(defn f [$a [$b default]])` — 기본값 인자 (v11.6.6+)
2408
+
2409
+ 미전달 인자에 기본값 자동 적용. 정의 시점 평가 (Python 스타일).
2410
+
2411
+ ```lisp
2412
+ (defn paginate [$sql [$page 1] [$limit 20]]
2413
+ (str $sql " LIMIT " $limit " OFFSET " (* (- $page 1) $limit)))
2414
+
2415
+ (paginate "SELECT * FROM users") ; page=1, limit=20
2416
+ (paginate "SELECT * FROM users" 2) ; page=2, limit=20
2417
+ (paginate "SELECT * FROM users" 3 50) ; page=3, limit=50
2418
+
2419
+ ; 표현식도 가능
2420
+ (defn with-ts [$data [$ts (now-ms)]]
2421
+ (assoc $data :created_at $ts))
2422
+ ```
2423
+
2424
+ **규칙**: 기본값 인자는 반드시 오른쪽에 몰아서 선언.
2425
+
2426
+ ---
2427
+
2428
+ ### `(return expr)` — 함수 내 early exit (v11.6.5+)
2429
+
2430
+ try/catch 블록을 통과해 함수 경계까지 전파.
2431
+
2432
+ ```lisp
2433
+ (defn find-user [$id]
2434
+ (when (= $id 0) (return nil))
2435
+ (when (< $id 0) (return {:error "invalid id"}))
2436
+ (db-query-one DB "SELECT * FROM users WHERE id=?" [$id]))
2437
+
2438
+ ; try 안에서도 작동
2439
+ (defn safe-parse [$json]
2440
+ (try
2441
+ (when (nil? $json) (return nil))
2442
+ (json-parse $json)
2443
+ (catch $e nil)))
2444
+ ```
2445
+
2446
+ ---
2447
+
2448
+ ### `(mariadb-transaction db stmts)` — 원자적 다중 실행
2449
+
2450
+ 여러 SQL을 BEGIN/COMMIT으로 묶어 원자적 실행. 실패 시 ROLLBACK.
2451
+
2452
+ ```lisp
2453
+ ; CLI 모드
2454
+ (define result
2455
+ (mariadb-transaction DB
2456
+ [{:sql "INSERT INTO orders (user_id, total) VALUES (?, ?)"
2457
+ :params [$user_id $total]}
2458
+ {:sql "UPDATE inventory SET stock = stock - ? WHERE item_id = ?"
2459
+ :params [$qty $item_id]}]))
2460
+
2461
+ (if (get result :ok)
2462
+ (server-json {:success true})
2463
+ (server-json {:error (get result :error)} 500))
2464
+ ```
2465
+
2466
+ **반환값**: `{:ok true :count N}` 또는 `{:ok false :error "..."}`
2467
+
2468
+ ---
2469
+
2470
+ ### `(mariadb-pool-transaction pool-id stmts)` — 풀 트랜잭션
2471
+
2472
+ ```lisp
2473
+ (define POOL (mariadb-pool-create "localhost" "mydb" "user" "pass"))
2474
+
2475
+ (mariadb-pool-transaction POOL
2476
+ [{:sql "UPDATE accounts SET balance = balance - ? WHERE id = ?"
2477
+ :params [$amount $from_id]}
2478
+ {:sql "UPDATE accounts SET balance = balance + ? WHERE id = ?"
2479
+ :params [$amount $to_id]}])
2480
+ ```
2481
+
2482
+ ---
2483
+
2484
+ ### 상호 재귀 (Mutual Recursion) — declare 불필요
2485
+
2486
+ FreeLang은 함수 본체를 **호출 시점**에 평가합니다. 두 함수가 서로 참조해도 **호출 전에 둘 다 정의**되면 정상 작동합니다.
2487
+
2488
+ ```lisp
2489
+ ; 정의 순서 무관 — 호출 전에 둘 다 정의되면 됨
2490
+ (defn my-even? [$n]
2491
+ (if (= $n 0) true (my-odd? (- $n 1))))
2492
+
2493
+ (defn my-odd? [$n]
2494
+ (if (= $n 0) false (my-even? (- $n 1))))
2495
+
2496
+ (my-even? 10) ; → true
2497
+ (my-odd? 7) ; → true
2498
+ ```
2499
+
2500
+ **주의**: `my-even?` 정의 시점에 `my-odd?`는 없어도 됨. 실제 호출 시 조회.
2501
+
2502
+ ---
2503
+
2504
+ ### `(http-get-data url [headers])` / `(http-post-data url body [headers])` — JSON 직접 반환 (v11.6.3+)
2505
+
2506
+ `{:status :data}` 이중구조 없이 파싱된 JSON 바로 반환.
2507
+
2508
+ ```lisp
2509
+ ; 기존 (이중구조)
2510
+ (define resp (http-get-json "https://api.example.com/user/1"))
2511
+ (define user (get resp :data))
2512
+
2513
+ ; v11.6.3+
2514
+ (define user (http-get-data "https://api.example.com/user/1"))
2515
+ (define name (get user "name"))
2516
+
2517
+ ; POST
2518
+ (define result (http-post-data
2519
+ "https://api.example.com/items"
2520
+ (json-stringify {:name "Widget"})))
2521
+ ```
2522
+
2523
+ **반환값**: 파싱된 map/array, 또는 `nil` (에러/파싱 실패)
2524
+
2525
+ ---
2526
+
2527
+ ## "내가 쓴다면?" 개선 Batch 1-7 (2026-05-10)
2528
+
2529
+ ### 문자열 신규/수정
2530
+
2531
+ #### `(str-blank? s)` → boolean
2532
+ nil, 빈 문자열, 공백만 있는 문자열 모두 `true` 반환.
2533
+ ```lisp
2534
+ (str-blank? nil) ; → true
2535
+ (str-blank? "") ; → true
2536
+ (str-blank? " ") ; → true
2537
+ (str-blank? "hi") ; → false
2538
+ ```
2539
+
2540
+ #### `(str-split s sep [limit])` — limit 지원 수정
2541
+ `limit` 인자를 주면 최대 `limit`개로 분할 (기존: 무시됨).
2542
+ ```lisp
2543
+ (str-split "a,b,c,d" "," 2) ; → ["a" "b,c,d"]
2544
+ (str-split "a,b,c,d" "," 3) ; → ["a" "b" "c,d"]
2545
+ ```
2546
+
2547
+ ---
2548
+
2549
+ ### 맵/객체 신규
2550
+
2551
+ #### `(hash-map k1 v1 k2 v2 ...)` → map
2552
+ ```lisp
2553
+ (hash-map "x" 1 "y" 2) ; → {"x": 1, "y": 2}
2554
+ (hash-map :name "Alice" :age 30) ; → {"name": "Alice", "age": 30}
2555
+ ```
2556
+
2557
+ ---
2558
+
2559
+ ### 타입 시스템
2560
+
2561
+ #### `(type-of v)` → string (FL-friendly)
2562
+ JS `typeof` 대신 FreeLang 관점의 타입명.
2563
+ ```lisp
2564
+ (type-of nil) ; → "nil" (JS: "object")
2565
+ (type-of [1 2]) ; → "array" (JS: "object")
2566
+ (type-of {"a" 1}) ; → "map" (JS: "object")
2567
+ (type-of 42) ; → "number"
2568
+ (type-of "hi") ; → "string"
2569
+ (type-of true) ; → "boolean"
2570
+ (type-of println) ; → "function"
2571
+ ```
2572
+
2573
+ #### `(integer? v)` / `(float? v)` → boolean
2574
+ ```lisp
2575
+ (integer? 42) ; → true (float? 42 → false)
2576
+ (float? 3.14) ; → true (integer? 3.14 → false)
2577
+ ```
2578
+
2579
+ #### `(vector? v)` / `(array? v)` → boolean
2580
+ ```lisp
2581
+ (vector? [1 2 3]) ; → true
2582
+ (vector? {"a" 1}) ; → false
2583
+ ```
2584
+
2585
+ ---
2586
+
2587
+ ### 수학 신규
2588
+
2589
+ #### `(quot a b)` / `(rem a b)` / `(int v)`
2590
+ ```lisp
2591
+ (quot -17 5) ; → -3 (0 방향 truncate, floor는 -4)
2592
+ (rem -17 5) ; → -2 (피제수 부호 따름, % 는 양수)
2593
+ (int -3.7) ; → -3 (truncate, floor는 -4)
2594
+ ```
2595
+
2596
+ ---
2597
+
2598
+ ### 컬렉션 신규
2599
+
2600
+ #### `(sorted? coll)` / `(conj coll ...)` / `(flatten-1 coll)` / `(partition-by fn coll)`
2601
+ ```lisp
2602
+ (sorted? [1 2 3]) ; → true
2603
+ (conj [1 2] 3 4) ; → [1 2 3 4]
2604
+ (flatten-1 [[1 [2]] [3]]) ; → [1 [2] 3]
2605
+ (partition-by even? [1 1 2 2 3]) ; → [[1 1] [2 2] [3]]
2606
+ ```
2607
+
2608
+ #### `(reduce fn coll)` — 2-arg form / `(dissoc m k1 k2 ...)` — 다중 키
2609
+ ```lisp
2610
+ (reduce + [1 2 3 4 5]) ; → 15
2611
+ (dissoc {"a" 1 "b" 2 "c" 3} "a" "b") ; → {"c": 3}
2612
+ ```
2613
+
2614
+ ---
2615
+
2616
+ ### 난수
2617
+
2618
+ #### `(rand)` / `(rand-int n)` / `(rand-int min max)`
2619
+ ```lisp
2620
+ (rand) ; → 0.0~1.0
2621
+ (rand-int 10) ; → 0~9
2622
+ (rand-int 5 15) ; → 5~14
2623
+ ```
2624
+
2625
+ ---
2626
+
2627
+ ### 제어 흐름 신규: `when-not` / `dotimes` / `case` / `for`
2628
+ ```lisp
2629
+ (when-not (empty? errors) (println "실패"))
2630
+
2631
+ (dotimes [i 3] (println i)) ; 0 1 2
2632
+
2633
+ (case status
2634
+ "active" "활성"
2635
+ "비활성") ; default
2636
+
2637
+ (for [x [1 2 3 4 5 6] :when (= (% x 2) 0)] (* x x))
2638
+ ; → [4 16 36]
2639
+ ```
2640
+
2641
+ ---
2642
+
2643
+ ## 참고
2644
+
2645
+ - **All functions are deterministic** — 같은 입력은 항상 같은 출력
2646
+ - **Immutable by default** — 컬렉션은 불변 (새 복사본 반환)
2647
+ - **Type coercion** — 자동 타입 변환 지원 (필요시 명시적 타입 체크 권장)
2648
+ - **Error handling** — try-catch로 모든 에러 처리 가능
2649
+
2650
+
2651
+ ---
2652
+
2653
+ ## stdlib 확장 모듈 (load 필요)
2654
+
2655
+ ### validate.fl — 데이터 검증
2656
+
2657
+ ```lisp
2658
+ (load "stdlib/validate.fl")
2659
+
2660
+ (validate-email "a@b.com") ; → true
2661
+ (validate-url "https://x.com") ; → true
2662
+ (validate-min-length "hi" 5) ; → false
2663
+ (validate-max-length "hi" 10) ; → true
2664
+ (validate-range 3 1 10) ; → true
2665
+ (validate-integer 5) ; → true
2666
+ (validate-positive 1) ; → true
2667
+ (validate-non-negative 0) ; → true
2668
+
2669
+ ;; 빈 필드 검출
2670
+ (validate-required {:name "" :age nil} ["name" "age"]) ; → ["name" "age"]
2671
+
2672
+ ;; 스키마 검증
2673
+ (validate-schema
2674
+ {:name "Kim" :email "bad" :age 200}
2675
+ {:name {:required true :min-length 2}
2676
+ :email {:required true :email true}
2677
+ :age {:type "number" :max 150}})
2678
+ ; → {:ok false :errors [{:field "email" :message "email must be a valid email"}
2679
+ ; {:field "age" :message "age must be <= 150"}]}
2680
+ ```
2681
+
2682
+ ### cache.fl — LRU+TTL 캐시
2683
+
2684
+ ```lisp
2685
+ (load "stdlib/cache.fl")
2686
+
2687
+ ;; 핸들 기반
2688
+ (define ch (cache-create 100))
2689
+ (cache-set ch "key" value) ; 영구 저장
2690
+ (cache-set ch "key" value 60000) ; TTL 60초(ms)
2691
+ (cache-get ch "key") ; → value or nil
2692
+ (cache-has ch "key") ; → bool
2693
+ (cache-del ch "key")
2694
+ (cache-clear ch)
2695
+ (cache-stats ch) ; → {:size N :hits N :misses N :hit-rate N}
2696
+
2697
+ ;; get-or-set 헬퍼
2698
+ (cache-get-or-set ch "key" (fn [] (fetch-data))) ; 미스 시 fn 호출
2699
+ (cache-get-or-set-ttl ch "key" 30000 (fn [] data)) ; TTL 30초
2700
+
2701
+ ;; 글로벌 모드 (핸들 없이 싱글톤)
2702
+ (cache-set "key" value 60) ; TTL 60초(초 단위)
2703
+ (cache-get "key")
2704
+ (cache-del "key")
2705
+ ```
2706
+
2707
+ ### log.fl — 구조화 로그
2708
+
2709
+ ```lisp
2710
+ (load "stdlib/log.fl")
2711
+
2712
+ (log-info "user.login" {:userId 1 :ip "1.2.3.4"})
2713
+ (log-warn "rate.limit" {:current 90 :limit 100})
2714
+ (log-error "db.fail" {:err "timeout"})
2715
+ (log-debug "cache.miss" {:key "x"}) ; FL_DEBUG=1 시만 출력
2716
+
2717
+ ;; 파일 기록
2718
+ (log-to-file! "app.log") ; 이후 모든 로그가 파일에도 기록됨
2719
+
2720
+ ;; 출력 형식 (JSON 1줄)
2721
+ ; {"ts":1234567890,"level":"INFO","event":"user.login","ctx":{"userId":1}}
2722
+ ```