SlideShare une entreprise Scribd logo
1  sur  178
Télécharger pour lire hors ligne
Scala   Android



                                     Konrad Malawski / @ktosopl
                                    GDG / PJUG / KSUG / SCKRK
                                       KrakDroid 14.12.2012
Sunday, December 16, 12
Sunday, December 16, 12
Sunday, December 16, 12
Scala is




Sunday, December 16, 12
Scala is




Sunday, December 16, 12
Scala is




Sunday, December 16, 12
Scala is




Sunday, December 16, 12
Scala is

                          Simple




Sunday, December 16, 12
Scala is

                           Simple ,
                          but Hard.



Sunday, December 16, 12
Scala is Simple.




Sunday, December 16, 12
Scala is Simple.




Sunday, December 16, 12
Scala is Hard.




                                http://apocalisp.wordpress.com/2010/10/26/
                                       type-level-programming
                          -in-scala-part-7-natural-transformation%C2%A0literals/
Sunday, December 16, 12
Scala is Hard.
object	
  Param	
  {

	
  	
  implicit	
  def	
  pToT[A[_],	
  B[_]](f:	
  (p:	
  Param[A])	
  =>	
  B[p.T]):	
  A~>B	
  =	
  new	
  (A	
  ~>	
  B)	
  {
	
  	
  	
  	
  def	
  apply[s](a:	
  A[s]):	
  B[s]	
  =	
  {
	
  	
  	
  	
  	
  	
  val	
  v:	
  Param[A]	
  {	
  type	
  T	
  =	
  s}	
  =	
  new	
  Param[A]	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  type	
  T	
  =	
  s
	
  	
  	
  	
  	
  	
  	
  	
  def	
  in	
  =	
  a
	
  	
  	
  	
  	
  	
  }
	
  	
  	
  	
  	
  	
  f(v)
	
  	
  	
  	
  }
	
  	
  }

}




                                   http://apocalisp.wordpress.com/2010/10/26/
                                          type-level-programming
                             -in-scala-part-7-natural-transformation%C2%A0literals/
Sunday, December 16, 12
Scala is




Sunday, December 16, 12
Scala is
                          A Functional,




Sunday, December 16, 12
Scala is
                           A Functional,
                          Object Oriented,




Sunday, December 16, 12
Scala is
                            A Functional,
                          Object Oriented,
                          Statically Typed,




Sunday, December 16, 12
Scala is
                            A Functional,
                          Object Oriented,
                          Statically Typed,
                              Scalable,




Sunday, December 16, 12
Scala is
                            A Functional,
                          Object Oriented,
                          Statically Typed,
                              Scalable,
                             Language...




Sunday, December 16, 12
Scala is
                                 A Functional,
                               Object Oriented,
                               Statically Typed,
                                   Scalable,
                                  Language...

                          ...running on the JVM and DVM!




Sunday, December 16, 12
Android




Sunday, December 16, 12
findViewById
              public class MyActivity extends Activity {

                   ListView comments;
                   Button newComment;

                   @Override
                   void onCreate(Bundle bundle) {
                     super.onCreate(bundle);
                     comments = (ListView) findViewById(R.id.comments);
                     newComment = (Button) findViewById(R.id.new_comment);
                     // ...
                   }
              }




Sunday, December 16, 12
findViewById
              public class MyActivity extends Activity {

                   ListView comments;
                                              is null at first...
                   Button newComment;

                   @Override
                   void onCreate(Bundle bundle) {
                     super.onCreate(bundle);
                     comments = (ListView) findViewById(R.id.comments);
                     newComment = (Button) findViewById(R.id.new_comment);
                     // ...
                   }
              }




Sunday, December 16, 12
findViewById
              public class MyActivity extends Activity {

                   ListView comments;
                   Button newComment;
                                                              initialized in
                   @Override                                    method...
                   void onCreate(Bundle bundle) {
                     super.onCreate(bundle);
                     comments = (ListView) findViewById(R.id.comments);
                     newComment = (Button) findViewById(R.id.new_comment);
                     // ...
                   }
              }




Sunday, December 16, 12
findViewById
              public class MyActivity extends Activity {

                   ListView comments;
                   Button newComment;

                   @Override
                   void onCreate(Bundle bundle) {
                     super.onCreate(bundle);
                     comments = (ListView) findViewById(R.id.comments);
                     newComment = (Button) findViewById(R.id.new_comment);
                     // ...
                   }
              }
                                    Explicit casting!




Sunday, December 16, 12
Robo Guice
                                          So many
               public class MakeANoteActivity
                  extends Activity
                                          words...
                  implements View.OnClickListener
               {
                   public static final String PHOTO_PATH = "picture_path";
                   public static final String PHOTO_ATTACHED = "photo_attached";

                      @Inject   SessionManager sessionManager;
                      @Inject   LocationHelper locationHelper;
                      @Inject   PhotoHelper photoHelper;
                      @Inject   Application context;

                      @Inject CalibrationHelper calibrationHelper;

                      @InjectView(R.id.attach_photo) Button attachPhoto;
                      @InjectView(R.id.note_text) EditText noteText;
                      @InjectView(R.id.save_button) Button save;
                      @InjectView(R.id.date) TextView dateText;
                      @InjectView(R.id.share) Button share;

                      @InjectResource(R.string.im_aircasting) String imAircasting;
                      @InjectResource(R.string.share_with) String shareWith;

                      // ...
               }




Sunday, December 16, 12
Robo Guice
               public class MakeANoteActivity
                  extends RoboActivity
                  implements View.OnClickListener
               {
                   public static final String PHOTO_PATH = "picture_path";
                   public static final String PHOTO_ATTACHED = "photo_attached";

                      @Inject   SessionManager sessionManager;
                      @Inject   LocationHelper locationHelper;   Type changes in XML,
                      @Inject   PhotoHelper photoHelper;            but not here...
                      @Inject   Application context;
                                                                 ClassCastException!
                      @Inject CalibrationHelper calibrationHelper;

                      @InjectView(R.id.attach_photo) Button attachPhoto;
                      @InjectView(R.id.note_text) EditText noteText;
                      @InjectView(R.id.save_button) Button save;
                      @InjectView(R.id.date) TextView dateText;
                      @InjectView(R.id.share) Button share;

                      @InjectResource(R.string.im_aircasting) String imAircasting;
                      @InjectResource(R.string.share_with) String shareWith;

                      // ...
               }




Sunday, December 16, 12
Robo Guice
               public class MakeANoteActivity
                  extends RoboActivity
                  implements View.OnClickListener
               {
                   public static final String PHOTO_PATH = "picture_path";
                   public static final String PHOTO_ATTACHED = "photo_attached";

                      @Inject   SessionManager sessionManager;
                      @Inject   LocationHelper locationHelper;          Guice is eager.
                      @Inject   PhotoHelper photoHelper;         Startup can take a few seconds!
                      @Inject   Application context;

                      @Inject CalibrationHelper calibrationHelper;

                      @InjectView(R.id.attach_photo) Button attachPhoto;
                      @InjectView(R.id.note_text) EditText noteText;
                      @InjectView(R.id.save_button) Button save;
                      @InjectView(R.id.date) TextView dateText;
                      @InjectView(R.id.share) Button share;

                      @InjectResource(R.string.im_aircasting) String imAircasting;
                      @InjectResource(R.string.share_with) String shareWith;

                      // ...
               }




Sunday, December 16, 12
Stairway to Scala




Sunday, December 16, 12
Another look at the Java code
               public class MakeANoteActivity extends RoboActivity
                  implements View.OnClickListener

               {
                   public static final String PHOTO_PATH = "picture_path";
                   public static final String PHOTO_ATTACHED = "photo_attached";

                   @Inject   SessionManager sessionManager;
                   @Inject   LocationHelper locationHelper;
                   @Inject   PhotoHelper photoHelper;
                   @Inject   Application context;

                   @Inject CalibrationHelper calibrationHelper;

                   @InjectView(R.id.attach_photo) Button attachPhoto;
                   @InjectView(R.id.note_text) EditText noteText;
                   @InjectView(R.id.save_button) Button save;
                   @InjectView(R.id.date) TextView dateText;
                   @InjectView(R.id.share) Button share;

                   @InjectResource(R.string.im_aircasting) String imAircasting;
                   @InjectResource(R.string.share_with) String shareWith;

                   // ...
               }




Sunday, December 16, 12
What if... Scala?
               public class MakeANoteActivity extends RoboActivity
                  implements View.OnClickListener

               {
                   public static final String PHOTO_PATH = "picture_path";
                   public static final String PHOTO_ATTACHED = "photo_attached";

                   @Inject   SessionManager sessionManager;
                   @Inject   LocationHelper locationHelper;
                   @Inject   PhotoHelper photoHelper;
                   @Inject   Application context;

                   @Inject CalibrationHelper calibrationHelper;

                   @InjectView(R.id.attach_photo) Button attachPhoto;
                   @InjectView(R.id.note_text) EditText noteText;
                   @InjectView(R.id.save_button) Button save;
                   @InjectView(R.id.date) TextView dateText;
                   @InjectView(R.id.share) Button share;

                   @InjectResource(R.string.im_aircasting) String imAircasting;
                   @InjectResource(R.string.share_with) String shareWith;

                   // ...
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get




                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                   val imAircasting = findResource[String](R.string.im_aircasting)
                   val shareWith    = findResource[String](R.string.share_with)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 public is default. = "picture_path"
                 val PhotoPath
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get




                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                                               ScalaActivity gives us some
                 val PhotoAttached = "photo_attached"
                                                              magic methods
                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get




                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                                                                               It’s so easy,
                  with    View.OnClickListener                           YOU   can implement it!
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                                               ScalaActivity gives us some
                 val PhotoAttached = "photo_attached"
                                                              magic methods
                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get




                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                                                                               It’s so easy,
                  with    View.OnClickListener                           YOU   can implement it!
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                                               ScalaActivity gives us some
                 val PhotoAttached = "photo_attached"
                                                              magic methods
                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get




                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
                                                                              Instead of “...Helper”,
               {                                                                    use Traits.
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get




                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"
                                                                   Type       Inference

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get




                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get


                                                                 Who’s missing here?

                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get


                                   lazy initialization
                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get



                                                                              Needs Context
                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get
                                                     What’s the type here?!?


                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get
                                                     What’s the type here?!?
                                                                 Typed Resource - “a better R”

                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get
                                                     What’s the type here?!?
                                                                 Typed Resource - “a better R”

                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                                      XML Type changes... Type here changes!
                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get
                                                     What’s the type here?!?
                                                                 Typed Resource - “a better R”

                   lazy   val   attachPhoto     =   findView(TR.attach_photo)
                   lazy   val   noteText        =   findView(TR.note_text)
                   lazy   val   save            =   findView(TR.save_button)
                   lazy   val   dateText        =   findView(TR.date)
                   lazy   val   share: Button   =   findView(TR.share)


                                                 You can be explicit though!
                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get




                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =         Like @InjectResource, but
                                                  findView(TR.share)                smarter

                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }
                                                                        Manifests vs. Type Erasure


Sunday, December 16, 12
What if... Scala?
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get




                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                                                        Does String have a toast()
                   val username = findResource[String](R.string.my_username)                  method?
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }

                                                                        Implicit Conversion

Sunday, December 16, 12
Typed Resource




Sunday, December 16, 12
Typed Resource = Better R




Sunday, December 16, 12
Typed Resource = Better R




Sunday, December 16, 12
Typed Resource = Better R
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get




                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)


                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
Typed Resource = Better R
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get
                   lazy val locationManager = LocationManager.get




                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)          Typed Resource

                   val username = findResource[String](R.string.my_username)
                   val friends = findResource[List[String]](R.string.friends)

                   def toastConferenceName() = "KrakDroid".toast()
               }




Sunday, December 16, 12
Typed Resource = Better R

      case class TypedResource[T](id: Int)
      case class TypedLayout(id: Int)

      object TR {
        val columns_pager = TypedResource[ViewPager](R.id.columns_pager)

          val workspaces = TypedResource[ExpandableListView](R.id.workspaces)

           val subtask_txt = TypedResource[TextView](R.id.subtask_txt)
          // ...

      }




Sunday, December 16, 12
Typed Resource = Better R

      case class TypedResource[T](id: Int)
      case class TypedLayout(id: Int)

      object TR {
        val columns_pager = TypedResource[ViewPager](R.id.columns_pager)

          val workspaces = TypedResource[ExpandableListView](R.id.workspaces)

           val subtask_txt = TypedResource[TextView](R.id.subtask_txt)
          // ...

      }




Sunday, December 16, 12
Typed Resource = Better R

      case class TypedResource[T](id: Int)
      case class TypedLayout(id: Int)                Wrappers

      object TR {
        val columns_pager = TypedResource[ViewPager](R.id.columns_pager)

          val workspaces = TypedResource[ExpandableListView](R.id.workspaces)

           val subtask_txt = TypedResource[TextView](R.id.subtask_txt)
          // ...

      }




Sunday, December 16, 12
Typed Resource = Better R

      case class TypedResource[T](id: Int)
      case class TypedLayout(id: Int)

      object TR {
        val columns_pager = TypedResource[ViewPager](R.id.columns_pager)

          val workspaces = TypedResource[ExpandableListView](R.id.workspaces)

           val subtask_txt = TypedResource[TextView](R.id.subtask_txt)
          // ...

      }




Sunday, December 16, 12
Typed Resource = Better R

      case class TypedResource[T](id: Int)
      case class TypedLayout(id: Int)

      object TR {
        val columns_pager = TypedResource[ViewPager](R.id.columns_pager)

          val workspaces = TypedResource[ExpandableListView](R.id.workspaces)

           val subtask_txt = TypedResource[TextView](R.id.subtask_txt)
          // ...

      }




Sunday, December 16, 12
TR in Action
               class MakeANoteActivity extends ScalaActivity
                  with    View.OnClickListener
                  with    PhotoOperations with CalibrationOperations
               {
                 val PhotoPath     = "picture_path"
                 val PhotoAttached = "photo_attached"

                   lazy val sessionManager = SessionManager.get   // magic here but
                   lazy val locationManager = LocationManager.get // we’ll see this later!




                   lazy   val   attachPhoto   =   findView(TR.attach_photo)
                   lazy   val   noteText      =   findView(TR.note_text)
                   lazy   val   save          =   findView(TR.save_button)
                   lazy   val   dateText      =   findView(TR.date)
                   lazy   val   share         =   findView(TR.share)

                   // magic here too, but we’ll implement this in a few slides!
                   val imAircasting = findResource[String](R.string.im_aircasting)
                   val shareWith    = findResource[String](R.string.share_with)

                   // ...
               }




Sunday, December 16, 12
Types




Sunday, December 16, 12
Types




            You always have the type information at hand.




Sunday, December 16, 12
Types




            You always have the type information at hand.

                          (IntelliJ IDEA, Ensmine/Emacs, Eclipse)
                               ⌘ SHIFT I
                                ALT =




Sunday, December 16, 12
An Implicit Context




Sunday, December 16, 12
An Implicit Context



                              Implicit != Explicit




Sunday, December 16, 12
An Implicit Context
                                       Implicit != Explicit


                          def toastMyName(name: String, ctx: Context) {
                            import android.widget.Toast._

                              makeText(ctx, msg, LENGTH_LONG).show()
                          }


                          toastMyName(”Siegfried”, getContext)




Sunday, December 16, 12
An Implicit Context
                                       Implicit != Explicit


                          def toastMyName(name: String, ctx: Context) {
                            import android.widget.Toast._

                              makeText(ctx, msg, LENGTH_LONG).show()
                          }
                                                            Explicit Parameter

                          toastMyName(”Siegfried”, getContext)




Sunday, December 16, 12
An Implicit Context
                                       Implicit != Explicit


                          def toastMyName(name: String, ctx: Context) {
                            import android.widget.Toast._

                              makeText(ctx, msg, LENGTH_LONG).show()
                          }
                                                            Explicit Parameter

                          toastMyName(”Siegfried”, getContext)




Sunday, December 16, 12
An Implicit Context
                                          Implicit != Explicit
                          Import inside a method!

                            def toastMyName(name: String, ctx: Context) {
                              import android.widget.Toast._

                                makeText(ctx, msg, LENGTH_LONG).show()
                            }


                            toastMyName(”Siegfried”, getContext)




Sunday, December 16, 12
An Implicit Context
                                       Implicit != Explicit


                          def toastMyName(name: String, ctx: Context) {
                            import android.widget.Toast._

                              makeText(ctx, msg, LENGTH_LONG).show()
                          }


                          toastMyName(”Siegfried”, getContext)




Sunday, December 16, 12
An Implicit Context
                               Implicit != Explicit


          def toastMyName(name: String)(implicit ctx: Context) {
            import android.widget.Toast._

              makeText(ctx, msg, LENGTH_LONG).show()
          }




Sunday, December 16, 12
Implicit Parameters
                               Implicit != Explicit


          def toastMyName(name: String)(implicit ctx: Context) {
            import android.widget.Toast._

              makeText(ctx, msg, LENGTH_LONG).show()   Implicit Parameter
          }




Sunday, December 16, 12
Implicit Parameters
                               Implicit != Explicit


          def toastMyName(name: String)(implicit ctx: Context) {
            import android.widget.Toast._

              makeText(ctx, msg, LENGTH_LONG).show()
          }




Sunday, December 16, 12
Implicit Parameters
                               Implicit != Explicit


          def toastMyName(name: String)(implicit ctx: Context) {
            import android.widget.Toast._

              makeText(ctx, msg, LENGTH_LONG).show()
          }




          toastMyName("Siegfried")




Sunday, December 16, 12
Implicit Parameters
                               Implicit != Explicit


          def toastMyName(name: String)(implicit ctx: Context) {
            import android.widget.Toast._

              makeText(ctx, msg, LENGTH_LONG).show()
          }

         implicit val context: Context = getContext



          toastMyName("Siegfried")




Sunday, December 16, 12
Implicit Parameters
                               Implicit != Explicit


          def toastMyName(name: String)(implicit ctx: Context) {
            import android.widget.Toast._

              makeText(ctx, msg, LENGTH_LONG).show()
          }

         implicit val context: Context = getContext



          toastMyName("Siegfried")

          toastMyName("Siegfried")(context)




Sunday, December 16, 12
An Implicit Context
                           class ScalaActivity
                             extends Activity
                                with ImplicitContext




Sunday, December 16, 12
An Implicit Context
                              class ScalaActivity
                                extends Activity
                                   with ImplicitContext




                          trait ImplicitContext {
                            this: Activity =>

                              implicit val ctx = getContext
                          }




Sunday, December 16, 12
An Implicit Context
                              class ScalaActivity
                                extends Activity
                                   with ImplicitContext


                                                          “I can be only mixed into
                                                                 an Activity.”

                          trait ImplicitContext {
                            this: Activity =>

                              implicit val ctx = getContext
                          }




Sunday, December 16, 12
An Implicit Context
                              class ScalaActivity
                                extends Activity
                                   with ImplicitContext


                                                             “I can be only mixed into
                                                                    an Activity.”

                          trait ImplicitContext {
                            this: Activity =>

                              implicit val ctx = getContext
                          }

                                                          So I know this method!




Sunday, December 16, 12
Manifests vs. Type Erasure




Sunday, December 16, 12
Manifests vs. Type Erasure




Sunday, December 16, 12
Manifests vs. Type Erasure

                          List<Thing> t = marshaller.parseList("[]")

   Java




Sunday, December 16, 12
Manifests vs. Type Erasure
                                                              Uhm... List<Object>...?

                          List<Thing> t = marshaller.parseList("[]")

   Java




Sunday, December 16, 12
Manifests vs. Type Erasure
                                                              Uhm... List<Object>...?

                          List<Thing> t = marshaller.parseList("[]")

   Java
                 List<Thing> t = marshaller.parseList("[]", Thing.class)




Sunday, December 16, 12
Manifests vs. Type Erasure
                                                               Uhm... List<Object>...?

                          List<Thing> t = marshaller.parseList("[]")

   Java                                                  Oh! List<Thing>, sure!

                 List<Thing> t = marshaller.parseList("[]", Thing.class)




Sunday, December 16, 12
Manifests vs. Type Erasure
                                                                 Uhm... List<Object>...?

                           List<Thing> t = marshaller.parseList("[]")

   Java                                                    Oh! List<Thing>, sure!

                 List<Thing> t = marshaller.parseList("[]", Thing.class)




 Scala                    val t: List[Thing] = marshaller.parseList("[]")




Sunday, December 16, 12
Manifests vs. Type Erasure
                                                                       Uhm... List<Object>...?

                           List<Thing> t = marshaller.parseList("[]")

   Java                                                          Oh! List<Thing>, sure!

                 List<Thing> t = marshaller.parseList("[]", Thing.class)




 Scala                    val t: List[Thing] = marshaller.parseList("[]")


                                                  List[Thing]!




Sunday, December 16, 12
Manifests vs. Type Erasure



             val shareWith   = findResource[String](R.string.share_with)




Sunday, December 16, 12
Manifests vs. Type Erasure



             val shareWith   = findResource[String](R.string.share_with)




Sunday, December 16, 12
Manifests vs. Type Erasure
    def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T =
      m.toString match {
        case "java.lang.String" =>
          ctx.getString(id).asInstanceOf[T]

            case other =>
              throw new UnableToResolveResource(ofType = other, id = id)
        }




             val shareWith       = findResource[String](R.string.share_with)

Sunday, December 16, 12
Manifests vs. Type Erasure
    def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T =
      m.toString match {
        case "java.lang.String" =>
          ctx.getString(id).asInstanceOf[T]         implicit

            case other =>
              throw new UnableToResolveResource(ofType = other, id = id)
        }




             val shareWith       = findResource[String](R.string.share_with)

Sunday, December 16, 12
Manifests vs. Type Erasure
    def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T =
      m.toString match {
        case "java.lang.String" =>
          ctx.getString(id).asInstanceOf[T]          implicit Manifest

            case other =>
              throw new UnableToResolveResource(ofType = other, id = id)
        }




             val shareWith       = findResource[String](R.string.share_with)

Sunday, December 16, 12
Manifests vs. Type Erasure
    def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T =
      m.toString match {
        case "java.lang.String" =>
          ctx.getString(id).asInstanceOf[T]           the type signature

            case other =>
              throw new UnableToResolveResource(ofType = other, id = id)
        }




             val shareWith       = findResource[String](R.string.share_with)

Sunday, December 16, 12
Manifests vs. Type Erasure
    def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T =
      m.toString match {
        case "java.lang.String" =>
          ctx.getString(id).asInstanceOf[T]        see the type... at runtime

            case "java.util.ArrayList[java.lang.String]" =>
              newArrayList(ctx.getString(id).asInstanceOf[T])

            case other =>
              throw new UnableToResolveResource(ofType = other, id = id)
        }




             val shareWith       = findResource[String](R.string.share_with)

Sunday, December 16, 12
Manifests vs. Type Erasure
    def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T =
      m.toString match {
        case "java.lang.String" =>
          ctx.getString(id).asInstanceOf[T]

            case "java.util.ArrayList[java.lang.String]" =>
              newArrayList(ctx.getString(id).asInstanceOf[T])

            case "Int" =>
              ctx.getString(id).toInt.asInstanceOf[T]

            case other =>
              throw new UnableToResolveResource(ofType = other, id = id)
        }




             val shareWith       = findResource[String](R.string.share_with)

Sunday, December 16, 12
Manifests vs. Type Erasure
    def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T =
      m.toString match {
        case "java.lang.String" =>
          ctx.getString(id).asInstanceOf[T]

            case "java.util.ArrayList[java.lang.String]" =>
              newArrayList(ctx.getString(id).asInstanceOf[T])

            case "Int" =>
              ctx.getString(id).toInt.asInstanceOf[T]

            case other =>                       java.lang.String has this...?
              throw new UnableToResolveResource(ofType = other, id = id)
        }




             val shareWith        = findResource[String](R.string.share_with)

Sunday, December 16, 12
Implicit Conversions




Sunday, December 16, 12
Implicit Conversions



                              Implicit != Explicit




Sunday, December 16, 12
Implicit Conversions
                              Implicit != Explicit




Sunday, December 16, 12
Implicit Conversions
                              Implicit != Explicit




Sunday, December 16, 12
Implicit Conversions
                               Implicit != Explicit

                           toastMyName("Siegfried")




Sunday, December 16, 12
Implicit Conversions
                               Implicit != Explicit
                                              Implicit Context, remember?

                           toastMyName("Siegfried")




Sunday, December 16, 12
Implicit Conversions
                               Implicit != Explicit

                           toastMyName("Siegfried")

                               What if we could...




Sunday, December 16, 12
Implicit Conversions
                               Implicit != Explicit

                           toastMyName("Siegfried")

                               What if we could...


                             "Siegfried".toast()




Sunday, December 16, 12
Implicit Conversions
                              Implicit != Explicit




Sunday, December 16, 12
Implicit Conversions
                                  Implicit != Explicit
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }




Sunday, December 16, 12
Implicit Conversions
                                  Implicit != Explicit
            Decorator

                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }




Sunday, December 16, 12
Implicit Conversions
                                  Implicit != Explicit
            Decorator
                                                               Constructor
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }




Sunday, December 16, 12
Implicit Conversions
                                   Implicit != Explicit
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }




                     new Toastable("Hello!").toast()




Sunday, December 16, 12
Implicit Conversions
                                  Implicit != Explicit
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }




Sunday, December 16, 12
Implicit Conversions
                                  Implicit != Explicit
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }


              trait ScalaToasts {

                  implicit def asToastable(str: String) =
                    new Toastable(str)
              }




Sunday, December 16, 12
Implicit Conversions
                                    Implicit != Explicit
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }
                                      Implicit Conversion: String => Toastable

              trait ScalaToasts {

                  implicit def asToastable(str: String) =
                    new Toastable(str)
              }




Sunday, December 16, 12
Implicit Conversions
                                       Implicit != Explicit
                             class Toastable(msg: String) {
                               def toast()(implicit ctx: Context) = ???
                             }
                                         Implicit Conversion: String => Toastable

              trait ScalaToasts {

                  implicit def asToastable(str: String) =
                    new Toastable(str)
              }
                          asToastable("Hello!").toast()




Sunday, December 16, 12
Implicit Conversions
                                  Implicit != Explicit
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }
                                      Implicit Conversion: String => Toastable

              trait ScalaToasts {

                  implicit def asToastable(str: String) =
                    new Toastable(str)
              }




Sunday, December 16, 12
Implicit Conversions
                                  Implicit != Explicit
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }


              trait ScalaToasts {

                  implicit def asToastable(str: String) =
                    new Toastable(str)
              }

               class ExampleActivity
                 extends Activity
                 with ImplicitContext
                 with ScalaToasts



Sunday, December 16, 12
Implicit Conversions
                                  Implicit != Explicit
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }


              trait ScalaToasts {

                  implicit def asToastable(str: String) =
                    new Toastable(str)
              }

               class ExampleActivity
                 extends Activity
                 with ImplicitContext
                 with ScalaToasts



Sunday, December 16, 12
Implicit Conversions
                                  Implicit != Explicit
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }


              trait ScalaToasts {

                implicit def asToastable(str: String) =
                  new Toastable(str)
              }                                 "Hello!".toast()


               class ExampleActivity
                 extends Activity
                 with ImplicitContext
                 with ScalaToasts



Sunday, December 16, 12
Implicit Conversions
                                  Implicit != Explicit
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }


              trait ScalaToasts {

                implicit def asToastable(str: String) =
                  new Toastable(str)
              }                                 "Hello!".toast()


               class ExampleActivity
                 extends Activity
                 with ImplicitContext
                 with ScalaToasts



Sunday, December 16, 12
Implicit Conversions
                                  Implicit != Explicit
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }


              trait ScalaToasts {

                implicit def asToastable(str: String) =
                  new Toastable(str)
              }                                 "Hello!".toast()


               class ExampleActivity
                 extends Activity
                 with ImplicitContext
                 with ScalaToasts



Sunday, December 16, 12
Implicit Conversions
                                  Implicit != Explicit
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }


              trait ScalaToasts {

                implicit def asToastable(str: String) =
                  new Toastable(str)
              }                                 "Hello!".toast()


               class ExampleActivity
                 extends Activity
                 with ImplicitContext
                 with ScalaToasts



Sunday, December 16, 12
Implicit Conversions
                                  Implicit != Explicit
                          class Toastable(msg: String) {
                            def toast()(implicit ctx: Context) = ???
                          }


              trait ScalaToasts {

                implicit def asToastable(str: String) =
                  new Toastable(str)
              }                                 "Hello!".toast()


               class ExampleActivity
                 extends Activity     asToastable("Hello!").toast()
                 with ImplicitContext
                 with ScalaToasts



Sunday, December 16, 12
Implicit Conversions




Sunday, December 16, 12
Collections




Sunday, December 16, 12
POJO




Sunday, December 16, 12
public class Person {
             private final String name;
             private final String nick;
                                                     POJO
                public Person(String name, String nick) {
                    this.name = name;
                    this.nick = nick;
                }

                public String getName() {
                    return name;
                }

                public String getNick() {
                    return nick;
                }

                @Override
                public boolean equals(Object o) {
                    if (this == o) return true;
                    if (!(o instanceof Person)) return false;

                      Person person = (Person) o;

                      if (name != null ? !name.equals(person.name) : person.name != null) return false;
                      if (nick != null ? !nick.equals(person.nick) : person.nick != null) return false;

                      return true;
                }

                @Override
                public int hashCode() {
                    int result = name != null ? name.hashCode() : 0;
                    result = 31 * result + (surname != null ? surname.hashCode() : 0);
                    return result;
                }
           }




Sunday, December 16, 12
public class Person {
             private final String name;
             private final String nick;
                                                     POJO
                public Person(String name, String nick) {
                    this.name = name;
                    this.nick = nick;
                }

                public String getName() {
                    return name;
                }

                public String getNick() {
                    return nick;
                }

                @Override
                public boolean equals(Object o) {
                    if (this == o) return true;
                    if (!(o instanceof Person)) return false;

                      Person person = (Person) o;

                      if (name != null ? !name.equals(person.name) : person.name != null) return false;
                      if (nick != null ? !nick.equals(person.nick) : person.nick != null) return false;

                      return true;
                }

                @Override
                public int hashCode() {
                    int result = name != null ? name.hashCode() : 0;
                    result = 31 * result + (surname != null ? surname.hashCode() : 0);
                    return result;
                }
           }




Sunday, December 16, 12
POSO*
                                       *Actually just a Case Class




                          case class Person(name: String, nick: String)




Sunday, December 16, 12
POSO*
                                       *Actually just a Case Class




                                                          val name: String

                          case class Person(name: String, nick: String)




Sunday, December 16, 12
Case Classes


                          case class Person(name: String, nick: String)




Sunday, December 16, 12
Case Classes
                          case class Person(name: String, nick: String)




Sunday, December 16, 12
Case Classes
                          case class Person(name: String, nick: String)




               val person = Person("Bruce Wayne", "Manbat") // whoops!




Sunday, December 16, 12
Case Classes
                          case class Person(name: String, nick: String)




               val person = Person("Bruce Wayne", "Manbat") // whoops!
               val fixed = person.copy(nick = "Batman")




Sunday, December 16, 12
Case Classes
                          case class Person(name: String, nick: String)




               val person = Person("Bruce Wayne", "Manbat") // whoops!
               val fixed = person.copy(nick = "Batman")


               val self        = Person(nick = "Ktoso" , name = "Konrad")




Sunday, December 16, 12
Case Classes
                          case class Person(name: String, nick: String)




               val person = Person("Bruce Wayne", "Manbat") // whoops!
               val fixed = person.copy(nick = "Batman")


               val self        = Person(nick = "Ktoso" , name = "Konrad")

               val Person(name, hero) = person
               val hello = ”Hello” + name + ” ” + surname




Sunday, December 16, 12
Case Classes
                          case class Person(name: String, nick: String)




               val person = Person("Bruce Wayne", "Manbat") // whoops!
               val fixed = person.copy(nick = "Batman")


               val self        = Person(nick = "Ktoso" , name = "Konrad")

               val Person(name, hero) = person
               val hello = ”Hello” + name + ” ” + surname



               fixed.toString should equal (”Person(Bruce Wayne, Batman)”)


                                   Still thinking assertThat().isEqualTo() is clean?

Sunday, December 16, 12
Given a list of People,
                          return all the Hero names.




Sunday, December 16, 12
Given a list of People,
                          return all the Hero names.

     public List<String> heroNames(List<Person> allPersons) {
       List<String> donePersons =
                             new ArrayList<String>(allPersons.size());

              for (Person person : allPersons) {
                if (person.isHero()) {
                  donePersons.add(person.getName());
                }
              }

              return ImmutableList.copyOf(donePersons);
          }




Sunday, December 16, 12
Java with Guava at their Best
                            Given a list of People,
                          return all the Hero names.




Sunday, December 16, 12
Java with Guava at their Best
                            Given a list of People,
                          return all the Hero names.
                 return FluentIterable
                    .from(people)
                    .filter(new Predicate<Person>() {
                       @Override
                       public boolean apply(Person person) {
                         return person != null && person.isHero();
                       }
                    })
                    .transform(new Function<Person, String>() {
                       @Override
                       public String apply(Person input) {
                         return input.getName();
                       }
                    })
                    .toImmutableList();



Sunday, December 16, 12
Sunday, December 16, 12
Java + Guava at their best
                            Given a list of People,
                          return all the Hero names.




Sunday, December 16, 12
Java + Guava at their best
                            Given a list of People,
                          return all the Hero names.



                             return FluentIterable
                                .from(people)
                                .filter(isSuperHero)
                                .transform(heroToName)
                                .toImmutableList();




                                   Java, yet pretty slick :-)
                                          I <3 Guava.

Sunday, December 16, 12
Scala Collections at Work
                            Given a list of People,
                          return all the Hero names.




Sunday, December 16, 12
Scala Collections at Work
                            Given a list of People,
                          return all the Hero names.



        def heroNames(people: List[Person]) =
            people filter(_.isHero) map { _.name}




Sunday, December 16, 12
And there’s more!




Sunday, December 16, 12
Simple Threading




Sunday, December 16, 12
Simple Threading

                          implicit val handler = new Handler




Sunday, December 16, 12
Simple Threading

                          implicit val handler = new Handler



                          inUiThread {
                            // ...
                          }




Sunday, December 16, 12
Simple Threading

                          implicit val handler = new Handler



                          inUiThread {
                            // ...
                          }


                          inFutureWithProgressDialog(timeout = 10.seconds) {
                            // ...
                          }




Sunday, December 16, 12
Simple Threading

                          implicit val handler = new Handler



                          inUiThread {
                            // ...
                          }


                          inFutureWithProgressDialog(timeout = 10.seconds) {
                            // ...
                          }                          Implicit Conversion on Int




Sunday, December 16, 12
on___
                     button.setOnClickListener(new View.OnClickListener() {
                       @Override
                       public void onClick(View view) {
   Java                  // ...
                       }
                     });




Sunday, December 16, 12
on___
                     button.setOnClickListener(new View.OnClickListener() {
                       @Override
                       public void onClick(View view) {
   Java                  // ...
                       }
                     });




                            button onClick { view =>
 Scala                         // ...
                            }



Sunday, December 16, 12
SharedPreferences




Sunday, December 16, 12
SharedPreferences

                    KanbaneryPreferences.projectId = projectId




Sunday, December 16, 12
SharedPreferences

                    KanbaneryPreferences.projectId = projectId



            val name: Option[Long] = KanbaneryPreferences.projectId




Sunday, December 16, 12
SharedPreferences

                    KanbaneryPreferences.projectId = projectId



            val name: Option[Long] = KanbaneryPreferences.projectId




                            What? No implicits?!   Assume it works! Skip!




Sunday, December 16, 12
SharedPreferences
                  object KanbaneryPreferences {

                    private val KeyLogin       = "login"

                          private def sharedPreferences(implicit ctx: Context) = ???

                          def login(implicit ctx: Context) =
                            sharedPreferences.getString(KeyLogin, "")




Sunday, December 16, 12
SharedPreferences
                  object KanbaneryPreferences {

                    private val KeyLogin       = "login"

                          private def sharedPreferences(implicit ctx: Context) = ???

                          def login(implicit ctx: Context) =
                            sharedPreferences.getString(KeyLogin, "")




Sunday, December 16, 12
SharedPreferences
                  object KanbaneryPreferences {

                    private val KeyLogin       = "login"

                          private def sharedPreferences(implicit ctx: Context) = ???




                          def login_=(number: String)(implicit ctx: Context) {
                            withSharedPreferencesEditor {
                              _.putString(KeyLogin, number)
                            }

                          }




Sunday, December 16, 12
SharedPreferences
                  object KanbaneryPreferences {

                    private val KeyLogin       = "login"

                          private def sharedPreferences(implicit ctx: Context) = ???




                          def login_=(number: String)(implicit ctx: Context) {
                            withSharedPreferencesEditor {
                              _.putString(KeyLogin, number)
                            }

                          }




Sunday, December 16, 12
SharedPreferences

                  def withSharedPreferencesEditor
                      (block: SharedPreferences.Editor => Unit)
                      (implicit ctx: Context) {

                          val editor = sharedPreferences.edit()

                          block(editor)

                          editor.commit()
                  }




Sunday, December 16, 12
SharedPreferences

                  def withSharedPreferencesEditor
                      (block: SharedPreferences.Editor => Unit)
                      (implicit ctx: Context) {

                          val editor = sharedPreferences.edit()

                          block(editor)

                          editor.commit()
                  }




Sunday, December 16, 12
SharedPreferences

                  def withSharedPreferencesEditor
                      (block: SharedPreferences.Editor => Unit)
                      (implicit ctx: Context) {

                          val editor = sharedPreferences.edit()

                          block(editor)

                          editor.commit()
                  }




Sunday, December 16, 12
SharedPreferences

                  def withSharedPreferencesEditor
                      (block: SharedPreferences.Editor => Unit)
                      (implicit ctx: Context) {

                          val editor = sharedPreferences.edit()

                          block(editor)

                          editor.commit()
                  }



                                            withSharedPreferencesEditor {
                                              _.putString(KeyLogin, number)
                                            }



Sunday, December 16, 12
String interpolation
                                (scala 2.10)




Sunday, December 16, 12
String interpolation
                                (scala 2.10)




Sunday, December 16, 12
String interpolation
                                (scala 2.10)




Sunday, December 16, 12
String interpolation
                                (scala 2.10)




                                               Won’t compile!




Sunday, December 16, 12
Let me warn you...




Sunday, December 16, 12
Let me warn you...



                          Scala is addictive.


Sunday, December 16, 12
Let me warn you...



                          Scala is addictive.


Sunday, December 16, 12
Scala is addictive.




Sunday, December 16, 12
Scala is addictive.




Sunday, December 16, 12
Scala is addictive.




Sunday, December 16, 12
Scala is addictive.




Sunday, December 16, 12
def links =
                          • Scala Lang http://www.scala-lang.org/
                          • Scala Koans http://www.scalakoans.org
                          • Blog.Project13.pl - http://www.blog.project13.pl
                          • SBT Android Plugin - https://github.com/jberkel/android-plugin
                          • Kanbanery for Android - https://github.com/ktoso/kanbanery-tv
                             • Check pl.project13.scala.android.*
                             • Now OpenSource, in Scala, and Lunar Logic is helping to dev :-)
                             • New version soon! Pull and play with it!
                          • Scaloid https://github.com/pocorall/scaloid
                             • Though I don’t think their impl. is very clean some things are v. nice!




Sunday, December 16, 12
def links =
                          • Scala Lang http://www.scala-lang.org/
                          • Scala Koans http://www.scalakoans.org
                          • Blog.Project13.pl - http://www.blog.project13.pl
                          • SBT Android Plugin - https://github.com/jberkel/android-plugin
                          • Kanbanery for Android - https://github.com/ktoso/kanbanery-tv
                             • Check pl.project13.scala.android.*
                             • Now OpenSource, in Scala, and Lunar Logic is helping to dev :-)
                             • New version soon! Pull and play with it!
                          • Scaloid https://github.com/pocorall/scaloid
                             • Though I don’t think their impl. is very clean some things are v. nice!



                                                                        Mailing lists rock!



Sunday, December 16, 12
Konrad Malawski / @ktosopl
                          GDG / PJUG / KSUG / SCKRK
                            KrakDroid 14.12.2012
Sunday, December 16, 12
I love feedback! <3    Konrad Malawski / @ktosopl
                                                GDG / PJUG / KSUG / SCKRK
                                                  KrakDroid 14.12.2012
Sunday, December 16, 12

Contenu connexe

En vedette

Git tak po prostu (SFI version)
Git tak po prostu (SFI version)Git tak po prostu (SFI version)
Git tak po prostu (SFI version)Konrad Malawski
 
TDD drogą do oświecenia w Scali
TDD drogą do oświecenia w ScaliTDD drogą do oświecenia w Scali
TDD drogą do oświecenia w ScaliKonrad Malawski
 
Open soucerers - jak zacząć swoją przygodę z open source
Open soucerers - jak zacząć swoją przygodę z open sourceOpen soucerers - jak zacząć swoją przygodę z open source
Open soucerers - jak zacząć swoją przygodę z open sourceKonrad Malawski
 
JavaOne 2013: Java 8 - The Good Parts
JavaOne 2013: Java 8 - The Good PartsJavaOne 2013: Java 8 - The Good Parts
JavaOne 2013: Java 8 - The Good PartsKonrad Malawski
 
Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014Konrad Malawski
 
HBase RowKey design for Akka Persistence
HBase RowKey design for Akka PersistenceHBase RowKey design for Akka Persistence
HBase RowKey design for Akka PersistenceKonrad Malawski
 
Ebay legacy-code-retreat
Ebay legacy-code-retreatEbay legacy-code-retreat
Ebay legacy-code-retreatKonrad Malawski
 
Need for Async: Hot pursuit for scalable applications
Need for Async: Hot pursuit for scalable applicationsNeed for Async: Hot pursuit for scalable applications
Need for Async: Hot pursuit for scalable applicationsKonrad Malawski
 
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)Konrad Malawski
 
Scalding - Hadoop Word Count in LESS than 70 lines of code
Scalding - Hadoop Word Count in LESS than 70 lines of codeScalding - Hadoop Word Count in LESS than 70 lines of code
Scalding - Hadoop Word Count in LESS than 70 lines of codeKonrad Malawski
 
100th SCKRK Meeting - best software engineering papers of 5 years of SCKRK
100th SCKRK Meeting - best software engineering papers of 5 years of SCKRK100th SCKRK Meeting - best software engineering papers of 5 years of SCKRK
100th SCKRK Meeting - best software engineering papers of 5 years of SCKRKKonrad Malawski
 
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsFresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsKonrad Malawski
 
Disrupt 2 Grow - Devoxx 2013
Disrupt 2 Grow - Devoxx 2013Disrupt 2 Grow - Devoxx 2013
Disrupt 2 Grow - Devoxx 2013Konrad Malawski
 
The things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaThe things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaKonrad Malawski
 
[Japanese] How Reactive Streams and Akka Streams change the JVM Ecosystem @ R...
[Japanese] How Reactive Streams and Akka Streams change the JVM Ecosystem @ R...[Japanese] How Reactive Streams and Akka Streams change the JVM Ecosystem @ R...
[Japanese] How Reactive Streams and Akka Streams change the JVM Ecosystem @ R...Konrad Malawski
 
The People of Proverbs (Part 3): The Sluggard
The People of Proverbs (Part 3): The SluggardThe People of Proverbs (Part 3): The Sluggard
The People of Proverbs (Part 3): The SluggardDavid Turner
 
The Need for Async @ ScalaWorld
The Need for Async @ ScalaWorldThe Need for Async @ ScalaWorld
The Need for Async @ ScalaWorldKonrad Malawski
 
The People of Proverbs (Part 6): The Wise
The People of Proverbs (Part 6): The WiseThe People of Proverbs (Part 6): The Wise
The People of Proverbs (Part 6): The WiseDavid Turner
 
Akka Streams in Action @ ScalaDays Berlin 2016
Akka Streams in Action @ ScalaDays Berlin 2016Akka Streams in Action @ ScalaDays Berlin 2016
Akka Streams in Action @ ScalaDays Berlin 2016Konrad Malawski
 
How Reactive Streams & Akka Streams change the JVM Ecosystem
How Reactive Streams & Akka Streams change the JVM EcosystemHow Reactive Streams & Akka Streams change the JVM Ecosystem
How Reactive Streams & Akka Streams change the JVM EcosystemKonrad Malawski
 

En vedette (20)

Git tak po prostu (SFI version)
Git tak po prostu (SFI version)Git tak po prostu (SFI version)
Git tak po prostu (SFI version)
 
TDD drogą do oświecenia w Scali
TDD drogą do oświecenia w ScaliTDD drogą do oświecenia w Scali
TDD drogą do oświecenia w Scali
 
Open soucerers - jak zacząć swoją przygodę z open source
Open soucerers - jak zacząć swoją przygodę z open sourceOpen soucerers - jak zacząć swoją przygodę z open source
Open soucerers - jak zacząć swoją przygodę z open source
 
JavaOne 2013: Java 8 - The Good Parts
JavaOne 2013: Java 8 - The Good PartsJavaOne 2013: Java 8 - The Good Parts
JavaOne 2013: Java 8 - The Good Parts
 
Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014
 
HBase RowKey design for Akka Persistence
HBase RowKey design for Akka PersistenceHBase RowKey design for Akka Persistence
HBase RowKey design for Akka Persistence
 
Ebay legacy-code-retreat
Ebay legacy-code-retreatEbay legacy-code-retreat
Ebay legacy-code-retreat
 
Need for Async: Hot pursuit for scalable applications
Need for Async: Hot pursuit for scalable applicationsNeed for Async: Hot pursuit for scalable applications
Need for Async: Hot pursuit for scalable applications
 
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)
 
Scalding - Hadoop Word Count in LESS than 70 lines of code
Scalding - Hadoop Word Count in LESS than 70 lines of codeScalding - Hadoop Word Count in LESS than 70 lines of code
Scalding - Hadoop Word Count in LESS than 70 lines of code
 
100th SCKRK Meeting - best software engineering papers of 5 years of SCKRK
100th SCKRK Meeting - best software engineering papers of 5 years of SCKRK100th SCKRK Meeting - best software engineering papers of 5 years of SCKRK
100th SCKRK Meeting - best software engineering papers of 5 years of SCKRK
 
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsFresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
 
Disrupt 2 Grow - Devoxx 2013
Disrupt 2 Grow - Devoxx 2013Disrupt 2 Grow - Devoxx 2013
Disrupt 2 Grow - Devoxx 2013
 
The things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaThe things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and Akka
 
[Japanese] How Reactive Streams and Akka Streams change the JVM Ecosystem @ R...
[Japanese] How Reactive Streams and Akka Streams change the JVM Ecosystem @ R...[Japanese] How Reactive Streams and Akka Streams change the JVM Ecosystem @ R...
[Japanese] How Reactive Streams and Akka Streams change the JVM Ecosystem @ R...
 
The People of Proverbs (Part 3): The Sluggard
The People of Proverbs (Part 3): The SluggardThe People of Proverbs (Part 3): The Sluggard
The People of Proverbs (Part 3): The Sluggard
 
The Need for Async @ ScalaWorld
The Need for Async @ ScalaWorldThe Need for Async @ ScalaWorld
The Need for Async @ ScalaWorld
 
The People of Proverbs (Part 6): The Wise
The People of Proverbs (Part 6): The WiseThe People of Proverbs (Part 6): The Wise
The People of Proverbs (Part 6): The Wise
 
Akka Streams in Action @ ScalaDays Berlin 2016
Akka Streams in Action @ ScalaDays Berlin 2016Akka Streams in Action @ ScalaDays Berlin 2016
Akka Streams in Action @ ScalaDays Berlin 2016
 
How Reactive Streams & Akka Streams change the JVM Ecosystem
How Reactive Streams & Akka Streams change the JVM EcosystemHow Reactive Streams & Akka Streams change the JVM Ecosystem
How Reactive Streams & Akka Streams change the JVM Ecosystem
 

Similaire à KrakDroid: Scala on Android

OSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
OSDC.fr 2012 :: Cascalog : progammation logique pour HadoopOSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
OSDC.fr 2012 :: Cascalog : progammation logique pour HadoopPublicis Sapient Engineering
 
Ciconf 2012 - Better than Ad-hoc
Ciconf 2012 - Better than Ad-hocCiconf 2012 - Better than Ad-hoc
Ciconf 2012 - Better than Ad-hocCalvin Froedge
 
JavaOne報告会 Java SE/JavaFX 編 - JJUG CCC 2010 Fall
JavaOne報告会 Java SE/JavaFX 編 - JJUG CCC 2010 FallJavaOne報告会 Java SE/JavaFX 編 - JJUG CCC 2010 Fall
JavaOne報告会 Java SE/JavaFX 編 - JJUG CCC 2010 FallYuichi Sakuraba
 
02 JavaScript Syntax
02 JavaScript Syntax02 JavaScript Syntax
02 JavaScript SyntaxYnon Perek
 

Similaire à KrakDroid: Scala on Android (7)

Kotlin techtalk
Kotlin techtalkKotlin techtalk
Kotlin techtalk
 
OSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
OSDC.fr 2012 :: Cascalog : progammation logique pour HadoopOSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
OSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
 
Ciconf 2012 - Better than Ad-hoc
Ciconf 2012 - Better than Ad-hocCiconf 2012 - Better than Ad-hoc
Ciconf 2012 - Better than Ad-hoc
 
JavaOne報告会 Java SE/JavaFX 編 - JJUG CCC 2010 Fall
JavaOne報告会 Java SE/JavaFX 編 - JJUG CCC 2010 FallJavaOne報告会 Java SE/JavaFX 編 - JJUG CCC 2010 Fall
JavaOne報告会 Java SE/JavaFX 編 - JJUG CCC 2010 Fall
 
02 JavaScript Syntax
02 JavaScript Syntax02 JavaScript Syntax
02 JavaScript Syntax
 
Scala 101-bcndevcon
Scala 101-bcndevconScala 101-bcndevcon
Scala 101-bcndevcon
 
REST Drupal
REST DrupalREST Drupal
REST Drupal
 

Plus de Konrad Malawski

Networks and Types - the Future of Akka @ ScalaDays NYC 2018
Networks and Types - the Future of Akka @ ScalaDays NYC 2018Networks and Types - the Future of Akka @ ScalaDays NYC 2018
Networks and Types - the Future of Akka @ ScalaDays NYC 2018Konrad Malawski
 
Akka Typed (quick talk) - JFokus 2018
Akka Typed (quick talk) - JFokus 2018Akka Typed (quick talk) - JFokus 2018
Akka Typed (quick talk) - JFokus 2018Konrad Malawski
 
ScalaSwarm 2017 Keynote: Tough this be madness yet theres method in't
ScalaSwarm 2017 Keynote: Tough this be madness yet theres method in'tScalaSwarm 2017 Keynote: Tough this be madness yet theres method in't
ScalaSwarm 2017 Keynote: Tough this be madness yet theres method in'tKonrad Malawski
 
State of Akka 2017 - The best is yet to come
State of Akka 2017 - The best is yet to comeState of Akka 2017 - The best is yet to come
State of Akka 2017 - The best is yet to comeKonrad Malawski
 
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYCBuilding a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYCKonrad Malawski
 
Akka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming WorldAkka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming WorldKonrad Malawski
 
Reactive integrations with Akka Streams
Reactive integrations with Akka StreamsReactive integrations with Akka Streams
Reactive integrations with Akka StreamsKonrad Malawski
 
Not Only Streams for Akademia JLabs
Not Only Streams for Akademia JLabsNot Only Streams for Akademia JLabs
Not Only Streams for Akademia JLabsKonrad Malawski
 
Reactive Streams, j.u.concurrent & Beyond!
Reactive Streams, j.u.concurrent & Beyond!Reactive Streams, j.u.concurrent & Beyond!
Reactive Streams, j.u.concurrent & Beyond!Konrad Malawski
 
End to End Akka Streams / Reactive Streams - from Business to Socket
End to End Akka Streams / Reactive Streams - from Business to SocketEnd to End Akka Streams / Reactive Streams - from Business to Socket
End to End Akka Streams / Reactive Streams - from Business to SocketKonrad Malawski
 
The Cloud-natives are RESTless @ JavaOne
The Cloud-natives are RESTless @ JavaOneThe Cloud-natives are RESTless @ JavaOne
The Cloud-natives are RESTless @ JavaOneKonrad Malawski
 
Krakow communities @ 2016
Krakow communities @ 2016Krakow communities @ 2016
Krakow communities @ 2016Konrad Malawski
 
Reactive Stream Processing with Akka Streams
Reactive Stream Processing with Akka StreamsReactive Stream Processing with Akka Streams
Reactive Stream Processing with Akka StreamsKonrad Malawski
 
Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Konrad Malawski
 
2014 akka-streams-tokyo-japanese
2014 akka-streams-tokyo-japanese2014 akka-streams-tokyo-japanese
2014 akka-streams-tokyo-japaneseKonrad Malawski
 
Distributed Consensus A.K.A. "What do we eat for lunch?"
Distributed Consensus A.K.A. "What do we eat for lunch?"Distributed Consensus A.K.A. "What do we eat for lunch?"
Distributed Consensus A.K.A. "What do we eat for lunch?"Konrad Malawski
 
DDDing Tools = Akka Persistence
DDDing Tools = Akka PersistenceDDDing Tools = Akka Persistence
DDDing Tools = Akka PersistenceKonrad Malawski
 

Plus de Konrad Malawski (18)

Networks and Types - the Future of Akka @ ScalaDays NYC 2018
Networks and Types - the Future of Akka @ ScalaDays NYC 2018Networks and Types - the Future of Akka @ ScalaDays NYC 2018
Networks and Types - the Future of Akka @ ScalaDays NYC 2018
 
Akka Typed (quick talk) - JFokus 2018
Akka Typed (quick talk) - JFokus 2018Akka Typed (quick talk) - JFokus 2018
Akka Typed (quick talk) - JFokus 2018
 
ScalaSwarm 2017 Keynote: Tough this be madness yet theres method in't
ScalaSwarm 2017 Keynote: Tough this be madness yet theres method in'tScalaSwarm 2017 Keynote: Tough this be madness yet theres method in't
ScalaSwarm 2017 Keynote: Tough this be madness yet theres method in't
 
State of Akka 2017 - The best is yet to come
State of Akka 2017 - The best is yet to comeState of Akka 2017 - The best is yet to come
State of Akka 2017 - The best is yet to come
 
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYCBuilding a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
 
Akka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming WorldAkka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming World
 
Reactive integrations with Akka Streams
Reactive integrations with Akka StreamsReactive integrations with Akka Streams
Reactive integrations with Akka Streams
 
Not Only Streams for Akademia JLabs
Not Only Streams for Akademia JLabsNot Only Streams for Akademia JLabs
Not Only Streams for Akademia JLabs
 
Reactive Streams, j.u.concurrent & Beyond!
Reactive Streams, j.u.concurrent & Beyond!Reactive Streams, j.u.concurrent & Beyond!
Reactive Streams, j.u.concurrent & Beyond!
 
End to End Akka Streams / Reactive Streams - from Business to Socket
End to End Akka Streams / Reactive Streams - from Business to SocketEnd to End Akka Streams / Reactive Streams - from Business to Socket
End to End Akka Streams / Reactive Streams - from Business to Socket
 
The Cloud-natives are RESTless @ JavaOne
The Cloud-natives are RESTless @ JavaOneThe Cloud-natives are RESTless @ JavaOne
The Cloud-natives are RESTless @ JavaOne
 
Krakow communities @ 2016
Krakow communities @ 2016Krakow communities @ 2016
Krakow communities @ 2016
 
Zen of Akka
Zen of AkkaZen of Akka
Zen of Akka
 
Reactive Stream Processing with Akka Streams
Reactive Stream Processing with Akka StreamsReactive Stream Processing with Akka Streams
Reactive Stream Processing with Akka Streams
 
Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014
 
2014 akka-streams-tokyo-japanese
2014 akka-streams-tokyo-japanese2014 akka-streams-tokyo-japanese
2014 akka-streams-tokyo-japanese
 
Distributed Consensus A.K.A. "What do we eat for lunch?"
Distributed Consensus A.K.A. "What do we eat for lunch?"Distributed Consensus A.K.A. "What do we eat for lunch?"
Distributed Consensus A.K.A. "What do we eat for lunch?"
 
DDDing Tools = Akka Persistence
DDDing Tools = Akka PersistenceDDDing Tools = Akka Persistence
DDDing Tools = Akka Persistence
 

Dernier

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 

Dernier (20)

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 

KrakDroid: Scala on Android

  • 1. Scala Android Konrad Malawski / @ktosopl GDG / PJUG / KSUG / SCKRK KrakDroid 14.12.2012 Sunday, December 16, 12
  • 8. Scala is Simple Sunday, December 16, 12
  • 9. Scala is Simple , but Hard. Sunday, December 16, 12
  • 10. Scala is Simple. Sunday, December 16, 12
  • 11. Scala is Simple. Sunday, December 16, 12
  • 12. Scala is Hard. http://apocalisp.wordpress.com/2010/10/26/ type-level-programming -in-scala-part-7-natural-transformation%C2%A0literals/ Sunday, December 16, 12
  • 13. Scala is Hard. object  Param  {    implicit  def  pToT[A[_],  B[_]](f:  (p:  Param[A])  =>  B[p.T]):  A~>B  =  new  (A  ~>  B)  {        def  apply[s](a:  A[s]):  B[s]  =  {            val  v:  Param[A]  {  type  T  =  s}  =  new  Param[A]  {                  type  T  =  s                def  in  =  a            }            f(v)        }    } } http://apocalisp.wordpress.com/2010/10/26/ type-level-programming -in-scala-part-7-natural-transformation%C2%A0literals/ Sunday, December 16, 12
  • 15. Scala is A Functional, Sunday, December 16, 12
  • 16. Scala is A Functional, Object Oriented, Sunday, December 16, 12
  • 17. Scala is A Functional, Object Oriented, Statically Typed, Sunday, December 16, 12
  • 18. Scala is A Functional, Object Oriented, Statically Typed, Scalable, Sunday, December 16, 12
  • 19. Scala is A Functional, Object Oriented, Statically Typed, Scalable, Language... Sunday, December 16, 12
  • 20. Scala is A Functional, Object Oriented, Statically Typed, Scalable, Language... ...running on the JVM and DVM! Sunday, December 16, 12
  • 22. findViewById public class MyActivity extends Activity { ListView comments; Button newComment; @Override void onCreate(Bundle bundle) { super.onCreate(bundle); comments = (ListView) findViewById(R.id.comments); newComment = (Button) findViewById(R.id.new_comment); // ... } } Sunday, December 16, 12
  • 23. findViewById public class MyActivity extends Activity { ListView comments; is null at first... Button newComment; @Override void onCreate(Bundle bundle) { super.onCreate(bundle); comments = (ListView) findViewById(R.id.comments); newComment = (Button) findViewById(R.id.new_comment); // ... } } Sunday, December 16, 12
  • 24. findViewById public class MyActivity extends Activity { ListView comments; Button newComment; initialized in @Override method... void onCreate(Bundle bundle) { super.onCreate(bundle); comments = (ListView) findViewById(R.id.comments); newComment = (Button) findViewById(R.id.new_comment); // ... } } Sunday, December 16, 12
  • 25. findViewById public class MyActivity extends Activity { ListView comments; Button newComment; @Override void onCreate(Bundle bundle) { super.onCreate(bundle); comments = (ListView) findViewById(R.id.comments); newComment = (Button) findViewById(R.id.new_comment); // ... } } Explicit casting! Sunday, December 16, 12
  • 26. Robo Guice So many public class MakeANoteActivity extends Activity words... implements View.OnClickListener { public static final String PHOTO_PATH = "picture_path"; public static final String PHOTO_ATTACHED = "photo_attached"; @Inject SessionManager sessionManager; @Inject LocationHelper locationHelper; @Inject PhotoHelper photoHelper; @Inject Application context; @Inject CalibrationHelper calibrationHelper; @InjectView(R.id.attach_photo) Button attachPhoto; @InjectView(R.id.note_text) EditText noteText; @InjectView(R.id.save_button) Button save; @InjectView(R.id.date) TextView dateText; @InjectView(R.id.share) Button share; @InjectResource(R.string.im_aircasting) String imAircasting; @InjectResource(R.string.share_with) String shareWith; // ... } Sunday, December 16, 12
  • 27. Robo Guice public class MakeANoteActivity extends RoboActivity implements View.OnClickListener { public static final String PHOTO_PATH = "picture_path"; public static final String PHOTO_ATTACHED = "photo_attached"; @Inject SessionManager sessionManager; @Inject LocationHelper locationHelper; Type changes in XML, @Inject PhotoHelper photoHelper; but not here... @Inject Application context; ClassCastException! @Inject CalibrationHelper calibrationHelper; @InjectView(R.id.attach_photo) Button attachPhoto; @InjectView(R.id.note_text) EditText noteText; @InjectView(R.id.save_button) Button save; @InjectView(R.id.date) TextView dateText; @InjectView(R.id.share) Button share; @InjectResource(R.string.im_aircasting) String imAircasting; @InjectResource(R.string.share_with) String shareWith; // ... } Sunday, December 16, 12
  • 28. Robo Guice public class MakeANoteActivity extends RoboActivity implements View.OnClickListener { public static final String PHOTO_PATH = "picture_path"; public static final String PHOTO_ATTACHED = "photo_attached"; @Inject SessionManager sessionManager; @Inject LocationHelper locationHelper; Guice is eager. @Inject PhotoHelper photoHelper; Startup can take a few seconds! @Inject Application context; @Inject CalibrationHelper calibrationHelper; @InjectView(R.id.attach_photo) Button attachPhoto; @InjectView(R.id.note_text) EditText noteText; @InjectView(R.id.save_button) Button save; @InjectView(R.id.date) TextView dateText; @InjectView(R.id.share) Button share; @InjectResource(R.string.im_aircasting) String imAircasting; @InjectResource(R.string.share_with) String shareWith; // ... } Sunday, December 16, 12
  • 29. Stairway to Scala Sunday, December 16, 12
  • 30. Another look at the Java code public class MakeANoteActivity extends RoboActivity implements View.OnClickListener { public static final String PHOTO_PATH = "picture_path"; public static final String PHOTO_ATTACHED = "photo_attached"; @Inject SessionManager sessionManager; @Inject LocationHelper locationHelper; @Inject PhotoHelper photoHelper; @Inject Application context; @Inject CalibrationHelper calibrationHelper; @InjectView(R.id.attach_photo) Button attachPhoto; @InjectView(R.id.note_text) EditText noteText; @InjectView(R.id.save_button) Button save; @InjectView(R.id.date) TextView dateText; @InjectView(R.id.share) Button share; @InjectResource(R.string.im_aircasting) String imAircasting; @InjectResource(R.string.share_with) String shareWith; // ... } Sunday, December 16, 12
  • 31. What if... Scala? public class MakeANoteActivity extends RoboActivity implements View.OnClickListener { public static final String PHOTO_PATH = "picture_path"; public static final String PHOTO_ATTACHED = "photo_attached"; @Inject SessionManager sessionManager; @Inject LocationHelper locationHelper; @Inject PhotoHelper photoHelper; @Inject Application context; @Inject CalibrationHelper calibrationHelper; @InjectView(R.id.attach_photo) Button attachPhoto; @InjectView(R.id.note_text) EditText noteText; @InjectView(R.id.save_button) Button save; @InjectView(R.id.date) TextView dateText; @InjectView(R.id.share) Button share; @InjectResource(R.string.im_aircasting) String imAircasting; @InjectResource(R.string.share_with) String shareWith; // ... } Sunday, December 16, 12
  • 32. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) val imAircasting = findResource[String](R.string.im_aircasting) val shareWith = findResource[String](R.string.share_with) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 33. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { public is default. = "picture_path" val PhotoPath val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 34. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" ScalaActivity gives us some val PhotoAttached = "photo_attached" magic methods lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 35. What if... Scala? class MakeANoteActivity extends ScalaActivity It’s so easy, with View.OnClickListener YOU can implement it! with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" ScalaActivity gives us some val PhotoAttached = "photo_attached" magic methods lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 36. What if... Scala? class MakeANoteActivity extends ScalaActivity It’s so easy, with View.OnClickListener YOU can implement it! with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" ScalaActivity gives us some val PhotoAttached = "photo_attached" magic methods lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 37. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations Instead of “...Helper”, { use Traits. val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 38. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" Type Inference lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 39. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get Who’s missing here? lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 40. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get lazy initialization lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 41. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get Needs Context lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 42. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get What’s the type here?!? lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 43. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get What’s the type here?!? Typed Resource - “a better R” lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 44. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get What’s the type here?!? Typed Resource - “a better R” lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) XML Type changes... Type here changes! val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 45. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get What’s the type here?!? Typed Resource - “a better R” lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share: Button = findView(TR.share) You can be explicit though! val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 46. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = Like @InjectResource, but findView(TR.share) smarter val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Manifests vs. Type Erasure Sunday, December 16, 12
  • 47. What if... Scala? class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) Does String have a toast() val username = findResource[String](R.string.my_username) method? val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Implicit Conversion Sunday, December 16, 12
  • 49. Typed Resource = Better R Sunday, December 16, 12
  • 50. Typed Resource = Better R Sunday, December 16, 12
  • 51. Typed Resource = Better R class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 52. Typed Resource = Better R class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get lazy val locationManager = LocationManager.get lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) Typed Resource val username = findResource[String](R.string.my_username) val friends = findResource[List[String]](R.string.friends) def toastConferenceName() = "KrakDroid".toast() } Sunday, December 16, 12
  • 53. Typed Resource = Better R case class TypedResource[T](id: Int) case class TypedLayout(id: Int) object TR { val columns_pager = TypedResource[ViewPager](R.id.columns_pager) val workspaces = TypedResource[ExpandableListView](R.id.workspaces) val subtask_txt = TypedResource[TextView](R.id.subtask_txt) // ... } Sunday, December 16, 12
  • 54. Typed Resource = Better R case class TypedResource[T](id: Int) case class TypedLayout(id: Int) object TR { val columns_pager = TypedResource[ViewPager](R.id.columns_pager) val workspaces = TypedResource[ExpandableListView](R.id.workspaces) val subtask_txt = TypedResource[TextView](R.id.subtask_txt) // ... } Sunday, December 16, 12
  • 55. Typed Resource = Better R case class TypedResource[T](id: Int) case class TypedLayout(id: Int) Wrappers object TR { val columns_pager = TypedResource[ViewPager](R.id.columns_pager) val workspaces = TypedResource[ExpandableListView](R.id.workspaces) val subtask_txt = TypedResource[TextView](R.id.subtask_txt) // ... } Sunday, December 16, 12
  • 56. Typed Resource = Better R case class TypedResource[T](id: Int) case class TypedLayout(id: Int) object TR { val columns_pager = TypedResource[ViewPager](R.id.columns_pager) val workspaces = TypedResource[ExpandableListView](R.id.workspaces) val subtask_txt = TypedResource[TextView](R.id.subtask_txt) // ... } Sunday, December 16, 12
  • 57. Typed Resource = Better R case class TypedResource[T](id: Int) case class TypedLayout(id: Int) object TR { val columns_pager = TypedResource[ViewPager](R.id.columns_pager) val workspaces = TypedResource[ExpandableListView](R.id.workspaces) val subtask_txt = TypedResource[TextView](R.id.subtask_txt) // ... } Sunday, December 16, 12
  • 58. TR in Action class MakeANoteActivity extends ScalaActivity with View.OnClickListener with PhotoOperations with CalibrationOperations { val PhotoPath = "picture_path" val PhotoAttached = "photo_attached" lazy val sessionManager = SessionManager.get // magic here but lazy val locationManager = LocationManager.get // we’ll see this later! lazy val attachPhoto = findView(TR.attach_photo) lazy val noteText = findView(TR.note_text) lazy val save = findView(TR.save_button) lazy val dateText = findView(TR.date) lazy val share = findView(TR.share) // magic here too, but we’ll implement this in a few slides! val imAircasting = findResource[String](R.string.im_aircasting) val shareWith = findResource[String](R.string.share_with) // ... } Sunday, December 16, 12
  • 60. Types You always have the type information at hand. Sunday, December 16, 12
  • 61. Types You always have the type information at hand. (IntelliJ IDEA, Ensmine/Emacs, Eclipse) ⌘ SHIFT I ALT = Sunday, December 16, 12
  • 62. An Implicit Context Sunday, December 16, 12
  • 63. An Implicit Context Implicit != Explicit Sunday, December 16, 12
  • 64. An Implicit Context Implicit != Explicit def toastMyName(name: String, ctx: Context) { import android.widget.Toast._ makeText(ctx, msg, LENGTH_LONG).show() } toastMyName(”Siegfried”, getContext) Sunday, December 16, 12
  • 65. An Implicit Context Implicit != Explicit def toastMyName(name: String, ctx: Context) { import android.widget.Toast._ makeText(ctx, msg, LENGTH_LONG).show() } Explicit Parameter toastMyName(”Siegfried”, getContext) Sunday, December 16, 12
  • 66. An Implicit Context Implicit != Explicit def toastMyName(name: String, ctx: Context) { import android.widget.Toast._ makeText(ctx, msg, LENGTH_LONG).show() } Explicit Parameter toastMyName(”Siegfried”, getContext) Sunday, December 16, 12
  • 67. An Implicit Context Implicit != Explicit Import inside a method! def toastMyName(name: String, ctx: Context) { import android.widget.Toast._ makeText(ctx, msg, LENGTH_LONG).show() } toastMyName(”Siegfried”, getContext) Sunday, December 16, 12
  • 68. An Implicit Context Implicit != Explicit def toastMyName(name: String, ctx: Context) { import android.widget.Toast._ makeText(ctx, msg, LENGTH_LONG).show() } toastMyName(”Siegfried”, getContext) Sunday, December 16, 12
  • 69. An Implicit Context Implicit != Explicit def toastMyName(name: String)(implicit ctx: Context) { import android.widget.Toast._ makeText(ctx, msg, LENGTH_LONG).show() } Sunday, December 16, 12
  • 70. Implicit Parameters Implicit != Explicit def toastMyName(name: String)(implicit ctx: Context) { import android.widget.Toast._ makeText(ctx, msg, LENGTH_LONG).show() Implicit Parameter } Sunday, December 16, 12
  • 71. Implicit Parameters Implicit != Explicit def toastMyName(name: String)(implicit ctx: Context) { import android.widget.Toast._ makeText(ctx, msg, LENGTH_LONG).show() } Sunday, December 16, 12
  • 72. Implicit Parameters Implicit != Explicit def toastMyName(name: String)(implicit ctx: Context) { import android.widget.Toast._ makeText(ctx, msg, LENGTH_LONG).show() } toastMyName("Siegfried") Sunday, December 16, 12
  • 73. Implicit Parameters Implicit != Explicit def toastMyName(name: String)(implicit ctx: Context) { import android.widget.Toast._ makeText(ctx, msg, LENGTH_LONG).show() } implicit val context: Context = getContext toastMyName("Siegfried") Sunday, December 16, 12
  • 74. Implicit Parameters Implicit != Explicit def toastMyName(name: String)(implicit ctx: Context) { import android.widget.Toast._ makeText(ctx, msg, LENGTH_LONG).show() } implicit val context: Context = getContext toastMyName("Siegfried") toastMyName("Siegfried")(context) Sunday, December 16, 12
  • 75. An Implicit Context class ScalaActivity extends Activity with ImplicitContext Sunday, December 16, 12
  • 76. An Implicit Context class ScalaActivity extends Activity with ImplicitContext trait ImplicitContext { this: Activity => implicit val ctx = getContext } Sunday, December 16, 12
  • 77. An Implicit Context class ScalaActivity extends Activity with ImplicitContext “I can be only mixed into an Activity.” trait ImplicitContext { this: Activity => implicit val ctx = getContext } Sunday, December 16, 12
  • 78. An Implicit Context class ScalaActivity extends Activity with ImplicitContext “I can be only mixed into an Activity.” trait ImplicitContext { this: Activity => implicit val ctx = getContext } So I know this method! Sunday, December 16, 12
  • 79. Manifests vs. Type Erasure Sunday, December 16, 12
  • 80. Manifests vs. Type Erasure Sunday, December 16, 12
  • 81. Manifests vs. Type Erasure List<Thing> t = marshaller.parseList("[]") Java Sunday, December 16, 12
  • 82. Manifests vs. Type Erasure Uhm... List<Object>...? List<Thing> t = marshaller.parseList("[]") Java Sunday, December 16, 12
  • 83. Manifests vs. Type Erasure Uhm... List<Object>...? List<Thing> t = marshaller.parseList("[]") Java List<Thing> t = marshaller.parseList("[]", Thing.class) Sunday, December 16, 12
  • 84. Manifests vs. Type Erasure Uhm... List<Object>...? List<Thing> t = marshaller.parseList("[]") Java Oh! List<Thing>, sure! List<Thing> t = marshaller.parseList("[]", Thing.class) Sunday, December 16, 12
  • 85. Manifests vs. Type Erasure Uhm... List<Object>...? List<Thing> t = marshaller.parseList("[]") Java Oh! List<Thing>, sure! List<Thing> t = marshaller.parseList("[]", Thing.class) Scala val t: List[Thing] = marshaller.parseList("[]") Sunday, December 16, 12
  • 86. Manifests vs. Type Erasure Uhm... List<Object>...? List<Thing> t = marshaller.parseList("[]") Java Oh! List<Thing>, sure! List<Thing> t = marshaller.parseList("[]", Thing.class) Scala val t: List[Thing] = marshaller.parseList("[]") List[Thing]! Sunday, December 16, 12
  • 87. Manifests vs. Type Erasure val shareWith = findResource[String](R.string.share_with) Sunday, December 16, 12
  • 88. Manifests vs. Type Erasure val shareWith = findResource[String](R.string.share_with) Sunday, December 16, 12
  • 89. Manifests vs. Type Erasure def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T = m.toString match { case "java.lang.String" => ctx.getString(id).asInstanceOf[T] case other => throw new UnableToResolveResource(ofType = other, id = id) } val shareWith = findResource[String](R.string.share_with) Sunday, December 16, 12
  • 90. Manifests vs. Type Erasure def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T = m.toString match { case "java.lang.String" => ctx.getString(id).asInstanceOf[T] implicit case other => throw new UnableToResolveResource(ofType = other, id = id) } val shareWith = findResource[String](R.string.share_with) Sunday, December 16, 12
  • 91. Manifests vs. Type Erasure def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T = m.toString match { case "java.lang.String" => ctx.getString(id).asInstanceOf[T] implicit Manifest case other => throw new UnableToResolveResource(ofType = other, id = id) } val shareWith = findResource[String](R.string.share_with) Sunday, December 16, 12
  • 92. Manifests vs. Type Erasure def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T = m.toString match { case "java.lang.String" => ctx.getString(id).asInstanceOf[T] the type signature case other => throw new UnableToResolveResource(ofType = other, id = id) } val shareWith = findResource[String](R.string.share_with) Sunday, December 16, 12
  • 93. Manifests vs. Type Erasure def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T = m.toString match { case "java.lang.String" => ctx.getString(id).asInstanceOf[T] see the type... at runtime case "java.util.ArrayList[java.lang.String]" => newArrayList(ctx.getString(id).asInstanceOf[T]) case other => throw new UnableToResolveResource(ofType = other, id = id) } val shareWith = findResource[String](R.string.share_with) Sunday, December 16, 12
  • 94. Manifests vs. Type Erasure def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T = m.toString match { case "java.lang.String" => ctx.getString(id).asInstanceOf[T] case "java.util.ArrayList[java.lang.String]" => newArrayList(ctx.getString(id).asInstanceOf[T]) case "Int" => ctx.getString(id).toInt.asInstanceOf[T] case other => throw new UnableToResolveResource(ofType = other, id = id) } val shareWith = findResource[String](R.string.share_with) Sunday, December 16, 12
  • 95. Manifests vs. Type Erasure def findResource[T](id: Int)(implicit ctx: Context, m: Manifest[T]): T = m.toString match { case "java.lang.String" => ctx.getString(id).asInstanceOf[T] case "java.util.ArrayList[java.lang.String]" => newArrayList(ctx.getString(id).asInstanceOf[T]) case "Int" => ctx.getString(id).toInt.asInstanceOf[T] case other => java.lang.String has this...? throw new UnableToResolveResource(ofType = other, id = id) } val shareWith = findResource[String](R.string.share_with) Sunday, December 16, 12
  • 97. Implicit Conversions Implicit != Explicit Sunday, December 16, 12
  • 98. Implicit Conversions Implicit != Explicit Sunday, December 16, 12
  • 99. Implicit Conversions Implicit != Explicit Sunday, December 16, 12
  • 100. Implicit Conversions Implicit != Explicit toastMyName("Siegfried") Sunday, December 16, 12
  • 101. Implicit Conversions Implicit != Explicit Implicit Context, remember? toastMyName("Siegfried") Sunday, December 16, 12
  • 102. Implicit Conversions Implicit != Explicit toastMyName("Siegfried") What if we could... Sunday, December 16, 12
  • 103. Implicit Conversions Implicit != Explicit toastMyName("Siegfried") What if we could... "Siegfried".toast() Sunday, December 16, 12
  • 104. Implicit Conversions Implicit != Explicit Sunday, December 16, 12
  • 105. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } Sunday, December 16, 12
  • 106. Implicit Conversions Implicit != Explicit Decorator class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } Sunday, December 16, 12
  • 107. Implicit Conversions Implicit != Explicit Decorator Constructor class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } Sunday, December 16, 12
  • 108. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } new Toastable("Hello!").toast() Sunday, December 16, 12
  • 109. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } Sunday, December 16, 12
  • 110. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } trait ScalaToasts { implicit def asToastable(str: String) = new Toastable(str) } Sunday, December 16, 12
  • 111. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } Implicit Conversion: String => Toastable trait ScalaToasts { implicit def asToastable(str: String) = new Toastable(str) } Sunday, December 16, 12
  • 112. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } Implicit Conversion: String => Toastable trait ScalaToasts { implicit def asToastable(str: String) = new Toastable(str) } asToastable("Hello!").toast() Sunday, December 16, 12
  • 113. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } Implicit Conversion: String => Toastable trait ScalaToasts { implicit def asToastable(str: String) = new Toastable(str) } Sunday, December 16, 12
  • 114. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } trait ScalaToasts { implicit def asToastable(str: String) = new Toastable(str) } class ExampleActivity extends Activity with ImplicitContext with ScalaToasts Sunday, December 16, 12
  • 115. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } trait ScalaToasts { implicit def asToastable(str: String) = new Toastable(str) } class ExampleActivity extends Activity with ImplicitContext with ScalaToasts Sunday, December 16, 12
  • 116. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } trait ScalaToasts { implicit def asToastable(str: String) = new Toastable(str) } "Hello!".toast() class ExampleActivity extends Activity with ImplicitContext with ScalaToasts Sunday, December 16, 12
  • 117. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } trait ScalaToasts { implicit def asToastable(str: String) = new Toastable(str) } "Hello!".toast() class ExampleActivity extends Activity with ImplicitContext with ScalaToasts Sunday, December 16, 12
  • 118. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } trait ScalaToasts { implicit def asToastable(str: String) = new Toastable(str) } "Hello!".toast() class ExampleActivity extends Activity with ImplicitContext with ScalaToasts Sunday, December 16, 12
  • 119. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } trait ScalaToasts { implicit def asToastable(str: String) = new Toastable(str) } "Hello!".toast() class ExampleActivity extends Activity with ImplicitContext with ScalaToasts Sunday, December 16, 12
  • 120. Implicit Conversions Implicit != Explicit class Toastable(msg: String) { def toast()(implicit ctx: Context) = ??? } trait ScalaToasts { implicit def asToastable(str: String) = new Toastable(str) } "Hello!".toast() class ExampleActivity extends Activity asToastable("Hello!").toast() with ImplicitContext with ScalaToasts Sunday, December 16, 12
  • 124. public class Person { private final String name; private final String nick; POJO public Person(String name, String nick) { this.name = name; this.nick = nick; } public String getName() { return name; } public String getNick() { return nick; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Person)) return false; Person person = (Person) o; if (name != null ? !name.equals(person.name) : person.name != null) return false; if (nick != null ? !nick.equals(person.nick) : person.nick != null) return false; return true; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + (surname != null ? surname.hashCode() : 0); return result; } } Sunday, December 16, 12
  • 125. public class Person { private final String name; private final String nick; POJO public Person(String name, String nick) { this.name = name; this.nick = nick; } public String getName() { return name; } public String getNick() { return nick; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Person)) return false; Person person = (Person) o; if (name != null ? !name.equals(person.name) : person.name != null) return false; if (nick != null ? !nick.equals(person.nick) : person.nick != null) return false; return true; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + (surname != null ? surname.hashCode() : 0); return result; } } Sunday, December 16, 12
  • 126. POSO* *Actually just a Case Class case class Person(name: String, nick: String) Sunday, December 16, 12
  • 127. POSO* *Actually just a Case Class val name: String case class Person(name: String, nick: String) Sunday, December 16, 12
  • 128. Case Classes case class Person(name: String, nick: String) Sunday, December 16, 12
  • 129. Case Classes case class Person(name: String, nick: String) Sunday, December 16, 12
  • 130. Case Classes case class Person(name: String, nick: String) val person = Person("Bruce Wayne", "Manbat") // whoops! Sunday, December 16, 12
  • 131. Case Classes case class Person(name: String, nick: String) val person = Person("Bruce Wayne", "Manbat") // whoops! val fixed = person.copy(nick = "Batman") Sunday, December 16, 12
  • 132. Case Classes case class Person(name: String, nick: String) val person = Person("Bruce Wayne", "Manbat") // whoops! val fixed = person.copy(nick = "Batman") val self = Person(nick = "Ktoso" , name = "Konrad") Sunday, December 16, 12
  • 133. Case Classes case class Person(name: String, nick: String) val person = Person("Bruce Wayne", "Manbat") // whoops! val fixed = person.copy(nick = "Batman") val self = Person(nick = "Ktoso" , name = "Konrad") val Person(name, hero) = person val hello = ”Hello” + name + ” ” + surname Sunday, December 16, 12
  • 134. Case Classes case class Person(name: String, nick: String) val person = Person("Bruce Wayne", "Manbat") // whoops! val fixed = person.copy(nick = "Batman") val self = Person(nick = "Ktoso" , name = "Konrad") val Person(name, hero) = person val hello = ”Hello” + name + ” ” + surname fixed.toString should equal (”Person(Bruce Wayne, Batman)”) Still thinking assertThat().isEqualTo() is clean? Sunday, December 16, 12
  • 135. Given a list of People, return all the Hero names. Sunday, December 16, 12
  • 136. Given a list of People, return all the Hero names. public List<String> heroNames(List<Person> allPersons) { List<String> donePersons = new ArrayList<String>(allPersons.size()); for (Person person : allPersons) { if (person.isHero()) { donePersons.add(person.getName()); } } return ImmutableList.copyOf(donePersons); } Sunday, December 16, 12
  • 137. Java with Guava at their Best Given a list of People, return all the Hero names. Sunday, December 16, 12
  • 138. Java with Guava at their Best Given a list of People, return all the Hero names. return FluentIterable .from(people) .filter(new Predicate<Person>() { @Override public boolean apply(Person person) { return person != null && person.isHero(); } }) .transform(new Function<Person, String>() { @Override public String apply(Person input) { return input.getName(); } }) .toImmutableList(); Sunday, December 16, 12
  • 140. Java + Guava at their best Given a list of People, return all the Hero names. Sunday, December 16, 12
  • 141. Java + Guava at their best Given a list of People, return all the Hero names. return FluentIterable .from(people) .filter(isSuperHero) .transform(heroToName) .toImmutableList(); Java, yet pretty slick :-) I <3 Guava. Sunday, December 16, 12
  • 142. Scala Collections at Work Given a list of People, return all the Hero names. Sunday, December 16, 12
  • 143. Scala Collections at Work Given a list of People, return all the Hero names. def heroNames(people: List[Person]) = people filter(_.isHero) map { _.name} Sunday, December 16, 12
  • 144. And there’s more! Sunday, December 16, 12
  • 146. Simple Threading implicit val handler = new Handler Sunday, December 16, 12
  • 147. Simple Threading implicit val handler = new Handler inUiThread { // ... } Sunday, December 16, 12
  • 148. Simple Threading implicit val handler = new Handler inUiThread { // ... } inFutureWithProgressDialog(timeout = 10.seconds) { // ... } Sunday, December 16, 12
  • 149. Simple Threading implicit val handler = new Handler inUiThread { // ... } inFutureWithProgressDialog(timeout = 10.seconds) { // ... } Implicit Conversion on Int Sunday, December 16, 12
  • 150. on___ button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Java // ... } }); Sunday, December 16, 12
  • 151. on___ button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Java // ... } }); button onClick { view => Scala // ... } Sunday, December 16, 12
  • 153. SharedPreferences KanbaneryPreferences.projectId = projectId Sunday, December 16, 12
  • 154. SharedPreferences KanbaneryPreferences.projectId = projectId val name: Option[Long] = KanbaneryPreferences.projectId Sunday, December 16, 12
  • 155. SharedPreferences KanbaneryPreferences.projectId = projectId val name: Option[Long] = KanbaneryPreferences.projectId What? No implicits?! Assume it works! Skip! Sunday, December 16, 12
  • 156. SharedPreferences object KanbaneryPreferences { private val KeyLogin = "login" private def sharedPreferences(implicit ctx: Context) = ??? def login(implicit ctx: Context) = sharedPreferences.getString(KeyLogin, "") Sunday, December 16, 12
  • 157. SharedPreferences object KanbaneryPreferences { private val KeyLogin = "login" private def sharedPreferences(implicit ctx: Context) = ??? def login(implicit ctx: Context) = sharedPreferences.getString(KeyLogin, "") Sunday, December 16, 12
  • 158. SharedPreferences object KanbaneryPreferences { private val KeyLogin = "login" private def sharedPreferences(implicit ctx: Context) = ??? def login_=(number: String)(implicit ctx: Context) { withSharedPreferencesEditor { _.putString(KeyLogin, number) } } Sunday, December 16, 12
  • 159. SharedPreferences object KanbaneryPreferences { private val KeyLogin = "login" private def sharedPreferences(implicit ctx: Context) = ??? def login_=(number: String)(implicit ctx: Context) { withSharedPreferencesEditor { _.putString(KeyLogin, number) } } Sunday, December 16, 12
  • 160. SharedPreferences def withSharedPreferencesEditor (block: SharedPreferences.Editor => Unit) (implicit ctx: Context) { val editor = sharedPreferences.edit() block(editor) editor.commit() } Sunday, December 16, 12
  • 161. SharedPreferences def withSharedPreferencesEditor (block: SharedPreferences.Editor => Unit) (implicit ctx: Context) { val editor = sharedPreferences.edit() block(editor) editor.commit() } Sunday, December 16, 12
  • 162. SharedPreferences def withSharedPreferencesEditor (block: SharedPreferences.Editor => Unit) (implicit ctx: Context) { val editor = sharedPreferences.edit() block(editor) editor.commit() } Sunday, December 16, 12
  • 163. SharedPreferences def withSharedPreferencesEditor (block: SharedPreferences.Editor => Unit) (implicit ctx: Context) { val editor = sharedPreferences.edit() block(editor) editor.commit() } withSharedPreferencesEditor { _.putString(KeyLogin, number) } Sunday, December 16, 12
  • 164. String interpolation (scala 2.10) Sunday, December 16, 12
  • 165. String interpolation (scala 2.10) Sunday, December 16, 12
  • 166. String interpolation (scala 2.10) Sunday, December 16, 12
  • 167. String interpolation (scala 2.10) Won’t compile! Sunday, December 16, 12
  • 168. Let me warn you... Sunday, December 16, 12
  • 169. Let me warn you... Scala is addictive. Sunday, December 16, 12
  • 170. Let me warn you... Scala is addictive. Sunday, December 16, 12
  • 171. Scala is addictive. Sunday, December 16, 12
  • 172. Scala is addictive. Sunday, December 16, 12
  • 173. Scala is addictive. Sunday, December 16, 12
  • 174. Scala is addictive. Sunday, December 16, 12
  • 175. def links = • Scala Lang http://www.scala-lang.org/ • Scala Koans http://www.scalakoans.org • Blog.Project13.pl - http://www.blog.project13.pl • SBT Android Plugin - https://github.com/jberkel/android-plugin • Kanbanery for Android - https://github.com/ktoso/kanbanery-tv • Check pl.project13.scala.android.* • Now OpenSource, in Scala, and Lunar Logic is helping to dev :-) • New version soon! Pull and play with it! • Scaloid https://github.com/pocorall/scaloid • Though I don’t think their impl. is very clean some things are v. nice! Sunday, December 16, 12
  • 176. def links = • Scala Lang http://www.scala-lang.org/ • Scala Koans http://www.scalakoans.org • Blog.Project13.pl - http://www.blog.project13.pl • SBT Android Plugin - https://github.com/jberkel/android-plugin • Kanbanery for Android - https://github.com/ktoso/kanbanery-tv • Check pl.project13.scala.android.* • Now OpenSource, in Scala, and Lunar Logic is helping to dev :-) • New version soon! Pull and play with it! • Scaloid https://github.com/pocorall/scaloid • Though I don’t think their impl. is very clean some things are v. nice! Mailing lists rock! Sunday, December 16, 12
  • 177. Konrad Malawski / @ktosopl GDG / PJUG / KSUG / SCKRK KrakDroid 14.12.2012 Sunday, December 16, 12
  • 178. I love feedback! <3 Konrad Malawski / @ktosopl GDG / PJUG / KSUG / SCKRK KrakDroid 14.12.2012 Sunday, December 16, 12