Runner in the High

技術のことをかくこころみ

プログラミング

redigoを使ったPubSubアダプタの実装

自分が開発しているgo-cleanarchitectureの中でドメインイベントのPublisher実装としてredigoを使ったPubSubアダプタの実装を用意したが、思ったよりもredigoを使ったRedisのPubSub周りに関連する実装があまりネットに転がっていなかった。 domainsパッケー…

VimでGitの操作環境を整える

自分はvim-fugitiveとvim-flogを使っている Plug 'tpope/vim-fugitive' Plug 'rbong/vim-flog' fugitiveだけでもgit logは見れるが --decorate や --graph などのコマンドを使っても色がつかないのでコミットログを見ることに関しては若干微妙。 ログを見る…

database/sqlとdatabase/sql/driverの関係性に学ぶインターフェイス設計

golangのdatabase/sqlには設計に関するドキュメントが用意されており、これが興味深い。 ドキュメント自体は非常に短い。以下のリンクでサクッと読める。 golang.org 中でも個人的に印象的なのは以下の説明で、ここからgolangにおけるdatabase/sqlの設計思想…

makeのlengthとcapacityについて、それからbytes.Bufferのアロケーション処理速度について

izumisy.work 上記の記事をstackoverflowで質問したら回答がついた。 stackoverflow.com 結論から言うと自分はmakeの使い方を間違えていて、makeの第3引数にあたるcapacityを省略してスライスを作成するとそこには空データが埋まってしまうとのこと。 なので…

リテラル値でmakeしたらヒープに乗らなくてアロケーションの回数は少なくなるんじゃないか?という実験

goコンパイラの最適化によって、可変長配列であってもリテラル値でlength指定されていればコンパイルする時点で確保するデータサイズが決定し結果的にランタイム時にアロケーションを発生させなくなるのではないかという仮説。 テストコード package app imp…

io.Readerで先頭Nバイトを読み捨てる

package main import ( "io" "io/ioutil" "strings" "os" ) func main() { a := strings.NewReader("123456789") r := io.LimitReader(a, 5) t := io.TeeReader(r, ioutil.Discard) io.ReadAll(t) io.Copy(os.Stdout, a) // 6789 }

ioutil.Discardとio.CopyNでメモリアロケーションせずデータサイズを判定する

ioutil パッケージに Discard という /dev/null 的な io.Writer が用意されている。 最近これを使うタイミングがあったのでメモ。以下のようなコードがあるとする。 package main import ( "fmt" "io" "io/ioutil" "strings" ) func main() { a := strings.N…

net/mailパッケージだけでもメールアドレスのバリデーションはできる

stackoverflow.com こんな感じで使える。 package main import ( "fmt" "net/mail" ) func main() { addr, err := mail.ParseAddress("izumisy.test@example.com") if err != nil { panic(err) } fmt.Println(addr.Address) // izumisy.test@example.com } …

deferで参照している変数のポインタを更新しても参照は変わらないっぽい

こういうやつ type Closer struct{ Value string } func (c *Closer) Close(id string) { fmt.Printf("Closed(%s): %p\n", id, c) } func newCloser(c *Closer) { n := &Closer{Value: "aaa"} fmt.Printf("New: %p\n", n) c = n } func main() { c := &Close…

フロントエンドアプリケーションにおいて状態をどこに置くべきか論

後学のために自分の考えていることをまとめてみる。 考えられるパターン これまでの経験から以下4つのパターンがある。 ローカルStateでprop-drillingする ローカルStateかつイベント経由でデータ交換をする グローバルStoreとローカルStateを併用する グロ…

Elmにおける比較処理の高速化テクニック

ここで触れられてた話がおもしろいかったのでざっくり紹介 discourse.elm-lang.org 文字列比較はcase文のほうが早い(ことがある) これは遅い ensureNonBreakingSpace : Char -> Char ensureNonBreakingSpace char = if char == ' ' then nonBreakingSpace …

Elmにおけるビルダパターンには後方互換性というメリットがある

Elmにおけるビルダパターンというのは以下のようなインターフェイスを指す。 -- setXxxのような関数をパイプでつないでいく雰囲気のやつ Button.new |> setPadding 10 |> setBackground "blue" |> setLabel "next" |> view このインターフェイスの優れた点は…

elm-firestoreにおける型安全なパス組み立ての設計

elm-firestoreのパス組み立て周りの実装を型安全な設計にしてみたのでその話。 github.com Firestoreにおけるパスの仕様 まず大前提としてFirestoreにはリソースの場所を示すパスという概念があり、ざっくりパスは以下のようなルールに基づいている。 ルート…

elm-firestore v10.0.0をリリースした

引き続きチビチビと作り続けていたelm-firestoreだが、とうとうv10をリリースした。 I finally have just rolled out elm-firestore v10.0.0! It has Query opertion support and fixes interface of transaction-related functions. Plus, integration test…

elm-typedパッケージを使えばもっと型で仕様を表現できるかも

elm-typedというパッケージを作った。詳しくは以下のGithubのREADMEに書いている。 github.com パッケージ自体が根本的に実現したいことはPunie/elm-idとかjoneshf/elm-taggedあたりとほぼほぼ同じ。プリミティブ型をそのまま使わず型エイリアスでもなく、プ…

ScalaではIntとStringを比較してもコンパイルエラーにならない

社内で以下のScalaコードがコンパイルエラーにならないというのが盛り上がっていた。 println(1 == "a") // コンパイル通るし結果はfalseになる 普段ElmとGoばっかり書いている&Scalaのことをとりあえず型に厳しい言語だと思いこんでいたこともあり若干意外…

Elmアプリケーションにおけるモジュールレベルでの詳細設計

Elmアプリケーションで比較的モジュール多めなアプリケーションの機能開発をするときに同僚とトライしている手法について。 言語的なElmのテクニックみたいな話ではなく、どちらかといえばもっと抽象的なハナシ。 1. 画面からざっくりとモジュールを見つけ出…

elm-firestoreでJSを1行も書かずにElmアプリケーションでFirestoreを使う

この記事はElm Advent Calendar 2020の8日目の記事です 今年の春頃からコツコツと個人開発のアプリケーションで使うためのElm用Firestoreライブラリのパッケージを作っていたので、その紹介をします。 github.com できることはREADMEに書いてあるとおりで、…

mercari/datastoreがDistinctOnメソッドをサポートした

先日PRを出していたものがマージされた。 github.com GCP DatastoreのDistinctOnは履歴系テーブルを触るときに便利で、例えばチームごとのログイン履歴を保持するLoginHistoryというカインドに対して「全チームの最新のログイン履歴を取得する」というクエリ…

ElmでCodecを用いてエンコーダ・デコーダの実装をケチる

この記事はFringe81 Advent Calendar 1日目の記事です。 Elmでアプリケーション開発をしているとほぼ100%出現するのがエンコーダ・デコーダの実装。 基本的に両方セットで実装することが多いが、データ構造が共通であればCodecと呼ばれる類の機能を提供する…

2020年末Rustlang環境構築

以下をやるだけ # インストール&初期セットアップ $ brew install rustup rust-analyzer $ rustup-init $ rustup update # プロジェクト作成 $ mkdir your_own_rust_project $ cd your_own_rust_project $ cargo init --vcs git --bin # rust-analyzerを使…

ElmでサードパーティーなUI系モジュールを使う際にはTEAを前提にしたインターフェースでラップする

Elm Packagesで公開されているモジュールの中にはTEAでいうところのviewやmodelしか提供されていないものがあったりする。 これがコレクション系モジュールだとか関数単位での機能提供が目的のモジュールであればまだ問題ないが、UIを提供するタイプのモジュ…

BtoBなソフトウェア開発における必読書3選

BtoBなソフトウェアの開発において業務知識なしにシステム設計をすることはほぼ不可能に近い。 これまで、業務支援系のシステム開発はSIer企業たちのお家芸であったが、近年ではWeb系のベンチャー企業やスタートアップであってもこれまでSIerが担っていたよ…

isucon10に出て予選敗退した

iguchi1124とhayashikunとisucon10に出た。一番伸びたスコアは1300くらい。 やったこと 覚えていることベースでやったことを書いてみる。 自分が覚えているのは基本アプリケーションサイドの変更ばっかり。 マシン構成の変更 hayashikunとiguchi1124がAP2台+…

Elmアプリケーションにおける型と抽象化手法

Elmは機能を絞った言語であるためScalaやHaskellのような高度な抽象化は言語機能上できないが、使う使わないに関わらず知識として「やれること」「やれないこと」を知っておくと、コード表現に幅が出る。 Extensible Record ざっくり言うとレコードのプロパ…

BigQueryのDATE関数とタイムゾーン周りの挙動

よく分からんところがあるので整理した。 SELECT date("2020-7-1T23:59:59+0900", "Asia/Tokyo") as tzDateWithTzString, date("2020-7-1T23:59:59", "Asia/Tokyo") as dateWithTzString, date("2020-7-1T23:59:59+0900") as tzDate, date("2020-7-1T23:59:5…

Interpreter Pattern in Elm: 副作用をテスタブルにする

Elmは純粋関数型プログラミング言語なので基本的にはアプリケーションを構成するすべての関数はテスタブルであるが、唯一Cmd型だけはテストすることができない。 たとえば以下のようなupdate関数においてPersistToStorageのメッセージが渡された際に必ずスト…

elm-multi-waitableで非同期処理の完了待ちをModelに表現する

Elmアプリケーションにおいて非同期処理の完了待ち実装をいい感じにするelm-multi-waitableというモジュールを公開した github.com 内部的には状態遷移のタイミングでデータを受け取って保持するステートマシンのようなものだが、これを使うことでフロントエ…

nvmやrbenvを遅延ロードさせる

nodeとかrubyとか特定のコマンドを使うときまでバージョンマネージャのローディングが遅延できたらなー思って調べてみたら、alias/unaliasを用いて遅延ロードっぽいことをやるテクニックを知った。 例えばnvmは以下のようにnodeやnpmなどのようなコマンドが…

Intellij IDEAのVMオプションとVSCodeの設定をイジってフリーズを減らす

去年末にお金をケチって買ったiMac 2019(Core i3 3.6 GHz, 8GB)でIntellij IDEAとVSCodeを起動していると、文字の入力もできないくらいレインボークルクルが頻発して仕事どころじゃないことがここの所よくあった。 数年前に買ったThinkCentreで動かしているU…