The document discusses the benefits of Scala as a programming language. It summarizes Scala's key features as being a functional and object-oriented language that runs on the JVM, provides improved type safety compared to Java/C#, and was designed by Martin Odersky who has deep experience with programming languages and industry. Everything in Scala can be treated as a function, including objects, which allows for more succinct coding patterns using functional idioms like map and filter.
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.
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.
"The joy of Scala" - Maxim Novak / Wix
Around eight years ago I started my journey as a developer. Since then, I've played around with many languages and thought that C# offers the best developer productivity. After joining Wix two years ago, I was exposed to the amazing world of Scala and Functional Programming and never looked back.
In Scala the code is much more concise, less ceremonious, immutable by default, combines functional with object oriented, seamlessly interoperates with Java, and many software engineering patterns are already baked into the language. Most importantly - Scala is FUN! By the end of the session you too will, hopefully, convert to Scala and never look back.
Recording of the lecture (Hebrew) - https://youtu.be/TcnYTwff2xU
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsJohn De Goes
Quark is a new Scala DSL for data processing and analytics that runs on top of the Quasar Analytics compiler. Quark is adept at processing semi-structured data and compiles query plans to operations that run entirely inside a target data source. In this presentation, John A. De Goes provides an overview of the open source library, showing several use cases in data processing and analytics. John also demonstrates a powerful technique that every developer can use to create their own purely-functional, type-safe DSLs in the Scala programming language.
Introduction to Lisp. A survey of lisp's history, current incarnations and advanced features such as list comprehensions, macros and domain-specific-language [DSL] support.
Short (45 min) version of my 'Pragmatic Real-World Scala' talk. Discussing patterns and idioms discovered during 1.5 years of building a production system for finance; portfolio management and simulation.
Some notes about programming in Scala: it covers Scala syntax and semantics, programming techniques, idioms, patterns. Many Scala features are introduced, from basic to intermediate and advanced. These are not introductory notes, but they assume a working knowledge with some other programming language (Java, C#, C++), object-oriented programming (OOP) concepts, and functional programming (FP) concepts.
JavaOne 2016 - Learn Lambda and functional programmingHenri Tremblay
This tutorial walks through tons of examples. You will learn everything you need to know about lambdas and functional programming in Java 8. I'm the supplier. You’re the consumer (and you will get the joke after the session).
Some languages, like SML, Haskell, and Scala, have built-in support for pattern matching, which is a generic way of branching based on the structure of data.
While not without its drawbacks, pattern matching can help eliminate a lot of boilerplate, and it's often cited as a reason why functional programming languages are so concise.
In this talk, John A. De Goes talks about the differences between built-in patterns, and so-called first-class patterns (which are "do-it-yourself" patterns implemented using other language features).
Unlike built-in patterns, first-class patterns aren't magical, so you can store them in variables and combine them in lots of interesting ways that aren't always possible with built-in patterns. In addition, almost every programming language can support first-class patterns (albeit with differing levels of effort and type-safety).
During the talk, you'll watch as a mini-pattern matching library is developed, and have the opportunity to follow along and build your own pattern matching library in the language of your choice.
Scalaz 8 is the latest edition of the popular functional programming library for Scala. In this whirlwind tour, maintainer John A. De Goes discusses some of the hottest features of Scalaz 8, including all of the following:
* A fast, concurrent, and leak-free effect system, which has small, composable, and powerful primitives for building practical, real-world software;
* A non-linear type class hierarchy, which permits a more powerful hierarchy that infers well without devastating ambiguous implicit errors;
* A new encoding for abstractions in category theory that providers higher fidelity and enables new categories of useful software to be developed;
* A Scala 2.12 encoding of opaque types that powers improved performance and better developer UX.
In this tour, you’ll see how the design of Scalaz 8 was inspired by a desire to provide Scala developers with a principled, performant, and pragmatic library that never sacrifices the safety and equational reasoning properties of functional programming. You’ll see live code snippets that show you how solving complex real world problems is simpler, faster, safer, and more reasonable than in previous versions of Scalaz. And hopefully you’ll be inspired at just how far functional programming in Scala has come in the past decade.
Java 8, lambdas, generics: How to survive? - NYC Java Meetup GroupHenri Tremblay
Lambdas are sexy. But they are adding complexity. Mixed with generics, it creates a dangerous cocktail. Together, we will start from the bottom of generics and go straight through lambda inference. To explain why it is the way it is and tell you how to survive.
The Next Great Functional Programming LanguageJohn De Goes
A LambdaConf 2015 talk.
John has no clue what the next great functional programming language will be like, but he's more than happy to hop up on stage and rant against type classes, nominative typing, data, modules, pattern matching, recursion, and, well, basically everything else you associate with functional programming! John will argue that to make radical progress in cheaply building correct software, we need to take one step backward and two steps forward, embracing dependent-typing, total functions, Turing-complete compilers, host languages, and automated proof search. Attend this talk to question your assumptions about functional programming... or just to heckle! Either way, all are welcome.
Slides for a lightning talk on Java 8 lambda expressions I gave at the Near Infinity (www.nearinfinity.com) 2013 spring conference.
The associated sample code is on GitHub at https://github.com/sleberknight/java8-lambda-samples
"The joy of Scala" - Maxim Novak / Wix
Around eight years ago I started my journey as a developer. Since then, I've played around with many languages and thought that C# offers the best developer productivity. After joining Wix two years ago, I was exposed to the amazing world of Scala and Functional Programming and never looked back.
In Scala the code is much more concise, less ceremonious, immutable by default, combines functional with object oriented, seamlessly interoperates with Java, and many software engineering patterns are already baked into the language. Most importantly - Scala is FUN! By the end of the session you too will, hopefully, convert to Scala and never look back.
Recording of the lecture (Hebrew) - https://youtu.be/TcnYTwff2xU
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsJohn De Goes
Quark is a new Scala DSL for data processing and analytics that runs on top of the Quasar Analytics compiler. Quark is adept at processing semi-structured data and compiles query plans to operations that run entirely inside a target data source. In this presentation, John A. De Goes provides an overview of the open source library, showing several use cases in data processing and analytics. John also demonstrates a powerful technique that every developer can use to create their own purely-functional, type-safe DSLs in the Scala programming language.
Introduction to Lisp. A survey of lisp's history, current incarnations and advanced features such as list comprehensions, macros and domain-specific-language [DSL] support.
Short (45 min) version of my 'Pragmatic Real-World Scala' talk. Discussing patterns and idioms discovered during 1.5 years of building a production system for finance; portfolio management and simulation.
Some notes about programming in Scala: it covers Scala syntax and semantics, programming techniques, idioms, patterns. Many Scala features are introduced, from basic to intermediate and advanced. These are not introductory notes, but they assume a working knowledge with some other programming language (Java, C#, C++), object-oriented programming (OOP) concepts, and functional programming (FP) concepts.
JavaOne 2016 - Learn Lambda and functional programmingHenri Tremblay
This tutorial walks through tons of examples. You will learn everything you need to know about lambdas and functional programming in Java 8. I'm the supplier. You’re the consumer (and you will get the joke after the session).
Some languages, like SML, Haskell, and Scala, have built-in support for pattern matching, which is a generic way of branching based on the structure of data.
While not without its drawbacks, pattern matching can help eliminate a lot of boilerplate, and it's often cited as a reason why functional programming languages are so concise.
In this talk, John A. De Goes talks about the differences between built-in patterns, and so-called first-class patterns (which are "do-it-yourself" patterns implemented using other language features).
Unlike built-in patterns, first-class patterns aren't magical, so you can store them in variables and combine them in lots of interesting ways that aren't always possible with built-in patterns. In addition, almost every programming language can support first-class patterns (albeit with differing levels of effort and type-safety).
During the talk, you'll watch as a mini-pattern matching library is developed, and have the opportunity to follow along and build your own pattern matching library in the language of your choice.
Scalaz 8 is the latest edition of the popular functional programming library for Scala. In this whirlwind tour, maintainer John A. De Goes discusses some of the hottest features of Scalaz 8, including all of the following:
* A fast, concurrent, and leak-free effect system, which has small, composable, and powerful primitives for building practical, real-world software;
* A non-linear type class hierarchy, which permits a more powerful hierarchy that infers well without devastating ambiguous implicit errors;
* A new encoding for abstractions in category theory that providers higher fidelity and enables new categories of useful software to be developed;
* A Scala 2.12 encoding of opaque types that powers improved performance and better developer UX.
In this tour, you’ll see how the design of Scalaz 8 was inspired by a desire to provide Scala developers with a principled, performant, and pragmatic library that never sacrifices the safety and equational reasoning properties of functional programming. You’ll see live code snippets that show you how solving complex real world problems is simpler, faster, safer, and more reasonable than in previous versions of Scalaz. And hopefully you’ll be inspired at just how far functional programming in Scala has come in the past decade.
Java 8, lambdas, generics: How to survive? - NYC Java Meetup GroupHenri Tremblay
Lambdas are sexy. But they are adding complexity. Mixed with generics, it creates a dangerous cocktail. Together, we will start from the bottom of generics and go straight through lambda inference. To explain why it is the way it is and tell you how to survive.
The Next Great Functional Programming LanguageJohn De Goes
A LambdaConf 2015 talk.
John has no clue what the next great functional programming language will be like, but he's more than happy to hop up on stage and rant against type classes, nominative typing, data, modules, pattern matching, recursion, and, well, basically everything else you associate with functional programming! John will argue that to make radical progress in cheaply building correct software, we need to take one step backward and two steps forward, embracing dependent-typing, total functions, Turing-complete compilers, host languages, and automated proof search. Attend this talk to question your assumptions about functional programming... or just to heckle! Either way, all are welcome.
Slides for a lightning talk on Java 8 lambda expressions I gave at the Near Infinity (www.nearinfinity.com) 2013 spring conference.
The associated sample code is on GitHub at https://github.com/sleberknight/java8-lambda-samples
This presentation takes you on a functional programming journey, it starts from basic Scala programming language design concepts and leads to a concept of Monads, how some of them designed in Scala and what is the purpose of them
Slides of a talk I gave at work on Scala. It is geared toward Java developers. Some of the examples are in my company's domain, which is analyzing energy usage (i.e. a "read" is an electric meter read).
After a recap of implicits I introduce the type class mechanics in Scala. Then I have a look at ways for good non-intrusive type class design. The main focus of this presentation are type classes in Scala. In the last chapter I show the Haskell implementation of my example.
download for better quality - Learn about the sequence and traverse functions through the work of Runar Bjarnason and Paul Chiusano, authors of Functional Programming in Scala https://www.manning.com/books/functional-programming-in-scala, and Sam Halliday, author of "Functional Programming for Mortals with Scalaz" https://leanpub.com/fpmortals
Error handling is critical for reactive systems, as expressed by the "resilient" trait. This talk examines strengths and weaknesses of existing approaches. I also consider preventing errors in the first place.
Reactive design: languages, and paradigmsDean Wampler
A talk first given at React 2014 and refined for YOW! LambdaJam 2014 that explores the meaning of Reactive Programming, as described in the Reactive Manifesto, and how well it is supported by general design paradigms, like Functional Programming, Object-Oriented Programming, and Domain Driven Design, and by particular design approaches, such as Functional Reactive Programming, Reactive Extensions, Actors, etc.
This talk discusses Spark (http://spark.apache.org), the Big Data computation system that is emerging as a replacement for MapReduce in Hadoop systems, while it also runs outside of Hadoop. I discuss why the issues why MapReduce needs to be replaced and how Spark addresses them with better performance and a more powerful API.
While Hadoop is the dominant "Big Data" tool suite today, it's a first-generation technology. I discuss its strengths and weaknesses, then look at how we "should" be doing Big Data and currently-available alternative tools.
The Art of the Pitch: WordPress Relationships and SalesLaura Byrne
Clients don’t know what they don’t know. What web solutions are right for them? How does WordPress come into the picture? How do you make sure you understand scope and timeline? What do you do if sometime changes?
All these questions and more will be explored as we talk about matching clients’ needs with what your agency offers without pulling teeth or pulling your hair out. Practical tips, and strategies for successful relationship building that leads to closing the deal.
Welcome to the first live UiPath Community Day Dubai! Join us for this unique occasion to meet our local and global UiPath Community and leaders. You will get a full view of the MEA region's automation landscape and the AI Powered automation technology capabilities of UiPath. Also, hosted by our local partners Marc Ellis, you will enjoy a half-day packed with industry insights and automation peers networking.
📕 Curious on our agenda? Wait no more!
10:00 Welcome note - UiPath Community in Dubai
Lovely Sinha, UiPath Community Chapter Leader, UiPath MVPx3, Hyper-automation Consultant, First Abu Dhabi Bank
10:20 A UiPath cross-region MEA overview
Ashraf El Zarka, VP and Managing Director MEA, UiPath
10:35: Customer Success Journey
Deepthi Deepak, Head of Intelligent Automation CoE, First Abu Dhabi Bank
11:15 The UiPath approach to GenAI with our three principles: improve accuracy, supercharge productivity, and automate more
Boris Krumrey, Global VP, Automation Innovation, UiPath
12:15 To discover how Marc Ellis leverages tech-driven solutions in recruitment and managed services.
Brendan Lingam, Director of Sales and Business Development, Marc Ellis
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionAggregage
Join Maher Hanafi, VP of Engineering at Betterworks, in this new session where he'll share a practical framework to transform Gen AI prototypes into impactful products! He'll delve into the complexities of data collection and management, model selection and optimization, and ensuring security, scalability, and responsible use.
A tale of scale & speed: How the US Navy is enabling software delivery from l...sonjaschweigert1
Rapid and secure feature delivery is a goal across every application team and every branch of the DoD. The Navy’s DevSecOps platform, Party Barge, has achieved:
- Reduction in onboarding time from 5 weeks to 1 day
- Improved developer experience and productivity through actionable findings and reduction of false positives
- Maintenance of superior security standards and inherent policy enforcement with Authorization to Operate (ATO)
Development teams can ship efficiently and ensure applications are cyber ready for Navy Authorizing Officials (AOs). In this webinar, Sigma Defense and Anchore will give attendees a look behind the scenes and demo secure pipeline automation and security artifacts that speed up application ATO and time to production.
We will cover:
- How to remove silos in DevSecOps
- How to build efficient development pipeline roles and component templates
- How to deliver security artifacts that matter for ATO’s (SBOMs, vulnerability reports, and policy evidence)
- How to streamline operations with automated policy checks on container images
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofsAlex Pruden
This paper presents Reef, a system for generating publicly verifiable succinct non-interactive zero-knowledge proofs that a committed document matches or does not match a regular expression. We describe applications such as proving the strength of passwords, the provenance of email despite redactions, the validity of oblivious DNS queries, and the existence of mutations in DNA. Reef supports the Perl Compatible Regular Expression syntax, including wildcards, alternation, ranges, capture groups, Kleene star, negations, and lookarounds. Reef introduces a new type of automata, Skipping Alternating Finite Automata (SAFA), that skips irrelevant parts of a document when producing proofs without undermining soundness, and instantiates SAFA with a lookup argument. Our experimental evaluation confirms that Reef can generate proofs for documents with 32M characters; the proofs are small and cheap to verify (under a second).
Paper: https://eprint.iacr.org/2023/1886
Climate Impact of Software Testing at Nordic Testing DaysKari Kakkonen
My slides at Nordic Testing Days 6.6.2024
Climate impact / sustainability of software testing discussed on the talk. ICT and testing must carry their part of global responsibility to help with the climat warming. We can minimize the carbon footprint but we can also have a carbon handprint, a positive impact on the climate. Quality characteristics can be added with sustainability, and then measured continuously. Test environments can be used less, and in smaller scale and on demand. Test techniques can be used in optimizing or minimizing number of tests. Test automation can be used to speed up testing.
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™UiPathCommunity
In questo evento online gratuito, organizzato dalla Community Italiana di UiPath, potrai esplorare le nuove funzionalità di Autopilot, il tool che integra l'Intelligenza Artificiale nei processi di sviluppo e utilizzo delle Automazioni.
📕 Vedremo insieme alcuni esempi dell'utilizzo di Autopilot in diversi tool della Suite UiPath:
Autopilot per Studio Web
Autopilot per Studio
Autopilot per Apps
Clipboard AI
GenAI applicata alla Document Understanding
👨🏫👨💻 Speakers:
Stefano Negro, UiPath MVPx3, RPA Tech Lead @ BSP Consultant
Flavio Martinelli, UiPath MVP 2023, Technical Account Manager @UiPath
Andrei Tasca, RPA Solutions Team Lead @NTT Data
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...UiPathCommunity
💥 Speed, accuracy, and scaling – discover the superpowers of GenAI in action with UiPath Document Understanding and Communications Mining™:
See how to accelerate model training and optimize model performance with active learning
Learn about the latest enhancements to out-of-the-box document processing – with little to no training required
Get an exclusive demo of the new family of UiPath LLMs – GenAI models specialized for processing different types of documents and messages
This is a hands-on session specifically designed for automation developers and AI enthusiasts seeking to enhance their knowledge in leveraging the latest intelligent document processing capabilities offered by UiPath.
Speakers:
👨🏫 Andras Palfi, Senior Product Manager, UiPath
👩🏫 Lenka Dulovicova, Product Program Manager, UiPath
Elevating Tactical DDD Patterns Through Object CalisthenicsDorra BARTAGUIZ
After immersing yourself in the blue book and its red counterpart, attending DDD-focused conferences, and applying tactical patterns, you're left with a crucial question: How do I ensure my design is effective? Tactical patterns within Domain-Driven Design (DDD) serve as guiding principles for creating clear and manageable domain models. However, achieving success with these patterns requires additional guidance. Interestingly, we've observed that a set of constraints initially designed for training purposes remarkably aligns with effective pattern implementation, offering a more ‘mechanical’ approach. Let's explore together how Object Calisthenics can elevate the design of your tactical DDD patterns, offering concrete help for those venturing into DDD for the first time!
In his public lecture, Christian Timmerer provides insights into the fascinating history of video streaming, starting from its humble beginnings before YouTube to the groundbreaking technologies that now dominate platforms like Netflix and ORF ON. Timmerer also presents provocative contributions of his own that have significantly influenced the industry. He concludes by looking at future challenges and invites the audience to join in a discussion.
Epistemic Interaction - tuning interfaces to provide information for AI supportAlan Dix
Paper presented at SYNERGY workshop at AVI 2024, Genoa, Italy. 3rd June 2024
https://alandix.com/academic/papers/synergy2024-epistemic/
As machine learning integrates deeper into human-computer interactions, the concept of epistemic interaction emerges, aiming to refine these interactions to enhance system adaptability. This approach encourages minor, intentional adjustments in user behaviour to enrich the data available for system learning. This paper introduces epistemic interaction within the context of human-system communication, illustrating how deliberate interaction design can improve system understanding and adaptation. Through concrete examples, we demonstrate the potential of epistemic interaction to significantly advance human-computer interaction by leveraging intuitive human communication strategies to inform system design and functionality, offering a novel pathway for enriching user-system engagements.
The Metaverse and AI: how can decision-makers harness the Metaverse for their...Jen Stirrup
The Metaverse is popularized in science fiction, and now it is becoming closer to being a part of our daily lives through the use of social media and shopping companies. How can businesses survive in a world where Artificial Intelligence is becoming the present as well as the future of technology, and how does the Metaverse fit into business strategy when futurist ideas are developing into reality at accelerated rates? How do we do this when our data isn't up to scratch? How can we move towards success with our data so we are set up for the Metaverse when it arrives?
How can you help your company evolve, adapt, and succeed using Artificial Intelligence and the Metaverse to stay ahead of the competition? What are the potential issues, complications, and benefits that these technologies could bring to us and our organizations? In this session, Jen Stirrup will explain how to start thinking about these technologies as an organisation.
17. class Logger(val level:Level) {
def apply(message: String) = {
// pass to Log4J...
Log4J.log(level, message)
}
}
class body is the
“primary” constructor
15
18. makes “level” a field
class Logger(val level:Level) {
def apply(message: String) = {
// pass to Log4J...
Log4J.log(level, message)
}
}
class body is the
“primary” constructor
15
19. makes “level” a field
class Logger(val level:Level) {
def apply(message: String) = {
// pass to Log4J...
Log4J.log(level, message)
} method
}
class body is the
“primary” constructor
15
34. “cons” empty list
val list =
1 :: 2 :: 3 :: 4 :: 5 :: Nil
23
35. “cons” empty list
val list =
1 :: 2 :: 3 :: 4 :: 5 :: Nil
head
23
36. “cons” empty list
val list =
1 :: 2 :: 3 :: 4 :: 5 :: Nil
head tail
23
37. Baked into the
Grammar?
val list =
1 :: 2 :: 3 :: 4 :: 5 :: Nil
24
38. Baked into the
Grammar?
val list =
1 :: 2 :: 3 :: 4 :: 5 :: Nil
No, just method calls!
val list = Nil.::(5).::(4).::(
3).::(2).::(1)
24
39. val list =
1 :: 2 :: 3 :: 4 :: 5 :: Nil
val list = Nil.::(5).::(4).::(
3).::(2).::(1)
25
40. val list =
1 :: 2 :: 3 :: 4 :: 5 :: Nil
val list = Nil.::(5).::(4).::(
3).::(2).::(1)
Method names can contain almost any
character.
25
41. val list =
1 :: 2 :: 3 :: 4 :: 5 :: Nil
val list = Nil.::(5).::(4).::(
3).::(2).::(1)
Any method ending in “:” binds to the right!
26
42. val list =
1 :: 2 :: 3 :: 4 :: 5 :: Nil
val list = Nil.::(5).::(4).::(
3).::(2).::(1)
If a method takes one argument, you can drop
the “.” and the parentheses, “(“ and “)”.
27
52. map called on list
(dropping the “.”)
list map {
s => s.toUpperCase
}
33
53. map called on list
(dropping the “.”) argument to map
(using “{“ vs. “(“)
list map {
s => s.toUpperCase
}
33
54. map called on list
(dropping the “.”) argument to map
(using “{“ vs. “(“)
list map {
s => s.toUpperCase
}
“function literal”
33
55. map called on list
(dropping the “.”) argument to map
(using “{“ vs. “(“)
list map {
s => s.toUpperCase
}
“function literal”
function
argument list
33
56. map called on list
(dropping the “.”) argument to map
(using “{“ vs. “(“)
list map {
s => s.toUpperCase
}
“function literal”
function function body
argument list
33
61. How the Sausage Is Made
class List[A] {
…
def map[B](f: A => B): List[B]
…
}
36
62. How the Sausage Is Made
Parameterized type
class List[A] {
…
def map[B](f: A => B): List[B]
…
}
36
63. How the Sausage Is Made
Parameterized type
class List[A] {
Declaration of map
…
def map[B](f: A => B): List[B]
…
} The function map’s return type
argument
36
64. How the Sausage Is Made
trait Function1[-A,+R] {
def apply(a:A): R
…
}
37
65. How the Sausage Is Made
like an “abstract” class
trait Function1[-A,+R] {
def apply(a:A): R
…
}
37
66. How the Sausage Is Made
like an “abstract” class
trait Function1[-A,+R] {
def apply(a:A): R
…
} No method body:
=> abstract
37
67. How the Sausage Is Made
“contravariant”,
like an “abstract” class
“covariant” typing
trait Function1[-A,+R] {
def apply(a:A): R
…
} No method body:
=> abstract
37
68. What the Compiler Does
(s:String) => s.toUpperCase
new Function1[String,String] {
def apply(s:String) = {
s.toUpperCase
}
}
38
69. What the Compiler Does
(s:String) => s.toUpperCase
What you write.
new Function1[String,String] {
def apply(s:String) = {
s.toUpperCase
} What the compiler
} generates
An anonymous class
38
70. What the Compiler Does
(s:String) => s.toUpperCase
What you write.
new Function1[String,String] {
def apply(s:String) = {
s.toUpperCase
} What the compiler
} generates
No “return”
needed An anonymous class
38
71. Recap
val list = "a" :: "b" :: Nil
list map {
s => s.toUpperCase
}
// => "A" :: "B" :: Nil
39
72. Recap
val list = "a" :: "b" :: Nil
list map {
s => s.toUpperCase
} Function “object”
// => "A" :: "B" :: Nil
39
73. Recap
val list = "a" :: "b" :: Nil
list map { {…} ok, instead of (…)
s => s.toUpperCase
} Function “object”
// => "A" :: "B" :: Nil
39
75. Avoiding Nulls
sealed abstract class Option[+T]
{…}
case class Some[+T](value: T)
extends Option[T] {…}
case object None
extends Option[Nothing] {…}
41
76. Avoiding Nulls
sealed abstract class Option[+T]
{…}
case class Some[+T](value: T)
extends Option[T] {…}
case object None
extends Option[Nothing] {…}
41
An Algebraic Data Type
77. // Java style (schematic)
class Map[K, V] {
def get(key: K): V = {
return value || null;
}}
42
78. // Java style (schematic)
class Map[K, V] {
def get(key: K): V = {
return value || null;
}}
42
79. // Java style (schematic)
class Map[K, V] {
def get(key: K): V = {
return value || null;
}}
// Scala style
class Map[K, V] {
def get(key: K): Option[V] = {
return Some(value) || None;
}}
Which is the better API?
42
80. In Use:
val m =
Map("one" -> 1, "two" -> 2)
…
val n = m.get("four") match {
case Some(i) => i
case None => 0 // default
}
43
81. In Use:
val m = Literal syntax for map creation
Map("one" -> 1, "two" -> 2)
…
val n = m.get("four") match {
case Some(i) => i
case None => 0 // default
}
Use pattern matching to extract the value (or not)
43
85. Case Classes
case class Some[+T](value: T)
●Provides factory method, pattern
matching, equals, toString, etc.
●Makes “value” a field without val
keyword.
45
89. Nothing
case object None
extends Option[Nothing] {…}
Special child type of all other
types. Used for this special
case where no actual
instances required.
47
101. User-defined Factory
Methods
val words =
List("Scala", "is", "fun!")
no new needed.
Can return a subtype!
53
102. class Person {
private String firstName;
private String lastName;
private int age;
public Person(String firstName, String lastName, int age){
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public void String getFirstName() {return this.firstName;}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void String getLastName() {return this.lastName;}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void int getAge() {return this.age;}
public void setAge(int age) {
this.age = age;
}
} 54
103. class Person {
private String firstName;
private String lastName;
private int age;
public Person(String firstName, String lastName, int age){
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public void String getFirstName() {return this.firstName;}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void String getLastName() {return this.lastName;}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void int getAge() {return this.age;}
public void setAge(int age) {
this.age = age;
} Typical Java
} 54
104. class Person(
var firstName: String,
var lastName: String,
var age: Int)
55
105. class Person(
var firstName: String,
var lastName: String,
var age: Int)
Typical Scala!
55
106. class Person(
var firstName: String,
var lastName: String,
var age: Int)
56
107. Class body is the
“primary” constructor
Parameter list for c’tor
class Person(
var firstName: String,
var lastName: String,
var age: Int)
No class body {…}.
Makes the arg a field nothing else needed!
with accessors
56
119. Traits
… or like
abstract classes +
multiple inheritance
(if you prefer).
63
120. Logger as a Mixin:
trait Logger {
val level: Level // abstract
def log(message: String) = {
Log4J.log(level, message)
}
}
64
121. Logger as a Mixin:
trait Logger {
val level: Level // abstract
def log(message: String) = {
Log4J.log(level, message)
}
} Traits don’t have
constructors, but
you can still
define fields.
64
122. Logger as a Mixin:
trait Logger {
val level: Level // abstract
…
}
65
123. Logger as a Mixin:
trait Logger {
val level: Level // abstract
…
}
val server =
new Server(…) with Logger {
val level = ERROR
}
server.log("Internet down!!")
65
124. Logger as a Mixin:
trait Logger {
val level: Level // abstract
…
} mixed in Logging
val server =
new Server(…) with Logger {
val level = ERROR
}
server.log("Internet down!!")
65
125. Logger as a Mixin:
trait Logger {
val level: Level // abstract
…
} mixed in Logging
val server =
new Server(…) with Logger {
val level = ERROR abstract
} member defined
server.log("Internet down!!")
65
137. Use the “Akka”
package shapes Actor library
import akka.actor._
class ShapeDrawingActor
extends Actor {
def receive = {
…
}
}
Actor for drawing shapes
73
138. Use the “Akka”
package shapes Actor library
import akka.actor._
class ShapeDrawingActor Actor
extends Actor {
def receive = {
receive and handle
…
each message
}
}
Actor for drawing shapes
73
139. Receive
receive = { method
case s:Shape =>
print("-> "); s.draw()
self.reply("Shape drawn.")
case "exit" =>
println("-> exiting...")
self.reply("good bye!")
case x => // default
println("-> Error: " + x)
self.reply("Unknown: " + x)
}
Actor for drawing shapes
74
140. receive = {
case s:Shape =>
print("-> "); s.draw()
self.reply("Shape drawn.")
case "exit" =>
println("-> exiting...")
self.reply("good bye!")
case x => // default
println("-> Error: " + x)
self.reply("Unknown: " + x)
}
Actor for drawing shapes
75
141. receive = {
case s:Shape =>
print("-> "); s.draw()
self.reply("Shape drawn.") pattern
case "exit" => matching
println("-> exiting...")
self.reply("good bye!")
case x => // default
println("-> Error: " + x)
self.reply("Unknown: " + x)
}
Actor for drawing shapes
75
142. receive = {
case s:Shape =>
print("-> "); s.draw()
self.reply("Shape drawn.") pattern
case "exit" => matching
println("-> exiting...")
self.reply("good bye!")
case x => // default
println("-> Error: " + x)
self.reply("Unknown: " + x)
}
Actor for drawing shapes
75
143. receive = {
case s:Shape =>
print("-> "); s.draw()
self.reply("Shape drawn.") pattern
case "exit" => matching
println("-> exiting...")
self.reply("good bye!")
case x => // default
println("-> Error: " + x)
self.reply("Unknown: " + x)
}
Actor for drawing shapes
75
144. receive = {
case s:Shape =>
print("-> "); s.draw()
self.reply("Shape drawn.")
case "exit" =>
println("-> exiting...")
self.reply("good bye!")
case x => // default
println("-> Error: " + x)
self.reply("Unknown: " + x)
}
76
145. receive = { draw shape
case s:Shape => & send reply
print("-> "); s.draw()
self.reply("Shape drawn.")
case "exit" =>
println("-> exiting...")
self.reply("good bye!")
case x => // default
println("-> Error: " + x)
self.reply("Unknown: " + x)
}
76
146. receive = {
case s:Shape =>
print("-> "); s.draw()
self.reply("Shape drawn.")
case "exit" =>
println("-> exiting...")
done
self.reply("good bye!")
case x => // default
println("-> Error: " + x)
self.reply("Unknown: " + x)
}
76
147. receive = {
case s:Shape =>
print("-> "); s.draw()
self.reply("Shape drawn.")
case "exit" =>
println("-> exiting...")
self.reply("good bye!")
case x => // default
println("-> Error: " + x)
self.reply("Unknown: " + x)
}
unrecognized message
76
148. receive = {
case s:Shape =>
print("-> "); s.draw()
self.reply("Shape drawn.")
case "exit" =>
println("-> exiting...")
self.reply("good bye!")
case x => // default
println("-> Error: " + x)
self.reply("Unknown: " + x)
}
76
149. package shapes
import akka.actor._
class ShapeDrawingActor extends Actor {
receive = {
case s:Shape =>
print("-> "); s.draw()
self.reply("Shape drawn.")
case "exit" =>
println("-> exiting...")
self.reply("good bye!")
case x => // default
println("-> Error: " + x)
self.reply("Unknown: " + x)
}
}
77
150. package shapes
import akka.actor._
class ShapeDrawingActor extends Actor {
receive = {
case s:Shape =>
print("-> "); s.draw()
self.reply("Shape drawn.")
case "exit" =>
println("-> exiting...")
self.reply("good bye!")
case x => // default
println("-> Error: " + x)
self.reply("Unknown: " + x)
}
}
Altogether
77
152. import shapes._
import akka.actor._
import akka.actor.Actor
a “singleton” type to hold main
object Driver {
def main(args:Array[String])={
val driver = actorOf[Driver]
driver.start
driver ! "go!"
}
}
class Driver … driver to try it out
78
153. import shapes._
import akka.actor._
import akka.actor.Actor
a “singleton” type to hold main
object Driver {
def main(args:Array[String])={
val driver = actorOf[Driver]
driver.start
driver ! "go!"
}
}
class Driver … driver to try it out
78
154. import shapes._
import akka.actor._
import akka.actor.Actor
a “singleton” type to hold main
object Driver {
def main(args:Array[String])={
val driver = actorOf[Driver]
driver.start
driver ! "go!" ! is the message
} send “operator”
}
class Driver … driver to try it out
78
155. …
class Driver extends Actor {
val drawer =
actorOf[ShapeDrawingActor]
drawer.start
def receive = {
…
}
}
driver to try it out
79
156. Its “companion” object Driver
… was on the previous slide.
class Driver extends Actor {
val drawer =
actorOf[ShapeDrawingActor]
drawer.start
def receive = {
…
}
}
driver to try it out
79
157. def receive = {
case "go!" =>
drawer ! Circle(Point(…),…)
drawer ! Rectangle(…)
drawer ! 3.14159
drawer ! "exit"
case "good bye!" =>
println("<- cleaning up…")
drawer.stop; self.stop
case other =>
println("<- " + other)
} driver to try it out
80
158. def receive = {
case "go!" => sent by main
drawer ! Circle(Point(…),…)
drawer ! Rectangle(…)
drawer ! 3.14159
drawer ! "exit"
case "good bye!" =>
println("<- cleaning up…")
drawer.stop; self.stop
case other =>
println("<- " + other)
} driver to try it out
80
159. def receive = {
case "go!" => sent by main
drawer ! Circle(Point(…),…)
drawer ! Rectangle(…)
drawer ! 3.14159
drawer ! "exit" sent by
case "good bye!" => drawer
println("<- cleaning up…")
drawer.stop; self.stop
case other =>
println("<- " + other)
} driver to try it out
80
160. case "go!" =>
drawer ! Circle(Point(…),…)
drawer ! Rectangle(…)
drawer ! 3.14159
drawer ! "exit"
// run Driver.main (see github README.md)
-> drawing: Circle(Point(0.0,0.0),1.0)
-> drawing: Rectangle(Point(0.0,0.0),
2.0,5.0)
-> Error: 3.14159
-> exiting... “<-” and “->” messages
<- Shape drawn. may be interleaved!!
<- Shape drawn.
<- Unknown: 3.14159
<- cleaning up...
81
179. Log put
trait QueueLogging[T]
extends Queue[T] {
abstract override def put(
t: T) = {
println("put("+t+")")
super.put(t)
}
}
What is “super” bound to??
93
180. class StandardQueue[T]
extends Queue[T] {
import ...ArrayBuffer
private val ab =
new ArrayBuffer[T]
def put(t: T) = ab += t
def get() = ab.remove(0)
…
}
94
181. class StandardQueue[T]
extends Queue[T] {
import ...ArrayBuffer
private val ab =
new ArrayBuffer[T]
def put(t: T) = ab += t
def get() = ab.remove(0)
…
}
Concrete (boring) implementation
94
182. val sq = new StandardQueue[Int]
with QueueLogging[Int]
sq.put(10) // #1
println(sq.get()) // #2
// => put(10) (on #1)
// => 10 (on #2)
95
183. val sq = new StandardQueue[Int]
with QueueLogging[Int]
sq.put(10) // #1
println(sq.get()) // #2
// => put(10) (on #1)
// => 10 (on #2)
Example use
95
184. val sq = new StandardQueue[Int]
with QueueLogging[Int]
sq.put(10) // #1
println(sq.get()) // #2
// => put(10) (on #1)
// => 10 (on #2)
96
185. Mixin composition;
no class required
val sq = new StandardQueue[Int]
with QueueLogging[Int]
sq.put(10) // #1
println(sq.get()) // #2
// => put(10) (on #1)
// => 10 (on #2)
Example use
96
186. Like Aspect-Oriented
Programming?
Traits give us advice,
but not a join point
“query” language.
97
187. Traits are a powerful
composition
mechanism!
98
207. For “Comprehensions”
val l = List(
Some("a"), None, Some("b"),
None, Some("c"))
for (Some(s) <- l) yield s
// List(a, b, c)
110
208. For “Comprehensions”
val l = List(
Some("a"), None, Some("b"),
None, Some("c"))
for (Some(s) <- l) yield s
// List(a, b, c)
Pattern match; only
take elements of “l”
No “if ” statement that are Somes.
110
Editor's Notes
Available now from oreilly.com, Amazon, etc.
I picked Scala to learn in 2007 because I wanted to learn a functional language. Scala appealed because it runs on the JVM and interoperates with Java. In the end, I was seduced by its power and flexibility.
First reason, we need the benefits of FP.
Java&#x2019;s object model (and to a lesser extent, C#&#x2018;s) has significant limitations.
We think of objects as mutable and methods as state-modifying, while FP emphasizes immutability, which reduces bugs and often simplifies code. Objects don&#x2019;t have to be mutable!
We rarely have the luxury of starting from scratch...
Odersky is the creator of Scala. He&#x2019;s a prof. at EPFL in Switzerland. Many others have contributed to it, mostly his grad. students.
GJ had generics, but they were disabled in javac until v1.5.
Not all objects are functions, but they can be...
A simple wrapper around your favorite logging library (e.g., Log4J).
Note how variables are declared, &#x201C;name: Type&#x201D;.
Note how variables are declared, &#x201C;name: Type&#x201D;.
Note how variables are declared, &#x201C;name: Type&#x201D;.
Note how variables are declared, &#x201C;name: Type&#x201D;.
Note how variables are declared, &#x201C;name: Type&#x201D;.
Note how variables are declared, &#x201C;name: Type&#x201D;.
After creating an instance of Logger, in this case for Error logging, we can &#x201C;pretend&#x201D; the object is a function!
After creating an instance of Logger, in this case for Error logging, we can &#x201C;pretend&#x201D; the object is a function!
Adding a parameterized arg. list after an object causes the compiler to invoke the object&#x2019;s &#x201C;apply&#x201D; method.
Adding a parameterized arg. list after an object causes the compiler to invoke the object&#x2019;s &#x201C;apply&#x201D; method.
Adding a parameterized arg. list after an object causes the compiler to invoke the object&#x2019;s &#x201C;apply&#x201D; method.
This is how any object can be a function, if it has an apply method. Note that the signature of the argument list must match the arguments specified. Remember, this is a statically-typed language!
While an object can be a function, every &#x201C;bare&#x201D; function is actually an object, both because this is part of the &#x201C;theme&#x201D; of scala&#x2019;s unification of OOP and FP, but practically, because the JVM requires everything to be an object!
There isn&#x2019;t an object-primitive divide, at the source level, in Scala, but it optimizes to primitives to avoid boxing, where it can.
We build up a literal list with the &#x201C;::&#x201D; cons operator to prepend elements, starting with an empty list, the Nil &#x201C;object&#x201D;. &#x201C;::&#x201D; binds to the right, so the second form shown is equivalent to the first.
Note the &#x201C;infix operator notation&#x201D;; x.m(y) ==> x m y
We build up a literal list with the &#x201C;::&#x201D; cons operator to prepend elements, starting with an empty list, the Nil &#x201C;object&#x201D;. &#x201C;::&#x201D; binds to the right, so the second form shown is equivalent to the first.
Note the &#x201C;infix operator notation&#x201D;; x.m(y) ==> x m y
We build up a literal list with the &#x201C;::&#x201D; cons operator to prepend elements, starting with an empty list, the Nil &#x201C;object&#x201D;. &#x201C;::&#x201D; binds to the right, so the second form shown is equivalent to the first.
Note the &#x201C;infix operator notation&#x201D;; x.m(y) ==> x m y
We build up a literal list with the &#x201C;::&#x201D; cons operator to prepend elements, starting with an empty list, the Nil &#x201C;object&#x201D;. &#x201C;::&#x201D; binds to the right, so the second form shown is equivalent to the first.
Note the &#x201C;infix operator notation&#x201D;; x.m(y) ==> x m y
We build up a literal list with the &#x201C;::&#x201D; cons operator to prepend elements, starting with an empty list, the Nil &#x201C;object&#x201D;. &#x201C;::&#x201D; binds to the right, so the second form shown is equivalent to the first.
Note the &#x201C;infix operator notation&#x201D;; x.m(y) ==> x m y
We build up a literal list with the &#x201C;::&#x201D; cons operator to prepend elements, starting with an empty list, the Nil &#x201C;object&#x201D;. &#x201C;::&#x201D; binds to the right, so the second form shown is equivalent to the first.
Note the &#x201C;infix operator notation&#x201D;; x.m(y) ==> x m y
We build up a literal list with the &#x201C;::&#x201D; cons operator to prepend elements, starting with an empty list, the Nil &#x201C;object&#x201D;. &#x201C;::&#x201D; binds to the right, so the second form shown is equivalent to the first.
Note the &#x201C;infix operator notation&#x201D;; x.m(y) ==> x m y
Note the &#x201C;infix operator notation&#x201D;; x.m(y) ==> x m y. It&#x2019;s not just a special case backed into the language grammar (like Java&#x2019;s special case for string addition). Rather, it&#x2019;s a general feature of the language you can use for your classes.
Note the &#x201C;infix operator notation&#x201D;; x.m(y) ==> x m y. It&#x2019;s not just a special case backed into the language grammar (like Java&#x2019;s special case for string addition). Rather, it&#x2019;s a general feature of the language you can use for your classes.
Maps also have a literal syntax, which should look familiar to you Ruby programmers ;) Is this a special case in the language grammar?
Scala provides mechanisms to define convenient &#x201C;operators&#x201D; as methods, without special exceptions baked into the grammer (e.g., strings and &#x201C;+&#x201D; in Java).
Scala provides mechanisms to define convenient &#x201C;operators&#x201D; as methods, without special exceptions baked into the grammer (e.g., strings and &#x201C;+&#x201D; in Java).
Scala provides mechanisms to define convenient &#x201C;operators&#x201D; as methods, without special exceptions baked into the grammer (e.g., strings and &#x201C;+&#x201D; in Java).
Scala provides mechanisms to define convenient &#x201C;operators&#x201D; as methods, without special exceptions baked into the grammer (e.g., strings and &#x201C;+&#x201D; in Java).
We won&#x2019;t discuss implicit conversions here, due to time....
Collections like List and Map have a set of common operations that can be used on them.
Let&#x2019;s map a list of strings with lower-case letters to a corresponding list of uppercase strings.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
Note that the function literal is just the &#x201C;s => s.toUpperCase&#x201D;. The {&#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
We&#x2019;ve used type inference, but here&#x2019;s how we could be more explicit about the argument list to the function literal.
We&#x2019;ve used type inference, but here&#x2019;s how we could be more explicit about the argument list to the function literal.
We&#x2019;ve used type inference, but here&#x2019;s how we could be more explicit about the argument list to the function literal.
Here&#x2019;s the declaration of List&#x2019;s map method (lots of details omitted&#x2026;). Scala uses [...] for parameterized types, so you can use &#x201C;<&#x201C; and &#x201C;>&#x201D; for method names!
Here&#x2019;s the declaration of List&#x2019;s map method (lots of details omitted&#x2026;). Scala uses [...] for parameterized types, so you can use &#x201C;<&#x201C; and &#x201C;>&#x201D; for method names!
Here&#x2019;s the declaration of List&#x2019;s map method (lots of details omitted&#x2026;). Scala uses [...] for parameterized types, so you can use &#x201C;<&#x201C; and &#x201C;>&#x201D; for method names!
Here&#x2019;s the declaration of List&#x2019;s map method (lots of details omitted&#x2026;). Scala uses [...] for parameterized types, so you can use &#x201C;<&#x201C; and &#x201C;>&#x201D; for method names!
Here&#x2019;s the declaration of List&#x2019;s map method (lots of details omitted&#x2026;). Scala uses [...] for parameterized types, so you can use &#x201C;<&#x201C; and &#x201C;>&#x201D; for method names!
We look at the actual implementation of Function1 (or any FunctionN). Note that the scaladocs have links to the actual source listings.
(We&#x2019;re omitting some details&#x2026;) The trait declares an abstract method &#x201C;apply&#x201D; (i.e., it doesn&#x2019;t also define the method.)
Traits are a special kind of abstract class/interface definition, that promote &#x201C;mixin composition&#x201D;. (We won&#x2019;t have time to discuss&#x2026;)
We look at the actual implementation of Function1 (or any FunctionN). Note that the scaladocs have links to the actual source listings.
(We&#x2019;re omitting some details&#x2026;) The trait declares an abstract method &#x201C;apply&#x201D; (i.e., it doesn&#x2019;t also define the method.)
Traits are a special kind of abstract class/interface definition, that promote &#x201C;mixin composition&#x201D;. (We won&#x2019;t have time to discuss&#x2026;)
We look at the actual implementation of Function1 (or any FunctionN). Note that the scaladocs have links to the actual source listings.
(We&#x2019;re omitting some details&#x2026;) The trait declares an abstract method &#x201C;apply&#x201D; (i.e., it doesn&#x2019;t also define the method.)
Traits are a special kind of abstract class/interface definition, that promote &#x201C;mixin composition&#x201D;. (We won&#x2019;t have time to discuss&#x2026;)
You use the function literal syntax and the compiler instantiates an anonymous class using the corresponding FunctionN trait, with a concrete definition of apply provided by your function literal.
You use the function literal syntax and the compiler instantiates an anonymous class using the corresponding FunctionN trait, with a concrete definition of apply provided by your function literal.
You use the function literal syntax and the compiler instantiates an anonymous class using the corresponding FunctionN trait, with a concrete definition of apply provided by your function literal.
You use the function literal syntax and the compiler instantiates an anonymous class using the corresponding FunctionN trait, with a concrete definition of apply provided by your function literal.
You use the function literal syntax and the compiler instantiates an anonymous class using the corresponding FunctionN trait, with a concrete definition of apply provided by your function literal.
Back to where we started. Note again that we can use &#x201C;{&#x2026;}&#x201D; instead of &#x201C;(&#x2026;)&#x201D; for the argument list (i.e., the single function) to map. Why, to get a nice block-like syntax.
Back to where we started. Note again that we can use &#x201C;{&#x2026;}&#x201D; instead of &#x201C;(&#x2026;)&#x201D; for the argument list (i.e., the single function) to map. Why, to get a nice block-like syntax.
Back to where we started. Note again that we can use &#x201C;{&#x2026;}&#x201D; instead of &#x201C;(&#x2026;)&#x201D; for the argument list (i.e., the single function) to map. Why, to get a nice block-like syntax.
Our functions can have state! Not the usual thing for FP-style functions, where functions are usually side-effect free, but you have this option. Note that this is like a normal closure in FP.
Our functions can have state! Not the usual thing for FP-style functions, where functions are usually side-effect free, but you have this option. Note that this is like a normal closure in FP.
We&#x2019;ve seen a lot of syntax. Let&#x2019;s recap a few of the ways Scala keeps your code succinct.
Java (and to a lesser extent C#) require explicit type &#x201C;annotations&#x201D; on all references, method arguments, etc., leading to redundancy and noise.
Note that Scala use [] rather than <>, so you can use &#x201C;<&#x201C; and &#x201C;>&#x201D; as method names!
Java (and to a lesser extent C#) require explicit type &#x201C;annotations&#x201D; on all references, method arguments, etc., leading to redundancy and noise.
Note that Scala use [] rather than <>, so you can use &#x201C;<&#x201C; and &#x201C;>&#x201D; as method names!
Java (and to a lesser extent C#) require explicit type &#x201C;annotations&#x201D; on all references, method arguments, etc., leading to redundancy and noise.
Note that Scala use [] rather than <>, so you can use &#x201C;<&#x201C; and &#x201C;>&#x201D; as method names!
Java (and to a lesser extent C#) require explicit type &#x201C;annotations&#x201D; on all references, method arguments, etc., leading to redundancy and noise.
Note that Scala use [] rather than <>, so you can use &#x201C;<&#x201C; and &#x201C;>&#x201D; as method names!
Java (and to a lesser extent C#) require explicit type &#x201C;annotations&#x201D; on all references, method arguments, etc., leading to redundancy and noise.
Note that Scala use [] rather than <>, so you can use &#x201C;<&#x201C; and &#x201C;>&#x201D; as method names!
Other things aren&#x2019;t needed...
Other things aren&#x2019;t needed...
Factory methods on the cheap...
Factory methods on the cheap...
Typical Java boilerplate for a simple &#x201C;struct-like&#x201D; class.
Deliberately too small to read...
Scala is much more succinct. It eliminates a lot of boilerplate.
Scala is much more succinct. It eliminates a lot of boilerplate.
Scala is much more succinct. It eliminates a lot of boilerplate.
Scala is much more succinct. It eliminates a lot of boilerplate.
Scala is much more succinct. It eliminates a lot of boilerplate.
Scala is much more succinct. It eliminates a lot of boilerplate.
Scala is much more succinct. It eliminates a lot of boilerplate.
Scala is much more succinct. It eliminates a lot of boilerplate.
Scala is much more succinct. It eliminates a lot of boilerplate.
Note that Scala does not define an argument list for &#x201C;firstName&#x201D;, so you can call this method as if it were a bare field access. The client doesn&#x2019;t need to know the difference!
Note that Scala does not define an argument list for &#x201C;firstName&#x201D;, so you can call this method as if it were a bare field access. The client doesn&#x2019;t need to know the difference!
Case classes also get equals, hashCode, toString, and the &#x201C;factory&#x201D; method we&#x2019;ve mentioned (e.g., for List and Map) that, by default, creates an instance of the type without the &#x201C;new&#x201D;. We&#x2019;ll see more about case classes later.
Fixes limitations of Java&#x2019;s object model.
Made-up example Java type.
Made-up example Java type.
Made-up example Java type.
Chances are, the &#x201C;logging&#x201D; and &#x201C;filtering&#x201D; behaviors are reusable, yet Java provides no built-in way to &#x201C;mix-in&#x201D; reusable implementations. Ad hoc mechanisms must be used.
Chances are, the &#x201C;logging&#x201D; and &#x201C;filtering&#x201D; behaviors are reusable, yet Java provides no built-in way to &#x201C;mix-in&#x201D; reusable implementations. Ad hoc mechanisms must be used.
One way to compare traits to what you know...
&#x2026; and another way.
I changed some details compared to our original Logger example, e.g., no &#x201C;level&#x201D; field. Mix in Logger.
I changed some details compared to our original Logger example, e.g., no &#x201C;level&#x201D; field. Mix in Logger.
I changed some details compared to our original Logger example, e.g., no &#x201C;level&#x201D; field. Mix in Logger.
FP is going mainstream because it is the best way to write robust concurrent software. Here&#x2019;s an example...
It&#x2019;s very hard to do multithreaded programming robustly. We need higher levels of abstraction, like Actors.
It&#x2019;s very hard to do multithreaded programming robustly. We need higher levels of abstraction, like Actors.
The actor model is not new!!
Our example. An actor for drawing geometric shapes and another actor that drives it.
&#x201C;Case&#x201D; classes for 2-dim. points and a hierarchy of shapes. Note the abstract draw method in Shape. The &#x201C;case&#x201D; keyword makes the arguments &#x201C;vals&#x201D; by default, adds factory, equals, etc. methods. Great for &#x201C;structural&#x201D; objects.
(Case classes automatically get generated equals, hashCode, toString, so-called &#x201C;apply&#x201D; factory methods - so you don&#x2019;t need &#x201C;new&#x201D; - and so-called &#x201C;unapply&#x201D; methods used for pattern matching.)
&#x201C;Case&#x201D; classes for 2-dim. points and a hierarchy of shapes. Note the abstract draw method in Shape. The &#x201C;case&#x201D; keyword makes the arguments &#x201C;vals&#x201D; by default, adds factory, equals, etc. methods. Great for &#x201C;structural&#x201D; objects.
(Case classes automatically get generated equals, hashCode, toString, so-called &#x201C;apply&#x201D; factory methods - so you don&#x2019;t need &#x201C;new&#x201D; - and so-called &#x201C;unapply&#x201D; methods used for pattern matching.)
Case classes for 2-dim. points and a hierarchy of shapes. Note the abstract draw method in Shape.
For our example, the draw methods will just do &#x201C;println(this.toString)&#x201D;.
Case classes for 2-dim. points and a hierarchy of shapes. Note the abstract draw method in Shape.
For our example, the draw methods will just do &#x201C;println(this.toString)&#x201D;.
Case classes for 2-dim. points and a hierarchy of shapes. Note the abstract draw method in Shape.
For our example, the draw methods will just do &#x201C;println(this.toString)&#x201D;.
An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received...
Note: This example uses Scala&#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received...
Note: This example uses Scala&#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received...
Note: This example uses Scala&#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received...
Note: This example uses Scala&#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received...
Note: This example uses Scala&#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received...
Note: This example uses Scala&#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received...
Note: This example uses Scala&#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received...
Note: This example uses Scala&#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
&#x201C;Receive&#x201D; blocks until a message is received. Then it does a pattern match on the message. In this case, looking for a Shape object, the &#x201C;exit&#x201D; message, or an unexpected object, handled with the last case, the default.
Each pattern is tested and the first match &#x201C;wins&#x201D;. The messages we expect are a Shape object, the &#x201C;exit&#x201D; string or anything else. Hence, the last &#x201C;case&#x201D; is a &#x201C;default&#x201D; that catches anything, we we treat as an unexpected error.
Each pattern is tested and the first match &#x201C;wins&#x201D;. The messages we expect are a Shape object, the &#x201C;exit&#x201D; string or anything else. Hence, the last &#x201C;case&#x201D; is a &#x201C;default&#x201D; that catches anything, we we treat as an unexpected error.
Each pattern is tested and the first match &#x201C;wins&#x201D;. The messages we expect are a Shape object, the &#x201C;exit&#x201D; string or anything else. Hence, the last &#x201C;case&#x201D; is a &#x201C;default&#x201D; that catches anything, we we treat as an unexpected error.
Each pattern is tested and the first match &#x201C;wins&#x201D;. The messages we expect are a Shape object, the &#x201C;exit&#x201D; string or anything else. Hence, the last &#x201C;case&#x201D; is a &#x201C;default&#x201D; that catches anything, we we treat as an unexpected error.
Each pattern is tested and the first match &#x201C;wins&#x201D;. The messages we expect are a Shape object, the &#x201C;exit&#x201D; string or anything else. Hence, the last &#x201C;case&#x201D; is a &#x201C;default&#x201D; that catches anything, we we treat as an unexpected error.
Each pattern is tested and the first match &#x201C;wins&#x201D;. The messages we expect are a Shape object, the &#x201C;exit&#x201D; string or anything else. Hence, the last &#x201C;case&#x201D; is a &#x201C;default&#x201D; that catches anything, we we treat as an unexpected error.
Each pattern is tested and the first match &#x201C;wins&#x201D;. The messages we expect are a Shape object, the &#x201C;exit&#x201D; string or anything else. Hence, the last &#x201C;case&#x201D; is a &#x201C;default&#x201D; that catches anything, we we treat as an unexpected error.
After handling each message, a response is sent to the sender, which we get by calling the &#x201C;sender&#x201D; method. The &#x201C;!&#x201D; is the message send method (from Erlang).
After handling each message, a response is sent to the sender, which we get by calling the &#x201C;sender&#x201D; method. The &#x201C;!&#x201D; is the message send method (from Erlang).
After handling each message, a response is sent to the sender, which we get by calling the &#x201C;sender&#x201D; method. The &#x201C;!&#x201D; is the message send method (from Erlang).
After handling each message, a response is sent to the sender, which we get by calling the &#x201C;sender&#x201D; method. The &#x201C;!&#x201D; is the message send method (from Erlang).
After handling each message, a response is sent to the sender, which we get by calling the &#x201C;sender&#x201D; method. The &#x201C;!&#x201D; is the message send method (from Erlang).
After handling each message, a response is sent to the sender, which we get by calling the &#x201C;sender&#x201D; method. The &#x201C;!&#x201D; is the message send method (from Erlang).
After handling each message, a response is sent to the sender, which we get by calling the &#x201C;sender&#x201D; method. The &#x201C;!&#x201D; is the message send method (from Erlang).
The whole thing, with &#x201C;elided&#x201D; imports and other edits, so it would fit. It looks busy on a presentation slide, but isn&#x2019;t a lot of code in an editor!
Here&#x2019;s the driver actor, a scala script (precompilation not required) to drive the drawing actor.
Normally, you would not do such synchronous call and response coding, if avoidable, as it defeats the purpose of using actors for concurrency.
The &#x201C;!&#x201D; method sends a message. Then we wait for a reply. In our receive method, we match on any &#x201C;reply&#x201D; and just print it.
This script uses the method &#x201C;self&#x201D; to get the actor corresponding to &#x201C;me&#x201D;.
The &#x201C;!&#x201D; method sends a message. Then we wait for a reply. In our receive method, we match on any &#x201C;reply&#x201D; and just print it.
This script uses the method &#x201C;self&#x201D; to get the actor corresponding to &#x201C;me&#x201D;.
The &#x201C;!&#x201D; method sends a message. Then we wait for a reply. In our receive method, we match on any &#x201C;reply&#x201D; and just print it.
This script uses the method &#x201C;self&#x201D; to get the actor corresponding to &#x201C;me&#x201D;.
The &#x201C;!&#x201D; method sends a message. Then we wait for a reply. In our receive method, we match on any &#x201C;reply&#x201D; and just print it.
This script uses the method &#x201C;self&#x201D; to get the actor corresponding to &#x201C;me&#x201D;.
The &#x201C;!&#x201D; method sends a message. Then we wait for a reply. In our receive method, we match on any &#x201C;reply&#x201D; and just print it.
This script uses the method &#x201C;self&#x201D; to get the actor corresponding to &#x201C;me&#x201D;.
Start the drawing actor, then send it four messages. The blue shows what gets printed (after the &#x201C;// => &#x201C;).
1st message and response.
2nd message and response.
3rd message and response.
4th message and response.
The power of combining the best features of FP (pattern matching and &#x201C;destructuring&#x201D;) and OOP (polymorphic behavior).
The power of combining the best features of FP (pattern matching and &#x201C;destructuring&#x201D;) and OOP (polymorphic behavior).
The power of combining the best features of FP (pattern matching and &#x201C;destructuring&#x201D;) and OOP (polymorphic behavior).
The power of combining the best features of FP (pattern matching and &#x201C;destructuring&#x201D;) and OOP (polymorphic behavior).
A very simple abstraction for a Queue.
(We&#x2019;re ignoring &#x201C;get&#x201D;&#x2026;) &#x201C;Super&#x201D; is not yet bound, because the &#x201C;super.put(t)&#x201D; so far could only call the abstract method in Logging, which is not allowed. Therefore, &#x201C;super&#x201D; will be bound &#x201C;later&#x201D;, as we&#x2019;ll so. So, this method is STILL abstract and it&#x2019;s going to override a concrete &#x201C;put&#x201D; &#x201C;real soon now&#x201D;.
(We&#x2019;re ignoring &#x201C;get&#x201D;&#x2026;) &#x201C;Super&#x201D; is not yet bound, because the &#x201C;super.put(t)&#x201D; so far could only call the abstract method in Logging, which is not allowed. Therefore, &#x201C;super&#x201D; will be bound &#x201C;later&#x201D;, as we&#x2019;ll so. So, this method is STILL abstract and it&#x2019;s going to override a concrete &#x201C;put&#x201D; &#x201C;real soon now&#x201D;.
(We&#x2019;re ignoring &#x201C;get&#x201D;&#x2026;) &#x201C;Super&#x201D; is not yet bound, because the &#x201C;super.put(t)&#x201D; so far could only call the abstract method in Logging, which is not allowed. Therefore, &#x201C;super&#x201D; will be bound &#x201C;later&#x201D;, as we&#x2019;ll so. So, this method is STILL abstract and it&#x2019;s going to override a concrete &#x201C;put&#x201D; &#x201C;real soon now&#x201D;.
(We&#x2019;re ignoring &#x201C;get&#x201D;&#x2026;) &#x201C;Super&#x201D; is not yet bound, because the &#x201C;super.put(t)&#x201D; so far could only call the abstract method in Logging, which is not allowed. Therefore, &#x201C;super&#x201D; will be bound &#x201C;later&#x201D;, as we&#x2019;ll so. So, this method is STILL abstract and it&#x2019;s going to override a concrete &#x201C;put&#x201D; &#x201C;real soon now&#x201D;.
(We&#x2019;re ignoring &#x201C;get&#x201D;&#x2026;) &#x201C;Super&#x201D; is not yet bound, because the &#x201C;super.put(t)&#x201D; so far could only call the abstract method in Logging, which is not allowed. Therefore, &#x201C;super&#x201D; will be bound &#x201C;later&#x201D;, as we&#x2019;ll so. So, this method is STILL abstract and it&#x2019;s going to override a concrete &#x201C;put&#x201D; &#x201C;real soon now&#x201D;.
Our concrete class. We import scala.collection.mutable.ArrayBuffer wherever we want, in this case, right were it&#x2019;s used. This is boring; it&#x2019;s just a vehicle for the cool traits stuff...
We instantiate StandardQueue AND mixin the trait. We could also declare a class that mixes in the trait.
The &#x201C;put(10)&#x201D; output comes from QueueLogging.put. So &#x201C;super&#x201D; is StandardQueue.
We instantiate StandardQueue AND mixin the trait. We could also declare a class that mixes in the trait.
The &#x201C;put(10)&#x201D; output comes from QueueLogging.put. So &#x201C;super&#x201D; is StandardQueue.
We instantiate StandardQueue AND mixin the trait. We could also declare a class that mixes in the trait.
The &#x201C;put(10)&#x201D; output comes from QueueLogging.put. So &#x201C;super&#x201D; is StandardQueue.
We instantiate StandardQueue AND mixin the trait. We could also declare a class that mixes in the trait.
The &#x201C;put(10)&#x201D; output comes from QueueLogging.put. So &#x201C;super&#x201D; is StandardQueue.
We instantiate StandardQueue AND mixin the trait. We could also declare a class that mixes in the trait.
The &#x201C;put(10)&#x201D; output comes from QueueLogging.put. So &#x201C;super&#x201D; is StandardQueue.
We instantiate StandardQueue AND mixin the trait. We could also declare a class that mixes in the trait.
The &#x201C;put(10)&#x201D; output comes from QueueLogging.put. So &#x201C;super&#x201D; is StandardQueue.
If you know AspectJ or Spring AOP, traits make it easy to implement &#x201C;advice&#x201D;, but there is no join point language for querying over the set of all possible join points, like a real AOP framework provides.
If I put the &#x201C;(n, line) =>&#x201D; on the same line as the &#x201C;{&#x201C;, it would look like a Ruby block.
Here&#x2019;s the code that implements loop...
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
Singleton &#x201C;objects&#x201D; replace Java statics (or Ruby class methods and attributes). As written, &#x201C;loop&#x201D; takes two parameters, the file to &#x201C;numberate&#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&#x2019;s specify what to do through &#x201C;f&#x201D;.
The oval highlights the comma separating the two parameters in the list. Watch what we do on the next slide...
We convert the single, two parameter list to two, single parameter lists, which is valid syntax.
Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}.
Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}.
Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}.
Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}.
Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}.
Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}.
Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}.
Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
Finishing the implementation, loop creates a buffered reader, then calls a recursive, nested method "doLoop".
Finishing the implementation, loop creates a buffered reader, then calls a recursive, nested method "doLoop".
Finishing the implementation, loop creates a buffered reader, then calls a recursive, nested method "doLoop".
Here is the nested method, doLoop.
Here is the nested method, doLoop.
Here is the nested method, doLoop.
Here is the nested method, doLoop.
A tail recursion - the recursive call is the last thing done in the function (or branch).
&#x201C;Functional Programming&#x201D; is based on the behavior of mathematical functions and variables.
&#x201C;Functional Programming&#x201D; is based on the behavior of mathematical functions.
&#x201C;Variables&#x201D; are actually immutable values.
&#x201C;Functional Programming&#x201D; is based on the behavior of mathematical functions.
&#x201C;Variables&#x201D; are actually immutable values.
FP is breaking out of the academic world, because it offers a better way to approach concurrency, which is becoming ubiquitous.
FP is breaking out of the academic world, because it offers a better way to approach concurrency, which is becoming ubiquitous.
A math function doesn&#x2019;t change any &#x201C;object&#x201D; or global state. All the work it does is returned by the function. This property is called &#x201C;referential transparency&#x201D;.
A math function doesn&#x2019;t change any &#x201C;object&#x201D; or global state. All the work it does is returned by the function. This property is called &#x201C;referential transparency&#x201D;.
side-effect free functions are far less likely to introduce subtle integration bugs, especially in concurrent systems. By encouraging immutable objects (e.g., when methods return new objects, rather than modify existing ones), that improves concurrency robustness.
Function are &#x201C;first-class citizens&#x201D;; you can assign them to variables and pass them to other (higher-order) functions, giving you composable behavior.
Function are &#x201C;first-class citizens&#x201D;; you can assign them to variables and pass them to other (higher-order) functions, giving you composable behavior.
FP is going mainstream because it is the best way to write robust concurrent software. Here&#x2019;s an example...
I am omitting MANY details. You can&#x2019;t instantiate Option, which is an abstraction for a container/collection with 0 or 1 item. If you have one, it is in a Some, which must be a class, since it has an instance field, the item. However, None, used when there are 0 items, can be a singleton object, because it has no state! Note that type parameter for the parent Option. In the type system, Nothing is a subclass of all other types, so it substitutes for instances of all other types. This combined with a proper called covariant subtyping means that you could write &#x201C;val x: Option[String = None&#x201D; it would type correctly, as None (and Option[Nothing]) is a subtype of Option[String].
I am omitting MANY details. You can&#x2019;t instantiate Option, which is an abstraction for a container/collection with 0 or 1 item. If you have one, it is in a Some, which must be a class, since it has an instance field, the item. However, None, used when there are 0 items, can be a singleton object, because it has no state! Note that type parameter for the parent Option. In the type system, Nothing is a subclass of all other types, so it substitutes for instances of all other types. This combined with a proper called covariant subtyping means that you could write &#x201C;val x: Option[String = None&#x201D; it would type correctly, as None (and Option[Nothing]) is a subtype of Option[String].
Returning Option tells the user that &#x201C;there may not be a value&#x201D; and forces proper handling, thereby drastically reducing sloppy code leading to NullPointerExceptions.
Returning Option tells the user that &#x201C;there may not be a value&#x201D; and forces proper handling, thereby drastically reducing sloppy code leading to NullPointerExceptions.
Returning Option tells the user that &#x201C;there may not be a value&#x201D; and forces proper handling, thereby drastically reducing sloppy code leading to NullPointerExceptions.
We&#x2019;re using the type system and pattern matching built into case classes to discriminate elements in the list. No conditional statements required.
This is just the tip of the iceberg of what &#x201C;for comprehensions&#x201D; can do and not only with Options, but other containers, too.
We&#x2019;re using the type system and pattern matching built into case classes to discriminate elements in the list. No conditional statements required.
This is just the tip of the iceberg of what &#x201C;for comprehensions&#x201D; can do and not only with Options, but other containers, too.
We&#x2019;re using the type system and pattern matching built into case classes to discriminate elements in the list. No conditional statements required.
This is just the tip of the iceberg of what &#x201C;for comprehensions&#x201D; can do and not only with Options, but other containers, too.