プログラム意味論のお勉強
ふと思い出しては何かを読んで、挫折してを繰り返しているのでいつまで経っても理解できていない。 けど、悔しいのでたぶん今後もチャレンジしていくと思うので自分用のリストを作っておく。
ウェブ
書籍
- プログラミング言語の基礎概念 / 五十嵐 淳 / サイエンス社
- プログラム意味論 / 横内 筧文 / 共立出版株式会社
ふと思い出しては何かを読んで、挫折してを繰り返しているのでいつまで経っても理解できていない。 けど、悔しいのでたぶん今後もチャレンジしていくと思うので自分用のリストを作っておく。
自分には思い通りのものを作ることはできなかった。
以下みたいなことを実現したい。
HashMap
let bag = Basket::new();
bag.set("Universe");
bag.set(42);
println!("i32: {}", bag.get::<i32>()); // => "i32: 42"
println!("&str: {}", bag.get::<&str>()); // => "&str: Universe"
// println!("bool: {}", bag.get::<bool>()); => Compile Error!
業務で Rust を使っていこうということになったので、Rust を勉強しながら何か Web アプリでも作ってみようと思って actix-web を触り始めた。サンプルコードをいじっていて気になったのはリクエストハンドラの引数の柔軟さで、まるでスクリプト言語のように扱える。
例えば以下は http://localhost:8080/hoge
にリクエストを受けると path 部分である /hoge
をレスポンスとして返す。
fn index(
req: HttpRequest,
) -> impl IntoFuture<Item = String, Error = Error> {
Ok(String::from(req.path()))
}
fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.default_service(web::route().to_async(index))
})
.bind("127.0.0.1:8080")?
.run()
}
リクエストハンドラに何かデータ(普通はアプリケーションの状態など)を渡すこともできる。この例だと http://localhost:8080/spacecat
にアクセスすると http://www.example.com/spacecat
が表示される。
fn index(
req: HttpRequest,
prefix: web::Data<&str>,
) -> impl IntoFuture<Item = String, Error = Error> {
Ok(format!("{}{}", prefix, req.path()))
}
fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.data("http://www.example.com")
.default_service(web::route().to_async(index))
})
.bind("127.0.0.1:8080")?
.run()
}
ここで「どこまで柔軟性があるんだろうか?」と思って、試しにリクエストハンドラの引数の順番を入れ替えてみた。
fn index(
prefix: web::Data<&str>,
req: HttpRequest,
) -> impl IntoFuture<Item = String, Error = Error> {
Ok(format!("{}{}", prefix, req.path()))
}
これ、ちゃんと動いてしまう。
Rust のようなガチガチに検証するタイプの言語でこの柔軟性を一体どうやって実現しているんだろう・・・? と思ったのがきっかけ。