kagamihogeの日記

kagamihogeの日記です。

JEP 289: Deprecate the Applet APIをテキトーに訳した。

http://openjdk.java.net/jeps/289 をテキトーに訳した。Javaの歴史を感じる……

JEP 289: Deprecate the Applet API

Owner    Daniil Titov
Created 2016/02/09 22:36
Updated 2016/05/26 17:34
Type    Feature
Status  Completed
Component   deploy?/?plugin
Scope   SE
Discussion  jdk9 dash dev at openjdk dot java dot net
Effort  XS
Duration    XS
Priority    3
Reviewed by Andy Herrick, David Dehaven, Kevin Rushforth, Stuart Marks
Endorsed by Kevin Rushforth
Release 9
Issue   8149502

Summary

Applet APIを非推奨化します。webブラウザベンダはJavaブラウザプラグインサポートを削除するため、このAPIはもはや重要でなくなってきています。開発者には代替テクノロジとしてJava Web Startやインストールするアプリケーションなどを紹介します。

Motivation

webブラウザでJavaアプレットを実行するにはブラウザプラグインの使用を必要とします。しかし、2015年後半時点で、ブラウザベンダの大半はプラグインサポートを削除済みであるか、削除に向けてのタイムラインをアナウンスしています。ブラウザプラグインが無くなれば、Applet APIを使う理由は無くなります。

Description

以下のクラスに@Deprecated(since="9")アノテーションを追加します。

  • java.applet.AppletStub
  • java.applet.Applet
  • java.applet.AudioClip
  • java.applet.AppletContext
  • javax.swing.JApplet

次回のメジャーリリースにおいてはApple APIの削除は予定していません。よって、アノテーションにはforRemoval = trueを指定しません。これ以降にAPIの削除提案を行う段階で、前もって少なくとも一度のメジャーリリースにおいてアノテーションforRemoval = trueを追加します。

appletviewerツールも同様に非推奨化します。非推奨化の警告はツール開始時に標準エラーストリームに出力されます。

Risks and Assumptions

APIを使用する全コードに対してJavaコンパイラが非推奨化の警告を出す可能性があります。もし警告がエラーとして扱われる場合、ビルドエラーとなる可能性があります。

JEP 286: Local-Variable Type Inferenceをテキトーに訳した

http://openjdk.java.net/jeps/286 をテキトーに訳した。英語とJavaの勉強には丁度良かろうと読んでみたけど、型推論の知識あんま無いんでかなり苦戦した。なので、誤訳してる可能性がかなりあると思います。

JEP 286: Local-Variable Type Inference

Author   Brian Goetz
Owner   Dan Smith
Created 2016/03/08 15:37
Updated 2016/03/09 20:18
Type    Feature
Status  Candidate
Component   specification?/?language
Scope   SE
Discussion  platform dash jep dash discuss at openjdk dot java dot net
Effort  M
Duration    S
Priority    3
Reviewed by Alex Buckley, Mark Reinhold
Endorsed by Mark Reinhold
Issue   8151454

Summary

ローカル変数宣言初期化子の型推論(type inference)を拡張するためにJava言語を改良します。

Goals

我々はJavaコード記述時に関する儀式的な箇所を削減することで開発者向けの使い勝手向上を図っています。静的な型安全性というJavaの約束事は維持しつつ、多くの場合に不要なローカル変数型の明示的な宣言(manifest declaration of local variable types)を削除することで実現します。この機能は例えば以下のような宣言になります。

var list = new ArrayList<String>();  // ArrayList<String>と推論
var stream = list.stream();          // Stream<String>と推論

この方法は、ローカル変数の初期化子・拡張forループのインデックス・従来型forループのローカル宣言のみに制限されます。なお、メソッド仮引数・コンストラクタ仮引数・メソッド戻り値型・フィールド・catch仮引数・その他の変数宣言では利用出来ません。

Success Criteria

適切な型を推論する本機能により、実際のコードベースのローカル変数宣言の相当量が変換可能なことを定量的に示したいと考えています。

定性的には、我々はローカル変数型には制限を設けたいと考えており、これらの制限を設ける動機は、一般的なユーザに利用しやすくするためです。(これは当然ながら一般的に達成困難です。すべてのローカル変数に妥当な型を推論することは出来ないというだけでなく、ある種のユーザは、制約解決(constraint solving)のアルゴリズムというよりは型推論を読心術(mind reading)の一種だと夢想しています。その場合には何の説明もしないほうが実用的かもしれません。)我々はある方法で線引きを設けようとしています。この方法では、ある特定の構成要素(particular construct)が境界線を越えるかどうかを明確に出来ます。また、この方法では、言語の任意の制限というよりは、コンパイラ診断によりユーザのコードの複雑さと効果的に結び付けることが可能です。

Motivation

開発者はおおむねJavaが要求するボイラープレートの度合いに不満を持っています。ローカルでの明示的な型宣言はおおむね不要と解釈可能であるか、何の役割なのか明確で適切な変数名によっても同様に不要と解釈可能です。

また、すべての変数に明示的な型を付ける必要性は、開発者に無意識のうちに過度な複雑な式をかかせる方向へと向かわせます。儀式的な宣言シンタックスが少ない状態では、複雑なチェーンあるいはネストした式をシンプルな式へと分解するための障害は少なくなります。

おおむねすべてのその他の一般的な静的型付け"中括弧"("curly-brace")言語では、JVMベースのものもそうでないものも、既にローカル変数型推論をサポートしています。C++(auto), C#(var), Scala(var/val), Go(declaration with :=). Javaはおそらくローカル変数型推論を採用していない唯一のメジャーな静的型付け言語であり、この点については、議論の余地はありません。

型推論の範囲はJava SE 8で広範囲に広がりました。これには、ラムダ式の推論と、ネストおよびチェーンされたジェネリックメソッド呼び出しのために拡張された推論を含みます。Java SE 8の変更によりメソッドチェーンを行うAPIの設計が容易となり、そうしたAPI(Streamsなど)はごく一般的なものとなり、開発者は中間型の推論については既に慣れ親しんだものとなっています。例えば以下のチェーンなどです。

int maxWeight = blocks.stream()
                      .filter(b -> b.getColor() == BLUE)
                      .mapToInt(Block::getWeight)
                      .max();

誰も中間型Stream<Block>IntStreamについて思い悩まない(し気付かない)し、ラムダ式bの型も同様で、これらの型はソースコード上には明示的に現れません。

ローカル変数型推論は柔軟な構造を持つAPIと同様の効果をもたらします*1。ローカル変数の用途の大半は本質的にチェーンであり、推論によるメリットを多くのケースで受けられます。

var path = Path.of(fileName);
var fileStream = new FileInputStream(path);
var bytes = Files.readAllBytes(fileStream);

Description

初期化子有りのローカル変数宣言・拡張forループのインデックス・従来型forループのインデックス変数宣言では、予約型名varが明示的な型の代わりに指定可能となります。

var list = new ArrayList<String>(); // ArrayList<String> と推論
var stream = list.stream();         // Stream<String> と推論

推論される型は初期化子の型に基づきます。初期化子が無い場合、初期化子はnullリテラルとなり、初期化子の型が適切なdenotable type(intersection typeとcapture typesを含む)に正規化可能なものが無いか、初期化子がターゲット型を要求するpoly expressionの場合(ラムダ式・メソッド参照(method ref)・暗黙的な配列初期化子(implicit array initializer))、その変数宣言はエラーになります。

final varのシノニムとしてvalないしletの追加も考えています。(大抵の場合、varで宣言するローカル変数は実質的にfinalです。)

var識別子はキーワードに入れるのではなく、予約型名(reserved type name)となります。つまり、変数やパッケージ名としてvarを使うコードは影響を受けません。クラスやインタフェース名としてvarを使うコードは影響を受けます(とはいえそうした名前は命名規則に違反していますが)。

初期化子の無いローカル変数の除外により"action at a distance"*2推論エラーを排除します。これにより一般的なプログラムのごく一部は型推論が出来ないことになります。

非denotableな型を持つ右辺式を除外することで機能はシンプルになりリスク軽減になります。しかし、すべての非denotable型を除外することは厳格すぎると思われます。実際のコードベースを分析すると、capture types(とそれより低い頻度で無名クラス型)がそれなりの頻度で現れます。無名クラス型は容易にdenotable型に正規化されます。例えば。

var runnable = new Runnable() { ... }

たとえ推論がより具体的な型(sharper type)であるFoo$23を生成したとしても、runnableの型はRunnableに正規化します。

同様に、capture types Foo<CAP>では、ワイルドカードFoo<?>に正規化が可能です。これらのテクニックにより推論が失敗するケースを劇的に減らせます。

JDKソースコードでプロトタイプを実行したところ、

  • 83.5% ソースコード内に存在する実型に推論された。
  • 4% 別のdenotable typeに推論された。(大抵はより具体的な型(sharper type))
  • 0% 推論した型が非denotableなために失敗した。
  • 8.5% 初期化子が無いために失敗した。
  • 3% 初期化子がnullなために失敗した。
  • .5% ターゲット型が要求されるために失敗した。

初期化子が無いものやnullで失敗したケースを除くと、ローカル変数の99%が推論可能であり、95%がソースコード内に存在する実型に推論されました。

(全ローカル変数の77%の)実質的にはfinalなローカル変数では、

  • 86% ソースコード内に存在する実型に推論された。
  • 4.5% 別のdenotable typeに推論された。(大抵はより具体的な型(sharper type))
  • 0% 推論した型が非denotableなために失敗した。
  • 8% 初期化子が無いために失敗した。
  • .5% 初期化子がnullなために失敗した。
  • .5% ターゲット型が要求されるために失敗した。

Alternatives

ローカル変数型に明示的な宣言が必要なままにすることも可能です。

代入の左辺においてダイアモンドをサポートすることも可能です。これはvarが扱うケースのサブセットとなります。

これまでに述べた設計ではスコープ・シンタックス・非denotable typeについての決定事項を含んでいます。挙げられた別案についてもこのドキュメント内で述べます。

Scope Choices

本機能について詳細な調査をしていたかもしれない別案がいくつか存在します。その一つとして、実質的にはfinalなローカル変数(val only)に機能を制限する、というものです。しかし、我々はこの案は採用しませんでした。理由としては、

  • 初期化子を持つローカル変数の大半(JDKおよび広範な資料の75%以上)はすでに実質的にはイミュータブルで、本機能が提供するミュータブルを避ける微調整("nudge")を制限することになります。
  • ラムダ・内部クラスによるCapturabilityは実質的にはfinalなローカル変数を既に提供しています。
  • In a code block with (say) 7 effectively final locals and 2 mutable ones, the types required for the mutable ones would be visually jarring, undermining much of the benefit of the feature.

我々は空のfinal("blank" finals)(つまり初期化子を必要とせず、代わりにdefinite assignment analysisに依存)のローカル変数を含めるように本機能を拡張することも検討しました。我々は"初期化子有りの変数"という制限に決定しました。その理由は、機能の簡潔さを維持しつつ候補となる変数の大半をカバーし、また、"action at a distance"エラーを減らすためです。

また、型推論時に初期化子だけでなくすべての代入式を考慮することも検討しました。本機能が利用可能なローカル変数の割合を引き上げられる一方で、"action at a distance"エラーのリスクも向上します。

Syntax Choices

シンタックスについて多様な意見が出るのはごく自然なことです。その多様さには大きく分けて二種類あり、使用するキーワード(var, autoなど)と、イミュータブルなローカル変数(val, let)形式には新規で別途のものを設けるかどうか、です。我々は以下のシンタックスに関する意見を議論しました。

  • var x = expr only (like C#)
  • var, plus val for immutable locals (like Scala, Kotlin)
  • var, pluslet``` for immutable locals (like Swift)
  • auto x = expr (like C++)
  • const x = expr (already a reserved word)
  • final x = expr (already a reserved word)
  • let x = expr
  • def x = expr (like Groovy)
  • x := expr (like Go)

イミュータブルなローカル変数(val, let)用に別の形式を持つかどうかはトレードオフがあり、設計意図を捕らえるために余計な労力が追加されます*3。我々は既にラムダとinner class captureにおいて実質的にはイミュータブルに関する分析を結果を得ており、ローカル変数の大半は既に実質的にはイミュータブルです。ある種の人々はvarvalの類似性を好み、コードを読む際には相違点は気にならないとする一方、そうでない人は似ているからこそ気が散る、と言います。また、ある種の人々はvarletが全く異なるのを好む一方、そうでない人はその違いに気が散らされる、と言います。(新しい形式をサポートするとしたら、その形式は(valletの双方で)構文上の重みは同等(equal syntactic weight)にすべきでしょう。怠惰であることにより、ユーザがイミュータブル宣言を省略する可能性を減らせます。)

autoは実現可能な選択肢ですが、JavaデベロッパC++よりかはJavascript, C#, Scalaの経験を持っていることが多いため、C++のエミュレートにはあまり価値がありません。

constfinalの使用は、新規キーワードの導入ではないため、当初は魅力的に映りました。しかし、このやり方ではミュータブルなローカル変数での推論は実行出来なくなります。defも同様な欠点があります。

goのシンタックス(代入演算子に別の種類を設ける)はあまりJavaっぽくないです。

Non-Denotable Types

nondenotable types(null型、無名クラス型、capture types, intersection types)に関する処理方法はいくつかの選択肢があります。エラーにする(明示的な型を要求)、推論型として許容する、denotable typesへの"変換"("detune")を試行する、が挙げられます。

エラー派の意見には以下などがあります。

  • リスクの縮小。captureとintersectionsなどのweird typesには仕様とコンパイラの両面で周知の落とし穴が多数あります。変数がこれらの型を持つのを許容すると、広く使用されるようになる可能性があり、そうすると落とし穴が顕在化してユーザを困惑させることになります。(我々はこれらの浄化に取り組んではいますが、この作業は時間が必要です)
  • 発現性温存(Expressibility-preserving). non-denotable typesをエラーにすることで、varを持つプログラムはvar無しのプログラムへと単純に変換することになります。

許容派の意見には以下などがあります。

  • チェーン呼び出しではdenotable typeの推論を既に行っているので、so it is not like our programs are free of these types anyway, or that the compiler need not deal with them.
  • capture type不要と考える場合、以下のケース(var x = m(), m()Foo<?>を返す)でcapture typeが使われるため、これをエラーにするとユーザは不満を抱く可能性がある。 これまでに述べたように我々はエラー派のアプローチを取っています。しかし、capture variablesを含むケースではこの制限にユーザが当惑することも認識しています。例えば、以下の推論です。
var c = Class.forName("com.foo.Bar")

この式の型は"明らかに"Class<?>ですが、推論はcapture type Class<CAP>を生成します。よって、我々はワイルドカードに変換可能なcapture variablesでは"uncapture"を取ることに決めました(this strategy has applications elsewhere as well)。capture typesは結果を汚染しかねない場合が数多くあるため、このテクニックは有効です。

また、我々は無名クラス型をそのスーパータイプに正規化します。intersectionないしunion typesは正規化しません。最後に、我々が推論不可能としている残りは初期化子がnullの場合です。

Risks and Assumptions

リスク:Javaには既に右辺(ラムダ式ジェネリックなメソッド型引数、ダイアモンド)での型推論(significant type inference)*4が存在するため、こうした式の左辺でvar/valを使用すると失敗する可能性があり、エラーメッセージから原因を読み取るのが難しくなる可能性があります。

左辺が推論される場合にはエラーメッセージを単純化することで軽減を図っています。

Main.java:81: error: cannot infer type for local
variable x
        var x;
            ^
  (cannot use 'val' on variable without initializer)

Main.java:82: error: cannot infer type for local
variable f
        var f = () -> { };
            ^
  (lambda expression needs an explicit target-type) 

Main.java:83: error: cannot infer type for local
variable g
        var g = null;
            ^
  (variable initializer is 'null')

Main.java:84: error: cannot infer type for local
variable c
        var c = l();
            ^
  (inferred type is non denotable)

Main.java:195: error: cannot infer type for local variable m
        var m = this::l;
            ^
  (method reference needs an explicit target-type)

Main.java:199: error: cannot infer type for local variable k
        var k = { 1 , 2 };
            ^
  (array initializer needs an explicit target-type)

リスク:non-denotable typesの推論は仕様およびコンパイラで以前から微妙だった箇所を顕在化させる可能性があります*5

軽減策としては一般的なnon-denotableについては正規化し、残りはエラーにします。

リスク:ソースの非互換性(型の名前として"var"を使っているユーザがいるかもしれない)

予約型名により軽減する。"var"と"val"などの名前は型の命名規則には準じていないため、型として使われている可能性は低いです。識別子としては"var"と"val"という名前はありふれています。こちらは特に問題ありません。

リスク:可読性の低下、リファクタリング時の困惑。

他言語の機能で見られるように、ローカル変数型推論を使うことでコードは明瞭にも不明瞭にもなりえます。最終的には、明瞭なコードを書く責任はユーザにあります。

*1:原文は Local variable type inference allows a similar effect in less tightly structured APIs; less tightly structured APIはつまりStreams APIみたいにメソッドチェーンで柔軟な記述が可能な設計のAPIを指してると思われる。直訳すれば『あまり密には構造化されていないAPI』だが、ここでは『柔軟な構造を持つAPI』とちょっと意訳した。

*2:何かを宣言したコードからかなり離れたコードでその宣言が何かをやらかすこと。グローバル変数の悪影響を論じる時とかに使われる単語っぽい。

*3:a tradeoff of additional ceremony for additional capture of design intent.が原文。上手く訳せなかったが、たぶん、新しい構文を増やすほど理解するのが大変になる、って感じだと思う(たぶん)

*4:この場合のsignificantは何と訳すのが良いかニュアンスが分からんので訳文には含めず

*5:原文はmight press on already-fragile pathsで、直訳だと『壊れやすい箇所にプレッシャーをかける』くらいの感じだが、要するに前からヤバい箇所が新しいブツにより浮き彫りになるかも、という意味だと思うんで、こういう訳にした

アトラス作品ファン交流会の眼鏡祭第24回(2016/04/16)に行ってきた

4/16 幻影眼鏡祭24♯FE - TwiPla に行ってきました。これはそのレポートになります。当日の様子はtwitterハッシュタグ#眼鏡祭0416から追うことが出来ます。

眼鏡祭とは

眼鏡祭はペルソナを中心したアトラス作品ファンのオフ会で、今回で24回目となりました。参加者数は200人超で、会場はキリストンカフェ 東京を貸切っての開催です。元々はペルソナ4のオフ会から出発したためにその頃からの参加者が多く、年齢層は30代以上がボリュームゾーンとなっています。ただし、ペルソナ4のアニメやペルソナ3の映画から入ってきた20台前半や、その他のアトラス作品から眼鏡祭を知って初めて来た方も毎回一定数存在します。今回もおおよそ2~3割の参加者が初回ないし二回目のため、大規模ながらもフレッシュな感覚のあるオフ会となっています。

眼鏡祭の特徴

眼鏡祭の特徴は、なんといってもコスプレな可能なオフ会な点でしょう。

上記は毎回恒例の全体集合写真です。参加者のうち、おおむね7~8割がコスプレをしているためこの写真のインパクトは相当なものがあります。

コスプレの作品・キャラ傾向ですが、やはりペルソナ3・4が中核を成しているのですが、今回はかなりバラけた印象があります。千枝が何故だか大量に居たり、根強いファンのいるペルソナ2 罪・罰のキャラが闊歩してるかと思えば、デビルサバイバー勢が一団を築いており、キャサリンの危険な大人の香り漂うグループが歩いていたり、アトラス作品ファンにはホットな真・女神転生IV FINAL(ファイナル)のキャラがいたり、人ならざる悪魔・ペルソナが徘徊していたり。眺めているだけでも圧倒される空間でした。

コスプレについて

眼鏡祭のコスプレの位置づけは、あくまでもコミュニケーションのツールの一つに過ぎません。ガチのレイヤーであれば技術の粋を結集した衣装を準備したりもしますが、そうでない人はそうでないなりの工夫を楽しんでいます。コスプレで話題作りというか、そのコスプレをしているということはそのキャラや登場作品に何らかの思い入れがあることの表れなので、自分も同じ考えであれば会話の切欠になります。コスプレは話しかける切欠がそのまま歩いているようなものです。もちろん、コスプレをして昼間から酒飲んで高まるのがただひたすらに楽しい、という要因もあります。

なお、眼鏡祭はコスプレが可能なオフ会であってコスプレイベントではありません。そのため参加者に課されるルールとして、写真撮影の際には必ず了承を取ること、また、その写真をtwitterなどSNSにアップする際にも了承を取ること、が設けられています。眼鏡祭でしかコスプレしない人もかなりの数で存在します。とはいえルールといっても大人の良識に収まるものなのでそこまで肩肘張るものでもありません。

ビギナー向け配慮

眼鏡祭は200人超の大規模オフ会のため、初心者向け配慮がかなり成されています。

参加者は上記のような名札をぶら下げるのですが、熟練度別に色分けがされています。何か困ったときにスタッフを見分けやすいためは当然として、赤色のビギナーには青色のスタッフや黒色の常連が積極的に話しかけたりなどをやりやすくしています。

参加者が会場に来ると、まず事前に振り分けられたコミュニティ別のテーブルに向かいます。

f:id:kagamihoge:20160424164833j:plain

このコミュニティはおおむね7~8人で、内訳はスタッフが1ないし2名、常連が4~5人、ビギナーが3~4人ぐらいのイメージです。ここのテーブルで仲良くなった人がいたらそのままそこに居てもいいし、乾杯後の自由時間に積極的に動き回っても大丈夫です。

会話のツールとして毎回色々な趣向が凝らされたツールが用意されるのですが、その一つがこのゲーマー履歴書です。私は当初こんなもん細かく書いていられるかと疑問視していましたが、意外にもみんな思い思いに書き込んで楽しんでおり、そして互いに見せ合って盛り上がっていたので、かなり成功を収めていました。やっぱり皆ゲームマンガアニメのこと話したり聞いたりしたいんですよね。

毎回恒例で配布されるノベルティのカードやポストカードも気合が入っています。これは各々3枚しか配られないので、目当てのカードが欲しければ、同コミュニティや会場を歩き回って交換なり何なりをするしかありません。

会場の様子

f:id:kagamihoge:20160424165203j:plain

眼鏡祭は特にコレといって決まったコンテンツはありません。乾杯が終わったあとは完全な自由行動です。先に書いたとおり、初期配置のコミュニティのテーブルに居てもいいし、推しキャラをファインダーに収めるべくウロウロしまくっても構わないし、DJの流す音楽に身を委ねていても良いです。

f:id:kagamihoge:20160424165311j:plain

スタッフがマイクで作品別・キャラ別など何らかのテーマ性のコスプレの集合写真を撮ります、という呼びかけも参加者の要望ベースで行われていました。会場のキャパシティは200人を超えても問題無いのですが、全員が立って歩き回れるほどのスペースはありません。そのため、同一作品のキャラクターをしている者同士で集合するのも一苦労です。そのため、その手間をスタッフが肩代わりしているのは良い仕事と言えるでしょう。コスプレをコスプレしてる人が撮りまくる光景は中々にコミカルです。

実際どうよ

先にも少し書きましたが、ゲーム・マンガ・アニメなどオタク話をしたいものなんですよね。その中でも更にアトラスゲーとなると、より偏屈度が増すというか、話が通じる可能性が下がります。そこで眼鏡祭はというと、少なくとも大体皆ペルソナ3・4は知っているし、他のアトラス作品もかなりの確率で知っている人が多いし、少なくとも話題に上げて変な顔する人はいません。

真4fのすれ違い通信が一瞬で32人行くような場所はそうは無いでしょう。

スタッフのがんばり

眼鏡祭の運営は基本的にボランティアベースです。会場や飲食はキリストンカフェのものですが、イベント会社を使っているとかそういうわけではありません。イラストや名札などの準備、告知や宣伝、会場のテーブル移動や元に戻す作業、受付と金銭管理、会場進行やアナウンス、男女別更衣室の管理、各コミュニティのスタッフなどなど。これ以外にも人知れぬ苦労が随所にあることでしょう。

この辺りは素直に感謝するしかありません。主催のマソーさん、スタッフの皆さん、今回の参加者に私と会話してくれた方々、それとこの日記で眼鏡祭のことを伝えるにはこのツイートが良かろうと特に承諾を得ず引用させて頂いた一連のツイート。今回も非常に楽しいイベントでした。

次回の眼鏡祭とその他のイベント

次回の眼鏡祭は7/2です。参加登録はこちら -> 7/2 アトラスとかペルソナが好きな人が集まる眼鏡祭25 Final - TwiPla

なお、眼鏡祭はやたらに人が多いのでここだけで知り合いや友達を作るのはオカン級でないと難しいものがあります。そういうわけで、眼鏡祭の人間が多く集まり、かつ、眼鏡祭本体よりかは人数が少ないイベントに繋げていくことを、主催のマソーさんもオススメしています。

上のツイートで眼鏡祭の主催でもあるマソーさんが紹介しているのは、終わっちゃいましたが4/23 眼鏡祭おかわり会!という最初から私服で眼鏡祭を肴に盛り上がる飲み会、ジュヴナイルの雄4/30 東京魔人学園を語る会in東京ゲーム音楽DJイベント「スーパーギルガメッシュナイト 5/10、ゲーム好きが集まる5/14 ゲーマーズギルドリターナー会、といったところです。

他にも千枝会だとか平成会だとかガンプラ会だとか、眼鏡祭でコスプレ興味持ったけど何していいか分からん人向けに【5/29眼鏡勢で!】コスプレしてみよう! - TwiPlaが立ったりとか、まぁなんというか……色々です。個人ですべてのイベントを追跡出来るものでもないし、するもんでもないですが、自分と相性良さそうなイベントにとりあえず出入りしてみると良いんでないでしょうか。

リンク

おまけ