文档与readme更新
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import std.io;
|
import std.io;
|
||||||
import std.time;
|
import std.time;
|
||||||
|
import std.value;
|
||||||
|
|
||||||
func benchmark(fn: Function, arg: Any) -> Null
|
func benchmark(fn: Function, arg: Any) -> Null
|
||||||
{
|
{
|
||||||
@@ -58,8 +59,26 @@ func fib(x)
|
|||||||
return fib(x - 1) + fib(x - 2);
|
return fib(x - 1) + fib(x - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
const n := 28;
|
func fib_tail(n, a=0, b=1) {
|
||||||
|
if n == 0 { return a; }
|
||||||
|
if n == 1 { return b; }
|
||||||
|
return fib_tail(n-1, b, a+b);
|
||||||
|
}
|
||||||
|
|
||||||
|
const n := 30;
|
||||||
|
|
||||||
|
io.println("! fib(" + value.string_from(n) + "):");
|
||||||
benchmark(fib, n);
|
benchmark(fib, n);
|
||||||
|
io.print("\n\n");
|
||||||
|
|
||||||
|
io.println("! fib_memo(" + value.string_from(n) + "):");
|
||||||
benchmark(fib_memo, n);
|
benchmark(fib_memo, n);
|
||||||
benchmark(fib_iter, n);
|
io.print("\n\n");
|
||||||
|
|
||||||
|
io.println("! fib_iter(" + value.string_from(n) + "):");
|
||||||
|
benchmark(fib_iter, n);
|
||||||
|
io.print("\n\n");
|
||||||
|
|
||||||
|
io.println("! fib_tail(" + value.string_from(n) + "):");
|
||||||
|
benchmark(fib_tail, n);
|
||||||
|
io.print("\n\n");
|
||||||
|
|||||||
68
README.md
68
README.md
@@ -1,15 +1,18 @@
|
|||||||
# Fig Language - A Modern Scripting Language
|
# Fig Language - A Modern Scripting Language
|
||||||
|
|
||||||
[Fig-Gitea](https://git.fig-lang.cn/PuqiAR/Fig)
|
[Fig-Gitea](https://git.fig-lang.cn/PuqiAR/Fig)
|
||||||
|
Recommend view on Gitea Endpoint
|
||||||
|
|
||||||
[简体中文](README_ZH-CN.md "Chinese version")
|
[简体中文](README_ZH-CN.md "Chinese version")
|
||||||
|
|
||||||
**Fig** is a statically-typed, expression-oriented programming language designed for clarity, safety, and modern development practices. With features inspired by Go, Rust, and JavaScript, Fig aims to provide a productive development experience while maintaining strong type safety.
|
**Fig** is a dynamically strongly typed programming language designed for clarity, safety, and modern development practices. With features inspired by Go, Rust, and JavaScript, Fig aims to provide a productive development experience while maintaining strong type safety.
|
||||||
|
|
||||||
|
[LanguageTutorial(zh_CN)](docs/zh_CN/01-简介.md "Chinese version")
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
### 🚀 Core Language Features
|
### 🚀 Core Language Features
|
||||||
- **Static typing with type inference** - Strong typing with minimal annotations
|
- **Dynamic typing with type inference** - Strong typing with minimal annotations
|
||||||
- **Modern control flow** - Full `for` loop support with proper scoping
|
- **Modern control flow** - Full `for` loop support with proper scoping
|
||||||
- **First-class functions** - Lambda expressions and closures
|
- **First-class functions** - Lambda expressions and closures
|
||||||
- **Rich data structures** - Structs, lists, maps, and tuples
|
- **Rich data structures** - Structs, lists, maps, and tuples
|
||||||
@@ -55,35 +58,6 @@ xmake run Fig [file]
|
|||||||
|
|
||||||
Replace `[file]` with the path to your input file.
|
Replace `[file]` with the path to your input file.
|
||||||
|
|
||||||
### 📁 Project Structure
|
|
||||||
.
|
|
||||||
├── ExampleCodes # Example programs & performance tests
|
|
||||||
│ └── SpeedTest # Performance benchmark samples
|
|
||||||
├── LICENSE # Project license
|
|
||||||
├── Logo # Project logo assets
|
|
||||||
├── README.md # English README
|
|
||||||
├── README_ZH-CN.md # Chinese README
|
|
||||||
├── compile_flags.txt # Compiler flags helper
|
|
||||||
├── fig-vscode # VSCode extension project
|
|
||||||
│ ├── node_modules # Extension dependencies
|
|
||||||
│ ├── out # Built extension output
|
|
||||||
│ ├── src # Extension source code
|
|
||||||
│ └── syntaxes # Syntax highlighting definition
|
|
||||||
├── src # Core Fig language source
|
|
||||||
│ ├── Ast # AST definitions
|
|
||||||
│ ├── Context # Runtime context
|
|
||||||
│ ├── Core # Core utilities (UTF8/string/etc.)
|
|
||||||
│ ├── Error # Error handling system
|
|
||||||
│ ├── Evaluator # Interpreter / evaluator
|
|
||||||
│ ├── Lexer # Lexical analyzer
|
|
||||||
│ ├── Module # Modules and builtins
|
|
||||||
│ ├── Parser # Parser
|
|
||||||
│ ├── Token # Token definitions
|
|
||||||
│ ├── Utils # Utilities & helper headers
|
|
||||||
│ └── Value # Runtime type/value system
|
|
||||||
├── test.fig # Test script
|
|
||||||
└── xmake.lua # Xmake build config
|
|
||||||
|
|
||||||
## Language Philosophy
|
## Language Philosophy
|
||||||
Fig is designed around several core principles:
|
Fig is designed around several core principles:
|
||||||
|
|
||||||
@@ -93,4 +67,34 @@ Replace `[file]` with the path to your input file.
|
|||||||
|
|
||||||
Modern ergonomics - Developer experience matters
|
Modern ergonomics - Developer experience matters
|
||||||
|
|
||||||
Gradual learning - Simple to start, powerful when needed
|
Gradual learning - Simple to start, powerful when needed
|
||||||
|
|
||||||
|
## Performance Summary
|
||||||
|
|
||||||
|
**Version:** 0.4.2-alpha (Tree-walker Interpreter)
|
||||||
|
**Test Hardware:** i5-13490F, Windows 11
|
||||||
|
|
||||||
|
**Execution Times for Fibonacci(30):**
|
||||||
|
- Naive Recursion: **11.72s**
|
||||||
|
- Memoization: **0.93ms** (12,600× faster)
|
||||||
|
- Iteration: **0.37ms** (31,300× faster)
|
||||||
|
- Tail Recursion: **0.40ms** (29,200× faster)
|
||||||
|
|
||||||
|
**Visual Comparison:**
|
||||||
|
```
|
||||||
|
Naive Recursion : ████████████████████████████████████████ 11.72s
|
||||||
|
Memoization : ▉ 0.93ms
|
||||||
|
Iteration : ▍ 0.37ms
|
||||||
|
Tail Recursion : ▎ 0.40ms
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key Insight:** Algorithm choice dominates performance in this tree-walker implementation.
|
||||||
|
|
||||||
|
**Detailed Reports:** [English](./docs/benchmark_result/benchmark_result_en_0.4.2-alpha.md) | [中文](./docs/benchmark_result/benchmark_result_zh_0.4.2-alpha.md)
|
||||||
|
|
||||||
|
|
||||||
|
## Language Documents
|
||||||
|
|
||||||
|
see ./docs/en_US/...
|
||||||
|
|
||||||
|
We're looking for translators to help translate our project and make it accessible to more language communities.
|
||||||
@@ -4,12 +4,14 @@
|
|||||||
|
|
||||||
[English](README.md "英文版本")
|
[English](README.md "英文版本")
|
||||||
|
|
||||||
**Fig** 是一种静态类型、面向表达式的编程语言,专为清晰性、安全性和现代开发实践而设计。Fig 融合了 Go、Rust 和 JavaScript 的灵感,旨在提供高效的开发体验,同时保持强大的类型安全。
|
**Fig** 是一种动态强类型的编程语言,专为清晰性、安全性和现代开发实践而设计。Fig 融合了 Go、Rust 和 JavaScript 的灵感,旨在提供高效的开发体验,同时保持强大的类型安全。
|
||||||
|
|
||||||
|
[语言入门教程(zh_CN)](docs/zh_CN/01-简介.md "第一章")
|
||||||
|
|
||||||
## 特性
|
## 特性
|
||||||
|
|
||||||
### 🚀 核心语言特性
|
### 🚀 核心语言特性
|
||||||
- **静态类型与类型推断** - 强类型系统,最少类型注解
|
- **动态类型与类型推断** - 强类型系统,最少类型注解
|
||||||
- **现代控制流** - 完整的 `for` 循环支持,正确的作用域管理
|
- **现代控制流** - 完整的 `for` 循环支持,正确的作用域管理
|
||||||
- **一等公民函数** - Lambda 表达式和闭包
|
- **一等公民函数** - Lambda 表达式和闭包
|
||||||
- **丰富的数据结构** - 结构体、列表、映射和元组
|
- **丰富的数据结构** - 结构体、列表、映射和元组
|
||||||
@@ -42,47 +44,43 @@ xmake build Fig
|
|||||||
|
|
||||||
4. 运行程序:
|
4. 运行程序:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
xmake run Fig [file]
|
xmake run Fig [file]
|
||||||
```
|
```
|
||||||
将`[file]`替换为输入文件的路径。
|
将`[file]`替换为输入文件的路径。
|
||||||
|
|
||||||
### 📁 项目结构
|
|
||||||
.
|
|
||||||
├── ExampleCodes # 示例代码与性能测试样例
|
|
||||||
│ └── SpeedTest # 性能相关测试示例
|
|
||||||
├── LICENSE # 项目开源协议
|
|
||||||
├── Logo # 项目标识资源
|
|
||||||
├── README.md # 英文 README
|
|
||||||
├── README_ZH-CN.md # 中文 README
|
|
||||||
├── compile_flags.txt # C/C++ 编译器参数提示
|
|
||||||
├── fig-vscode # VSCode 插件项目
|
|
||||||
│ ├── node_modules # VSCode 插件依赖
|
|
||||||
│ ├── out # 构建产物
|
|
||||||
│ ├── src # VSCode 插件源码
|
|
||||||
│ └── syntaxes # 语法高亮定义
|
|
||||||
├── src # Fig 语言核心源码
|
|
||||||
│ ├── Ast # 抽象语法树节点
|
|
||||||
│ ├── Context # 运行上下文
|
|
||||||
│ ├── Core # 核心基础设施(字符串/UTF8 等)
|
|
||||||
│ ├── Error # 错误系统
|
|
||||||
│ ├── Evaluator # 解释执行器
|
|
||||||
│ ├── Lexer # 词法分析器
|
|
||||||
│ ├── Module # 模块与内置库
|
|
||||||
│ ├── Parser # 语法解析器
|
|
||||||
│ ├── Token # Token 定义
|
|
||||||
│ ├── Utils # 实用工具与第三方 header
|
|
||||||
│ └── Value # 运行时类型系统与值表示
|
|
||||||
├── test.fig # 测试脚本
|
|
||||||
└── xmake.lua # Xmake 构建脚本
|
|
||||||
|
|
||||||
|
|
||||||
## 语言设计哲学
|
## 语言设计哲学
|
||||||
Fig 围绕几个核心原则设计:
|
Fig 围绕几个核心原则设计:
|
||||||
|
|
||||||
1. **清晰优于巧妙** - 代码首先应该可读
|
1. **清晰优于巧妙** - 代码首先应该可读
|
||||||
2. **默认为安全** - 在编译时防止常见错误
|
2. **默认为安全** - 在编译时防止常见错误
|
||||||
3. **现代人机工程学** - 开发者体验很重要
|
3. **现代人机工程学** - 开发者体验很重要
|
||||||
4. **渐进式学习** - 入门简单,需要时功能强大
|
4. **渐进式学习** - 入门简单,需要时功能强大
|
||||||
|
|
||||||
|
## 性能概览
|
||||||
|
|
||||||
|
**版本:** 0.4.2-alpha (树遍历解释器)
|
||||||
|
**测试硬件:** i5-13490F, Windows 11
|
||||||
|
|
||||||
|
**计算 Fibonacci(30) 的执行时间:**
|
||||||
|
- 朴素递归: **11.72秒**
|
||||||
|
- 记忆化: **0.93毫秒** (快12,600倍)
|
||||||
|
- 迭代: **0.37毫秒** (快31,300倍)
|
||||||
|
- 尾递归: **0.40毫秒** (快29,200倍)
|
||||||
|
|
||||||
|
**可视化对比:**
|
||||||
|
```
|
||||||
|
朴素递归 : ████████████████████████████████████████ 11.72秒
|
||||||
|
记忆化递归 : ▉ 0.93毫秒
|
||||||
|
迭代算法 : ▍ 0.37毫秒
|
||||||
|
尾递归 : ▎ 0.40毫秒
|
||||||
|
```
|
||||||
|
|
||||||
|
**核心发现:** 在此树遍历实现中,算法选择主导性能表现。
|
||||||
|
|
||||||
|
**详细报告:** [English](./docs/benchmark_result/benchmark_result_en_0.4.2-alpha.md) | [中文](./docs/benchmark_result/benchmark_result_zh_0.4.2-alpha.md)
|
||||||
|
|
||||||
|
|
||||||
|
## 语言文档
|
||||||
|
在 docs/zh_CN/... 查看更多
|
||||||
|
我们正在寻找译者来帮助翻译项目文件以便于不同语言社区的使用
|
||||||
117
docs/benchmark_result/benchmark_result_en_0.4.2-alpha.md
Normal file
117
docs/benchmark_result/benchmark_result_en_0.4.2-alpha.md
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
# Fig Language Performance Benchmark Report
|
||||||
|
|
||||||
|
## Version: 0.4.2-alpha (Tree-walker Interpreter)
|
||||||
|
|
||||||
|
### Test Environment
|
||||||
|
- **CPU:** Intel Core i5-13490F
|
||||||
|
- **OS:** Windows 11
|
||||||
|
- **Compiler/Interpreter:** Fig Tree-walker v0.4.2-alpha
|
||||||
|
- **Test Date:** Current test execution
|
||||||
|
|
||||||
|
### Executive Summary
|
||||||
|
This benchmark evaluates the performance of four different Fibonacci algorithm implementations in Fig language, calculating the 30th Fibonacci number (832,040). The results demonstrate significant performance variations based on algorithmic approach, highlighting the interpreter's efficiency characteristics.
|
||||||
|
|
||||||
|
## Performance Results
|
||||||
|
|
||||||
|
### Raw Execution Times
|
||||||
|
|
||||||
|
| Algorithm | Time (seconds) | Time (milliseconds) | Relative Speed |
|
||||||
|
| --------------------------- | -------------- | ------------------- | ---------------- |
|
||||||
|
| `fib` (Naive Recursion) | 11.7210479 s | 11721.0479 ms | 1.00× (baseline) |
|
||||||
|
| `fib_memo` (Memoization) | 0.0009297 s | 0.9297 ms | 12,600× faster |
|
||||||
|
| `fib_iter` (Iterative) | 0.0003746 s | 0.3746 ms | 31,300× faster |
|
||||||
|
| `fib_tail` (Tail Recursion) | 0.0004009 s | 0.4009 ms | 29,200× faster |
|
||||||
|
|
||||||
|
### Visual Performance Comparison
|
||||||
|
```
|
||||||
|
Naive Recursion : ████████████████████████████████████████ 11.72s
|
||||||
|
Memoization : ▉ 0.93ms
|
||||||
|
Iteration : ▍ 0.37ms
|
||||||
|
Tail Recursion : ▎ 0.40ms
|
||||||
|
```
|
||||||
|
|
||||||
|
## Detailed Analysis
|
||||||
|
|
||||||
|
### 1. Naive Recursive Implementation (`fib`)
|
||||||
|
- **Time:** 11.721 seconds (11,721 ms)
|
||||||
|
- **Algorithm Complexity:** O(2ⁿ) exponential
|
||||||
|
- **Performance Notes:**
|
||||||
|
- Demonstrates the high cost of repeated function calls in tree-walker interpreters
|
||||||
|
- Shows exponential time complexity with just n=30
|
||||||
|
- Highlights the need for algorithmic optimization in interpreted languages
|
||||||
|
|
||||||
|
### 2. Memoized Recursive Implementation (`fib_memo`)
|
||||||
|
- **Time:** 0.93 milliseconds
|
||||||
|
- **Algorithm Complexity:** O(n) linear (with memoization overhead)
|
||||||
|
- **Performance Notes:**
|
||||||
|
- 12,600× speedup over naive recursion
|
||||||
|
- Shows efficient hash table/dictionary operations in Fig
|
||||||
|
- Demonstrates that caching can overcome interpreter overhead
|
||||||
|
|
||||||
|
### 3. Iterative Implementation (`fib_iter`)
|
||||||
|
- **Time:** 0.375 milliseconds
|
||||||
|
- **Algorithm Complexity:** O(n) linear
|
||||||
|
- **Performance Notes:**
|
||||||
|
- Fastest implementation (31,300× faster than naive)
|
||||||
|
- Shows efficient loop execution and variable operations
|
||||||
|
- Minimal function call overhead
|
||||||
|
|
||||||
|
### 4. Tail Recursive Implementation (`fib_tail`)
|
||||||
|
- **Time:** 0.401 milliseconds
|
||||||
|
- **Algorithm Complexity:** O(n) linear
|
||||||
|
- **Performance Notes:**
|
||||||
|
- Comparable to iterative approach (slightly slower due to recursion overhead)
|
||||||
|
- Current interpreter does not implement Tail Call Optimization (TCO)
|
||||||
|
- Shows linear recursion is efficient for moderate depths (n=30)
|
||||||
|
|
||||||
|
## Technical Insights
|
||||||
|
|
||||||
|
### Interpreter Performance Characteristics
|
||||||
|
1. **Function Call Overhead:** Significant, as shown by the naive recursion performance
|
||||||
|
2. **Loop Efficiency:** Excellent, with iterative approaches performing best
|
||||||
|
3. **Memory Access:** Hash table operations (memoization) are efficient
|
||||||
|
4. **Recursion Depth:** Linear recursion (tail recursion) performs well up to moderate depths
|
||||||
|
|
||||||
|
### Algorithmic Impact
|
||||||
|
The benchmark clearly demonstrates that **algorithm choice has a greater impact than interpreter optimization** in this version:
|
||||||
|
- Poor algorithm (naive recursion): 11.7 seconds
|
||||||
|
- Good algorithm (any O(n) approach): < 1 millisecond
|
||||||
|
|
||||||
|
## Version-Specific Observations (v0.4.2-alpha)
|
||||||
|
|
||||||
|
### Strengths
|
||||||
|
- Excellent performance for iterative algorithms
|
||||||
|
- Efficient basic operations (arithmetic, loops, conditionals)
|
||||||
|
- Effective memory access patterns for cached results
|
||||||
|
- Linear recursion performance acceptable for typical use cases
|
||||||
|
|
||||||
|
### Areas for Improvement
|
||||||
|
- High function call overhead in deeply recursive scenarios
|
||||||
|
- No tail call optimization implemented
|
||||||
|
- Exponential algorithm performance shows interpreter limits
|
||||||
|
|
||||||
|
## Recommendations for Developers
|
||||||
|
|
||||||
|
1. **Prefer iterative solutions** for performance-critical code
|
||||||
|
2. **Use memoization** for recursive problems with overlapping subproblems
|
||||||
|
3. **Tail recursion is acceptable** for linear recursion patterns
|
||||||
|
4. **Avoid exponential algorithms** in interpreted code
|
||||||
|
5. **Benchmark different approaches** as algorithmic choice dominates performance
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
Fig v0.4.2-alpha demonstrates **practical performance for well-designed algorithms**. While the tree-walker interpreter has inherent overhead for certain patterns (like deep recursion), it executes efficient O(n) algorithms with sub-millisecond performance for n=30.
|
||||||
|
|
||||||
|
The interpreter shows particular strength in:
|
||||||
|
- Iterative loop execution
|
||||||
|
- Basic arithmetic and control flow
|
||||||
|
- Dictionary/table operations for caching
|
||||||
|
|
||||||
|
The performance characteristics are suitable for a wide range of application domains, provided developers employ standard algorithmic optimization techniques.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Report Generated:** Based on actual benchmark execution
|
||||||
|
**Interpreter Type:** Tree-walker
|
||||||
|
**Version:** 0.4.2-alpha
|
||||||
|
**Key Takeaway:** Algorithmic efficiency dominates performance; Fig executes optimized algorithms efficiently despite being an alpha-stage tree-walker interpreter.
|
||||||
117
docs/benchmark_result/benchmark_result_zh_0.4.2-alpha.md
Normal file
117
docs/benchmark_result/benchmark_result_zh_0.4.2-alpha.md
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
# Fig 语言性能基准测试报告
|
||||||
|
|
||||||
|
## 版本: 0.4.2-alpha (树遍历解释器)
|
||||||
|
|
||||||
|
### 测试环境
|
||||||
|
- **CPU:** Intel Core i5-13490F
|
||||||
|
- **操作系统:** Windows 11
|
||||||
|
- **编译器/解释器:** Fig 树遍历解释器 v0.4.2-alpha
|
||||||
|
- **测试日期:** 当前测试执行
|
||||||
|
|
||||||
|
### 执行摘要
|
||||||
|
本基准测试评估了 Fig 语言中四种不同斐波那契算法实现的性能,计算第30个斐波那契数(832,040)。结果显示基于算法方法的显著性能差异,突出了解释器的效率特性。
|
||||||
|
|
||||||
|
## 性能结果
|
||||||
|
|
||||||
|
### 原始执行时间
|
||||||
|
|
||||||
|
| 算法 | 时间(秒) | 时间(毫秒) | 相对速度 |
|
||||||
|
| ------------------- | ------------ | ------------- | ------------ |
|
||||||
|
| `fib` (朴素递归) | 11.7210479 s | 11721.0479 ms | 1.00× (基准) |
|
||||||
|
| `fib_memo` (记忆化) | 0.0009297 s | 0.9297 ms | 12,600× 更快 |
|
||||||
|
| `fib_iter` (迭代) | 0.0003746 s | 0.3746 ms | 31,300× 更快 |
|
||||||
|
| `fib_tail` (尾递归) | 0.0004009 s | 0.4009 ms | 29,200× 更快 |
|
||||||
|
|
||||||
|
### 可视化性能对比
|
||||||
|
```
|
||||||
|
朴素递归 : ████████████████████████████████████████ 11.72秒
|
||||||
|
记忆化递归 : ▉ 0.93毫秒
|
||||||
|
迭代算法 : ▍ 0.37毫秒
|
||||||
|
尾递归 : ▎ 0.40毫秒
|
||||||
|
```
|
||||||
|
|
||||||
|
## 详细分析
|
||||||
|
|
||||||
|
### 1. 朴素递归实现 (`fib`)
|
||||||
|
- **时间:** 11.721 秒 (11,721 毫秒)
|
||||||
|
- **算法复杂度:** O(2ⁿ) 指数级
|
||||||
|
- **性能说明:**
|
||||||
|
- 展示了树遍历解释器中重复函数调用的高成本
|
||||||
|
- 在仅 n=30 的情况下显示了指数时间复杂度
|
||||||
|
- 突出了解释型语言中算法优化的必要性
|
||||||
|
|
||||||
|
### 2. 记忆化递归实现 (`fib_memo`)
|
||||||
|
- **时间:** 0.93 毫秒
|
||||||
|
- **算法复杂度:** O(n) 线性(含记忆化开销)
|
||||||
|
- **性能说明:**
|
||||||
|
- 比朴素递归快 12,600 倍
|
||||||
|
- 显示 Fig 中哈希表/字典操作的高效性
|
||||||
|
- 证明缓存可以克服解释器开销
|
||||||
|
|
||||||
|
### 3. 迭代实现 (`fib_iter`)
|
||||||
|
- **时间:** 0.375 毫秒
|
||||||
|
- **算法复杂度:** O(n) 线性
|
||||||
|
- **性能说明:**
|
||||||
|
- 最快的实现(比朴素递归快 31,300 倍)
|
||||||
|
- 显示高效的循环执行和变量操作
|
||||||
|
- 函数调用开销最小
|
||||||
|
|
||||||
|
### 4. 尾递归实现 (`fib_tail`)
|
||||||
|
- **时间:** 0.401 毫秒
|
||||||
|
- **算法复杂度:** O(n) 线性
|
||||||
|
- **性能说明:**
|
||||||
|
- 与迭代方法相当(由于递归开销略慢)
|
||||||
|
- 当前解释器未实现尾调用优化(TCO)
|
||||||
|
- 显示线性递归在中等深度(n=30)下是高效的
|
||||||
|
|
||||||
|
## 技术洞察
|
||||||
|
|
||||||
|
### 解释器性能特征
|
||||||
|
1. **函数调用开销:** 显著,如朴素递归性能所示
|
||||||
|
2. **循环效率:** 优秀,迭代方法表现最佳
|
||||||
|
3. **内存访问:** 哈希表操作(记忆化)高效
|
||||||
|
4. **递归深度:** 线性递归(尾递归)在中等深度下表现良好
|
||||||
|
|
||||||
|
### 算法影响
|
||||||
|
基准测试清楚地表明,**在此版本中,算法选择比解释器优化影响更大**:
|
||||||
|
- 差算法(朴素递归):11.7 秒
|
||||||
|
- 好算法(任何 O(n) 方法):< 1 毫秒
|
||||||
|
|
||||||
|
## 版本特定观察 (v0.4.2-alpha)
|
||||||
|
|
||||||
|
### 优势
|
||||||
|
- 迭代算法性能优秀
|
||||||
|
- 基本操作(算术、循环、条件判断)高效
|
||||||
|
- 缓存结果的内存访问模式有效
|
||||||
|
- 线性递归性能在典型用例中可接受
|
||||||
|
|
||||||
|
### 改进空间
|
||||||
|
- 深度递归场景中函数调用开销高
|
||||||
|
- 未实现尾调用优化
|
||||||
|
- 指数算法性能显示解释器限制
|
||||||
|
|
||||||
|
## 给开发者的建议
|
||||||
|
|
||||||
|
1. **性能关键代码优先使用迭代解决方案**
|
||||||
|
2. **对于有重叠子问题的递归问题使用记忆化**
|
||||||
|
3. **线性递归模式可接受尾递归**
|
||||||
|
4. **避免在解释型代码中使用指数算法**
|
||||||
|
5. **基准测试不同方法**,因为算法选择主导性能
|
||||||
|
|
||||||
|
## 结论
|
||||||
|
|
||||||
|
Fig v0.4.2-alpha 展示了**对设计良好的算法的实用性能**。虽然树遍历解释器对某些模式(如深度递归)有固有开销,但它能以亚毫秒性能执行高效的 O(n) 算法(n=30时)。
|
||||||
|
|
||||||
|
解释器在以下方面表现特别出色:
|
||||||
|
- 迭代循环执行
|
||||||
|
- 基本算术和控制流
|
||||||
|
- 用于缓存的字典/表操作
|
||||||
|
|
||||||
|
性能特征适用于广泛的应用领域,前提是开发者采用标准的算法优化技术。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**报告生成时间:** 基于实际基准测试执行
|
||||||
|
**解释器类型:** 树遍历解释器
|
||||||
|
**版本:** 0.4.2-alpha
|
||||||
|
**关键要点:** 算法效率主导性能;尽管 Fig 是 alpha 阶段的树遍历解释器,但它能高效执行优化算法。
|
||||||
24
docs/zh_CN/01-简介.md
Normal file
24
docs/zh_CN/01-简介.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Fig 语言简介
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
Fig 是一门动态类型、解释执行的编程语言,专注于简洁语法和实用的语言特性。它采用树遍历解释器架构,支持多种编程范式。
|
||||||
|
|
||||||
|
## 实际观察到的特性
|
||||||
|
1. **解释执行**:基于 AST 的树遍历解释器,无编译步骤
|
||||||
|
2. **动态类型系统**:运行时类型检查,支持类型注解但不强制
|
||||||
|
3. **混合范式**:支持函数式、面向对象和命令式风格
|
||||||
|
4. **模块系统**:支持代码组织和复用
|
||||||
|
5. **内置类型**:整数、浮点数、字符串、列表、映射等
|
||||||
|
6. **垃圾回收**:基于引用计数的自动内存管理
|
||||||
|
|
||||||
|
## 语言设计特点
|
||||||
|
- **渐进类型**:支持类型注解但不强制,兼顾灵活性和可读性
|
||||||
|
- **一等公民函数**:函数可以作为参数传递和返回
|
||||||
|
- **闭包支持**:完整的词法作用域和闭包
|
||||||
|
- **错误处理**:异常机制和 try-catch 结构
|
||||||
|
- **可变与不可变**:const/var 区分,平衡安全与灵活
|
||||||
|
|
||||||
|
## 目标应用场景
|
||||||
|
- 脚本编写和自动化任务
|
||||||
|
- 教育用途和学习编程
|
||||||
|
- 配置语言和DSL
|
||||||
82
docs/zh_CN/02-快速开始.md
Normal file
82
docs/zh_CN/02-快速开始.md
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# 快速开始
|
||||||
|
|
||||||
|
## 运行 Fig 程序
|
||||||
|
|
||||||
|
Fig 语言通过解释器直接执行源代码文件。基本执行命令如下:
|
||||||
|
|
||||||
|
`./Fig 你的脚本.fig`
|
||||||
|
|
||||||
|
### 查看帮助和版本
|
||||||
|
|
||||||
|
显示帮助信息:
|
||||||
|
`./Fig -h` 或 `./Fig --help`
|
||||||
|
|
||||||
|
显示版本信息:
|
||||||
|
`./Fig -v` 或 `./Fig --version`
|
||||||
|
|
||||||
|
### 示例
|
||||||
|
|
||||||
|
创建一个名为 `hello.fig` 的文件,内容为:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import std.io;
|
||||||
|
io.println("Hello, Fig!");
|
||||||
|
```
|
||||||
|
|
||||||
|
在终端中运行:
|
||||||
|
`./Fig hello.fig`
|
||||||
|
|
||||||
|
你会看到输出:`Hello, Fig!`
|
||||||
|
|
||||||
|
## 程序示例
|
||||||
|
|
||||||
|
### 简单表达式程序
|
||||||
|
|
||||||
|
Fig 程序可以只包含表达式:
|
||||||
|
|
||||||
|
```go
|
||||||
|
1 + 2 * 3
|
||||||
|
```
|
||||||
|
|
||||||
|
运行此程序会输出计算结果 `7`。
|
||||||
|
|
||||||
|
### 带变量的程序
|
||||||
|
|
||||||
|
```go
|
||||||
|
var x = 10;
|
||||||
|
var y = x * 2;
|
||||||
|
y + 5
|
||||||
|
```
|
||||||
|
|
||||||
|
运行输出 `25`。
|
||||||
|
|
||||||
|
## 错误处理
|
||||||
|
|
||||||
|
当源代码有语法或类型错误时,解释器会显示详细的错误信息。例如:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
An error occurred! Fig 0.4.2-alpha (2026-01-23 01:30:46)[llvm-mingw 64 bit on `Windows`]
|
||||||
|
✖ TypeError: Variable `x` expects init-value type `Int`, but got 'Double'
|
||||||
|
at 1:14 in file 'your_file.fig'
|
||||||
|
var x: Int = 3.14;
|
||||||
|
^
|
||||||
|
```
|
||||||
|
|
||||||
|
错误信息包括:
|
||||||
|
- 错误类型和描述
|
||||||
|
- 发生错误的文件和位置
|
||||||
|
- 相关的堆栈跟踪信息
|
||||||
|
|
||||||
|
## 运行流程
|
||||||
|
|
||||||
|
1. **编写代码**:使用任何文本编辑器创建 `.fig` 文件
|
||||||
|
2. **保存文件**:确保文件扩展名为 `.fig`
|
||||||
|
3. **执行程序**:在终端中运行 `./Fig 文件名.fig`
|
||||||
|
4. **查看结果**:程序输出显示在终端中
|
||||||
|
5. **调试错误**:根据错误信息修改代码
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
- Fig 源文件必须使用 UTF-8 编码
|
||||||
|
- 语句通常以分号结束,但程序最后一条表达式可以省略分号
|
||||||
|
- 文件路径可以包含空格,但建议使用引号包裹:`./Fig "my script.fig"`
|
||||||
213
docs/zh_CN/03-基础语法.md
Normal file
213
docs/zh_CN/03-基础语法.md
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
# 基础语法
|
||||||
|
|
||||||
|
## 注释
|
||||||
|
|
||||||
|
Fig 支持两种注释格式:
|
||||||
|
|
||||||
|
单行注释:
|
||||||
|
```go
|
||||||
|
// 这是一个单行注释
|
||||||
|
var x = 10; // 注释可以在语句后面
|
||||||
|
```
|
||||||
|
|
||||||
|
多行注释:
|
||||||
|
```go
|
||||||
|
/* 这是一个
|
||||||
|
多行注释 */
|
||||||
|
/* 注释内可以有 // 嵌套的单行注释 */
|
||||||
|
```
|
||||||
|
|
||||||
|
注释不能嵌套多个多行注释:`/* /* 嵌套 */ */` 会导致错误。
|
||||||
|
|
||||||
|
## 变量声明
|
||||||
|
|
||||||
|
### 可变变量
|
||||||
|
```go
|
||||||
|
var name = "Fig";
|
||||||
|
var count = 0;
|
||||||
|
count = count + 1; // 可以重新赋值
|
||||||
|
```
|
||||||
|
|
||||||
|
### 常量
|
||||||
|
```go
|
||||||
|
const PI = 3.14159;
|
||||||
|
const MAX_SIZE = 100;
|
||||||
|
// PI = 3.14; // 错误:常量不能重新赋值
|
||||||
|
```
|
||||||
|
|
||||||
|
常量必须在声明时初始化。
|
||||||
|
|
||||||
|
### 类型注解(可选)
|
||||||
|
```go
|
||||||
|
var name: String = "Fig";
|
||||||
|
var age: Int = 14;
|
||||||
|
const VERSION: Double = 0.4;
|
||||||
|
```
|
||||||
|
|
||||||
|
类型注解提供额外的类型信息,但解释器会在运行时进行类型检查。
|
||||||
|
|
||||||
|
## 标识符命名
|
||||||
|
|
||||||
|
### 规则
|
||||||
|
- 可以包含字母、数字和下划线
|
||||||
|
- 不能以数字开头
|
||||||
|
- 区分大小写
|
||||||
|
- 支持 Unicode 字符
|
||||||
|
|
||||||
|
### 有效示例
|
||||||
|
```go
|
||||||
|
var count = 0;
|
||||||
|
var user_name = "Alice";
|
||||||
|
var 计数器 = 0; // 中文标识符
|
||||||
|
var π = 3.14159; // Unicode 符号
|
||||||
|
var _private = true; // 以下划线开头
|
||||||
|
```
|
||||||
|
|
||||||
|
### 无效示例
|
||||||
|
```
|
||||||
|
var 123abc = 0; // 不能以数字开头
|
||||||
|
var my-var = 0; // 不能包含连字符
|
||||||
|
```
|
||||||
|
|
||||||
|
## 基本字面量
|
||||||
|
|
||||||
|
### 数字
|
||||||
|
```go
|
||||||
|
// 整数
|
||||||
|
var a = 42; // 十进制
|
||||||
|
var b = -100; // 负数
|
||||||
|
var c = 0; // 零
|
||||||
|
|
||||||
|
// 浮点数
|
||||||
|
var d = 3.14;
|
||||||
|
var e = 1.0;
|
||||||
|
var f = -0.5;
|
||||||
|
var g = 1.23e-10; // 科学计数法
|
||||||
|
```
|
||||||
|
|
||||||
|
### 字符串
|
||||||
|
```go
|
||||||
|
var s1 = "Hello";
|
||||||
|
var s2 = "World";
|
||||||
|
var s3 = "包含\"引号\"的字符串"; // 转义引号
|
||||||
|
var s4 = "第一行\n第二行"; // 转义换行符
|
||||||
|
```
|
||||||
|
|
||||||
|
多行字符串直接跨行书写:
|
||||||
|
```rust
|
||||||
|
var message = "这是一个
|
||||||
|
多行字符串
|
||||||
|
可以包含多行内容";
|
||||||
|
```
|
||||||
|
|
||||||
|
### 布尔值
|
||||||
|
```go
|
||||||
|
var yes = true;
|
||||||
|
var no = false;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 空值
|
||||||
|
```dart
|
||||||
|
var nothing = null;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 分号使用
|
||||||
|
|
||||||
|
所有语句都必须以分号结束:
|
||||||
|
|
||||||
|
```go
|
||||||
|
var x = 10; // 正确
|
||||||
|
var y = 20 // 错误:缺少分号
|
||||||
|
|
||||||
|
func add(a, b) {
|
||||||
|
return a + b; // return 语句需要分号
|
||||||
|
} // 函数体右花括号后不需要分号
|
||||||
|
```
|
||||||
|
|
||||||
|
表达式作为独立语句时也需要分号:
|
||||||
|
```go
|
||||||
|
1 + 2 * 3; // 表达式语句需要分号
|
||||||
|
io.println("test"); // 函数调用语句需要分号
|
||||||
|
```
|
||||||
|
|
||||||
|
## 表达式与语句
|
||||||
|
|
||||||
|
### 表达式
|
||||||
|
表达式会产生一个值(包括 `null`):
|
||||||
|
```go
|
||||||
|
1 + 2 // 值为 3
|
||||||
|
x * y // 值为乘积
|
||||||
|
funcCall(arg) // 值为函数返回值
|
||||||
|
```
|
||||||
|
|
||||||
|
### 语句
|
||||||
|
语句执行操作但不产生值:
|
||||||
|
```go
|
||||||
|
var x = 10; // 声明语句
|
||||||
|
if condition {} // 条件语句
|
||||||
|
return value; // 返回语句
|
||||||
|
```
|
||||||
|
|
||||||
|
表达式可以作为语句使用(表达式语句):
|
||||||
|
```go
|
||||||
|
1 + 2; // 计算但丢弃结果
|
||||||
|
io.println("hi"); // 函数调用作为语句
|
||||||
|
```
|
||||||
|
|
||||||
|
## 关键字
|
||||||
|
|
||||||
|
Fig 语言的关键字包括:
|
||||||
|
|
||||||
|
| 类别 | 关键字 |
|
||||||
|
| -------- | ----------------------------------------------------------- |
|
||||||
|
| 声明 | `func`, `var`, `const`, `struct`, `interface`, `import` |
|
||||||
|
| 控制流 | `if`, `else`, `while`, `for`, `return`, `break`, `continue` |
|
||||||
|
| 错误处理 | `try`, `catch`, `throw`, `Finally` |
|
||||||
|
| 逻辑运算 | `and`, `or`, `not` |
|
||||||
|
| 类型相关 | `is`, `impl`, `new`, `public` |
|
||||||
|
|
||||||
|
这些关键字不能用作标识符名称。
|
||||||
|
|
||||||
|
## 操作符
|
||||||
|
|
||||||
|
### 算术运算符
|
||||||
|
`+`, `-`, `*`, `/`, `%`, `**`(幂运算)
|
||||||
|
|
||||||
|
### 比较运算符
|
||||||
|
`==`, `!=`, `<`, `>`, `<=`, `>=`
|
||||||
|
|
||||||
|
### 逻辑运算符
|
||||||
|
`and`, `or`, `not`, `&&`, `||`, `!`
|
||||||
|
|
||||||
|
### 位运算符
|
||||||
|
`&`, `|`, `^`, `~`, `<<`, `>>`
|
||||||
|
|
||||||
|
### 赋值运算符
|
||||||
|
`=`, `:=`, `+=`, `-=`, `*=`, `/=`, `%=`, `^=`
|
||||||
|
|
||||||
|
### 其他运算符
|
||||||
|
`.`(成员访问), `?`(三元运算), `...`(可变参数), `->`(箭头), `=>`(双箭头)
|
||||||
|
|
||||||
|
## 空白字符
|
||||||
|
|
||||||
|
Fig 对空白字符没有特殊要求:
|
||||||
|
- 空格和制表符可以互换使用
|
||||||
|
- 缩进不影响程序语义
|
||||||
|
- 操作符周围的空格是可选的(但建议添加以提高可读性)
|
||||||
|
|
||||||
|
## 代码示例
|
||||||
|
|
||||||
|
```go
|
||||||
|
// 完整的程序示例
|
||||||
|
import std.io;
|
||||||
|
|
||||||
|
func calculate(a: Int, b: Int) -> Int {
|
||||||
|
var result = a * b;
|
||||||
|
return result + 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
const x = 5;
|
||||||
|
const y = 3;
|
||||||
|
var answer = calculate(x, y);
|
||||||
|
io.println("结果是:" + answer.toString());
|
||||||
|
```
|
||||||
156
docs/zh_CN/04-数据类型.md
Normal file
156
docs/zh_CN/04-数据类型.md
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
# 数据类型
|
||||||
|
|
||||||
|
## 类型系统
|
||||||
|
|
||||||
|
Fig 语言是动态类型语言,运行时进行类型检查。
|
||||||
|
|
||||||
|
## 基本类型
|
||||||
|
|
||||||
|
### Null 类型
|
||||||
|
表示空值,只有一个值 `null`。
|
||||||
|
```dart
|
||||||
|
var a = null;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Int 类型
|
||||||
|
64位有符号整数。
|
||||||
|
```go
|
||||||
|
var x = 42;
|
||||||
|
var y = -100;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Double 类型
|
||||||
|
双精度浮点数。
|
||||||
|
```go
|
||||||
|
var pi = 3.14;
|
||||||
|
var speed = 2.998e8;
|
||||||
|
```
|
||||||
|
|
||||||
|
### String 类型
|
||||||
|
字符串。
|
||||||
|
```go
|
||||||
|
var s1 = "Hello";
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bool 类型
|
||||||
|
布尔值,`true` 或 `false`。
|
||||||
|
```go
|
||||||
|
var yes = true;
|
||||||
|
var no = false;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 复合类型
|
||||||
|
|
||||||
|
### List 类型
|
||||||
|
有序集合。
|
||||||
|
```go
|
||||||
|
var list = [1, 2, 3];
|
||||||
|
var mixed = [1, "text", true];
|
||||||
|
```
|
||||||
|
可以通过 **length()** 方法获取长度,返回Int
|
||||||
|
通过 **get()** 方法获取指定下标,不存在的下标返回null
|
||||||
|
|
||||||
|
### Map 类型
|
||||||
|
键值对集合。
|
||||||
|
```go
|
||||||
|
var map = {"key": "value", "num": 42};
|
||||||
|
```
|
||||||
|
|
||||||
|
通过 **get()** 方法获取指定下标,不存在的下标返回 `null`
|
||||||
|
|
||||||
|
### Function 类型
|
||||||
|
函数。
|
||||||
|
```go
|
||||||
|
var f = func(x, y) { return x + y; };
|
||||||
|
```
|
||||||
|
|
||||||
|
## 自定义类型
|
||||||
|
|
||||||
|
### 结构体定义
|
||||||
|
```rust
|
||||||
|
struct Person {
|
||||||
|
name: String;
|
||||||
|
age: Int;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
默认字段为私有,如需声明为外部可见的字段,使用 public关键字
|
||||||
|
如
|
||||||
|
```go
|
||||||
|
struct Person {
|
||||||
|
public name: String;
|
||||||
|
public age: Int;
|
||||||
|
|
||||||
|
public func greeting()
|
||||||
|
{
|
||||||
|
io.println("hello!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 创建实例
|
||||||
|
使用 `new` 关键字:
|
||||||
|
```go
|
||||||
|
var p = new Person {name: "Alice", age: 20};
|
||||||
|
```
|
||||||
|
|
||||||
|
支持三种初始化方式:
|
||||||
|
1. 命名参数:`new Person {name: "Alice", age: 20}`
|
||||||
|
2. 位置参数:`new Person {"Alice", 20}`
|
||||||
|
3. 简写方式:`new Person {name, age}`(使用同名变量)
|
||||||
|
|
||||||
|
## 类型操作
|
||||||
|
|
||||||
|
### 类型检查
|
||||||
|
使用 `is` 运算符:
|
||||||
|
```go
|
||||||
|
var x = "hello";
|
||||||
|
io.println(x is String); // true
|
||||||
|
|
||||||
|
var p = new Person {name: "Alice", age: 20};
|
||||||
|
io.println(p is Person); // true
|
||||||
|
```
|
||||||
|
|
||||||
|
### 获取类型
|
||||||
|
使用 `value.type()` 函数(获取内部类型):
|
||||||
|
```go
|
||||||
|
import std.value;
|
||||||
|
|
||||||
|
var num = 42;
|
||||||
|
var str = "hello";
|
||||||
|
var lst = [1, 2, 3];
|
||||||
|
|
||||||
|
io.println(value.type(num)); // 获取 num 的类型
|
||||||
|
io.println(value.type(str)); // 获取 str 的类型
|
||||||
|
io.println(value.type(lst)); // 获取 lst 的类型
|
||||||
|
```
|
||||||
|
|
||||||
|
## 类型转换
|
||||||
|
|
||||||
|
### 转换函数
|
||||||
|
通过 `std.value` 模块:
|
||||||
|
```go
|
||||||
|
import std.value;
|
||||||
|
|
||||||
|
var str = value.string_from(42); // "42"
|
||||||
|
var num = value.int_parse("123"); // 123
|
||||||
|
var dbl = value.double_parse("3.14"); // 3.14
|
||||||
|
```
|
||||||
|
|
||||||
|
## 错误处理
|
||||||
|
|
||||||
|
### try-catch 语法
|
||||||
|
```rust
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 可能抛出异常的代码
|
||||||
|
}
|
||||||
|
catch(e: ErrorType)
|
||||||
|
{
|
||||||
|
// 处理特定类型的错误
|
||||||
|
}
|
||||||
|
catch(e: AnotherError)
|
||||||
|
{
|
||||||
|
// 处理另一种错误
|
||||||
|
}
|
||||||
|
```
|
||||||
289
docs/zh_CN/05-函数.md
Normal file
289
docs/zh_CN/05-函数.md
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
# 函数
|
||||||
|
|
||||||
|
## 函数定义
|
||||||
|
|
||||||
|
### 基本语法
|
||||||
|
```go
|
||||||
|
func 函数名(参数列表) -> 返回类型 {
|
||||||
|
函数体
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例
|
||||||
|
```go
|
||||||
|
// 简单函数
|
||||||
|
func greet() -> Null {
|
||||||
|
io.println("Hello!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 带参数的函数
|
||||||
|
func add(a: Int, b: Int) -> Int {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 省略返回类型(默认为 Any)
|
||||||
|
func say(message: String) {
|
||||||
|
io.println(message);
|
||||||
|
// 没有 return,返回 null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 参数
|
||||||
|
|
||||||
|
### 必需参数
|
||||||
|
```go
|
||||||
|
func power(base: Double, exponent: Double) -> Double {
|
||||||
|
return base ** exponent;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 默认参数
|
||||||
|
参数可以指定默认值:
|
||||||
|
```go
|
||||||
|
func createPerson(name: String, age: Int = 18) -> Null {
|
||||||
|
io.println(name + " is " + age + " years old");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
createPerson("Alice"); // 使用默认 age=18
|
||||||
|
createPerson("Bob", 25); // 指定 age=25
|
||||||
|
```
|
||||||
|
|
||||||
|
### 可变参数
|
||||||
|
使用 `...` 表示可变参数,接收一个 List:
|
||||||
|
```go
|
||||||
|
func sum(numbers...) -> Int {
|
||||||
|
var total = 0;
|
||||||
|
var i = 0;
|
||||||
|
for i = 0; i < numbers.length(); i = i + 1 {
|
||||||
|
total = total + numbers.get(i);
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
sum(1, 2, 3); // 返回 6
|
||||||
|
sum(1, 2, 3, 4, 5); // 返回 15
|
||||||
|
```
|
||||||
|
|
||||||
|
可变参数不支持类型限制,获取到的总是 List 类型。
|
||||||
|
|
||||||
|
## 返回值
|
||||||
|
|
||||||
|
### 显式返回
|
||||||
|
使用 `return` 语句返回值:
|
||||||
|
```go
|
||||||
|
func max(a: Int, b: Int) -> Int {
|
||||||
|
if a > b {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 无返回值
|
||||||
|
函数如果没有 return 语句,返回 null:
|
||||||
|
```go
|
||||||
|
func log(message: String) -> Null {
|
||||||
|
io.println("[LOG] " + message);
|
||||||
|
// 函数结束,返回 null
|
||||||
|
}
|
||||||
|
|
||||||
|
func process(data: List) {
|
||||||
|
if data.length() == 0 {
|
||||||
|
return; // 提前返回 null
|
||||||
|
}
|
||||||
|
// 处理数据...
|
||||||
|
// 函数结束,返回 null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 函数作为值
|
||||||
|
|
||||||
|
### 函数赋值
|
||||||
|
函数是一等公民,可以赋值给变量:
|
||||||
|
```go
|
||||||
|
var addFunc = func(a: Int, b: Int) -> Int {
|
||||||
|
return a + b;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
var result = addFunc(3, 4); // result = 7
|
||||||
|
```
|
||||||
|
|
||||||
|
### 函数作为参数
|
||||||
|
```go
|
||||||
|
func applyOperation(x: Int, y: Int, op: Function) -> Int {
|
||||||
|
return op(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
func multiply(a: Int, b: Int) -> Int {
|
||||||
|
return a * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
var product = applyOperation(3, 4, multiply); // product = 12
|
||||||
|
```
|
||||||
|
|
||||||
|
### 函数作为返回值
|
||||||
|
```go
|
||||||
|
func makeMultiplier(factor: Int) -> Function {
|
||||||
|
return func(x: Int) -> Int {
|
||||||
|
return x * factor;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
var double = makeMultiplier(2);
|
||||||
|
var triple = makeMultiplier(3);
|
||||||
|
|
||||||
|
io.println(double(5)); // 输出 10
|
||||||
|
io.println(triple(5)); // 输出 15
|
||||||
|
```
|
||||||
|
|
||||||
|
## 匿名函数
|
||||||
|
|
||||||
|
### Lambda 表达式
|
||||||
|
```go
|
||||||
|
// 完整形式
|
||||||
|
var square = func(x: Int) {
|
||||||
|
return x * x;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 简写形式(单表达式)
|
||||||
|
var squareShort = func(x: Int) => x * x;
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
io.println(square(5)); // 输出 25
|
||||||
|
io.println(squareShort(5)); // 输出 25
|
||||||
|
```
|
||||||
|
|
||||||
|
### 立即调用函数表达式
|
||||||
|
```go
|
||||||
|
var result = func(x: Int, y: Int){
|
||||||
|
return x + y;
|
||||||
|
}(3, 4); // result = 7
|
||||||
|
```
|
||||||
|
|
||||||
|
## 闭包
|
||||||
|
|
||||||
|
### 捕获外部变量
|
||||||
|
函数可以捕获其定义作用域中的变量:
|
||||||
|
```go
|
||||||
|
func makeCounter() -> Function {
|
||||||
|
var count = 0;
|
||||||
|
|
||||||
|
return func(){
|
||||||
|
count = count + 1;
|
||||||
|
return count;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用
|
||||||
|
var counter = makeCounter();
|
||||||
|
io.println(counter()); // 输出 1
|
||||||
|
io.println(counter()); // 输出 2
|
||||||
|
io.println(counter()); // 输出 3
|
||||||
|
```
|
||||||
|
|
||||||
|
每个闭包有自己独立的捕获变量:
|
||||||
|
```go
|
||||||
|
var c1 = makeCounter();
|
||||||
|
var c2 = makeCounter();
|
||||||
|
|
||||||
|
io.println(c1()); // 输出 1
|
||||||
|
io.println(c1()); // 输出 2
|
||||||
|
io.println(c2()); // 输出 1(独立的计数)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 递归函数
|
||||||
|
|
||||||
|
函数可以调用自身:
|
||||||
|
```go
|
||||||
|
func factorial(n: Int) -> Int {
|
||||||
|
if n <= 1 {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return n * factorial(n - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
io.println(factorial(5)); // 输出 120
|
||||||
|
```
|
||||||
|
|
||||||
|
### 嵌套函数定义
|
||||||
|
```go
|
||||||
|
func outer(x: Int) -> Int {
|
||||||
|
func inner(y: Int) -> Int {
|
||||||
|
return y * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return inner(x) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
io.println(outer(10)); // 输出 21
|
||||||
|
```
|
||||||
|
|
||||||
|
## 函数调用
|
||||||
|
|
||||||
|
### 普通调用
|
||||||
|
```go
|
||||||
|
func calculate(a: Int, b: Int, c: Int) -> Int {
|
||||||
|
return a + b * c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 位置参数调用
|
||||||
|
var result = calculate(1, 2, 3); // 1 + 2*3 = 7
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方法调用语法
|
||||||
|
对象的方法调用:
|
||||||
|
```go
|
||||||
|
var list = [1, 2, 3];
|
||||||
|
var length = list.length(); // 方法调用
|
||||||
|
```
|
||||||
|
|
||||||
|
## 函数示例
|
||||||
|
|
||||||
|
### 实用函数组合
|
||||||
|
```go
|
||||||
|
import std.io;
|
||||||
|
|
||||||
|
// 高阶函数示例
|
||||||
|
func compose(f: Function, g: Function) -> Function {
|
||||||
|
return func(x: Any) -> Any {
|
||||||
|
return f(g(x));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用
|
||||||
|
func addOne(x: Int) -> Int {
|
||||||
|
return x + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
func double(x: Int) -> Int {
|
||||||
|
return x * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
var addThenDouble = compose(double, addOne);
|
||||||
|
io.println(addThenDouble(5)); // (5+1)*2 = 12
|
||||||
|
```
|
||||||
|
|
||||||
|
### 回调函数模式
|
||||||
|
```go
|
||||||
|
func processData(data: List, callback: Function) -> Null {
|
||||||
|
var i = 0;
|
||||||
|
for i = 0; i < data.length(); i = i + 1 {
|
||||||
|
var result = callback(data.get(i));
|
||||||
|
io.println("处理结果: " + result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用
|
||||||
|
var numbers = [1, 2, 3, 4, 5];
|
||||||
|
processData(numbers, func(x){
|
||||||
|
return x * x;
|
||||||
|
});
|
||||||
|
```
|
||||||
126
docs/zh_CN/06-面对对象.md
Normal file
126
docs/zh_CN/06-面对对象.md
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
# 面对对象
|
||||||
|
|
||||||
|
> Fig中只有结构体(`struct`) 遵循go圣经 组合由于继承 (struct组合尚未推出)
|
||||||
|
|
||||||
|
## 结构体定义
|
||||||
|
完整语法:
|
||||||
|
```cpp
|
||||||
|
struct Point
|
||||||
|
{
|
||||||
|
public x: Int; // 公开字段
|
||||||
|
public y: Int; // 公开字段
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Person
|
||||||
|
{
|
||||||
|
name: String; // 私有字段,无法被外部访问
|
||||||
|
age: Int; // 私有字段,无法被外部访问
|
||||||
|
sex: String = "Airplane"; // 私有字段,无法被外部访问
|
||||||
|
|
||||||
|
public func getName() -> String // 公开类函数
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 结构体初始化
|
||||||
|
语法:
|
||||||
|
```go
|
||||||
|
|
||||||
|
// 位置参数构造
|
||||||
|
var person := new Person{
|
||||||
|
"Fig", // name
|
||||||
|
1, // age
|
||||||
|
"Language" // sex
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
// 命名参数构造模式,可以无序
|
||||||
|
var person := new Person{
|
||||||
|
name: "Fig",
|
||||||
|
age: 1,
|
||||||
|
sex: "Language"
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
// 语法糖:同名变量构造
|
||||||
|
const name := "Fig";
|
||||||
|
const age := 1;
|
||||||
|
const sex := "Language";
|
||||||
|
|
||||||
|
var person := new Person{sex, name, age}; // 可以无序,自动匹配
|
||||||
|
```
|
||||||
|
|
||||||
|
请注意,同名变量构造(shorthand)模式请规范使用:
|
||||||
|
|
||||||
|
示例:定义
|
||||||
|
```cpp
|
||||||
|
struct Point
|
||||||
|
{
|
||||||
|
public x;
|
||||||
|
public y;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
使用:
|
||||||
|
```go
|
||||||
|
var a := Point{1,2};
|
||||||
|
io.println(a.x, a.y); // 1 2
|
||||||
|
|
||||||
|
var x := 7;
|
||||||
|
var y := 6;
|
||||||
|
var b := Point{y, x};
|
||||||
|
io.println(b.x, b.y); // 7 6
|
||||||
|
// ??
|
||||||
|
```
|
||||||
|
|
||||||
|
使用该模式最好有序构造,如果你清楚你在做什么,完全可以利用它
|
||||||
|
|
||||||
|
## 结构体运算符重载
|
||||||
|
|
||||||
|
**目前不支持**
|
||||||
|
|
||||||
|
## 接口与实现
|
||||||
|
`interface` 与 `implement`
|
||||||
|
|
||||||
|
### 定义接口
|
||||||
|
```go
|
||||||
|
interface Printable
|
||||||
|
{
|
||||||
|
toString() -> String;
|
||||||
|
getName() -> String
|
||||||
|
{
|
||||||
|
return "Printable";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 `interface` + 名字 {内容}定义结构体
|
||||||
|
方法签名为 `method() -> type`,其中必须提供返回类型,这是约定。
|
||||||
|
提供默认方法将在子类实现为实现情况下自动替补
|
||||||
|
|
||||||
|
### 实现
|
||||||
|
```rust
|
||||||
|
struct Person
|
||||||
|
{
|
||||||
|
name: String;
|
||||||
|
age: Int;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Printable for Person
|
||||||
|
{
|
||||||
|
toString()
|
||||||
|
{
|
||||||
|
return name + ":" + age;
|
||||||
|
}
|
||||||
|
getName()
|
||||||
|
{
|
||||||
|
return "Person";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
实现时不需要也不允许提供返回类型,必须与`interface`约定一致
|
||||||
|
内部通过动态派发 vtable实现
|
||||||
Reference in New Issue
Block a user