删除ipv6隧道
SICP Ch1

[转]Guile Common Problems

scturtle posted @ 2011年5月26日 12:09 in Other , 2393 阅读

来自这儿的Google Notebook

作者是王垠,不过貌似他的主页上已经找不到这篇文章

很多内容可以进一步info guile解决


Guile Common Problems

guile 的配置文件是什么?

~/.guile

guile 说在 load path 里找不到文件怎么办?

guile 的 load path 是由 %load-path 变量控制的。把路径加入这个变量就行了。

或者设置环境变量 GUILE_LOAD_PATH.

怎样知道现在系统里加入了哪些 feature?

*features* 变量。

guile 能使用 syntax-case 系统吗?

能。它在 guile 的 ice-9 模块里。

(use-syntax (ice-9 syncase))

之后就能使用 syntax-case 了。

在 Guile 怎样调试 Scheme 程序?

使用 (ice-9 debug) 模块就行了。(debug) 就可以进入 debugger.

可以使用 trace untrace trace-stack untrace-stack 来跟踪函数。

如果想要更方便的设置断点,可 以使用 guile-debugger。可以在这里下载:

http://www.ossau.uklinux.net/guile/index.html

在程序里使用

(use-modules (ossau breakpoints))

就能设置断点了。

guile 提供怎样的帮助系统?

(help)
通用的帮助系统。
(apropos "thread")
显示当前系统里含有 "thread" 字样的函数 或者变量,和它们的位置。
(source apropos)
显示 apropos 函数的源代码。

怎样使用 Guile 的面向对象系统 GOOPS?

在 Guile 里使用 goops 模块就行了。

(use-modules (oop goops))

比如,我们来重载一个加法操作符 "+":

(define-method (+ (x <string>) (y <string>))
  (string-append x y))

(+ 1 2)
(+ "abc" "de")

怎样统计函数运行的时间?

(ice-9 time)

(use-modules (ice-9 time))
(time (sleep 3))

怎样让 Guile 具有 expect 的功能?

(use-modules (ice-9 expect))

怎样方便的显示信息,就跟 C 的 printf 那样?

使用 format 就行了。先加载 format 模块。

(use-modules (ice-9 format))

然后使用 format

format destination format-string args ...

destination 是输出的端口。如果是一个 port 就把格式化好的内容 送到那个端口。如果是 #t 就输出到 current output port。如果是 就输出到一个 string。如果是一个数就输出到 stderr.

格式化串里常用字符的含义:

~~
一个 ~ 符号。
~%
换行符。
~t
一个 TAB.
~a
像 display 那样输出 arg。
~s
像 write 那样输出 arg。
~y
漂亮的打印 arg.
~d
decimal 整数。
~x
hexadecimal 整数。
~o
octal 整数。
~b
binary 整数。
~r
数字读音输出。比如 10 被输出为 "ten"。如果使用 ~:r 就会输 出序数词。如果使用 ~@r 就会输出大写罗马数字。~:@r 输出罗 马序数词。
~f
浮点数。比如 1.23
~e
以科学计数法输出浮点数。比如 1.34E+0.
~g
选择 ~f 和 ~e 中较短的一个作为输出。
~$
只输出两位小数。适合用于输出钱的数目。看看它的名字就知 道。
~c
输出 char.
~? ~k
把 arg 作为一个格式串。接下来的参数必须是一个 list 包含格式串里的 value.
~!
flush.
~#\newline
续行
~(
大小写转换开始。如果是 ~( 就是全部小写。如果是 ~@(,转 换成 capitcalize,如果是 ~:@( 转换成全部大写。
~)
大小写转换结束。

如何让 guile 的命令行支持 readline?

(use-modules (ice-9 readline))
(activate-readline)

如果“重载”函数名?

如果你不想用 OOP 但是想根据参数个数来重载函数名,可以用 case-lambda。它在 SRFI-16 里。你可以这样使用:

(use-modules (srfi srfi-16))

(define foo (case-lambda
              ((x) #t)
              ((x y) (+ x y))
              (z
                (apply * z))))
(foo 'bar)
(foo 2 4)
(foo 3 3 3)

如何方便的操作 string?

SRFI-13 有很多方便的操作 string 的函数。 比如:

string-any pred s [start end]
string-every pred s [start end]

用于判断字符串里的字符是否满足 pred 设定的条件。

string-tabulate proc len

制造一个长度 len 的 string, 对每一个位置使用 proc 来初始化。

string-join ls [delimiter grammar]

把 list ls 里的字符组合成一个字符串。使用分解符 delimiter, 使用语法 grammar。grammar 可以是 infix, string-infix, suffix, 或者 prefix.

string-copy str [start end]

拷贝子字符串。

substring/shared str start [end]

也是拷贝。但是共享空间。

string-copy! target tstart s [start end]

把 s 里 [start, end) 之间的部分拷贝到 target 里从 tstart 开 始的区域。target 和 s 可以是同一个 string.

string-fill! str chr [start end]
string-index s char_pred [start end]

在 s 里寻找 char-pred, 如果 char-pred 是一个字符。否则在 s 里寻找满足 char-pred 函数的位置。

string-contains s1 s2 [start1 end1 start2 end2]
string-contains-ci s1 s2 [start1 end1 start2 end2]

在 s1 里寻找 s2.

string-replace s1 s2 [start1 end1 start2 end2]

把 s1 里的一部分换成 s2 里的一部分。

string-filter s char_pred [start end]

把 s 里的字符通过 char_pred 过滤。

string-delete s char_pred [start end]

作用正好跟 string-filter 相反。

比如:

(define (p1 x)
  (char-upper-case? x))

(string-filter "kiHck!shAit*hLaLaldsjfOha" p1)

结果是 "HALLO".

string-tokenize s [token_char start end]

把一个string切分成几个,用 token_char 作为分割。如果没有 token_char 就用空白作为分割。比如:

(string-tokenize "ha kick flip")

结果是 ("ha" "kick" "flip").

如何方便的操纵 list?

SRFI-1 里有很多函数用来操作 list.

怎样用 string 作为 port?

SRFI-6 提供了 string port 的支持。

open-input-string, open-output-string and get-output-string

怎样定义 record?

SRFI-9 提供 define-record-type. 这跟 Scheme 48 的 record一样。

比如:

guile> (use-modules (srfi srfi-9))
guile> (define-record-type :foo (make-foo x) foo?
                           (x get-x) (y get-y set-y!))
guile> (define f (make-foo 1))
guile> f
#<:foo x: 1 y: #f>
guile> (get-x f)
1
guile> (set-y! f 2)
2
guile> (get-y f)
2
guile> f
#<:foo x: 1 y: 2>
guile> (foo? f)
#t
guile> (foo? 1)
#f

怎样进行同时的 list 赋值?

SRFI-11 提供了 let-values.

(use-modules (srfi srfi-11))
(let-values (((x y) (values 1 2))
             ((z f) (values 3 4)))
   (+ x y z f))

怎样把复杂的数据结构漂亮的显示出来?

使用 (ice-9 pretty-print) 就行。比如:

(use-modules (ice-9 pretty-print))
(pretty-print '(define (foo) (lambda (x)
(cond ((zero? x) #t) ((negative? x) -x) (else (if (= x 1) 2
(* x x x)))))))

结果是:

  (lambda (x)
    (cond ((zero? x) #t)
          ((negative? x) -x)
          (else (if (= x 1) 2 (* x x x))))))

怎样使用 value histroy?

(use-modules (ice-9 history))
guile> 1
$1 = 1
guile> (+ $1 $1)
$2 = 2
guile> (* $2 $2)
$3 = 4

怎样在出错时自动显示 backtrace?

(debug-enable 'backtrace)

怎样改变 guile 的 REPL?

Scheme Procedure: read-enable option-symbol
Scheme Procedure: print-enable option-symbol
Scheme Procedure: debug-enable option-symbol
Scheme Procedure: trap-enable option-symbol 

Scheme Procedure: read-disable option-symbol
Scheme Procedure: print-disable option-symbol
Scheme Procedure: debug-disable option-symbol
Scheme Procedure: trap-disable option-symbol 

syntax: read-set! option-symbol value
syntax: print-set! option-symbol value
syntax: debug-set! option-symbol value
syntax: trap-set! option-symbol value 
  • Read:
keywords         #f      Style of keyword recognition: #f or 'prefix
case-insensitive no      Convert symbols to lower case.
positions        yes     Record positions of source code expressions.
copy             no      Copy source code expressions.
  • Eval
stack           22000   Size of thread stacks (in machine words).
  • Print
source          no      Print closures with source.
closure-hook    #f      Hook for printing closures.

怎样改变 debugger 的行为?

stack           20000   Stack size limit (0 = no check).
debug           yes     Use the debugging evaluator.
backtrace       no      Show backtrace on error.
depth           20      Maximal length of printed backtrace.
maxdepth        1000    Maximal number of stored backtrace frames.
frames          3       Maximum number of tail-recursive frames in backtrace.
indent          10      Maximal indentation in backtrace.
backwards       no      Display backtrace in anti-chronological order.
procnames       yes     Record procedure names at definition.
trace           no      *Trace mode.
breakpoints     no      *Check for breakpoints.
cheap           yes     *Flyweight representation of the stack at traps.

怎样从一个外部程序得到输入,就像 popen?

使用 (ice-9 popen) module:

(use-modules (ice-9 popen))
(define p (open-input-pipe "ls -l"))
(read-line p)

guile 有没有方便的排序函数?

试试这些:

(define a '(2 3 45 5 6))

(define b '(83 3 59 18 38))

(sorted? a <)

(define as (sort a <))
(define bs (sort b <))

(merge as bs <)

(sort! a <)

(stable-sort b <)

(define v1 '#(23 4 5 8 34 83 23 18 35))

(sort v1 <)

(restricted-vector-sort! v1 < 4 7)

怎样深度 copy 一个对象?

copy-tree.

怎样把一个对象转换成 string?

object->string

(object->string fact1)

 


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter