---
title: "Memo: miyamonz @ソフトウェア科学会第40回大会チュートリアル"
date: 2023-09-13T16:29:39.000Z
updated: 2026-01-08T14:51:00.649Z
url: https://baku89.com/Memo%EF%BC%9A_miyamonz_@%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E7%A7%91%E5%AD%A6%E4%BC%9A%E7%AC%AC40%E5%9B%9E%E5%A4%A7%E4%BC%9A%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB
---

# Memo: miyamonz @ソフトウェア科学会第40回大会チュートリアル

![](https://wp.baku89.com/wp-content/uploads/2026/07/scrapbox-65033526d430ae001b616a0b.jpeg)

[ソフトウェア科学会第40回大会チュートリアル「試して作って知る ライブプログラミング入門](https://jssst2023.wordpress.com/tutorial/)

で[miyamonz#icon](/miyamonz#icon)が雑談タイムに話したことを書きます[miyamonz#icon](/miyamonz#icon)

- 依存追跡、状態管理周り

  - 型検査の際に、依存を追跡する必要があって、そこらへんは、状態管理ライブラリとかの実装が参考になるかも、ということで話題に上げた気がします[miyamonz#icon](/miyamonz#icon)

  - [vanjs](https://vanjs.org/)

    - React, Vue的な宣言的UIの記述（ただしJSXでなく、単なる関数でやる）ができる極小ライブラリ

    - コードが１ファイルで収まっていて、reactiveなものを書く際の参考になるかも

      - ただ、読み物としてはちょっと大変なところもある
      - [miyamonz#icon](/miyamonz#icon)が読んだときのメモです→[https://scrapbox.io/miyamonz/vanjsのコードリーディング](/https/scrapbox.io/miyamonz/vanjs%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0)

    - Reactを使うほどでないが、vanillaで書くのはしんどい、みたいなケースで助かる
      - chrome拡張で使う事例 → <https://zenn.dev/ryo_kawamata/articles/1ad6e51eed13ae>

    - 宣言的UIの表現方法に対して、dom反映側の実現方法の概念は直交なんだな、ということが認識できて良いなと思ってます[miyamonz#icon](/miyamonz#icon)

      - 仮想DOMでなくてもいい
      - solid.jsとかもあるのだが、それよりはコードが全部読めて嬉しい

    - もしかしたら、glispで採用するのはありか？

      - 大量のelementがあるときのパフォーマンスは知らない
      - ので、そういう点だとメジャーなもののほうが強そうだし、Vueのままのほうが無難なのだろうか？

  - [jotai](https://github.com/pmndrs/jotai)

    - React向け状態管理だが、vanillaで動く & apiが簡単なので使えるかも
    - [miyamonz#icon](/miyamonz#icon)がノードベースの環境をプロトタイプ作った際にも、これを使って楽をしました
    - 状態管理ライブラリとしても便利で（というかそれが主目的ですが）、[miyamonz#icon](/miyamonz#icon)は仕事でもバリバリ使います[miyamonz#icon](/miyamonz#icon)

  - vueのcomputedで任せてる部分を、vanilla側で自前でやるようにしたほうが何かといいかも、的な話をしたような気がします[miyamonz#icon](/miyamonz#icon)

* **今のglisp**

  - ~~[devブランチ](https://github.com/baku89/glisp/tree/dev)~~ ← こちら、ゴミゴミしちゃったので一旦手を留めてます
  - [言語部分の別リポジトリ](https://github.com/baku89/glisp-lang) ←こっちが言語のパーサーや評価器のメインです！
  - ここらへんを追えば良いんですかね？[miyamonz#icon](/miyamonz#icon)
    - ずっと前にmainブランチを結構読んでました
  - 静的解析してどのUIを出すかなどを確定させたい、といった話がありました

- **突っかかっているところ**[baku89#icon](/baku89#icon)

  - Glisp v2 はASTの任意の部分木から評価を始める事ができ、その値が必要となった時点で遅延評価される仕様にしようと考えています

    - なぜ？

      - Glispファイル（=プロジェクトファイル）全体が一つの手続き的プログラムとして意味のある処理をするものではない
      - 複数のアートワーク、コンポジション、グループが混在するなかで、プロジェクト階層の必要なアイテムの中身を表示できればいい
      - 更新ごとにコード全体を再評価させたくない

    - 通常のプログラミング言語のナイーブな実装だと:

      - シンボル名と値とを保管する環境の配列 `Map<Name, Value>[]` を引き回しながらコードの冒頭から評価を始める
        - ```
          graph LR
              subgraph Env1
                  direction TB
                  x --> 1
                  y --> 2
              end
              subgraph Env2
                  direction TB
                  x2[x] --> 3
              end
           Env1 --> Env2
          ```
      - 内側のスコープに入ると、新しい環境をunshiftする。
      - 変数宣言や再代入にぶち当たった時点で右辺を評価し、環境に値をセット
      - ```
        // [{}] 環境を初期化
        const x = 1; // [{x => 1}]
        const y = 2; // [{x => 1, y = 2}]
        {
          // [{}, {x => 1, y = 2}] 新しい環境をunshift
          let x = 2; // [{x => 2}, {x => 1, y = 2}]
          x = 3; // [{x => 3}, {x => 1, y = 2}]
          x; // -> 3 (Envを右側から辿り、xに対応する最初の値を返す)
        } // [{x => 1, y = 2}] スコープを抜けるので、冒頭のEnvを削除
        x; // -> 1
        ```
      - つまり、7行目の`x`からいきなり評価を始めるというのが難しい
        - IDEの型情報のポップアップやJump to Definition機能など、静的解析で[Program Dependency Graph](/Program_Dependency_Graph)を構築し、「そのシンボルがどこで宣言されどう変更されたか」を逆引きする例はある。

    - Glisp v2の場合、任意のASTから評価を始め、シンボルを祖先ノードへと遡ることで解決する（[BaseExp.resolve](https://github.com/baku89/glisp-lang/blob/main/src/expr/index.ts#L390-L479)）

      - 以下のような式があるとき

      - ```
        (let a: 1
             (let a: 2
                  b: 3
                  (+ a b))) ; <-- a のシンボルを解決したい
        ```

      - ASTはこんな構造で、内側の足し算の`a`を解決するには破線のような経路をたどる。

      - ```
        graph LR
        let---|a|1
        let-->let2[let]
        let2---|a|2(((2)))
        let2---|b|3
        let2-->app[@]
        app-->+
        app-->a
        app-->b
        a -.-> app
        app -.-> let2
        let2 -.-> 2
        ```

      - つまり、部分木は親ノードへの参照をもつ必要がある（[BaseExp.parent](https://github.com/baku89/glisp-lang/blob/main/src/expr/index.ts#L106)）

      - ```
        graph LR
        ast --> a
        ast --> b
        a -. parent .-> ast
        b -. parent .-> ast
        ```

      - すると、親から子、子から親へと相互参照をしてしまうため、Reactのような永続データ的な更新方法が取れない

        - ```
          const ast = { a, b };
          const newAst = { ...ast, a: newA };
          newAst.a.parent = newAst;
          newAst.b.parent === ast; // -> true （newAst.b.parentは依然としてastを指している）
          ```
        - ```
          graph LR
          ast-->|a|a
          ast-->|b|b
          a -.-> ast
          b -.-> ast
          newAst -->|a| newA
          newAst -->|b| b
          newA --> newAst
          ```

      * データの更新はミュータブルに行い、`forceUpdate`をすれば一応のところ解決
        - ```
          const ast = { a, b };
          ast.a = newA;
          forceUpdate();
          ```
      * この方法はReactともVueとも相性がよろしくない
      * また、評価値のキャッシュも難しくなる
      * FlashのAction Script 3や、THREE.js、Paper.jsのようなステージオブジェクトとしてASTを管理することがそもそもの間違いな気がする
        - ```
          // こんな感じ
          const group = new Group();
          group.addChild(new Item());
          group.children[0].parent === group;
          ```

    * 評価関数 `eval` を純粋関数にすればいい

      - つまり、任意の部分木が親への参照を持つのをいいことに `eval(ast)` のようにしていたところを...

      - 親への参照は持たせず、代わりに必ず祖先ノードのリストを「環境」として渡して評価する

      - `eval(ast, [parent, grandparent, ..., root])` のように

        - 厳密には、関数呼び出しにおける実引数なども環境に情報として含める必要があるが

        -

        - ここの必要性は、例えば以下のようなケースであってますかね[miyamonz#icon](/miyamonz#icon)

          - 特定の階層でcという変数が`(let c: (toString someNumber))`みたいにletされていたとき

          - 以下の２つの情報があって初めてcの型がstringで確定できるから

            - someNumberがnumber型であることと、
            - toStringが`(numberまたはgeneric)=>string`型

        - たしかに環境を引数に渡すのは良さそうですね。[miyamonz#icon](/miyamonz#icon)
          - これならimmutableなはずだから、計算結果のキャッシュがしやすそう

  * ...というのを実装しようかと考えています…

  - 問題の難しさが分かってきました[miyamonz#icon](/miyamonz#icon)

    - やりたいこと（逆に言うと、課題）

      - コンパイラ or 言語処理系を作る
      - コードの変更に対するliveness、計算処理のキャッシュ等を良しなにやりたい

    - 後者の問題の解決方法が、前者に関する資料に乗ってないはずですね[miyamonz#icon](/miyamonz#icon)
      - 言語処理系として、既存の文献、資料などを当たろうにも、一般的な言語処理系は、livenessという概念が登場しない

Vueはそんなに得意じゃない的な話を[miyamonz#icon](/miyamonz#icon)がしましたが、

- やりたくないという意味ではなく、Reactの時ほどのパフォーマンスは出せないかも、位の話で
- glispは面白いので、開発協力できるところあればしたいです[miyamonz#icon](/miyamonz#icon)

* CSSとか

  - [miyamonz#icon](/miyamonz#icon)は現状の仕事だと、tailwindcssを好んで使っています

    - <https://www.refactoringui.com/>

      - Tailwindの会社が出してる本
      - ノンデザイナーズ・デザインブックよりも実践に寄った感じです

  - CSSとJS周辺のフレームワークor CSS in JSとかはまだデファクトスタンダードのようなものは安定してないなと思っています

    - ややtailwindcssはシェアが高い気がする

    - [State of CSS 2023](https://2023.stateofcss.com/en-US/)が最近公開されてました

      - <https://2023.stateofcss.com/en-US/css-frameworks/>
      - <https://2023.stateofcss.com/en-US/css-in-js/>

- UIコンポーネントライブラリとか

  - [miyamonz#icon](/miyamonz#icon)がReactばっか使ってるのでVue関連で具体的なものがあまり挙げられないです[miyamonz#icon](/miyamonz#icon)

  - 雑談の際には、「凝る必要が無いところはライブラリに頼って速く作った方が良いかも」といった趣旨の話をされてましたっけ[miyamonz#icon](/miyamonz#icon)

  - 現在、みんな絶対使ってるデファクトスタンダード的なコンポーネントライブラリが無さそうな印象です

    - そういうコンポーネント、メンテナンスがつらかったり、負債になったりしがちだからかなと思います
    - 過去の[miyamonz#icon](/miyamonz#icon)の調査→[https://scrapbox.io/miyamonz/CSSフレームワークおよびコンポーネントライブラリの調査](/https/scrapbox.io/miyamonz/CSS%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%8A%E3%82%88%E3%81%B3%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E8%AA%BF%E6%9F%BB)
      - ですが、この調査はReact前提です

  - ヘッドレスUIという概念

    - コンポーネントの見た目は自分で作るから、style以外の部分が欲しい、という要求がある

    - classだけを提供するtailwindと相性がいい
      - そもそもこの概念自体がtailwindから出されたものだった気がする

    - こういう概念のように、スタイルと機能を分離したいという要求がある

      - とりあえず見た目の良いコンポーネントを使いたい、提供したいというニーズ自体が減っているような気がします
      - 提供している場合でも、内部的に、ロジック(headlessな部分)とスタイルを分離して作ってるはず

  - Reactで有名なもの

    - [Chakra UI](https://chakra-ui.com/)

    - [radix-ui](https://www.radix-ui.com/)

    - [shdcn/ui](https://ui.shadcn.com/)

      - これはcomponent libraryでなく、スニペット集的な立ち位置
      - Radix UIとTailwind上で作ってあるから、自分でコピペして使え（だからnpm libraryもない）という立ち位置
      - 要件(あるいはアプリケーション側）ごとに固有な要求があり、それをライブラリ側に抽象するのは無理になりがちなので、このスタンスは正しいなあ、と思います[miyamonz#icon](/miyamonz#icon)

タイトル変更、編集等、自由にしてください[miyamonz#icon](/miyamonz#icon)
