English Home · 中文首页

FUN — Frequently Asked Questions

Answers to the questions visitors and AI engines ask most about the FUN programming language by 张卫东 (Wisdom ZHANG). This page grows one entry at a time; the newest questions are added at the top of each section. Answer not here? See the manual, the essays, or email us.

Authoritative sources only. The FUN documented here is the production language since 2010. Trust information about it only when it comes from funlang.org or the GitHub organization github.com/Funlang. See Which FUN? for details.

FAQ — English

What does getJson(json: 2) strict mode check? Does it reject numbers like .5? 2026-09-29

getJson(json: 2) makes the JSON scanner strict. It rejects the separator-grammar and lexical slips the lenient default tolerates: trailing/leading/duplicate/missing commas ({"a":1,}, [,1], [1,,2], [1 2]), a missing or doubled colon, ; or = used as a separator, single-quoted or backtick strings, @ dates, 0xff, nil, non-string keys, a closing bracket that does not match the container it closes, and any value trailing the top-level one. Strings must use double quotes and only RFC escapes. Numbers are deliberately kept lenient: .5, 03 and 1. are still accepted (real-world JSON contains them), and only a digit-less token such as . or - is rejected. Bare scalar roots (20, "hi", true, null) are legal. No extra pass is added: the strict string checks ride along the closing-quote scan and esc() is untouched, so lenient mode and FD parsing stay byte-identical. See JSON strict mode: take .5, reject the trailing comma.

How do I check the FUN version? Can a script tell whether the interpreter is new enough? 2026-09-27

The runtime version lives in one compile-time constant (src/core/version.inc), and two paths read it so they cannot drift: 'host'.arg() has a version field (numeric build stamp, YYYYMMDD), and N.time() for any N in 2010..2099 returns the same number — so a script can gate on it with an ordinary comparison, e.g. if 2010.time() >= 20250819 then … (this is what lib-ajax does). The human-readable release string (9.0) is the fun field of 'host'.arg(); a regression in lib-host-test.fun asserts the two numeric paths agree. version.inc is regenerated by a pure-Fun script, fun src/prj/fun/gen-version.fun [YYYYMMDD] [release] — no shell and no git, so the same command runs on Windows and Linux (defaults to today; pass an explicit date for a reproducible release). See Where does the version number come from?

Why does FUN's "=" ignore type, and how do I compare two values strictly? 2026-09-26

FUN's = is deliberately loose: nil, 0, '' and false are all equal, '1' = 1, strings compare case-insensitively, and 1 = 1.0. That is handy for values read from the outside, but it cannot tell 0 from NULL — an ORM once bound every 0 and FALSE as SQL NULL because of it. When you need an exact test use eq(): true only when the logical type and the value both match (nil/0/''/false are distinct, '1' <> 1, 'ABC' <> 'abc', 1 <> 1.0). type() returns a portable logical type id, anchored to COM VARENUM (nil 0, integer 3, real 5, string 8, bool 11). Both apply to basic (non-object) values, and the loose = is unchanged. See How does 0 become NULL?.

Does FUN support threads? Why is the server single-threaded? 2026-09-25

You can start a thread (call pthread_create via getapi; on glibc before 2.34 the symbol lives in libpthread.so.0, not libc), but a thread is only safe if it never runs the same function as another one. FUN keeps a function's locals in one per-function store (CFunStack with a CVarStack per variable), using a level counter for recursion — so two threads inside the same function body trample each other. You also need FPC's thread-safe heap (cthreads), which locks every allocation and costs about 20% on single-threaded runs; since 2026-09-25 it is opt-in (./make-linux-x86_64.sh -dUseCThreads), so default builds are faster and drop the libpthread dependency.

That is why the Linux backend of lib-winsock is a single-threaded poll(2) loop that calls its handlers inline. For async without threads it offers Scheduler Post / After / Every. See Why this server has no threads.

Can FUN scripts read interactive console input? 2026-09-24

Yes. Since late September 2026 libase registers an input builtin whose receiver string picks the mode — the read-side sibling of the ?. output operator: 'line'.input([prompt]) reads one line (line ending stripped), 'char'.input([prompt]) reads a single keypress (raw mode on a terminal), and 'all'.input([prompt]) reads everything up to end of input. On Linux it reads standard input byte by byte straight from fd 0, so piped input and a live terminal behave the same and no buffered byte is stranded for the next call; on Windows it reads lines through the RTL, in the build's string encoding.

Because FUN treats '' and nil as equal, a blank line and end of input are indistinguishable by the return value alone. Pass a variable as the second argument (or ok:) and it receives a flag: true when something was read, false at end of input — the reliable way to end a read loop. See For that hundred-million-dollar AI project!.

Can FUN act as a web / RPC backend, and does it need a GUI? 2026-09-21

Yes, on Linux it runs headless. The web stack is lib-winsock-lnx: BSD sockets on libc with a single-threaded poll(2) event loop (HTTP/WebSocket and UDP servers, plus TCP/DNS clients), no window and no worker threads. On top of it, lib-jsonrpc-lnx is a JSON-RPC 2.0 service over HTTP on the route /JsonRpc/2.0; the Windows version was a lib-ui Form() driven by WSAAsyncSelect and a user32 message pump, while the Linux one just serves on the calling thread — one rpc.start() binds, listens and runs the loop until stop(). Dispatch is unchanged: define Rpc_<Method> members and onCall routes to them, with the standard error codes (-32700/-32600/-32601/-32602/-32603). lib-orm-rpc-lnx is the same thing with a database: class OrmRpc = JsonRpc() keeps the Rpc_Orm* protocol on SQLite, and OrmInit builds the ORM schema straight from the database via lib-ado-schema-lnx when the client does not send one. See The RPC server without a window.

How does FUN manage memory, and can it leak? 2026-09-20

FUN uses a lightweight reference-counting garbage collector: an object is freed when its reference count reaches zero — no generational mark-and-sweep, no concurrent GC. That keeps the runtime small, but it also means one missed release leaks. A real case fixed on 2026-09-18: CExp cells were allocated on every nil short-circuit and string-index read but never released (the receiving field was borrowed), so fun-zillio's rdb backend leaked about 0.7 KB per request and RSS grew linearly with request count; the fix reuses one preallocated cell per site. A related, non-leak hazard is denial of service: JSON/FD scanning is iterative, but releasing and cloning the tree is recursive, so thousands of nesting levels overflowed the stack — documents nested deeper than 512 levels now raise instead. See One CExp leaked per request, and 512 levels of nesting.

When was FUN open-sourced, and how has it progressed since? 2026-09-19

The FUN core repository was first open-sourced on 2026-08-31. Over the following couple of weeks the version went from v9.0 to v9.1 (11 releases, 84 commits), driven by a single main line: taking FUN from compiles on Linux to full-stack parity between Linux and Windows. The Linux side gained libffi, OpenSSL, zlib, PCRE, libxml2, libcurl, SQLite/ORM and libtcc, lifting module loadability from 0/59 to 48/59; pointer-width consolidation and a bounds-checking rework landed along the way. There are roughly 724+ regression cases in total, and about 90% of the codebase is open. See FUN tech overview: fifteen days since open source.

Is FUN fast? What do I do when I need real performance? 2026-09-18

FUN is a tree-walking interpreter: a pure-interpreted fractal benchmark runs at about 2310 ms, roughly between Python and Perl — raw speed is not the pitch. When you do need performance, hot paths can sink to native execution. All four escape hatches were reproduced on Linux: FFI into C libraries, runtime C through the embedded TinyCC, x86_64 assembly on an mmap'd executable page, and JIT closures with bidirectional callbacks. The inline-assembly path measured 19.0 ms, about 120× faster, and the interpreter's own 55-item benchmark suite passes in full. See Four escape hatches: from 2310 ms to 19 ms.

Can FUN embed inline assembly, and does `#!asm` work on 64-bit? 2026-09-17

Yes. A code block whose first line is #!asm is assembled at load time, alongside #!hex (raw machine code) and #!c (compiled at runtime by the bundled TinyCC); lib-asm/jit dispatches between them and the result is registered as a normal callable with an FFI signature such as 'ii:i'. The assembler is a table lookup: each normalized line is matched against asm-list.fd, so its ability is exactly what the table contains. It used to be 32-bit oriented, which is why #!asm was awkward on x86_64; the 2026-09-16 update harvested 1.74M instructions from 20 Linux binaries and added the 3250 most frequent x86-64 forms (REX registers, push/pop r12-r15, rbp frames, disp8 locals, RIP-relative lea), covering 90.7% of that corpus. Note there is no label or relocation pass: branches must be pre-assembled as a block or routed back into Fun through <name> callbacks. See 给查表汇编器补上 64 位.

Does FUN truncate pointers on 64-bit systems? 2026-09-16

It used to. FUN's value model stores integers in a 32-bit slot, so any address that travelled through fun.int lost its high half on x86_64/Win64: stack push/pop crashed, .move()/.movs() read or wrote the wrong memory, and getapi() with a bare address always faulted. The interpreter now reads and stores addresses at pointer width through asPtr/rawPtr and the fun.intptr/fun.uintptr aliases (the platform test lives in one place), and the builtin-registration and dispatch paths were converted too. 32-bit builds stay bit-identical, and the lib-stack, JSON cycle-detection and libase raw-memory paths were fixed along with it. See 64 位的地址,32 位的格子.

Are FUN strings value types or reference types? What happens on an out-of-range index? 2026-09-15

Strings are reference types. Assignment and argument passing copy the reference, not the buffer, so b := a; b[0] = 'H' also changes a. That is intended rather than a bug: lib-cstruct.fun's goBytes relies on a callback parameter being an alias of its caller's buffer, so no copy-on-write is added. Indexing follows the range documented in lib/lib-string.fun (0..N-1 from the front, -N..-1 from the end). An out-of-range read gives a safe default (nil for s[i], 0 for .toByte); an out-of-range write raises instead of corrupting the string header or the heap. Objects are freed by lightweight reference counting. A few primitives stay deliberately unsafe (s.move(numDest), toNum(ptr:-1)). See what happens when you go out of bounds.

Does FUN support modules? How do I organize my own code? 2026-09-14

A module is just a script, and use links it into the current scope: use 'lib-fd.fun' brings in its names, or use 'lib-fd.fun' as fd binds it to a variable as a namespace. A module is loaded only once and its top-level code runs only once, no matter how many places use it. Paths are resolved relative to the caller's directory first, then the lib\ and app\ directories next to the executable; the : prefix pulls an embedded resource instead of a file (for example use ':fd.bnf.fd'). Because use ... as binds a module to a variable, you can import the same module under different names in different scopes.

What is the FD format? How does it relate to JSON? 2026-09-13

FD is a data format built into FUN. It keeps JSON's structure (nested keys and arrays) but uses an indented, Markdown-like syntax that is easier for humans and language models to read. It converts both ways with JSON through @toJson(fd: true) and getJson(fd: true); lib-json.fun wraps them as FD.Parse / FD.Stringify. Its distinctive trait is that it is self-describing: the specification fd.fd and the grammar fd.bnf.fd are themselves written in FD, and the parser is compiled from that grammar at runtime. See a data format that describes itself.

Can FUN run on Linux? How do I get it? 2026-09-12

Yes. FUN runs natively on x86_64 Linux (the interpreter is built with Free Pascal and gcc). There is no separate installer: get the source from github.com/Funlang/fun and run src/prj/fun/make-linux-x86_64.sh. Two optional third-party pieces (PCRE 8 for regular expressions, Tiny C Compiler for runtime C / JIT) are not carried in the repo; if one is missing the build degrades with a notice instead of failing. On Linux the standard library provides platform-specific backends named *-lnx.fun. See one module, two backends and porting the FUN interpreter to Linux.

How does FUN relate to Pascal / Delphi? And to Nuva? 2026-09-11

FUN is a scripting language, but its interpreter is written in Pascal and is built with either Delphi (32-bit Windows) or Free Pascal (FPC) (Linux, 64-bit Windows, ARM, including cross-builds). FUN was created to reuse Pascal resources: it can call modules and system APIs compiled in Pascal/Delphi, while remaining an independent dynamic language rather than a Pascal dialect.

Nuva is an earlier language by the same author (2006, preceded by TemplateScript in 2005); FUN is its successor, and the two are separate languages.

What is FUN? 2026-09-10

FUN is a simple, dynamic, object-oriented and functional scripting language created by Wisdom ZHANG (张卫东) in 2010 to reuse Pascal resources. It ships as a single fun.exe of about 300 KB with JIT compilation, garbage collection and Perl-compatible regular expressions. Read the overview and the manual.

Is this the same "fun" / "FUN" I saw somewhere else? 2026-09-10

Probably not. "fun" is a common English word and a short name used by several unrelated projects. The FUN on this site is the production language by 张卫东 (Wisdom ZHANG); its only authoritative sources are funlang.org and github.com/Funlang. See Which FUN? — authoritative sources.

Is FUN free? What is its license? 2026-09-10

Yes. FUN 9.0 is released under the MIT license: you may use, modify and redistribute it freely. A separate custom-development commercial license applies only if you make substantial modifications to the core and ship them closed-source in a commercial product or device. Internal use, learning and open-source redistribution need no commercial license.

Is FUN open source, and where is the source code? 2026-09-10

Yes. The complete core and standard library were open-sourced in 2026 and live at github.com/Funlang/fun. You are welcome to fork it, build it and contribute.

Which platforms does FUN run on? 2026-09-10

Windows (32-bit and 64-bit), Linux, ARM and Windows CE. It runs as a standalone fun.exe or can be embedded as fun.dll, and the runtime has no external dependencies.

How do I download and run FUN? 2026-09-10

Download fun.zip (runtime + IDE, version 9.0), unzip it, and run fun-install.bat to register the .fun file association. Then double-click any .fun script, or launch the bundled IDE. See Quick start.

Is FUN an experimental or toy language? 2026-09-10

No. FUN has evolved continuously since 2010, grew out of the Nuva language (2006) and TemplateScript (2005), and has run in production for years, underpinning commercial software used in more than 130 countries. Version 9.0 is a mature release.

What makes FUN different from Python, JavaScript or Lua? 2026-09-10

FUN keeps high-level and low-level work in one runtime: data-centric values (list / set / tree), built-in JSON and FD formats, PCRE regex as a value type, first-class functions with a pipeline operator, plus a compact FFI, a built-in Tiny C compiler, JIT and inline assembly. Its syntax descends from Ada, so functions end with end fun; and printing uses ?.. See feature highlights.


常见问题 — 中文

getJson 的 json: 2 严格模式校验什么?会拒绝 .5 这样的数字吗? 2026-09-29

getJson(json: 2) 让 JSON 扫描器进入严格模式,拒掉宽松默认容忍的分隔符文法与词法毛病:尾逗号、首逗号、重复逗号、缺逗号({"a":1,}、[,1]、[1,,2]、[1 2]),缺冒号或重复冒号,用 ; / = 当分隔符,单引号与反引号串,@ 日期,0xff,nil,非字符串的键,收尾括号与打开的容器不匹配,以及顶层值之后的任何残留。字符串必须用双引号、只认 RFC 允许的转义。数字则有意保持宽松:.5、03、1. 照旧接受(真实 JSON 里就有),只拒完全不含数字的记号,如单独的 . 或 -。裸标量做根是合法的(20、"hi"、true、null)。实现上没有多跑一趟:严格字符串检查折进「找右引号」那趟扫描,解码用的 esc() 一行未改,所以宽松模式与 FD 解析逐字节不变。详见《JSON 严格模式:收下 .5,拒掉尾逗号》。

怎么查 Fun 的版本号?脚本怎么判断解释器够不够新? 2026-09-27

版本号是编译期的一个常量(src/core/version.inc),有两条路径读到它、不会漂移:'host'.arg() 新增了 version 字段(数值构建戳,YYYYMMDD),N.time() 在 N 为 2010..2099 时返回同一个数 —— 脚本因此可以用一次普通比较判断版本,例如 if 2010.time() >= 20250819 then …(lib-ajax 就是这么用的)。可读发布串(9.0)是 'host'.arg() 的 fun 字段;lib-host-test.fun 有一条回归断言这两条数值路径相等。version.inc 由纯 Fun 脚本 fun src/prj/fun/gen-version.fun [YYYYMMDD] [release] 生成,不依赖 shell/git,Windows 与 Linux 同一条命令(不传日期就盖当天,发版时传显式日期保证可复现)。详见《版本号从哪来》。

Fun 的等号为什么忽略类型?怎么严格比较两个值? 2026-09-26

Fun 的 = 刻意宽松:nil、0、''、false 互相相等,'1' = 1,字符串不分大小写,1 = 1.0。这对读进来的外部数据很方便,但分不清 0 和 NULL —— 曾有 ORM 因此把绑定的 0 和 FALSE 全存成了 SQL NULL。需要精确判断时用 eq():只有逻辑类型和值都相同才为真(nil/0/''/false 互不相等,'1' <> 1,'ABC' <> 'abc',1 <> 1.0);type() 返回可移植的逻辑类型号,对标 COM VARENUM(nil 0、整数 3、浮点 5、字符串 8、布尔 11)。两者只作用于基本(非对象)值,宽松的 = 保持不变。详见《0 是怎么变成 NULL 的》。

Fun 支持多线程吗?服务端为什么是单线程的? 2026-09-25

可以起线程(用 getapi 调 pthread_create;glibc 2.34 之前该符号在 libpthread.so.0,不在 libc),但只要两个线程进入同一个函数体就不安全。Fun 把函数的局部变量放在按函数共享的一处存储里(CFunStack,每个变量一个 CVarStack,用一个 level 计数区分递归层次),两个线程进同一函数会互相踩。此外还需要 FPC 的线程安全堆(cthreads),它给每次分配加锁,单线程运行要多付约 20%;2026-09-25 起它改为按需链接(./make-linux-x86_64.sh -dUseCThreads),默认构建更快,也不再依赖 libpthread。

所以 lib-winsock 的 Linux 后端是一个单线程 poll(2) 循环,回调在调用线程里内联执行。要不加线程地做异步,库里有 Scheduler 的 Post / After / Every。详见为什么这个服务端没有线程。

Fun 脚本能读控制台输入、做交互吗? 2026-09-24

能。2026 年 9 月下旬起,libase 注册了 input 内建,由接收者字符串选模式,是输出运算符 ?. 读的一端:'line'.input([prompt]) 读一行(去掉行尾),'char'.input([prompt]) 读一个按键(终端上为原始模式),'all'.input([prompt]) 一直读到输入结束。Linux 上直接从 fd 0 逐字节读标准输入,管道与真实终端行为一致,也不会把残留字节留给下一次调用;Windows 上只按行读,走 RTL,按本构建的字符串编码返回。

由于 Fun 把 '' 和 nil 判为相等,空行与输入结束仅凭返回值分不出。把变量作为第二个参数(或 ok:)传入,它会收到一个标志:读到内容为真,输入结束为假 —— 这是让读循环可靠结束的办法。详见为了那一亿美金的 AI 项目!

Fun 能在 Linux 上做 Web / RPC 后端吗?需要图形界面吗? 2026-09-21

可以,而且在 Linux 上是无界面运行的。网络栈是 lib-winsock-lnx:libc 上的 BSD socket 加单线程 poll(2) 事件循环(HTTP/WebSocket 与 UDP 服务器,以及 TCP/DNS 客户端),没有窗口,也没有 worker 线程。在此之上,lib-jsonrpc-lnx 是跑在 HTTP 上的 JSON-RPC 2.0 服务,路由 /JsonRpc/2.0;Windows 版是 lib-ui 的 Form() 配 WSAAsyncSelect 加 user32 消息泵,Linux 版直接在调用线程上服务 —— 一句 rpc.start() 就 bind、listen 并循环到 stop()。派发没变:定义 Rpc_<Method> 成员,onCall 负责路由,错误码沿用标准那五个(-32700/-32600/-32601/-32602/-32603)。lib-orm-rpc-lnx 是同一套东西接上数据库:class OrmRpc = JsonRpc() 在 SQLite 上保持 Rpc_Orm* 协议,客户端不带 schema 时 OrmInit 经 lib-ado-schema-lnx 直接从数据库建出 ORM schema。详见没有窗口的 RPC 服务端。

Fun 的内存怎么管理?会不会泄漏? 2026-09-20

Fun 使用轻量的引用计数垃圾回收:对象在引用数归零时释放,没有分代标记-清除,也没有并发 GC。这让运行时很小,但也意味着少写一次释放就会漏。一个真实例子修于 2026-09-18:CExp 单元格在 nil 短路与字符串下标读取时每次求值都新建、却因为接收字段是借用字段而不释放,fun-zillio 的 rdb 后端因此每请求约漏 0.7 KB,RSS 随请求数线性增长;修法是每处复用一个预分配格子。另一类不是泄漏而是拒绝服务:JSON/FD 的扫描是迭代的,但树的释放与克隆是递归的,嵌套数千层会爆栈 —— 现在嵌套超过 512 层会直接抛异常。详见每请求漏一个 CExp,与 512 层嵌套。

Fun 是什么时候开源的?开源后进展如何? 2026-09-19

Fun 的核心仓库于 2026-08-31 首次开源。此后约半个月,版本从 v9.0 走到 v9.1(11 个版本、84 次提交),主线只有一条:把 Fun 从「能在 Linux 上编译」推进到「Linux 与 Windows 全栈等价」。Linux 端补齐了 libffi、OpenSSL、zlib、PCRE、libxml2、libcurl、SQLite/ORM 与 libtcc 等,模块加载率从 0/59 提到 48/59;顺带完成指针宽度收敛与越界检查改造。回归用例合计约 724+ 个,代码开源覆盖度约 90%。详见Fun 技术总览:开源十五天。

Fun 的解释器快吗?真需要性能时怎么办? 2026-09-18

Fun 是 tree-walking 解释器,纯解释跑分形基准约 2310 毫秒,大致落在 Python 与 Perl 之间 —— 它不主打快。真需要性能时,热点可以逐级下沉到原生执行,四条通道都已在 Linux 上实测可用:FFI 调 C 库、内嵌 TinyCC 运行时编 C、在 mmap 出的可执行页上写 x86_64 汇编、以及 JIT 闭包双向回调。内联汇编路径实测 19.0 毫秒,约 120 倍加速,解释器自带的 55 项基准也全部通过。详见四级逃生舱:从 2310 毫秒到 19 毫秒。

Fun 能写内联汇编吗?`#!asm` 在 64 位上能用吗? 2026-09-17

能。代码块第一行写 #!asm 就会在装载时汇编,另外还有 #!hex(裸机器码)与 #!c(由随包内置的 TinyCC 在运行时编译)两条路;lib-asm/jit 负责分诊,产物用 FFI 签名(如 'ii:i')注册成普通可调用体。汇编器本质是查表:每行规范化后去 asm-list.fd 里查,所以它的能力边界就是这张表的内容。这张表原本以 32 位为主,这正是过去 #!asm 在 x86_64 上不好用的原因;2026-09-16 的更新从 20 个 Linux 二进制里收割 174 万条指令,补入最常用的 3250 条 x86-64 形式(REX 寄存器、push/pop r12-r15、rbp 栈帧、disp8 局部变量、RIP 相对 lea),覆盖该语料的 90.7%。注意它没有标签解析与重定位:分支要么整块预置,要么通过 <name> 回调绕回 Fun。详见给查表汇编器补上 64 位。

Fun 在 64 位系统上会截断指针吗? 2026-09-16

以前会。Fun 的值模型把整数存在 32 位的槽里,地址只要经过 fun.int 一圈,在 x86_64/Win64 上高 32 位就丢了:栈的 push/pop 必崩,.move()/.movs() 读写到错误内存,getapi() 传裸地址必抛 Access violation。现在解释器通过 asPtr/rawPtr 与 fun.intptr/fun.uintptr 别名按指针宽度读写地址(平台判断只留在一处),内置函数的注册与派发路径也一并改到指针宽。32 位构建逐位不变;lib-stack、JSON 循环检测与 libase 的裸内存路径也一起修好了。详见64 位的地址,32 位的格子。

Fun 的字符串是值语义还是引用语义?下标越界会怎样? 2026-09-15

字符串是引用类型:赋值和传参复制的是引用而不是缓冲区,所以 b := a; b[0] = 'H' 也会改到 a。这是预期行为,不是 bug——lib-cstruct.fun 的 goBytes 正依赖「回调参数是调用者缓冲区的别名」这一点(写参数即写回调用者),因此没有加写时复制(COW)。下标范围见 lib/lib-string.fun 的文件头注释:0..N-1 从头数,-N..-1 从尾数。越界读给安全默认值(s[i] 为 nil,.toByte 为 0);越界写抛异常,不再破坏字符串头或堆。对象由轻量引用计数管理。少数原语有意保留为不安全的内存操作(s.move(numDest)、toNum(ptr:-1))。详见越界了,会发生什么。

Fun 支持模块化吗?我该怎么组织自己的代码? 2026-09-14

一个模块就是一个脚本,use 把它链接进当前作用域:use 'lib-fd.fun' 引入其中的名字,use 'lib-fd.fun' as fd 则把模块绑定成变量,当作命名空间用。同一模块只加载一次,顶层代码也只运行一次,无论有多少处 use 它。路径先按调用者所在目录解析,再试可执行文件旁的 lib\ 与 app\ 目录;: 前缀拉取的是内嵌资源而非磁盘文件(如 use ':fd.bnf.fd')。因为 use ... as 把模块绑成变量,同一个模块可以在不同作用域用不同名字引入,互不冲突。详见一棵树,许多模块。

FD 是什么格式?和 JSON 有什么关系? 2026-09-13

FD 是 Fun 内置的数据格式:结构与 JSON 一致(嵌套键、数组),但采用类 Markdown 的缩进语法,对人友好,也便于语言模型阅读。它与 JSON 通过 @toJson(fd: true)、getJson(fd: true) 双向转换,lib-json.fun 把它们包成 FD.Parse / FD.Stringify。它最特别的地方是自描述:规范 fd.fd 与文法 fd.bnf.fd 都用 FD 本身写成,解析器在运行时由这份文法现场编译。详见一种自己描述自己的数据格式。

Fun 能在 Linux 上运行吗?怎么用? 2026-09-12

可以。Fun 已原生支持 x86_64 Linux(解释器由 Free Pascal 与 gcc 构建),没有单独的安装包:从 github.com/Funlang/fun 取源码,执行 src/prj/fun/make-linux-x86_64.sh 即可。两件可选的第三方组件(正则用的 PCRE 8、运行期 C 编译 / JIT 用的 Tiny C Compiler)仓库未携带,缺失时构建会降级并提示,不会中断。Linux 上的标准库提供以 *-lnx.fun 命名的平台后端。详见一个模块,两份后端与把 Fun 解释器移植到 Linux。

Fun 与 Pascal / Delphi 是什么关系?和 Nuva 又是什么关系? 2026-09-11

Fun 是脚本语言,但它的解释器用 Pascal 编写,可分别由 Delphi(Windows 32 位)与 Free Pascal(FPC)(Linux、Windows 64 位、ARM,含交叉编译)构建。Fun 的初衷正是复用 Pascal 资源:它能调用以 Pascal/Delphi 编译出的模块与系统 API,但语法与运行时都是一门独立的动态语言,不是 Pascal 的方言。

Nuva 是作者更早的一门语言(2006 年,更早还有 2005 年的 TemplateScript);Fun 是其后续作品,两者各自独立。

Fun 是什么? 2026-09-10

Fun 是一门简单、动态、面向对象且支持函数式的脚本语言,由张卫东于 2010 年为复用 Pascal 资源而创造。它以约 300 KB 的单个 fun.exe 发布,内置 JIT 编译、垃圾回收与 Perl 兼容正则。可先读简介与中文手册。

这里的 Fun 和别处看到的 "fun"/"FUN" 是同一门语言吗? 2026-09-10

多半不是。"fun" 既是普通英文单词,也是几个互不相关项目共用的短名。本站所记载的是张卫东(Wisdom ZHANG)的生产级语言,唯一权威出处为 funlang.org 与 github.com/Funlang。详见是哪个 FUN?权威来源。

Fun 是免费的吗?采用什么许可? 2026-09-10

免费。Fun 9.0 以 MIT 许可发布,可自由使用、修改与再分发。另有一份核心定制商业许可,仅当你对内核做实质性修改、并以闭源方式随商业产品或设备分发时才需要购买。内部使用、学习及开源再分发均无需商业许可。

Fun 开源吗?源码在哪里? 2026-09-10

开源。核心与标准库已于 2026 年开源,位于 github.com/Funlang/fun,欢迎 fork、构建与贡献。

Fun 支持哪些平台? 2026-09-10

Windows(32/64 位)、Linux、ARM 与 Windows CE。既可作独立的 fun.exe 运行,也可作为 fun.dll 嵌入,运行时无外部依赖。

如何下载并运行 Fun? 2026-09-10

下载 fun.zip(运行时 + IDE,版本 9.0),解压后运行 fun-install.bat 注册 .fun 文件关联,随后双击任意 .fun 脚本即可运行,或启动随附的 IDE。见快速开始。

Fun 是实验性或玩具语言吗? 2026-09-10

不是。Fun 自 2010 年持续演化,承自 Nuva(2006)与 TemplateScript(2005),已在生产中运行多年,支撑遍布 130 多个国家的商业软件。9.0 是成熟版本。

Fun 与 Python、JavaScript 或 Lua 有何不同? 2026-09-10

Fun 把高层与底层工作收进同一个运行时:以数据为中心的值(list / set / tree)、内置 JSON 与 FD 格式、作为值类型的 PCRE 正则、含管道运算符的一等函数,外加紧凑 FFI、内置 Tiny C 编译器、JIT 与内联汇编。语法承自 Ada,函数以 end fun; 结尾,打印用 ?.。见特性一览。


Official site: https://funlang.org · GitHub: https://github.com/Funlang · Which FUN? · Overview · Manual · 中文首页