kmizuの日記

プログラミングや形式言語に関係のあることを書いたり書かなかったり。

HOPEG 0.0.1リリースしました。

タイトル以上のことはほとんど書くことがないのですが、HOPEG、最初のリリースです。 詳しくは以下。

github.com

hopeg 0.0.1をlibraryDependencyに追加して、利用コードの中で

import com.github.kmizu.hopeg._
val grammar = HOPEGParser.parse(
  """
        |S = P("") !.; P(r) = "a" P("a" r) / "b" P("b" r) / r;
  """.stripMargin
)
val evaluator = HOPEGEvaluator(grammar)
evaluate.evaluate("abba", 'S) // "abba"は入力文字列 'Sは開始記号

のようにして使えます。マッチしたら、

Some[String]

マッチしなかったら

None

が返ってくる簡単なインタフェースです。今後は、

  • 型チェッカの実装
  • パーザの改善(パーズエラー時のメッセージの改善)

辺りやっていこうかと思います。それにしても、HOPEGの表現力、どうなってるんでしょうね?チューリング完全になってはいけないし、そうなってはいないと思うのですが…。First Order PEGの表現する言語は真に文脈自由言語を含んでいそうなのですが。

Higher Order PEG(HOPEG) がHiger Orderになりました

去年のエントリ

kmizu.hatenablog.com

でHigher Order PEG(HOPEG)の評価器を公開したと書いたのですが、その時点でのHOPEGは、まだ First Orderで、パラメタ付き規則自体は扱えても、規則そのものを引数として渡すことはできませんでした。で、最近、再びHOPEGについて考えていて、とりあえずHigher Orderにしてみようと一晩頑張ったらHigher Orderになりました。これによって、従来はできなかった

S = APPLY2(ALTER, "a", "b") !. ;
ALTER(x, y) = x / y ; 
APPLY2(F, x, y) = F(x, y) ; // aかbのどちらかにマッチする

みたいなのが書けるようになりました。ここでは、パラメタ付き規則APPLY2の第一引数自体がパラメタを取るようになっています。これによって当然表現能力は上がると思われるわけですが、どの程度のことが表現できるようになったかはよく考えていないので、いい例があれば教えてください…。

ところで、形式言語を作る(拡張)するというのは楽しいものですね。プログラミング言語の設計とはまた違った楽しさがあります。プログラミング言語の場合、本質的な表現能力は等価(チューリング完全)な上で、いかにして生産性を高くするかとか、安全性を高めるかとかいう目標を考えて設計するわけですが、形式言語を拡張したりする場合、そもそもその表現能力自体が変化するので、「どのように」表現能力が変化するのかに思いを巡らせるのが楽しいです。

とはいえ、自分もあくまでPEGという既存の形式言語を拡張しただけなので、そのうち、自分で一から形式言語(文法)を設計してみたいですね(?)

なお、ソースコード

github.com

にて公開中ですので、興味を持った型はスターを付けるなり、issueにドキュメント要望など書いてくださるとモチベーションが上がります。

Java Generics 導入の裏側

このエントリは、これまで自分がさんざんTwitterで書いてきたことですし、Martin Odersky教授へのインタビュー

www.artima.com

でおおむね語られていることでもあります。ただ、この辺の事情についてあまり詳しくない方も居るようなので、上記インタビューの引用を交えて、JavaGenericsが入るに至った経緯や関連して活躍した人物についても書いてみようと思います。

事の始まりは1995年にJavaが発表されたことでした。これに触発された、Philip Wadler先生(世界的に有名なコンピュータ科学者)、Martin Odersky先生と同じ研究室に居た助手さん?がこれでなんかやってみないかと煽ったらしく、翌年の1996年には、JavaGenerics高階関数、ADTなど関数型プログラミング言語の機能を入れ込んだPizza言語をMartin Odersky先生が発表することになります。

このPizza言語に関する仕事を知った、当時Sunのコアチームに居たGilad Brachaらが、「PizzaのGenericsは興味深いのでうんたらかんたら」といったことを言ったようで、これがJava Genericsの前身である「Generic Java(GJ)」チームの結成につながったようです。

GJチームの構成は公式ページにかかれていますが、

  • Philip Wadler
  • Martin Odersky
  • Gilad Bracha
  • Dave Stoutamire

というそうそうたる面子です(どのように凄いのかは略)。GJチームによって、1998年にはGJコンパイラが動作するようになりました。さて、実はこの時点で現時点でのJava Genericsの仕様は(Wildcardを除いて)ほぼ動作するようになっていたようです。raw typeのような仕様も、ソースコードの完全後方互換のためにこの時点でどうやら入ったようです。

個人的には、もっと早めにGenericsを取り込んでおけば良かったのに…と思うのですが、GJコンパイラはSunに買収され、JDK1.3から、Genericsをオフにして出荷されるということになったのでした。それから約6年の歳月を経て、ようやくJava Genericsは陽の目をみることになったのでした。

とはいっても、Sunがその空白の6年間、何もしていなかったかというとそういうわけではなく、

  • May 1999: Sun proposes to Add Generics to Java, based on GJ.(JSR14)
  • May 2001: Sun releases prototype for Adding Generics to Java.(based on the GJ compiler.)
  • January 2003: Generics headed for inclusion in Java 1.5.

このように、GenericsJavaに導入すべく動いていたようです。しかし、GJコンパイラとGJの仕様が1998年に既にあったことを考えると、あまりにも長い空白期間であったように思えます(政治的な事情があったのかもしれません。あとは、ワイルドカード導入(これはGJとの差分にあたる)にあたって何かあったのかもしれません)

ちなみに、Javaが初期にGenericsを持っていなかったのは、特別な設計ポリシーがあったわけではなく

Martin Odersky: When Java first shipped, Bill Joy and James Gosling and the other members of the Java team thought that Java should have generics, only they didn't have the time to do a good job designing it in.

意訳: Javaが最初に出荷されたとき、Bill JoyJames GoslingといったJavaチームはJavaにはGenericsがあるべきだと考えていたが、良い設計をする時間がなかったのだ

ということで、初期のJavaGenericsがないことを弁護していた方々はこれを知ったら何と思うんでしょうね…。

P.S. GJチームの中で、Odersky先生は主にGJコンパイラを書くことに注力していたようですが、他の面々はどの辺りの貢献があったのでしょうか?識者の方のツッコミお待ちしております。

過敏性腸症候群という病気

注意 以下は、お腹壊すとかそういう系統の話になりますので、苦手な方は読むのをご遠慮ください。

皆様、こんにちは。@kmizuです。そういえば、今日はScalaMatsuri 2016の2日目でしたね。私は何をしてたかと言えば、風邪&下痢で寝込んでいました。1日目もそうだったのですが、2日目は下痢で寝るのを妨害されたためかなり消耗しています。仮にもScalaMatsuri座長であるのに(今年は象徴座長みたいな面が強いですが(そもそも象徴にすらなっていたのか?))情けない限りです。

起きてみて、ふと唐突に、自分の持病である過敏性腸症候群について整理しておきたいなという気分になったので、これから書いてみることにします。だいたい個人の体験談であり、人によって症状の軽重は違うので私の症状が過敏性腸症候群を代表していると思わないでください。あとまあ、同情してもらう程の大層な病でもないと思っていますが、kmizuが居酒屋で突然トイレに駆け込んだりしたら、だいたいこれの症状だと思ってもらって間違いありません。

皆様、過敏性腸症候群IBS)という病気を聞いたことがある人はおられるでしょうか。結構メジャーな病気らしいので、恥ずかしいからと隠している人も含めると結構な数の人が知っているのではないかと思います。

基本的にWikipediaの記事でおおむねあってるので引用します。

過敏性腸症候群(かびんせいちょうしょうこうぐん、英語:Irritable Bowel Syndrome、略称:IBS)は、主として大腸の運動および分泌機能の異常で起こる病気の総称。検査を行っても炎症や潰瘍といった器質的疾患が認められないにもかかわらず、下痢や便秘、腹痛、ガス過多による下腹部の張りなどの症状が起こる。以前は大腸の機能の異常によって引き起こされる病気ということで「過敏性大腸症候群」と呼ばれていたが、最近では、大腸だけではなく小腸にも関係することなどからこのように呼ばれている。20 - 40歳代に多く、ストレスの多い先進国に多い病気である[1]。

ポイントは、検査を行っても炎症や潰瘍といった器質的疾患が認められないにもかかわらず下痢や便秘、腹痛、ガス過多による下腹部の張りなどの症状が起こることにあります。器質的疾患があったら個別の病名がついてくるはずですからね。

症状によって、大まかに

  • 不安定型(交代型) 腹痛および腹部の違和感、下痢と便秘が複数日間隔で交互に現れる(交代性便通異常)。
  • 慢性下痢型 少しでもストレスや不安を感じると下痢を引き起こす。神経性下痢などとも呼ばれる。
  • 分泌型 強い腹痛の後、大量の粘液が排泄される。
  • ガス型

大別されるようです。自分の場合は、慢性下痢型(だがたまに便秘になる)でしょうか。

この病気になったのは、つくばに居た博士後期課程1年(2008年)の秋頃です。当初はあまりにも下痢が続く(1カ月以上)ので、腸の病気か何かと思い腸の検査を受けたのですが特に何も見つからず、過敏性腸症候群と診断されました。それから約7年、この病気と付き合い続けています。

自分の型(慢性下痢型)が一番やっかいな点は、ちょっとしたストレスで下痢を引き起こすことです。本当にちょっとしたストレスです。たとえば、今日はちょっと身体がだるいなとか、Twitterやっててちょっと💢っとしたとかそのレベルでマジで下痢が起こります。もちろん、100%下痢になるというわけではないのですが、結構な確率で「当たり」ます。これのせいで、自分のメンタル状態を確認する癖がついてしまいました。

社会人になって最初の職場では、会社に到着するなりトイレに駆け込むというのが常態化していました(満員電車にもまれるのがストレスだったのかもしれません)。今の職場はストレスがかなり少ない方だと思いますが、それでも出社後何度かトイレに行くことが普通になっています。

この病気、それなりに歴史があるだけあって、ある程度治療法がありますが、個人差が大きいらしく、自分にはいずれの治療法も大きな効果が見られませんでした。せいぜいが、できるだけストレス源を避ける、くらいでしょうか。また、見ればわかるように、それほど劇的な症状があるわけではなく、単なる慢性下痢(これを単なると言っていいかは人によると思いますが)なので、病気自慢できるほどでもありません。

今でこそ慣れてそれなりに付き合い方を覚えた感じもありますが、日常生活の様々な場面で下痢が突然起こるというのは結構なストレス(また生活の質の低下)になります。そもそも、ストレスを起因として下痢が起こることが多いので、それによるストレスで悪化するという悪循環です。さらに、下痢が頻発するため、何度もお尻をトイレットペーパーで拭くことになり、これは痔にもつながりやすいです(実際に痔になったことがあります)。

また、今日みたいに、下痢が水様便になるくらいまで悪化することもたまにあり、こういう場合、一日トイレに釘付けになるのでそれによる機会損失も馬鹿になりません。この病気の治療法として、薬物療法の他にライフスタイルの改善も効果があるようなので、ちょっと真剣に改善に取り組もうかと考えている今日この頃です。

ここまで書いてきましたが、何かすぐに改善できるものでもなく、知人になんとなく自分の持病について知ってもらいたくて書いたのでした。なんとかなるといいのですが…。

最後に、ScalaMatsuriスタッフという立場でありながら当日参加できず、結果的に迷惑になってしまった他のScalaMatsuriスタッフの方々、申し訳ありませんでした。ともあれ、Twitterの様子を見る限り、成功裏に終わったようで何よりです。

Scalaのマクロは「実験的」(experimental)な機能です

タイトルがほとんど全てを表していますが、念のため説明します。

Scala 2.10からマクロが言語機能として導入され、Scala 2.11でも維持されています。ただし、あくまで現状のマクロは「実験的」な機能であり、ファイル毎に

import scala.language.experimental.macros

と書くか、コンパイラオプションで

-language:experimental.macros

と指定する必要があります。Scalaのライブラリ設計者には、新しい機能を使ってライブラリをもっと便利にしたいという人が多いことからか、マクロを使ったライブラリが既に多く存在しています。しかし、繰り返しますが、現状のマクロは「実験的」です。

Macros - blackbox vs whitebox - Scala Documentation

今の所は、Scala 2.12 ではマクロやリフレクション関連の変更は予定されていない。全機能が Scala 2.10 と 2.11 同様に実験的機能扱いのままで、機能が削除されることもない。本稿が書かれた背景となった状況は変わったが、書かれた内容はまだ生きているのでこのまま読み進んでほしい。

と書かれているので、Scala 2.12でも現状のマクロがそのまま使える可能性は高いですが、あくまで暫定的な判断であって、仕様が固まったわけではありません。マクロを使う事やマクロを使ったライブラリを使うことには多少のリスクが存在することを理解しておいてください。また、(コンパイル時に完全なプログラムを走らせることができる)マクロには、原理的にIDEによるサポートの恩恵が受けにくくなる(現在最良のScala IDEであるIntelliJ IDEAでさえ)というデメリットがあることも考える必要があります。以上を考慮した上でマクロを使うのは自由ですが、トレードオフが存在する事は意識する必要があります。