Chez Scheme
※(chez (chez scheme))
https://www.scheme.com/
┌──┐
│目次│
├──┘
│◎Chez Scheme chez
│ ◆シンタックス syntax
│ ◆表記法 note
│ ◆特殊形式 spe
│ ◆変数とLet表現 var
│ ◆プロシージャの定義とラムダ表記 proc
│ ◆リカージョン rec
│ ◆直列化、繰り返し ser
│ ◆条件判断 if
│ ◆型変換 conv
│ ◆リスト処理 list
│ ◆算術演算 math
│ ◆文字処理 char
│ ◆文字列処理 string
│ ◆Vectors vec
│ ◆マッピング map
│ ◆アサインメント assign
│ ◆I/O io
│ ◆マクロとシンタックス拡張 macro
│ ◆末尾回帰 tail
│ ◆継続 cc
│ ◆遅延評価 deval
│ ◆システムインタフェース system
│ ◆拡張 ext
│ ◆デバッグ debug
│◎SWL swl
│ ◆Widget widget
│ ◆Editor editor
│ ◆REPL repl
│ ◆Examples examples
_◇識別子
シンボル、変数、キーワード、モジュール名
│ a-zまでの小文字
│ A-Zまでの大文字
│ 0-9までの数字
│ 記号
│ ? ! . + – * / < = > : $ % ^ & _ ~
※識別子名としては大文字は小文字に変換される
│ ⇒ただしグループエスケープにより大文字のままとすることもできる。
※標準Schemeの識別子
│ 数字と + – . で始まってはならない
※例外として + – … が識別子として確定している
※識別子は
│ 空白文字
│ カッコ ( )
│ ダブルクゥオート ”
│ コメント文字 ;
│ で区切られねばならない
※Chez Scheme拡張
│ 数字や+ – . で始まるものを識別子
│ 識別子の途中に # がはいってもよい
│ 単独の { } も識別子として使える
※エスケープキャラクタ
│ バックスラッシュ 1文字
│ || |と|の間のグループをエスケープ
_◇リスト
│ 通常 ( ) を使用する
※コンスセル
│ アドレスを2個格納できるメモリ領域
│ 第1アドレスcar
│ 第2アドレスcdr
※リスト
│ cdr部が次のコンスセルを指し数珠繋ぎになったもの。
│ 末尾のコンスセルのcdr部は空リスト'()を指す
│ ⇒コンスセルを使っていないデータを atom と呼ぶ
※プロパーなリスト
│ 末尾が空リスト
※インプロパーなリスト
│ 末尾が空リストでない
│ ⇒ドッテド・ペア表記される
例)
(cons ‘a ‘b)
⇒(a . b)
※Chez Scheme拡張
│ [ ] を使用することもできる
│ ⇒特定のカッコを分離することができる
※空リスト ()
※リストの第1要素はプロシージャもしくはスペシャルフォームとして解釈される。
│ そのままの形で扱いたいときは、クオートする。
例)'(a b c d)
_◇真偽値
│ #t
│ #f
│ ⇒条件式では#f以外はすべて真となる
│ (数値、空リスト、nilも真)
_◇数値表現
│ 通常の整数
例) -123
比
例)1/2
浮動小数
例)1.3 1e23
│ ⇒eのかわりにs, f, d, lなどをつかうことでサイズを変えることができる。通常はdouble
│ s short
│ f single
│ d double
│ l long
複素数
│ 1.3-2.7i
│ -1.2@73 極座標表現
#o #b #x プリフィックスに続けて各進数の浮動小数点数値を記することもできる
#b バイナリ
#o オクタル
#d デシマル
#x ヘクサデシマル
+inf.0 正の無限大
-inf.0 負の無限大
+nan.0 NaN
-nan.0 NaN
※不明な桁のある数値表現
例)
1###
※exactであることを強制する #e
例)
#e1.0
⇒整数の1
※inexactであることを強制する #i
例)
#i1
⇒浮動小数の1.0
※Chez Scheme拡張
│ #nr という形のプリフィックスにより2進から36進までを表現できる
例)#36rZZ
36進数のZZ = 35*36+35=1295
_◇非印字文字
│ 空白文字とみなされるもの
#\space
#\newline
#\backspace
#\linefeed (newlineと同じ)
#\page
#\return
#\tab
そうではないもの
#\nul
#\rubout
#\000 (000には8進数)記法により非印字文字を表現することもできる
_◇ベクトル
│ リストと似ているがプリフィックス#を持つ
│ リストと違い、要素の番号でアクセスできるデータ構造
│ 番号は0からはじまり要素数-lまで
│ 要素の型はなんでもよく、1つのベクトルに複数の型が含まれてもよい
例)
#(a b c)
例)100の長さをもつオール0のベクタ
#100(0)
⇒print-vector-length を偽とすると長さ表記をしないようになる。
_◇文字列、文字
│ 文字列は “” で囲む
│ 文字は #\プリフィックスをつける
例)#\a
_◇Boxes
│ cdrセルを欠く単一セルのオブジェクト
│ プリフィックス #& が付けられる
_◇end-of-file OBJECT
#!eof
_◇コメント
│ ;で始まり、行末まで
①? のついたプロシージャは真偽値を返す
②文字、文字列、ベクトルに作用するプロシージャは
│ char-
│ string-
│ vector-
で始まる
③変換を行うプロシージャは -> を使ってあらわす
例)vector->list
④副作用を持つプロシージャには ! をつける
例)set!
◆特殊形式
│ スペシャルフォーム
│ 通常のプロシージャと異なり、リストの全ての要素を評価しないプロシージャ
_◇グローバル変数の定義
define を用いる
│ (define 変数名 値)
│ ⇒値としてラムダ式を与えればプロシージャの定義となる
│ ⇒変数とプロシージャに区別はない
例)
(define gvar “str”)
⇒変数を評価すると値が変える
⇒プロシージャをリストの第一要素としてリストを評価するとプロシージャが実行される
⇒プロシージャを単独あるいは、リストの第1要素以外で評価すると
│ #<procedure>
が返る
_◇レキシカル変数
①lambda パラメータ
│ 変数は呼び出される度に束縛される
│ スコープは手続きの本体内
_◇ let
│ 特殊形式
│ 本体で利用するローカル変数のリストを導入し処理を行う
│ ⇒初期化部ではローカル変数は見えない
(let ((var val) …) exp1 exp2 …)
※変数にバインドするものがラムダ式であれば、ローカルなメソッドが定義される
※名前つき let
(let 名前 ((var val) …) exp1 exp2 …)
⇒名前がついているので、処理内で自分自身を呼び出すことができる。その際、let自身は既に定義されているのでローカル変数の再初期化は起こらない。
例)
(let countdown ((i 10)) (if (= i 0) 'liftoff (begin (display i) (newline) (countdown (- i 1)))))
_◇ let*
│ 特殊形式
│ 本体に利用するローカル変数のリストを導入し処理を行う
│ 初期部は直列に処理
│ 先に現れた変数のレキシカルスコープ内で後の変数が初期化される
_◇ letrec
│ 導入されたレキシカル変数は、すべての初期化部から互いに見える。
│ ⇒再帰的なローカル手続きが可能
_◇ラムダ表記
│ (lambda )
_◇ lambda
│ 特殊形式
例)
(define プロシージャ名 (lambda (引数リスト) (処理)))
※lambda無しの省略記法
(define (プロシージャ名 引数) (処理))
※lambdaの処理本体は暗黙の begin(prog形式)である
※レストパラメータ
│ 任意個の引数を持つプロシージャを定義するためにレストパラメータを定義することができる
│ ⇒ドットで記述する
例)
(lambda (a b c . d) …
⇒通常の3引数a b c に加えて残をリストとして d に与える
※ループは末尾呼び出しによる再帰による
_◇begin
│ 特殊形式
│ 順番に評価する必要のあるフォームをひとつにする
│ (begin (式1) … (式n))
_◇do
│ 変数を変化させながらの繰り返しループ
(do ((var 初期値 更新値) ...) (test 戻り値 ...) exp ...)
_◇ if
│ 特殊形式
│ (if テスト条件の述語 真のときの値 偽のときの値)
│ 真であれば 真のときの値が評価され
│ 偽であれば 偽のときの値が評価される
│ ⇒他方は評価されないので特殊形式である
_◇ and, or
│ and
│ 任意個の引数をとる
│ 引数を左から評価する
│ 最初に偽になったところでその値を返す
│ 残りの引数は評価しない
│ 最後の引数が評価されたときは、その値を返す
│ ⇒and条件が成り立たなければ#fが返る
│ and条件が成り立てば#tと解釈できる値が返る
│ ⇒条件式の結合に使うことも、条件実行に使うこともできる
│ or
│ 任意個の引数をとる
│ 引数を左から評価する
│ 最初に真になったところでその値を返す
│ 残りの引数は評価しない
│ 最後の引数が評価されたときは、その値を返す
│ ⇒or条件が成り立たなければ#fが返る
│ or条件が成り立てば#tと解釈できる値が返る
│ ⇒条件式の結合に使うことも、条件実行に使うこともできる
_◇ cond
│ 条件は上から順番に調べ、一致したところの節を評価する
│ 節には複数の式を書くことができ、最後の値が返る
(cond (条件述語1 条件成り立った場合の節) ... (else その他の場合の節))
※condの節は暗黙の begin である
_◇ case
│ 全てのケースが所属テストの場合、caseがつかえる
例)
(case c ((#\a) 1) ((#\b) 2) (else 3)
_◇ when, unless
(when 条件述語 処理) 条件述語が真なら処理が実行される (unless 条件述語 処理) 条件述語は偽なら処理が実行される
※処理部は暗黙の begin である
_◇述語
eq?
│ 2引数のアドレスを比較し、一致すれば真
│ ⇒数値の比較での挙動は互換性がない
eqv?
│ 2引数のデータ型と値を比較し、一致すれば真
│ 文字列やコンスセルはアドレスが異なれば偽
equal?
│ 文字列やリストの内容が一致すれば真
pair?
│ コンスセルを含むオブジェクトなら真
list?
│ リストの場合は真。'()はコンスセルでないがリスト
null?
│ ヌル(空リスト)なら真
symbol?
│ シンボルなら真
char?
│ 文字なら真
string?
│ 文字列なら真
number?
│ 数値なら真
complex?
│ 複素数なら真
real?
│ 有理数なら真
integer?
│ 整数なら真
exact?
│ 浮動小数でなければ真
inexact?
│ 浮動小数なら真
= < > <= >=
│ 任意個の引数をとる
│ 引数の間でシンボルの示す関係が成り立てば真
odd? even? positive? negative? zero?
vector?
│ ベクタなら真
_◇ not
_◇文字列
string->number
│ 文字列表現に応じて適切な数値に変換する
│ 文字列に基数接頭辞 #d #o などをつけてもよい
│ 第2引数に基数を設定してもよい(整数)
│ 数値に変換できなければ #fを返す
number->string
│ 数値を文字列に変換する
│ 第2引数に基数を設定してもよい
string->list
│ 文字列を文字のリストに変換する
_◇文字
char->integer
│ 文字をASCII符号に変換する
_◇car, cdr, cons, list
car
│ コンスセルのcar部をとりだす
cdr
│ コンスセルのcdr部をとりだす
cons
│ 第1引数をcar 第2引数をcdrとする新たなコンスセルを作る
list
│ 個数を限定しない引数をつなげてプロパーなリストを作る
│ (list) ()
│ (list ‘a) (a)
│ (list ‘a ‘b) (a b)
_◇ set-car!, set-cdr!
(set-car! pair obj)
│ pairのcar部をobjで置き換える
(set-cdr! pair obj)
│ pairのcdr部をobjで置き換える
_◇ length, list-ref, list-tail
(length list)
│ リストの要素数を返す
(list-ref list n)
│ リストのn番目(0始まり)を返す
(list-tail list n)
│ リストの後ろから数えてn番目(0はじまり)を返す
_◇ append, reverse
(append list …)
│ リストを接続する
(reverse list)
│ リストの要素の順を反転したリストを返す
_◇ memq, memv, member
(memq obj list)
│ listの中でobjとアドレスの一致する要素があればそれ以降のリストを返す
(memv obj list)
│ listの中でobjと型と値の一致する要素があればそれ以降のリストを返す
(member obj list)
│ listの中でobjと値の一致する要素があればそれ以降のリストを返す
_◇ assq, assv, assoc
※連想リストの処理
│ ドットペアのcarがキー、cdrがバリューに相当する
(assq obj alist)
│ ドットペアのリストである alist の中で、ペアのcarがobjとアドレスの一致するペアがあればそれを返す
(assv obj alist)
│ ドットペアのリストである alist の中で、ペアのcarがobjと型と値の一致するペアがあればそれを返す
(assoc obj alist)
│ ドットペアのリストである alist の中で、ペアのcarがobjと値の一致するペアがあればそれを返す
_◇quote
│ 特殊形式
│ シンボルやリストなど評価して欲しくないデータそのものを与えるために使う
│ (quote (a b c))
│ は
│ '(a b c)
│ と同じ
_◇apply
│ プロシージャを引数のリストに適用
(apply プロシージャ 引数 … 引数リスト)
│ ⇒プロシージャに引き続く引数の最後はリストでなければならない。
│ ⇒その前の引数を含めた引数リストにプロシージャを適用する
_◇型チェック
integer?
rational?
real?
complex?
exact?
inexact?
_◇数値のテスト
zero?
positive
│ >0
negative?
even?
odd?
_◇複素数型
real-part
imag-part
(make-rectangular r1 r2)
│ r1+r2i
(make-polar r1 r2)
│ r1@r2
(angle num)
│ 極形式にしたときの角度を返す
(magnitude num)
│ 極形式の大きさを返す
_◇ exact->inexact, inexact->exact
exact->inexact
│ 浮動小数点数に変換する。
│ (比を小数で表したいときなど)
inexact->exact
_◇ +, – , *, /
│ 任意個数の引数をとる
※割り算の場合、2個目以降は全て除数
_◇ quotient remainder module sqrt
quotient
│ 整数除算の商
(remainder i1,i2)
│ 余りをもとめる。余りの符号はi1と同じ
modulo 余り
│ 余りをもとめる。余りの符号はi2と同じ
sqrt
│ 平方根
_◇まるめ
(truncate 実数)
│ ゼロ方向でもっとも近い整数
(floor 実数)
│ -無限大方向でもっとも近い整数
(ceiling 実数)
│ 無限大方向でもっとも近い整数
(round 実数)
│ もっとも近い整数。丁度中間の場合は偶数の方が返る
_◇その他の演算
1+
│ 1を足す
1-
│ 1を引く
abs
│ 絶対値
max
│ 最大値
min
│ 最小値
(gcd int …)
│ 最大公約数
(lcm int …)
│ 最小公倍数
_◇分数
(rationalize 実数1 実数2)
│ 実数2の誤差の範囲で、もっともシンプルな実数1の分数表現を求める
(numerator 分数)
│ 分子を求める
(denominator 分母)
│ 分母を求める
_◇三角関数
sin
cos
tan
asin
acos
atan 引数1個と引数2個の両方がある
│ 引数が (1/2)πになる可能性があるなら2引数
※π
│ (* 4.0 (atan 1.0))
_◇指数、対数、べき乗
exp 指数関数
log 自然対数
(expt a b) aのb乗
_◇文字比較
※通常の文字比較に加え、大文字、小文字を区別しないchar-ci比較がある
char=?
char-ci=?
char<?
char-ci<?
char>?
char-ci>?
char<=?
char-ci<=?
char>=?
char-ci>=?
_◇文字テスト
char-alphabetic?
char-numeric?
char-lower-case?
char-upper-case?
char-whitespace?
_◇文字変換
char-upcase
│ 大文字に変換
char-downcase
│ 小文字に変換
char->integer
│ 数値に変換
integer-char
│ 数値を文字に変換
_◇文字列比較
(string=?)
(string<?)
(string>?)
(string<=?)
(string>=?)
(string-ci=?)
(string-ci<?)
(string-ci>?)
(string-ci<=?)
(string-ci>=?)
ケースに依存しない版
_◇文字列生成
(string char … )
│ 引数文字を連結して文字列とする
(make-string 文字数 文字)
│ 文字を文字数だけ並べた文字列を作る
_◇文字列操作
(string-length 文字列)
│ 文字列の長さを返す
(string-ref 文字列 文字のインデックス)
│ 文字列からインデックスで示される文字を返す
│ インデックスは0で始まる
(string-set! 文字列 idx char)
│ 文字列のidx番目文字にcharを埋め込む
(string-copy 文字列)
│ 文字列のコピーを返す
(string-append 文字列1 …)
│ 連結した文字列を返す
(substring 文字列 start_idx end_idx)
│ 文字列からstart_idxで始まり、end_idxの直前までの部分文字列を取り出す
(string-fill! 文字列 文字)
│ 文字列を文字で受けつくす
_◇変換
(string->list 文字列)
│ 文字列を文字のリストにする
(list->string リスト)
│ 文字を要素とするリストを文字列にする
_◇ベクトルの生成
(vector obj …)
│ 引数を要素とするベクトルを作る
(makevector n obj)
│ nの長さを持つ要素の値がobjのベクトルを作る
│ ⇒nが0なら空ベクトル
│ ⇒objを省略すると、値は不定
_◇ベクトルへのアクセス
(vector-length vec)
│ ベクタの長さを返す
(vector-ref vec n)
│ ベクタのn番目の要素を返す
(vector-set! vec n obj)
│ ベクタのn番目の要素をobjで置き換える
(vector-fill! vec obj)
│ ベクタの全要素をobjで置き換える
_◇ベクトルの変換
(vector->list vec)
│ ベクタをリストに変換
(list->vector lis)
│ リストをベクタに変換
_◇行列の操作
※ベクトルを要素とするベクトルにより行列を表現できる
例)
#(#(2 3) #(3 4) #(4 5))
◆マッピング
│ 入力リストの各要素にプロシージャを適用する
_◇ map
│ 与えられた手続きを対象のリストの各要素に適用し、結果のリストを返す
(map プロシージャ 対象のリスト)
_◇ for-each
│ 与えられた手続きを対象のリストの各要素に適用するが、結果を返さない
(for-each プロシージャ 対象のリスト)
◆アサインメント
│ 新たなバインディングを作るのではなく、既存のバインディングの値を書き換える
_◇ set!
│ 特殊形式
│ そのスコープで見えている変数の値を書き換える
_◇ read-char, read-line, read
(read-char)
│ 次の文字をポートから読む
(read-line)
│ 次の行(改行は含まない)をポートから読み文字列として返す
(read)
│ 次のS式を読む
_◇ write-char, write, display, newline
(write-char)
│ 文字をポートに書き出す
(write)
│ S式をポートに書き出す。
│ マシン可読のフォーマットで書き出す
│ 文字列は2重引用符
│ 文字は#\構文
(display)
│ S式をポートに書き出す。
(newline)
│ 新しい行を開始する
_◇ポート
│ 標準入力、標準出力対象ではポートを省略できる
│ ⇒明示する場合は
│ (current-input-port)
│ (current-output-port)
│ を呼び出す
※ポートのオープン
(open-input-file “ファイル名”)
│ 入力ポートを返す
(open-output-file “ファイル名”)
│ 入力ポートを返す
※ポートのクローズ
(close-input-port pvar)
(close-output-port pvar)
※ポートへの出力例
(display 9 (current-output-port))
※ファイルポートを自動クローズするプロシージャ
(call-with-input-file “ファイル名” 手続き)
(call-with-output-file “ファイル名” 手続き)
ファイルをオープンし、手続きを適用し、手続き終了後、ポートをクローズして手続きの結果を持って戻る
_◇文字列ポート
│ 文字列をポートに結びつけ、文字列に対して入出力することができる
例)
(define i (open-input-string “入力文字列”))
(define o (open-output-string))
⇒oに蓄えられた文字列は
(get-output-string o)
で取得できる
※文字列ポートはクローズの必要がない
_◇ load
│ load はファイルに含まれる全てのフォームを順に評価する
_◇ file-exists?
│ ファイルの存在をチェックする
_◇ delete-file
│ ファイルを消去する
_◇ eof-object?
◆マクロとシンタックス拡張
│ 式が評価される前に変換され、変換後の式が評価される。
_◇マクロ定義
(define-syntax マクロ名 (syntax-rules () ( (_ 引数) (変換後の処理) )))
※_ はマクロ名にあたり、変換前の構文を定義する
※対になる2番目の引数は変換後の式である
_◇ syntax-rules
│ 引数の異なる複数のパターンを列挙することができる
_◇ define-syntax
◆末尾回帰
│ ※最後に呼び出される関数が自分自身であること
│ ⇒名前付きletを使うとプログラムしやすい
◆継続
│ 継続は大域脱出などに使われる非局所な制御構造。任意の場所へのジャンプも可能
_◇ call-with-current-continuation
call/cc
①引数として、手続きをとる
②その手続きは1引数でなければならない
③その手続きを「現在の継続」とよばれる値を引数に与えて呼び出す
④現在の継続が呼び出されると、そこまで実行されていたものは捨てられ、現在の継続にその時点の引数が引き渡されて実行される
│ ⇒現在の継続はトップレベルからそこまでの全履歴である。
例)
(+ 1 (call/cc (lambda (k) (+ 2 (k 3)))))
│ ⇒call/ccした時点で、「現在の継続」は(+ 1 [])
│ ⇒これをkに代入し、それを呼び出している
※現在の継続を変数に取っておけば、何度でも呼び出すことができる。
│ ⇒これを呼び出せば、いつでもトップレベルにいたる道筋に戻すことができる
◆遅延評価
│ 値が必要になるまで計算せず、必要とされた時点で計算される。
│ ⇒データ構造に繰り返しを組み込むことができる
※プロミス
│ 評価法が指示されているが実際の計算が行われていない状態
※フォース
│ プロミスを強制することで値を計算する
│ ⇒プロミスは何度でもフォースできる
(delay proc)
│ procをプロミスにする
(promise? obj)
│ objがプロミスなら#t
(force promise)
│ プロミスをフォースして評価させる
_◇無限リスト
_◇ system
(system “OSコマンド”)
│ 引数文字列をOSコマンドとして実行させる
│ その終了ステータスが0なら真を返し、それ以外では偽を返す。
│ コマンド実行時の出力は標準出力に送られる
_◇ getenv
│ 環境変数の設定を返す
(getenv “環境変数名”)
_◇module
│ モジュールを定義することで名前空間を分離することができる。
(module (インポートする外部変数リスト) 定義 ... )
※(import モジュール名)
とすることでライブラリをインポートできる
(module () (import モジュール名) ...
※(include “ファイル名”)
とすることで外部ファイルをインクルードすることもできる
_◇ trace-lambda
│ 通常の lambda と同様であるが、内部で呼び出すプロシージャのネストをトレースする出力を行う
_◇ trace-let
│ 通常の let と同様であるが、内部で呼び出すプロシージャのネストをトレースする出力を行う
_◇ trace, untrace
(trace var1 var2 …)
│ var1 … にはプロシージャを与える
│ var1 がtrace-lambdaにより定義されているように設定する
│ ⇒設定後、var1を呼び出すとトレースが起こる
(untrace var1 var2 …)
│ トレースを解除する
_◇ debug
(debug)
│ インタラクティブ・デバッガを呼び出す
│ 命令は ? により表示される
_◇ inspect
(inspect obj)
│ インタラクティブインスペクタを obj に対して呼び出す
│ objに適用できるコマンドを表示するには ?
?? 一般的コマンドを表示
_◇Widgetの生成
①全てのウイジットは createマクロにより生成される
②<toplevel>以外の全てのウイジットにはキーワードの直後に親となるウイジットが示されなければならない
③生成したウイジットは
[シンボル (create …)]
構文によりシンボルにバインドすることでつかえるようになる
例)<toplevel>の生成
[top (create <toplevel> with (title: “TITLE”))]
例)<toplevel>の下にラベルの生成
[label (create <label> top with …)]
④生成されたウイジットは show メソッドで表示される
_◇ボタンとラベル
(module () (import swl:oop) (import swl:macros) (import swl:generics) (import swl:option) (let ([top0 (create <toplevel> with (title: "TOP WINDOW"))]) (let* ( [label0 (create <label> top0 with (title: "LABEL") (font: (create <font> 'times 14 '(bold italic))) (width/char: 30))] [button (create <button> top0 with (title: "PUSH BUTTON") (action: (let ([count 0]) (lambda (self) (set! count (+ count 1)) (set-title! label0 (format "~a click(s)" count))))))]) (show label0) (show button))) )
_◇キャンバス+ボタン+ラベル
(module () (import swl:oop) (import swl:macros) (import swl:generics) (import swl:option) (define x1 2) (define y1 2) (define x2 10) (define y2 10) (let* ([top (create <toplevel> with (title: "TOP WINDOW"))] [canvas (create <canvas> top with (background-color: (make <rgb> 215 215 255)))] [label (create <label> top with (title: "...NO MESSAGE..."))] [frame1 (create <frame> top)] [button1 (create <button> frame1 with (title: "INC BUTTON") (action: (lambda (self) (set! x2 (+ x2 10)) (set! y2 (+ y2 10)))))] [button2 (create <button> frame1 with (title: "DRAW BUTTON") (action: (let ([rect '()]) (lambda (self) (set! rect (create <rectangle> canvas x1 y1 x2 y2))))))] [quit-button (create <button> frame1 with (title: "QUIT") (width/char: 5) (action: (lambda (self) (destroy top))))]) (pack button1 (side: 'left)) (pack button2 (side: 'left)) (pack quit-button (side: 'left)) (pack frame1 (side: 'top)) (pack canvas (side: 'top)) (pack label (side: 'top))) )