2020/02/06
以下のコードを見てください。
type HogeUnion = 1 | 2;
function printHogeUnion(x: HogeUnion) {
console.log(x);
}
HogeUnion型、つまり1 | 2であるxを受け取って出力するだけの単純な関数printHogeUnionを定義しています。何も問題がないコードです。
もしTSの型の健全性が壊されてxに1 | 2以外の値が入ってきた時にすぐ気付けるようにランタイム型チェックを行いたくなったとしましょう。例えばprintHogeUnion(0 as any)を実行すると0を出力するのではなく例外を投げるといった具合です。この時unreachable関数を定義し、printHogeUnionにランタイム型チェックのコードを追加して以下のようになります。
function unreachable(): never {
throw new Error("unreachable");
}
function printHogeUnion(x: HogeUni
2019/12/21
はじめに
RustでWebAssemblyインタプリタを作ったのでその実装の話や、wasmの仕様についての記事です。
HListを使ったジェネリックプログラミングの話や、最後の方には「自作言語 on 自作wasmインタプリタ on 自作wasmインタプリタ」みたいな話も出てきます。
分かりにくい所や間違っている所は指摘してくださると助かります。
リポジトリ
https://github.com/kgtkr/wasm-rs
作った成果物のリポジトリです。まだpublishはしていませんがクレートになっています。
cargoのexample実行に対応しているのでそれを見ればだいたい分かると思います。
今回はadc-2019-12-22というタグがついたコミットのソースを元に解説していきます。
https://github.com/kgtkr/wasm-rs/tree/adc-2019-12-22
仕様書
この記事では仕様書を読みながら順番に実装を解説していきます。
https://webassembly.github.io/spec/
2019/12/09
Rustにはcatch_unwindという関数がありpanicをキャッチすることが出来ます。
Rustのパニック機構 - 簡潔なQ
しかしここから得られるエラー情報がかなり少ないです。キャッチして得られるResultのError型はBox<dyn Any>みたいな型ですが、これがほとんどStringまたは&strとなっており(今の所他の型を見ていませんが詳しい方教えて下さい)、確認した所スタックトレース情報やパニックが発生したソースの位置情報は入っていませんでした。例えば以下のコードはpanic testと出力します。
if let Err(e) = panic::catch_unwind(move || {
panic!("panic test");
}) {
println!("{}", any_to_string(&*e));
}
fn any_to_string(any: &dyn std::any::Any) -> String {
if let Some(s) = any.downcast_ref::<S
2019/12/08
資料
31回だったのに32回と勘違いしててURLが32になっていますが気にしないでください。ライブデモ多いので多分LT資料だけじゃよく分かりません。
https://gitpitch.com/kgtkr/slide-student-lt-32
LT動画
内容
自己紹介wasmに関する説明
watについて(watコード読みながら解説した)wasm(バイナリ)について(wasmバイナリ読みながら解説した)
rustでwasmインタプリタ作った話
デコーダーエンコーダースタックマシン
自作言語 on 自作インタプリタ(ライブデモ)自作言語 on 自作インタプリタ on 自作インタプリタ(ライブデモ)
補足資料とか
成果物: https://github.com/kgtkr/wasm-rswasm仕様書: https://webassembly.github.io/spec/core/index.html自作言語などについて(去年のアドカレ)
WebAssemblyでメモリアロケータを実装WebAssemblyでGCを実装するWebAssemblyに
2019/11/02
はじめに
WebAssemblyにはbrという命令があります。
この命令はbr <label>という形になっており、<label>が示す制御構造に対して何らかの動作をします。
例えばブロックに対して使えばブロックを抜け、ループの中で使えばcontinueのような振る舞いをします。
wasmのループについてはκeenさんのWebAssemblyのloopはまりどころという記事を見てみて下さい。
なぜこのように制御構造によってブロックを抜ける働きをしたり、continueの働きをしたりするか仕様書を読んでいたところ理由が分かり面白いと思ったので記事にしました。
br命令
基本的にはbr 数値という形の命令です。この数値は相対的な値となっておりbr命令を囲っているすぐ外側の制御構造に対してなにかするときはbr 0と、その外側であればbr 1と...いうふうに指定します。
また、watでは制御構造に$labelをつけることでbr $labelと書けばbr命令がどの深さに関係なくその制御構造に対して命令を実行することができます。
例
関数に対して
2019/08/27
初めに
この記事は型安全な型定義とそれが可能な実装に関する考察であり利用者側にとっての使いやすさなどは考慮していません。ここに型安全ではない例としてあげた、もしくそれと同じような定義となっているライブラリも型推論に頼っていれば基本的に安全な事と、使いやすさを考えると仕方ない部分があることは理解しておりそのようなライブラリに対する批判でもありません。
曖昧な知識で考えた自分用メモのようなものなので間違っている所がある可能性は高いですし参考にはしないで下さい。間違ってる所があればTwitterなどで指摘してくださると嬉しいです。
オブジェクトのキーの集合の値表現
以下のような関数定義があるとする。
function f<T extends object, K extends keyof T>(obj: T, keys: Keys<K>): Result<T, K>;
この時型コンストラクタResultの性質によって場合分けし、Keys、つまりオブジェクトのキー集合の安全な受け取り型を考える。
またobj: Tとkeys: Keys<K>を
2019/07/16
TL;DR
import { isT, isNotT, defineIsT } from "safe-type-predicate";
// isA: (x: "a" | "b") => x is "a"
const isA = defineIsT((x: "a" | "b") =>
x === "a" ? isT(x) : isNotT()
);
GitHub
safe-type-predicate
type predicate and its dangers
TypeScript has a feature called type predicate.
This is by coding the return value of a function that takes an appropriate type of value x and returns boolean as x is T. If true is returned, x is of type T, false This is a function that
2019/07/16
TL;DR
import { isT, isNotT, defineIsT } from "safe-type-predicate";
// isA: (x: "a" | "b") => x is "a"
const isA = defineIsT((x: "a" | "b") =>
x === "a" ? isT(x) : isNotT()
);
GitHub
safe-type-predicate
type predicateとその問題点
TypeScriptにはtype predicateという機能が存在する。
これは適当な型の値xを受け取りbooleanを返す関数の戻り値をx is Tと書くことで、trueを返せばxがT型、falseを返せばそうでないことを表す機能である。
これによってユーザー定義関数で型ガードを行うことを可能にしている。
例えばunknown型、つまり任意の型を受け取りその値がstring型であるかを返す関数は次のようになる。
function isString(x: unknown): x is
2019/04/15
When type level programming, various errors occur.So we need to suppress it.
This article introduces two ways to suppress errors.
I checked with v3.4.2.
Suppress type constraint error
There are operations in TS that can only be of the type that satisfies the condition.
Here are some examples.
type F<T extends any[]> = T;
type X = F<A>;// A require to extends any[]
type Y = B["x"]// B require object type and have roperty named `x`
However, even if it is known that the con
2019/04/15
TypeScriptの型レベルプログラミングでは様々な型エラーが発生するため、それを抑制しながら作っていかなければいけません。
今回はエラーを回避するテクニックを2つ紹介します。
v3.4.2で動作確認をしています。
型制約エラーを抑制する
TSには型の型のようなものがあり、それを満たす型にしかできないような操作があります。
いくつか例を挙げます。
type F<T extends any[]> = T;
type X = F<A>;// Aはany[]を継承していなければいけない
type Y = B["x"]// Bはオブジェクト型で`x`というプロパティを持っていなければいけない
しかしこのような条件を満たしていることが分かっていてもコンパイラが推論出来ておらずエラーになることがあります。
そのような時は以下のようなCast型を定義して使いましょう。
これはTはPを継承している時は分かっている時にCast<T, P>と書いて使います。
type Cast<T, P> = T extends P ? T : P;
例です。