Scala Option symbolic syntax


#1

Saw something interesting in a modern Scala codebase and extrapolated this out of it:

/** Helpers to make Option syntax more succinct. */
object OptionUtils {
  /** Shortcut type symbol for the Option type. */
  type ?[A] = Option[A]

  /** Enables `foo.?` instead of `Some(foo)` */
  implicit class OptionSome[A](val a: A) extends AnyVal {
    @inline def `?`: ?[A] = Option(a)
  }

  implicit class OptionOps[A](val option: ?[A]) extends AnyVal {
    /** Enables `foo.!` instead of `foo.get`. Use with caution as usual! */
    @inline def `!`: A = option.get

    /** Enables `foo ?? bar` instead of `foo.getOrElse(bar)`. Called the
        nil-coalescing operator in Swift. */
    @inline def `??`(default: => A): A = option.getOrElse(default)

    /** Enables `foo ?? bar` instead of `foo.orElse(bar)`. */
    @inline def `??`(default: => ?[A]): ?[A] = option.orElse(default)
  }
}

Thoughts? Complaints? Note that Swift provides similar syntax ( https://developer.apple.com/documentation/swift/optional#2849660 ), so it’s not terribly innovative.


#2

Looks good except one spot. I’d change ?:

@inline def `?`: ?[A] = Option(a)

in case a is null.
Having two functions named ?? is a little confusing, since one returns an Option, while the other does not. Maybe ?! for the one that uses getOrElse?


#3

Thanks for the feedback! Agreed about using Option to guard against null. For the other one–I get your point, I just want an API where I don’t care about the specific types too much as long as it’s still type-safe and the basic logic is followed (this-or-that). Also, it works the same way in Swift without too much trouble :slight_smile:


#4

Nice idea. But I would use it as a personal tool, and then share the code without the sugar. I wander how I could transform the code back to Option (scalafix?)