標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

Go言語の構造体からのS式のエンコーダー・デコーダーを作りました。

Go言語の構造体からのS式のエンコーダーデコーダーを作りました。

type Foo struct {
    Bar   string         `sxpr:"bar"`
    Baz   float64        `sxpr:"baz"`
    Qux   []int          `sxpr:"qux"`
    Quux  map[string]int `sxpr:"quux"`
    Quuux string         `sxpr:"quuux"`
    Corge func()         `sxpr:"corge"`
}

という風にフィールドのタグを付けておくと

// import "github.com/hymkor/sxencode-go"

value := &Foo{
    Bar:   "hogehoge",
    Baz:   0.1,
    Qux:   []int{1, 2, 3, 4},
    Quux:  map[string]int{"ahaha": 1, "ihihi": 2, "ufufu": 3},
    Quuux: "a\"\\\n\tb",
    Corge: nil,
}

sxpr, err := sxencode.Marshal(value)
if err != nil {
    return err
}

fmt.Println(string(sxpr))

で、次のようなS式の文字列を生成できます。

((bar "hogehoge")(baz 0.1)(qux (1 2 3 4))(quux (("ahaha" 1)("ihihi" 2)("ufufu" 3)))(quuux "a\"\\
    b"))

出力した S式は SBCL, OKI ISLisp, gmnlisp で読み込めます(そして、多分、他のLisp処理系でも。README にテストスクリプトあります)

S式は JSON と違って改行コードがそのままフィールド区切りになるので、ログ用にJSONL みたいな別仕様を用意する必要がないところが強いと考えています。

ということで、Go の標準パッケージ "log/slog" の出力形式をS式にするパッケージも作成しました。

logger := slog.New(sxlog.New(os.Stderr))
slog.SetDefault(logger)
slog.Info("hello", "count", 3)

の結果が

("2025-07-24 00:06:58" INFO "hello" ("count" 3))

となります。S式、もっと普及したらいいと思うんですけどね