Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Brief tour of psp-std

1,633 views

Published on

Some slides about some software.

Published in: Software
  • Be the first to comment

Brief tour of psp-std

  1. 1. psp-std a nonstandard library github.com/paulp/psp-std
  2. 2. Things I like. • -Yno-imports -Yno-predef • -Yno-adapted-args • consistency • correctness • convenience • no dependencies
  3. 3. A consciously constructed namespace. // This is only a sliver. type Any = scala.Any type GTOnce[+A] = sc.GenTraversableOnce[A] type tailrec = scala.annotation.tailrec type sciList[+A] = sci.List[A] type sciMap[K, +V] = sci.Map[K, V] type IOException = jio.IOException
  4. 4. Size, not lies. /** The Size hierarchy is: * Size * / * Atomic Bounded * / * Infinite Precise */
  5. 5. Julia! Lua! Over here! final class Vindex[Base] private[std](val indexValue: Long) extends AnyVal type Index = Vindex[Zero.type] type Nth = Vindex[One.type] psp> 1 to 3 apply 1 Main.scala:1004: type mismatch; found : Int(1) required: psp.std.all.Vdex psp> 1 to 3 apply 1.index res3: Int = 2 psp> 1 to 3 apply 1.nth res4: Int = 1
  6. 6. Type classes, not for show (Except for Show) trait Eq[-A] extends Any { def eqv(x: A, y: A): Bool } trait Hash[-A] extends Any { def hash(x: A): Long } trait Order[-A] extends Any { def less(x: A, y: A): Bool } trait Show[-A] extends Any { def show(x: A): String } trait Empty[+A] extends Any { def empty: A }
  7. 7. Empty. implicit def emptyFromCanBuild[A, R](implicit z: CanBuild[A, R]): Empty[R] = Empty(z().result) implicit def emptyFromMakes[A, R](implicit z: Makes[A, R]): Empty[R] = Empty(elems()) implicit def emptyJavaSet[A]: Empty[jSet[A]] = Empty(new jHashSet[A]) // which provides us e.g. psp> emptyValue[String] res19: String = "" psp> val x: Index = emptyValue x: Index = -1
  8. 8. Empty's gonna empty psp> view[String]().zhead res18: String = "" // as opposed to psp> view[Int]().zhead Error: could not find implicit Empty[Int] psp> view("a", "b") zreducel (_ append _) res20: String = ab psp> some(5.index).zget res21: Index = 5 psp> none[Index]().zget res22: Index = -1
  9. 9. Repent, then convert psp> view(1 -> 2).toMap[jMap] res8: jMap[Int, Int] = {1=2} psp> view(1 -> 2).toMap[sciMap] res9: sciMap[Int, Int] = Map(1 -> 2) psp> view(1 -> 2).to[sciVector] res10: sciVector[(Int, Int)] = Vector(1 -> 2) psp> view(1 -> 2).to[Vec] res11: Vec[(Int, Int)] = [ 1 -> 2 ]
  10. 10. You may be specific. psp> 'a' to 'g' res12: CharRange = [a..g] psp> ('a' to 'g').force[String] res13: String = abcdefg psp> ('a' to 'g').force[Vec[Char]] res14: Vec[Char] = [ a, b, c, d, e, f, g ] psp> ('a' to 'g').force[sciList[Char]] res15: sciList[Char] = List(a, b, c, d, e, f, g) psp> ('a' to 'g').to[Array] res16: Array[Char] = [ a, b, c, d, e, f, g ]
  11. 11. Handful of better methods psp> 1 to 20 splitAfter 10.size res16: Split[Int] = [ 1, 2, 3, ... ] / [ 11, 12, 13, ... ] // Requires a Show[Int] instance psp> 1 to 40 grep """(d)1""".r res17: View[Int] = [ 11, 22, 33 ] psp> 1 to 7 splitAround 3.nth res3: Split[Int] = [ 1, 2 ] / [ 4, 5, 6, 7 ] // span plus one psp> 2.andUp takeToFirst (_ % 5 == 0) res4: View[Long] = [ 2, 3, 4, 5 ]
  12. 12. Predicate algebra psp> def divBy(n: Long): ToBool[Long] = _ % n == 0L defined function divBy psp> 0.andUp filter divBy(7) res24: View[Long] = [ 0, 7, 14, ... ] psp> 0.andUp filter divBy(7) && divBy(3) res25: View[Long] = [ 0, 21, 42, ... ]
  13. 13. Binary relation algebra psp> val xs = 1 to 100 zipTail xs: Zip[Int, Int] = [ 1 -> 2, 2 -> 3, 3 -> 4, ... ] psp> val p1: Pred2[Int] = (_ > 8 && _ < 12) p1: (Int, Int) => Bool = <function2> psp> xs filter p1 res39: Zip[Int, Int] = [ 9 -> 10, 10 -> 11 ] psp> xs filter p1 && (_ + _ == 19) res41: Zip[Int, Int] = [ 9 -> 10 ]
  14. 14. Pairness awareness psp> val xs = 1 to 100 zipTail xs: Zip[Int, Int] = [ 1 -> 2, 2 -> 3, 3 -> 4, ... ] psp> xs filter (_ > 8 && _ < 12) res30: Zip[Int, Int] = [ 9 -> 10, 10 -> 11 ] psp> (1 to 10).zipTail forall (_ + 1 == _) res31: Boolean = true
  15. 15. Fitter splitter psp> 1 to 10 span (_ <= 5) res2: Split[Int] = [ 1, 2, 3, 4, 5 ] / [ 6, 7, 8, 9, 10 ] psp> 1 to 10 span (_ <= 5) mapRight (_.reverseView take 2) join res3: View[Int] = [ 1, 2, 3, 4, 5, 10, 9 ] psp> 1 to 6 splitAfter 3.size collate res4: View[Int] = [ 1, 4, 2, 5, 3, 6 ]
  16. 16. Fair trade collections psp> val xs = scala.collection.immutable.BitSet(1, 2, 3) xs: sciBitset = BitSet(1, 2, 3) psp> xs o (_ map (_ + 1 toChar)) Error: could not find implicit Makes[Char, BitSet] psp> xs o (_ map (_ + 1 toChar) map (_.toInt)) res2: sciBitset = BitSet(2, 3, 4)
  17. 17. To infinity... and no further psp> def primes = mpartition(2L.andUp)(xs => _ % xs.head === 0) defined function primes psp> println(primes take 7 map (_ take 5)) 2 4 6 8 10 3 9 15 21 27 5 25 35 55 65 7 49 77 91 119 11 121 143 187 209 13 169 221 247 299 17 289 323 391 493
  18. 18. Products via type class. // Pattern matching Java map entries psp> javaMap(1 -> 2, 3 -> 4) collect { case 1 -> n => n } res2: View[Int] = [ 2 ] psp> javaMap(1 -> 2, 3 -> 4) zfirst { case 3 -> n => some(n) } res3: Option[Int] = 4 psp> javaMap(1 -> 2, 3 -> 4) zfirst { case 5 -> n => some(n) } res4: Option[Int] = - // And get a java map back psp> javaMap(1 -> 2, 3 -> 4) o (_ collect { case a->b => b->a } ) res5: jMap[Int, Int] = {2=1, 4=3}
  19. 19. Invariant leaf collections. // "You saved me, Capt. Invariance!" psp> vec(1, 2, 3) :+ 4L found : Long(4L) required: Int // For contrast. scala> Vector(1, 2, 3) :+ 4L res1: scala.collection.immutable.Vector[AnyVal] = Vector(1, 2, 3, 4)

×