scala

warning: Creating default object from empty value in /opt/bitnami/apps/portal/htdocs/modules/taxonomy/taxonomy.pages.inc on line 33.

scopt 4

in

scopt 4 における関数型 DSL は以下のようになる:

import scopt.OParser
val builder = OParser.builder[Config]
val parser1 = {
  import builder._
  OParser.sequence(
    programName("scopt"),
    head("scopt", "4.x"),
    // option -f, --foo
    opt[Int]('f', "foo")
      .action((x, c) => c.copy(foo = x))
      .text("foo is an integer property"),
    // more options here...
  )
}
 
// OParser.parse returns Option[Config]
OParser.parse(parser1, args, Config()) match {
  case Some(config) =>
    // do something
  case _ =>
    // arguments are bad, error message will have been displayed
}

OptionParser 内でメソッドを呼ぶのではなく、関数型 DSL はまず特定の Config データ型に対するビルダーを作って、opt[A](...) など Oparser[A, Config] を返す関数を呼ぶ。

これらの OParser[A, Config] パーサーは OParser.sequence(...) を用いて合成できる。

最初は for 内包表記を使ってこの合成を表すことも考えていたが、その見た目に慣れて人にとっては分かりづらいと思ったので sequence 関数を作った。

scala.Seq のマスキング

in

現行の Scala 2.13.0-M5 のままで行くと、scala.Seqscala.collection.Seq から scala.collection.immutable.Seq に変更される予定だ。Scala 2.13 collections rework に何故今まで不変じゃなかったのかの解説が少し書かれている。行間から推し量ると、scala.Seq がデフォルトで不変になることを喜ぶべきだと言っているんだと思う。

デフォルトで列が不変になることはアプリや新しく書かれるコードには良いことだと思う。ライブラリ作者にとってはもう少しこみいっているかもしれない。

  • あなたがクロスビルドされたライブラリを持っていて
  • ライブラリのユーザも複数の Scala バージョンを使っていて
  • ライブラリのユーザが Array(...) を使っていた場合

この不変 Seq への変更は、breaking change つまり非互換な API 変更となりうる。

-Xlint, -Xfatal-warnings, そして Scalafix を用いた Scala の厳格化

in

コンパイルする、さもなければコンパイルしない。警告などいらない。最近気に入っている Scala コンパイラのフラグは "-Xlint""-Xfatal-warnings" の 2つだ。

以下は、サブプロジェクトと共に使えるセッティングの例だ:

ThisBuild / scalaVersion := "2.12.6"
 
lazy val commonSettings = List(
  scalacOptions ++= Seq(
    "-encoding", "utf8",
    "-deprecation",
    "-unchecked",
    "-Xlint",
    "-feature",
    "-language:existentials",
    "-language:experimental.macros",
    "-language:higherKinds",
    "-language:implicitConversions"
  ),
  scalacOptions ++= (scalaVersion.value match {

sbt-nocomma を用いたカンマの消去

in

本稿は build.sbt からカンマを消去する nocomma { ... } マクロを導入する sbt-nocomma を紹介する。

import Dependencies._
 
lazy val root = (project in file("."))
  .settings(nocomma {
    ThisBuild / organization := "com.example"
    ThisBuild / scalaVersion := "2.12.4"
    ThisBuild / version      := "0.1.0-SNAPSHOT"
 
    name := "Hello"
 
    // comment works
    libraryDependencies += scalaTest % Test
  })

猫番: 17日目

in

猫番: 17日目を書いた。始対象と終対象、積、双対性、余積など抽象構造を見ていきつつ、Either を coproduct として使う方法を紹介します。

ファイルパスの URI 参照へのエンコード方法

in

本稿では古くて新しい問題であるファイルパスの Uniform Resource Identifier (URI) へのエンコード方法について議論する。

2017年現在、権威ある情報の元は RFC 8089 - The "file" URI Scheme だ。未来の読者の人は "file URI scheme RFC" で検索して最新版を探してほしい。プログラマの人は RFC を読んで下さい。この覚え書きは URI エンコーディングに関連した問題の認識を高めるためのものだが、RFC の代替とはならない。

最近 file:/foo/bar がパースできないというプラットフォーム間の相互乗り入れ問題に出くわした。ファイルパスを URI として表現するのに関連した問題に悩まされるのはこれが最初でもない。ファイルシステムという概念は 1960年代に遡り、1990年代から URL があることを考えると、このコンセンサスが取れていないというのは意外なことだ。しかし、十進法小数のように、深く掘り下げたり、データを交換しはじめると、Matrix のほころびが見えてくるのかもしれない。

Contraband、case class の代替案

in

しばらく考えている疑問がいくつかある:

  • データや API はどう書かれるべきだろうか?
  • そのデータは Java や Scala ではどう表現されるべきか?
  • そのデータは JSON などのワイヤーフォーマットにどう変換することができるか?
  • そのデータをどうやってバイナリ互換性を崩さずに進化させることができるか?

case class の限界

Scala でデータ型を表現する慣用的な方法は sealed trait と case class だが、バイナリ互換性を保ったままフィールドを追加することができない。簡単な Greeting という case class を例に取って、それがどのようなクラスとコンパニオンオブジェクトに展開されるか考察してみよう:

package com.example
 
class Greeting(name: String) {
  override def equals(o: Any): Boolean = ???
  override def hashCode: Int = ???
  override def toString: String = ???
  def copy(name: String = name): Greeting = ???
}

Gigahorse 0.2.0

in

Gigahorse 0.2.0 をリリースした。新機能は 2つのバックエンドを選べるようになったことだ。
@alexdupre さんが AHC 1.9 から Netty 4 ベースの AHC 2.0 への移行をコントリビュートしてくれた。#12

さらに、#15 で僕が実験的な Akka HTTP サポートを追加した。

詳しくは Gigahorse ドキュメントを参照してほしい。

Scala 2.12.0 リリースノート

in

昨日リリースされたばかりの Scala 2.12.0 のリリースノートを翻訳しました。
Lightbend 社 Scala チームのコンパイラ魂を感じ取れる、マニアな内容になっています。

Scala 2.12.0 がリリースされました!

Scala 2.12 コンパイラは Java 8 から使えるようになった新しい VM 機能を利用するために、完全なオーバーホールが行われた。

sjson-new とアズカバンの囚人

in

本稿は sjson-new に関する第3部だ。パート1パート2も是非読んでみてほしい。

sbt のコード内にはデータ永続化が数百メガバイトのオーダーに達している部分がいくつかあって、特にマシンに SSD が積まれていない場合は性能ボトルネックになる疑いがあるんじゃないかと思っている。
当然、最初に飛びついたのは Google Protocol Buffers のエンコーディングを参考に独自のバイナリフォーマットを実装することだった。

sbt-jmh を用いたマイクロベンチマーク

僕がまずやるべきだったのは、ベンチマークを取ることだ。@ktosopl (Konrad Malawski)君の sbt-jmh を使うとマイクロベンチマークは簡単に作ることができる。ビルドにプラグインを入れて、JmhPlugin を有効化したサブプロジェクトを定義するだけだ。

Syndicate content