dackdive's blog

新米webエンジニアによる技術ブログ。JavaScript(React), Salesforce, Python など

TypeScriptの公式チートシートを読んだ

先週の This Week In React に流れてきたやつ。

ざっと読んでみたけどそこまで目新しい発見はありませんでした。以下メモ。 💬 はコメント。

Classes

f:id:dackdive:20220124011610p:plain
https://www.typescriptlang.org/static/TypeScript%20Classes-83cc6f8e42ba2002d5e2c04221fa78f9.png

class Location {
  constructor(public x: number, public y: number) {}
}

const loc = new Location(20, 40);
loc.x // 20
loc.y // 40
  • Abstract Classes
  • Decorators and Attributes
    • デコレータをクラス、メソッド、アクセサ、プロパティやパラメータに使えるよ、とだけ
    • どういう動作になるのかは書かれておらず

Interfaces

f:id:dackdive:20220124011739p:plain
https://www.typescriptlang.org/static/TypeScript%20Interfaces-34f1ad12132fb463bd1dfe5b85c5b2e6.png

  • Common Syntax
    • 💬 new XXX() したときの型の宣言とかしばらく知らなかった
      • new(s: string): JSONResponse;
  • Extension via merging
    • interface は複数宣言することでマージできる

Types

f:id:dackdive:20220124011836p:plain
https://www.typescriptlang.org/static/TypeScript%20Types-4cbf7b9d45dc0ec8d18c6c7a0c516114.png

左上の Type vs Interface にどっち使う?の判断材料について言及されていた。

  • Type vs Interface
    • Interface はオブジェクトの形状を表現するのにしか使えない
    • Interface は複数回宣言することで拡張できる
    • パフォーマンスがクリティカルな型は Interface のほうが速い可能性がある
  • 💬 このへんの型については新しい知見はなかった
    • Primitive Type, Object Literal Type, Tuple Type, Union Type, Intersection Types(& によるマージ)
  • Type Indexing
  • Type from Value: typeof 値 で値を元にした型が作れる
  • Type from Func Return: ReturnType<関数の型> で関数の戻り値の型が作れる
  • Type from Module

以下はライブラリを作成するときや既存のJavaScriptコードを表現するときに素晴らしい機能だが、多くのTypeScriptアプリケーションではほとんど使わないとのこと。

  • Mapped Types
type Artist = { name: string, bio: string };

type Subscriber<Type> = {
  [Property in keyof Type]:
    (newValue: Type[Property]) => void
}
type ArtistSub = Subscriber<Artist>
  • Conditional Types: A extends B ? C : D
  • Template Union Types
    • 型にテンプレートリテラルを使う
    • type AllLocaleIDs = `${SupportedLangs}_${FooterLocaleIDs}_id`

Control Flow Analysis

f:id:dackdive:20220124011918p:plain
https://www.typescriptlang.org/static/TypeScript%20Control%20Flow%20Analysis-8a549253ad8470850b77c4c5c351d457.png

  • If Statements
    • if で型を絞り込む
  • Discriminated Unions
    • Union の各メンバが同じプロパティを持っている場合、 if や switch で型を絞り込める
type Responses =
  | { status: 200, data: any }
  | { status: 301, to: string }
  | { status: 400, error: Error }
  • Type Guards
    • 関数の戻り値の型に is を使うやつ
    • これは as と同じく TypeScript の推論に頼らず自分で宣言しているだけなので取り扱い注意
  • Assertion Functions
    • 関数の戻り値の型を asserts <引数> is SomeType で定義するやつ
  • Assignment
    • as const

所感

  • 「全然知らねえ!」というのはなかったよかった
  • Mapped Types とか Conditional Types とか Assertion Functions とか、説明聞いただけだとよくわからんみたいなのが最低限のサンプルコード載せてくれてるのはありがたい

KPT以外のふりかえり手法について調べた

背景

現職のログラスでは週に3回ぐらいのペースで10分勉強会というものをやっています。

先日そこでふりかえり手法について話したので、自分のブログにも残しておきます。
社内事情的なものを消した以外は、ほぼ勉強会のときに使った資料そのままです。

---------------資料ここから------------------

少し前に見たこの資料が面白かったので、+αで調べたことも含め紹介します

本日のゴール

  • KPT以外にもこんなふりかえりあるんだ〜というのを知ってもらう
  • それぞれのチームでいろんなふりかえり試してみようという機運になる

はじめに

実は奥が深いふりかえり
  • ふりかえりだけで1冊の本になる

f:id:dackdive:20220113015304p:plain:w240f:id:dackdive:20220113015308p:plain:w240

個人的にはKPTもけっこう難しい面があると思っている

KPT以外の方法も選択肢として知っておくといいよね!ということで調べた


ふりかえり手法の紹介

主に冒頭のスライドと、ふりかえりカタログ を参考に。

1. タイムライン

f:id:dackdive:20220113015749p:plain

  • チームでもちょっと取り入れてる
  • 事実ベースで書き出すので良いこと悪いこと思い出すきっかけになるのは👍
  • 毎日書かないと1週間でも思い出せないという学び
2. Fun / Done / Learn

f:id:dackdive:20220113015832p:plain

  • 前職で一時期やってた
  • 進め方に書いてないけど、最初に今週やったことを事実ベースで書き出してから図にマッピングする
    • →タイムラインと同じく、事実ベースで思い出すので感情に左右されにくい
  • KPT よりポジティブな雰囲気になりやすい
    • チーム作りたてのときとかメンバーにシャイな人が多いと効果アリ
  • (良い意味で)今のログラスでは別に必要ないかなーという印象
    • Kも出てるし、Pもそんな暗い雰囲気にならず議論できてるので
3. Good & New

f:id:dackdive:20220113015940p:plain - 前職ではデイリーチェックイン時のざつだんで使ってた - これ単体で使うというよりはふりかえりとかのアイスブレイク的用途かな

4. 象、死んだ魚、嘔吐

f:id:dackdive:20220113020156p:plain

  • ネーミングセンスよ
  • やったことはないが、各項目を読むと意外と理にかなってるのでは?という気も
  • 月1とか、ちょっとまとまった期間におけるふりかえりとかによさそう
5. Six Thinking Hats (6つの帽子思考法)

f:id:dackdive:20220113020017p:plain

  • モブプロの本に出てきた
  • 類似のものとして「斜に構える、構えないを繰り返す」というのがある
    • こっちのがシンプル
  • どちらも、強制的に批判的・ネガティブな意見を出させるのは言いにくいこと言わせるという点でよさそう

おわりに

  • なんでこんな話をしようと思ったかというと、「気軽に実験できる文化を維持したいよね」みたいな気持ちがあった。自戒もこめて
  • 前提として、何かをするときに「なんでやるのか」「どんな効果を期待しているのか」を考えておくの大事
  • 一方で、やってみないとわからないこともある
  • 「それなんでやるんですか」をやりすぎると何も実験できない組織になる
  • ふりかえりのやり方にしてもそうで、実験のハードルとしてはめちゃ低い
    • 失敗してもたかが1週間なのでどんどん実験してみよう。自戒もこめて
  • アトラクタの永瀬さんもこんなことを言っている

先が読めないからこそアジャイルが役に立つ 予定調和にハマらないためのスクラム活用術

実際にControlled Chaos……制御されたカオスという言い方をしたりします。その中で安全に実験や失敗をしてみることが、そもそものアジャイルスクラムの価値かなと私は考えていて。
...
アクションに起こしやすくて、計測可能なトライというか改善を上げることはもちろんいいんですが。そうではなくて、お願いしたいことはたまに実験をしてみてほしい。一見何も相関がなさそうなことをやってみると、実はあとから因果があったと判明するかもしれません。

  • 制御されたカオスを楽しもう!

参考リンク

------------資料ここまで---------------

後日談

この話をした翌日が月次振り返りで、早速「象、死んだ魚、嘔吐」を試してみようという動きになった。それだけでも話してよかった。

2021年のふりかえりと2022年にやりたいこと

完全に年を越してしまったが、毎年書いてるので書く。

去年:

dackdive.hateblo.jp

2021年の四半期ごとのふりかえり:

読んだもの

第一特集の「[自作OS×自作ブラウザで学ぶ]Webページが表示されるまで」が気になって買った。
けっこうシステムコールのところとか難しくて理解があやふやだった記憶。

これは WebAssembly 特集が読みたくて。
読書メモ:Software Design 2021年3月号の「WebAssembly入門」を読んだ - dackdive's blog

今だと 日本語訳 も出ているのでそっち買った方がいい。

読書メモ:「The Art of WebAssembly」を読んだ - dackdive's blog

一瞬だけ Ansible をやる必要性にかられて買った。
前半しか読んでないが、Playbook とか Inventory といった基本的な用語が公式ドキュメント読むよりはるかにわかりやすく説明されててよかった。

面白かった。こういう本もっと読みたい。
得意なこととはなにかっていうエピソードが印象的だった。

仕事をするとき、同じくらいのエネルギーを注いでいるはずなのに、妙によろこんでもらえるときと、あんまりよろこんでもらえないときがあるんですよ。
(中略)
つまり、自分たちがすごく苦労したと思ってないのに、妙に評価してもらえるときというのは、放っておいても、どんどんいい結果が出て、いい循環になって、どんどん力が出ていく状態。それが自分たちに向いている得意なこと、そうじゃないことは向いてないことだ、というふうに、わたしはだいたい判断していますね。

これも面白い本だった。仕事と全然関係ない息抜きに良かった。

評判良さそうだったのと Concurrent Mode あたり気になって読んだ。だいたい全部読み終わったはずだけど読書メモ書けてないな...

書いたもの

時系列で。だいたいこのブログで、たまに Zenn の方にちゃんとまとめた情報を書くようにしてた。

作ったもの

これぐらい。

Pixe.la という草生やす API サービスをブラウザ上で試せる君。

あとは、2020年の終わりぐらいから読んだ記事はここに残すようにした。
https://reading-list.zaki-yama.dev/

所感

ざっくり、1年の前半は Rust や WebAssembly を勉強していて、後半は追いつけてなかったフロントエンド技術のキャッチアップに注力していた。
後悔はないが、最近は Rust は全く勉強できてなくて、周りでやってる声もよく聞くようになったのでもっかい一から入門したいなという気持ち。

今年の後半には University of the People (UoPeople) への入学と株式会社ログラス への転職という比較的大きな決断が2つあった。
UoPeople に関しては無事最初の term を乗り越えてもうすぐ 2 term 目も終わろうかというところ。正直まだ面白いと思える授業内容ではない (その前段の基本的なプログラミングの授業をやっている) が、このペースなら仕事や子育てと並行して続けられそうだという感触が得られたのは良かった。のんびりやっていきたい。
転職に関しても良い選択だったと思っている。以前の職場もそうだが、優秀で人間的にも良い人たちに囲まれているのはとてもありがたいこと。もうすぐ3ヶ月経とうとしているので転職エントリを書きたい。

2022年にやりたいこと

去年も書いた気がするけど、大きく変えたい・新たに挑戦したいみたいなことはなくて、引き続きコンピューターサイエンスや Web フロントエンドの勉強を継続していきたい。

コンピューターサイエンスはよくも悪くも UoPeople 以外のことを始める余裕はないので挫折しないよう頑張る。
去年以上に頑張る必要があると思ったのはフロントエンド領域で、Hooks 時代の React における設計の知見だったりとかテストまわりだとかで自分がリードできるほどの能力がないと感じており、このあたりは喫緊の課題。当面はフロントエンドのテストのことを勉強したい。

あとは Rust。なんとか時間を見つけて勉強を再開したい。。。

おわりに

2021年は引き続きコロナでメンタル的に辛いときもあったので、なんもできなかったなーとか思ってたんだけど、こうしてふりかえると一応前の年よりは前進してる感じがして良い。

2022年もよろしくお願いします。

2021年7月〜9月のふりかえり

前回:2021年4〜6月のふりかえり - dackdive's blog

✨ やったこと

7月: The Art of WebAssembly を読んだ

6 月から読み始めて、感想ブログを書いたのが 8/2。約2ヶ月かかった。

感想

dackdive.hateblo.jp

8月: Next.js, SWR, Chakra UI などを勉強した

8月は読書を一旦やめて、最近あまりキャッチアップできてないと感じていたフロントエンド周りの技術を勉強した。
結果としてこのようなものを作った。

9月: University of the People (UoPeople) に入学した

前四半期で申し込みまで済ませていた UoPeople だが、9月から本格的に講義がスタートした。
正確にはまだ正式な学生にはなれてなくて、Degree Student と呼ばれる正式な学生になるために必須の科目を受講している。

今は UNIV 1001 Online Education Strategies という一般教養みたいな科目と CS 1101 Programming Fundamentals (Python) というプログラミング基礎みたいな科目の2コマをやっている。すでに限界。

📝ブログ

↑に挙げたものがすべて。

💬 所感

気持ちの部分ではあんまり書くことがない。良い意味では前四半期より気持ちが前向きになっているということなのかもしれないし、悪い意味ではこの四半期大したことしてなくてほぼ記憶がないということなのかもしれない。

それでも、8月にキャッチアップしたかった技術を学べたし9月入ってからは大学の講義についていくので精一杯で、充実感はある。

💪次の四半期(2021年10〜12月)のテーマ

次の四半期でやりたいこと、というのがあんまり思いつかない。。。

  • まずは UoPeople で受講中の2コマちゃんと単位とって正式な学生になりたい
  • 本だと📕 Rust in Action かな

💸 買ったもの

本ぐらい。

Pixela APIをブラウザ上で試せるPlaygroundをNext.jsで作った

作った。
f:id:dackdive:20210905015031p:plain:w480

最低限の機能しかないしコードも汚いところいっぱいあるけどとりあえず公開することにした。
ここで試せます。

pixela-api-playground.zaki-yama.dev

ソースコードはこちらに。

モチベーション

ここのところ仕事では SDK など GUI を持たないライブラリやCLI を作ることが多く、Next.jsswr といった最近よく聞くフロントエンド技術スタックを素振りできずにいて危機感があった。

これらの素振りをするのにちょうどよい題材はないものかと思っていたところ、 Pixela という API サービスに出会ったので
この API をブラウザ上で実行できる簡単な Web アプリケーションを作ってみた。

Pixela について、詳しくは公式サイト(https://pixe.la/ja) の説明に譲るとして、GitHub の Contribution Graph のような草を生やすことができる API サービス。
習慣化したい活動を何でも記録して草を生やすことができる。最高。

自分の場合は、日々の読書時間を記録して GitHub ぽく見れたらなーと思っていたところこのサービスを見つけた。

Pixela は、 すべての機能が REST 風の API でしか提供されていない ところが特徴的。つまり、最初のユーザー登録から何からすべて curl などを利用して直接 API を叩いて行う必要がある。

これは API を利用することに慣れたプログラマにとって非常にとっつきやすい一方、特に最初どんな API があるのか、どんなリクエストに対してどんなレスポンスが返ってくるのかを色々試したいようなときには GUI でのインターフェースもあると自分以外の人にとっても便利かもなーと思い、ブラウザ上で API を一通り試せるようなサイトを作ることにした。

機能について

今のところは本当に各種 API を揃えただけ、という感じなので、便利機能とかはないです。
グラフ表示 API など一部の APIJSON ではなく SVG でレスポンスが返ってくるが、そういったものはサイト上で直接画像が見られるようになっている。

f:id:dackdive:20210905003457p:plain:w480

今後時間があれば作りたい機能はいくつかあって、

  • ログイン機能
    • 自分が使う上で一番ほしい。username, token を毎回入力したくない
  • レスポンスの JSON をコピーするボタン
  • ユーザーのグラフをまとめて表示するページ
    • どちらかというとダッシュボードでは感はあるが
  • サポーター限定の機能(パラメータ)はそれとわかるようにしたい
  • ダークモード対応
    • 技術的にやってみたいというだけ

などなど。

反応があればやる気も上がると思うので、リポジトリに Star をお願いします...🙏

技術的な話

今回使った主な技術スタックは以下。

それぞれ、初めて使ってみた感想とかよくわからなかったとこを書く。

Next.js

公式ドキュメントが非常に充実しているので、まずは Learn Next.js を一通りやってその後は必要になった機能だけ個別に調べる、というやり方で十分だった。

今回は必要にならなかったけど SSG、SSR、ISR の違いとかが理解できた。

SWR

今回のようにボタン押したらリクエスト送るだけのアプリに対しては完全に too much だったとは思うものの、どういう使い勝手なのか試したくて導入した。

条件付きフェッチ – SWR
の項にもあるように、「ボタンが押されたら useSWR() する」のではなく「レンダリングのたびに常に useSWR() は実行されるので、実際に fetch するかどうか別の state で管理する」というところは
ちょっとこれまでと発想を変える必要があった。けど hooks に共通して言える考え方なんだろうな、そういう意味で hooks 時代の設計に頭が追いついてないんだろうなとも思った。

あと、恥ずかしながらしばらく fetch や axios などのライブラリの代わりとして選択できるものだと思っていて、あくまでデータの「取得」用のライブラリだということに遅れて気がついた。
ref. how to use post method and pass params in swr? · Issue #93 · vercel/swr

🤔 わからなかったこと

クエリパラメータがそこそこあるような API を叩くとき、 useSWR()key パラメータをどう指定するのがお作法的に正しいのかよくわからなかった。

引数 – SWR にあるように第一引数の key には配列を渡せるが、

const { data: user } = useSWR(['/api/user', token], fetcher)

クエリパラメータが複数あるからといってそれをオブジェクトにまとめてしまうのは NG とされている。

// NG
const { data: events } = useSWR(['/api/events', { from, to }], fetcher)

基本的にクエリパラメータが異なると別々の結果としてキャッシュしたいから key には含めておきたいと思うんだけど、
クエリパラメータが増えるごとに配列に追加することになる?

そうすると fetcher 関数の引数も増えて...って思ったけど、第二引数をこう書けばいいのか。

const { data: events } = useSWR(['/api/events', from, to], (url, from, to) => fetcher(url, { from, to })

Chakra UI

よくある UI コンポーネントライブラリの1つとして必要なものだけ使った、という感じなので、どのあたりに強みがあるのかとかはまだ理解が不十分。

Comparison - Chakra UI
ここを一回ちゃんと読んだほうがいい。

あと、Chakra UI を使えば Tailwind CSS の思想とかも理解できるかと思ったけど全然そんなことはなかった。

あわせて読みたい

React Hook Foom

フォーム項目にきめ細かいバリデーションを実装したい場合に力を発揮しそうだなと思いつつ、今回は必須項目ぐらいしかなかったのでこれも too much ですね。

また、Chakra UI のドキュメントに
Chakra UI + React Hook Form - Chakra UI
なんてページもあるぐらいだから両方組み合わせるのも余裕なんだと思ってたけどそんなことなかったです。
ラジオボタン (Radio, RadioGroup) にどう組み込むのかわからず今のところこうなっている。

<FormControl>
  <FormLabel>type</FormLabel>
  <Controller
    control={control}
    name="type"
    render={({ field: { onChange, value } }) => {
      return (
        <RadioGroup onChange={onChange} value={value}>
          <Stack spacing={4} direction="row">
            <Radio value="int">int</Radio>
            <Radio value="float">float</Radio>
          </Stack>
        </RadioGroup>
      );
    }}
  />
</FormControl>

🤔 わからなかったこと

「単純なラベルつき input + 必須バリデーション + エラー時のメッセージ表示」みたいなことをやろうとすると
こういうコードを何回も書くことになる。

<FormControl isInvalid={!!errors.username}>
  <FormLabel htmlFor="username">username</FormLabel>
  <Input
    id="username"
    type="text"
    {...register("username", {
      required: "This is required.",
    })}
  />
  <FormErrorMessage>
    {errors.username && errors.username.message}
  </FormErrorMessage>
</FormControl>

さすがにこれはめんどいってことでコンポーネントに切り出したけど、TypeScript の型が合わず何箇所か挫折してる。

type Props<TFieldValues extends Record<string, any>> = {
  name: keyof TFieldValues;
  required?: boolean;
  register: UseFormRegister<TFieldValues>;
  errors: FieldErrors<TFieldValues>;
};

export default function Input<TFieldValues>({
  name,
  required,
  register,
  errors,
}: Props<TFieldValues>) {
  return (
    <FormControl isInvalid={!!errors[name]}>
      {/* @ts-ignore */}
      <FormLabel htmlFor={name}>{name}</FormLabel>
      <ChakraUIInput
        // @ts-ignore
        id={name}
        type="text"
        // @ts-ignore
        {...register(name, {
          required: required && "This is required.",
        })}
      />
      {/* @ts-ignore */}
      <FormErrorMessage>{errors[name]?.message}</FormErrorMessage>
    </FormControl>
  );
}

これは正解がよくわからない。

「The Art of WebAssembly」を読んだ

読んだので簡単なまとめを。

この本について

前半は WebAssembly の基本的なしくみや Node.js・ブラウザで動かす方法、後半はパフォーマンス測定やデバッグ方法について学べる本。
また、特定の言語やツールチェイン(たとえば Rust だったら wasm-pack とか)に依存した内容ではなく、WAT と呼ばれる WebAssembly のテキスト表現を書きながら実装する。

構成

ざっくり Chapter ごとにやってることを書く。

  • Chapter 1: Introduction to WebAssembly
    • WebAssemblyとは何か、その特徴は、なぜ WebAssembly を使うかみたいな話
    • WebAssembly Text Format (WAT) の紹介もここで
  • Chapter 2: WAT Basics
    • WAT の基本構文:関数の import、data、変数、if 文や loop など
  • Chapter 3: Functions and Tables
    • WebAssembly で定義した関数を JS から呼び出す
    • Table (function table) について。Table を使った場合と関数を直接呼び出した場合のパフォーマンス比較
  • Chapter 4: Low Level Bit Manipulation
    • ビット演算について。 読んでない
  • Chapter 5: String Manipulation
    • 文字列操作
    • Null-Terminated Strings と Length-Prefixed Strings という 2 つのポピュラーな方法
  • Chapter 6: Linear Memory
    • linear memory の使い方
    • オブジェクトのような複雑なデータ構造を linear memory でどう管理するか
  • Chapter 7: Web Applications
    • ブラウザで WebAssembly を実行する方法
    • DOM 操作をどう実現するか
  • Chapter 8: Working with the Canvas
    • Canvas を使ったアニメーション
  • Chapter 9: Optimizing Performance
    • ブラウザの DevTools を使ったパフォーマンス計測と改善
    • パフォーマンス改善につながるテクニック
  • Chapter 10: Debugging WebAssembly
  • Chapter 11: AssemblyScript

Chapter 8 の Canvas アプリケーションは↓のような、物体の衝突判定アプリ。
正方形の形をした大量の物体が一定速度で動いており、他と衝突してるときだけ色が変わるというもの。
フレームごとの物体の座標計算と衝突判定を WebAssembly 側でやっている。

f:id:dackdive:20210802001349g:plain:w480

これは https://rustwasm.github.io/book/ で作ったものと似てるなーと思った。

全体的な感想

C や Rust からのコンパイルではなく素の WAT をひたすら書くので実用的な知識が得られたとは思わないけど、知らなかったことも多かったので学びはあった。

特に

  • WebAssembly では文字列扱うの難しいのは知っていたが、Chapter 5 で具体的なアプローチとともに文字列操作の方法を学べた
  • Chapter 6 の linear memory の章で、やや複雑な( i32 みたいなプリミティブな値でない)データ構造を扱うために linear memory 上にデータをどう格納するのかがわかった
  • Chapter 9 で DevTools でのパフォーマンスの見方がわかった(これは若干 WebAssembly 関係なくなるけど)
  • ところどころでパフォーマンス比較の話が登場しており、WebAssembly をどういうとき/どういうふうに使うべき/べきでないみたいなのが腹落ちした。たとえば:
    • 純粋な WebAssembly 関数と、WebAssembly 関数の内部で JS から import した関数を呼び出した場合
    • Table を使って間接的に関数を呼び出した場合と直接呼び出した場合
    • 同じ処理内容を WebAssembly で実装した場合と JS で実装した場合

というあたりはよかった。

反面、WAT の構文の説明とか動作原理についてきちんと説明されてないと感じる部分もいくつかあった。たとえば i32.store / i32.load とか data とか。
local variable や global variable ってデータ上はどういうふうに格納されてるの?とか。

WAT の構文だけで言えば、 MDN のこのページを読むのとそんなに大差ないのでは、と感じた。

本自体の構成については、300 ページ弱あるもののサンプルコードは基本的に省略せず全部載せているためコードが大半を占めていて、ページ数から受ける印象ほど読むのが辛くなかった。
またコードの説明はかなり丁寧に書かれていた。

なんだかんだ英語の本を読むのが初めての挑戦だったけど挫折せずに完走できてよかった。

良かったところ、勉強になったところ

Chapter 2: WAT Basics

WAT の記法は S式 (S-Expression) 以外に Linear Instruction List Style というのもあり、両者が混在している。

S 式で表現した

(i32.add (i32.const 3) (i32.const 2))

は、Linear Instruction List Style で書いた以下と等価。

i32.const 3
i32.const 2
i32.add

後者は値が上から順にスタックされてく様子を脳内で覚えておかないといけないので、S 式の方が読みやすいと個人的には思う。

Chapter 5: String Manipulation

文字列を linear memory を介して JS とやり取りする場合、文字列の開始位置とともに文字列がどこで終わるのかという情報も JS 側がわかる必要がある。
そのための2つのポピュラーな方法として Null-Terminated Strings と Length-Prefixed Strings という方法がある。

1) Null-Terminated Strings

文字列の終わりに null 終端文字列を挿入する。

;; wat 側
(data (i32.const 0) "null-terminating string\00")
// js 側
const bytes = new Uint8Array(memory.buffer, str_pos, max_mem - str_pos);

let log_string = new TextDecoder("utf8").decode(bytes);
log_string = log_string.split("\0")[0];

2) Length-Prefixed Strings

文字列の最初に文字列自体の長さを埋め込んでおく。

;; wat 側
;; 22 文字で、16 進数にすると 16
(data (i32.const 512) "\16length-prefixed string")
// js 側
const str_len = new Uint8Array(memory.buffer, str_pos, 1)[0];
// 文字列自体の長さが先頭に1バイト埋め込まれているので + 1
const bytes = new Uint8Array(memory.buffer, str_pos + 1, str_len);
const log_string = new TextDecoder("utf8").decode(bytes);
Chapter 6: Linear Memory

Linear Memory は「ページ」という単位で確保する。1ページ 64 KB、最大ページ数は 32,767。

WAT 側では

(memory 1)

JS 側では

const memory = new WebAssembly.Memory({ initial: 1 });

というように初期化時にページ数を指定する。

(p125 「Collision Detection」)
あるデータ構造の配列を linear memory に格納する場合、以下の情報が必要。

  • starting address: linear memory 上でそのデータ構造の配列が始まる位置
  • stride: データ構造1つあたりに必要なバイト数 = distance in bytes between each structure
  • offset of any structure's attributes: データ構造の各属性へのオフセット
    • たとえば x, y という属性があり、それぞれ 4 バイトだとすると、そのデータ構造の属性 y のオフセットは 4

f:id:dackdive:20210802013205p:plain

学習メモ

読みながら取ったメモは
https://github.com/zaki-yama/learn-rust-and-webassembly/tree/main/the-art-of-webassembly
の章ごとのディレクトリに置いてある。

2021年4〜6月のふりかえり

前回:2021年1〜3月のふりかえり - dackdive's blog

✨ やったこと

「ゼロからの OS 自作入門」は中断(挫折)した

3 月に買った OS 自作入門だが、手元のメモによると 5 月上旬ぐらいで更新が止まっている。。。
たしか、6 月に「The Art of WebAssembly」という本が発売されることを知ってそっちに興味持ってからゆるやかに終了してしまったんだな。

The Art of WebAssembly を読んでいる

というわけで 6 月から読み始めたのはこの本。

C++もRustも使わずWATファイルを直接手書きしながらWebAssemblyを学んでいく、というストロングスタイルの本。
長いが今のところわかりやすい。

📝ブログ

この四半期に書いたブログは以下。

また、ブログとして消化できてないが、こういったことを調べてた時期もあった↓

TypeScriptでType AliasesとInterfacesどちらを使うべきか

💬 所感

続:なんとなくしんどい

前回のふりかえりでも「集中力・モチベーションが上がらないと感じる時期があった」って書いてるけど、相変わらず仕事もプライベートもなんとなくモチベが上がらない感覚はある。
これについては少し前のこういった記事を目にした。

これを読んで、そうか自分は languishing なのかもしれないと認識するようになった。また、名前がついているぐらいだから自分以外にも似たような感覚の人は少なくないのかもしれない、ということがわかって少し気が楽になった。

あとここに詳細を書くのは憚られるんだけど、身内の不幸とかもあってそれもけっこう心を揺さぶられる要因になったりもした。

Rust の勉強が止まってしまった

WebAssembly の本を読み始めたのはいいけど、Rust のコードを書く機会がめっきりなくなってしまった。
がんばって Exercism 再開したいなーとも思うし、Twitter で見かけたこの本もセールで衝動買いしてしまったので次読むとしたらこの本かもしれない。

UoPeople (University of the People) に申し込みした

ようやく手続きした。事前にがんばってTOEFLのスコアを取得してたので、最初の英語の授業は免除できそう。
ただ、タームの期限最終日に申し込みしたりTOEFLのスコア提出を後からメールで送ったりした関係で、本来6月からスタートできてたはずが最初のコースは次タームからになりそう。

そして、この間にいろいろあったのでモチベーションは勢いで申し込んだときより下がってしまっている。。。
やってみてだめならやめる、卒業をゴールにするとしんどいので興味あるCS系の授業を自分のペースで学ぶ、ぐらいの気持ちでやっていきたい。

💪次の四半期(2021年7〜9月)のテーマ

  • 📕The Art of WebAssembly
  • 📕Rust in Action

💸 買ったもの

logicool ワイヤレスマウス MX ERGO

★★★★★
同僚氏がオススメしてたので買った。トラックボールは使ったことがなかったけど非常に良い。

ダブルステンレスドリッパー・粕谷モデル

★★★★☆
ほぼ毎日コーヒーを飲むので買った。
以前は安物のセラミックフィルターだったので洗わないといけない金属フィルターには抵抗がなかった。 ネルドリップっぽいかどうかはわからないけどたしかに味はまろやかになった気がする。人によってはちょい物足りないと感じるかも。