nashcft's blog

時々何か書く。

午前

これはブランチ運用をどーのこーのというのが昨晩あったようでこのあとアナウンスがありPRの受け入れ先も用意されてめでたし。

午後

なんかAndroid SDKのインストール時にライセンスへの同意がまだ済んでないよとのことでビルドが通らなくなってしまった。
${ANDROID_HOME}/licenses のファイルを持ってきたりしてもダメで、docker image 側の問題だろうなーという感じだったのだが Docker Hub の見方がいまいち分からずどこに Dockerfile があるのか分からなかったので Discussで報告して帰宅。
業務時間の3/4くらいあれこれやって結局解決できず、CircleCIのビルドが真っ赤なまま帰らざるを得なかったのでとても悲しい。
書いてる今投げた報告を見たら別の報告と merge されてて、やっぱ docker image に build-tools がインストールされてなかったようだ。とりあえずなんとかなりそう。

同居人が夕飯を作ってる間に包丁で指を強かに切ってしまい、応急処置をして様子を見てたのだがそれだけじゃダメそうだったので救急外来に行って診てもらった。
救急外来っていうと重篤な状態じゃないのに使っていいのかなーと躊躇ってしまう印象があったが、夜間外来とか時間外外来とも呼ばれているようでなるほどとなった。
あと時間外で担当できる科が病院ごとに日によって違うそうなので、近所で時間外受け入れをやっている病院の外来に直接電話をかけるのではなく #7119 に状況を伝えて適切な病院を紹介してもらった方が良いという知見を得た。

イベントが立て続けに発生し大変疲れた。これから夕飯を食べる。

日記的なもの

継続的になんかしらの文章を書くということをしようと思ったので日記的なものを書くことにした。

今日は先週から取り組んでいた、CIにCircleCI を使っているレポジトリを 1.0 から 2.0 に移行する作業の残りを片付けた。先週の時点で半分は移行が終わっていて、残りはフローががほぼ一緒だったので殆ど時間もかからず終わらせることができた。
一点だけ躓いて、回避したもののまだ解決していないことがあって、working_directory に指定した path を環境変数 CIRCLE_WORKING_DIRECTORY を使って呼んでディレクトリ移動などをしようとしたところ、job出力の表示上は想定通りの path になったにもかかわらず "No such file or directory" となってしまった。環境変数を使っていた箇所をハードコードしたら全く同じ path なのに問題なく通ったので現在は全てそのようにしている。

circleci.com

とりあえずそれ以外は上手くいってて、2.0でのconfig の書き方や workflow の組み立て方も理解したし、移行後のCI実行時間もかなり短縮されたのでだいぶ気持ちが良かった。

あとは細かい修正のプルリクをいくつか出して、残りの時間は Android とそのアプリ開発の概要に関するレクチャーを受けていた。

明日は Android アプリ開発の勉強をしつつ Danger を本格的にCIに組み込むタスクに取り掛かる予定。

eureka Meetup 04 -チーム開発ナイト- memo

6月末の

Pairsにおいて大事にしたいユーザ体験やプロダクトで大事にしている価値

  • テーマ: UX -> チームの作り方
  • 大事にするUX
    • 出会えること:
      • マッチングUU, メッセージUU
      • 誰でも迷わず使える
    • 安心・安全である: 24x365 監視体制

価値観

  • ユーザに対して真摯
    • don't be evil
    • ちょっとした不具合や触り心地の悪さを許さない
    • monetize < UX
    • マーケットリーダー: オンラインデーティングに対する印象に対する影響
  • 機能追加≠価値追加
    • 機能 < 提供価値
    • 仕様ないではなく課題への解決方法を考えるという文化
  • たくさん機能が欲しいわけではない
    • 減らす、磨く
    • 価値は何か?
    • 数字・ユーザが使う様子を見せる
  • 規律よりも規範
    • チーム数の増加: 10~12人超えたくらいでチームを分ける
    • 「語れる人」を各チームに必ず含める
      • 語れる人を増やす必要 -> 考えていることがバラバラに
    • 局所最適化した動き・考えに傾きがち
    • ビジョン・理念の浸透スピード < 人の増加
      • 意思統一の難しさ
    • やってること
      • 最初はチームリーダーを通していた
      • PMとしてチーム全体に投げかける
      • 全社会
      • 社内SNSで発信、お気持ち課題の提起、同じことを何回も言い続ける
      • 張り紙、意外と効果がある
      • 良いことはどんどん褒める
      • エモい話をぶっ込む
    • recap
      • プロダクトの芯をぶらさず伝える
      • 発信者が実践者としてやっていく

自己組織化された開発チームの作り方

  • 何かを始める時のポイント
    • 変えることを目的にしてはいけない。何故を伝える
    • 「何故」 -> 強いチームが必要 という流れのポエムを投稿
      • 熱量は大事
    • 自ら考え、小さく実践、フィードバックする
    • 自己組織化したチームを目指したい -> 会社の理念に合致するね
    • 小さく、正しく始める (問題点の見える化、フィードバック)
  • 全社を動かす時のポイント
    • 2人目のフォロワーが重要
      • すでにチームになっている
    • 経営課題にリンクさせる
    • 解決されると得られる基準にCXOを常に会話する
      • 価値を提供するための手段
    • 短期での結果を求めず中長期で課題を解決させる大局的な視座が必要
    • 会社のステージに応じて作戦を考える -> 画像の出典: elastic leadership
      • サバイバルモード
      • 学習モード
      • 自己組織化モード
    • 透明性大事: 十分な情報があれば自律的に動ける
      • みんなが見えるところで発信 (フィードバックとか) -> お互いで学び合うことができる
    • なんか楽しい・良さそう感を出していくことが大事
    • 外部の専門家を巻き込む
      • 全部自分でやらなくて良い
      • WHYを伝える努力、思いの代弁

スクラムマスター、プロダクトオーナーを両方経験して分かったこ

  • 何故チーム開発なの?
    • 一人でできることは小さい
  • scrumの具体的なお話
    • daily scrum
      • warmup (openingテーマ)
      • burndwon chartを見る: 単なる目安であって正確にやってはいない
        • 見積もりは1~2時間幅
      • 各自が話す (いつもの3つ)
        • 問題解決: みんなで
      • 5 finger: ゴールに全員で達成できそうかを評価 (1,2がでたら解決するためのアクションを話す)
      • あるある失敗談
        • 困ってるけどなんとかします (気合い): next actionは? 助けられることはない?
        • JIRAに乗ってないことをやった: 透明性を壊している. POへの確認は?
        • BCが落ちてない -> もう少し様子を見ましょう: 理由や状況をきちんと把握しよう
      • リファインメント
        • ?
        • ?
        • ストーリーポイントで素早く道もる
        • (次のスプリントなどで)開発できる状態に
      • その場で疑問が解消しなかったら即持ち帰り課題にして次の日までに調べてやり直し
      • 毎日にしてよかった点
        • PO <-> 開発チームの会話を毎日モテている
        • プランニングの時に慌てることがなくなった
      • 失敗談
        • ユーザへ価値を届けるための他の手段を議論できていない。価値にフォーカスして手段を議論する
        • POの要望がでかい -> 会話しながら小さく分割していく。本当に価値を届けられるものを最も小さい規模で MVP
      • SMで大事にしていること
        • 推測より会話 (齟齬の原因は推測)
  • Q&A
    • 24x365の監視体制: 開発じゃなくてカスタマーケアのチーム
      • チーム分けると顧客フィードバックに関する学びが薄くなるのでは?
      • 改善のためのチームを作ってとか体制を作ってる
    • 開発チーム内のロールだったりとか
      • ios x 2, android x 1 server x 3
      • インフラ? -> 専用チームがいて、開発チームと連携して活動したり

新チームで初スクラムして感じたチームの成長に大切なこと

  • 大切なこと
    • why and value
      • メンバー全員で議論して、回答を作り上げる -> インセプションデッキ
      • 認識統一
      • POから繰り返し伝えること
    • 選択と集中
      • 手広くやろうとすると崩壊
      • やってることを増やしすぎず着実に終わらせる
      • あるべき、 ありたい vs 現状
      • KPT -> Tryたくさん出てくる -> priorityをつける -> 重要なのから着実に終わらせる
        • 着実にやって成功体験をきちんと積む
  • Q&A
    • やっぱTry溜まっちゃうよね
      • Tryを推進するための責任を持つパーソンが必要では? 誰かがやってる、or 他のやり方
      • 推進はSMが行っているがどうするか考えるのは開発チームでやってる
    • why and valueを実践、定着させるためのワークショップ・お話など

#builderscon メモ: Haskellを使おう (Track B 14:30~15:30)

builderscon.io

speakerdeck.com

スライド見つつメモ読み返すとどこでついていけなくなったかがよくわかる 😇
最初は調べてメモの内容を充実させてから投稿しようと思ったけど現実的な時間でできそうにないしスライド読もうねという感想なので投げました

モナド周りは5月のJJUGで発表された↓のスライドがわかりやすかった記憶があるので読み直して勉強し直します…

www.slideshare.net

agenda

  • 話すこと
    • stack/ecosystem
    • 実行制御
    • IO処理
    • 外部パッケージの利用
  • 話さないこと
    • Haskellの抽象的なあれこれ

Stack

  • cabal-installに代わるbuildtool
  • 依存パッケージのローカライズ
    • cabalは全部globalな管理してたくさい
  • 最速でREPL
    • curlでインストール -> stack setup -> stack ghci
  • Stackage
    • package一覧
    • Hoogle (関数名/型名/型定義 (::型名) で検索)
    • doc (モジュール一覧、依存・非依存package)
  • buildポイント
    • ghc-options: -WALL @ *.cabal
      • 全警告表示
    • hlint
    • ghc-options: -threaded @ *.cabal
    • hpack
    • ghc 8.2.1
      • error表示がcolored

Haskellのコミュニティ

書籍が出る

実行制御

  • 順次処理: do
    • 操作を並べて書く
  • 分岐: caseなど
  • 繰り返し: リスト、Freeモナドなど再帰データ型を介した繰り返しは得意
    • map, foldr, mapM_
    • continue は filter
    • break は takeWhile
    • 手続き的なループは…
      • 再帰で同様な振る舞いを記述できる (loopを用いる)
      • Streamingライブラリを用いる (e.g. conduit)

I/O処理

  • 書けるけどそれほど得意でもない
  • appにおいてはほとんどの場合I/Oが主役
    • I/O処理ができないと利用価値が…
    • 利用価値のあるappを作りましょう
  • I/Oのノウハウを会得しよう
  • I/Oが可能な場所
    • IOモナドの中
      • e.g. main関数
    • IOをモナド変換子でラップしたモナドの中
      • a -> b -> … -> OtherMonadT Hoge (SomeMonad Foo Bar IO) z みたいな
      • lift
    • MonadIO型クラス
      • MonadIO m => a -> b -> … -> m z みたいな
      • liftIO
    • IOモナド
      • 入出力、mutable変数、例外やcatch
    • IOモナドがないとこれらの機能を利用できない
      • State, Errorなどのモナドはあくまで模倣
    • 書きやすいかというと…
      • >>= はcallbackを要求: callback hell…
      • doで隠す
    • モナド状の操作
      • 操作: 戻り値の型が Monad m => m a の形式のもの
        • putStrLn :: String -> IO ()
        • とか
      • 操作でないもの
        • unsafePerformIO :: IO a -> a
        • runState :: State s a -> s (a, s)
      • do記法にかけるもの
        • 操作に引数を適用した、Monad m => m a型を持つ式
        • 一つのdoブロックには1つのモナド操作しか書けない
        • 並べた操作がどう実行されるかはモナドによる
          • IOでは並べられた順に
      • do記法のコツ
        • 変数定義
          • let x = ... vs x <- ...
            • <-は操作を実行した結果を取り出して束縛
              • 操作を直接引数にできないので必ず <- で束縛してから使う
            • letは右辺をそのまま束縛

アプリケーションと状態

  • 状態の受け渡し
    • State, Reader
    • doブロックに書けるモナド操作は一つだけ
      • ウッ
  • モナド変換子
    • モナド m に操作を追加する
    • モナド m の操作は lift を経由して使う
    • runHogehogeT という命名でモナド m に戻す関数が存在
    • StateTモナド変換子
    • ReaderTモナド変換子
      • 読み込みだけでなく状態を表現できる
  • FWに現れるMonadIO

パッケージの選び方

  • Stackageの自分が使うLTSから選ぶ
    • Cのライブラリへの依存でハマることが多い (特にWindows)
    • ドキュメントをよく読んでおこう

#builderscon メモ: Antipatterns of Android app development (Track E 13:20~14:20)

builderscon.io

www.slideshare.net

AP 1: 古い本買う

  • 開発環境が古い
  • プラグインのサポートが終了している
  • android: java -> jarをクラスパスに放り込む
    • jarにリソースを入れたい、入らない
    • aarができる (.zipにすると見られる)
androidを知る1: Activity
  • 開発者はactivityを継承したクラスを定義していく
  • OSからいろいろな情報を受け取る: 画面の回転など

AP 2: 画面回転 -> android:configChanges

  • configChanges()は使わない

AP 3: 画面進む -> 戻るでたまに落ちる

  • activityの復元を考えていない
  • onSaveInstanceState()で保存
  • onCreate()で復元
  • onRestoreInstanceState() だとうまくいかない
  • OSが破棄するタイミングがマチマチ
    • 動作確認時は開発者向けオプション「アクティビティを保持しない」を設定する

AP 4: アクセストークン -> static変数に入れる…?

  • サードパーティでもやらかしてるのがある
  • Androidのプロセス: プロセスでJava (Dalvik) VM が起動する
  • 1 app: 1 proc
  • activityはいろんなappで起動、static変数はプロセス単位で持つ
  • 別アプリから呼ばれなくても…?
  • static変数: プロセス止まると消える
    • プロセスはいきなり止まる: activityの中断中 (backgroundにいる時) 止められることがある
      • PC appは最小化してもプロセスは死なない
      • でもちゃんと再開できる、がstatic変数は揮発
  • 永続化or状態をactivityに持たせる
  • 動作確認?
    • 開発者オプション「バックグラウンドプロセスを使用しない」

AP 5: UIをfragmentで -> 2つある -> android.app.Fragmentを使う

  • Fragment?
    • viewの生成と管理
    • activityはUIを提供するがOSとのやりとりがあったりして大変
      • activityに全部やらせると破綻する
      • 3.0からFragmentがviewの生成と管理をactivityから引き剥がした
    • android.app.Fragment
      • プラットフォームで提供
      • OSバージョンに縛られる
    • android.support.v4.app.Fragment
      • サポートライブラリで提供
      • v4: api Lvのこと (ただしLv14?)
      • 更新すれば新しい機能が使える
  • サポートライブラリ版を使いましょう

AP 6: 呼び出し元に処理結果を伝える実装をfragmentで

  • fragment処理をinterface経由?で渡す
  • NextFragment表示中に中断すると->callbackオブジェクトは復元できない
    • bundleに放り込めるのはprimitiveと放り込める条件を満たすオブジェクト
  • setTargetFragment()でfragment間の値を渡せる
  • getTargetFragment()で呼び出し元を取得
    • Fragment::onActivityResultを使ってなんたら

AP 7: iOS appのAndroid版つくる依頼 -> 見た目、操作感をiOSそのまんまにする

  • 下タブが悪いとは言えない
  • トップレベル項目が2つなら下タブ以外の表現で
  • 横スクロールしないのに > マーク
  • まずmaterial designに従ってデザインしよう
  • アンチパターンがいっぱい -> 知ってれば回避できる -> 勉強しましょう

Neo4jユーザ勉強会#11 に参加してきた

“Living Clojure” の読書メモが積み上がってる状態で書くのもどうなのというのはあるけど参加してきたので書く。殆ど読み終わってるけど日常的にブログを書くというかアウトプットする習慣が全くついてないよね…

jp-neo4j-usersgroup.connpass.com

ところで第1回以来の参加です。

お知らせ

タイムテーブルなどの説明。

Neo4j を MS Azure 上で動かす (workshop)

事前にAzureのセットアップをしてきて、この時間にNeo4jをインストールしてbuiltinのGUIで遊ぶということをした。
実際このGUIで遊ぶというのはNeo4jのサイト上のsandboxで触れるようなことをわざわざAzureに突っ込むという手間をかけた上で行うというもので特にAzureが絡んでくることの意義が見出せず、MSの協力があったためにどうにかしてMSと関連づけようとした苦しい何かを感じるものだった。

Graph Connect 2017 Europeの参加報告

登壇者の方がGraph Connect 2017 Europeに参加してきたということで、そのカンファレンスとkeynoteの紹介という内容。Graph Connectの発表資料は全部サイト上で録画を視聴できるし、スライドもslideshareに上がっているということでありがたいということがわかった。
keynoteは、まあ国際カンファレンスのkeynoteを駆け足とはいえ20分で読んだり説明したりしながら紹介しきれるわけがないよね、ということで半分いかないくらいで打ち切り。keynote自体はあとで全部読んでおく。紹介されていた範囲は直近の大きな事例紹介みたいな内容で、最近はknowledge graphがアツいとか何とかだった気がする。eBayが購買アシスタントのbotの裏側をNeo4jでやってて、ユーザへの質問の回答をパラメータとしてクエリを作って商品のレコメンドをしてる、とかそんな。

openCypher Meetup in Londonの参加報告

Neo4jのクエリ言語だったcypherがいつの間にか独立していて*1openCypherというプロジェクトになっていた。それで定期的? にmeetingを開いて課題をこなしたり議論したりしているらしい。報告にあったLondonでの会は2回目の開催だそうで、次は秋頃にNewYorkで行われるそう。
openCypherとして独立したことで汎用的なグラフ探索クエリ言語として様々なプロダクトに実装されるようになっており、プロジェクトのページで紹介されている。
帰宅してから適当に検索したら当日の流れが公開されているのを見つけた。Prologで実装とか強い事が書かれている。
あとこれか一個前の発表の中でジェンダー的にアレな発言があって渋い顔になった。

LT

上記の報告発表の後で軽食とビールが振舞われて、それを食べたり飲んだりしながらLTを聞いた。MSの予算的なアレで潤沢な食事とビールが提供され、ビールは1人あたり500ml瓶2.5本分あるよとのことでMS様様という感じだったが私は普段アルコールの類を飲まないので1本で限界だった。

グラフ可視化ライブラリまとめ

D3.js, GraphViz, Cytospace, Linkurious (sigma.js), Keylinesの出力を比較した感じ。
Cytospaceが使いやすさと出力の見た目的にオススメだそう。後↓のスライドいいよとのこと。

www.slideshare.net

Neo4jのStored ProcedureとFunctionの紹介

タイトル見たときに何だと… となったけど、Javaで処理を書いたものをjarとしてNEO4J_HOME/plugin/に置いておくとcypherからCALL foo()という感じで呼べるよということだった。実装は去年から入ったとのこと。Documentも見つけたのでこの土日で読む。
Procedureやfunctionは以下の3つに大別されるとのこと:

  • Neo4j builtin
  • APOC (Awesome Procedures On Cypher)
  • User defined

APOCはthird partyの実装で2009年から存在していたのだが2016年にNeo4jがprocedureを導入するまでずっと日の目を見なかったとかそんな道のりを歩んできたというエピソードが面白かった。これには全部で320以上のprocedureやfunction実装されており、一部はbuildinと被るものもあるが大体はこれの中から使いたいものが見つかるレベルだそうな。

居酒屋

元居酒屋店長で今はkusanagiエヴァンジェリストをやっているという人のグラフデータモデルいいですねというお話だった。気がする。この頃には酔いが回ってきててちゃんと内容覚えられなくなってきてた。

日本OSS推進フォーラムの紹介

正式会員と政府からもらったお金で夜にメイド喫茶で飲み会をする組織という理解をした。政府からお金は出てないかもしれない。中韓と合同の会議? への渡航費諸々は自腹って言ってたから飲み会も自腹かもしれない。

全体的な感想

第1回の勉強会に参加した時にも書いたけどベンダのご紹介感の強いというか、それ使って開発してるとかそういう雰囲気のある発表はprocedureとfunctionの話くらいだったしもっと何とかなんねーのという感じもある。グラフデータベースとかNeo4jとか学びたいという人が参加しても大した収穫は得られないし各自やっていくとかtwitterでワイワイやるとかの方がずっと学びを得られると思った。

*1:Neo4j 2.2 くらいから追ってなくて、その頃cypherはまだ「Neo4jのクエリ言語」だった

Living Clojure 読書メモ

Clojure入門のために “Living Clojure” を読んでいる。
読みっ放しにするのも何なので、適当なところでメモをまとめて記録しておくことにした。

Preface

Chapter 1. The Structure of Clojure

Simple Values

  • Decimal以外にRatioによる表現がある
;; decimal
3.14

;; ratio
1/3

Collections

;; List: 
'(1 2 3)
;; Vector: 
[1 2 3]
;; Map:
{:key1 "value1", :key2 "value2"}
;; Set: 
#{:foo :bar}
  • Listの区切りはコンマではなく空白
    • コンマも無視されて空白として解釈されるので使用はできる
  • consはList以外に使うとListにキャストされるっぽい ((cons 1 [])の返却値が(1)だった)
  • nthlastといったCollectionの先頭以外の要素を取得する関数はListとVectorの両方に使えるが先頭からのtraversalが必要なListよりもindexでアクセスできるVectorの方がパフォーマンスが良い
    • indexによる要素へのアクセスが必要な場合はVectorを使う
  • 全てのCollectionはimmutableでpersistent
    • persistent? -> “… these collections will do smart creation of new version of themselves by using structural sharing.”
  • conjはデータ構造によって要素を追加する場所が異なる
    • Listなら先頭、Vectorなら末尾
  • Mapでvalueを取得するときはgetを使う方法とkeyを関数として扱う方法がある
    • keyを関数とする方法がよりClojure的だが場所によってgetを使うこともある (明示のため)
  • Setに対する集合操作 (union, intersection, difference) を呼ぶ際は clojure.set/unionというように記述する

Binding

  • 変数に値をバインドする的な方法は (def foo "value")
    • 厳密にはいわゆる変数とは違うけどそれについてはChapter 3で
    • global variable的な立ち位置っぽい
  • letだとletの中だけアクセスできる
(def foo "foo")
foo
;; -> "foo"

(let [foo "foo2"
      bar "bar"]
    [foo bar])
;; -> ["foo2" "bar"]

foo
;; -> "foo"
bar
;; -> CompilerException java.lang.RuntimeException: Unable to resolve symbol: bar in this context...

Functions

  • Anonymous functionのfnがあって
(fn [<params>] <body>)
  • defn(def some-fn (fn [<params>] <body>))の略
(defn some-fn [<params>] <body>)
  • Anonymous functionは省略っぽい記述がある
    • #(<body including params>)
    • パラメータは% (複数ある際は%の後に数字をつける) で表す
;; Textの例
(#(str "Off we go" "!" " - " %1 %2) "again" "?")

Namespace

  • (ns foo.bar)で作成(と切り替え、はREPLのみ?)
  • *ns*がnamespaceを返す
  • require
    • 引数にnamespaceだけ: (require 'clojure.set)
      • Fully qualified namespaceでアクセスできる e.g. clojure.set/union
    • as: (require '[foo.bar :as fb])
      • (fb/some-fn) とかそんな
    • refer all: (require '[foo.bar :refer :all])
      • 呼び出したnamespaceに対象のnamespace内のすべてのsymbolをロードしてsymbolだけでアクセスできる
      • symbolの衝突とか由来が分かりにくかったりするのでやたらと使わない方が良い
  • userequire:refer :allしたのと同じ、だけどrequire:refer :allで書いた方が良いっぽい

Chapter 2. Flow and Functional Transformations

  • 用語 (本書を読むにあたって十分なレベルで)
    • expression: 評価されて結果が得られるコード
    • form: 評価してエラーが返ってこないexpression

Logic Tests and Flow Control

  • =はequalityを検査している
  • Equality of Collections
(= #{:a :b} #{:a :b})
;; => true
(= #{:a :b} [:a :b])
;; => false
(= #{:a :b} '(:a :b))
;; => false
(= '(:a :b) [:a :b])
;; => true
  • empty?seq

※追記 (2017/02/26) ※

Twitterで各collectionはSeqableを継承したIPersistentCollectionを実装しているという指摘をいただいて、Clojureソースコードを読み直してみると確かにそうだった。継承や実装をちゃんと見ていなかった。
しかしそれでも何か腑に落ちないものがあり、もう一度よく読み直してみたらそもそも自分が勘違いをしていたことがわかった。
つまり、最初私は各collectionが共通のinterfaceか何かを持っていて、「それの振る舞いとして」seq関数が実装されており、それを介してsequenceを得ることができると考えていた。
だが実際はseq関数 (の実装) とcollection及びそれらが持つ共通の抽象構造は分かれていて、seqcore.cljで定義された、これを通してcollectionをsequenceに変換する、構造とは独立した関数 (実際に処理が実装されているのはRT.java?) で、各collectionは単に遡っていくとSeqableを実装している構造体で、そのためにseqを通してsequenceにすることができる (RT.seqを見ると厳密にはこの説明は正しくないのだけど、簡単のため)、ということのようだ。

というかきちんとサンプルコード見れば(seq coll)となっているのだからseq関数自体は構造から独立してるのわかるじゃん…

※追記終わり※

  • someの返却値
    • 第二引数のcollectionの各要素に対してpredicateが最初に返すlogically trueな値
    • nil (predicateを満たす値がなかった場合)
  • someの第一引数 (predicate) にSetを使うこともある
    • logically falseな値をSetに入れると破綻する
  • condcase
    • マッチするものがない場合、condnilを、caseIllegalArgumentExceptionを返す
    • caseはdefaultを設定できる (リストの要素が奇数の場合最後のexpressionがdefaultとして評価される)

Functions Creating Functions ~

  • partial
    • curryingじゃなくてただの部分適用の話…?
  • 関数合成はcomp

Destructuring

  • :asで元々の構造を保持できる
  • :orでデフォルト値を設定できる
  • [{:keys [param1 param2]}]という形での指定が一般的

Recursion

  • looprecur
    • loopを用いると初期値の隠蔽ができる
    • recur再帰呼び出しに使われる (loopを使ってるとloopの開始地点から再帰処理を開始?)
  • recurはstackを積まないようにしてくれる
    • なんか条件がありそう (末尾再帰のみとか)

The Functional Shape of ~

  • mapreduce
  • 副作用が発生するタイミング
    • doall
  • mapには複数のcollectionを渡すことができる
    • それぞれの同じindexの要素を用いて関数を実行する
    • 素数が少ない方に合わせる
  • complement: 関数を引数にとり、反対の論理値を返す関数を返す
;; Vectorから`nil`を取り除く: 
(filter (complement nil?) [:a nil :b :c nil :d])
;; => (:a :b :c)
;; 以下も同じ挙動
(remove nil? [:a nil :b :c nil :d])
  • for
    • 複数のcollectionを与えるとネストする
    • :letによってfor内のlet bindingができる
    • :when <condition>を与えると条件を満たす時のみ評価が実行される
  • flatten
  • into
  • partition
    • partition-all
    • partition-by