mike、mikeなるままに…

プログラムに関してぬるま湯のような記事を書きます

gradle1.6からgroovyのconfigurationはdeprecatedになっています

gradle1.6からgroovyのconfigurationは非推奨になっています

まあ今さらですが、さきほどbuild.gradleを書いた時に、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ gradle idea
The groovy configuration has been deprecated and is scheduled to be removed in Gradle 2.0. Typically, usages of 'groovy' can simply be replaced with 'compile'. In some cases, it may be necessary to additionally configure the 'groovyClasspath' property of GroovyCompile and Groovydoc tasks.
:ideaModule
Download http://repo1.maven.org/maven2/org/codehaus/groovy/groovy-all/2.1.3/groovy-all-2.1.3.pom
Download http://repo1.maven.org/maven2/org/codehaus/groovy/groovy-all/2.1.3/groovy-all-2.1.3-sources.jar
Download http://repo1.maven.org/maven2/org/codehaus/groovy/groovy-all/2.1.3/groovy-all-2.1.3.jar
:ideaProject
:ideaWorkspace
:idea

BUILD SUCCESSFUL

Total time: 11.174 secs
$ 

と表示されたので、「うぉっ」と思ってドキュメントを読んでみました。

groovy configuration is deprecated

じゃあ、今後どうするのかというと、

compile configurationにgroovyのartifactを指定する

ということです。

つまり、これまでは

build.gradle
1
2
3
dependencies {
    groovy : 'org.codehaus:groovy:groovy-all:2.1.3'
}

と書いていましたが、

build.gradle
1
2
3
dependencies {
    compile : 'org.codehaus.groovy:groovy-all:2.1.3'
}

と書けばよいようです。

プログラマーのための会計知識・用語 - (2)

普通のエンタープライズ系プログラマーであれば、会計用語はちゃんと英語で覚えているものですよね(白目

僕はにも言ったとおりに、

出来損ないのエンタープライズ系プログラマーなので、

アメリカの中学生向けの会計の簡単な本で勉強しています。

この本の第二章に書かれていることをまとめてみます。

会計の基本用語

  • 勘定 : Account
  • 勘定科目 : Account Titile
  • 借方 : Debit
  • 貸方 : Credit
  • 総勘定元帳 : Ledger
  • 勘定科目一覧 : The Chart of Accounts
  • 仕訳 : Journal
  • 複式簿記 : Double-Entry Bookkeeping
  • 試算表 : Trial balance

前回の復習

  • 資産 : Assets
  • 負債 : Liabilities
  • 資本 : Capital

借方と貸方の決まり事 (Convention)

エンタープライズ系プログラマーなら当然わかっていると思いますが…

勘定科目(Account Title)は借方科目なのか貸方科目なのか決まっていますね。

借方系の勘定 (The Account to be debited)

  • 資産(Asset)の増加
  • 費用(Expense)の増加
  • 負債(Liabilities)の減少
  • 資本(Capital)の減少
  • 収入(Income)の減少

借方系の勘定 (The Account to be credited)

  • 負債(Liabilities)の増加
  • 資本(Capital)の増加
  • 収入(Income)の増加
  • 資産(Asset)の減少
  • 費用(Expense)の減少

会計のドメインモデルを作ってみる

ここまで来たら、もう会計のドメインモデル作れますね。

勘定

Account.groovy
1
2
3
4
5
@Cannonical
class Account {
    String title
    AccountChart accountChart
}

取引

Transaction.groovy
1
2
3
4
5
6
7
8
@Cannonical
class Transaction {
    long id
    Date date
    Debit debit
    Credit credit
    String memo
}

借方

Debit.groovy
1
2
3
4
5
6
@ToString
class Debit {
    Account item
    int value
    String memo
}

貸方

Credit.groovy
1
2
3
4
5
6
@ToString
class Credit {
    Account item
    int value
    String memo
}

借方と貸方でクラスの構造が全く同じなので、

訓練されたSIer諸氏に於いては同じクラスを使おうと言い出すとおもいます。

しかし、java-ja.dddで増田さんがおっしゃっていたとおり、

借方と貸方は別物なので、別のクラスにします。

java-ja.dddのまとめについてはこちら

勘定科目

AccountChart.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enum AccountChart {
    ASSET{
        AccountConvention increase() {AccountConvention.DEBIT}
        AccountConvention decrease() {AccountConvention.CREDIT}
    }, EXPENSE{
        AccountConvention increase() {AccountConvention.DEBIT}
        AccountConvention decrease() {AccountConvention.CREDIT}
    }, LIABILITIES{
        AccountConvention increase() {AccountConvention.CREDIT}
        AccountConvention decrease() {AccountConvention.DEBIT}
    }, CAPITAL{
        AccountConvention increase() {AccountConvention.CREDIT}
        AccountConvention decrease() {AccountConvention.DEBIT}
    }, INCOME{
        AccountConvention increase() {AccountConvention.CREDIT}
        AccountConvention decrease() {AccountConvention.DEBIT}
    }
}

勘定の決まりごと

AccountConveintion.groovy
1
2
3
enum AccountConvention {
    DEBIT, CREDIT
}

この二つのクラスを書いていて、DebitとかCreditのクラスを生成するメソッドはこのあたりにあるといいなと思ってきた。

例えば、費用が増加した場合

1
2
3
4
AccountChart.EXPENSE
        .increase()
        .by('売上原価', '商品が売れた')
        .for(item.asCredit())

という感じで書きたいですね。

そうすると、AccountChart.groovyを少し直さないといけないですね…

以下、宿題

Rearrange the following list of accounts and produce a trial balance.

  • Accounts Payable(900)
  • Accounts Receivable(1,400)
  • Capital(3,200)
  • Cash(2,000)
  • Drawing(400)
  • Equipment(1,800)
  • Fees income(2,600)
  • General expense(100)
  • Notes Payable(1,100)
  • Rent expense(500)
  • Salaries expense(800)
  • Supplies(600)
  • Supplies expense(200)

SourceTreeで細かくコミットする

gitのコミットの粒度はなるべく細かいほうがいいですよね

こんにちわ、みけです。

今日はgitの話です。

表題にあるようにgitは細かくコミットしたほうがよいです。

なぜなら、

  • mergeが簡単にできる
  • やらかした時に細かいレベルで元に戻れる
  • 細かければpushするときにまとめればいいや的な

といったメリットがあるからと思っています。

詳細はこっちの記事読んだほうがいいです。

いや、そんなこと言ったってコミット頻繁にしてないっすよ

これ、僕のことで、そもそもコミットを頻繁にしていないので、Work Treeに変更がたくさん溜まってしまいます。

そうすると、僕のようなdullな人がgit addする時はgit add -pで小分けにしながらステージに載せていくのですが、Hunkのサイズを変えるのに一々git add -pの後にsをしているとわりと面倒い。(参考 – Can I modify git-add’s hunk size?)

まあ、かといって、「gitできない奴はVSSでもやってろよ」とか言われると辛い…

そこでSourceTreeですよ

Atlassianの回し者ではありませんが、SourceTreeがそんな僕には便利です。

変更が溜まりに溜まったwork tree

hunkがでかすぎるので小さくします。

hunkが細かくなります。

さらに行単位で変更を選びます

意味のある単位にまとまったのでコミットします

commitボタンを推します。

適度な粒度でコミットしたのでプッシュします。

pushボタンのところにプッシュされていないコミットの数が出ています。

pushボタンを押してプッシュします。

プッシュ完了すると、ローカルとリモートが一致した状態になります。

細かい粒度でコミット出来ましたね

  • SourceTree、マジ便利、マジ神、ハンパないです。
  • いや、そもそもそんなにWork Treeに変更を溜め込むなという話ですね…

Erlangのlistsモジュールを試してみる - 第2回

Erlangのlistsモジュールを試してみるの第二回は次のコマンドの結果について試していきます。

1
2
3
4
5
6
7
8
9
10
11
lists:sublist(
    lists:sort(
        lists:map(
            fun({F, A}) ->
                atom_to_list(F) ++
                "/" ++
                integer_to_list(A)
            end,
            lists:module_info(exports))),
    17,
    16).

結果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[
  "keydelete/3",
  "keyfind/3",
  "keymap/3",
  "keymember/3",
  "keymerge/3",
  "keyreplace/4",
  "keysearch/3",
  "keysort/2",
  "keystore/4",
  "keytake/3",
  "last/1",
  "map/2",
  "mapfoldl/3",
  "mapfoldr/3",
  "max/1",
  "member/2"
]

です。

keydelete/3

Erlang公式ドキュメント

keydelete(Key, N, TupleList1) –> TupleList2

Types

  • Key = term()
  • N = integer() >= 1 (1..tuple_size(Tuple))
  • TupleList1 = TupleList2 = [Tuple]
  • Tuple = tuple()

Returns a copy of TupleList1 where the first occurrence of a tuple whose Nth element compares equal to Key is deleted, if there is such a tuple.

参照元

Explain

引数に与えられたタプルのリストのコピーを返します。ただし、リスト中のタプルで、タプルのN番目の要素が引数Keyと同じ値のもので最も先頭に近いものは取り除かれます。

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
1> lists:keydelete(jim, 1,
1> [
1>     {mike, 32, programmer}, {jim, 22, engineer}, {tim, 40, scientist},
1>     {bob, 36, officer}, {lod, 22, dentist}, {iwan, 27, evangelist},
1>     {simon, 36, typist}, {dag, 34, student}, {jack, 21, programmer},
1>     {john, 21, engineer}, {mike, 27, scientist}, {jim, 24, officer}
1> ]).
[{mike,32,programmer},
 {tim,40,scientist},
 {bob,36,officer},
 {lod,22,dentist},
 {iwan,27,evangelist},
 {simon,36,typist},
 {dag,34,student},
 {jack,21,programmer},
 {john,21,engineer},
 {mike,27,scientist},
 {jim,24,officer}]
2> lists:keydelete(madscientist, 3,
2> [
2>     {mike, 32, programmer}, {jim, 22, engineer}, {tim, 40, scientist},
2>     {bob, 36, officer}, {lod, 22, dentist}, {iwan, 27, evangelist},
2>     {simon, 36, typist}, {dag, 34, student}, {jack, 21, programmer},
2>     {john, 21, engineer}, {mike, 27, scientist}, {jim, 24, officer}
2> ]).
[{mike,32,programmer},
 {jim,22,engineer},
 {tim,40,scientist},
 {bob,36,officer},
 {lod,22,dentist},
 {iwan,27,evangelist},
 {simon,36,typist},
 {dag,34,student},
 {jack,21,programmer},
 {john,21,engineer},
 {mike,27,scientist},
 {jim,24,officer}]
3> lists:keydelete(madscientist, 4,
3> [
3>     {mike, 32, programmer}, {jim, 22, engineer}, {tim, 40, scientist},
3>     {bob, 36, officer}, {lod, 22, dentist}, {iwan, 27, evangelist},
3>     {john, 21, engineer}, {mike, 27, scientist}, {jim, 24, officer}
3> ]).
[{mike,32,programmer},
 {jim,22,engineer},
 {tim,40,scientist},
 {bob,36,officer},
 {lod,22,dentist},
 {iwan,27,evangelist},
 {john,21,engineer},
 {mike,27,scientist},
 {jim,24,officer}]

まず最初の例では、リストの中で一番最初に出てくるキーの位置1番目の値がjimであるタプルを削除したリストが返されます。元のリストで9番目のタプルも同様の条件ですが、こちらは削除されません。

次の例ではリストで一致しない条件で実行しています。返されるリストは何も削除されていません。

最後の例ではリストのタプルの要素数より多い番号を指定して削除を実施します。もちろん、返されるリストは何も削除されていません。

keyfind/3

Erlang公式ドキュメント

keyfind(Key, N, TupleList) –> Tuple | false

Types

  • Key = term()
  • N = integer() >= 1 (1..tuple_size(Tuple))
  • TupleList = [Tuple]
  • Tuple = tuple()

Searches the list of tuples TupleList for a tuple whose Nth element compares equal to Key. Returns Tuple if such a tuple is found, otherwise false.

参照元

Explain

タプルのリストから指定位置の要素についてKeyに一致する最初のタプルを返します。

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1> lists:keyfind(36, 2,
1> [
1>     {mike, 32, programmer}, {jim, 22, engineer}, {tim, 40, scientist},
1>     {bob, 36, officer}, {lod, 22, dentist}, {iwan, 27, evangelist},
1>     {simon, 36, typist}, {dag, 34, student}, {jack, 21, programmer},
1>     {john, 21, engineer}, {mike, 27, scientist}, {jim, 24, officer}
1> ]).
{bob,36,officer}
2> lists:keyfind(jim, 1,
2> [
2>     {mike, 32, programmer}, {jim, 22, engineer}, {tim, 40, scientist},
2>     {bob, 36, officer}, {lod, 22, dentist}, {iwan, 27, evangelist},
2>     {simon, 36, typist}, {dag, 34, student}, {jack, 21, programmer},
2>     {john, 21, engineer}, {mike, 27, scientist}, {jim, 24, officer}
2> ]).
{jim,22,engineer}
3> lists:keyfind(madscientist, 3,
3> [
3>     {mike, 32, programmer}, {jim, 22, engineer}, {tim, 40, scientist},
3>     {bob, 36, officer}, {lod, 22, dentist}, {iwan, 27, evangelist},
3>     {simon, 36, typist}, {dag, 34, student}, {jack, 21, programmer},
3>     {john, 21, engineer}, {mike, 27, scientist}, {jim, 24, officer}
3> ]).
false

最初の例ではタプルの二番目の値が36のものを探して、返します。

次の例ではタプルの最初の値がjimのものを探して返しますが、9番目に現れるものは返されません。

最後の例では一致するものがない条件で検索を行いますが、存在しないためfalseが返ってきます。

keymap/3

Erlang公式ドキュメント

keymap(Fun, N, TupleList1) –> TupleList2

Types

  • Fun = fun((Term1 :: term()) –> Term2 :: term())
  • N = integer() >= 1 (1..tuple_size(Tuple))
  • TupleList1 = TupleList2 = [Tuple]
  • Tuple = tuple()

Returns a list of tuples where, for each tuple in TupleList1, the Nth element Term1 of the tuple has been replaced with the result of calling Fun(Term1).

参照元

Explain

タプルに対して指定した位置の要素に、引数で渡した関数を実行した結果が入れられた、新しいタプルのリストが返されます。

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1> IsProgrammer = fun(X) -> X =:= programmer end.
#Fun<erl_eval.6.17052888>
2> lists:keymap(IsProgrammer, 3,
2> [
2>     {mike, 32, programmer}, {jim, 22, engineer}, {tim, 40, scientist},
2>     {bob, 36, officer}, {lod, 22, dentist}, {iwan, 27, evangelist},
2>     {simon, 36, typist}, {dag, 34, student}, {jack, 21, programmer},
2>     {john, 21, engineer}, {mike, 27, scientist}, {jim, 24, officer}
2> ]).
[{mike,32,true},
 {jim,22,false},
 {tim,40,false},
 {bob,36,false},
 {lod,22,false},
 {iwan,27,false},
 {simon,36,false},
 {dag,34,false},
 {jack,21,true},
 {john,21,false},
 {mike,27,false},
 {jim,24,false}]

この例ではタプルの3番目の要素がprogrammerならtrueに変換し、そうでなければfalseに変換した新しいタプルのリストを返します。

keymember/3

Erlang公式ドキュメント

keymember(Key, N, TupleList) –> boolean()

Types

  • Key = term()
  • N = integer() >= 1 (1..tuple_size(Tuple))
  • TupleList = [Tuple]
  • Tuple = tuple()

Returns true if there is a tuple in TupleList whose Nth element compares equal to Key, otherwise false.

参照元

Explain

指定位置にKeyを含むタプルがリスト中にあればtrue、なければfalseが返ってきます。

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1> lists:keymember(bob, 1,
1> [{mike,32,programmer},
1>  {jim,22,engineer},
1>  {tim,40,scientist},
1>  {bob,36,officer},
1>  {lod,22,dentist},
1>  {iwan,27,evangelist},
1>  {simon,36,typist},
1>  {dag,34,student},
1>  {jack,21,programmer},
1>  {john,21,engineer},
1>  {mike,27,scientist},
1>  {jim,24,officer}
1> ]).
true
2> lists:keymember(madscientist, 3,
2> [
2>  {mike,32,programmer},
2>  {jim,22,engineer},
2>  {tim,40,scientist},
2>  {bob,36,officer},
2>  {lod,22,dentist},
2>  {iwan,27,evangelist},
2>  {simon,36,typist},
2>  {dag,34,student},
2>  {jack,21,programmer},
2>  {john,21,engineer},
2>  {mike,27,scientist},
2>  {jim,24,officer}
2> ]).
false

最初の例では、1番目の要素がbobであるタプルがリスト中に含まれていますので、trueが返されます。

次の例では、3番目の要素がmadscientistのタプルはリスト中に含まれていないので、falseが返されます。

keymerge/3

Erlang公式ドキュメント

keymerge(N, TupleList1, TupleList2) –> TupleList3

Types

  • N = integer() >= 1 (1..tuple_size(Tuple))
  • TupleList1 = [T1]
  • TupleList2 = [T2]
  • TupleList3 = [(T1 | T2)]
  • T1 = T2 = Tuple
  • Tuple = tuple()

Returns the sorted list formed by merging TupleList1 and TupleList2. The merge is performed on the Nth element of each tuple. Both TupleList1 and TupleList2 must be key-sorted prior to evaluating this function. When two tuples compare equal, the tuple from TupleList1 is picked before the tuple from TupleList2.

参照元

Explain

この関数は引数で与えられた二つのタプルリストをソートしてマージした状態で返します。ソートのキーは引数のN番目の要素になります。引数に与えられるタプルリストは事前にソートされていることが求められます。双方のタプルでキーの値が一致する場合、左側の引数のリストから取られたタプルが右のものに優先されます。

Example

1
2
3
4
5
6
7
8
1> lists:keymerge(1,
1>   [{a, 1}, {c, 1}, {d, 1}],
1>   [{b, 2}, {d, 2}]).
[{a,1},{b,2},{c,1},{d,1},{d,2}]
2> lists:keymerge(1,
2>   [{x, 1}, {d, 1}, {e, 1}],
2>   [{t, 2}, {a, 2}, {d, 2}]).
[{t,2},{a,2},{d,2},{x,1},{d,1},{e,1}]

最初の例では、事前にソートされたタプルリストが引数として与えられ、マージされたリストが返されます。また、[{d, 1}, {d, 2}]のようにキーの値が一致するものは左側の引数に与えられたものが優先されています。

次の例では、事前にソートされていないタプルリストが引数として与えられていますが、返されるリストはマージされていない状態で返ってきます。

keyreplace/4

Erlang公式ドキュメント

keyreplace(Key, N, TupleList1, NewTuple) –> TupleList2

Types

  • Key = term()
  • N = integer() >= 1 (1..tuple_size(Tuple))
  • TupleList1 = TupleList2 = [Tuple]
  • NewTuple = Tuple
  • Tuple = tuple()

Returns a copy of TupleList1 where the first occurrence of a T tuple whose Nth element compares equal to Key is replaced with NewTuple, if there is such a tuple T.

参照元

Explain

タプルリストの中で最も最初に現れたN番目の要素がKeyであるタプルを引数で指定されたタプルに変更したリストを返します。

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1> lists:keyreplace(b, 1,
1> [
1>  {a, original},
1>  {b, original},
1>  {c, original},
1>  {d, original},
1>  {b, not_change}],
1> {b, changed}).
[{a,original},
 {b,changed},
 {c,original},
 {d,original},
 {b,not_change}]
2> lists:keyreplace(x, 1,
2> [
2>  {a, original},
2>  {b, original},
2>  {c, original}],
2> {x, not_appear}).
[{a,original},{b,original},{c,original}]

最初の例では最も最初に現れる1番目の要素がbであるタプルが引数で与えられたタプルと交換されて返されます。最後に現れる同じKeyをもつタプルは変わっていません。

次の例ではKeyに一致するタプルが存在しないため、元のリストと同じ物が返ってきます。

keysearch/3

Erlang公式ドキュメント

keysearch(Key, N, TupleList) –> {value, Tuple} | false

Types

  • Key = term()
  • N = integer() >= 1 (1..tuple_size(Tuple))
  • TupleList = [Tuple]
  • Tuple = tuple()

Searches the list of tuples TupleList for a tuple whose Nth element compares equal to Key. Returns {value, Tuple} if such a tuple is found, otherwise false.

This function is retained for backward compatibility. The function lists:keyfind/3 (introduced in R13A) is in most cases more convenient.

参照元

Explain

タプルリストの中でN番目の要素がKeyである最初のタプルを探して、{value, Tuple}の形式で返します。見つからない場合は、falseを返します。

なお、この関数は下位互換のために残っているものであり、R13Aより導入されたlists:keyfind/3関数の方が便利です。

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1> lists:keysearch(c, 1,
1> [
1>   {a, 1},
1>   {b, 1},
1>   {c, 1},
1>   {d, 1},
1>   {c, 2}]).
{value,{c,1}}
2> lists:keysearch(x, 1,
2> [
2>   {a, 1},
2>   {b, 1},
2>   {c, 1},
2>   {d, 1},
2>   {c, 2}]).
false

最初の例では1番目の要素がcであるタプルを探して{value, {c, 1}}のように返します。二番目に現れるものは返しません。

次の例では条件に該当するタプルがないためにfalseが返ってきます。

keysort/2

Erlang公式ドキュメント

keysort(N, TupleList1) –> TupleList2

Types

  • N = integer() >= 1 (1..tuple_size(Tuple))
  • TupleList1 = TupleList2 = [Tuple]
  • Tuple = tuple()

Returns a list containing the sorted elements of the list TupleList1. Sorting is performed on the Nth element of the tuples. The sort is stable.

参照元

Explain

引数に渡されたタプルリストをN番目の要素でソートしたリストを返します。ソートは安定ソートです。

Example

1
2
3
4
5
6
7
8
9
10
11
12
1> lists:keysort(1,
1> [
1>   {x, 1},
1>   {r, 1},
1>   {t, 1},
1>   {x, 2},
1>   {c, 1},
1>   {s, 1},
1>   {r, 2},
1>   {a, 1},
1>   {x, 3}]).
[{a,1},{c,1},{r,1},{r,2},{s,1},{t,1},{x,1},{x,2},{x,3}]

ソートされた結果が返ってきます。安定ソートのため、重複するキーに対しては元の順番が維持されます。

keystore/4

Erlang公式ドキュメント

keystore(Key, N, TupleList1, NewTuple) –> TupleList2

Types

  • Key = term()
  • N = integer() >= 1 (1..tuple_size(Tuple))
  • TupleList1 = [Tuple]
  • TupleList2 = [Tuple, …]
  • NewTuple = Tuple
  • Tuple = tuple()

Returns a copy of TupleList1 where the first occurrence of a tuple T whose Nth element compares equal to Key is replaced with NewTuple, if there is such a tuple T. If there is no such tuple T a copy of TupleList1 where [NewTuple] has been appended to the end is returned.

参照元

Explain

タプルリストの中で一番最初に出てくるN番目の要素がKeyであるタプルを、引数のタプルと交換したリストを返します。Keyに一致するリストがない場合は、リストの最後に追加されて返されます。

Example

1
2
3
4
5
6
7
8
9
10
11
12
1> lists:keystore(b, 1,
1>   [{a, origin}, {b, origin}, {c, origin}, {b, not_store}],
1>   {b, new_tuple}).
[{a,origin},{b,new_tuple},{c,origin},{b,not_store}]
2> lists:keystore(x, 1,
2>   [{a, origin}, {b, origin}, {c, origin}, {b, not_store}],
2>   {x, not_found}).
[{a,origin},
 {b,origin},
 {c,origin},
 {b,not_store},
 {x,not_found}]

最初の例では、1番目の要素がbであるタプルが、引数に与えられた新しいタプルに交換されたリストが返ってきます。

次の例では、該当するタプルが存在しないため、引数に与えられた新しいタプルがリストの最後に追加されて返ってきます。

keytake/3

Erlang公式ドキュメント

keytake(Key, N, TupleList1) –> {value, Tuple, TupleList2} | false

Types

  • Key = term()
  • N = integer() >= 1 (1..tuple_size(Tuple))
  • TupleList1 = TupleList2 = [Tuple]
  • Tuple = tuple()

Searches the list of tuples TupleList1 for a tuple whose Nth element compares equal to Key. Returns {value, Tuple, TupleList2} if such a tuple is found, otherwise false. TupleList2 is a copy of TupleList1 where the first occurrence of Tuple has been removed.

参照元

Explain

タプルリストの中から初めて現れるN番目の要素がKeyであるタプルを取り出し、{value, Tuple, TupleList2}の形式で返します。戻されるタプルリストには条件に一致したタプルは含まれていません。一致するものがない場合は、falseが返されます。

Example

1
2
3
4
5
6
1> lists:keytake(b, 1,
1> [{a, 1}, {b, 1}, {c, 1}, {b, 2}]).
{value,{b,1},[{a,1},{c,1},{b,2}]}
2> lists:keytake(x, 1,
2> [{a, 1}, {b, 1}, {c, 1}, {b, 2}]).
false

最初の例では一番最初に現れる1番目の要素がbのタプルが取り出され、後から現れるものは残ったリストとともに返されています。

次の例では、条件に一致するタプルがないため、falseが返されます。

last/1

Erlang公式ドキュメント

last(List) –> Last

Types

  • List = [T, …]
  • Last = T
  • T = term()

Returns the last element in List.

参照元

Explain

リストの最後の要素を返します。

Example

1
2
3
4
5
6
1> lists:last([1,2,3,4,5]).
5
2> lists:last([1]).
1
3> lists:last([]).
** exception error: no function clause matching lists:last([]) (lists.erl, line 213)

最初の例ではリストの最後の要素5が返されます。

次の例では長さ1のリストを引数として渡して、最後の要素=たったひとつの要素である1が返されます。

最後の例では長さ0のリストを引数として渡します。この場合は例外が発生します。

map/2

Erlang公式ドキュメント

map(Fun, List1) –> List2

Types

  • Fun = fun((A) –> B)
  • List1 = [A]
  • List2 = [B]
  • A = B = term()

Takes a function from As to Bs, and a list of As and produces a list of Bs by applying the function to every element in the list. This function is used to obtain the return values. The evaluation order is implementation dependent.

参照元

Explain

要素を返還する関数を引数に取ります。そしてリストの要素1つずつに関数を適用した結果が入ったリストが返されます。なお、実行順序は実装に依存しています。

Example

1
2
1> lists:map(fun(X) -> X rem 2 =:= 0 end, [1, 2, 3, 4, 5]).
[false,true,false,true,false]

引数に偶数かどうか判定する関数を渡します。引数のリストは1から5までの整数ですので、falsetrueが繰り返されるリストが返ってきます。

mapfoldl/3

Erlang公式ドキュメント

mapfoldl(Fun, Acc0, List1) –> {List2, Acc1}

Types

  • Fun = fun((A, AccIn) –> {B, AccOut})
  • Acc0 = Acc1 = AccIn = AccOut = term()
  • List1 = [A]
  • List2 = [B]
  • A = B = term()

mapfoldl combines the operations of map/2 and foldl/3 into one pass.

参照元

Explain

mapfoldl/3関数はmap/2関数とfoldl/3関数を一つにまとめたような関数です。

Example

1
2
3
4
5
6
7
1> Multiply = fun ({R1, I1}, {R2, I2}) ->
1>     {R1 * R2 - I1 * I2, R1 * I2 + I1 * R2} end.
#Fun<erl_eval.12.17052888>
2> lists:mapfoldl(fun(X, A) -> Res = Multiply(X, A), {Res, Res} end,
2>   {1, 0},
2> [{1, -1}, {-1, 1}, {-1, -1}, {1, -1}]).
{[{1,-1},{0,2},{2,-2},{0,-4}],{0,-4}}

複素数{R, I}に対して、掛け算をする関数Multiplyを定義し、lists:mapfoldl/3で初期値{1, 0}から左から順繰りに掛け算をしていきます。返されたタプルの左要素には掛け算の経過が、タプルの右側の要素には最終的な掛け算の結果が返っています。

mapfoldr/3

Erlang公式ドキュメント

mapfoldr(Fun, Acc0, List1) –> {List2, Acc1}

Types

  • Fun = fun((A, AccIn) –> {B, AccOut})
  • Acc0 = Acc1 = AccIn = AccOut = term()
  • List1 = [A]
  • List2 = [B]
  • A = B = term()

mapfoldr combines the operations of map/2 and foldr/3 into one pass.

参照元

Explain

mapfoldr関数はmap/2関数とfoldr/3関数を組み合わせた関数です。

Example

1
2
3
4
5
6
7
1> Multiply = fun ({R1, I1}, {R2, I2}) ->
1>     {R1 * R2 - I1 * I2, R1 * I2 + I1 * R2} end.
#Fun<erl_eval.12.17052888>
2> lists:mapfoldr(fun(X, A) -> Res = Multiply(X, A), {Res, Res} end,
2>   {1, 0},
2> [{1, -1}, {-1, 1}, {-1, -1}, {1, -1}]).
{[{0,-4},{2,-2},{-2,0},{1,-1}],{0,-4}}

先ほどと同じく複素数の計算をしています。返されたタプルの左側の順序が先ほどのmapfoldl/3関数と異なっていることがわかると思います。

max/1

Erlang公式ドキュメント

max(List) –> Max

Types

  • List = [T, …]
  • Max = T
  • T = term()

Returns the first element of List that compares greater than or equal to all other elements of List.

参照元

Explain

他のすべての要素より大きい最初の要素を返します。

Example

1
2
1> lists:max([0,-2,4,-6]).
4

リストの中の最大値である4が返されます。

member/2

Erlang公式ドキュメント

member(Elem, List) –> boolean()

Types

  • Elem = T
  • List = [T]
  • T = term()

Returns true if Elem matches some element of List, otherwise false.

参照元

Explain

指定した要素と一致する要素があればtrueを、なければfalseを返します。

Example

1
2
3
4
1> lists:member({a,1}, [{b,1},{c,1},{a,2},{d,1},{a,1}]).
true
2> lists:member({a,1}, [{b,1},{c,1},{a,2},{d,1}]).
false

最初の例では指定した要素{a,1}に一致する要素がリストにあるためtrueが返ってきます。

次の例では指定した要素{a,1}に一致する要素がリストにないためfalseが返ってきます。

次回

次回は次の式の結果をやっていきます。

1
2
3
4
5
6
7
8
9
10
11
lists:sublist(
    lists:sort(
        lists:map(
            fun({F, A}) ->
                atom_to_list(F) ++
                "/" ++
                integer_to_list(A)
            end,
            lists:module_info(exports))),
    17,
    16).

Erlangのlistsモジュールを試してみる - 第1回

みけです。

Erlangのlistsモジュールを試してみるの第一回になります。

なお、最初の16個は

1
2
3
4
5
6
7
8
9
10
11
lists:sublist(
    lists:sort(
        lists:map(
            fun({F, A}) ->
                atom_to_list(F) ++
                "/" ++
                integer_to_list(A)
            end,
            lists:module_info(exports))),
    1,
    16).

の実行結果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[
  "all/2",
  "any/2",
  "append/1",
  "append/2",
  "concat/1",
  "delete/2",
  "dropwhile/2",
  "duplicate/2",
  "filter/2",
  "flatlength/1",
  "flatmap/2",
  "flatten/1",
  "flatten/2",
  "foldl/3",
  "foldr/3",
  "foreach/2"
]

です。

all/2

Erlang公式ドキュメント

all(Pred, List) –> boolean()

Types
  • Pred = fun((Elem :: T) –> boolean())
  • List = [T]
  • T = term()

Returns true if Pred(Elem) returns true for all elements Elem in List, otherwise false.

参照元

解説

  • すべての要素が第一引数に与えられた関数でtrueになればtrueを返します。
  • 第一引数に与えられた関数でfalseになるものが一つでもあれば、falseを返します。

実例

1
2
3
4
1> lists:all(fun(X) -> X rem 2 =:= 0 end, [0,2,4,6,8]).
true
2> lists:all(fun(X) -> X rem 2 =:= 0 end, [0,1,2,3,4]).
false

偶数であることを判断する関数を第一引数に与えています。

最初の例では全部偶数である[0, 2, 4, 8]が与えられています。

その結果、trueが返ってきます。

一方、二番目の例では単なる1間隔の順列[1, 2, 3, 4]が与えられています。

したがって、falseが返ってきます。

any/2

Erlang公式ドキュメント

any(Pred, List) –> boolean()

Types
  • Pred = fun((Elem :: T) –> boolean())
  • List = [T]
  • T = term()

Returns true if Pred(Elem) returns true for at least one element Elem in List.

参照元

解説

  • リストの要素のうち、一つでも第一引数に渡した関数がtrueを返せばtrueが返ってきます。
  • リストの要素すべてで、第一引数の関数を満たさなければfalseが返ってきます。

実例

1
2
3
4
5
1> lists:any(fun(X) -> is_integer(X) end,                                         1>     [0.0, a, "hoge", 1, fun(X) -> true end]).
true
2> lists:any(fun(X) -> is_integer(X) end,
2>     [0.0, a, "hoge", [1], fun(X) -> true end]).
false

整数であることを判断する関数を第一引数として与えています。

最初の例ではリストの4番目の要素1が整数ですので、この関数からtrueが返ってきます。したがって、実行結果はtrueとなります。

2つ目の例では先ほどは整数だった1をリスト[1]に変更しています。そのため、関数がtrueを返すものがありません。したがって、実行結果はfalseになります。

append/1

Erlang公式ドキュメント

append(ListOfLists) –> List1

Types
  • ListOfLists = [List]
  • List = List1 = [T]
  • T = term()

Returns a list in which all the sub-lists of ListOfLists have been appended.

参照元

解説

リストの中に含まれる複数のリストを結合した新しいリストを返します。

実例

1
2
3
4
1> lists:append([[1], [2,3,4],[a,b,c]]).
[1,2,3,4,a,b,c]
2> lists:append([[1],[2,[3,4],5],[a,b,c]]).
[1,2,[3,4],5,a,b,c]

最初の例ではリストの中にある複数のリストが結合されて一つのリストにまとまります。

次の例ではリストの中にある複数のリストが結合されて一つのリストにまとまっていますが、リスト中のリスト中のリストは展開されません。

append/2

Erlang公式ドキュメント

append(List1, List2) –> List3

Types

  • List1 = List2 = List3 = [T]
  • T = term()

Returns a new list List3 which is made from the elements of List1 followed by the elements of List2.

参照元

解説

リストを結合して新しいリストを返します。

実例

1
2
1> lists:append("ir", "of").
"irof"

リスト"ir"とリスト"of"が結合されて、新しいリスト"irof"が返されます。

concat/1

Erlang公式ドキュメント

concat(Things) –> string()

Types

  • Things = [Thing]
  • Thing = atom() | integer() | float() | string()

Concatenates the text representation of the elements of Things. The elements of Things can be atoms, integers, floats or strings.

参照元

解説

リスト中の要素の文字列表現を結合する。要素はアトム、整数、浮動小数点数、文字列。

実例

1
2
1> lists:concat([lists, ':', "concat", '/', 1]).
"lists:concat/1"

アトム、アトム、文字列、アトム、整数を結合して文字列を出力しています。

delete/2

Erlang公式ドキュメント

delete(Elem, List1) –> List2

Types

  • Elem = T
  • List1 = List2 = [T]
  • T = term()

Returns a copy of List1 where the first element matching Elem is deleted, if there is such an element.

参照元

解説

リストから指定要素にマッチする最初の要素を削除したリストを返します。

実例

1
2
3
4
5
6
1> lists:delete(a, [q,a,w,s,e]).
[q,w,s,e]
2> lists:delete(a, [f,o,o,b,a,r,b,a,z]).
[f,o,o,b,r,b,a,z]
3> lists:delete(hoge, [foo, bar, baz]).
[foo,bar,baz]

最初の例では、リストの中に指定した要素aがあるため、それを削除したリストが返されます。

次の例では、リストの中に指定した要素aが2つありますが、最初のaが削除されたリストが返されます。

最後の例では、リストの中に指定した要素hogeと同じ要素がないため、元のリストと同じ内容のリストが返されます。

dropwhile/2

Erlang公式ドキュメント

dropwhile(Pred, List1) –> List2

Types

  • Pred = fun((Elem :: T) –> boolean())
  • List1 = List2 = [T]
  • T = term()

Drops elements Elem from List1 while Pred(Elem) returns true and returns the remaining list.

参照元

解説

引数として与えた関数Pred(Elem)trueを返す間、要素Elemをリストから削除して、残ったリストを返します。

実例

1
2
3
4
5
1> lists:dropwhile(fun(X) -> X < 5 end, [1,2,3,4,5,6,7]).
[5,6,7]
2> lists:dropwhile(fun(X) -> X > 2 end,
2>     [4,4,5,4,2,2,1,3,3,5]).
[2,2,1,3,3,5]

最初の例では要素が5より小さい要素は除外され、5より大きいリストが返されます。

次の例では、要素が2より大きい間の要素は除外され、初めて2が出てきた後の要素が残ったリストが返されます。(返されたリストには関数がtrueを返すものが含まれます)

duplicate/2

Erlang公式ドキュメント

duplicate(N, Elem) –> List

Types

  • N = integer() >= 0
  • Elem = T
  • List = [T]
  • T = term()

Returns a list which contains N copies of the term Elem.

参照元

解説

要素ElemN回繰り返したリストが返されます。

実例

1
2
1> lists:duplicate(5, irof).
[irof,irof,irof,irof,irof]

要素irof5回繰り返されたリストが返されます。

filter/2

Erlang公式ドキュメント

filter(Pred, List1) –> List2

Types

  • Pred = fun((Elem :: T) –> boolean())
  • List1 = List2 = [T]
  • T = term()

List2 is a list of all elements Elem in List1 for which Pred(Elem) returns true.

参照元

解説

リストの中から条件を満たす要素を取り出したリストを返します。

実例

1
2
3
1> lists:filter(fun(X) -> X rem 3 =:= 0 end,
1>     [1,2,3,4,5,6,7,8]).
[3,6]

リストの中から3の剰余が0のものを取り出したリストを返します。

flatlength/1

Erlang公式ドキュメント

flatlength(DeepList) –> integer() >= 0

Types

  • DeepList = [term() | DeepList]

Equivalent to length(flatten(DeepList)), but more efficient.

参照元

解説

BIFのlength/1関数と同様な関数ですが、より便利です。

実例

1
2
3
4
1> lists:flatlength([[1,2,3],4,[[5,6],7]]).
7
2> length([[1,2,3],4,[[5,6],7]]).
3

内部にリストを含むリストに対して内部のリストの要素数を含む要素数を返します。最初の例では内部リストの要素の数を含めて7を返します。

一方、BIFのlength/1では、内部リストを一つの要素として数えるため、3が返ってきます。

flatmap/2

Erlang公式ドキュメント

flatmap(Fun, List1) –> List2

Types

  • Fun = fun((A) –> [B])
  • List1 = [A]
  • List2 = [B]
  • A = B = term()

Takes a function from As to lists of Bs, and a list of As (List1) and produces a list of Bs by applying the function to every element in List1 and appending the resulting lists.

参照元

解説

第一引数には要素Aからリスト[B]を生成する関数を取ります。第二引数はリストです。そしてリスト[B]が結合されたリストが返されます。

実例

1
2
3
4
5
6
7
8
9
1> lists:flatmap(fun(X) -> [X * 2, X * 2 + 1] end,
1>     [0,1,2,3]).
[0,1,2,3,4,5,6,7]
2> lists:flatmap(fun(X) -> X * X end, [1,2,3,4]).
** exception error: bad argument
     in operator  ++/2
        called as 16 ++ []
     in call from lists:flatmap/2 (lists.erl, line 1235)
     in call from lists:flatmap/2 (lists.erl, line 1235)

最初の例での第一引数の関数は、入力された要素を倍にした値と、倍にした値に1を加えた値の二つを要素としてもつリストを返します。これをリスト[0, 1, 2, 3]に対して実行し、最終的にそれらを結合したリスト[0,1,2,3,4,5,6,7]が返ってきます。

次の例では、第一引数の関数は入力された要素の二乗を返します。これをリスト[1, 2, 3, 4]に対して実行します。しかし第一引数が返す値はリストではないため、例外が発生して終了します。

flatten/1

Erlang公式ドキュメント

flatten(DeepList) –> List

Types

  • DeepList = [term() | DeepList]
  • List = [term()]

Returns a flattened version of DeepList.

参照元

解説

内部にリストを持つリストのネストをなくしたリストを返します。

実例

1
2
1> lists:flatten([1,2,[3,4,[5],6],[[[7],8]],9]).
[1,2,3,4,5,6,7,8,9]

内部にリストを持つリストから、ネストなしリストを返します。

flatten/2

Erlang公式ドキュメント

flatten(DeepList, Tail) –> List

Types

  • DeepList = [term() | DeepList]
  • Tail = List = [term()]

Returns a flattened version of DeepList with the tail Tail appended.

参照元

解説

最初のネストがあるリストにlists:flatten/1を施して、第二引数のリストを追加したリストを返します。

実例

1
2
3
4
5
6
1> lists:flatten(
1>     [1,[2,3,[[4],5]],6], [7,8]).
[1,2,3,4,5,6,7,8]
2> lists:flatten(
2>     [1,[2,3,[[4],5]],6], [[7],8]).
[1,2,3,4,5,6,[7],8]

最初の例では、ネストしたリストからネストを外し、第二引数のリストを追加したリストが返ってきます。

次の例でも、第一引数のネストしたリストのネストが外れ、第二引数のリストを追加したものが返ってきますが、第二引数のリストのネストは残ったままとなります。

foldl/3

Erlang公式ドキュメント

foldl(Fun, Acc0, List) –> Acc1

Types

  • Fun = fun((Elem :: T, AccIn) –> AccOut)
  • Acc0 = Acc1 = AccIn = AccOut = term()
  • List = [T]
  • T = term()

Calls Fun(Elem, AccIn) on successive elements A of List, starting with AccIn == Acc0. Fun/2 must return a new accumulator which is passed to the next call. The function returns the final value of the accumulator. Acc0 is returned if the list is empty.

参照元

解説

リストの左側から1つずつ要素を取り出し、第一引数の関数を連続で呼び出します。第一引数の関数は二つの引数を取り、次回の引数として使われる値を返します。第二引数には初期値を与えます。lists:foldl関数は最後の第一引数の関数の結果を返します。

実例

1
2
3
4
5
6
1> lists:foldl(fun(X, Accum) -> X + Accum end,
1>     0, [1,2,3,4,5]).
15
2> lists:foldl(fun(X, Accum) -> [X * X | Accum] end,
2>     [], [1,2,3,4,5]).
[25,16,9,4,1]

最初の例では初期値0からリスト[1,2,3,4,5]を順番に足していき、最後の結果15を返します。

次の例では、初期値[]のリストにリスト[1,2,3,4,5]の要素の二乗を追加していき、最終的にリスト[25,16,9,4,1]を返します。

foldr/3

Erlang公式ドキュメント

foldr(Fun, Acc0, List) –> Acc1

Types

  • Fun = fun((Elem :: T, AccIn) –> AccOut)
  • Acc0 = Acc1 = AccIn = AccOut = term()
  • List = [T]
  • T = term()

Like foldl/3, but the list is traversed from right to left.

参照元

解説

lists:foldl/3と同様に順次計算していきますが、lists:foldr/3では関数の引数をリストの右から左の順番で取っていきます。

実例

1
2
3
4
5
6
1> lists:foldr(fun(X, Accum) -> X + Accum end,
1>     0, [1,2,3,4,5]).
15
2> lists:foldr(fun(X, Accum) -> [{X, X * X}|Accum] end,
2>     [], [1,2,3,4,5]).
[{1,1},{2,4},{3,9},{4,16},{5,25}]

最初の例では、初期値0に対してリスト[1,2,3,4,5]の要素を右側から足していき、最後の結果15を返します。

次の例では、初期値[]に、リスト[1,2,3,4,5]の元の数とその二乗のペアを右側から追加していき、最後の結果[{1,1}, {2,4}, {3,9}, {4,16}, {5,25}]を返します。

foreach/2

Erlang公式ドキュメント

foreach(Fun, List) –> ok

Types

  • Fun = fun((Elem :: T) –> term())
  • List = [T]
  • T = term()

Calls Fun(Elem) for each element Elem in List. This function is used for its side effects and the evaluation order is defined to be the same as the order of the elements in the list.

参照元

解説

第一引数に与えられた関数をリストの要素すべてに適用します。この関数は副作用のある処理に用いられます。処理順はリストの順番に実行されます。

実例

1
2
3
4
5
6
7
8
9
10
3> lists:foreach(fun(X) ->
3>     io:format("~p x ~p = ~p~n",
3>         [X, X, X * X]) end,
3>     [1,2,3,4,5]).
1 x 1 = 1
2 x 2 = 4
3 x 3 = 9
4 x 4 = 16
5 x 5 = 25
ok

リストの要素を順番に標準出力に出力しています。

次回

次回は次の式の結果をやっていきます。

1
2
3
4
5
6
7
8
9
10
11
lists:sublist(
    lists:sort(
        lists:map(
            fun({F, A}) ->
                atom_to_list(F) ++
                "/" ++
                integer_to_list(A)
            end,
            lists:module_info(exports))),
    17,
    16).

プログラマーのための会計知識・用語 - (1)

こんにちわみけです。

一般的にエンタープライズ系プログラマーは

会計用語の英単語は丸暗記していると聞きました。

僕は戦えないエンタープライズ系プログラマーなので、

今、猛勉強しています。

超基本用語

英単語 日本語 意味
Assets 資産 今持っている価値のある物 |
Liabilities 負債 外部に起因する価値 |
Capital 資本 権利者が持っている価値 |

基本重要式

  • Assets = Liabilities + Capital
  • 資産 = 負債 + 資本

まとめ

The accounting equation of

Assets = Liablities + Capital

shouled balance after every transaction.

from (Schaum’s Easy Outlines Bookkeeping and Accounting p.2)

会計式「資産 = 負債 + 資本」はすべての取引において成立しなければならない。

JJUG CCC 2013 Spring に行ってきた

みけです。

2013/05/11行われたJJUG CCC 2013 Springに午後から行って来ました。

なんか午前の基本講演のJim Weaverさんと

JavaFX Advent Calendar2012をやった人達で

ランチに行ってきたそうです。

午前に行けなくて残念…

以下、僕が参加したセッションのまとめ

H-1 Java EE 6 から Java EE 7 に向かって

王子こと寺田さんのセッション。

まあ、大体聞いたことのある話でした(失礼!)。

  • JavaEE7に向けてJavaEE6も勉強して下さい。
  • JavaEE6はJavaEE5以前に比べてかなり軽量化されています。
  • JavaEE6からはテストも非常に容易になっています。

といった感じです。

その他、JavaEE7に追加される機能の一部の概要の説明がありました。

結論

  • JavaEE7はおもろいので、ぜひやろうぜ
  • JavaEE6やってない人はJavaEE6からどうぞ
  • 資料公開してくれるはず、はず、はず

H-2 H-2 Project Lambda Essential

桜庭さんのProject Lambdaに関するセッション。

まあ、ラムダは大体わかっているし、あれでしたが、

Streamに関する話は面白かったです。

Streamとは?

終端の定義されていないCollectionのことだそうです。

次のようなクラスが定義されています。

  • Object用 java.util.stream.Stream<T>
  • int用 java.util.stream.IntStream
  • long用 java.util.stream.LongStream
  • double用 java.util.stream.DoubleStream

メソッドとか

メソッドとかの例を上げてみます。

ちなみに、昔(今)どうやっているかも一緒に書きます。

filter
filter
1
2
3
IntStream stream = IntStream.range(1,10);
int[] result = stream.filter(x -> x % 2 == 0).toArray();
// result -> [2, 4, 6, 8, 10]

昔のやり方

filter-old-style
1
2
3
4
5
6
7
8
9
10
List<Integer> list = new ArrayList<>();
List<Integer> result = new ArrayList<>();
for (int i = 1; i <= 10; i ++) {
    list.add(i);
}
for (int item : list) {
  if (item % 2 == 0) {
      result.add(item);
  }
}
map
map
1
2
3
IntStream stream = IntStream.range(1,4);
int[] result = stream.map(x -> x * x).toArray();
// result -> [1, 4, 9, 16]

ちなみに昔のやり方

map-old-style
1
2
3
4
5
6
7
8
List<Integer> list = new ArrayList<>();
List<Integer> result = new ArrayList<>();
for (int i = 1; i <= 4; i ++) {
    list.add(i);
}
for (int item : list) {
    list.add(item * item);
}
reduce
reduce
1
2
3
IntStream stream = IntStream.range(1,10);
int result = stream.reduce(0, (x, y) -> x + y).get();
// result -> 55

ちなみに昔のやり方

reduce-old-style
1
2
3
4
5
6
7
8
List<Integer> list = new ArrayList<>();
int result = 0;
for (int i = 1; i <= 10; i ++) {
    list.add(i);
}
for (int item : list) {
    result += item;
}

対応

  • filter –> if文
  • map –> getter
  • reduce –> 副作用プログラミング

Project Lambdaに関して

lambdaを使用しているのにHoge$A.classみたいなものができない

lambda式が表しているクラスは動的に評価されてinvoke dynamicで実行される

mapとreduceを実行しているのに、ループが一回しかまわらない

map/reduce式は遅延して実行される

まとめ

  • Project LambdaとかStreamは記法がかなり変わるので、使用禁止と言われないように勉強しろ(とくにプロジェクトのエロイエライ人)

R5-3 Type Annotation って何? それを使うとプログラムはどう変わる?

Type Annotationに関するセッション

比較

  • これまでのアノテーション(AnnotationType)は宣言をするアノテーション
  • TypeAnnotationは型、参照の利用に関する説明のアノテーション

TypeAnnotation-example
1
2
3
4
5
// 空リストではない、読み取り専用のリスト
@NotEmpty @ReadOnly List<String> customer = CustomerService.getCustomer().withMultipleAccount();

// nullなkey不可、空リストでなく読み取り専用なvalueを持つマップ
Map<@NonNull String, @NotEmpty List<@ReadOnly Text>> document = DocumentService.splitDocumentToTextList(doc);

ここでなんとかServiceとか書いていますが、テキトーなので突っ込まないで下さい。

記述位置で意味が異なる

position-has-much-meanings
1
2
3
4
5
6
7
8
// 読み取り専用のリスト
// customers.add(customer)や、customers.replace(index, customer)はできない。
@ReadOnly List<Customer> customers = CustomerService.getCustomer().withMultipleAccount();

// 変更可能なリスト
// ただし入っているCustomerへの変更は不可
// customer.addNewAddress(address)などは実行できない
List<@ReadOnly Customer> customers = CustomerService.getCustomer().withMultipleAccount();

使えない場所

  • クラスリテラル
  • import文
  • staticメンバー

簡単な例

  • @NonNull
  • @NotEmpty
  • @Interned
  • @ReadOnly
  • @Critical

残念なこと

  • 書けるけど、意味は無い…
  • JavaSE8で事前定義された型アノテーションは(今のところ)ない
  • Java SE8でも入らないし、Java SE9でも入らないかもしれない
  • 単純に実装者が気をつけろよレベル

まとめ

うむ、なんかちょっと残念。

H-4 失敗から学ぶAPI設計

イケメンことゆーすけさんのセッション

Twitter4Jのプロモーションとか、たくさん使ってもらうためにしたことなどを発表

たくさん使ってもらうためのプロモーション的な

  • 汚いことでもなんでもする
  • 手厚いサポートをする。ggrksとかしない

たくさん使ってもらうための技術的な

  • インターフェースを使わないでクラスを使う
  • あまりパッケージを増やさない
  • 名前はよく考える
  • デザパタとかも使わせない
  • 継承させない
  • 本当に使ってほしくないクラスは異様な名前にする

あとは、資料が公表されているので、そちらを参照。

R5-5 [BOF] Java読書会ライブ

実は昔デブサミのLT大会でLTを聞いてから興味を持っていたので、聞いてみたかったセッション

実際に音読をしているし、途中で議論をやっていて面白そうでした。

今はJUnit実践入門を読んでいるそうです。

概要

  • 月一回土曜日に開催
  • まず自己紹介と近況の報告をする
  • 書記を選出する
  • 書記は議論のポイントなどをまとめてサイトに掲載する
  • 午前10:00くらいから昼間でと午後5時まで続ける
  • その後は有志で飲みに行く

まあ、普通の勉強会ですね。

質疑応答

読む本はどうやって決定しているか?

  • 投票によって決定しているそうです。
  • なお、投票は普通の参加者は1票、書記は2票を入れることができるそうです。

どれくらいのスピードで読んでいるのか

  • 毎回約60ページ程度読んでいます。

予習とか必要か?

  • してないけど、してくる人もいる

コードの実行をしたりするのか?

  • パソコン持ってきていてやってくれる人もいる

どんな本が読書会に向いているか

  • 入門本よりはすこし難しめな本で、どうしても積ん読になってしまうようなもののほうが適している
  • いろんなコンテキストを持っている人が参加するので、それが勉強になる

まとめ

面白そうなので、一回参加してみたいと思いました。

参考リンク : Java読書会BOFのページ

R2-6 [BOF] 地方における勉強会事情

沖縄、大都会岡山、札幌+急遽大阪のコミュニティ・勉強会の主催者によるパネルディスカッション

東京の勉強会との違いがわかる一方で、

Javaの勉強会が抱えている問題と共通するものがあるなーという感じがしました。

詳しくはtogetterにまとめられていますので、

そちらを参照して下さい。

JJUG CCC 2013 Spring R2-6 [BOF] 地方における勉強会事情

2013/05/12 19:54 追記

地方の勉強会で初参加する人は

勉強会に参加してきたというブログを読んで

いけそうだなと思って参加するらしいです。

したがって、勉強会の活性化をしたいなら

  • とにかくブログを書け
  • 勉強会はブログを書くまでが勉強会です

JJUG CCC 2013 Spring 懇親会

一応参加して来ました。

そしてなぜかLTさせられることになったので、

グダグダなやつをやってきました。

参考 : ゆとりさんが鮨を奢ってくれるそうなので、感謝の気持を込めて、たくさんのプロセスに「sushi」と言わせてみた

まとめ

Java楽しいですね。

僕はもう人間的にかなり不活性ですが、

Java自体は活性化して貰いたいので、

なんか継続できる勉強会でもやりたいなと思います。

Erlangのリスト系モジュールを試してみる - 第0回

こんにちわ、みけです。

Erlangの初心者・初級・初歩レベルの僕にとって、

まず色々とBIFだとか、基本的なモジュールを使いこなせるのが、

上達への近道かと思ったので、

listsモジュールについて、

すべての関数を試してみようと思います。

モジュール情報を表示する

まず、モジュールの情報を表示するモジュールcのコマンドは

m(Module)関数です。

早速listsモジュールに試して見る。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
1> m(lists).
Module lists compiled: Date: February 25 2013, Time: 19.27
Compiler options:  [{outdir,"/net/isildur/ldisk/daily_build/r16b_prebuild_master-opu_o.2013-02-25_20/otp_src_R16B/lib/stdlib/src/../ebin"},
                    {i,"/net/isildur/ldisk/daily_build/r16b_prebuild_master-opu_o.2013-02-25_20/otp_src_R16B/lib/stdlib/src/../include"},
                    {i,"/net/isildur/ldisk/daily_build/r16b_prebuild_master-opu_o.2013-02-25_20/otp_src_R16B/lib/stdlib/src/../../kernel/include"},
                    warnings_as_errors,debug_info]
Object file: /opt/local/lib/erlang/lib/stdlib-1.19.1/ebin/lists.beam
Exports: 
all/2                         nthtail/2
any/2                         partition/2
append/2                      prefix/2
append/1                      reverse/1
concat/1                      reverse/2
delete/2                      rkeymerge/3
dropwhile/2                   rmerge/2
duplicate/2                   rmerge/3
filter/2                      rmerge3/3
flatlength/1                  rukeymerge/3
flatmap/2                     rumerge/3
flatten/2                     rumerge/2
flatten/1                     rumerge3/3
foldl/3                       seq/2
foldr/3                       seq/3
foreach/2                     sort/2
keydelete/3                   sort/1
keyfind/3                     split/2
keymap/3                      splitwith/2
keymember/3                   sublist/3
keymerge/3                    sublist/2
keyreplace/4                  subtract/2
keysearch/3                   suffix/2
keysort/2                     sum/1
keystore/4                    takewhile/2
keytake/3                     ukeymerge/3
last/1                        ukeysort/2
map/2                         umerge/3
mapfoldl/3                    umerge/1
mapfoldr/3                    umerge/2
max/1                         umerge3/3
member/2                      unzip/1
merge/1                       unzip3/1
merge/2                       usort/2
merge/3                       usort/1
merge3/3                      zf/2
min/1                         zip/2
module_info/0                 zip3/3
module_info/1                 zipwith/3
nth/2                         zipwith3/4
ok

関数がたくさんあって、数えるの面倒いな…

詳細なモジュール情報を表示する

lists:module_info/0関数でも同じようなものを調べられる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2> lists:module_info().
[{exports,[{append,2},
           {append,1},
           {subtract,2},
           {nth,2},
           {nthtail,2},
           {prefix,2},
           {suffix,2},
           {last,1},
           {seq,2},
           {seq,3},
           {sum,1},
           {duplicate,2},
           {min,1},
           {max,1},
           {sublist,3},
           {sublist,2},
           {zip,2},
           {unzip,1},
           {zip3,3},
           {unzip3,1},
           {zipwith,3},
           {zipwith3,4},
           {merge,1},
           {merge3,3},
           {rmerge3,...},
           {...}|...]},
 {imports,[]},
 {attributes,[{vsn,[257948301539042745638557295194154171573]}]},
 {compile,[{options,[{outdir,"/net/isildur/ldisk/daily_build/r16b_prebuild_master-opu_o.2013-02-25_20/otp_src_R16B/lib/stdlib/src/../ebin"},
                     {i,"/net/isildur/ldisk/daily_build/r16b_prebuild_master-opu_o.2013-02-25_20/otp_src_R16B/lib/stdlib/src/../include"},
                     {i,"/net/isildur/ldisk/daily_build/r16b_prebuild_master-opu_o.2013-02-25_20/otp_src_R16B/lib/stdlib/src/../../kernel/include"},
                     warnings_as_errors,debug_info]},
           {version,"4.9"},
           {time,{2013,2,25,19,27,47}},
           {source,"/net/isildur/ldisk/daily_build/r16b_prebuild_master-opu_o.2013-02-25_20/otp_src_R16B/lib/stdlib/src/lists.erl"}]}]

exportsされている関数、

途中で表示が切れてまんがな…

BIFとかリスト内包表記で頑張ってみる

今はエントリーの長さに影響をする関数の数を知りたいので、

リストの内包表記でlists:module_info/0

結果を絞って、BIFの

  • length/1 – リストの長さを取得する
  • hd/1 – リストの先頭要素を取得する

を用いてlistsモジュールの関数の数を数えてみる。

1
2
3> length(hd([Items || {Atom, Items} <- lists:module_info(), Atom =:= exports])).
80

というわけで、80もあるので、

16個ずつ調べていこうと思う。

追記 (2013/05/13 9:16)

2013/05/12 21:19 頃に

voluntasさん(@voluntas)から メッセージをいただきました。

length(lists:module_info(exports))

で同じ事が取得できるとのこと。

実際にやってみたら

1> length(lists:module_info(exports)). 80

あ、できた、ありがとうございます!

ちなみにドキュメントにもありました。

The module_info/0 and module_info/1 functions

ドキュメント読まんとイケませんね

まとめ

まとめもクソもないのですが、

次回から約5回にわたって、

listsモジュールの関数を試していきます。

FC2ブログのエディターがクソいのでGroovyのMarkupBuilderで記事を書いた件

こんにちわ、自虐的なみけです。

自虐的なツイートをtogetterにまとめたら、

自虐的だからたかが知れている、ビジネスなめてんの

とコメントいただきました。

はい。

FC2ブログのエディターがクソな件

まあ、このブログを始めると同時に、

ドラクエ用のブログをFC2の方に

書いているわけですが、

FC2のあのブログエディターなめてんの?

テーブル書いたら

わけわからん改行が出てくるし、

スタイルタグはシカトされるし、

UI舐めきってて、ビジネスを舐めているとしか考えられん。

しかたがないのでタグの中にstyle属性を

書くことにしたわけですが、

テーブルの要素一つ一つにstyleを手でちまちま書いていた日には、

いくら暇すぎる僕でも、

忙しくなりすぎる。

しかたないので、

Groovygroovy.xml.MarkupBuilder

使うことにしました。

何をやろうとしてたかというと、

仕訳を作ろうとしていたわけで、

いくらの投資でいくら回収できるという

話をするのに複式簿記がよくて、

それをGroovyで自動集計させながら、

最終的に総勘定元帳を作り出すというもの。

MarkupBuilder便利すな

ところで…

このスクリプトを書いている時に、

  • 簿記 (Bookkeeping)
  • 仕訳 (Journal)
  • 借方 (Debit)
  • 貸方 (Credit)

といった基本的な単語がわかってないことが

わかりました。

というわけで、

簿記・会計のドメインに強くなるべく、

この本を買ったとさ。

おわり。

mike、mikeなるままに…Githubに移動しました。

どーも、みけです。 Githubでブログを書くことにしました。

試しにgistのコードも載せてみます。

あまりマークダウン使いこなせてないんで、

良い感じの記事になるにはもうちょい時間かかると思う。