0
Scalathe smarter cousin                     David Rosell
Scalathe smarter cousin
Scala                  the smarter cousinObject Oriented  Functional
Scala                              the smarter cousin general-purpose, type-safeObject Oriented  Functional
Scala                              the smarter cousin general-purpose, type-safeObject Oriented  Functional runs on JVM (a...
OOP                                  as it should be doneCollections                Scala are              library oriente...
Closures
scala> var more = 1more: Int = 1scala> val addMore = (x: Int) => x + moreaddMore: (Int) => Int = <function>
scala> var more = 1more: Int = 1scala> val addMore = (x: Int) => x + moreaddMore: (Int) => Int = <function>scala> addMore(...
Usingresources
def writeSomething(file: File): Unit = {  val writer = new PrintWriter(file)  try {    writer.println(“Hello Kitty”)    wr...
def writeSomething(file: File): Unit = {  val writer = new PrintWriter(file)  try {    writer.println(“Hello Kitty”)    wr...
def writeSomething(file: File): Unit = {  val writer = new PrintWriter(file)  try {    writer.println(“Hello Kitty”)    wr...
def writeSomething(file: File): Unit = {  val writer = new PrintWriter(file)  try {    writer.println(“Hello Kitty”)    wr...
def writeSomething(file: File) {  val writer = new PrintWriter(file)  try {    writer.println(“Hello Kitty”)    writer.pri...
writer.println(“Hello Kitty”)      writer.println(new Date)“calling writeSomething must write to file” in {  val file = ne...
def writeSomething(file: File) {  val writer = new PrintWriter(file)  try {    writer.println(“Hello Kitty”)    writer.pri...
def writeSomething(file: File) {  val writer = new PrintWriter(file)  try {    writer.println(“Hello Kitty”)    writer.pri...
writer.println(“Hello Kitty”)      writer.println(new Date)def writeSomething(file: File) {  val writer = new PrintWriter(...
Backgroundval list = List(“Pelle”, “Stina”)for (name <- list) {  println(name)}
Backgroundval list = List(“Pelle”, “Stina”)list.foreach( aFunc(...) )
Backgroundval list = List(“Pelle”, “Stina”)list.foreach( aFunc(...) )def aFunc(s: String): Unit = {   println(s)}
Background         def aFunc(s: String): Unit = {            println(s)         }val list = List(“Pelle”, “Stina”)list.for...
Background         def aFunc(s: String): Unit = {            println(s)         }val list = List(“Pelle”, “Stina”)list.for...
Background         def aFunc(s: String): Unit = {            println(s)         }val list = List(“Pelle”, “Stina”)list.for...
Background         def aFunc(s: String): Unit = {            println(s)         }val list = List(“Pelle”, “Stina”)list.for...
Background         def aFunc(s: String): Unit = {            println(s)         }val list = List(“Pelle”, “Stina”)list.for...
Backgroundval list = List(“Pelle”, “Stina”)list.foreach( println _ )
Backgroundval list = List(“Pelle”, “Stina”)list.foreach( println _ )for (name <- list) {  println(name)}
def writeTo(file: File) {  val writer = new PrintWriter(file)  try {    writer.println(“Hello Kitty”)    ...    writer.pri...
writer.println(“Hello Kitty”)      writer.println(new Date)def writeTo(file: File) {  val writer = new PrintWriter(file)  ...
def op(writer: PrintWriter) {    writer.println(“Hello Kitty”)    writer.println(new Date)}def writeTo(file: File) {  val ...
def op(writer: PrintWriter) {    writer.println(“Hello Kitty”)    writer.println(new Date)}      def writeTo(file: File) {...
def op(writer: PrintWriter) {    writer.println(“Hello Kitty”)    writer.println(new Date)}      def writeTo(file: File) {...
def op(writer: PrintWriter) {    writer.println(“Hello Kitty”)    writer.println(new Date)}
def op(writer: PrintWriter) {    writer.println(“Hello Kitty”)    writer.println(new Date)}def writeTo(file: File, op: Pri...
def op(writer: PrintWriter) {    writer.println(“Hello Kitty”)    writer.println(new Date)}def writeTo(file: File, op: Pri...
def writeTo(file: File, op: PrintWriter => Unit) {  val writer = new PrintWriter(file)  try {      op(writer)    } finally...
def writeTo(file: File, op: PrintWriter => Unit) {  val writer = new PrintWriter(file)  try {      op(writer)    } finally...
def writeTo(file: File, op: PrintWriter => Unit) {  val writer = new PrintWriter(file)  try {      op(writer)    } finally...
def writeTo(file: File, op: PrintWriter => Unit) {  val writer = new PrintWriter(file)  try {      op(writer)    } finally...
def writeTo(file: File, op: PrintWriter => Unit) {  val writer = new PrintWriter(file)  try {      op(writer)    } finally...
def writeTo(file: File, op: PrintWriter => Unit) {  val writer = new PrintWriter(file)  try {      op(writer)    } finally...
def writeTo(file: File, op: PrintWriter => Unit) {  val writer = new PrintWriter(file)  try {      op(writer)    } finally...
)(def writeTo(file: File, op: PrintWriter => Unit) {  val writer = new PrintWriter(file)  try {      op(writer)    } final...
Currying                      )(def writeTo(file: File, op: PrintWriter => Unit) {  val writer = new PrintWriter(file)  tr...
)(def writeTo(file: File, op: PrintWriter => Unit) {  val writer = new PrintWriter(file)  try {    op(writer)    } finally...
def writeTo(file: File)(op: PrintWriter => Unit) {  val writer = new PrintWriter(file)  try {    op(writer)    } finally {...
“calling writeTo must write to file” in {  val file = new File(“test.txt”)  try {    writeTo(file)      val cont = Source....
writeTo(file) { writer =>         writer.println(“Hello Kitty”)         writer.println(new Date)      }“calling writeTo mu...
“calling writeTo must write to file” in {  val file = new File(“test.txt”)  try {    writeTo(file) { writer =>        writ...
“calling writeTo must write to file” in {  val file = new File(“test.txt”)  try {    val now = new Date    writeTo(file) {...
“calling writeTo must write to file” in {  val file = new File(“test.txt”)  try {    val now = new Date    writeTo(file) {...
def writeTo(file: File, op: PrintWriter => Unit) {  val writer = new PrintWriter(file)  try {    op(writer)  } finally {  ...
“calling writeSomething must write to file” in {    val file = new File(“test.txt”)    try {      val now = new Date      ...
“calling writeSomething must write to file” in {   withFile { file =>      val now = new Date      writeTo(file) { writer ...
“calling writeSomething must write to file” in {   withFile { file =>      val now = new Date      writeTo(file) { writer ...
“calling writeSomething must write to file” in {   withFile { file =>      val now = new Date      writeTo(file) { writer ...
“calling writeSomething must write to file” in {   withFile { file =>      val now = new Date      writeTo(file) { writer ...
def withFile(op: File => Unit) {  val file = new File(“test.txt”)  try {    op(file)    } finally {      file.delete    }}...
def withFile(op: File => Unit) {  val file = new File(“test.txt”)  try {    op(file)    } finally {      file.delete    }}...
object WriteToFileSpecs extends Specification with TestFileHelper {   ...}trait TestFileHelper {    def withFile(op: File ...
JVM      Community      Language
JVM   Community
Scala gives• More concise - type inference• More expressive - operator notation• OOP for real• Slick functional collection...
1’st edition freehttp://www.artima.com/pins1ed/
David Rosell
David RosellBlogSpot: http://drsimplestuff.blogspot.com GitHub: https://github.com/daros   E-mail: david.rosell@redpill-li...
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Scala - den smarta kusinen
Upcoming SlideShare
Loading in...5
×

Scala - den smarta kusinen

288

Published on

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
288
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • general-purpose, \ntype-safe language \n for the Java Platform \nthat combines \n object-oriented \n and \n functional programming\n
  • general-purpose, \ntype-safe language \n for the Java Platform \nthat combines \n object-oriented \n and \n functional programming\n
  • general-purpose, \ntype-safe language \n for the Java Platform \nthat combines \n object-oriented \n and \n functional programming\n
  • general-purpose, \ntype-safe language \n for the Java Platform \nthat combines \n object-oriented \n and \n functional programming\n
  • general-purpose, \ntype-safe language \n for the Java Platform \nthat combines \n object-oriented \n and \n functional programming\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript of "Scala - den smarta kusinen"

    1. 1. Scalathe smarter cousin David Rosell
    2. 2. Scalathe smarter cousin
    3. 3. Scala the smarter cousinObject Oriented Functional
    4. 4. Scala the smarter cousin general-purpose, type-safeObject Oriented Functional
    5. 5. Scala the smarter cousin general-purpose, type-safeObject Oriented Functional runs on JVM (and CLR)
    6. 6. OOP as it should be doneCollections Scala are library oriented Duck typing Equals DSL’s n! = 1*2*3*...*n
    7. 7. Closures
    8. 8. scala> var more = 1more: Int = 1scala> val addMore = (x: Int) => x + moreaddMore: (Int) => Int = <function>
    9. 9. scala> var more = 1more: Int = 1scala> val addMore = (x: Int) => x + moreaddMore: (Int) => Int = <function>scala> addMore(1)res1: Int = 2scala> more = 10more: Int = 10scala> addMore(1)res3: Int = 11
    10. 10. Usingresources
    11. 11. def writeSomething(file: File): Unit = { val writer = new PrintWriter(file) try { writer.println(“Hello Kitty”) writer.println(new Date) } finally { writer.close }}
    12. 12. def writeSomething(file: File): Unit = { val writer = new PrintWriter(file) try { writer.println(“Hello Kitty”) writer.println(new Date) } finally { writer.close }}
    13. 13. def writeSomething(file: File): Unit = { val writer = new PrintWriter(file) try { writer.println(“Hello Kitty”) writer.println(new Date) } finally { writer.close }}object WriteToFileSpecs extends Specification { ...}
    14. 14. def writeSomething(file: File): Unit = { val writer = new PrintWriter(file) try { writer.println(“Hello Kitty”) writer.println(new Date) } finally { writer.close }}“calling writeSomething must write to file” in { val file = new File(“test.txt”) try { writeSomething(file) val cont = Source.fromFile(file).getLines.toList cont(0) must be equalTo “Hello Kitty” cont(1) } finally { file.delete }}
    15. 15. def writeSomething(file: File) { val writer = new PrintWriter(file) try { writer.println(“Hello Kitty”) writer.println(new Date) } finally { writer.close }}“calling writeSomething must write to file” in { val file = new File(“test.txt”) try { writeSomething(file) val cont = Source.fromFile(file).getLines.toList cont(0) must be equalTo “Hello Kitty” cont(1) } finally { file.delete }}
    16. 16. writer.println(“Hello Kitty”) writer.println(new Date)“calling writeSomething must write to file” in { val file = new File(“test.txt”) try { writeSomething(file) val cont = Source.fromFile(file).getLines.toList cont(0) must be equalTo “Hello Kitty” cont(1) ??? how to test a ‘now’-date } finally { file.delete }}
    17. 17. def writeSomething(file: File) { val writer = new PrintWriter(file) try { writer.println(“Hello Kitty”) writer.println(new Date) } finally { writer.close }}
    18. 18. def writeSomething(file: File) { val writer = new PrintWriter(file) try { writer.println(“Hello Kitty”) writer.println(new Date) } finally { writer.close }}
    19. 19. writer.println(“Hello Kitty”) writer.println(new Date)def writeSomething(file: File) { val writer = new PrintWriter(file) try { } finally { writer.close }}
    20. 20. Backgroundval list = List(“Pelle”, “Stina”)for (name <- list) { println(name)}
    21. 21. Backgroundval list = List(“Pelle”, “Stina”)list.foreach( aFunc(...) )
    22. 22. Backgroundval list = List(“Pelle”, “Stina”)list.foreach( aFunc(...) )def aFunc(s: String): Unit = { println(s)}
    23. 23. Background def aFunc(s: String): Unit = { println(s) }val list = List(“Pelle”, “Stina”)list.foreach( (s: String): Unit => { println(s) } )
    24. 24. Background def aFunc(s: String): Unit = { println(s) }val list = List(“Pelle”, “Stina”)list.foreach( (s: String) => { println(s) } )
    25. 25. Background def aFunc(s: String): Unit = { println(s) }val list = List(“Pelle”, “Stina”)list.foreach( s => println(s) )
    26. 26. Background def aFunc(s: String): Unit = { println(s) }val list = List(“Pelle”, “Stina”)list.foreach( _ => println(_) )
    27. 27. Background def aFunc(s: String): Unit = { println(s) }val list = List(“Pelle”, “Stina”)list.foreach( println(_) )
    28. 28. Backgroundval list = List(“Pelle”, “Stina”)list.foreach( println _ )
    29. 29. Backgroundval list = List(“Pelle”, “Stina”)list.foreach( println _ )for (name <- list) { println(name)}
    30. 30. def writeTo(file: File) { val writer = new PrintWriter(file) try { writer.println(“Hello Kitty”) ... writer.println(new Date) } finally { writer.close }}
    31. 31. writer.println(“Hello Kitty”) writer.println(new Date)def writeTo(file: File) { val writer = new PrintWriter(file) try { ... } finally { writer.close }}
    32. 32. def op(writer: PrintWriter) { writer.println(“Hello Kitty”) writer.println(new Date)}def writeTo(file: File) { val writer = new PrintWriter(file) try { ... } finally { writer.close }}
    33. 33. def op(writer: PrintWriter) { writer.println(“Hello Kitty”) writer.println(new Date)} def writeTo(file: File) { val writer = new PrintWriter(file) try { ... } finally { writer.close } }
    34. 34. def op(writer: PrintWriter) { writer.println(“Hello Kitty”) writer.println(new Date)} def writeTo(file: File) { val writer = new PrintWriter(file) try { ... } finally { writer.close } }
    35. 35. def op(writer: PrintWriter) { writer.println(“Hello Kitty”) writer.println(new Date)}
    36. 36. def op(writer: PrintWriter) { writer.println(“Hello Kitty”) writer.println(new Date)}def writeTo(file: File, op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { ... } finally { writer.close }}
    37. 37. def op(writer: PrintWriter) { writer.println(“Hello Kitty”) writer.println(new Date)}def writeTo(file: File, op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close }}
    38. 38. def writeTo(file: File, op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close }}def op(writer: PrintWriter) { writer.println(“Hello Kitty”) writer.println(new Date)}val file = new File(“test.txt”)val op = (writer: PrintWriter) => { writer.println(“Hello Kitty”) writer.println(new Date) }writeTo(file, op)
    39. 39. def writeTo(file: File, op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close }}val file = new File(“test.txt”)val op = (writer: PrintWriter) => { writer.println(“Hello Kitty”) writer.println(new Date) }writeTo(file, op)
    40. 40. def writeTo(file: File, op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close }}val file = new File(“test.txt”)writeTo(file, (writer: PrintWriter) => { op) writer.println(“Hello Kitty”) writer.println(new Date) }
    41. 41. def writeTo(file: File, op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close }}val file = new File(“test.txt”)writeTo(file, (writer: PrintWriter) => { writer.println(“Hello Kitty”) writer.println(new Date) })
    42. 42. def writeTo(file: File, op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close }}val file = new File(“test.txt”) writer => { writer.println(“Hello Kitty”) writer.println(new Date) }
    43. 43. def writeTo(file: File, op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close }}val file = new File(“test.txt”)writeTo(file, writer => { writer.println(“Hello Kitty”) writer.println(new Date) })
    44. 44. def writeTo(file: File, op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close }}
    45. 45. )(def writeTo(file: File, op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close }}
    46. 46. Currying )(def writeTo(file: File, op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close }}
    47. 47. )(def writeTo(file: File, op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close }}val file = new File(“test.txt”)writeTo(file)(writer => writer.println(“Hello Kitty”) writer.println(new Date))
    48. 48. def writeTo(file: File)(op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close }}val file = new File(“test.txt”)writeTo(file) { writer => writer.println(“Hello Kitty”) writer.println(new Date)}
    49. 49. “calling writeTo must write to file” in { val file = new File(“test.txt”) try { writeTo(file) val cont = Source.fromFile(file).getLines.toList cont(0) must be equalTo “Hello Kitty” cont(1) ??? how to test a ‘now’-date } finally { file.delete }}
    50. 50. writeTo(file) { writer => writer.println(“Hello Kitty”) writer.println(new Date) }“calling writeTo must write to file” in { val file = new File(“test.txt”) try { writeTo(file) val cont = Source.fromFile(file).getLines.toList cont(0) must be equalTo “Hello Kitty” cont(1) ??? how to test a ‘now’-date } finally { file.delete }}
    51. 51. “calling writeTo must write to file” in { val file = new File(“test.txt”) try { writeTo(file) { writer => writer.println(“Hello Kitty”) writer.println(new Date) } val cont = Source.fromFile(file).getLines.toList cont(0) must be equalTo “Hello Kitty” cont(1) ??? how to test a ‘now’-date } finally { file.delete }}
    52. 52. “calling writeTo must write to file” in { val file = new File(“test.txt”) try { val now = new Date writeTo(file) { writer => writer.println(“Hello Kitty”) writer.println(new Date) } val cont = Source.fromFile(file).getLines.toList cont(0) must be equalTo “Hello Kitty” cont(1) ??? how to test a ‘now’-date } finally { file.delete }}
    53. 53. “calling writeTo must write to file” in { val file = new File(“test.txt”) try { val now = new Date writeTo(file) { writer => writer.println(“Hello Kitty”) writer.println(now) } val cont = Source.fromFile(file).getLines.toList cont(0) must be equalTo “Hello Kitty” cont(1) must be equalTo now.toString } finally { file.delete }}
    54. 54. def writeTo(file: File, op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close }}“calling writeTo must write to file” in { val file = new File(“test.txt”) try { val now = new Date writeTo(file) { writer => writer.println(“Hello Kitty”) writer.println(now) } val cont = Source.fromFile(file).getLines.toList cont(0) must be equalTo “Hello Kitty” cont(1) must be equalTo now.toString } finally { file.delete }}
    55. 55. “calling writeSomething must write to file” in { val file = new File(“test.txt”) try { val now = new Date writeTo(file) { writer => writer.println(“Hello Kitty”) writer.println(now) } val cont = Source.fromFile(file).getLines.toList cont(0) must be equalTo “Hello Kitty” cont(1) must be equalTo now.toString } finally { file.delete }}
    56. 56. “calling writeSomething must write to file” in { withFile { file => val now = new Date writeTo(file) { writer => writer.println(“Hello Kitty”) writer.println(now) } val cont = Source.fromFile(file).getLines.toList cont(0) must be equalTo “Hello Kitty” cont(1) must be equalTo now.toString }}def withFile(op: File => Unit) { val file = new File(“test.txt”) try { op(file) } finally { file.delete }}
    57. 57. “calling writeSomething must write to file” in { withFile { file => val now = new Date writeTo(file) { writer => writer.println(“Hello Kitty”) writer.println(now) } val cont = Source.fromFile(file).getLines.toList cont(0) must be equalTo “Hello Kitty” cont(1) must be equalTo now.toString }}
    58. 58. “calling writeSomething must write to file” in { withFile { file => val now = new Date writeTo(file) { writer => writer.println(“Hello Kitty”) writer.println(now) } val cont = Source.fromFile(file).getLines.toList validate(file) { cont => cont(0) must be equalTo “Hello Kitty” cont(1) must be equalTo now.toString }}
    59. 59. “calling writeSomething must write to file” in { withFile { file => val now = new Date writeTo(file) { writer => writer.println(“Hello Kitty”) writer.println(now) } validate(file) { cont => cont(0) must be equalTo “Hello Kitty” cont(1) must be equalTo now.toString } }}def validate(file: File)(op: List[String] => Unit) { val cont = Source.fromFile(file).getLines.toList op(cont)}
    60. 60. def withFile(op: File => Unit) { val file = new File(“test.txt”) try { op(file) } finally { file.delete }}def validate(file: File)(op: List[String] => Unit) { val cont = Source.fromFile(file).getLines.toList op(cont)}
    61. 61. def withFile(op: File => Unit) { val file = new File(“test.txt”) try { op(file) } finally { file.delete }}def validate(file: File)(op: List[String] => Unit) { val cont = Source.fromFile(file).getLines.toList op(cont)}
    62. 62. object WriteToFileSpecs extends Specification with TestFileHelper { ...}trait TestFileHelper { def withFile(op: File => Unit) { val file = new File(“test.txt”) try { op(file) } finally { file.delete } } def validate(file: File)(op: List[String] => Unit) { val cont = Source.fromFile(file).getLines.toList op(cont) }}
    63. 63. JVM Community Language
    64. 64. JVM Community
    65. 65. Scala gives• More concise - type inference• More expressive - operator notation• OOP for real• Slick functional collection api• Full access to Java
    66. 66. 1’st edition freehttp://www.artima.com/pins1ed/
    67. 67. David Rosell
    68. 68. David RosellBlogSpot: http://drsimplestuff.blogspot.com GitHub: https://github.com/daros E-mail: david.rosell@redpill-linpro.com
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×