A talk given at the Wix Ukraine R&D meetup in Dnipropetrovsk, Ukraine on May 22, 2014.
So you've heard of this newfangled "Scala" thing and think it might be worth checking out. Good for you! Unfortunately, it's also daunting. Your first search for Scala is likely to pitch it as a "statically-typed hybrid object-oriented and functional language", which is technically true but doesn't really help much.
Instead, this talk will provide an overview of the language, focusing on five highly practical advantages Scala has over Java without a brain hemorrhage-inducing paradigm shift, followed by some tips and recommendations on Scala adoption in the real world and (as time allows) open-ended Q&A.
The need for functional programming languages is more important than ever with the current hardware and software trends. Scala has become the number one choice for functional programming languages and is becoming the language of choice for many development teams. But with the introduction of functional programming in Java 8 is Scala still relevant and needed?
He often used to say there was only one Road; that it was like a great river: its springs were at every doorstep and every path was its tributary. "It's a dangerous business, Frodo, going out of your door," he used to say. "You step into the Road, and if you don't keep your feet, there is no telling where you might be swept off to."
-- Frodo Baggins in The Fellowship of the Ring
When you go off and learn something new there is no telling what you'll bring back. Join me on my travels in the Land of Clojure and see how ideas from Clojure have effected my day-to-day programming in other languages like JavaScript. See how ideas from ES 6 and Lodash can be traced to functional languages like Clojure. You'll never look at the way you program the same way again.
The need for functional programming languages is more important than ever with the current hardware and software trends. Scala has become the number one choice for functional programming languages and is becoming the language of choice for many development teams. But with the introduction of functional programming in Java 8 is Scala still relevant and needed?
He often used to say there was only one Road; that it was like a great river: its springs were at every doorstep and every path was its tributary. "It's a dangerous business, Frodo, going out of your door," he used to say. "You step into the Road, and if you don't keep your feet, there is no telling where you might be swept off to."
-- Frodo Baggins in The Fellowship of the Ring
When you go off and learn something new there is no telling what you'll bring back. Join me on my travels in the Land of Clojure and see how ideas from Clojure have effected my day-to-day programming in other languages like JavaScript. See how ideas from ES 6 and Lodash can be traced to functional languages like Clojure. You'll never look at the way you program the same way again.
Kotlin er et open-source programmeringsspråk til JVMen laget av JetBrains, som også bruker språket til utvikling av sine egne produkter. Det er et pragmatisk alternativ til Java med konsis syntaks, eksplisitt håndtering av nullverdier og gode verktøy for funksjonell programmering. Med andre ord kommer Kotlin med mye snacks som Java ikke har i dag.
Vi i BEKK mener at Kotlin gjør mye riktig og er et godt alternativ eller supplement til Java, samtidig som terskelen for å bruke det er lav. Java-utviklere vil raskt kunne sette seg inn i en kodebase skrevet i Kotlin og fordelene ved å starte å bruke Kotlin er verdt det.
Are you stuck in the Java world? I’ll share my story about convincing my team and the client of the benefits of Kotlin. Furthermore I’ll delve into how we migrated an existing Java Android app, with 300k active users, to Kotlin.
Even if you have never seen Kotlin before, come and see how you will create better apps with this modern and elegant language. At the end of this talk you’ll be able to convince your team / client why it’s a great to use Kotlin.
The power of Kotlin can be leveraged everywhere you use Java, since it compiles to JVM bytecode. So even if you’re not an Android developer, check out this session to get acquainted with Kotlin!
No excuses: switch to Kotlin
With the advent of the Room (the official ORM for Android). Android Database persistence has become easier than ever. Simply annotate your model objects and just like magic you have a persistent data model. However, with such simplicity, we often times forget the basics. Concepts like referential integrity, proper indexing, foreign keys and relationships can often feel, well... foreign these days. Yet, these are essential concepts in good data design and will help safe guard your app against data loss and corruption.
Greach 2015 AST – Groovy Transformers: More than meets the eye!Iván López Martín
Slides for my Greach 2015 talk: http://greachconf.com/speakers/ivan-lopez-ast-groovy-transformers-more-than-meets-the-eye/
The source code is: https://github.com/lmivan/greach2015
Groovy is a great language with extremely powerful capabilities about compile time meta-programming. Do you know that provides more than 40 AST transformations out-of-the box just to make your life as a developer easier?
In this talk you will learn the most important transformations provided by Groovy. I’ll use a lot of code examples to explain all the concepts.
A talk given at GeeCON 2018 in Prague, Czech Republic
In this talk we'll take a hard look at one of the most commonly used, and at least as commonly misunderstood, elements in software engineering: time. Time is so fundamental to the way humans experience reality that we don't normally give it a second thought, but it's just as fundamental to software systems. Without a correct model for working with time BAD THINGS HAPPEN: data is persisted out of order, exceptions occur where they shouldn't be possible, and production systems blow up.
We'll cover the various common representations of time, acknowledge their caveats and deficiencies, and hopefully learn a few new tools and practices along the way.
Nondeterministic Software for the Rest of UsTomer Gabel
A talk given at GeeCON 2018 in Krakow, Poland.
Classically-trained (if you can call it that) software engineers are used to clear problem statements and clear success and acceptance criteria. Need a mobile front-end for your blog? Sure! Support instant messaging for a million concurrent users? No problem! Store and serve 50TB of JSON blobs? Presto!
Unfortunately, it turns out modern software often includes challenges that we have a hard time with: those without clear criteria for correctness, no easy way to measure performance and success is about more than green dashboards. Your blog platform better have a spam filter, your instant messaging service has to have search, and your blobs will inevitably be fed into some data scientist's crazy contraption.
In this talk I'll share my experiences of learning to deal with non-deterministic problems, what made the process easier for me and what I've learned along the way. With any luck, you'll have an easier time of it!
Kotlin er et open-source programmeringsspråk til JVMen laget av JetBrains, som også bruker språket til utvikling av sine egne produkter. Det er et pragmatisk alternativ til Java med konsis syntaks, eksplisitt håndtering av nullverdier og gode verktøy for funksjonell programmering. Med andre ord kommer Kotlin med mye snacks som Java ikke har i dag.
Vi i BEKK mener at Kotlin gjør mye riktig og er et godt alternativ eller supplement til Java, samtidig som terskelen for å bruke det er lav. Java-utviklere vil raskt kunne sette seg inn i en kodebase skrevet i Kotlin og fordelene ved å starte å bruke Kotlin er verdt det.
Are you stuck in the Java world? I’ll share my story about convincing my team and the client of the benefits of Kotlin. Furthermore I’ll delve into how we migrated an existing Java Android app, with 300k active users, to Kotlin.
Even if you have never seen Kotlin before, come and see how you will create better apps with this modern and elegant language. At the end of this talk you’ll be able to convince your team / client why it’s a great to use Kotlin.
The power of Kotlin can be leveraged everywhere you use Java, since it compiles to JVM bytecode. So even if you’re not an Android developer, check out this session to get acquainted with Kotlin!
No excuses: switch to Kotlin
With the advent of the Room (the official ORM for Android). Android Database persistence has become easier than ever. Simply annotate your model objects and just like magic you have a persistent data model. However, with such simplicity, we often times forget the basics. Concepts like referential integrity, proper indexing, foreign keys and relationships can often feel, well... foreign these days. Yet, these are essential concepts in good data design and will help safe guard your app against data loss and corruption.
Greach 2015 AST – Groovy Transformers: More than meets the eye!Iván López Martín
Slides for my Greach 2015 talk: http://greachconf.com/speakers/ivan-lopez-ast-groovy-transformers-more-than-meets-the-eye/
The source code is: https://github.com/lmivan/greach2015
Groovy is a great language with extremely powerful capabilities about compile time meta-programming. Do you know that provides more than 40 AST transformations out-of-the box just to make your life as a developer easier?
In this talk you will learn the most important transformations provided by Groovy. I’ll use a lot of code examples to explain all the concepts.
A talk given at GeeCON 2018 in Prague, Czech Republic
In this talk we'll take a hard look at one of the most commonly used, and at least as commonly misunderstood, elements in software engineering: time. Time is so fundamental to the way humans experience reality that we don't normally give it a second thought, but it's just as fundamental to software systems. Without a correct model for working with time BAD THINGS HAPPEN: data is persisted out of order, exceptions occur where they shouldn't be possible, and production systems blow up.
We'll cover the various common representations of time, acknowledge their caveats and deficiencies, and hopefully learn a few new tools and practices along the way.
Nondeterministic Software for the Rest of UsTomer Gabel
A talk given at GeeCON 2018 in Krakow, Poland.
Classically-trained (if you can call it that) software engineers are used to clear problem statements and clear success and acceptance criteria. Need a mobile front-end for your blog? Sure! Support instant messaging for a million concurrent users? No problem! Store and serve 50TB of JSON blobs? Presto!
Unfortunately, it turns out modern software often includes challenges that we have a hard time with: those without clear criteria for correctness, no easy way to measure performance and success is about more than green dashboards. Your blog platform better have a spam filter, your instant messaging service has to have search, and your blobs will inevitably be fed into some data scientist's crazy contraption.
In this talk I'll share my experiences of learning to deal with non-deterministic problems, what made the process easier for me and what I've learned along the way. With any luck, you'll have an easier time of it!
This talk revisits dependency injection, and attempts to answer a single question honestly, or at least while pointing out and acknowledging the biases at play: "is dependency injection a good thing?"
Dependency injection has fast established itself as a major design pattern in modern software. No longer the province of server-side and enterprise software, it is now a fundamental component of frameworks from Spring to Angular.js.
With such widespread success, the time is ripe to take a fresh look at dependency injection if we are to understand it better. After all, DI is instrumental in building large systems that are loosely coupled, and it cleanly separates your tests from implementation... or does it?
(A talk given at GeeCON 2017 in Prague, Czech Republic)
Although event sourcing (and its sister pattern CQRS) has been gaining traction in recent years, it's still baffling for many engineers attempting to implement it for the first time. While there's plenty of material on the subject, most of it is too basic or theoretical for practical applications, and engineers often end up having to reinvent (or rediscover) suitable approaches and techniques.
This talk focuses on practical aspects of building event-sourced systems, lessons learned from our experience building such systems at Wix. We'll walk through the design and implementation of a relatively simple event-sourced system, covering the event model, underlying persistence model, code layering/factoring and operational considerations.
A talk given at Reversim Summit 2017 in Tel-Aviv, Israel.
The beautiful thing about software engineering is that it gives you the warm and fuzzy illusion of total understanding: I control this machine because I know how it operates. This is the result of layers upon layers of successful abstractions, which hide immense sophistication and complexity. As with any abstraction, though, these sometimes leak, and that's when a good grounding in what's under the hood pays off.
The second talk in this series peels a few layers of abstraction and takes a look under the hood of our "car engine", the CPU. While hardly anyone codes in assembly language anymore, your C# or JavaScript (or Scala or...) application still ends up executing machine code instructions on a processor; that is why Java has a memory model, why memory layout still matters at scale, and why you're usually free to ignore these considerations and go about your merry way.
You'll come away knowing a little bit about a lot of different moving parts under the hood; after all, isn't understanding how the machine operates what this is all about?
(From a talk given at BuildStuff 2016 in Vilnius, Lithuania.)
The beautiful thing about software engineering is that it gives you the warm and fuzzy illusion of total understanding: I control this machine because I know how it operates. This is the result of layers upon layers of successful abstractions, which hide immense sophistication and complexity. As with any abstraction, though, these sometimes leak, and that's when a good grounding in what's under the hood pays off.
This first in what will hopefully be a series of talks covers the fundamentals of storage, providing an overview of the three storage tiers commonly found on modern platforms (hard drives, RAM and CPU cache). You'll come away knowing a little bit about a lot of different moving parts under the hood; after all, isn't understanding how the machine operates what this is all about?
-- A talk given at GeeCON Kraków 2016.
With Java 8 adoption skyrocketing, is Scala still relevant? In our opinion, the answer is an unequivocal yes. To make our point, Tomer Gabel (system architect at Wix) will showcase practical examples where Scala's features provide a definitive advantage over Java 8. These include:
* Effective logging with traits and by-name parameters;
* Pattern matching for fun and profit;
* Type-safe, efficient serialization with type classes.
A talk given at a Wix Ukraine R&D meetup in Dnipropetrovsk, Ukraine on 6 April, 2016.
Video recording: https://youtu.be/EXxA3PlcdBg?t=3680
Sample code: https://github.com/holograph/scala-vs-java8
(A talk given at Wix R&D in Dnipro, Ukraine on March 2017. Video available at https://www.youtube.com/watch?v=eIX33mQdkAI&feature=youtu.be)
While microservices are conceptually simple, it's a deep rabbit hole to go down. Deceptively simple questions can have far-reaching implications: Which communication protocol should I choose? Is event-driven the way to go? What monitoring tools should I put in place?
In this talk we'll cover some of the fundamental questions, outline the solutions adopted or developed by Wix, and share our hindsight on what worked well for us, what didn't and thoughts on future directions for our stack.
Scala Refactoring for Fun and Profit (Japanese subtitles)Tomer Gabel
A talk given at Scala Matsuri 2016 in Tokyo, Japan.
New Scala practitioners often experience the uncomfortable feeling of "not quite getting it." If you've studied the syntax and written tests, maybe production code; if you're becoming comfortable with the language and libraries, but keep worrying that there's "a better way", or that your code isn't "idiomatic enough" - this session is for you.
By refactoring a real, live codebase, this talk will provide you with new tools and increased confidence. Between the provided examples and the ensuing discussion, you will walk away with a better feel for Scala and how to employ it in the real world.
Of the myriad challenges in scaling up an engineering organization, onboarding new employees is probably the least well-understood. There are relatively common solutions for large-scale recruitment, finance and administration, but onboarding remains a question that many organizations struggle with.
At Wix we've been struggling with massive scaling challenges: over the last two years our company headcount has doubled itself, and we had to learn to cope with the influx while maintaining velocity. In this talk we'll share with you the story of how we set up Wix Academy, an engineer-driven training organization, the solutions we've developed (and still are!), and what we've learned in our first year of operation.
A presentation given at Velocity 2016 in Amsterdam, The Netherlands (previously at BuildStuff 2015 in Vilnius, Lithuania).
The Scala programming language has been gaining significant traction over the last few years, being adopted by vastly different organizations from startups to large enterprises. While the language itself is pretty well understood and explained in tutorials and books, there is an apparent dearth of practical advice for new adopters on the best approach to integrating the new technology. In this talk I’ll attempt to offer such advice gathered over several years of production Scala use, focusing on tools, practices, patterns and the community, in the hope of making your transition into the Scala ecosystem easier and better-informed up front.
A talk given at JavaOne 2015 in San Francisco.
A talk given at JDay Lviv 2015 in Ukraine; originally developed by Yoav Abrahami, and based on the works of Kyle "Aphyr" Kingsbury:
Consistency, availability and partition tolerance: these seemingly innocuous concepts have been giving engineers and researchers of distributed systems headaches for over 15 years. But despite how important they are to the design and architecture of modern software, they are still poorly understood by many engineers.
This session covers the definition and practical ramifications of the CAP theorem; you may think that this has nothing to do with you because you "don't work on distributed systems", or possibly that it doesn't matter because you "run over a local network." Yet even traditional enterprise CRUD applications must obey the laws of physics, which are exactly what the CAP theorem describes. Know the rules of the game and they'll serve you well, or ignore them at your own peril...
Leveraging Scala Macros for Better ValidationTomer Gabel
A talk given at Scalapeño 2014 and JavaOne 2014 (video links to follow).
Data validation is a common enough problem that numerous attempts have been made to solve it elegantly. The de-facto solution in Java (JSR 303) has a number of shortcomings and fails to leverage the powerful Scala type system. The release of Scala 2.10.x introduced a couple of experimental metaprogramming features, namely reflection and macros. In this talk I'll introduce macros by way of a practical example: implementing a full-blown data validation engine, utilizing def macros and a Scala DSL to enable elegant validator definition syntax and call-site.
A talk given at ScalaUA 2016 in Kiev, Ukraine.
Scala combines a powerful type system with a lean but flexible syntax. This combination enables incredible flexibility in library design, most particularly in designing internal DSLs for many common scenarios: specification definition and matching in Specs² and ScalaTest, request routing in Spray and query construction in Squeryl, just to name a few. The budding DSL designer, however, will quickly realize that there are precious few resources on how to best approach the problem in Scala; the various techniques, limitations and workarounds are not generally well understood or documented, and every developer ends up running into the same challenges and dead-ends. In this talk I'll attempt to summarize what I've learned from reading, extending and designing Scala DSLs in the hopes that it'll save future Scala library designers a whole lot of pain.
Functional Leap of Faith (Keynote at JDay Lviv 2014)Tomer Gabel
Keynote talk given at JDay Lviv 2014 in Ukraine (http://www.jday.com.ua/). Video coming soon.
Abstract:
Some say that there's nothing new under the sun. However, looking back on five to six decades of computing, it's easy to see that things progress at their own leisurly pace. Structured programming, originating in the '60s, did not gain mainstream adoption until the '80s; object-oriented programming was hotly debated in the '70s and '80s but only gained widespread acceptance in the '90s. Every couple of decades sees an engineering leap that radically improves the software engineering discipline across the board. I believe we are now at such an inflection point, with functional programming concepts slowly sifting into the mainstream. After this talk, I hope you will too.
Watch video (in Hebrew): http://parleys.com/play/53f7a9cce4b06208c7b7ca1e
Type classes are a fundamental feature of Scala, which allows you to layer new functionality on top of existing types externally, i.e. without modifying or recompiling existing code. When combined with implicits, this is a truly remarkable tool that enables many of the advanced features offered by the Scala library ecosystem. In this talk we'll go back to basics: how type classes are defined and encoded, and cover several prominent use cases.
A talk given at the Underscore meetup on 19 August, 2014.
Nashorn: JavaScript that doesn’t suck (ILJUG)Tomer Gabel
View the video (in Hebrew) on Parleys: http://www.parleys.com/play/537f3dade4b0e9793767cd35
Java 8 introduces a new JavaScript engine called Nashorn. This presentation gives an overview of the new engine, provides some historical context and dives into the implementation details.
Originally presented at the Israeli Java User Group (ILJUG) Java 8 launch event on April 28th, 2014.
A teaser talk for Scala newbies, introducing five basic elements that (in my opinion) make the transition from Java to Scala a no-brainer.
Given at the 7th JJTV (Israeli Java/JVM user group) tool night, July 2nd, 2013.
May Marketo Masterclass, London MUG May 22 2024.pdfAdele Miller
Can't make Adobe Summit in Vegas? No sweat because the EMEA Marketo Engage Champions are coming to London to share their Summit sessions, insights and more!
This is a MUG with a twist you don't want to miss.
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisGlobus
JASMIN is the UK’s high-performance data analysis platform for environmental science, operated by STFC on behalf of the UK Natural Environment Research Council (NERC). In addition to its role in hosting the CEDA Archive (NERC’s long-term repository for climate, atmospheric science & Earth observation data in the UK), JASMIN provides a collaborative platform to a community of around 2,000 scientists in the UK and beyond, providing nearly 400 environmental science projects with working space, compute resources and tools to facilitate their work. High-performance data transfer into and out of JASMIN has always been a key feature, with many scientists bringing model outputs from supercomputers elsewhere in the UK, to analyse against observational or other model data in the CEDA Archive. A growing number of JASMIN users are now realising the benefits of using the Globus service to provide reliable and efficient data movement and other tasks in this and other contexts. Further use cases involve long-distance (intercontinental) transfers to and from JASMIN, and collecting results from a mobile atmospheric radar system, pushing data to JASMIN via a lightweight Globus deployment. We provide details of how Globus fits into our current infrastructure, our experience of the recent migration to GCSv5.4, and of our interest in developing use of the wider ecosystem of Globus services for the benefit of our user community.
In software engineering, the right architecture is essential for robust, scalable platforms. Wix has undergone a pivotal shift from event sourcing to a CRUD-based model for its microservices. This talk will chart the course of this pivotal journey.
Event sourcing, which records state changes as immutable events, provided robust auditing and "time travel" debugging for Wix Stores' microservices. Despite its benefits, the complexity it introduced in state management slowed development. Wix responded by adopting a simpler, unified CRUD model. This talk will explore the challenges of event sourcing and the advantages of Wix's new "CRUD on steroids" approach, which streamlines API integration and domain event management while preserving data integrity and system resilience.
Participants will gain valuable insights into Wix's strategies for ensuring atomicity in database updates and event production, as well as caching, materialization, and performance optimization techniques within a distributed system.
Join us to discover how Wix has mastered the art of balancing simplicity and extensibility, and learn how the re-adoption of the modest CRUD has turbocharged their development velocity, resilience, and scalability in a high-growth environment.
Listen to the keynote address and hear about the latest developments from Rachana Ananthakrishnan and Ian Foster who review the updates to the Globus Platform and Service, and the relevance of Globus to the scientific community as an automation platform to accelerate scientific discovery.
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Globus
Large Language Models (LLMs) are currently the center of attention in the tech world, particularly for their potential to advance research. In this presentation, we'll explore a straightforward and effective method for quickly initiating inference runs on supercomputers using the vLLM tool with Globus Compute, specifically on the Polaris system at ALCF. We'll begin by briefly discussing the popularity and applications of LLMs in various fields. Following this, we will introduce the vLLM tool, and explain how it integrates with Globus Compute to efficiently manage LLM operations on Polaris. Attendees will learn the practical aspects of setting up and remotely triggering LLMs from local machines, focusing on ease of use and efficiency. This talk is ideal for researchers and practitioners looking to leverage the power of LLMs in their work, offering a clear guide to harnessing supercomputing resources for quick and effective LLM inference.
We describe the deployment and use of Globus Compute for remote computation. This content is aimed at researchers who wish to compute on remote resources using a unified programming interface, as well as system administrators who will deploy and operate Globus Compute services on their research computing infrastructure.
Software Engineering, Software Consulting, Tech Lead.
Spring Boot, Spring Cloud, Spring Core, Spring JDBC, Spring Security,
Spring Transaction, Spring MVC,
Log4j, REST/SOAP WEB-SERVICES.
How to Position Your Globus Data Portal for Success Ten Good PracticesGlobus
Science gateways allow science and engineering communities to access shared data, software, computing services, and instruments. Science gateways have gained a lot of traction in the last twenty years, as evidenced by projects such as the Science Gateways Community Institute (SGCI) and the Center of Excellence on Science Gateways (SGX3) in the US, The Australian Research Data Commons (ARDC) and its platforms in Australia, and the projects around Virtual Research Environments in Europe. A few mature frameworks have evolved with their different strengths and foci and have been taken up by a larger community such as the Globus Data Portal, Hubzero, Tapis, and Galaxy. However, even when gateways are built on successful frameworks, they continue to face the challenges of ongoing maintenance costs and how to meet the ever-expanding needs of the community they serve with enhanced features. It is not uncommon that gateways with compelling use cases are nonetheless unable to get past the prototype phase and become a full production service, or if they do, they don't survive more than a couple of years. While there is no guaranteed pathway to success, it seems likely that for any gateway there is a need for a strong community and/or solid funding streams to create and sustain its success. With over twenty years of examples to draw from, this presentation goes into detail for ten factors common to successful and enduring gateways that effectively serve as best practices for any new or developing gateway.
Unleash Unlimited Potential with One-Time Purchase
BoxLang is more than just a language; it's a community. By choosing a Visionary License, you're not just investing in your success, you're actively contributing to the ongoing development and support of BoxLang.
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus
As part of the DOE Integrated Research Infrastructure (IRI) program, NERSC at Lawrence Berkeley National Lab and ALCF at Argonne National Lab are working closely with General Atomics on accelerating the computing requirements of the DIII-D experiment. As part of the work the team is investigating ways to speedup the time to solution for many different parts of the DIII-D workflow including how they run jobs on HPC systems. One of these routes is looking at Globus Compute as a way to replace the current method for managing tasks and we describe a brief proof of concept showing how Globus Compute could help to schedule jobs and be a tool to connect compute at different facilities.
Quarkus Hidden and Forbidden ExtensionsMax Andersen
Quarkus has a vast extension ecosystem and is known for its subsonic and subatomic feature set. Some of these features are not as well known, and some extensions are less talked about, but that does not make them less interesting - quite the opposite.
Come join this talk to see some tips and tricks for using Quarkus and some of the lesser known features, extensions and development techniques.
GraphSummit Paris - The art of the possible with Graph TechnologyNeo4j
Sudhir Hasbe, Chief Product Officer, Neo4j
Join us as we explore breakthrough innovations enabled by interconnected data and AI. Discover firsthand how organizations use relationships in data to uncover contextual insights and solve our most pressing challenges – from optimizing supply chains, detecting fraud, and improving customer experiences to accelerating drug discoveries.
Globus Connect Server Deep Dive - GlobusWorld 2024Globus
We explore the Globus Connect Server (GCS) architecture and experiment with advanced configuration options and use cases. This content is targeted at system administrators who are familiar with GCS and currently operate—or are planning to operate—broader deployments at their institution.
Top 7 Unique WhatsApp API Benefits | Saudi ArabiaYara Milbes
Discover the transformative power of the WhatsApp API in our latest SlideShare presentation, "Top 7 Unique WhatsApp API Benefits." In today's fast-paced digital era, effective communication is crucial for both personal and professional success. Whether you're a small business looking to enhance customer interactions or an individual seeking seamless communication with loved ones, the WhatsApp API offers robust capabilities that can significantly elevate your experience.
In this presentation, we delve into the top 7 distinctive benefits of the WhatsApp API, provided by the leading WhatsApp API service provider in Saudi Arabia. Learn how to streamline customer support, automate notifications, leverage rich media messaging, run scalable marketing campaigns, integrate secure payments, synchronize with CRM systems, and ensure enhanced security and privacy.
Launch Your Streaming Platforms in MinutesRoshan Dwivedi
The claim of launching a streaming platform in minutes might be a bit of an exaggeration, but there are services that can significantly streamline the process. Here's a breakdown:
Pros of Speedy Streaming Platform Launch Services:
No coding required: These services often use drag-and-drop interfaces or pre-built templates, eliminating the need for programming knowledge.
Faster setup: Compared to building from scratch, these platforms can get you up and running much quicker.
All-in-one solutions: Many services offer features like content management systems (CMS), video players, and monetization tools, reducing the need for multiple integrations.
Things to Consider:
Limited customization: These platforms may offer less flexibility in design and functionality compared to custom-built solutions.
Scalability: As your audience grows, you might need to upgrade to a more robust platform or encounter limitations with the "quick launch" option.
Features: Carefully evaluate which features are included and if they meet your specific needs (e.g., live streaming, subscription options).
Examples of Services for Launching Streaming Platforms:
Muvi [muvi com]
Uscreen [usencreen tv]
Alternatives to Consider:
Existing Streaming platforms: Platforms like YouTube or Twitch might be suitable for basic streaming needs, though monetization options might be limited.
Custom Development: While more time-consuming, custom development offers the most control and flexibility for your platform.
Overall, launching a streaming platform in minutes might not be entirely realistic, but these services can significantly speed up the process compared to building from scratch. Carefully consider your needs and budget when choosing the best option for you.
3. This
is
Spar–
I
mean,
Java
public class Person {!
private String name;!
private String surname;!
private int age;!
!
public Person( String name, String surname, int age ) {!
this.name = name;!
this.surname = surname;!
this.age = age;!
}!
!
public String getName() { return name; }!
public String getSurname() { return surname; }!
public int getAge() { return age; }!
!
@Override!
public String toString() { /* … */ }!
}
4. Let’s
make
some
people!
public class SimplePersonGenerator {!
!
// Prepare a bunch of useful constants…!
!
private static List<String> names;!
private static List<String> surnames;!
!
static {!
names = new ArrayList<>();!
names.add( "Jeffrey" );!
names.add( "Walter" );!
names.add( "Donald" );!
!
surnames = new ArrayList<>();!
surnames.add( "Lebowsky" );!
surnames.add( "Sobchak" );!
surnames.add( "Kerabatsos" );!
}!
5. IT’S
MADE
OF
PEOPLE!
// Continued from previous slide!
!
private static Random random = new Random();!
!
public static Person generatePerson( int age ) {!
String name = names.get( random.nextInt( names.size() ) );!
String surname = surnames.get( random.nextInt( surnames.size() ) );!
return new Person( name, surname, age );!
}!
!
public List<Person> generatePeople( int count, int age ) {!
List<Person> people = new ArrayList<>( count );!
for ( int i = 0; i < count; i++ )!
people.add( generatePerson( age ) );!
return Collections.unmodifiableList( people );!
}!
6. Scala
syntax
101
Java
public class Person {!
private String name;!
private String surname;!
private int age;!
!
public Person( String name, String surname,!
int age ) {!
this.name = name;!
this.surname = surname;!
this.age = age;!
}!
!
public String getName() { return name; }!
public String getSurname() { return surname; }!
public int getAge() { return age; }!
!
@Override!
public String toString() { /* … */ }!
}
7. Scala
syntax
101
Java
public class Person {!
private String name;!
private String surname;!
private int age;!
!
public Person( String name, String surname,!
int age ) {!
this.name = name;!
this.surname = surname;!
this.age = age;!
}!
!
public String getName() { return name; }!
public String getSurname() { return surname; }!
public int getAge() { return age; }!
!
@Override!
public String toString() { /* … */ }!
}
Scala
case class Person(!
name: String,!
surname: String,!
age: Int )!
8. Scala
syntax
101
Java
public class Person {!
private String name;!
private String surname;!
private int age;!
!
public Person( String name, String surname,!
int age ) {!
this.name = name;!
this.surname = surname;!
this.age = age;!
}!
!
public String getName() { return name; }!
public String getSurname() { return surname; }!
public int getAge() { return age; }!
!
@Override!
public String toString() { /* … */ }!
}
Scala
case class Person(!
name: String,!
surname: String,!
age: Int )!
Provides:
– Constructor
– Property
geOers
– hashCode/equals
– toString
– …
and
more
9. Onwards…
Java
public class SimplePersonGenerator {!
!
// Prepare a bunch of useful constants…!
!
private static List<String> names;!
private static List<String> surnames;!
!
static {!
names = new ArrayList<>();!
names.add( "Jeffrey" );!
names.add( "Walter" );!
names.add( "Donald" );!
!
surnames = new ArrayList<>();!
surnames.add( "Lebowsky" );!
surnames.add( "Sobchak" );!
surnames.add( "Kerabatsos" );!
}!
11. ...
and
finally:
Java
private static Random random = new Random();!
!
public static Person generatePerson( int age ) {!
String name = names.get( !
random.nextInt( names.size() ) ); !
String surname = surnames.get( !
random.nextInt( surnames.size() ) );!
return new Person( name, surname, age );!
}!
!
public List<Person> generatePeople(!
int count, int age ) {!
List<Person> people = new ArrayList<>( count );!
for ( int i = 0; i < count; i++ )!
people.add( generatePerson( age ) );!
return Collections.unmodifiableList( people );!
}!
12. ...
and
finally:
Java
private static Random random = new Random();!
!
public static Person generatePerson( int age ) {!
String name = names.get( !
random.nextInt( names.size() ) ); !
String surname = surnames.get( !
random.nextInt( surnames.size() ) );!
return new Person( name, surname, age );!
}!
!
public List<Person> generatePeople(!
int count, int age ) {!
List<Person> people = new ArrayList<>( count );!
for ( int i = 0; i < count; i++ )!
people.add( generatePerson( age ) );!
return Collections.unmodifiableList( people );!
}!
Scala
private val random: Random = new Random!
!
def generatePerson( age: Int ): Person = {!
val name: String =!
names( random.nextInt( names.size ) )!
val surname: String =!
surnames( random.nextInt( surnames.size ) )!
new Person( name, surname, age )!
}!
!
!
13. ...
and
finally:
Java
private static Random random = new Random();!
!
public static Person generatePerson( int age ) {!
String name = names.get( !
random.nextInt( names.size() ) ); !
String surname = surnames.get( !
random.nextInt( surnames.size() ) );!
return new Person( name, surname, age );!
}!
!
public List<Person> generatePeople(!
int count, int age ) {!
List<Person> people = new ArrayList<>( count );!
for ( int i = 0; i < count; i++ )!
people.add( generatePerson( age ) );!
return Collections.unmodifiableList( people );!
}!
Scala
private val random: Random = new Random!
!
def generatePerson( age: Int ): Person = {!
val name: String =!
names( random.nextInt( names.size ) )!
val surname: String =!
surnames( random.nextInt( surnames.size ) )!
new Person( name, surname, age )!
}!
!
def generatePeople( count: Int, age: Int ):!
List[ Person ] = {!
val people: mutable.ListBuffer[ Person ] =!
mutable.ListBuffer.empty!
for ( i <- 0 until count ) {!
people.append( generatePerson( age ) )!
}!
people.result()!
}!
!
15. We
started
off
with:
Java
private static Random random = new Random();!
!
public static Person generatePerson( int age ) {!
String name = names.get( !
random.nextInt( names.size() ) ); !
String surname = surnames.get( !
random.nextInt( surnames.size() ) );!
return new Person( name, surname, age );!
}!
!
public static List<Person> generatePeople(!
int count, int age ) {!
List<Person> people = new ArrayList<>( count );!
for ( int i = 0; i < count; i++ )!
people.add( generatePerson( age ) );!
return Collections.unmodifiableList( people );!
}!
Scala
private val random: Random = new Random!
!
def generatePerson( age: Int ): Person = {!
val name: String =!
names( random.nextInt( names.size ) )!
val surname: String =!
surnames( random.nextInt( surnames.size ) )!
new Person( name, surname, age )!
}!
!
def generatePeople( count: Int, age: Int ):!
List[ Person ] = {!
val people: mutable.ListBuffer[ Person ] =!
mutable.ListBuffer.empty!
for ( i <- 0 until count ) {!
people.append( generatePerson( age ) )!
}!
people.result()!
}!
!
16. Let’s
simplify!
Java
private static Random random = new Random();!
!
public static Person generatePerson( int age ) {!
String name = names.get( !
random.nextInt( names.size() ) ); !
String surname = surnames.get( !
random.nextInt( surnames.size() ) );!
return new Person( name, surname, age );!
}!
!
public static List<Person> generatePeople(!
int count, int age ) {!
List<Person> people = new ArrayList<>( count );!
for ( int i = 0; i < count; i++ )!
people.add( generatePerson( age ) );!
return Collections.unmodifiableList( people );!
}!
Scala
private val random = new Random!
!
def generatePerson( age: Int ): Person = {!
val name =!
names( random.nextInt( names.size ) )!
val surname =!
surnames( random.nextInt( surnames.size ) )!
new Person( name, surname, age )!
}!
!
def generatePeople( count: Int, age: Int ):!
List[ Person ] = {!
val people =!
mutable.ListBuffer.empty[ Person ]!
for ( i <- 0 until count ) {!
people.append( generatePerson( age ) )!
}!
people.result()!
}!
!
17. Also
works
for
result
types:
Java
private static Random random = new Random();!
!
public static Person generatePerson( int age ) {!
String name = names.get( !
random.nextInt( names.size() ) ); !
String surname = surnames.get( !
random.nextInt( surnames.size() ) );!
return new Person( name, surname, age );!
}!
!
public static List<Person> generatePeople(!
int count, int age ) {!
List<Person> people = new ArrayList<>( count );!
for ( int i = 0; i < count; i++ )!
people.add( generatePerson( age ) );!
return Collections.unmodifiableList( people );!
}!
Scala
private val random = new Random!
!
def generatePerson( age: Int ) = {!
val name =!
names( random.nextInt( names.size ) )!
val surname =!
surnames( random.nextInt( surnames.size ) )!
new Person( name, surname, age )!
}!
!
def generatePeople( count: Int, age: Int ) = {!
val people =!
mutable.ListBuffer.empty[ Person ]!
for ( i <- 0 until count ) {!
people.append( generatePerson( age ) )!
}!
people.result()!
}!
!
18. Also
works
for
result
types:
Java
private static Random random = new Random();!
!
public static Person generatePerson( int age ) {!
String name = names.get( !
random.nextInt( names.size() ) ); !
String surname = surnames.get( !
random.nextInt( surnames.size() ) );!
return new Person( name, surname, age );!
}!
!
public List<Person> generatePeople(!
int count, int age ) {!
List<Person> people = new ArrayList<>( count );!
for ( int i = 0; i < count; i++ )!
people.add( generatePerson( age ) );!
return Collections.unmodifiableList( people );!
}!
Scala
private val random = new Random!
!
def generatePerson( age: Int ) = {!
val name =!
names( random.nextInt( names.size ) )!
val surname =!
surnames( random.nextInt( surnames.size ) )!
new Person( name, surname, age )!
}!
!
def generatePeople( count: Int, age: Int ) = {!
val people =!
mutable.ListBuffer.empty[ Person ]!
for ( i <- 0 until count ) {!
people.append( generatePerson( age ) )!
}!
people.result()!
}!
!
Not necessarily a good idea.
• Code readability
• Public APIs
• Compilation times
19. Bonus
points:
Named
arguments
Java
private static Random random = new Random();!
!
public static Person generatePerson( int age ) {!
String name = names.get( !
random.nextInt( names.size() ) ); !
String surname = surnames.get( !
random.nextInt( surnames.size() ) );!
return new Person( name, surname, age );!
}!
!
public static List<Person> generatePeople(!
int count, int age ) {!
List<Person> people = new ArrayList<>( count );!
for ( int i = 0; i < count; i++ )!
people.add( generatePerson( age ) );!
return Collections.unmodifiableList( people );!
}!
Scala
private val random = new Random!
!
def generatePerson( age: Int ) = Person(!
name = names( random.nextInt( names.size ) )!
surname =
surnames( random.nextInt( surnames.size ) )!
age = age!
)!
!
def generatePeople( count: Int, age: Int ) = {!
val people =!
mutable.ListBuffer.empty[ Person ]!
for ( i <- 0 until count ) {!
people.append( generatePerson( age ) )!
}!
people.result()!
}!
!
21. Quick
example
Java
private static Random random = new Random();!
!
public static Person generatePerson( int age ) {!
String name = names.get( !
random.nextInt( names.size() ) ); !
String surname = surnames.get( !
random.nextInt( surnames.size() ) );!
return new Person( name, surname, age );!
}!
!
public static List<Person> generatePeople(!
int count, int age ) {!
List<Person> people = new ArrayList<>( count );!
for ( int i = 0; i < count; i++ )!
people.add( generatePerson( age ) );!
return Collections.unmodifiableList( people );!
}!
Scala
private val random = new Random!
!
def generatePerson( age: Int ) = Person(!
name = names( random.nextInt( names.size ) )!
surname =
surnames( random.nextInt( surnames.size ) )!
age = age!
)!
!
def generatePeople( count: Int, age: Int ) = {!
val people =!
mutable.ListBuffer.empty[ Person ]!
for ( i <- 0 until count ) {!
people.append( generatePerson( age ) )!
}!
people.result()!
}!
!
22. Quick
example
Java
private static Random random = new Random();!
!
public static Person generatePerson( int age ) {!
String name = names.get( !
random.nextInt( names.size() ) ); !
String surname = surnames.get( !
random.nextInt( surnames.size() ) );!
return new Person( name, surname, age );!
}!
!
public static List<Person> generatePeople(!
int count, int age ) {!
List<Person> people = new ArrayList<>( count );!
for ( int i = 0; i < count; i++ )!
people.add( generatePerson( age ) );!
return Collections.unmodifiableList( people );!
}!
Scala
private val random = new Random!
!
def generatePerson( age: Int ) = Person(!
name = names( random.nextInt( names.size ) )!
surname =
surnames( random.nextInt( surnames.size ) )!
age = age!
)!
!
!
!
!
def generatePeople( count: Int, age: Int ) =!
List.fill( count ) { generatePerson( age ) }!
23. Scala
collec[ons
primer
// Some data to start with…!
val people = generatePeople( 5 )!
!
val names = people.map( p => p.name )!
!
val adults = people.filter( p => p.age >= 18 )!
!
val averageAge = !
people.map( p => p.age ).sum / people.size!
!
// Functions are 1st class citizens!
def isAdult( p: Person ) = p.age >= 18!
val adults2 = people.filter( isAdult )!
assert( adults2 == adults )
24. Maps,
too
val trivial: Map[ String, String ] =!
Map( "name" -> "Jeffrey Lebowsky",!
"alias" -> "The Dude" )!
!
val directory: Map[ Char, List[ Person ] ] =!
people!
.groupBy( p => p.surname.head.toUpper )!
.withDefaultValue( List.empty )!
!
val beginningWithK: List[ Person ] =!
directory( 'K' )!
!
val countByFirstLetter: Map[ Char, Int ] = !
directory.mapValues( list => list.size )!
25. And
much,
much,
much
more
!
val ( adults, minors ) = people.partition( p => p.age >= 18 )!
!
val randomPairs = Random.shuffle( people ).grouped( 2 )!
!
val youngest = people.minBy( p => p.age )!
!
val oldest = people.maxBy( p => p.age )!
!
val hasSeniorCitizens = people.exists( p => p.age >= 65 )
26. Caveat
emptor
• Scala
is
flexible
– You
can
do
the
same
thing
in
mul[ple
ways:
people.foreach( person => println( person ) ) !// "Normal"!
people.foreach { person => println( person ) } !// Block-style!
people.foreach { println(_) } ! ! !// Placeholder syntax!
people.foreach( println ) ! ! !// With function!
people foreach println ! ! ! !// Infix notation
• Stay
sane.
Stay
safe.
– Pick
a
style
and
s[ck
with
it
28. Back
in
Java-‐Land
public class Person {!
private String name;!
private String surname;!
private int age;!
!
public Person( String name, String surname, int age ) {!
this.name = name;!
this.surname = surname;!
this.age = age;!
}!
!
public String getName() { return name; }!
public String getSurname() { return surname; }!
public int getAge() { return age; }!
!
@Override!
public String toString() { /* … */ }!
}
We want to make these
optional.
29. Typical
solu[on
in
Java
public class PartiallyKnownPerson {!
private String name;!
private String surname;!
private Integer age;!
!
public PartiallyKnownPerson( String name, String surname, Integer age ) {!
this.name = name;!
this.surname = surname;!
this.age = age;!
}!
!
public String getName() { return name; }!
public String getSurname() { return surname; }!
public Integer getAge() { return age; }!
!
@Override!
public String toString() { /* … */ }!
}
30. This
sucks
public class PartiallyKnownPerson {!
private String name;!
private String surname;!
private Integer age;!
!
public PartiallyKnownPerson ( String name, String surname, Integer age ) {!
this.name = name;!
this.surname = surname;!
this.age = age;!
}!
!
public String getName() { return name; }!
public String getSurname() { return surname; }!
public Integer getAge() { return age; }!
!
@Override!
public String toString() { /* … */ }!
}
Returned values
always need to be
checked.
Implicit; does not document intent.
31. Falling
back
to
JavaDocs
/**!
* Creates a new person.!
* @param name The person's name (or {@literal null} if unknown).!
* @param surname The person's surname (or {@literal null} if unknown).!
* @param age The person's age (or {@literal null} if unknown).!
*/!
public PartiallyKnownPerson( String name, String surname, Integer age ) {!
this.name = name;!
this.surname = surname;!
this.age = age;!
}
32. Falling
back
to
JavaDocs
/**!
* Creates a new person.!
* @param name The person's name (or {@literal null} if unknown).!
* @param surname The person's surname (or {@literal null} if unknown).!
* @param age The person's age (or {@literal null} if unknown).!
*/!
public PartiallyKnownPerson( String name, String surname, Integer age ) {!
this.name = name;!
this.surname = surname;!
this.age = age;!
}!
This still sucks.
33. Falling
back
to
JavaDocs
/**!
* Creates a new person.!
* @param name The person's name (or {@literal null} if unknown).!
* @param surname The person's surname (or {@literal null} if unknown).!
* @param age The person's age (or {@literal null} if unknown).!
*/!
public PartiallyKnownPerson( String name, String surname, Integer age ) {!
this.name = name;!
this.surname = surname;!
this.age = age;!
}!
!
boolean isAdult( Person p ) {!
return p.getAge() >= 18; // I love the smell of NPEs in the morning!
}
This still sucks.Because:
34. Op[onal
arguments,
the
Scala
way
case class PartiallyKnownPerson( name: Option[ String ] = None,!
surname: Option[ String ] = None,!
age: Option[ Int ] = None ) {!
!
def isAdult = age.map( _ > 18 )!
}!
!
val person = PartiallyKnownPerson( name = Some( "Brandt" ) )!
!
val explicitAccess = person.age.get // <-- NoSuchElementException thrown here!
!
val withDefault = person.name.getOrElse( "Anonymous" )!
println( "Hello " + withDefault + "!" )!
!
// Options are also zero- or single-element collections!!
def greet( whom: Iterable[ String ] ) =!
whom.foreach { name => println( "hello" + name ) }!
greet( person.name )
36. Back
in
Java
land…
import org.slf4j.Logger;!
import org.slf4j.LoggerFactory;!
!
public class ClassWithLogs {!
private static Logger log = LoggerFactory.getLogger( ClassWithLogs.class );!
!
public String getNormalizedName( Person person ) {!
log.info( "getNormalizedName called" );!
log.debug( "Normalizing " + person.toString() );!
String normalizedName = person.getName().toUpperCase().trim();!
log.debug( "Normalized name is: " + normalizedName );!
return normalizedName;!
}!
}
37. …
boilerplate
is
king
import org.slf4j.Logger;!
import org.slf4j.LoggerFactory;!
!
public class ClassWithLogs {!
private static Logger log = LoggerFactory.getLogger( ClassWithLogs.class );!
!
public String getNormalizedName( Person person ) {!
log.info( "getNormalizedName called" );!
log.debug( "Normalizing " + person.toString() );!
String normalizedName = person.getName().toUpperCase().trim();!
log.debug( "Normalized name is: " + normalizedName );!
return normalizedName;!
}!
}
x1000 classes…
Eager evaluation
38. What
can
we
do
about
it?
• A
solu[on
should:
– Require
minimal
boilerplate
– Cause
few
or
no
side-‐effects
– Be
composable
– Perform
well
• An
abstract
base
class
is
useless
– Only
one
base
class
allowed
– No
way
to
do
lazy
evalua[on
40. Boilerplate
is
king
Java
public class ClassWithLogs {!
private static Logger log =!
LoggerFactory.getLogger(!
ClassWithLogs.class );!
!
public String getNormalizedName(!
Person person ) {!
log.info( "getNormalizedName called" );!
log.debug( "Normalizing " +!
person.toString() );!
String normalizedName =!
person.getName().toUpperCase().trim();!
log.debug( "Normalized name is: " +!
normalizedName );!
return normalizedName;!
}!
}
Scala
!
class ClassWithLogs extends Logging {!
!
!
!
def getNormalizedName( person: Person ) = {!
logInfo( "getNormalizedName called" )!
logDebug( "Normalizing " +!
person.toString )!
val normalizedName =!
person.name.toUpperCase.trim!
logDebug( "Normalized name is: " +!
normalizedName )!
normalizedName!
}!
}
41. Not
convinced?
• Consider:
trait Iterator[ T ] {!
def hasNext: Boolean!
def next: T
// Or throw NoSuchElementException!
}!
!
trait Iterable[ T ] {!
def getIterator: Iterator[ T ]!
def first: T // Or throw NoSuchElementException!
def firstOption: Option[ T ]!
def last: T // Or throw NoSuchElementException!
def lastOption: Option[ T ]!
def size: Int!
}
• What
if
you
need
to
implement
ArrayList,
HashSet,
LinkedList…?
42. A
saner
op[on
trait BaseIterable[ T ] extends Iterable[ T ] {!
!
def firstOption = {!
val it = getIterator!
if ( it.hasNext ) Some( it.next ) else None!
}!
!
def first = firstOption.getOrElse( throw new NoSuchElementException )!
!
def size = {!
val it = getIterator!
var count = 0!
while ( it.hasNext ) { count += 1; it.next }!
count!
}!
!
// …!
}
43. Massive
win!
case class ArrayList[ T ]( array: Array[ T ] )!
extends BaseIterable[ T ] {!
!
def getIterator = new Iterator[ T ] {!
var index = 0!
!
def hasNext = index < array.length!
!
def next =!
if ( hasNext ) {!
val value = array( index )!
index += 1!
value!
} else!
throw new NoSuchElementException!
}!
}
• No
boilerplate
• Implement
only
“missing
bits”
• Mix
and
match
mul[ple
traits!
• Need
features?
– Add
to
your
concrete
class
• Need
performance?
– Override
the
default
implementa[on
45. Enhancing
our
domain
model
Java
enum MaritalStatus { !
single, married, divorced, widowed !
}!
!
enum Gender { !
male, female !
}!
!
class Person {!
private String name;!
private String surname;!
private int age;!
private MaritalStatus maritalStatus;!
private Gender gender;!
// …!
}!
46. Enhancing
our
domain
model
Java
enum MaritalStatus { !
single, married, divorced, widowed !
}!
!
enum Gender { !
male, female !
}!
!
class Person {!
private String name;!
private String surname;!
private int age;!
private MaritalStatus maritalStatus;!
private Gender gender;!
// …!
}!
Scala
sealed trait MaritalStatus!
case object Single extends MaritalStatus!
case object Married extends MaritalStatus!
case object Divorced extends MaritalStatus!
case object Widowed extends MaritalStatus!
!
sealed trait Gender!
case object Male extends Gender!
case object Female extends Gender!
!
case class Person(!
name: String, surname: String, age: Int,!
maritalStatus: Option[ MaritalStatus ],!
gender: Option[ Gender ] )!
47. Saluta[on
genera[on
Java
public String getSalutation() {!
if ( gender == null ) return null;!
switch( gender ) {!
case male:!
return "Mr.";!
!
case female:!
if ( maritalStatus == null )!
return "Ms.";!
switch( maritalStatus ) {!
case single:!
return "Miss";!
!
case married:!
case divorced:!
case widowed:!
return "Mrs.";!
}!
}!
48. Saluta[on
genera[on
Java
public String getSalutation() {!
if ( gender == null ) return null;!
switch( gender ) {!
case male:!
return "Mr.";!
!
case female:!
if ( maritalStatus == null )!
return "Ms.";!
switch( maritalStatus ) {!
case single:!
return "Miss";!
!
case married:!
case divorced:!
case widowed:!
return "Mrs.";!
}!
}!
Scala
!
!
def salutation: Option[ String ] = !
( gender, maritalStatus ) match {!
case (Some(Male ), _ ) => Some("Mr.")!
case (Some(Female), Some(Single)) => Some("Miss")!
case (Some(Female), None ) => Some("Ms.")!
case (Some(Female), _ ) => Some("Mrs.")!
case (None , _ ) => None!
}
49. Why
is
this
awesome?
• Other
use
cases
include:
– Reac[ng
to
objects
of
unknown
type
– Decomposing
structures
• Extensible
via
extractor
objects
• Compiler
performs
exhaus0veness
check!
51. What
about
Java
8,
you
ask?
• Java
8
is
awesome
• …
it
validates
Scala!
• But
it’s
not
up
to
par
• Closures/lambdas:
– Syntax
is
limited
– Func[ons
aren’t
1st
class
• Default
methods
aren’t
a
subs[tute
for
traits
– No
self-‐type
annota[on
– No
visibility
modifiers
(e.g.
protected
members)
52. Note
that
we
haven’t
covered…
• For
comprehensions
• Lazy
vals
• Tuples
• Generics
– Type
bounds
– Variance
– Higher-‐kinded
types
• Implicits
– Type
classes
– Conversions
– Parameters
• Func[ons
and
par[al
func[ons
• Top
and
boOom
types
• Scoped
imports
• Extractor
objects
(unapply/-‐seq)
• Structural
types
• Type
members
– …
and
path-‐dependent
types
• Futures
and
promises
• Macros
• DSLs
53. Thanks
you
for
listening!
Ques[ons?
Code
is
on
GitHub
I
am
on
TwiOer
@tomerg
Scala
is
on
the
internetz