强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Guile/Scheme 编程教程 / 第1章:Guile 概述

第 1 章:Guile 概述

1.1 什么是 Guile

Guile(GNU Ubiquitous Intelligent Language for Extensions)是 GNU 项目官方推荐的扩展语言。它的名字本身就是一个双关语——在英语中 “guile” 意为"狡诈、机智",恰好体现了 Lisp 家族语言灵活多变的特性。

Guile 的核心定位:

角色 说明
独立脚本语言 可编写完整的应用程序和脚本
嵌入式扩展语言 通过 C API 嵌入到 C/C++ 程序中
GNU 生态核心组件 GnuCash、GDB、GNU Mailutils 等均使用 Guile 扩展
Guix 系统配置语言 GNU Guix 操作系统的包管理和系统配置均使用 Guile 编写

1.2 Scheme 语言标准

Guile 实现了多个 Scheme 标准,理解这些标准对于正确使用 Guile 至关重要。

1.2.1 标准演进时间线

标准 年份 状态 Guile 支持
R4RS 1991 早期标准 完全兼容
R5RS 1998 经典标准 完全兼容
R6RS 2007 大型标准 部分兼容(通过模块)
R7RS-small 2013 现代标准 大部分兼容
R7RS-large 进行中 扩展标准 逐步支持中

1.2.2 R5RS:经典基础

R5RS 是最广泛使用的 Scheme 标准,也是 Guile 的核心基础。它定义了:

;; R5RS 核心特性演示

;; 1. 词法作用域 (lexical scoping)
(define x 10)
(let ((x 20))
  x)  ; => 20
x    ; => 10(外层绑定不受影响)

;; 2. 一等函数 (first-class functions)
(define (apply-twice f x)
  (f (f x)))
(apply-twice (lambda (n) (* n 2)) 3)  ; => 12

;; 3. 尾递归优化 (tail-call optimization)
(define (factorial n acc)
  (if (<= n 1)
      acc
      (factorial (- n 1) (* n acc))))
(factorial 10 1)  ; => 3628800

;; 4. 连续 (continuations) —— Guile 通过 call/cc 支持
(+ 1 (call/cc
       (lambda (k)
         (+ 2 (k 3)))))  ; => 4

1.2.3 R6RS:模块与库

R6RS 引入了标准化的库系统和更严格的语义规范:

;; R6RS 风格的库定义(Guile 中通过模块实现类似功能)
;; 在 Guile 中,我们使用 define-module 替代 R6RS 的 library

(define-module (my-math basic)
  #:export (square cube))

(define (square x) (* x x))
(define (cube x) (* x x x))

注意:Guile 并未完全实现 R6RS,而是选择性地吸收了其中优秀的设计。在实际开发中,建议使用 Guile 原生的模块系统而非 R6RS 库。

1.2.4 R7RS-small:现代化改进

R7RS-small 在保持 Scheme 简洁性的同时引入了一些实用特性:

;; R7RS 特性示例

;; 定义记录类型 (record type)
;; Guile 通过 srfi-9 提供类似功能
(use-modules (srfi srfi-9))

(define-record-type <point>
  (make-point x y)
  point?
  (x point-x)
  (y point-y))

(define p (make-point 3 4))
(point-x p)  ; => 3
(point-y p)  ; => 4

;; 命名 let(Guile 原生支持)
(let loop ((i 0) (acc '()))
  (if (= i 5)
      (reverse acc)
      (loop (+ i 1) (cons i acc))))
; => (0 1 2 3 4)

1.3 GNU 扩展特性

Guile 在标准 Scheme 基础上提供了丰富的 GNU 扩展,使其更适合实际工程使用。

1.3.1 核心扩展概览

扩展类别 特性 说明
模块系统 define-module / use-modules 比 R6RS 库更灵活
字符串扩展 SRFI-13 字符串库 完整的字符串操作 API
正则表达式 POSIX 正则 (ice-9 regex)
进程管理 system* / pipe 调用外部程序
网络编程 Socket API TCP/UDP 网络通信
并发编程 线程、通道、期货 (ice-9 threads)
哈希表 SRFI-69 键值对数据结构
JSON/YAML 第三方库 数据序列化

1.3.2 实用扩展示例

;; 1. 字符串处理(SRFI-13)
(use-modules (srfi srfi-13))

(string-join '("Hello" "Guile" "World") "-")
; => "Hello-Guile-World"

(string-contains "Hello Guile World" "Guile")
; => 6

;; 2. 正则表达式
(use-modules (ice-9 regex))

(define m (string-match "([0-9]+)\\.([0-9]+)" "version 3.0.5"))
(match:substring m 0)  ; => "3.0"
(match:substring m 1)  ; => "3"
(match:substring m 2)  ; => "0"

;; 3. 哈希表
(define ht (make-hash-table))
(hash-set! ht 'name "Guile")
(hash-set! ht 'version 3)
(hash-ref ht 'name)    ; => "Guile"
(hash-ref ht 'version) ; => 3

;; 4. 进程调用
(use-modules (ice-9 popen))
(use-modules (ice-9 textual-ports))

(let* ((port (open-input-pipe "uname -a"))
       (output (get-string-all port)))
  (close-pipe port)
  (display output))

1.3.3 SRFI 扩展标准

SRFI(Scheme Requests for Implementation)是 Scheme 社区的标准扩展库。Guile 内置支持大量 SRFI:

SRFI 编号 名称 功能
SRFI-1 列表库 高级列表操作
SRFI-9 记录类型 define-record-type
SRFI-13 字符串库 字符串操作
SRFI-14 字符集 字符集操作
SRFI-26 剪裁 cut/cute 部分应用
SRFI-31 递归 rec 表达式
SRFI-38 外部表示 共享结构的读写
SRFI-41 惰性流
SRFI-43 向量库 向量操作
;; SRFI 使用示例

;; SRFI-1: 列表操作
(use-modules (srfi srfi-1))

(filter even? '(1 2 3 4 5 6))    ; => (2 4 6)
(iota 5)                          ; => (0 1 2 3 4)
(take '(1 2 3 4 5) 3)            ; => (1 2 3)
(drop '(1 2 3 4 5) 3)            ; => (4 5)
(fold + 0 '(1 2 3 4 5))          ; => 15

;; SRFI-26: 部分应用(cut)
(use-modules (srfi srfi-26))

(map (cut * 2 <>) '(1 2 3 4 5))  ; => (2 4 6 8 10)
(map (cut list 1 <> 3) '(a b c)) ; => ((1 a 3) (1 b 3) (1 c 3))

;; SRFI-31: 递归命名表达式
(use-modules (srfi srfi-31))

(rec (fact
      (lambda (n)
        (if (<= n 1) 1 (* n (fact (- n 1))))))
  (fact 10))  ; => 3628800

1.4 Guile 与 Common Lisp 对比

对于有 Lisp 背景的开发者,理解 Guile Scheme 与 Common Lisp 的差异至关重要。

1.4.1 核心设计哲学对比

特性 Guile Scheme Common Lisp
设计哲学 最小化、优雅 实用、大而全
作用域 纯词法作用域 词法 + 动态作用域
命名空间 单一命名空间 独立的函数/变量命名空间
宏系统 卫生宏 (syntax-rules) defmacro(非卫生)
真值 #f 外皆为真 TNIL
可变性 默认不可变 默认可变
标准 R5RS/R6RS/R7RS ANSI Common Lisp
实现 单一实现 多种实现(SBCL、CLISP 等)

1.4.2 语法差异示例

;; ============== Guile Scheme ==============

;; 函数定义
(define (greet name)
  (string-append "Hello, " name "!"))

;; 条件表达式
(define (describe n)
  (cond
    ((< n 0) "negative")
    ((= n 0) "zero")
    (else "positive")))

;; 命名 let(循环惯用法)
(let loop ((i 0))
  (when (< i 5)
    (display i) (newline)
    (loop (+ i 1))))

;; 多值返回
(define (divmod a b)
  (values (quotient a b) (remainder a b)))

(call-with-values
  (lambda () (divmod 17 5))
  (lambda (q r)
    (format #t "~a 余 ~a~%" q r)))
;; ============== Common Lisp ==============

;; 函数定义 —— 需要显式声明函数
(defun greet (name)
  (format nil "Hello, ~a!" name))

;; 条件表达式
(defun describe (n)
  (cond
    ((< n 0) "negative")
    ((= n 0) "zero")
    (t "positive")))  ;; T 而非 else

;; 循环 —— 使用 loop 宏
(loop for i from 0 below 5
      do (format t "~a~%" i))

;; 多值返回
(defun divmod (a b)
  (values (floor a b) (mod a b)))

(multiple-value-bind (q r)
    (divmod 17 5)
  (format t "~a 余 ~a~%" q r))

1.4.3 选择建议

场景 推荐 原因
GNU 工具扩展 Guile 原生支持
学习函数式编程 Guile Scheme 更简洁、更纯粹
大型工业项目 Common Lisp 生态更成熟
嵌入式脚本 Guile C API 更友好
数值计算 Common Lisp 类型声明优化
操作系统配置 Guile (Guix) 原生集成

1.5 适用场景

1.5.1 典型应用领域

1. 应用程序扩展脚本

┌─────────────────────────────────┐
│        主程序 (C/C++)            │
│  ┌───────────────────────────┐  │
│  │    Guile 解释器嵌入       │  │
│  │  ┌─────────────────────┐  │  │
│  │  │  用户脚本 (.scm)    │  │  │
│  │  │  - 自定义规则       │  │  │
│  │  │  - 插件系统         │  │  │
│  │  │  - 配置扩展         │  │  │
│  │  └─────────────────────┘  │  │
│  └───────────────────────────┘  │
└─────────────────────────────────┘

2. 使用 Guile 的知名项目

项目 用途 说明
GnuCash 金融软件 使用 Guile 编写报表和业务规则
GDB 调试器 Python/Guile 脚本扩展
LilyPond 乐谱排版 Guile 作为核心配置语言
GNU Guix 包管理器 系统配置完全用 Guile 编写
GNU Make 构建工具 实验性 Guile 扩展
TeXmacs 编辑器 Guile 作为插件语言

3. 业务场景示例:配置文件处理

;; 使用 Guile 作为配置语言,替代 YAML/JSON
;; config.scm

(define *server-config*
  '((host . "0.0.0.0")
    (port . 8080)
    (workers . 4)
    (database
      . ((adapter . "postgresql")
         (host . "localhost")
         (port . 5432)
         (name . "myapp")))
    (logging
      . ((level . "info")
         (file . "/var/log/app.log")))))

;; 配置读取函数
(define (config-get config key)
  (let ((entry (assq config key)))
    (if entry (cdr entry) #f)))

;; 使用示例
(config-get *server-config* 'port)  ; => 8080

4. 业务场景示例:数据转换管道

;; 数据处理管道
(use-modules (srfi srfi-1)
             (ice-9 regex)
             (json))

(define (process-log-lines lines)
  "处理日志行,提取错误信息并统计"
  (let* ((error-lines (filter
                        (lambda (line)
                          (string-contains line "ERROR"))
                        lines))
         (parsed (map
                   (lambda (line)
                     (let ((m (string-match
                                "\\[(.+?)\\] ERROR (.+)" line)))
                       (if m
                           `((time . ,(match:substring m 1))
                             (message . ,(match:substring m 2)))
                           #f)))
                   error-lines))
         (valid (filter identity parsed)))
    `((total-errors . ,(length valid))
      (errors . ,valid))))

1.5.2 Guile 的优势

优势 详细说明
完全自由 GNU GPL 许可证,无商业限制
标准兼容 兼容 R5RS/R7RS,代码可移植
C 集成 一流的 C FFI,嵌入简单
模块系统 强大的命名空间管理
并发支持 绿色线程、CPS 引擎
活跃社区 GNU 核心项目,持续维护
Guix 生态 与 GNU Guix 深度集成

1.5.3 Guile 的局限

局限 说明
生态规模 相比 Python/JavaScript,库较少
数值性能 对于密集计算,不如 C/Rust
学习曲线 S-表达式对新手有一定门槛
社区规模 相比主流语言社区较小
GUI 支持 原生 GUI 库选择有限

1.6 Guile 版本选择

截至 2026 年,Guile 的版本状况:

版本 状态 建议
Guile 2.2 维护模式 旧项目兼容
Guile 3.0 稳定版 推荐使用
Guile 4.0 开发中 关注但不用于生产
# 检查 Guile 版本
guile --version
# GNU Guile 3.0.9
# Copyright (C) 1995-2024 Free Software Foundation, Inc.

1.7 本章小结

要点 说明
Guile 是什么 GNU 官方扩展语言,基于 Scheme
核心标准 R5RS 为基础,吸收 R6RS/R7RS 优点
GNU 扩展 模块系统、SRFI、网络、进程管理
与 CL 对比 更简洁、更纯粹,但生态较小
适用场景 GNU 工具扩展、脚本、配置、嵌入

扩展阅读


下一章:第 2 章:安装与环境搭建