Introducing Aptus: a utility library to improve the Scala experience

Hi everyone,

This is an announcement for Aptus, a new open source utility library for Scala (Apache 2 license).

Here’s a hodgepodge of examples showcasing where it typically applies and how to use it:

// assuming: libraryDependencies += 
//   "io.github.aptusproject" %% "aptus-core" % "0.3.0"
import aptus._

"hello"                    .p // prints "hello"
"hello".assert(_.size <= 5).p // prints "hello"
"hello".assert(_.size >  5).p // assertion error
"hello".p.toUpperCase.p       // prints: "hello", then "HELLO"

"hello".append(" you!").p // prints "hello you!"
"hello".quote          .p // prints "\"hello\""
"hello".padLeft(8, ' ').p // prints "   hello"

"hello|world".splitBy("|").p // prints Seq(hello, world)

"hello".pipeIf(_.size <= 5)(_.toUpperCase).p // prints "HELLO"
"hello".pipeIf(_.size >  5)(_.toUpperCase).p // prints "hello"

"hello".in.someIf(_.size <= 5).p // prints Some("hello")
"hello".in.someIf(_.size >  5).p // prints None

Seq()    .force.option.p // prints "None"
Seq(1)   .force.option.p // prints "Some(1)"
Seq(1)   .force.one   .p // prints "1"
Seq(1, 2).force.one   .p // error
Seq(1, 2).force.option.p // error

"foo".in.some.p // Some("foo")
"foo".in.seq .p // Seq ("foo")

(1, 2).mapSecond(_ + 1) // prints (1, 3)

(Some(1), Some(2)).toOptionalTuple.p // prints Some((1, 2))

Seq(1, 2, 3).zipSameSize(Seq(4, 5, 6)).p // Seq((1,4), (2,5), (3,6))

implicit val ord: Ordering[Seq[Int]] = aptus.seqOrdering
Seq(Seq(4, 5, 6), Seq(1, 2, 3)).sorted.p // Seq(Seq(1, 2, 3), Seq(4, 5, 6))

Seq(1 -> "a", 2 -> "b")          .force.map.p // Map(1 -> "a", 2 -> "b")
Seq(1 -> "a", 2 -> "b", 2 -> "c").force.map.p // error

Seq(1, 2, 3, 4, 5).slidingPairs // Seq((1, 2), (2, 3), (3, 4), (4, 5))

().fs.homeDirectoryPath().p // prints "/home/tony" (for me)
"echo hello".systemCall() // prints: "hello"

Seq("hello", "world").writeFileLines("/tmp/lines.gz")
"/tmp/lines.gz".readFileLines().p // prints: Seq("hello", "world")

More thorough examples can be found on the main README page, along with how to set it up, and the motivation for creating it.

I would love to hear your thoughts on it! In particular I’m curious to hear about some of the examples I describe in the README page, such as this one or that one. Do you:

  1. Never encounter such situations, or too rarely to care
  2. Encounter them but prefer to:
    • a. Use the manual way
    • b. Not code defensively
    • c. Create your own utility methods
    • d. Use another library to handle them (if so which?)

Thank you!

Anthony (http://anthonycros.com)