個人事業主になったので真面目にアウトプットしてみるブログ

フリーで顧客の会社に潜り込んでAndroidアプリつくって、とりあえず食っていけるようにアウトプットを増やしていくブログです。

新しい客先で感じたことメモ

  • すでにKotlinが適用されていると、すでにいくつかの暗黙的なルールができているので、気になったら質問して認識を合わせる必要がある(多分Javaではそんなことがなかったので、言語自体の文化の成熟の問題なのだろうか?)
  • アプリの機能(画面遷移、表示、非表示条件)を知らないと改善すべき問題が見えてこない(知識の醸成が必要になるのですぐに良い意見が出せない、がバイアスの元にもなるので無駄に知らない方が良い事もあって中々難しい)
  • チームのコードレビューに関する暗黙的な認識差が割とあって、曖昧なものは割とはっきりさせないと、変な空気を読んだ対応になるので作業の理由に矛盾が生まれる
  • スクラムで施策を模索する段階から関わらせてもらえると楽しい(が知識不足がネックになる、知らないことははっきり知らないと言わないと伝わらない)
  • メモ魔になるべし
  • 別の案件で培ったものは無駄にならない
  • 開発は楽しい
  • 問題は何かを見つけるのが楽しい(問題の認識摺り合わせが難しいが)
  • 周りにやる気がある人がいると負けんきで自動的にやる気が湧いてくる(It's automatic!)
  • ここで何が得られるのか、今あるチャンスはなんなのか、見極めが必要(英語力とか?世界に目を向ける視点とか?プロダクトを効率よく進化させる動き方とか?)
  • 開発は難しい
  • プラットフォーム間でもコミュニケーションは必要だよね
  • チームは違ってもプラットフォーム内でのコミュニケーションも大事だね
  • 環境がやる気になるのを再確認
  • 有言実行していきたい

  • 開発は楽しい

  • 開発は難しい

言語化できないもの

今年一年振り返って、ツイッターで呟きながら
言語化しづらくてモヤっとしているものを書き連ねていきます。
内容はないです。



生きづらさ
- お金の稼ぎ口の問題
- プログラマとしての興味の指向
- エンジニアとしての成長

Androidについて
- LiveDataとDataBindingは未来じゃない
- ViewModelのLiveDataのコードがスッキリするやつを真面目に考える
- Android Jetpack Composeがなぜ良いか
- AndroidのView(RecyclerViewなど)は嫌いだ
- こんなにAndroidアプリの制作のノウハウが増えていっても全然簡単になってないなー

プログラミングについて
- 最近頭の中でフワフワ思っている、Composableなプログラミングについて

お仕事
- 良い意味でチームにハマる時・ハマらない時
- 期間が製品品質の向上をジャマする
- 評価精度に思う疑問・相対的評価を統計学的に寄せるインセンティブに関する問題とか、どういう式使っているかは個別に依存しているから言及しづらい
- お仕事をするフリをする人々、でも仕方ないよなーとも思いつつ
- 学習的無気力と戦いたい(無気力の壁への恐怖)
- 知識のバックグラウンドが異なると噛み合わない(持っている課題感、取り組もうとしている課題が違う)
- 付箋(Post It)は最強のお仕事のお友達!!
- フリーランスとしての組織への向き合い方

Androidプログラマの関数型プログラミング勉強振り返り

関数型プログラミングがわからなかった。

  • 遅延評価がわからなかった(なにそれおいしいの?)
  • 純粋関数がわからなかった(こわせるよ?)
  • 参照透過性がわからなかった(オブジェクト指向のストラテジーとかに似てる?)
  • 副作用がわからなかった(結局副作用ってなんのことを指すの?)
  • ラムダがわからなかった(関数の参照・・・コールバックだよね?)
  • 高階関数がわからなかった(メソッドチェーンで書くシーケンシャルな処理だよね?)
  • イミュータブルがわからなかった(コンフリクトおきない?)
  • 状態がなくなるがわからなかった(結局状態は必要では?)
  • 宣言的がわからなかった(どれも宣言的といえなくはない?)

今はなんとなくわかる。

  • 遅延評価は、今、その処理の実行をする必要ないけど今書ける処理として書いておくやつ。書かれている場所と実行タイミングが異なって、メモリに優しい書き方。けどやりすぎる評価されるタイミングが重なって辛いとか、色々ありそう。
  • 入力が同じだったら純粋関数は結果が変わらない関数。自分でそうつくらないといけない。なので関数外のスコープの変数を参照してはいけない(やらないと無理な時もあるかも)。純粋関数もJavaにかかればあっという間に壊せる。なので出来るだけJavaよりはKotlinを選んで、末端までイミュータブルなデータを利用する。一応Stringも普通に扱えばImmutable。data classは積極的に使おう。普通のclassのインスタンスを純粋関数に代入しては壊れる元。
  • 透過参照性は組み替えても処理の全体的な性質が変わらなようにできるようなもの。純粋関数のみで構成し、うまく使うことで戦略的な組み替えが可能になる。べつに戦略的につくらなくてもいい。純粋関数でボトムアップとしてつくれば結果的透過参照性のある処理のかたまりができる(だよね?)
  • 副作用は純粋関数以外のもので構成され、他影響を与えるもの。つまりクラスのメンバ変数の参照や代入によって他の処理、次の処理の結果がインプットは同じなのに変わる可能性があるもの。同じスコープ関数の外にある変数に値を再代入することを破壊的代入、もしくは自殺行為という。ただしクロージャ的なものはスコープ外で宣言しないとできないし、クロージャへの参照のスコープを限定的にすれば、その関数(スコープ)の外からみれば純粋関数。外から見て純粋かというのは大事かも?DBやFileのIOや通信結果も副作用といえばそう。その失敗や一定の値を返さない事によって他の処理の期待値が壊れて不協和音、システムの破壊につながるような処理は副作用。適切にリトライなり、冪等的にロールバックしたり、結果をエラーハンドリングに流すなりして、全体的にはあらかじめ決められた処理として動いていれば問題ない。イメージ的には正の数の時はこの関数、負のときにはこの関数、結果的にプロットされる全体像がみえていればいい。みたいな感じ。かな?
  • ラムダは遅延評価をさせるもの。もしくは遅延評価を前提にした透過参照的に宣言された大きな処理、再利用性の高い処理への組み込み単位。カリー化などを使って部分適用を利用しながらラムダ内の評価タイミングを遅らせながらラムダを評価する材料をあつめるみたいな段階的なことも可能。変数のように扱えるので、プログラムの表現方法が格段にあがる。ただし評価される時のオーバーヘッドが通常の処理よりあるのでJavaやKotlinにはあるので注意。必然的な部分にとどめないともっさりするかも?関数が第一級、参照として扱えるみたい話もラムダのこと。
  • 高階関数は関数が引数だったり、返り値が関数になるような関数のこと。JavaやKotlinだとラムダのこと。ラムダを引数にしたり、ラムダをかえすようなものをいう。カリー化は後者の良い例で、filter/map/zipみたいなやつが前者の良い例。前者は遅延評価を前提としていて、実際には必要になった時だけそのラムダが評価される。別に作っていけないわけではないので必要だとおもったら作るのが普通。別にモナドには高階関数がいくつかあることが条件にあるけどモナドを作る必要はない。(モナドはしらないでもプログラムはある程度できる、スタイルの問題だったり、作らなくても自然とつかっていたりするかも)
  • イミュータブルはどんなタイミングでみても全く同じであること。コレクション(リスト、マップ、セット)や構造体(すべてfinalでメンバ変数を定義したDTOみたいなもの、data classなど)。その値を変更する場合は必ず別のインスタンスにシャローコピーを施しながら、変更したい値だけを入れ替える。data classでいうとcopy関数で簡単にそれが可能。イミュータブルでないものは、addやremoveが可能なコレクションや、varで宣言されたフィールドが存在するclassなど。ただし。
val printlist: (List<Int>) -> (() -> Unit) = { list -> {
    println(list)
} }
printlist(mutableListOf(1, 2, 3))()

みたいにListに対してMutableList(変更可能なリスト)を渡すことができるので、Kotlinでのリストは実質イミュータブルなものはない。リードオンリーになるので、正確なイミュータブルなリストを使いたい場合はEclipse Collectionsを使うと良いらしいよ。

残り二つは時間の都合でまたこんどー。

Android界隈でKotlin Coroutinesの登場によってRxJavaが不要と言われる原因とそれに対する反論

ちまたでKotlin Coroutinesの登場でRxJavaが不要になりつつあるという噂が流れているみたいなので、どう言う状況なのかまとめてみました。

さっき書いたこの記事

pooh3-mobi.hatenablog.jp

まぁ論拠は薄いし、そんなデータそろえてって、みんながすげー納得するようなことを一朝一夕でやるなんて、データサイエンティストさんに失礼ですよ。マナー違反ですね。 ということで、とりあえず前提としてRxJavaは通信ライブラリであるRetrofitとセットで広がったものでリアクティブプログラミングをやろうと思って使っていた人はほとんどいなかった!(衝撃的事実)という前提で話を展開していくとします。

続きを読む

FRPとReactive Extensions

FRPとReactive Extensions

Rx(Reactive Extensions)はFRPではないとい批判を聞く事がありますし、オライリーから出ているRxJavaの書籍(英語版)の説明にも似たようなことが書かれています。

参考:「Reactive Programming with RxJava: Creating Asynchronous, Event-Based Applications」

しかし一方で広義ではそれらもFRPを実現するためのスタイルの一つとして認める話もあります。FPR界隈からみるとRxは厳密性には欠けるが、FRPからインスパイアされたものであるという表現が正しいという見方もあるようです。

続きを読む

RxJavaは通信系ライブラリ(Retrofit)とセットだったという事実について

何言ってんだお前。 RxJavaはリアクティブプログラミングのためのライブラリであって、通信系のライブラリじゃねーよ。

はいごもっともとです。

それに・・うん、してった。

でなんでこんな話をしたかというと、RxJavaでリアクティブプログラミングなんかやろうとする人が少なかったんじゃないかという仮説が突然浮かんだので現実を見つめようとおもいました。

続きを読む

関数名、メソッド名でgetXXXがダメな理由

ダメである理由

getという単語は、その単語自体がその中で何をしているのかを隠してしまうので、容易に誤解が発生してしまいやすいこと。
・同じオブジェクトからは同じ値が返ってくるという勘違いが発生する恐れがある
・一部のおじさんにはgetter/setterもつ、特異なクラスをイメージさせてしまう
 →別の問題へ派生する可能性が出る:必要もないのにsetを用意しマルチスレッドで扱われるときにその邪悪さの効果を発揮する。すなわち複数で参照され得に参照するスレッドが異なっているときに、setを使ってしまう事で、別のスレッド側ではたまに起きる(たまたまタイミングが一致したときだけ)のような、発見が難しいバグとなって現れる。

よく言われる代替案

・単純な参照ではない場合
 →load/fetch/find/request/など実際の処理がイメージしやすい命名を選ぶ
・単純な参照の場合
 →System.currentTimeInMillis()のように直接参照しているようなイメージになるようにする
 or→finalかつ非privateな値として宣言しgetterをはさまず直接参照する

getしか使いようがないが、getをそのまま使うと誤解が発生するケースの代替案
・言葉としてgetしか使いようがない場合、オンメモリ上の参照でNullが発生する可能性がある場合
 →getXXXOrNull()
・言葉としてgetしか使いようがない場合、対象の存在がオンメモリ上ではなく外部に依存していて、Nullがあり得る場合
 →getXXXIfExist()


まとめ

絶対に使わないとするとすごく難しい問題が出てくる。しかしできるだけ防ぎたい問題である。