コミュニケーションが下手であることを自覚することのメリット。壁に立ち向かう時の心構え。
Rustの構造体や列挙型に関するメモ、Isabelleの定数畳み込みと定数伝播に関するメモ、チームのマネージャー・マネージメントに関するメモ。
diary
communication
日々繰り返し、このブログで、コミュニケーションについて語っているが、ふと周りを見ると、いくつか気づいたことがある
- コミュニケーションについてそれほど真剣に悩んでいる人が少ないこと
- コミュニケーションがたいていの人が下手、もしくは下手なことに無自覚
- お願いと相談の区別すらつかない
- 同僚を子供か囚人のように扱っている人がいる
- コミュニケーションをあえてやろうと挑む人が少ない
- コミュニケーションをうまくやろうとする人が少ない?
だからと言って自分のことが免罪符になるわけではないが、 自分は、自分がコミュニケーションが下手であることに気づき、どうすればよいか悩み、開発にはコミュニケーションが必要不可欠だから敢えてやらねばならない、そしてうまくやらねばならないと活動しているのだなぁと気づいた。
how to handle wall(barrier)
壁に対してどう立ち向かうか、というたとえ話をふと思い出した。 (どこ出典かわからない。ググってもヒットしなかった)
- 壁の前で跪くか
- 壁を打ち砕くか
- 壁をすり抜けるか
これがどういう話だったのかを思い出せないのだが、自分で今これを解釈するのであれば、 壁の前で跪くユーザーに寄り添い、壁を打ち砕かんとする創業者に耳を傾け、エンジニアは壁をすり抜けろ、ということになるのであろう。
今日の勉強
rust
pp.100-110
5章
- implの関数(メソッドの話をしている)には、自動参照および参照外しがある
- C++のようなオブジェクトに対して直接でもオブジェクトのポインタに対しての区別をユーザーが行うのは不要である
- コンパイラがオブジェクトのシグニチャに合致するように自動でオブジェクトに以下のいずれかを付与する
&で読み込みのみか&mutで書き込みもか*で所有権を奪うか
selfを自明な受けてという- これのおかげで自動参照及び参照外しが有瀧
- メソッドの受け手に関して借用が明示されない、というのが、所有権を実際に使うのがRustにおいて簡単である大きな理由
- implの関数で、複数の引数(
self以外に追加する)にすることができる - 関連関数
- implの別の有益な機能
- selfを引数に取らない関数
- 関数でありメソッドではない
- なぜなら対象となる構造体のインスタンスが存在しないから
- e.g., 新規インスタンスを返すコンストラクタなどがある
::という記法を使う。- この記法は関連関数とモジュールによって作りだされる名前空間両方に使用される。
- implの別の有益な機能
- 1つの構造体に対して複数のimplブロックを作れる
- 分けることが有用になるケースは10章で扱うジェネリック型とトレイトの議論の中で表れる
- まとめ
- 構造体: 自分の領域で意味のある独自の型を作成できる
- その使用: 関連のあるデータ片を相互に結合させたままにし、各部品に名前をつけ、コードを明確にする
- メソッド: 構造体のインスタンスが行う動作を指定する
- 関連関数: インスタンスを利用することなく、構造体に特有な機能を名前空間分けすることができる。
6章
- 列挙型(enum)
- 取りうる値を列挙することで型を定義させる
- 取りうる値を全て列挙できる
- どちらか一方の値で、同時に両方にならない場合に役立つ
- 取りうる値を全て列挙できる
- 代数的データ型に酷似している
- enumの値は列挙子のいずれか1つにしかなりえない
- 列挙子というのは、enumの要素のことである。
- 列挙子は種類の語り方のみであり、値の保存を考えることは必須ではない。
- 取りうる値を列挙することで型を定義させる
enumの書き方:
enum 列挙型名 {
xxx,
yyy,
}
- enumの値
型::列挙子で各列挙子のインスタンスを生成する- 型は一緒なので、それぞれの列挙子に対して、異なる関数は作らなくてよい
- enumを使えば、構造体より簡潔な方法で、表現することができる場合がある
- enumの各列挙子に直接データを添付することができ、
- 列挙子に紐づけるデータの型と量は異なっても良い
- これが構造体ではできないこと
- いかなる種類のデータでも格納できる
- 列挙型も入れられる
- 構造体との類似点:
- 異なる種類の構造体定義を定義すること
- ただし、enumの方が、構造体よりも、関数を簡単に作ることができる場合がある
- implが使えるということ
- 異なる種類の構造体定義を定義すること
team
- リーダーのいないチームは機能しない
- かじ取りする人のいない船みたいなもの
- ソフトウェアの方向性に影響を与えるためには、エンジニアリングリーダーシップを隅々まで理解する必要がある
- マネージャー
- 誕生
- 産業革命期
- 労働者を監督するマネージャーという立場
- 労働者を人参と鞭とで管理していた
- 今ではもう全く効果がない
- 変化
- エンジニアは数か月間かけて新しいチームに追いつく
- 考えたり創造したりするためにの育成・時間・空間が必要
- 違い
- 昔のマネージャー
- 親と子の関係のようなもの
- どうやって仕事を完了させるかを考える
- リーダー
- HRTでエンジニアを信頼するようにすれば、エンジニアはその信頼に答える
- チームのための道を作り、安全と安心に気を配る
- 何ができるかを考える
- どうやって完了させるかはチームが考える
- 昔のマネージャー
- 二種類のリーダーがGoogleにはある
- TL(Team Lead): プロダクトの全部・一部の技術的な方向性に責任を持つ
- TLM(Technical Lead Manager): TLの責任に加え、チームにいるエンジニアのキャリアや幸せという、人の管理にも責任を持つ
- 誕生
- Managerになることへの不安
- コードを書く時間が減ることへの不安
- 定量化できないものが増えることへの不安
- チームの幸せと生産性をたかめるのが仕事の指標である
- 定量化できないものが増えることへの不安
- 無能なマネージャーになるのではないかという不安
- ピーターの法則で、階級制度があるところでは、必ずその人の無能レベルまで昇進する
- コードを書く時間が減ることへの不安
- Managerになるべき大きな理由
- 自分をスケールできるから
- マネージャーに向いているかもしれないから
- 実際、マネージャーに向いていた人が多くいる
- マネジメント病(管理したがり病)の負の再生産の問題について
- サーバントリーダーシップで治療する
- チームに奉仕すること
- HRTの雰囲気づくりをすること
- アドバイスを与えたり、
- 順調に進めるよう穴を埋めたり
- 自らの手を汚す
- 技術的な側面とチームの人間関係の両方を扱う
- サーバントリーダーシップで治療する
マネジメントのアンチパターン
- 言いなりになる人を採用する
- 仕事が増えるぞ
- むしろ、自分より球が良くて、代わりになる人を採用しよう
- 新しいチャンスを産む
- パフォーマンスの低い人を無視する
- 数名でもパフォーマンスの低い人がいるだけでチームはうまくいかなくなる
- 「願いは戦略ではない」
- パフォーマンスの低い人にはコーチングをする
- HRTとともに
- マイクロマネジメントをする
- 小さい目標から大きな目標へ
- マイルストーンには明確な期待を設定する
- 明確な期待が設定すると結果がわかりやすくなる
- 期待に応えない人をどうするかというのが一番難しい問題
- 立ち去ってもらうことがチームにとって一番良いこと
- パフォーマンスの低い人にはコーチングをする
- 人間の問題を無視する
- 人間的な側面を無視してしまうととんでもないことになる
- ちょっとした共感さえあればよかったことがしょっちゅうある
- みんなの友達になる
- 友人関係のままであろうとするな
- 友人関係も失うことになる
- 上下関係があると人工的な友人関係を作りだしてしまう可能性がある
- 友人関係も失うことになる
- 友人関係とチームをリードすることとを混同してはならない
- 友人関係ではなく、不安を感じさせずに仲良くしたいなら、一緒にランチしろ
- 友人関係のままであろうとするな
- 採用を妥協する
- 採用基準を満たす人を取れ
- 採用すべきでない人の採用のコストは高い
- チームを子供として扱う
- 子供・囚人として扱うことは、信頼していないということ
- これのコストは馬鹿高い
- 信頼されていることを感じれば責任を感じるようになる
- 子供・囚人として扱うことは、信頼していないということ
次はリーダーシップパターン
isabelle
pp. 156-159
定数畳み込みと定数伝播の続き
- 定数値を保存するテーブル
tが、runtime statesに漸近することの、approxの定義 - arithmetic expressions のfoldの
afoldの正しさの証明- induction貼って、あとは自動
- 自動と書いているが、自分で書いたら、sledgehammerでサジェストされなかったので、
simp: approx_defしてsimplificationしたり、- subgoalの形を見て、splitをしたりした。
split: option.splitsplit: option.split aexp.split
- 言語ごとのfailure semanticsを保存するように定数畳み込みの定義には注意を払え
- Invalid programに対して、validな結果を返すようなものもあるから
- induction貼って、あとは自動
- arithmetic expressionsに限定しない定数畳み込みと定数伝播の実装
fold :: com => tab => com- 基本的なアイディア
- take a command
- take a table
- produce new command
- sequential composition (
fold c_1;;c_2 t)について考えないといけないこと- recustionに適用する
fold c_2に対しては、c_1の実行結果でアサインされたものの新しいvalueを取り上げるべきである- この認識は、最適化の分析から得られる
- 基本的なアイディア
- foldの実装には補助関数
defs :: com => tab => tabが必要- commandを実行した後の、既知の定数値と変数を記述するような新たなtableを生成する関数
primrec defs :: com => tab => tabIFのケースでは、両方の枝で同じ値が割り当てられている確認して、そういうテーブルを作るmergeという補助関数を使う
WHILEのケースでは、- 永遠にループするかどうかを静的に解析できない
- 13章までいけばできるらしいが
- だから、tableに追加できない
- tableに追加できないだけではなく、tableに初期に保存していたものと矛盾する可能性がある
- だから、loop bodyの中に含まれるassignment statementのleft-handの変数を全部取り除く必要がある。
lvarsという補助変数で、assignmentsのleft-hand側、つまり、変数の集合を取る- 取り除くのには
t|`S = \lambda x. if x \in S then t x else Noneというものを使っている。
- 永遠にループするかどうかを静的に解析できない
primrec fold :: com => tab => tabの実装ができるIFのケースでmergeを使っているWHILEのケースでは、defsの場合と同様、loop bodyの中に含まれるassignment statementの変数を全部取り除く必要がある
primrecについて- 原始再帰的関数のこと
- 参考書類