正格関数と非正格関数について

みなさん、こんにちは。id:ogxwxです。

今回は、自分なりに正格関数と非正格関数の違いについて簡単に説明したいと思います。

まずいきなりですが、正格関数とは何か説明していきます。

正格関数

正格関数とは、引数に値を渡した時点で評価される関数のことです。

def f(n: Unit): Unit = {
    println("start")
    n
}

こんな感じの関数です。普通の関数定義ですね〜。

次に実際に関数を呼び出してみたいと思います。

今回は引数の評価順をわかりやすくf(println("end"))このような形で呼び出しを行いました。

実際の結果は以下のようになります。

end
start

本来であれば

start
end

と評価されると思った方もいると思いますが、正格関数は引数に値を渡した時点で評価されるため、このような結果となってしまいます。

では、どうすれば想定する評価順にできるのでしょうか。

非正格関数

ここでは非正格関数について説明したいと思います。

非正格関数とは引数で値を評価せず、関数内でその引数が呼び出された時に評価する関数のことです。文だとわかりにくいので以下に非正格関数のサンプルを作成しました。

def lazyF(n: => Unit): Unit = {
    println("start")
    n
}

ほぼ正格関数と同じ定義ですが、引数の型の定義方法が異なります。Scalaでは引数の型に=>を追加するだけで、引数の評価方法を非正格評価にすることができます。これによって非正格関数を作成することができます。

非正格関数の呼び出し方法は正格関数と同じく、引数に評価させたい値を渡すだけでOKです。実際の非正格関数呼び出し時のものです。

lazyF(println("end"))

すると想定される評価で表示されました。

start
end

この結果から、非正格関数は関数内で引数を呼び出した時に値が評価されることがわかります。正格関数だと引数に値を渡した時点で評価されているので、非正格関数は正格関数に比べて引数の評価地点を遅延させているんですね〜

もう一つの非正格関数

ここでは、別の非正格関数の定義方法について説明したいと思います。 Scalaは、関数の引数や返り値に関数を定義することができます(高階関数)。 そして先ほど引数の型定義に=>を追加することで、正格関数から非正格関数を作成することができると説明しましたが、他にも引数の型定義に() => と定義しても非正格関数を作成することもできます。引数の型を関数にするだけですね。またその引数を関数内で呼び出すには、関数呼び出しの呼び出し方法で書く必要があります。 以下に() => を使った関数を定義してみました。

def lazyG(n: () => Unit): Unit = {
    println("start")
    n()
}

また、この関数呼び出し方法は最初に紹介した関数呼び出し方法と少し異なります。 異なる点は、引数の型が関数であるため明示的に引数に関数を定義させる必要がある点です。 以下のように定義してあげる必要があります。

lazyG(() => println("end"))

結果は最初に紹介した非正格関数と同じ結果になります。

start
end

まとめ

自分なりに正格関数と非正格関数について説明してみました。ちなみに正格評価は、ほとんどのプログラミング言語での評価方法でもあり、非正格の評価方法もif...elseの評価方法でもあります。また、遅延リストには非正格評価があったりと正格・非正格の評価方法は幅広く使われている技術でもあります。なので、もし気になる方は調べてみてください。

最後ですが、今回紹介した正格関数と非正格関数の違いについてのコードをgistにまとめました。ありがとうございました〜

gist.github.com

PostgreSQLのサードパーティ'uuid-ossp'を使ってuuidの生成方法とテーブル定義を行う

みなさん、こんにちは。id:ogxwxです。

今回はPostgreSQLサードパーティuuid-osspを使って、uuidの生成方法とテーブル定義を行う方法について記事を書いてみました。

uuidとは

uuidとは(Universally Unique IDentifier)の略で、そのままの意味で一意に識別されるIDというものです。なので、PRIMARY KEYとして定義します。

tools.ietf.org

導入

PostgreSQLでuuidを生成させるには、'uuid-ossp'というサードパーティをインストールする必要があります。

インストールは以下のSQLコマンドを実行することで、設定が完了します。インストール後、uuid生成機能とUUIDデータ型が追加されます。

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

実行

インストール完了後、実際にuuidが生成できるか確認してみます。

以下のSQLコマンドを実行してみます。

SELECT uuid_generate_v1();

画像のように表示されれば、uuidの設定は完了です。

f:id:ogxwx:20190422131233p:plain
uuid-generate-v1

uuid生成関数について

今回は、uuid_generate_v1()と,uuid_generate_v4()の2つの関数について説明したいと思います。uuid_generate_v1()の生成関数は、現在時刻+PCのMACアドレスの組み合わせでuuidが生成されています。一方で、uuid_generate_v4()では、ランダムな数を元にuuidが生成されます。

個人的にですが、uuidの値をpcに依存させたくないのでuuid_generate_v4()をよく使用しています。

他にもuuid生成するための関数があるので、興味のある人はみてみてください。

www.postgresql.org

実際に使用してみる

実際に食べ物テーブルを定義してみましょう。

CREATE TABLE foods (
  id uuid DEFAULT uuid_generate_v4(),
  name char(32) NOT NULL,
  PRIMARY KEY (id)
);

ここでは、食べ物の識別IDをUUIDで識別していることがわかります。また、'uuid-ossp'というサードパーティをインストールしたことでuuid型で定義できていることもわかります。

uuid生成関数には、uuid_generate_v4()を使用しています。

次にfoodsテーブルにデータを追加していきます。

INSERT INTO foods VALUES (uuid_generate_v4(), 'アイスクリーム');
INSERT INTO foods VALUES (uuid_generate_v4(), 'ケーキ');
INSERT INTO foods VALUES (uuid_generate_v4(), 'チョコレート');

追加後、select * from foodsと実行すると以下のように表示されると思います。

f:id:ogxwx:20190422135102p:plain
foods

ちゃんと、idがUUIDで識別されていることがわかります。

以下、gistの方にまとめました。

gist.github.com

最後に

この記事を読んでくださりありがとうございます! 今回は、uuidとは何か、PostgreSQLでの使用方法について簡単ではありますが説明させてもらいました。

今後も何かあればブログ等で発信していきたいと思います!

リクルートインターンに参加しました

みなさん、こんにちは。id:ogxwxです。

今回は、リクルートインターンに参加したことについてブログを書いてみました。

最初に

2/25〜3/25の期間中でリクルートインターンに参加させてもらいました。

インターン参加の経緯は、個人的にリクルートってどんな会社なんだろうと技術的興味から参加させてもらいました。

インターン参加決定までの流れ

インターン参加決定までの流れは コーディングテスト->1次面接->2次面接->結果発表という流れでした。 

その中でも特に思い出深かったのが2次面接で、色々ありすぎのありすぎでscalaについてずっと話していた記憶がありますw

また、合格通知の日がクリスマスで、最高のクリスマスプレゼントでもありました!

配属先

スタディサプリENGLISHサーバーサイドチームにお世話になりました。

eigosapuri.jp

スタディサプリENGLISHのサーバーサイドでは、scalaを使用して開発を行なっています。

以下の記事からもわかりますが、かなり関数型指向で開発が行われていました。 

tech.recruit-mp.co.jp

他にも、gRPCを使用していたり、マイクロサービス化してあったりととてもモダンな設計で開発が行われていました。

ちなみに、自分はある監視処理系のバッチ開発を行いました。

インターン期間中に行ったこと

社員の方と同じスケジュールをこなした

インターン期間中は、他の社員さんと同じスケジュールをこなしました。実際に、自分が取り組んでいることの状況報告や、サーバチームの定例会に参加することができました。大体ですが、こんな感じで働くのか〜 を知ることができました。

コードレビュー

実際にscala界隈で有名な人たちと一緒にコードレビューを行いました。自分の作成したコードに対してレビューをしてもらったり、実際に自分でレビューをしてみたりと、コードレビューの重要性に気づかされました。

自分の技術力が低かったので、レビューするのが面倒だったと思うのですが、とても親切に丁寧にレビューをしてくれてすごく感謝しています。 ありがとうございました! 

イベントに参加

インターン期間中に、色々なイベントに参加させてもらいました。その中で、スタディサプリENGLISHのリリースイベントに実際に参加をしたのですが、みんなで"開発お疲れ様!"と言い合う雰囲気にいい会社だなと感じました。

LT会

週1回、数名の発表者(インターン生とリクルートの社員)が、自分の興味ある技術についてLTするという会で、技術分野はデータサイエンスやアルゴリズム・データ構造、セキュリティになど幅広い技術分野があり、とても刺激的でした。 

あと、お寿司とかお菓子とか食べながらでもあったので、とてもなごやかなLT会でした!

最終成果発表

インターン最終日にインターン期間中に行ったことをテーマに最終成果発表を行いました。 緊張もありましたが、なんとかやり遂げることができました!

毎日ランチ

インターン期間中はタダでかなり豪華なランチ(ステーキ、焼肉定食)をすることができました。 また、様々な技術分野の人たちとランチに行くことができたので、自分の知らなかったことを知れるいい機会でもありました。

学んだこと

scala関数型指向プログラミング

スタディサプリENGLISHのサーバーサイドはscalaを関数型指向で書いており、最初はコードを読むこと自体難しかったですが、色んな人のサポートもあって なんとかロジックの組み立てまで一人でできるレベルになりました。

ソフトウェア設計の重要性

正しい設計はソフトウェアの拡張性をあげるみたいなのを何かの本で読みましたが、確かにそうで
実際にインターン期間中である機能を追加した時、簡単に機能追加できたことを自分の身で実感しました。またモジュールの依存性も一方向だったこともあり、単体テストの作成も容易でした。ソフトウェア設計は本当に重要だなっていうことを改めて実感しました。

コードレビューの重要性

インターンに参加する前は、コードレビューをあまりやったことがなかったし、それにここまで重要だとも思ってもいなかった・・・ でもこのインターンで、ロジック一つ一つの構成をしっかり考えるようになったし、技術力もかなりアップしたと思います。 サーバーチームと、もっとたくさんコードレビューしたかったな・・・ 

最後に

このインターンに参加できたことで、技術的にも社会的にもすごく成長できました! 

本当にスタディサプリENGLISHのサーバーサイドチームのみなさま方、他チームのみなさま方、人事のみなさま方のおかげだと思います。 

本当にありがとうございました!