Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Philip Schwarz
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Haskell, Scala and Java.
Inspired by the example in Scott Wlaschin’s F# book: Domain Modeling Made Functional.
Download for better results.
Java 19 Code: https://github.com/philipschwarz/fruit-salad-and-fruit-snack-ADT-example-java
The Functional Programming Triad of Map, Filter and FoldPhilip Schwarz
This slide deck is my homage to SICP, the book which first introduced me to the Functional Programming triad of map, filter and fold.
It was during my Computer Science degree that a fellow student gave me a copy of the first edition, not long after the book came out.
I have not yet come across a better introduction to these three functions.
The upcoming slides are closely based on the second edition of the book, a free online copy of which can be found here:
https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html.
Download for original image quality.
Errata:
slide 20: the Clojure map function is in fact the Scheme one repeated - see code below for correction.
Scheme code: https://github.com/philipschwarz/the-fp-triad-of-map-filter-and-fold-scheme
Clojure code: https://github.com/philipschwarz/the-fp-triad-of-map-filter-and-fold-clojure
Left and Right Folds- Comparison of a mathematical definition and a programm...Philip Schwarz
We compare typical definitions of the left and right fold functions, with their mathematical definitions in Sergei Winitzki’s upcoming book: The Science of Functional Programming.
Errata:
Slide 13: "The way 𝑓𝑜𝑙𝑑𝑙 does it is by associating to the right" - should, of course ,end in "to the left".
ZIO-Direct allows direct style programming with ZIO. This library provides a *syntactic sugar* that is more powerful than for-comprehensions as well as more natural to use. Simply add the `.run` suffix to any ZIO effect in order to retrieve it's value.
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Philip Schwarz
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Haskell, Scala and Java.
Inspired by the example in Scott Wlaschin’s F# book: Domain Modeling Made Functional.
Download for better results.
Java 19 Code: https://github.com/philipschwarz/fruit-salad-and-fruit-snack-ADT-example-java
The Functional Programming Triad of Map, Filter and FoldPhilip Schwarz
This slide deck is my homage to SICP, the book which first introduced me to the Functional Programming triad of map, filter and fold.
It was during my Computer Science degree that a fellow student gave me a copy of the first edition, not long after the book came out.
I have not yet come across a better introduction to these three functions.
The upcoming slides are closely based on the second edition of the book, a free online copy of which can be found here:
https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html.
Download for original image quality.
Errata:
slide 20: the Clojure map function is in fact the Scheme one repeated - see code below for correction.
Scheme code: https://github.com/philipschwarz/the-fp-triad-of-map-filter-and-fold-scheme
Clojure code: https://github.com/philipschwarz/the-fp-triad-of-map-filter-and-fold-clojure
Left and Right Folds- Comparison of a mathematical definition and a programm...Philip Schwarz
We compare typical definitions of the left and right fold functions, with their mathematical definitions in Sergei Winitzki’s upcoming book: The Science of Functional Programming.
Errata:
Slide 13: "The way 𝑓𝑜𝑙𝑑𝑙 does it is by associating to the right" - should, of course ,end in "to the left".
ZIO-Direct allows direct style programming with ZIO. This library provides a *syntactic sugar* that is more powerful than for-comprehensions as well as more natural to use. Simply add the `.run` suffix to any ZIO effect in order to retrieve it's value.
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Philip Schwarz
(download for perfect quality) - See how recursive functions and structural induction relate to recursive datatypes.
Follow along as the fold abstraction is introduced and explained.
Watch as folding is used to simplify the definition of recursive functions over recursive datatypes
Part 1 - through the work of Richard Bird and Graham Hutton.
This version corrects the following issues:
slide 7, 11 fib(0) is 0,rather than 1
slide 23: was supposed to be followed by 2-3 slides recapitulating definitions of factorial and fibonacci with and without foldr, plus translation to scala
slide 36: concat not invoked in concat example
slides 48 and 49: unwanted 'm' in definition of sum
throughout: a couple of typographical errors
throughout: several aesthetic imperfections (wrong font, wrong font colour)
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1Philip Schwarz
slides can look grainy and/or out of focus when seen on slideshare - download for flawless quality - Based on Scott Wlaschin’s great book 'Domain Modeling Made Functional' and on Martin Odersky's talk 'A Tour of Scala 3'.
Scala Intro training @ Lohika, Odessa, UA.
This is a basic Scala Programming Language overview intended to evangelize the language among any-language programmers.
Frameworks are bulky, quirky, and non-compositional, which has led to a rejection of Spring and similar frameworks in the Scala ecosystem. Yet, despite their drawbacks, frameworks have been used to boost team productivity in many large companies. In this presentation, Pavel and Kai will introduce Izumi 1.0, a Scala microframework based on compositional functional programming. Designed to help you and your team achieve new levels of productivity, Izumi now includes full compile-time checks for your configurable applications and completely reworked Tagless Final hierarchy for Bifunctors and Trifunctors.
Functional Domain Modeling - The ZIO 2 WayDebasish Ghosh
Principled way to design and implement functional domain models using some of the patterns of domain driven design. DDD, as the name suggests, is focused towards the domain model and the patterns of architecture that it encourages are also based on how we think of interactions amongst the basic abstractions of the domain. Of course the primary goal of the talk is to discuss how Scala and Zio 2 can be a potent combination in realizing the implementation of such models. This is not a talk on FP, the focus will be on how to structure and modularise an application based on some of the patterns of DDD.
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...Philip Schwarz
First see the problem solved using the List monad and a Scala for comprehension.
Then see the Scala program translated into Haskell, both using a do expressions and using a List comprehension.
Understand how the Scala for comprehension is desugared, and what role the withFilter function plays.
Also understand how the Haskell do expressions and List comprehension are desugared, and what role the guard function plays.
Scala code for Part 1: https://github.com/philipschwarz/n-queens-combinatorial-problem-scala-part-1
Errata: on slide 30, the resulting lists should be Haskell ones rather than Scala ones.
Nat, List and Option Monoids -from scratch -Combining and Folding -an examplePhilip Schwarz
Nat, List and Option Monoids, from scratch. Combining and Folding: an example.
Code: https://github.com/philipschwarz/nat-list-and-option-monoids-from-scratch-combining-and-folding-an-example
Http4s, Doobie and Circe: The Functional Web StackGaryCoady
Http4s, Doobie and Circe together form a nice platform for building web services. This presentations provides an introduction to using them to build your own service.
For decades, the Functor, Monoid, and Foldable type class hierarchies have dominated functional programming. Implemented in libraries like Scalaz and Cats, these type classes have an ancient origin in Haskell, and they have repeatedly proven useful for advanced functional programmers, who use them to maximize code reuse and increase code correctness.
Yet, as these type classes have been copied into Scala and aged, there is a growing awareness of their drawbacks, ranging from being difficult to teach to weird operators that don’t make sense in Scala (ap from Applicative), to overlapping and lawless type classes (Semigroupal), to a complete inability to abstract over data types that possess related structure (such as isomorphic applicatives).
In this presentation, John A. De Goes introduces a new Scala library with a completely different factoring of functional type classes—one which throws literally everything away and starts from a clean slate. In this new factoring, type classes leverage Scala’s strengths, including variance and modularity. Pieces fit together cleanly and uniformly, and in a way that satisfies existing use cases, but enables new ones never before possible. Finally, type classes are named, organized, and described in a way that makes teaching them easier, without compromising on algebraic principles.
If you’ve ever thought functional type classes were too impractical or too confusing or too restrictive, now’s your chance to get a fresh perspective on a library that just might make understanding functional programming easier than ever before!
‘go-to’ general-purpose sequential collections -from Java To ScalaPhilip Schwarz
The simple idea of this slide deck is that it collects in a single place quite a bit of information that can be used to gain a basic understanding of some key differences between the ’goto’ sequential collections of Java and Scala.
Errata:
* the twitter handle of Daniel Westheide is @kaffeecoder and not @cafeecoder
* on slide 35, the numbers 215, 220, 225 and 230, should be 2^15, 2^20, 2^25 and 2^30 respectively
* on slide 54, the bottom left node should be green rather than black
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
ZIO: Powerful and Principled Functional Programming in ScalaWiem Zine Elabidine
This is an introduction of purely functional programming type safe abstractions that provide a variety of features for building asynchronous and concurrent applications data structures built on ZIO.
You'll learn by examples about the power of functional programming to solve the hard problems of software development in a principled, without compromises.
Free Monads are a powerful technique that can separate the representation of programs from the messy details of how they get run.
I'll go into the details of how they work, how to use them for fun and profit in your own code, and demonstrate a live Free Monad-driven tank game.
Supporting code at https://github.com/kenbot/free
At the heart of data processing, event-sourcing, actors, and much more is the queue—a data structure that allows producers to pass work to consumers in a flexible way. On the JVM, most libraries, including Akka, are powered by Java concurrent queues, which are reliable but were designed in a different era, for synchronous (blocking) procedural code. In this presentation, John A. De Goes—architect of the Scalaz 8 effect system—introduces IOQueue, a new type of queue powered by the Scalaz 8 IO monad. IOQueue never blocks and provides seamless, composable back-pressure across an entire application, without users having to think about the problem or write any special code. John will discuss how IOQueue achieves these remarkable properties, and show how the structure can be used to solve hard problems with just a few lines of type-safe, leak-free, composable Scala code. Come learn about the power of Scalaz to solve the hard problems of software development, in a principled way, without compromises.
ECMAScript is the name of the international standard that defines JavaScript. ES6 → ECMAScript 2015. Latest ECMAScript version is ES7 which is ECMAScript 2016.
Basically it is a superset of es5
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Philip Schwarz
(download for perfect quality) - See how recursive functions and structural induction relate to recursive datatypes.
Follow along as the fold abstraction is introduced and explained.
Watch as folding is used to simplify the definition of recursive functions over recursive datatypes
Part 1 - through the work of Richard Bird and Graham Hutton.
This version corrects the following issues:
slide 7, 11 fib(0) is 0,rather than 1
slide 23: was supposed to be followed by 2-3 slides recapitulating definitions of factorial and fibonacci with and without foldr, plus translation to scala
slide 36: concat not invoked in concat example
slides 48 and 49: unwanted 'm' in definition of sum
throughout: a couple of typographical errors
throughout: several aesthetic imperfections (wrong font, wrong font colour)
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1Philip Schwarz
slides can look grainy and/or out of focus when seen on slideshare - download for flawless quality - Based on Scott Wlaschin’s great book 'Domain Modeling Made Functional' and on Martin Odersky's talk 'A Tour of Scala 3'.
Scala Intro training @ Lohika, Odessa, UA.
This is a basic Scala Programming Language overview intended to evangelize the language among any-language programmers.
Frameworks are bulky, quirky, and non-compositional, which has led to a rejection of Spring and similar frameworks in the Scala ecosystem. Yet, despite their drawbacks, frameworks have been used to boost team productivity in many large companies. In this presentation, Pavel and Kai will introduce Izumi 1.0, a Scala microframework based on compositional functional programming. Designed to help you and your team achieve new levels of productivity, Izumi now includes full compile-time checks for your configurable applications and completely reworked Tagless Final hierarchy for Bifunctors and Trifunctors.
Functional Domain Modeling - The ZIO 2 WayDebasish Ghosh
Principled way to design and implement functional domain models using some of the patterns of domain driven design. DDD, as the name suggests, is focused towards the domain model and the patterns of architecture that it encourages are also based on how we think of interactions amongst the basic abstractions of the domain. Of course the primary goal of the talk is to discuss how Scala and Zio 2 can be a potent combination in realizing the implementation of such models. This is not a talk on FP, the focus will be on how to structure and modularise an application based on some of the patterns of DDD.
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...Philip Schwarz
First see the problem solved using the List monad and a Scala for comprehension.
Then see the Scala program translated into Haskell, both using a do expressions and using a List comprehension.
Understand how the Scala for comprehension is desugared, and what role the withFilter function plays.
Also understand how the Haskell do expressions and List comprehension are desugared, and what role the guard function plays.
Scala code for Part 1: https://github.com/philipschwarz/n-queens-combinatorial-problem-scala-part-1
Errata: on slide 30, the resulting lists should be Haskell ones rather than Scala ones.
Nat, List and Option Monoids -from scratch -Combining and Folding -an examplePhilip Schwarz
Nat, List and Option Monoids, from scratch. Combining and Folding: an example.
Code: https://github.com/philipschwarz/nat-list-and-option-monoids-from-scratch-combining-and-folding-an-example
Http4s, Doobie and Circe: The Functional Web StackGaryCoady
Http4s, Doobie and Circe together form a nice platform for building web services. This presentations provides an introduction to using them to build your own service.
For decades, the Functor, Monoid, and Foldable type class hierarchies have dominated functional programming. Implemented in libraries like Scalaz and Cats, these type classes have an ancient origin in Haskell, and they have repeatedly proven useful for advanced functional programmers, who use them to maximize code reuse and increase code correctness.
Yet, as these type classes have been copied into Scala and aged, there is a growing awareness of their drawbacks, ranging from being difficult to teach to weird operators that don’t make sense in Scala (ap from Applicative), to overlapping and lawless type classes (Semigroupal), to a complete inability to abstract over data types that possess related structure (such as isomorphic applicatives).
In this presentation, John A. De Goes introduces a new Scala library with a completely different factoring of functional type classes—one which throws literally everything away and starts from a clean slate. In this new factoring, type classes leverage Scala’s strengths, including variance and modularity. Pieces fit together cleanly and uniformly, and in a way that satisfies existing use cases, but enables new ones never before possible. Finally, type classes are named, organized, and described in a way that makes teaching them easier, without compromising on algebraic principles.
If you’ve ever thought functional type classes were too impractical or too confusing or too restrictive, now’s your chance to get a fresh perspective on a library that just might make understanding functional programming easier than ever before!
‘go-to’ general-purpose sequential collections -from Java To ScalaPhilip Schwarz
The simple idea of this slide deck is that it collects in a single place quite a bit of information that can be used to gain a basic understanding of some key differences between the ’goto’ sequential collections of Java and Scala.
Errata:
* the twitter handle of Daniel Westheide is @kaffeecoder and not @cafeecoder
* on slide 35, the numbers 215, 220, 225 and 230, should be 2^15, 2^20, 2^25 and 2^30 respectively
* on slide 54, the bottom left node should be green rather than black
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
ZIO: Powerful and Principled Functional Programming in ScalaWiem Zine Elabidine
This is an introduction of purely functional programming type safe abstractions that provide a variety of features for building asynchronous and concurrent applications data structures built on ZIO.
You'll learn by examples about the power of functional programming to solve the hard problems of software development in a principled, without compromises.
Free Monads are a powerful technique that can separate the representation of programs from the messy details of how they get run.
I'll go into the details of how they work, how to use them for fun and profit in your own code, and demonstrate a live Free Monad-driven tank game.
Supporting code at https://github.com/kenbot/free
At the heart of data processing, event-sourcing, actors, and much more is the queue—a data structure that allows producers to pass work to consumers in a flexible way. On the JVM, most libraries, including Akka, are powered by Java concurrent queues, which are reliable but were designed in a different era, for synchronous (blocking) procedural code. In this presentation, John A. De Goes—architect of the Scalaz 8 effect system—introduces IOQueue, a new type of queue powered by the Scalaz 8 IO monad. IOQueue never blocks and provides seamless, composable back-pressure across an entire application, without users having to think about the problem or write any special code. John will discuss how IOQueue achieves these remarkable properties, and show how the structure can be used to solve hard problems with just a few lines of type-safe, leak-free, composable Scala code. Come learn about the power of Scalaz to solve the hard problems of software development, in a principled way, without compromises.
ECMAScript is the name of the international standard that defines JavaScript. ES6 → ECMAScript 2015. Latest ECMAScript version is ES7 which is ECMAScript 2016.
Basically it is a superset of es5
Recently a new breed of "multi-model" databases has emerged. They are a document store, a graph database and a key/value store combined in one program. Therefore they are able to cover a lot of use cases which otherwise would need multiple different database systems.
This approach promises a boost to the idea of "polyglot persistence", which has become very popular in recent years although it creates some friction in the form of data conversion and synchronisation between different systems. This is, because with a multi-model database one can enjoy the benefits of polyglot persistence without the disadvantages.
In this talk I will explain the motivation behind the multi-model approach, discuss its advantages and limitations, and will then risk to make some predictions about the NoSQL database market in five years time, which I shall only reveal during the talk.
Data-Oriented Programming in Java. Data-Oriented Programming (DOP) focuses on decreasing the complexity of the Object-Oriented Programming (OOP) application systems by rethinking data, i.e., separating data and code. DOP divides the system into two core components (Data entities and Code Module), where you can think about each separately.
Data-Oriented Programming in Java. Data-Oriented Programming (DOP) focuses on decreasing the complexity of the Object-Oriented Programming (OOP) application systems by rethinking data, i.e., separating data and code. DOP divides the system into two core components (Data entities and Code Module), where you can think about each separately.
However, before moving to Data Oriented Programming in OOP languages like Java, it is essential to understand how OOP increases the complexity of creating a system.
So in this blog, we will cover OOP and its complexity, data-oriented programming, how we can separate code from data in Java, and ways to represent immutable data in Java and data with records.
Domain Driven Design is a software development process that focuses on finding a common language for the involved parties. This language and the resulting models are taken from the domain rather than the technical details of the implementation. The goal is to improve the communication between customers, developers and all other involved groups. Even if Eric Evan's book about this topic was written almost ten years ago, this topic remains important because a lot of projects fail for communication reasons.
Relational databases have their own language and influence the design of software into a direction further away from the Domain: Entities have to be created for the sole purpose of adhering to best practices of relational database. Two kinds of NoSQL databases are changing that: Document stores and graph databases. In a document store you can model a "contains" relation in a more natural way and thereby express if this entity can exist outside of its surrounding entity. A graph database allows you to model relationships between entities in a straight forward way that can be expressed in the language of the domain.
In this talk I want to look at the way a multi model database that combines a document store and a graph database can help you to model your problems in a way that is understandable for all parties involved, and explain the benefits of this approach for the software development process.
Functional programming in scala courseraKetan Raval
Functional programming in scala coursera
https://bit.ly/37xWOFf
-------------------------------------------------------------
Program on a Higher Level. Write elegant functional code to analyze data that's big or small
Although animals do not use language, they are capable of many of the same kinds of cognition as us; much of our experience is at a non-verbal level.
Semantics is the bridge between surface forms used in language and what we do and experience.
Language understanding depends on world knowledge (i.e. “the pig is in the pen” vs. “the ink is in the pen”)
We might not be ready for executives to specify policies themselves, but we can make the process from specification to behavior more automated, linked to precise vocabulary, and more traceable.
Advances such as SVBR and an English serialization for ISO Common Logic means that executives and line workers can understand why the system does certain things, or verify that policies and regulations are implemented
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidPhilip Schwarz
The subject of this deck is the small Print[A] program in the following blog post by Noel Welsh: https://www.inner-product.com/posts/direct-style-effects/.
Keywords: "direct-style", "context function", "context functions", "algebraic effect", "algebraic effects", "scala", "effect system", "effect systems", "effect", "side effect", "composition", "fp", "functional programming"
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
For functions that can be defined both as an instance of a right fold and as an instance of a left fold, one may be more efficient than the other.
Let's look at the example of a function 'decimal' that converts a list of digits into the corresponding decimal number.
Erratum: it has been pointed out that it is possible to define the zip function using a right fold (see slide 5).
Tagless Final Encoding - Algebras and Interpreters and also ProgramsPhilip Schwarz
Tagless Final Encoding - Algebras and Interpreters and also Programs - An introduction, through the work of Gabriel Volpe.
Slide deck home: http://fpilluminated.com/assets/tagless-final-encoding-algebras-interpreters-and-programs.html
A sighting of traverseFilter and foldMap in Practical FP in ScalaPhilip Schwarz
Slide deck home: http://fpilluminated.com/assets/sighting-of-scala-cats-traverseFilter-and-foldMap-in-practical-fp-in-scala.html.
Download PDF for perfect image quality.
A sighting of sequence function in Practical FP in ScalaPhilip Schwarz
Slide deck home: http://fpilluminated.com/assets/sighting-of-scala-cats-sequence-function-in-practical-fp-in-scala.html.
Download PDF for perfect image quality.
This talk was presented on Aug 3rd 2023 during the Scala in the City event a ITV in London https://www.meetup.com/scala-in-the-city/events/292844968/
Visit the following for a description, slideshow, all slides with transcript, pdf, github repo, and eventually a video recording: http://fpilluminated.com/assets/n-queens-combinatorial-puzzle-meets-cats.html
At the centre of this talk is the N-Queens combinatorial puzzle. The reason why this puzzle features in the Scala book and functional programming course by Martin Odersky (the language’s creator), is that such puzzles are a particularly suitable application area of 'for comprehensions'.
We’ll start by (re)acquainting ourselves with the puzzle, and seeing the role played in it by permutations. Next, we’ll see how, when wanting to visualise candidate puzzle solutions, Cats’ monoidal functions fold and foldMap are a great fit for combining images.
While we are all very familiar with the triad providing the bread, butter and jam of functional programming, i.e. map, filter and fold, not everyone knows about the corresponding functions in Cats’ monadic variant of the triad, i.e. mapM, filterM and foldM, which we are going to learn about next.
As is often the case in functional programming, the traverse function makes an appearance, and we shall grab the opportunity to point out the symmetry that exists in the interrelation of flatMap / foldMap / traverse and flatten / fold / sequence.
Armed with an understanding of foldM, we then look at how such a function can be used to implement an iterative algorithm for the N-Queens puzzle.
The talk ends by pointing out that the iterative algorithm is smarter than the recursive one, because it ‘remembers’ where it has already placed previous queens.
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...Philip Schwarz
Kleisli composition, flatMap, join, map, unit. A study/memory aid, to help learn/recall their implementation/interrelation.
Version 2, updated for Scala 3
Nat, List and Option Monoids -from scratch -Combining and Folding -an examplePhilip Schwarz
Nat, List and Option Monoids, from scratch. Combining and Folding: an example.
This is a new version of the original which has some cosmetic changes and a new 7th slide which only differs from slide 6 in that it defines the fold function in terms of the foldRight function.
Code: https://github.com/philipschwarz/nat-list-and-option-monoids-from-scratch-combining-and-folding-an-example
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...Philip Schwarz
When I posted the deck for Part 1 to the Scala users forum, Odd Möller linked to a paper titled "The Genuine Sieve of Eratosthenes", which speaks of the Unfaithful Sieve.
Part 2 is based on that paper and on Richard Bird's faithful Haskell implementation of the Sieve, which we translate into Scala.
Scala code for Richard Bird's infinite primes Haskell program: https://github.com/philipschwarz/sieve-of-eratosthenes-part-2-scala
Jordan Peterson - The pursuit of meaning and related ethical axiomsPhilip Schwarz
I have only recently become aware of the work of Jordan Peterson. Because I am finding it so interesting, I hope that the following small collection of excerpts from some of his writings and speeches might entice any fellow latecomers to find out more about his work. See below for my own summary of some of the subjects touched upon in these slides.
Download for best results.
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...Philip Schwarz
Defining filter using
(a) recursion
(b) folding
(c) folding with S, B and I combinators
(d) folding with applicative functor and identity function.pdf
This second version adds a simpler folding definition, which I had left out in the first version.
The Sieve of Eratosthenes - Part 1 - with minor correctionsPhilip Schwarz
In this slide deck we are going to see some examples of how the effort required to read an understand the Sieve of Eratosthenes varies greatly depending on the programming paradigm used to implement the algorithm.
We'll see code in Java, Scheme, Haskell and Scala.
This version of the deck contains some minor corrections (see errata section in first version for details)
Advanced Flow Concepts Every Developer Should KnowPeter Caitens
Tim Combridge from Sensible Giraffe and Salesforce Ben presents some important tips that all developers should know when dealing with Flows in Salesforce.
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...Juraj Vysvader
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I didn't get rich from it but it did have 63K downloads (powered possible tens of thousands of websites).
Check out the webinar slides to learn more about how XfilesPro transforms Salesforce document management by leveraging its world-class applications. For more details, please connect with sales@xfilespro.com
If you want to watch the on-demand webinar, please click here: https://www.xfilespro.com/webinars/salesforce-document-management-2-0-smarter-faster-better/
Accelerate Enterprise Software Engineering with PlatformlessWSO2
Key takeaways:
Challenges of building platforms and the benefits of platformless.
Key principles of platformless, including API-first, cloud-native middleware, platform engineering, and developer experience.
How Choreo enables the platformless experience.
How key concepts like application architecture, domain-driven design, zero trust, and cell-based architecture are inherently a part of Choreo.
Demo of an end-to-end app built and deployed on Choreo.
Modern design is crucial in today's digital environment, and this is especially true for SharePoint intranets. The design of these digital hubs is critical to user engagement and productivity enhancement. They are the cornerstone of internal collaboration and interaction within enterprises.
Your Digital Assistant.
Making complex approach simple. Straightforward process saves time. No more waiting to connect with people that matter to you. Safety first is not a cliché - Securely protect information in cloud storage to prevent any third party from accessing data.
Would you rather make your visitors feel burdened by making them wait? Or choose VizMan for a stress-free experience? VizMan is an automated visitor management system that works for any industries not limited to factories, societies, government institutes, and warehouses. A new age contactless way of logging information of visitors, employees, packages, and vehicles. VizMan is a digital logbook so it deters unnecessary use of paper or space since there is no requirement of bundles of registers that is left to collect dust in a corner of a room. Visitor’s essential details, helps in scheduling meetings for visitors and employees, and assists in supervising the attendance of the employees. With VizMan, visitors don’t need to wait for hours in long queues. VizMan handles visitors with the value they deserve because we know time is important to you.
Feasible Features
One Subscription, Four Modules – Admin, Employee, Receptionist, and Gatekeeper ensures confidentiality and prevents data from being manipulated
User Friendly – can be easily used on Android, iOS, and Web Interface
Multiple Accessibility – Log in through any device from any place at any time
One app for all industries – a Visitor Management System that works for any organisation.
Stress-free Sign-up
Visitor is registered and checked-in by the Receptionist
Host gets a notification, where they opt to Approve the meeting
Host notifies the Receptionist of the end of the meeting
Visitor is checked-out by the Receptionist
Host enters notes and remarks of the meeting
Customizable Components
Scheduling Meetings – Host can invite visitors for meetings and also approve, reject and reschedule meetings
Single/Bulk invites – Invitations can be sent individually to a visitor or collectively to many visitors
VIP Visitors – Additional security of data for VIP visitors to avoid misuse of information
Courier Management – Keeps a check on deliveries like commodities being delivered in and out of establishments
Alerts & Notifications – Get notified on SMS, email, and application
Parking Management – Manage availability of parking space
Individual log-in – Every user has their own log-in id
Visitor/Meeting Analytics – Evaluate notes and remarks of the meeting stored in the system
Visitor Management System is a secure and user friendly database manager that records, filters, tracks the visitors to your organization.
"Secure Your Premises with VizMan (VMS) – Get It Now"
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?XfilesPro
Worried about document security while sharing them in Salesforce? Fret no more! Here are the top-notch security standards XfilesPro upholds to ensure strong security for your Salesforce documents while sharing with internal or external people.
To learn more, read the blog: https://www.xfilespro.com/how-does-xfilespro-make-document-sharing-secure-and-seamless-in-salesforce/
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar
The European Union Agency for Law Enforcement Cooperation (Europol) has suffered an alleged data breach after a notorious threat actor claimed to have exfiltrated data from its systems. Infamous data leaker IntelBroker posted on the even more infamous BreachForums hacking forum, saying that Europol suffered a data breach this month.
The alleged breach affected Europol agencies CCSE, EC3, Europol Platform for Experts, Law Enforcement Forum, and SIRIUS. Infiltration of these entities can disrupt ongoing investigations and compromise sensitive intelligence shared among international law enforcement agencies.
However, this is neither the first nor the last activity of IntekBroker. We have compiled for you what happened in the last few days. To track such hacker activities on dark web sources like hacker forums, private Telegram channels, and other hidden platforms where cyber threats often originate, you can check SOCRadar’s Dark Web News.
Stay Informed on Threat Actors’ Activity on the Dark Web with SOCRadar!
First Steps with Globus Compute Multi-User EndpointsGlobus
In this presentation we will share our experiences around getting started with the Globus Compute multi-user endpoint. Working with the Pharmacology group at the University of Auckland, we have previously written an application using Globus Compute that can offload computationally expensive steps in the researcher's workflows, which they wish to manage from their familiar Windows environments, onto the NeSI (New Zealand eScience Infrastructure) cluster. Some of the challenges we have encountered were that each researcher had to set up and manage their own single-user globus compute endpoint and that the workloads had varying resource requirements (CPUs, memory and wall time) between different runs. We hope that the multi-user endpoint will help to address these challenges and share an update on our progress here.
Code reviews are vital for ensuring good code quality. They serve as one of our last lines of defense against bugs and subpar code reaching production.
Yet, they often turn into annoying tasks riddled with frustration, hostility, unclear feedback and lack of standards. How can we improve this crucial process?
In this session we will cover:
- The Art of Effective Code Reviews
- Streamlining the Review Process
- Elevating Reviews with Automated Tools
By the end of this presentation, you'll have the knowledge on how to organize and improve your code review proces
Cyaniclab : Software Development Agency Portfolio.pdfCyanic lab
CyanicLab, an offshore custom software development company based in Sweden,India, Finland, is your go-to partner for startup development and innovative web design solutions. Our expert team specializes in crafting cutting-edge software tailored to meet the unique needs of startups and established enterprises alike. From conceptualization to execution, we offer comprehensive services including web and mobile app development, UI/UX design, and ongoing software maintenance. Ready to elevate your business? Contact CyanicLab today and let us propel your vision to success with our top-notch IT solutions.
A Comprehensive Look at Generative AI in Retail App Testing.pdfkalichargn70th171
Traditional software testing methods are being challenged in retail, where customer expectations and technological advancements continually shape the landscape. Enter generative AI—a transformative subset of artificial intelligence technologies poised to revolutionize software testing.
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...informapgpstrackings
Keep tabs on your field staff effortlessly with Informap Technology Centre LLC. Real-time tracking, task assignment, and smart features for efficient management. Request a live demo today!
For more details, visit us : https://informapuae.com/field-staff-tracking/
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.
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Anthony Dahanne
Les Buildpacks existent depuis plus de 10 ans ! D’abord, ils étaient utilisés pour détecter et construire une application avant de la déployer sur certains PaaS. Ensuite, nous avons pu créer des images Docker (OCI) avec leur dernière génération, les Cloud Native Buildpacks (CNCF en incubation). Sont-ils une bonne alternative au Dockerfile ? Que sont les buildpacks Paketo ? Quelles communautés les soutiennent et comment ?
Venez le découvrir lors de cette session ignite
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.
Designing for Privacy in Amazon Web ServicesKrzysztofKkol1
Data privacy is one of the most critical issues that businesses face. This presentation shares insights on the principles and best practices for ensuring the resilience and security of your workload.
Drawing on a real-life project from the HR industry, the various challenges will be demonstrated: data protection, self-healing, business continuity, security, and transparency of data processing. This systematized approach allowed to create a secure AWS cloud infrastructure that not only met strict compliance rules but also exceeded the client's expectations.
Algebraic Data Types forData Oriented Programming - From Haskell and Scala to Java
1. Algebraic Data Types
for
Data Oriented Programming
From Haskell and Scala to Java
Data Oriented Programming in Java
https://www.infoq.com/articles/data-oriented-programming-java/
Inspired by and based on by Brian Goetz’s blog post
@BrianGoetz
Java Language Architect
2. @philip_schwarz
This slide deck was inspired by Brian Goetz’s great InfoQ blog post
Data Oriented Programming in Java.
I really liked the post and found it very useful. It is great to see Java
finally supporting Data Oriented Programming.
The first three slides of the deck consist of excerpts from the post.
https://www.infoq.com/articles/data-oriented-programming-java/
3. @BrianGoetz
Data-oriented programming
Java's strong static typing and class-based modeling can still be tremendously useful for smaller
programs, just in different ways. Where OOP encourages us to use classes to model business
entities and processes, smaller codebases with fewer internal boundaries will often get more
mileage out of using classes to model data. Our services consume requests that come from the
outside world, such as via HTTP requests with untyped JSON/XML/YAML payloads. But only the
most trivial of services would want to work directly with data in this form; we'd like to represent
numbers as int or long rather than as strings of digits, dates as classes like LocalDateTime, and lists
as collections rather than long comma-delimited strings. (And we want to validate that data at the
boundary, before we act on it.)
Data-oriented programming encourages us to model data as data. Records, sealed classes,
and pattern matching, work together to make that easier.
Data-oriented programming encourages us to model data as (immutable) data, and keep the code
that embodies the business logic of how we act on that data separately. As this trend towards
smaller programs has progressed, Java has acquired new tools to make it easier to model data as
data (records), to directly model alternatives (sealed classes), and to flexibly destructure
polymorphic data (pattern matching) patterns.
Programming with data as data doesn't mean giving up static typing. One could do data-oriented
programming with only untyped maps and lists (one often does in languages like Javascript), but
static typing still has a lot to offer in terms of safety, readability, and maintainability, even when we
are only modeling plain data. (Undisciplined data-oriented code is often called "stringly typed",
because it uses strings to model things that shouldn't be modeled as strings, such as numbers,
dates, and lists.)
4. The combination of records, sealed types, and pattern matching makes it easy to follow these principles,
yielding more concise, readable, and more reliable programs.
While programming with data as data may be a little unfamiliar given Java's OO underpinnings, these
techniques are well worth adding to our toolbox.
It's not either/or
Many of the ideas outlined here may look, at first, to be somewhat "un-Java-like", because most of us have been taught to start by modeling entities and
processes as objects. But in reality, our programs often work with relatively simple data, which often comes from the "outside world" where we can't count
on it fitting cleanly into the Java type system. …
When we're modeling complex entities, or writing rich libraries such as java.util.stream, OO techniques have a lot to offer us. But when we're building
simple services that process plain, ad-hoc data, the techniques of data-oriented programming may offer us a straighter path. Similarly, when exchanging
complex results across an API boundary (such as our match result example), it is often simpler and clearer to define an ad-hoc data schema using ADTs,
than to complect results and behavior in a stateful object (as the Java Matcher API does.)
The techniques of OOP and data-oriented programming are not at odds; they are different tools for different granularities and situations. We can freely
mix and match them as we see fit.
Algebraic data types
This combination of records and sealed types is an example of what are called algebraic data
types (ADTs). Records are a form of "product types", so-called because their state space is the cartesian
product of that of their components. Sealed classes are a form of "sum types", so-called because the set
of possible values is the sum (union) of the value sets of the alternatives. This simple combination of
mechanisms -- aggregation and choice -- is deceptively powerful, and shows up in many programming
languages.
@BrianGoetz
5. Data oriented programming in Java
Records, sealed classes, and pattern matching are designed to work together to support
data-oriented programming.
Records allow us to simply model data using classes; sealed classes let us model choices;
and pattern matching provides us with an easy and type-safe way of acting on polymorphic
data.
Support for pattern matching has come in several increments; the first added only type-test
patterns and only supported them in instanceof; the next supported type-test patterns
in switch as well; and most recently, deconstruction patterns for records were added in Java
19. The examples in this article will make use of all of these features.
While records are syntactically concise, their main strength is that they let us cleanly and
simply model aggregates.
Just as with all data modeling, there are creative decisions to make, and some modelings are
better than others.
Using the combination of records and sealed classes also makes it easier to make illegal
states unrepresentable, further improving safety and maintainability.
@BrianGoetz
6. Among Haskell, Scala and Java, Haskell was the first to include features
enabling Data Oriented programming. When Scala was born, it also supported
the paradigm. In Java, support for the paradigm is being retrofitted.
7. In the next three slides we look at how, since its inception, Scala
included features enabling Data Oriented programming: case classes,
sealed abstract classes (or sealed traits), and pattern matching.
8. Chapter 15 Case Classes and Pattern Matching
This chapter introduces case classes and pattern matching, twin constructs that support you when writing regular, non-
encapsulated data structures. These two constructs are particularly helpful for tree-like recursive data. If you have
programmed in a functional language before, then you will probably recognize pattern matching. Case classes will be
new to you, though. Case classes are Scala’s way to allow pattern matching on objects without requiring a large amount
of boilerplate. In the common case, all you need to do is add a single case keyword to each class that you want to be
pattern matchable. This chapter starts with a simple example of case classes and pattern matching. It then goes through
all of the kinds of patterns that are supported, talks about the role of sealed classes, discusses the Option type, and
shows some non-obvious places in the language where pattern matching is used. Finally, a larger, more realistic example
of pattern matching is shown.
15.1 A simple example
Before delving into all the rules and nuances of pattern matching, it is worth looking at a simple example to get the
general idea. Let’s say you need to write a library that manipulates arithmetic expressions, perhaps as part of a domain-
specific language you are designing. A first step to tackle this problem is the definition of the input data. To keep things
simple, we’ll concentrate on arithmetic expressions consisting of variables, numbers, and unary and binary operations.
This is expressed by the hierarchy of Scala classes shown in Listing 15.1.
The hierarchy includes an abstract base class Expr with four subclasses, one for each kind of expression being
considered. The bodies of all five classes are empty. As mentioned previously, in Scala you can leave out the braces
around an empty class body if you wish, so class C is the same as class C {}.
2007
Case classes
The other noteworthy thing
about the declarations of Listing
15.1 is that each subclass has a
case modifier. Classes with such
a modifier are called case
classes. Using the modifier
makes the Scala compiler add
some syntactic conveniences to
your class.
abstract class Expr
case class Var(name: String) extends Expr
case class Number(num: Double) extends Expr
case class UnOp(operator: String, arg: Expr) extends Expr
case class BinOp(operator: String, left: Expr, right: Expr) extends Expr
Listing 15.1 · Defining case classes.
9. 15.5 Sealed classes
Whenever you write a pattern match, you need to make sure you have covered all of the possible cases. Sometimes
you can do this by adding a default case at the end of the match, but that only applies if there is a sensible default
behavior. What do you do if there is no default? How can you ever feel safe that you covered all the cases?
In fact, you can enlist the help of the Scala compiler in detecting missing combinations of patterns in a match
expression. To be able to do this, the compiler needs to be able to tell which are the possible cases. In general, this is
impossible in Scala, because new case classes can be defined at any time and in arbitrary compilation units. For
instance, nothing would prevent you from adding a fifth case class to the Expr class hierarchy in a different
compilation unit from the one where the other four cases are defined.
The alternative is to make the superclass of your case classes sealed. A sealed class cannot have any new subclasses
added except the ones in the same file. This is very useful for pattern matching, because it means you only need to
worry about the subclasses you already know about. What’s more, you get better compiler support as well. If you
match against case classes that inherit from a sealed class, the compiler will flag missing combinations of patterns with
a warning message.
Therefore, if you write a hierarchy of classes intended to be pattern matched, you should consider sealing them. Simply
put the sealed keyword in front of the class at the top of the hierarchy. Programmers using your class hierarchy will
then feel confident in pattern matching against it. The sealed keyword, therefore, is often a license to pattern match.
Listing 15.16 shows an example in which Expr is turned into a sealed class.
sealed abstract class Expr
case class Var(name: String) extends Expr
case class Number(num: Double) extends Expr
case class UnOp(operator: String, arg: Expr) extends Expr
case class BinOp(operator: String, left: Expr, right: Expr) extends Expr
Listing 15.16 · A sealed hierarchy of case classes.
2007
10. Pattern matching
Say you want to simplify arithmetic expressions of the kinds just presented. There is a multitude of possible
simplification rules. The following three rules just serve as an illustration:
UnOp("-", UnOp("-", e)) => e // Double negation
BinOp("+", e, Number(0)) => e // Adding zero
BinOp("*", e, Number(1)) => e // Multiplying by one
Using pattern matching, these rules can be taken almost as they are to form the core of a simplification function in
Scala, as shown in Listing 15.2. The function, simplifyTop, can be used like this:
scala> simplifyTop(UnOp("-", UnOp("-", Var("x"))))
res4: Expr = Var(x)
def simplifyTop(expr: Expr): Expr = expr match {
case UnOp("-", UnOp("-", e)) => e // Double negation
case BinOp("+", e, Number(0)) => e // Adding zero
case BinOp("*", e, Number(1)) => e // Multiplying by one
case _ => expr
}
Listing 15.2 · The simplifyTop function, which does a pattern match.
2007
11. In the next two slides we go back to Brian Goetz’s blog
post to see how ADTs for ad-hoc instances of data
structures like Option and Tree can be written in Java 19.
12. Application: Ad-hoc data structures
Algebraic data types are also useful for modeling ad-hoc versions of general purpose data structures.
The popular class Optional could be modeled as an algebraic data type:
sealed interface Opt<T> {
record Some<T>(T value) implements Opt<T> { }
record None<T>() implements Opt<T> { }
}
(This is actually how Optional is defined in most functional languages.)
Common operations on Opt can be implemented with pattern matching:
static<T, U> Opt<U> map(Opt<T> opt, Function<T, U> mapper) {
return switch (opt) {
case Some<T>(var v) -> new Some<>(mapper.apply(v));
case None<T>() -> new None<>();
}
}
Similarly, a binary tree can be implemented as:
sealed interface Tree<T> {
record Nil<T>() implements Tree<T> { }
record Node<T>(Tree<T> left, T val, Tree<T> right) implements Tree<T> { }
}
@BrianGoetz
13. and we can implement the usual operations with pattern matching:
static<T> boolean contains(Tree<T> tree, T target) {
return switch (tree) {
case Nil() -> false;
case Node(var left, var val, var right) ->
target.equals(val) || left.contains(target) || right.contains(target);
};
}
static<T> void inorder(Tree<T> t, Consumer<T> c) {
switch (tree) {
case Nil(): break;
case Node(var left, var val, var right):
inorder(left, c);
c.accept(val);
inorder(right, c);
};
}
It may seem odd to see this behavior written as static methods, when common behaviors like traversal
should "obviously" be implemented as abstract methods on the base interface. And certainly, some
methods may well make sense to put into the interface. But the combination of records, sealed classes, and
pattern matching offers us alternatives that we didn't have before; we could implement them the old
fashioned way (with an abstract method in the base class and concrete methods in each subclass); as default
methods in the abstract class implemented in one place with pattern matching; as static methods; or (when
recursion is not needed), as ad-hoc traversals inline at the point of use.
Because the data carrier is purpose-built for the situation, we get to choose whether we want the behavior
to travel with the data or not. This approach is not at odds with object orientation; it is a useful addition to
our toolbox that can be used alongside OO, as the situation demands.
@BrianGoetz
14. @philip_schwarz
While in Programming in Scala (first edition) we saw the three features that enable Data
Oriented programming, we did not come across any references to the term Algebraic
Data Type, so let us turn to later Scala books that do define the term.
By the way, if you are interested in a more comprehensive introduction to Algebraic Data
Types, then take a look at the following deck, where the next four slides originate from:
15. Defining functional data structures
A functional data structure is (not surprisingly) operated on using only pure functions. Remember, a pure function must not
change data in place or perform other side effects. Therefore, functional data structures are by definition immutable.
…
let’s examine what’s probably the most ubiquitous functional data structure, the singly linked list. The definition here is
identical in spirit to (though simpler than) the List data type defined in Scala’s standard library.
…
Let’s look first at the definition of the data type, which begins with the keywords sealed trait.
In general, we introduce a data type with the trait keyword.
A trait is an abstract interface that may optionally contain implementations of some methods.
Here we’re declaring a trait, called List, with no methods on it.
Adding sealed in front means that all implementations of the trait must be declared in this file.1
There are two such implementations, or data constructors, of List (each introduced with the keyword case) declared next, to
represent the two possible forms a List can take.
As the figure…shows, a List can be empty, denoted by the data constructor Nil, or it can be nonempty, denoted by the data
constructor Cons (traditionally short for construct). A nonempty list consists of an initial element, head, followed by a List
(possibly empty) of remaining elements (the tail).
1 We could also say abstract class here instead of trait. The distinction between the two is not at all significant for our
purposes right now. …
sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]
Functional Programming in Scala
(by Paul Chiusano and Runar Bjarnason)
@pchiusano @runarorama
16. 3.5 Trees
List is just one example of what’s called an algebraic data type (ADT). (Somewhat confusingly, ADT is sometimes used
elsewhere to stand for abstract data type.) An ADT is just a data type defined by one or more data constructors, each of
which may contain zero or more arguments. We say that the data type is the sum or union of its data constructors, and
each data constructor is the product of its arguments, hence the name algebraic data type.14
14 The naming is not coincidental. There’s a deep connection, beyond the scope of this book, between the
“addition” and “multiplication” of types to form an ADT and addition and multiplication of numbers.
Tuple types in Scala
Pairs and tuples of other arities are also algebraic data types. They work just like the ADTs we’ve been writing here, but have
special syntax…
Algebraic data types can be used to define other data structures. Let’s define a simple binary tree data structure:
sealed trait Tree[+A]
case class Leaf[A](value: A) extends Tree[A]
case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]
…
Functional Programming in Scala
(by Paul Chiusano and Runar Bjarnason)
@pchiusano @runarorama
sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]
17. • The List algebraic data type is the sum of its data constructors, Nil and Cons.
• The Nil constructor has no arguments.
• The Cons constructor is the product of its arguments head: A and tail: List[A].
sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]
• The Tree algebraic data type is the sum of its data constructors, Leaf and Branch.
• The Leaf constructor has a single argument.
• The Branch constructor is the product of its arguments left: Tree[A] and right: Tree[A]
sealed trait Tree[+A]
case class Leaf[A](value: A) extends Tree[A]
case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]
Let’s recap (informally) what we just saw in FPiS.
SUM
SUM
PRODUCT
PRODUCT
18. Algebraic Type Systems
Now we can define what we mean by an “algebraic type system.” It’s not as scary as it
sounds—an algebraic type system is simply one where every compound type is
composed from smaller types by AND-ing or OR-ing them together. F#, like most
functional languages (but unlike OO languages), has a built-in algebraic type
system.
Using AND and OR to build new data types should feel familiar—we used the same kind
of AND and OR to document our domain. We’ll see shortly that an algebraic type
system is indeed an excellent tool for domain modeling. @ScottWlaschin
Jargon Alert: “Product Types” and “Sum Types”
The types that are built using AND are called product types.
The types that are built using OR are called sum types or tagged unions or, in F#
terminology, discriminated unions. In this book I will often call them choice types,
because I think that best describes their role in domain modeling.
19. In the next slide we see that sum types, as opposed
to product types, are also known as coproducts.
20. 4.1 Data
The fundamental building blocks of data types are
• final case class also known as products
• sealed abstract class also known as coproducts
• case object and Int, Double, String (etc) values
with no methods or fields other than the constructor parameters. We prefer abstract class to trait in order to get
better binary compatibility and to discourage trait mixing. The collective name for products, coproducts and values is
Algebraic Data Type (ADT).
We compose data types from the AND and XOR (exclusive OR) Boolean algebra: a product contains
every type that it is composed of, but a coproduct can be only one. For example
• product: ABC = a AND b AND c
• coproduct: XYZ = x XOR y XOR z
written in Scala
// values
case object A
type B = String
type C = Int
// product
final case class ABC(a: A.type, b: B, c: C)
// coproduct
sealed abstract class XYZ
case object X extends XYZ
case object Y extends XYZ
4.1.1 Recursive ADTs
When an ADT refers to itself, we call it a Recursive Algebraic Data Type.
The standard library List is recursive because :: (the cons cell) contains a reference
to List. The following is a simplification of the actual implementation:
sealed abstract class List[+A]
case object Nil extends List[Nothing]
final case class ::[+A](head: A, tail: List[A]) extends List[A]
21. @philip_schwarz
In the next three slides, we’ll see what Brian Goetz meant when he said, “that’s how
Optional is defined in most functional languages”.
If you are not familiar with Monads then feel free to simply skim the third of those slides.
If you want to know more about the Option Monad, then see the following slide deck:
22. We introduce a new type, Option. As we mentioned earlier, this type also exists in the
Scala standard library, but we’re re-creating it here for pedagogical purposes:
sealed trait Option[+A]
case class Some[+A](get: A) extends Option[A]
case object None extends Option[Nothing]
Option is mandatory! Do not use null to denote that an optional value is absent. Let’s have a
look at how Option is defined:
sealed abstract class Option[+A] extends IterableOnce[A]
final case class Some[+A](value: A) extends Option[A]
case object None extends Option[Nothing]
Since creating new data types is so cheap, and it is possible to work with them
polymorphically, most functional languages define some notion of an optional value. In
Haskell it is called Maybe, in Scala it is Option, … Regardless of the language, the
structure of the data type is similar:
data Maybe a = Nothing –- no value
| Just a -- holds a value
sealed abstract class Option[+A] // optional value
case object None extends Option[Nothing] // no value
case class Some[A](value: A) extends Option[A] // holds a value
We have already encountered scalaz’s improvement over scala.Option, called Maybe. It is
an improvement because it does not have any unsafe methods like Option.get, which can
throw an exception, and is invariant.
It is typically used to represent when a thing may be present or not without giving any extra
context as to why it may be missing.
sealed abstract class Maybe[A] { ... }
object Maybe {
final case class Empty[A]() extends Maybe[A]
final case class Just[A](a: A) extends Maybe[A]
Over the years we have all got very used to
the definition of the Option monad’s
Algebraic Data Type (ADT).
23. With the arrival of Scala 3 however, the definition of the
Option ADT becomes much terser thanks to the fact that it
can be implemented using the new enum concept .
24. enum Option[+A]:
case Some(a: A)
case None
def map[B](f: A => B): Option[B] =
this match
case Some(a) => Some(f(a))
case None => None
def flatMap[B](f: A => Option[B]): Option[B] =
this match
case Some(a) => f(a)
case None => None
def fold[B](ifEmpty: => B)(f: A => B) =
this match
case Some(a) => f(a)
case None => ifEmpty
def filter(p: A => Boolean): Option[A] =
this match
case Some(a) if p(a) => Some(a)
case _ => None
def withFilter(p: A => Boolean): Option[A] =
filter(p)
object Option :
def pure[A](a: A): Option[A] = Some(a)
def none: Option[Nothing] = None
extension[A](a: A):
def some: Option[A] = Some(a)
Option is a monad, so we have given it a
flatMap method and a pure method. In Scala
the latter is not strictly needed, but we’ll make
use of it later.
Every monad is also a functor, and this is
reflected in the fact that we have given Option a
map method.
We gave Option a fold method, to allow us to
interpret/execute the Option effect, i.e. to
escape from the Option container, or as John a
De Goes puts it, to translate away from
optionality by providing a default value.
We want our Option to integrate with for
comprehensions sufficiently well for our current
purposes, so in addition to map and flatMap
methods, we have given it a simplistic withFilter
method that is just implemented in terms of
filter, another pretty essential method.
There are of course many many other methods
that we would normally want to add to Option.
The some and none methods
are just there to provide the
convenience of Cats-like syntax
for lifting a pure value into an
Option and for referring to the
empty Option instance.
25. What about Algebraic Data Types in Haskell?
Let’s turn to that in the next four slides.
26. Algebraic types and pattern matching
Algebraic data types can express a combination of types, for example:
type Name = String
type Age = Int
data Person = P String Int -- combination
They can also express a composite of alternatives:
data MaybeInt = NoInt | JustInt Int
Here, each alternative represents a valid constructor of the algebraic type:
maybeInts = [JustInt 2, JustInt 3, JustInt 5, NoInt]
Type combination is also known as “product of types” and the type alternation as “sum of types”. In this way, we
can create an “algebra of types”, with sum and product as operators, hence the name Algebraic data types.
By parametrizing algebraic types, we can create generic types:
data Maybe' a = Nothing' | Just’ a
Algebraic data type constructors also serve as “deconstructors“ in pattern matching:
fMaybe f (Just' x) = Just' (f x)
fMaybe f Nothing' = Nothing’
fMaybes = map (fMaybe (* 2)) [Just’ 2, Just’ 3, Nothing]
On the left of the = sign we deconstruct; on the right we construct. In this sense, pattern matching is the
complement of algebraic data types: they are two sides of the same coin.
27. 16.1 Product types—combining types with “and”
Product types are created by combining two or more existing types with and. Here are some common examples:
• A fraction can be defined as a numerator (Integer) and denominator (another Integer).
• A street address might be a number (Int) and a street name (String).
• A mailing address might be a street address and a city (String) and a state (String) and a zip code (Int).
Although the name product type might make this method of combining types sound sophisticated, this is the
most common way in all programming languages to define types. Nearly all programming languages support
product types. The simplest example is a struct from C. Here’s an example in C of a struct for a book and an
author.
Listing 16.1 C structs are product types—an example with a book and author
struct author_name {
char *first_name;
char *last_name;
};
struct book {
author_name author;
char *isbn;
char *title;
int year_published;
double price;
};
In this example, you can see that the author_name type is made by combining two Strings (for those unfamiliar,
char * in C represents an array of characters). The book type is made by combining an author_name, two Strings,
an Int, and a Double. Both author_name and book are made by combining other types with an and. C’s structs are
the predecessor to similar types in nearly every language, including classes and JSON.
Listing 16.2 C’s author_name and book structs translated to Haskell
data AuthorName = AuthorName String String
data Book = Author String String Int
28. 16.2 Sum types—combining types with “or ”
Sum types are a surprisingly powerful tool, given that they provide only the capability to combine two types
with or. Here are examples of combining types with or:
• A die is either a 6-sided die or a 20-sided die or ....
• A paper is authored by either a person (String) or a group of people ([String]).
• A list is either an empty list ([]) or an item consed with another list (a:[a]).
The most straightforward sum type is Bool.
Listing 16.8 A common sum type: Bool
data Bool = False | True
An instance of Bool is either the False data constructor or the True data constructor. This can give the mistaken
impression that sum types are just Haskell’s way of creating enu- merative types that exist in many other
programming languages. But you’ve already seen a case in which sum types can be used for something more
powerful, in lesson 12 when you defined two types of names.
Listing 16.9 Using a sum type to model names with and without middle names
type FirstName = String
type LastName = String
type MiddleName = String
data Name = Name FirstName LastName | NameWithMiddle FirstName MiddleName LastName
In this example, you can use two type constructors that can either be a FirstName consisting of two Strings or a
NameWithMiddle consisting of three Strings. Here, using or between two types allows you to be expressive about
what types mean. Adding or to the tools you can use to combine types opens up worlds of possibility in
Haskell that aren’t available in any other programming language without sum types.
29. Data
Haskell has a very clean syntax for ADTs. This is a linked list structure:
data List a = Nil | Cons a (List a)
List is a type constructor, a is the type parameter, | separates the data constructors, which are: Nil the empty list and
a Cons cell. Cons takes two parameters, which are separated by whitespace: no commas and no parameter brackets.
There is no subtyping in Haskell, so there is no such thing as the Nil type or the Cons type: both construct a List.
30. In his blog post, Brian Goetz first looked at the following sample applications of Data Oriented programming:
• Complex return types (we skipped this)
• Ad-hoc data structures (we covered this)
He then turned to more complex domains and chose as an example the evaluation of simple arithmetic expressions.
This is a classic example of using ADTs.
We got a first hint of the expression ADT (albeit a slightly more complex version) in the first edition of Programming in Scala:
See the next two slides for when I first came across examples of the expression ADT in Haskell and Scala.
sealed abstract class Expr
case class Var(name: String) extends Expr
case class Number(num: Double) extends Expr
case class UnOp(operator: String, arg: Expr) extends Expr
case class BinOp(operator: String, left: Expr, right: Expr) extends Expr
31. 8.7 Abstract machine
For our second extended example, consider a type of simple arithmetic expressions built up from integers using an
addition operator, together with a function that evaluates such an expression to an integer value:
data Expr = Val Int | Add Expr Expr
value :: Expr -> Int
value (Val n) = n
value (Add x y) = value x + value y
For example, the expression (2 + 3) + 4 is evaluated as follows:
value (Add (Add (Val 2) (Val 3)) (Val 4))
= { applying value }
value (Add (Val 2) (Val 3)) + value (Val 4)
= { applying the first value }
(value (Val 2) + value (Val 3)) + value (Val 4)
= { applying the first value }
(2 + value (Val 3)) + value (Val 4)
= { applying the first value }
(2 + 3) + value (Val 4)
= { applying the first + }
5 + value (Val 4)
= { applying value }
5 + 4
= { applying + }
9
2007
32. 4.7 Pattern Matching
Martin Odersky
In did this course in 2013 (the second edition more
recently). The lectures for the first edition are freely
available on YouTube.
34. More complex domains
The domains we've looked at so far have either been "throwaways" (return values used across a call
boundary) or modeling general domains like lists and trees. But the same approach is also useful for
more complex application-specific domains. If we wanted to model an arithmetic expression, we
could do so with:
sealed interface Node { }
sealed interface BinaryNode extends Node {
Node left(); Node right();
}
record AddNode(Node left, Node right) implements BinaryNode { }
record MulNode(Node left, Node right) implements BinaryNode { }
record ExpNode(Node left, int exp) implements Node { }
record NegNode(Node node) implements Node { }
record ConstNode(double val) implements Node { }
record VarNode(String name) implements Node { }
Having the intermediate sealed interface BinaryNode which abstracts over addition and
multiplication gives us the choice when matching over a Node; we could handle both addition and
multiplication together by matching on BinaryNode, or handle them individually, as the situation
requires. The language will still make sure we covered all the cases.
@BrianGoetz
35. Writing an evaluator for these expressions is trivial. Since we have variables in our expressions, we'll need a store for
those, which we pass into the evaluator:
double eval(Node n, Function<String, Double> vars) {
return switch (n) {
case AddNode(var left, var right) -> eval(left, vars) + eval(right, vars);
case MulNode(var left, var right) -> eval(left, vars) * eval(right, vars);
case ExpNode(var node, int exp) -> Math.exp(eval(node, vars), exp);
case NegNode(var node) -> -eval(node, vars);
case ConstNode(double val) -> val;
case VarNode(String name) -> vars.apply(name);
}
}
The records which define the terminal nodes have reasonable toString implementations, but the output is probably more
verbose than we'd like. We can easily write a formatter to produce output that looks more like a mathematical
expression:
String format(Node n) {
return switch (n) {
case AddNode(var left, var right) -> String.format("("%s + %s)", format(left), format(right));
case MulNode(var left, var right) -> String.format("("%s * %s)", format(left), format(right));
case ExpNode(var node, int exp) -> String.format("%s^%d", format(node), exp);
case NegNode(var node) -> String.format("-%s", format(node));
case ConstNode(double val) -> Double.toString(val);
case VarNode(String name) -> name;
}
}
@BrianGoetz
36. In order to run that code, I downloaded
the Java 19 early access build.
37. When I tried to compile the code, I got the following error, so I replaced the
call to Math.exp with a call to Math.pow and renamed ExpNode to PowNode.
For the sake of consistency with the classic expression ADT, I also did the following:
• renamed Node to Expr
• renamed AddNode, MulNode, etc. to Add, Mul, etc.
• dropped the BinaryNode interface
See next slide for the resulting code.
38. import java.util.Map;
import java.util.function.Function;
public class Main {
static double eval(Expr e, Function<String, Double> vars) {
return switch (e) {
case Add(var left, var right) -> eval(left, vars) + eval(right, vars);
case Mul(var left, var right) -> eval(left, vars) * eval(right, vars);
case Pow(var expr, int exp) -> Math.pow(eval(expr, vars), exp);
case Neg(var expr) -> -eval(expr, vars);
case Const(double val) -> val;
case Var(String name) -> vars.apply(name);
};
}
static String format(Expr e) {
return switch (e) {
case Add(var left, var right) -> String.format("(%s + %s)", format(left), format(right));
case Mul(var left, var right) -> String.format("(%s * %s)", format(left), format(right));
case Pow(var expr, int exp) -> String.format("%s^%d", format(expr), exp);
case Neg(var expr) -> String.format("-%s", format(expr));
case Const(double val) -> Double.toString(val);
case Var(String name) -> name;
};
}
static Map<String,Double> bindings = Map.of("x",4.0,"y", 2.0);
static Function<String,Double> vars = v -> bindings.getOrDefault(v, 0.0);
public static void main(String[] args) { … }
}
public static void main(String[] args) {
var expr =
new Add(
new Mul(
new Pow(new Const(3.0),2),
new Var("x")),
new Neg(new Const(5.0)));
System.out.println(”expr=” + format(expr));
System.out.println("vars=” + bindings);
System.out.println(”value=” + eval(expr,vars));
}
public sealed interface Expr { }
record Add(Expr left, Expr right) implements Expr { }
record Mul(Expr left, Expr right) implements Expr { }
record Pow(Expr left, int exp) implements Expr { }
record Neg(Expr expr) implements Expr { }
record Const(double val) implements Expr { }
record Var(String name) implements Expr { }
41. def eval(e: Expr, vars: String => Double): Double =
e match
case Add(left, right) => eval(left, vars) + eval(right, vars)
case Mul(left, right) => eval(left, vars) * eval(right, vars)
case Pow(expr, exp) => Math.pow(eval(expr, vars), exp)
case Neg(expr) => - eval(expr, vars)
case Const(value) => value
case Var(name) => vars(name)
def format(e: Expr): String =
e match
case Add(left, right) => s"(${format(left)} + ${format(right)})"
case Mul(left, right) => s"(${format(left)} * ${format(right)})"
case Pow(expr, exp) => s"${format(expr)}^$exp"
case Neg(expr) => s"-${format(expr)}"
case Const(value) => value.toString
case Var(name) => name
val bindings = Map( "x" -> 4.0, "y" -> 2.0)
def vars(v: String): Double = bindings.getOrElse(v, 0.0)
@main def main(): Unit =
val expr = Add(
Mul(
Pow(Const(3.0),2),
Var("x")),
Neg(Const(5.0)))
println(s"expr=${format(expr)}")
println(s"vars=$bindings")
println(s"result=${eval(expr,vars)}")
enum Expr:
case Add(left: Expr, right: Expr)
case Mul(left: Expr, right: Expr)
case Pow(left: Expr, exp: Int)
case Neg(node: Expr)
case Const(value: Double)
case Var(name: String)
expr=((3.0^2 * x) + -5.0)
vars=Map(x -> 4.0, y -> 2.0)
result=31.0
42. sealed trait Expr
case class Add(left: Expr, right: Expr) extends Expr
case class Mul(left: Expr, right: Expr) extends Expr
case class Pow(expr: Expr, exp: Int) extends Expr
case class Neg(expr: Expr) extends Expr
case class Const(value: Double) extends Expr
case class Var(name: String) extends Expr
def eval(e: Expr, vars: String => Double): Double =
e match
case Add(left, right) => eval(left, vars) + eval(right, vars)
case Mul(left, right) => eval(left, vars) * eval(right, vars)
case Pow(expr, exp) => Math.pow(eval(expr, vars), exp)
case Neg(expr) => - eval(expr, vars)
case Const(value) => value
case Var(name) => vars(name)
def format(e: Expr): String =
e match
case Add(left, right) => s"(${format(left)} + ${format(right)})"
case Mul(left, right) => s"(${format(left)} * ${format(right)})"
case Pow(expr, exp) => s"${format(expr)}^$exp"
case Neg(expr) => s"-${format(expr)}"
case Const(value) => value.toString
case Var(name) => name
val bindings = Map( "x" -> 4.0, "y" -> 2.0)
def vars(v: String): Double = bindings.getOrElse(v, 0.0)
@main def main(): Unit =
val expr = Add(
Mul(
Pow(Const(3.0),2),
Var("x")),
Neg(Const(5.0)))
println(s"expr=${format(expr)}")
println(s"vars=$bindings")
println(s"result=${eval(expr,vars)}")
Same code as on the previous slide, except
that for the ADT, instead of using the
syntactic sugar afforded by enum, we use the
more verbose sealed trait plus case classes.
43. And now, to conclude this slide deck,
let’s translate the code into Haskell.
44. data Expr = Add Expr Expr |
Mul Expr Expr |
Pow Expr Int |
Neg Expr |
Const Double |
Var String
eval :: Expr -> (String -> Double) -> Double
eval (Add l r) vars = eval l vars + eval r vars
eval (Mul l r) vars = eval l vars * eval r vars
eval (Pow e n) vars = eval e vars ^ n
eval (Neg e) vars = - eval e vars
eval (Const i) _ = i
eval (Var v) vars = vars v
format :: Expr -> String
format (Add l r) = "(" ++ format l ++ " + " ++ format r ++ ")"
format (Mul l r) = "(" ++ format l ++ " * " ++ format r ++ ")"
format (Pow e n) = format e ++ " ^ " ++ show n
format (Neg e) = "-" ++ format e
format (Const i) = show i
format (Var v) = v
bindings = [("x", 4.0), ("y", 2.0)]
vars :: String -> Double
vars v = maybe undefined id (lookup v bindings)
main :: IO ()
main = let expression = (Add
(Mul
(Pow (Const 3.0) 2)
(Var "x")
)
(Neg (Const 5.0))
)
in do putStrLn ("expr=" ++ format expression)
putStr "vars="
print bindings
putStrLn ("value=" ++ show (eval expression vars))
expr=((3.0 ^ 2 * x) + -5.0)
vars=[("x",4.0),("y",2.0)]
value=31.0