読者です 読者をやめる 読者になる 読者になる

Pseudo Engineer

ソフトウェアの話とか書いてくよ

Line Bot の Play framework テンプレート in Scala

Line Bot Awardsに挑戦しようとラズパイ買ったり準備したものの、ほとんど手を付けなかったorz

せっかくなので、Line Bot 用のPlay framework テンプレートを公開する。

github.com

macOS Sierra - Samba安定化

去年、macOSでのSamba安定化について書いたが、Sierraになって方法が変わったのでメモ。

jetbeaver.hatenablog.com

/etc/nsmb.conf のシンタックスが変わった

manページ見てもらえれば分かるが、シンタックスが変わっている。

$ man nsmb.conf
SMB1にする

こうすればいい。
/etc/nsmb.conf

[default]
protocol_vers_map=1

エンジニアの価値

私も普段はSIerをdisってばかりですが、じゃあWeb系が至高とも言い切れないモヤモヤを抱えて生きてます。

イケてる環境のWEB系の労働生産性がイケてないSIerのたった三割しかない件 - プロマネブログ

資本主義における自由市場経済ではお金がものをいうわけで、すなわちお金の生産性として語るほうが指標としてはわかりやすい。

金で測るエンジニアの生産性

経営者の力量や営業の成果との比は単純に比較しようもないので、ポジションによる影響を無視すると、エンジニアの生産性は以下で示される。

{ \displaystyle
エンジニアの生産性 = \frac{営業利益 * エンジニア比率}{エンジニア数}
}

エンジニアの生産性をあげるには、高付加価値のプロダクトを作って売上立てるか、プロダクトの生産効率を上げて開発人数減らすしかない。エンジニアの考える生産性ってコード書いた量とかスピードに注目されがちですが、それにも当然限界があって、いかに付加価値を作るかを考えねばならない。

どこかで聞いた文句、「売上はすべてを癒やす」とはエンジニアの生産性にも寄与しているわけです。利益あってのエンジニア。

エンジニアの幸せ

エンジニアは技術が好きだからやってるわけです。お金だけでは満たされない。

クールなプロダクトを作りたい。
最先端の技術を使いこなしたい。
最高の開発環境でストレスフリーにコーディングしたい。
オシャレなオフィスで、そしてたまにスタバでドヤりながら仕事したい。

やることやってれば、出社時間・勤務時間なんて自由でいいと思う。別にイヤホンで音楽聴きながらやったって誰かが迷惑するわけでもないし。私も激しく共感します。

エンジニアの給与

SIerの世界なんて数億程度のプロジェクトなんてざらにあるし、そんなの小さい部類です。SIerの顧客って大きなお金を動かせる人が多いし、特注の作り込みが必要なら値段ふっかけるもんです。結果として売上・利益も大きく、ひいては給与も高いと期待できる。

Web系で働いてたとき、「俺のほうができるのになんであいつと給料変わんないのか」とか愚痴ってる人いたけど、会社内の相対的な差を気にしてもしょうがないと思う。その人は転職して給与あがって、めでたしめでたし。結局、お金は気になるわけですね。

給料あげたい? Welcome to SIer as Project Manager!!
プロマネは責任も大きいわけで、でかいプロジェクトでこけると何人か首飛びますけど。)

閑話休題

エンジニアの価値をあげるにはどうするか

Web系の人たちは技術力向上において、すごく努力してると思います。SIerで見た「俺、人集めるしかできない」とか言って丸投げしてた方より、よっぽどWeb系で頑張ってる人を尊敬してます。

でも、技術だけでは足りない。どうやって価値を上げるか。

私は、桁違いにスケールの大きな夢を真面目に追う人を、エンジニアリングで応援するのがいいと思ってます。例えば、火星に行くとか言ってるクレイジーな天才など。

その夢が叶ったとき、巨大な利益と技術力(エンジニアリングとしての生産性)が相まって、エンジニアの価値が真に高まるでしょう。

あってもなくてもいいようなサービスとか、浮き沈みの激しいゲームとか作ってても、いつまでもエンジニアの価値は上がらないんじゃないだろうか。

Haskell道 その5

前回はファンクターでした。
今回はアプリカティブファンクターです。

アプリカティブファンクターとは?

ファンクターは文脈を持った値を入れる箱でした。値は整数、浮動小数点数、文字列などです。ところでHaskellは関数がファーストクラスでした。つまり関数を値のように扱えるということです。となると、ファンクターに関数を入れてもいいのでは? 答えはYes。ファンクターに関数も入れられるようになったのがアプリカティブファンクターです。
言い換えると、アプリカティブファンクターは文脈を持った関数も入れられる箱です。なお、アプリカティブファンクターでは長くて呼びづらいので単にアプリカティブと呼んだりします。

アプリカティブに値を適用

箱の中に関数があるのですから、関数に値を適用したいですよね。それが <*> です。
試しにMaybeのアプリカティブに値を適用してみましょう。

Prelude> let a = Just (+2)
Prelude> a <*> Just 3
Just 5

「2を足すかもしれない」ものに対して「3かもしれない」ものを適用すれば、「5かもしれない」ものになりました。ここでもMaybeの文脈が維持されていますね。

pure と <*>

ここでアプリカティブの定義を見てみます。

class (Functor f) => Applicative f where
    pure :: a -> f a
    (<*>) :: f (a -> b) -> f a -> f b

f (a -> b) -> f a という定義からアプリカティブに値を適用するには、同じ文脈に入れたファンクター値で与えなければなりません。上述のMaybeの例だと、a に適用するのに Just 3 でわざわざファンクター値にしていました。ここで a はアプリカティブであれば何でもいいような抽象的なコードの場合、具体的な型がわかりません。そこで pure の登場です。pure :: a -> f a の定義の通り、与えられた値を文脈にいれて返すだけです。
Maybeの例をpure で書きなおしてみましょう。

Prelude> let a = Just (+2)
Prelude> a <*> pure 3
Just 5

pureの活用方法は他にもあります。例えばアプリカティブではない関数にファンクター値を適用する場合です。まずは fmap でやってみます。

Prelude> fmap (+) (Just 3) <*> Just 4
Just 7

それならば、最初から(+)をアプリカティブにして <*> を連鎖させて部分適用していっても良さそうです。

Prelude> pure (+) <*> Just 3 <*> Just 4
Just 7

これでも十分そうですが便利な中置演算子 <$> を利用することもできます。

Prelude> (+) <$> Just 3 <*> Just 4
Just 7

<$> の実体は fmap のエイリアスなので、ファンクターがアプリカティブを実装していなくても使うことはできます。

(<$>) :: (Functor f) => (a -> b) -> f a -> f b
f <$> x = fmap f x

Prelude> (+3) <$> Just 3
Just 6

アプリカティブ則

第一法則「idのアプリカティブで写してもファンクター値は同じである」
pure id <*> v = v
第二法則「アプリカティブの連鎖でファンクター値を写したものと、アプリカティブで関数合成してからファンクター値を写したものは同じである」
pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
第三法則「文脈に入れてから関数に適用したものと、関数に適用してから文脈に入れたものは同じである」
pure f <*> pure x = pure (f x)
第四法則「アプリカティブでファンクター値を写したものと、ファンクター値を$演算子で関数化してアプリカティブで写してものは同じである」
u <*> pure y = pure ($ y) <*> u

まとめると、ファンクター則と同様に与えられた関数や値を無視したり、関数適用以外の余計なことはしないということですね。箱はあくまで箱であり、入れ物にすぎないということです。



補足:
$演算子は優先度の低い演算子であるため引数を右結合させたい場合(かっこを減らしたい場合)に有用という記述をわりと見かけますが、それだけでは少々説明不足です。

($) :: (a -> b) -> a -> b
f $ x = f x

$は関数本体と引数を受け取り引数を関数本体に適用する優先度の低い演算子です。これは関数適用を右結合させる以外のもう1つの活用方法として、関数が引数を待つのではなく、引数が関数を待つ関数を作ることができます。

Prelude> let f = \x -> x + 1
Prelude> :info f
f :: Num a => a -> a
Prelude> let p = ($ 1)
Prelude> :info p
p :: Num a => (a -> b) -> b 
Prelude> p f
2

$は演算子なため中置記法(f $ x)が可能でした。なので($ 1)とすれば右引数を部分適用した関数が作れます。なお、すごいHaskellたのしく学ぼう!の5.6章にも詳しい解説があります。

Haskell道 その4

前回からかなり空いてますがHaskellの勉強はゆったりながら続けてますよ。

途中の章はいろいろ飛ばしてファンクターに行きましょう。

ファンクターとは?

ファンクターは文脈を持った箱です。箱の中にある値に文脈を持たせるともいえます。箱なので値を取り出して、加工して、また戻すこともできます。

ファンクターといえば、Maybe型が有名です。
Maybeの定義はこちら。

data Maybe a = Just a | Nothing

ここでの a は箱に入れる値の型です。Java的にはジェネリクス

Maybe型とは、値に不確実性の文脈を与えます。日本語的には「もしかすると〜かもしれない(失敗していなければ)」という意味です。

ファンクター値に関数を適用

ファンクターの箱の中にある値をファンクター値と呼んだりします。そしてファンクター値に関数に適用するのが fmap です。関数に適用させて得られた値はそのままファンクターに包まれたままです。イメージとしては、箱の中に入れたまま値を関数に適用させる感じです。

試しにMaybeのファンクター値に対して3を掛けてみます。

Prelude> let a = Just 2
Prelude> a
Just 2
Prelude> fmap (\x -> x * 3) a
Just 6

「2かもしれない」ものに対して3を掛ければ、「6かもしれない」ものになりました。ここで重要なのは文脈が維持されることにあります。

ファンクター則

第一法則「idで写してもファンクター値は同じである」

id は 与えられた引数をそのまま返す関数です。Maybeで示すと以下が成り立つ。

fmap id (Just 3) == id (Just 3)
第二法則「gの次にfでファンクター値を写したものと、合成関数f・gでファンクター値を写したものは同じである」

Maybeで示すと以下が成り立つ。

fmap f $ fmap g (Just 3) == fmap (f . g) (Just 3)

まとめると「箱から値を取り出して、与えられた関数を適用して、また戻す」という動作のみが fmap で実装されていればいいことになる。
与えられた関数を無視したり、関数適用以外の余計なことはしないということですね。

【書評】グラフデータベース

グラフデータベース ―Neo4jによるグラフデータモデルとグラフデータベース入門

グラフデータベース ―Neo4jによるグラフデータモデルとグラフデータベース入門

1年ほどの積ん読を経て、やっと読みきった(遅っ)
代表的グラフデータベースの1つ、Neo4jの開発に関わっている人が執筆している。そのためNeo4jを基準に解説されているが、内容は具体的でわかりやすい。データがどのようにストレージに保存されているのか、どうやって検索しているのかなど、実装についても触れているところがおもしろい。

”関係性”が重要なデータはグラフで表すのが適切である。グラフデータベースはその名の通り、グラフ構造でデータを保存できる。関係性はセマンティックな方向性に関係なく、双方向でストレージに保存されるため、ノード間をどちらの方向にも高速に辿ることができる。ここが一般的なリレーショナルデータベースとの大きな違いで、例えばRDBはインデックスを構築しておくことで高速に検索が可能だが、それはあくまでインデックスを順に辿る場合である。逆方向にインデックスを辿ろうとすると、テーブル全体の検索が必要になるため、とても時間がかかる。そこでいい感じにテーブル設計を行うのも可能だが、複雑になる上、スキーマ変更となると苦労するのは目に見えてる。

グラフデータベースはスキーマレスで変更にも強い。ただしグラフの構成が下手くそだと検索や拡張で苦労する。そこはRDBと同じく経験が必要かな。RDBより優れているというわけではなく、型にはまったときはすごい強力だと思う。スキーマが決まってるデータのまとまりをたくさん保存するにはRDBがいい。

アプリケーション観点ではグラフから最短経路を探索したり、SNSような人の関係性からコミュニティを見つけたり、新たなつながりを予測したりなどに応用できる。なんか使えそうなんだけど、世の中の事象をグラフで表せないか日頃から考察しないとな。それとグラフ理論を勉強したほうがいいなぁ。

プロキシ環境でのIntelliJ IDEA with SBT

プロキシ環境でIntelliJ IDEA with SBTを使う

社内ではプロキシ通さないといけないケースも結構あるでしょう。IntelliJ IDEAでscalaやる場合は、sbtがほぼ必須です。そんなときにどこにプロキシの設定をすればいいのかご紹介。

プロキシ設定する箇所は3箇所

IntelliJ IDEAのプロキシ設定

ここは環境に応じてでプロキシ設定を入れてください。
f:id:jetBeaver:20160524215311p:plain

IntelliJ IDEAからsbt実行時のプロキシ設定

ここはビルドだけでなく、sbtファイル変更時のリフレッシュでも利用されます。
赤矢印のところに「-Dhttp.proxyHost=proxy.bar.com -Dhttp.proxyPort=8080 -Dhttps.proxyHost=proxy.bar.com -Dhttps.proxyPort=8080」などを入力する。
f:id:jetBeaver:20160524215318p:plain

IntelliJ IDEAからsbt起動時のプロキシ設定

SBT Consoleを起動する場合は、ここの設定が利用されます。
赤矢印のところに「-Dhttp.proxyHost=proxy.bar.com -Dhttp.proxyPort=8080 -Dhttps.proxyHost=proxy.bar.com -Dhttps.proxyPort=8080」などを入力する。
f:id:jetBeaver:20160524215322p:plain