サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
掃除・片付け
zenn.dev/qnighy
WebAssemblyをちょっといじってみて思ったところをまとめてみます。 設計思想 WebAssembly/designに設計文書がまとまっています。特にHighLevelGoals.mdから読み取れるポイントは以下の4点です。 サンドボックス化された環境であること。 移植性があること。つまり、特定の実CPUアーキテクチャ等に依存しないこと。 少なくともC/C++の(十分に高速な)コンパイルターゲットとして機能すること。 安定した仕様を持つこと。 サンドボックスという観点からは、先行技術として以下のようなものが特筆に値します。 Webサンドボックス JavaScript および asm.js Javaアプレット Flash (ActionScript) NaCl, PNaCl Web以外のサンドボックス OSのユーザーランド、特にLinux userland これらのサンドボックスとの比
デザインパターンライブラリを作った JSRの話だけ読みたい人は読み飛ばしてもOKです。 JavaScriptのtry-catchはC++の影響を受けており、以下の特徴があります。 (A) throwは大域脱出的である。 (B) try-catchはブロック内の全ての例外副作用に対して一括で作用する。 (C) try-catchは文であり、値を返せない。 (D) TypeScriptにおいて、例外型は明示されない。 このうち (B), (C), (D) の問題を解決するため、RustのResultや類似のパラダイムをJSに輸入する試みがしばしば行われています。しかしこの解決手段にはいくつかの問題があり、 (E) rethrowの専用構文がないためボイラープレートが増える。 (F) 出力ストリームに対するwriteなど、戻り値を持たない副作用関数に対するエラーハンドリングが抜け落ちないようにL
以下のページに主要ブラウザのuser agent stylesheetへのリンクがまとまっています。 しかし、2024年2月時点で、これらは最新リビジョンへのリンクを参照していません。以下が現在の正しい最新版URLです。 Chromium (Chrome) のuser agent stylesheet 奇妙なことに、Chromiumのソースツリーの third_party/blink 以下の内容は、フォルダ名に反し、Blinkの正式な最新版のようです。 GitHub上の公式ミラーからもアクセスできます。 WebKit (Safari) のuser agent stylesheet
all: unset; などを使ってUAスタイルシートを消してまっさらな場所からスタイルを当てるのは気持ちがいいですが、アクセシビリティ等の観点から重要な分岐が見落とされる可能性があります。 ここではChromeのUAスタイルシートを参考に、検討しておいたほうがいい状態をいくつかリストします。 (もちろん、既存のUIコンポーネントライブラリの使用が可能であれば、それが最も堅牢な選択肢でしょう。) 参考 各ブラウザのスタイルシート HTMLのスタイルシート UAスタイルの中には、CSSのカスケードルールの範疇で実装されているものもあれば、レンダリングエンジンの特別処理として書かれていて作者スタイルシートでの上書きが不可能なものもあります。これはブラウザ実装により異なります。 スコープ UIコンポーネントを作るような場面を想定しています。したがって、要素名自体は固定として、その中で見落としがち
Xで出したクイズの解説です。 問題は次の通りです。 以下のJavaScriptの比較は常にtrueになるでしょうか? それともfalseになる可能性があるでしょうか? (そして、あるとしたらそれはどのような場合でしょうか?) JSON.stringify( eval( "(" + JSON.stringify(x) + ")" ) ) === JSON.stringify(x) ただし、以下の条件を仮定します。 Objectなどのビルトインの定義は汚染されていないものとし、evalはglobalThis.evalを指しているものとします 内側のstringifyがエラーになる場合は除外します 答え この出題をわざわざすることからだいたい予想がついてしまうと思いますが、これは「falseになる可能性がある」というのが正しいです。 問題は、具体的にどのような場合があるかです。 これについて、当
bqpbというライブラリを作ったので解説します。 使い方についてはリポジトリ内のドキュメントを参照してください。 動機 protobufはGoogleが開発したバイナリシリアライゼーションフォーマットです。msgpackやCBORもバイナリシリアライゼーションフォーマットですが、これらがスキーマレスフォーマットに分類されるのに対して、protobufはスキーマ依存のフォーマットです。この意味では同じくスキーマ依存のフォーマットであるASN.1 DERに近いと考えるのがよいでしょう。 一方、BigQueryはGoogleによるデータウェアハウスです。データへのアクセスにはもっぱらBigQuery用のSQLが用いられます。 BigQueryにはJSONを扱う関数群がありますが、protobufを扱う関数は今のところありません。もし何らかの理由で(たとえば簡潔であるとか、protobufでやり取
ipc_bot とは ipc_bot は2023年5月までTwitter (現: X) で稼動していたbotで、「直観主義命題論理」と呼ばれる問題を自動で解いてくれるbotです。 現在はXの読み取り系のAPIが有料化されたことから、Mastodonにお引っ越ししています。(Misskey等の他のActivityPub実装からも利用できます) 使い方 直観主義命題論理の式をテキストで表記してメンションすると、結果が画像で返信されます。以下のような具合です。 命題の書き方と結果の読み方 命題 「命題 (proposition)」とは、ありていに言えばbool型の式のようなものです。ただし、それが具体的に計算可能である必要はありません。重要なことは、その式の評価値の真理性(真か偽か)を議論することができるという点です。 ipc_botが対象としているのは「命題論理 (propositional
課題 Rustでシンプルな単一化を書くことを考えます。単一化は主に型推論の実装に用いられます。 ここでは以下の方針で実装します。 一階の単一化。 変数は非負整数のidで表現し、0から順に付番する。 変数以外の項はRustのADTを使った通常の木構造で表現し、ノードの共有は行わない。 変数参照の縮約は行わない。 この方針のもと実装すると、およそ以下のようなコードになります。 #[derive(Debug, Clone)] pub struct UnifyEnv { vars: Vec<Option<Type>>, } #[derive(Debug)] pub struct UnificationFailure; #[derive(Debug, Clone, PartialEq, Eq)] pub enum Type { Var(usize), Constr { constr: u32, ar
本記事ではJavaScriptのテンプレートリテラルとタグ付きテンプレートの言語仕様について説明します。その後、筆者が作成したdedentライブラリ (@qnighy/dedent) を紹介し、このライブラリがどのようにテンプレートの機能を活用しているかを説明します。 いつものように言語仕様の細かい話がメインなので、そういう話が好きな人にはおすすめです。 テンプレートリテラル テンプレートリテラルとは テンプレートリテラル (template literal; see: MDN, ES) は ` で始まるリテラルで、文字列を返します。 テンプレートリテラルはES5以前からある文字列リテラル (string literal; see: ES) と役割が似ていますが、いくつかの違いがあります。ここではまずテンプレートリテラルと文字列リテラルの違いを説明していきます。 置換 置換 (substi
何を作ったか これを作りました。 解決しようとした課題 「小説家になろう」は公式に「小説Atom」というフィードを提供しており、小説の最新話を読むにはこれで事足ります。 しかし、すでに多くの話数が投稿されているストーリーを一気に読むのは大変なことがあります。 このような場合に、一度にまとめて読み進めるのではなく、一定のペースで少しずつ読み進めていく仕組みがあると便利だと考えました。 仕様 配信方法 やりたいことは「一定のペースで、過去のエピソードを配信する」ということです。 このような更新情報を提供するには古典的な仕組みとしてRSS/Atomがあります。RSS/Atomによる最新情報の取得は以前ほどは広くは使われていないように思えますが、今でもフィードリーダーは生き残っています。特定のSNSに連携するよりは汎用的な形式のほうが応用の幅は広くとれます。また、RSS/Atomであればpush通
TLSの有無 言うまでもないことですが、httpsでは通信路をTLSを使って保護することが想定されています。[1][2] デフォルポート httpは80、httpsは443です。[3][4] 権威性 以降の説明に入る前に前提を確認します。本稿は「httpとhttpsの違い」と題されていますが、これはURLのスキーム部分のことを指しています。URLはリソースの所在を指すものであり、通信方法はそこから二次的に決まるものです。このことを前提に置きつつ権威性について説明します。 Webにおいて、所望のリソースにアクセスする方法はひとつではありません。このような方法のうち、リソースの所有者の制御下にある(第三者による加工などが行われていないと期待される)方法で取得することを権威的アクセスと呼びます。[5] どのようなアクセス方法が権威的とみなせるかについて100%客観的で統一的な指標があるわけではな
何が大変か? VSCodeはMSが作っているだけあってTypeScript統合がほぼ整っており、特に設定を頑張らなくてもそのままIDE機能が効くことが多いです。現代の多くのJavaScriptプロジェクトはこれで事足ります。 しかし、これには例外があります。Reactの実装は現時点ではFlowで書かれています。FlowはTypeScriptと同様のコンセプトを持つAltJS言語です。FlowはReactと同じくMeta(Facebook)製であるため、これまでReactでFlowが使われてきたのは一定の合理性があると言えるでしょう。 Flowの拡張子が *.js であることから、TypeScriptのIDE機能はFlowのソースコードに対しても反応します。文法が似ていることもあり、Go To Definitionなどの機能もある程度までは動作しますが、完全ではありません。また、エラー表示が
export type Bookmark = { id: number; url: string; comment: string; }; このファイルには型しか書いてありませんね。ということは、「型定義ファイル」として bookmark.d.ts という名前にするべきでしょうか。実はそうではなく、この場合は bookmark.ts とするべきです。 「型定義ファイル」とは、「どこか別の場所にある実装に型をつけるためのファイル」です。たとえば、以下のファイルは「どこか別の場所にある実装」に型をつけているから、 *.d.ts にするのは自然です。 いっぽう、 type Bookmark は別のどこかにある *.js の型を与えているわけではないので、 *.ts でよいです。 このように本来 *.ts であるべきものを *.d.ts にしてしまうことには問題があります。代表的な問題として型エラ
Rustで値の文字列表現を返すにあたって、 String を直接返すのではなく Display を実装するのが一般的です。この派生パターンとして以下の4つのパターンを紹介します。 基本: 文字列化を実装したいとき 文字列化をインターフェースに含めたいとき カスタム文字列化 カスタム文字列化をインターフェースに含めたいとき 基本: 文字列化を実装したいとき Displayを実装すると、文字列化できるようになります。 println!, format! などのフォーマット処理から呼べるようになるほか、 .to_string() というヘルパ関数が使えるようになります。 以下はプログラミング言語処理系において、「変数」をあらわす構造体に文字列化を実装する例です。 Playground pub struct Var(String); impl std::fmt::Display for Var {
Rubocopのプラグイン(cop)などのためにユーザーがRuby ASTを触る機会がありますが、このRuby ASTには混乱をまねきかねない部分がいくつかあります。そこで本稿では混乱しやすい部分を簡潔にまとめました。 Ruby AST AST (抽象構文木) は構文解析の結果を保持するためのデータ構造です。 ここではRubyにおける構文解析ライブラリのデファクトスタンダードであるparser gemのASTを扱います。 Ruby本体が提供するRipperやRubyVM::AbstractSyntaxTreeといったAPIもありますが、Ripperは字句単位の情報取得に特化したAPI設計になっておりそのままASTとして使えるようになっていません。RubyVM::AbstractSyntaxTreeはVMでの利用に向いた設計になっており、外部ツールから利用するのには必ずしも便利ではない面があ
本稿の目的 Rustに存在しない「クラス」をRustの既存機能の組み合わせとして表現することで、一般的なOOP言語とRustのデータ表現に対する考え方の違いと、各概念がどのように対応しているかを理解しやすくすることが主な目的です。 主な想定言語 C++, Java, JavaScript, Rubyのクラスを主に想定しています。 方針 サブタイピング Rustにはごく限定的なサブタイピングしかないため、クラスのサブタイピングに相当する変換は明示的に .as_ref() / .as_mut() として表現します。 Deref / DerefMut を使うことで、このような振る舞いを部分的に再現できる場合もあります。ただし、この用途でDeref / DerefMutを使うのは推奨されていません。 カプセル化 一般的なOOP言語では継承関係に基づいたアクセス制御 (protectedなど) が行
型推論オプション 型推論の結果が変わるもの。 ⭐strict ... 以下のセット alwaysStrict strictNullChecks T | null や T | undefined が T に縮退しなくなる。 例 strictBindCallApply Function の各種メソッドが any に縮退しなくなる。 例 strictFunctionTypes コールバック関数の引数が共変でもunifyするようになる結果、型変数の推論優先度が変わることがある。 例 strictPropertyInitialization noImplicitAny 宣言型がない場合にflow typeが使われる機会が増える。 例 noImplicitThis thisの宣言型がない場合に文脈から型が決定される機会が増える。 例 useUnknownInCatchVariables catch (
症状 WSL2におけるOpenSSHのAgentについては以下の記事を参照。 混沌を極めるWindowsのssh-agent事情 - Qiita WSL2 の SSH Agent 盆栽 - 趣味はデバッグ…… 手元のPCでは npiperelay + socat を使ったAgent Relay構成にしているが、最近になって動かなくなった。Agentから結果が得られず、毎回ストレージの秘密鍵を開くためにパスワードが要求されるようになっていた。 何を調査したか 秘密鍵を移動。パスワードが聞かれなくなり、エラーになることを確認 → Agentから毎回パスワードを聞かれているのではなく、そもそもAgentがうまく動いていない ssh-add -T ~/.ssh/id_rsa.pub は正しく動作することを確認 → 少なくとも基本的な通信経路は生きている openssh-portable を自分でビ
dyno (RFC3192) はopen traitのための仕組み (言い換えると、trait downcastingの仕組み) をライブラリレベルで実現する提案です。 できることのイメージ 例として、以下のようなトレイトを考えます。 (std::error::Error を説明のために簡略化したものです) // エラー型はこれを実装する pub trait Error { // エラーの文字列表現を取得する fn to_string(&self) -> String; } これを拡張可能トレイトにするのが本RFCの目的です。 実際の実装はライブラリレベルで行われていますが、わかりやすくするために「拡張構文として書くならこんな感じ」というイメージを先に説明します。 open traitとしての説明 次のように、定義済みのError traitを拡張できる仕組みであると説明できます。 ⚠️こ
いかにも既知な気がしますが、ぱっと既存の議論が探せないのでとりあえず書き出してみます。 ※用語は独自のものです。また、証明・定義は厳密に検証しているわけではないので誤りがあるかもしれません。 この定義でカバーできること 先頭 ^ 末尾 $ 肯定先読み (?= ... ) 否定先読み (?! ... ) 肯定後読み (?<= ... ) 否定後読み (?<! ... ) この定義でカバーしないこと 選択の左右の優先度 (r1|r2 vs. r2|r1) 最長優先と最短優先の区別 (r* vs. r*?) 基本の正規表現 基本の正規表現は通常以下のように定義されます。 \Sigma はアルファベットで有限サイズとします。 文字リテラル a (a は文字 a \in \Sigma) 空文字列 \epsilon と連接 R_1R_2 (R_1, R_2 は正規表現) 空集合 \emptyset と
事前条件も事後条件もテストも全部 assert!() でいいの? まあ、いいんじゃないでしょうかという話 Rustでは実行時表明とテスト表明の双方を同じ仕組み (panic機構) を用いて行います。 Rustを書くにあたって、この部分に違和感を覚えた人もいるのではないかと思います (多数派ではないと思いますが)。本稿ではこの違和感について分析し、Rustではそれで問題ないと確認することを目指します。 ※割とフワッとした話に終始します Resultとpanic Rustではエラー処理の方法としてResultとpanicの2種類の方法を提供しています。これは大まかに以下のように使い分けられます。 プログラムが想定しなければいけないエラー (ユーザーが誤った入力を与えた場合や入出力エラーなど) はResultを使う。 プログラムが想定外の状態に陥った場合 (意図しない配列の境界外参照など) はp
本稿では直和による多態性を実現する2つの機能、enumとtraitを拡張性の観点から比較します。 → Expression problem ※enumとtraitを使い分けるにあたってはパフォーマンス要件など他の条件も考慮するべきですが、本記事は多態性の観点のみ説明します。 数式 — enumによる例 本稿では数式をあらわすデータ型を例として扱います。enumではこのように定義されます。 #[derive(Debug)] pub enum Expr { Var(String), Add(Box<Expr>, Box<Expr>), Sub(Box<Expr>, Box<Expr>), Mul(Box<Expr>, Box<Expr>), Div(Box<Expr>, Box<Expr>), } impl Expr { pub fn eval(&self, vars: &HashMap<St
データをシリアライズするには、独自のフォーマットを定めるよりも、基本的な定義済みの構造を組み合わせてフォーマットを作るほうが望ましい場合が多いです。 そのような仕組みとしてJSON, S式, XMLなどが存在しますが、これらは 「基本的な構造」として何を選ぶか、という観点からそれぞれに個性を持っています。 本記事では、具体的な構文のことは基本的に忘れて、各フォーマットが採用するデータモデルの違いに焦点を絞って比較します。 JSON data JSON = Value data Value = -- Compounds Array [Value] | Object (Map String Value) -- Scalars | Null | Boolean Boolean | String String -- UCS-2 | Number IntegerOrFloat -- no NaNs
次のようなパッケージ (クレート) を作ったので解説します。 動機 Rustには所有権があるため、普通のswapパターンが動かない場合があります。これに対応するため、std::mem::swapという関数が用意されています。 let mut x = 'a'; let mut y = 'b'; std::mem::swap(&mut x, &mut y); assert_eq!((x, y), ('b', 'a'));
TypeScriptではデザインパターンとしてtagged unionによる直和がよく使われます。このときパターンマッチに相当する処理はswitchで行われますが、そこで直和に対する分岐が網羅的であることの保証を実行時と型検査時の両方で賢く行う方法がこれまでも模索されてきました。 今回、ヘルパー関数を導入せずにいくつかの問題を同時に解決する賢い方法を思い付いたので共有します。 コード これだけです。 // switch (action.type) { ... default: throw new Error(`Unknown type: ${(action as { type: "__invalid__" }).type}`); // .. } 以下、より詳しく説明します。 問題 TypeScriptではオブジェクトに type プロパティーを用意し、決まった文字列を入れることで直和を実現
※大風呂敷を広げてやる気だけ表明する記事です。まだ中身はない。 はじめに Rustは2009年頃に誕生し、2015年に正式リリースされたプログラミング言語です。その革新性はおよそ以下のように集約されます。 shared XOR mutable とそれに付随する発明 (所有権、ライフタイム) により、ミュータブル参照が正しく扱えるようになった (責任分界点が明確になった) こと。 上記のアイデアにより、高パフォーマンス・低フットプリントが求められるアプリケーションやOS・GC・アロケーターのない環境で動く必要のあるアプリケーションをより安全に書けるようになったこと。 プログラマーが安全に・快適にプログラムを書くための既知の優れた道具 (パッケージマネージャーなど) を計画的に取り入れ、伝統的なプログラミング言語が抱えがちな問題を広範に解決したこと。 これらの革新性から、これまでC/C++が担
Cycloneとは CycloneはRustのリージョン推論の原型のひとつになった実験的なプログラミング言語です。 現在はメンテナンスされていませんが、歴史的な意義があることからCycloneのビルド環境を整備してみました。 (完結するかは未定) ソースの取得 CycloneのWebサイトは生きているので、ソースはCycloneのDownloadページから取得できます。しかしここに不穏な文言があります。 If you use gcc 4, you must get the latest version of Cyclone from SVN (see below). 最新安定版よりも新しい版があること、またgccのバージョンに依存して壊れることが読み取れます。そしてSubversionと書いてあることから嫌な予感がした人もいると思いますが、このリポジトリは既に動いていません。 というわけで
注意事項 おそらくCRuby (いわゆるMRI) 限定です。3.1.2で確認しています。 環境構築が面倒だったため、実際には32bit環境でテストしていません。意図通りに動かなかったらすみません…… 以下解説 doキーワードの多重性 RubyではLRパーサージェネレーターであるBisonを使いながらも、LR(1)とは思えない高度な構文をパースさせるために、字句解析器が非常に複雑な状態管理を行っています。見た目が同じトークンでも、Bisonに渡すときには状態に応じて異なるトークンとして認識させることがあります。 doキーワードもそのような多重性をもつトークンの例で、構文解析器からは以下の5種類のトークンとしてあらわれます: 通常の識別子 foo.do ラムダ式のdo-endブロック -> do end 真のdo-endブロック f g do end 偽のdo-endブロック f do end
for-ofを用いて広義のRAIIを実現する方法を紹介し、JavaScriptでリソース管理を行うパターン3種を比較します。 タイトルはorumin氏の記事のリスペクトです。 RAIIについて RAII (リソース確保は初期化である) はC++におけるリソース管理方式を表す言葉で、デストラクタにより暗黙的にリソース解放処理を行うことでプログラマの注意力に頼らずにリソース管理を行うことができます。 C++やRustのRAIIの特徴は、専用の制御構文を持たずに、変数のスコープに基づいてリソース管理が行われることです。 // C++ RAII // スコープから抜けるときに自動的に解放される std::fstream fs; fs.open("/proc/cpuinfo", std::fstream::in);
次のページ
このページを最初にブックマークしてみませんか?
『Masaki Haraさんの記事一覧』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く