The document describes ZIO, a functional programming library for Scala. It discusses how:
- ZIO programs are values that define effects to run concurrently using fibers.
- The R in ZIO[R, E, A] represents requirements - services required to run the program.
- Requirements can be eliminated by providing values using ZIO.provide.
- Modules define services using Has and provide accessor methods via ZIO.accessM.
- ZLayer represents recipes for building requirement outputs from inputs or resources. It is backed by ZManaged for safe acquisition/release.
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingJohn De Goes
As professional software engineers, sometimes messy details of the real world stand in the way of us delivering principled software. Flaky connections, unreliable services, and bulletproof job scheduling in the presence of non-determinism and failure all tricky problems that discourage us from writing principled software. Yet sometimes the shortcuts we take to solve these problems result in downtime for the business and sleepless nights for us.
In this brand-new presentation, created exclusively for Scala in the City, John A. De Goes will show how functional programming can help bring order to even the most chaotic systems. Using ZIO, a new zero-dependency Scala library for building massively scalable asynchronous and concurrent applications, John will demonstrate how functional programming leverages reified effects and algebras to solve the trickiest of reliability and scheduling problems in a principled, composable, flexible way.
Join John for an evening of fun and functional programming as you explore fresh ways of thinking about reliability and scheduling, and come out of the talk with valuable skills for using ZIO to solve the everyday problems you encounter at work.
Free monads and free applicatives have proven an incredibly useful tool in repertoire of the functional programmer: they separate concerns, encourage denotational semantics for program specification, allow easy and type-safe mocking of purely functional code, and allow dynamic introspection and optimization.
Despite these benefits, free monads are notoriously constrained: by themselves, they cannot handle parallelism (only sequentiality), and because they provide only a monad, richer structures (such as monads that fail, or monads that support alternation) cannot be expressed without crude hacks that limit composability and expressiveness.
In this session, John A. De Goes shows how the free monad can be deconstructed for its individual features, and then rebuilt using a more powerful technique that enables more extensibility. The resulting structure — no longer technically a "free monad" — allows reification of as few or as many aspects of computation as are necessary to model the problem domain.
After the session, attendees will know how to augment their existing free programs to add parallelism, racing, failure, and other aspects of computation as required by their problem. In addition, through this thorough deconstruction and reconstruction of the free monad, attendees will have a very deep understanding of reified computation and why the free monad has the structure and limitations it does.
Découverte d'algèbre, d'interpréteur par la création d'un DSL pour la base de données Aerospike. Le tout est implémenté dans le langage Scala avec un style fonctionnel.
A tour of Python: slides from presentation given in 2012.
[Some slides are not properly rendered in SlideShare: the original is still available at http://www.aleksa.org/2015/04/python-presentation_7.html.]
Moore's Law may be dead, but CPUs acquire more cores every year. If you want to minimize response latency in your application, you need to use every last core - without wasting resources that would destroy performance and throughput. Traditional locks grind threads to a halt and are prone to deadlocks, and although actors provide a saner alternative, they compose poorly and are at best weakly-typed.
In this presentation, created exclusively for Scalar Conf, John reveals a new alternative to the horrors of traditional concurrency, directly comparing it to other leading approaches in Scala. Witness the beauty, simplicity, and power of declarative concurrency, as you discover how functional programming is the most practical solution to solving the tough challenges of concurrency.
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingJohn De Goes
As professional software engineers, sometimes messy details of the real world stand in the way of us delivering principled software. Flaky connections, unreliable services, and bulletproof job scheduling in the presence of non-determinism and failure all tricky problems that discourage us from writing principled software. Yet sometimes the shortcuts we take to solve these problems result in downtime for the business and sleepless nights for us.
In this brand-new presentation, created exclusively for Scala in the City, John A. De Goes will show how functional programming can help bring order to even the most chaotic systems. Using ZIO, a new zero-dependency Scala library for building massively scalable asynchronous and concurrent applications, John will demonstrate how functional programming leverages reified effects and algebras to solve the trickiest of reliability and scheduling problems in a principled, composable, flexible way.
Join John for an evening of fun and functional programming as you explore fresh ways of thinking about reliability and scheduling, and come out of the talk with valuable skills for using ZIO to solve the everyday problems you encounter at work.
Free monads and free applicatives have proven an incredibly useful tool in repertoire of the functional programmer: they separate concerns, encourage denotational semantics for program specification, allow easy and type-safe mocking of purely functional code, and allow dynamic introspection and optimization.
Despite these benefits, free monads are notoriously constrained: by themselves, they cannot handle parallelism (only sequentiality), and because they provide only a monad, richer structures (such as monads that fail, or monads that support alternation) cannot be expressed without crude hacks that limit composability and expressiveness.
In this session, John A. De Goes shows how the free monad can be deconstructed for its individual features, and then rebuilt using a more powerful technique that enables more extensibility. The resulting structure — no longer technically a "free monad" — allows reification of as few or as many aspects of computation as are necessary to model the problem domain.
After the session, attendees will know how to augment their existing free programs to add parallelism, racing, failure, and other aspects of computation as required by their problem. In addition, through this thorough deconstruction and reconstruction of the free monad, attendees will have a very deep understanding of reified computation and why the free monad has the structure and limitations it does.
Découverte d'algèbre, d'interpréteur par la création d'un DSL pour la base de données Aerospike. Le tout est implémenté dans le langage Scala avec un style fonctionnel.
A tour of Python: slides from presentation given in 2012.
[Some slides are not properly rendered in SlideShare: the original is still available at http://www.aleksa.org/2015/04/python-presentation_7.html.]
Moore's Law may be dead, but CPUs acquire more cores every year. If you want to minimize response latency in your application, you need to use every last core - without wasting resources that would destroy performance and throughput. Traditional locks grind threads to a halt and are prone to deadlocks, and although actors provide a saner alternative, they compose poorly and are at best weakly-typed.
In this presentation, created exclusively for Scalar Conf, John reveals a new alternative to the horrors of traditional concurrency, directly comparing it to other leading approaches in Scala. Witness the beauty, simplicity, and power of declarative concurrency, as you discover how functional programming is the most practical solution to solving the tough challenges of concurrency.
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...Philip Schwarz
Java’s records, sealed interfaces and text blocks are catching up with Scala’s case classes, sealed traits and multiline strings
Judge for yourself in this quick IDE-based visual comparison
of the Scala and Java translations of Martin Fowler’s refactored Javascript code.
There are many popular stream libraries for Scala developers, including Akka Streams, scalaz-stream, fs2, plus others in the Java ecosystem. While all excellent choices for building reactive Scala applications, their reliance on effects makes them particularly difficult to test and reason about. In this talk, long-time Scala functional programmer John A. De Goes takes to the stage to demonstrate a new approach to modeling streams that requires less machinery and has more reasoning power, composability, flexibility, and testability than many other approaches. By attending the talk, you'll learn how the best stream library may be the one you get for (co)free!
Introduction to how to test our programs using imperative programming and functional programming with Tagless Final technique and how to make it simpler using ZIO. ZIO provides many features for concurrency and asynchronous programs. This presentation is about how to use ZIO environment to test your application.
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...Philip Schwarz
Java’s records, sealed interfaces and text blocks are catching up with Scala’s case classes, sealed traits and multiline strings
Judge for yourself in this quick IDE-based visual comparison
of the Scala and Java translations of Martin Fowler’s refactored Javascript code.
There are many popular stream libraries for Scala developers, including Akka Streams, scalaz-stream, fs2, plus others in the Java ecosystem. While all excellent choices for building reactive Scala applications, their reliance on effects makes them particularly difficult to test and reason about. In this talk, long-time Scala functional programmer John A. De Goes takes to the stage to demonstrate a new approach to modeling streams that requires less machinery and has more reasoning power, composability, flexibility, and testability than many other approaches. By attending the talk, you'll learn how the best stream library may be the one you get for (co)free!
Introduction to how to test our programs using imperative programming and functional programming with Tagless Final technique and how to make it simpler using ZIO. ZIO provides many features for concurrency and asynchronous programs. This presentation is about how to use ZIO environment to test your application.
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.
ZIO provides a variety of features for building synchronous, asynchronous and concurrent applications and enables us to use functional effects in Scala.
- Why functional effects?
- How to use functional effects and data types built on ZIO?
- How to manage errors and recover from them?
- How to manage resources and how to make concurrent tasks?
Final tagless. The topic strikes fear into the hearts of Scala developers everywhere—and not without reason. Final tagless allows developers to build composable Domain Specific Languages (DSLs) that model interaction with the outside world. Programs written using the final tagless style can be tested deterministically and reasoned about at compile-time. Yet the technique requires confusing, compiler-choking higher-kinded types, like `F[_]`, and pervasive, non-inferable context bounds like `F[_]: Concurrent: Console: Logging`. Many have looked at final tagless and wondered if all the layers of complexity and ceremony are really worth the benefits.
In this presentation, John A. De Goes provides a gentle and accessible introduction to final tagless, explaining what it is and the problem it intends to solve. John shows that while final tagless is easier to use than free monads, the technique suffers from a litany of drawbacks that push developers away from functional programming in Scala. John then introduces a novel approach that shares some of the benefits of final tagless, but which is idiomatic Scala, easy to explain, doesn’t need any complex type machinery, provides flawless type inference, and works beautifully across Scala 2.x and Scala 3.
Come join John for an evening of fun as you learn how to write functional code in Scala that's easy to test and easy to reason about—all without the complexity of free monads or final tagless.
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.
Functional programming languages promise to be easier to test and easier to debug. However, when learning the functional way we often try to translate our current techniques to another language. This is usually not easy and the end result is far from those promises we've heard. Early frustrations might even discourage from further learning.
In this talk I will show you two very simple patterns:
- Designing code around single data structure
- Dealing with impure parts of program like DBs, external services or IO
This should give beginners jump start for their first toy projects and further exploration.
Jay Clifford [InfluxData] | Tips & Tricks for Analyzing IIoT in Real-Time | I...InfluxData
Transforming raw machine data into real business outcomes such as OE and OEE is a journey. In this talk we will learn some tips and tricks for analyzing and transforming your machine data using InfluxDB and other third-party platforms.
This talk will explore inference from the perspective of protocols and generics and is based off a series of blog posts I've written(foxinswift.com) on the topic. In the first part of my talk casting number types through inference. I'll then show you struct serialization example demonstrating inferring a type through a mapping function. My last example will take you through inferring an associatedtype on a barebones promise implementation and we'll use it to in the context of making a network request. To finish things off I'll briefly speak on what's new in swift generics and some limitations of those features.
A complete list of MySQL commands with little description.
These are the available commands used for administration.
This was prepared while I was in CSIT VII Semester and would like to share with
you.
You use InfluxData to monitor the performance of your infrastructure and apps—so it is equally important to keep your InfluxEnterprise instance up and running. Tim Hall, InfluxData VP of Products, will outline why and how you can monitor InfluxEnterprise with InfluxDB.
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxrickgrimesss22
Discover the essential features to incorporate in your Winzo clone app to boost business growth, enhance user engagement, and drive revenue. Learn how to create a compelling gaming experience that stands out in the competitive market.
Enhancing Research Orchestration Capabilities at ORNL.pdfGlobus
Cross-facility research orchestration comes with ever-changing constraints regarding the availability and suitability of various compute and data resources. In short, a flexible data and processing fabric is needed to enable the dynamic redirection of data and compute tasks throughout the lifecycle of an experiment. In this talk, we illustrate how we easily leveraged Globus services to instrument the ACE research testbed at the Oak Ridge Leadership Computing Facility with flexible data and task orchestration capabilities.
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/
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Mind IT Systems
Healthcare providers often struggle with the complexities of chronic conditions and remote patient monitoring, as each patient requires personalized care and ongoing monitoring. Off-the-shelf solutions may not meet these diverse needs, leading to inefficiencies and gaps in care. It’s here, custom healthcare software offers a tailored solution, ensuring improved care and effectiveness.
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamtakuyayamamoto1800
In this slide, we show the simulation example and the way to compile this solver.
In this solver, the Helmholtz equation can be solved by helmholtzFoam. Also, the Helmholtz equation with uniformly dispersed bubbles can be simulated by helmholtzBubbleFoam.
May Marketo Masterclass, London MUG May 22 2024.pdfAdele Miller
Can't make Adobe Summit in Vegas? No sweat because the EMEA Marketo Engage Champions are coming to London to share their Summit sessions, insights and more!
This is a MUG with a twist you don't want to miss.
Enterprise Resource Planning System includes various modules that reduce any business's workload. Additionally, it organizes the workflows, which drives towards enhancing productivity. Here are a detailed explanation of the ERP modules. Going through the points will help you understand how the software is changing the work dynamics.
To know more details here: https://blogs.nyggs.com/nyggs/enterprise-resource-planning-erp-system-modules/
top nidhi software solution freedownloadvrstrong314
This presentation emphasizes the importance of data security and legal compliance for Nidhi companies in India. It highlights how online Nidhi software solutions, like Vector Nidhi Software, offer advanced features tailored to these needs. Key aspects include encryption, access controls, and audit trails to ensure data security. The software complies with regulatory guidelines from the MCA and RBI and adheres to Nidhi Rules, 2014. With customizable, user-friendly interfaces and real-time features, these Nidhi software solutions enhance efficiency, support growth, and provide exceptional member services. The presentation concludes with contact information for further inquiries.
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.
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Globus
Large Language Models (LLMs) are currently the center of attention in the tech world, particularly for their potential to advance research. In this presentation, we'll explore a straightforward and effective method for quickly initiating inference runs on supercomputers using the vLLM tool with Globus Compute, specifically on the Polaris system at ALCF. We'll begin by briefly discussing the popularity and applications of LLMs in various fields. Following this, we will introduce the vLLM tool, and explain how it integrates with Globus Compute to efficiently manage LLM operations on Polaris. Attendees will learn the practical aspects of setting up and remotely triggering LLMs from local machines, focusing on ease of use and efficiency. This talk is ideal for researchers and practitioners looking to leverage the power of LLMs in their work, offering a clear guide to harnessing supercomputing resources for quick and effective LLM inference.
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisGlobus
JASMIN is the UK’s high-performance data analysis platform for environmental science, operated by STFC on behalf of the UK Natural Environment Research Council (NERC). In addition to its role in hosting the CEDA Archive (NERC’s long-term repository for climate, atmospheric science & Earth observation data in the UK), JASMIN provides a collaborative platform to a community of around 2,000 scientists in the UK and beyond, providing nearly 400 environmental science projects with working space, compute resources and tools to facilitate their work. High-performance data transfer into and out of JASMIN has always been a key feature, with many scientists bringing model outputs from supercomputers elsewhere in the UK, to analyse against observational or other model data in the CEDA Archive. A growing number of JASMIN users are now realising the benefits of using the Globus service to provide reliable and efficient data movement and other tasks in this and other contexts. Further use cases involve long-distance (intercontinental) transfers to and from JASMIN, and collecting results from a mobile atmospheric radar system, pushing data to JASMIN via a lightweight Globus deployment. We provide details of how Globus fits into our current infrastructure, our experience of the recent migration to GCSv5.4, and of our interest in developing use of the wider ecosystem of Globus services for the benefit of our user community.
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.
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.
Listen to the keynote address and hear about the latest developments from Rachana Ananthakrishnan and Ian Foster who review the updates to the Globus Platform and Service, and the relevance of Globus to the scientific community as an automation platform to accelerate scientific discovery.
Into the Box Keynote Day 2: Unveiling amazing updates and announcements for modern CFML developers! Get ready for exciting releases and updates on Ortus tools and products. Stay tuned for cutting-edge innovations designed to boost your productivity.
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!
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTier1 app
Even though at surface level ‘java.lang.OutOfMemoryError’ appears as one single error; underlyingly there are 9 types of OutOfMemoryError. Each type of OutOfMemoryError has different causes, diagnosis approaches and solutions. This session equips you with the knowledge, tools, and techniques needed to troubleshoot and conquer OutOfMemoryError in all its forms, ensuring smoother, more efficient Java applications.
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns
Unlocking Business Potential: Tailored Technology Solutions by Prosigns
Discover how Prosigns, a leading technology solutions provider, partners with businesses to drive innovation and success. Our presentation showcases our comprehensive range of services, including custom software development, web and mobile app development, AI & ML solutions, blockchain integration, DevOps services, and Microsoft Dynamics 365 support.
Custom Software Development: Prosigns specializes in creating bespoke software solutions that cater to your unique business needs. Our team of experts works closely with you to understand your requirements and deliver tailor-made software that enhances efficiency and drives growth.
Web and Mobile App Development: From responsive websites to intuitive mobile applications, Prosigns develops cutting-edge solutions that engage users and deliver seamless experiences across devices.
AI & ML Solutions: Harnessing the power of Artificial Intelligence and Machine Learning, Prosigns provides smart solutions that automate processes, provide valuable insights, and drive informed decision-making.
Blockchain Integration: Prosigns offers comprehensive blockchain solutions, including development, integration, and consulting services, enabling businesses to leverage blockchain technology for enhanced security, transparency, and efficiency.
DevOps Services: Prosigns' DevOps services streamline development and operations processes, ensuring faster and more reliable software delivery through automation and continuous integration.
Microsoft Dynamics 365 Support: Prosigns provides comprehensive support and maintenance services for Microsoft Dynamics 365, ensuring your system is always up-to-date, secure, and running smoothly.
Learn how our collaborative approach and dedication to excellence help businesses achieve their goals and stay ahead in today's digital landscape. From concept to deployment, Prosigns is your trusted partner for transforming ideas into reality and unlocking the full potential of your business.
Join us on a journey of innovation and growth. Let's partner for success with Prosigns.
3. ZIO-101: PROGRAMS
val prg: ZIO[Console with Random, Nothing, Long] = for {
n <- random.nextLong // ZIO[Random, Nothing, Long]
_ <- console.putStrLn(s"Extracted $n ") // ZIO[Console, Nothing, Unit]
} yield n
val allNrs: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAll(List.fill(100)(prg))
val allNrsPar: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllPar(List.fill(100)(prg))
val allNrsParN: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllParN(10)(List.fill(100)(prg))
4. ZIO-101: PROGRAMS
▸ ZIO programs are values
val prg: ZIO[Console with Random, Nothing, Long] = for {
n <- random.nextLong // ZIO[Random, Nothing, Long]
_ <- console.putStrLn(s"Extracted $n ") // ZIO[Console, Nothing, Unit]
} yield n
val allNrs: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAll(List.fill(100)(prg))
val allNrsPar: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllPar(List.fill(100)(prg))
val allNrsParN: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllParN(10)(List.fill(100)(prg))
5. ZIO-101: PROGRAMS
▸ ZIO programs are values
▸ Concurrency based on fibers (green threads)
val prg: ZIO[Console with Random, Nothing, Long] = for {
n <- random.nextLong // ZIO[Random, Nothing, Long]
_ <- console.putStrLn(s"Extracted $n ") // ZIO[Console, Nothing, Unit]
} yield n
val allNrs: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAll(List.fill(100)(prg))
val allNrsPar: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllPar(List.fill(100)(prg))
val allNrsParN: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllParN(10)(List.fill(100)(prg))
6. ZIO-101: PROGRAMS
▸ ZIO programs are values
▸ Concurrency based on fibers (green threads)
val prg: ZIO[Console with Random, Nothing, Long] = for {
n <- random.nextLong // ZIO[Random, Nothing, Long]
_ <- console.putStrLn(s"Extracted $n ") // ZIO[Console, Nothing, Unit]
} yield n
val allNrs: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAll(List.fill(100)(prg))
val allNrsPar: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllPar(List.fill(100)(prg))
val allNrsParN: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllParN(10)(List.fill(100)(prg))
7. ZIO-101: PROGRAMS
▸ ZIO programs are values
▸ Concurrency based on fibers (green threads)
val prg: ZIO[Console with Random, Nothing, Long] = for {
n <- random.nextLong // ZIO[Random, Nothing, Long]
_ <- console.putStrLn(s"Extracted $n ") // ZIO[Console, Nothing, Unit]
} yield n
val allNrs: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAll(List.fill(100)(prg))
val allNrsPar: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllPar(List.fill(100)(prg))
val allNrsParN: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllParN(10)(List.fill(100)(prg))
8. ZIO-101: PROGRAMS
▸ ZIO programs are values
▸ Concurrency based on fibers (green threads)
val prg: ZIO[Console with Random, Nothing, Long] = for {
n <- random.nextLong // ZIO[Random, Nothing, Long]
_ <- console.putStrLn(s"Extracted $n ") // ZIO[Console, Nothing, Unit]
} yield n
val allNrs: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAll(List.fill(100)(prg))
val allNrsPar: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllPar(List.fill(100)(prg))
val allNrsParN: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllParN(10)(List.fill(100)(prg))
9. ZIO-101: PROGRAMS
▸ ZIO programs are values
▸ Concurrency based on fibers (green threads)
val prg: ZIO[Console with Random, Nothing, Long] = for {
n <- random.nextLong // ZIO[Random, Nothing, Long]
_ <- console.putStrLn(s"Extracted $n ") // ZIO[Console, Nothing, Unit]
} yield n
val allNrs: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAll(List.fill(100)(prg))
val allNrsPar: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllPar(List.fill(100)(prg))
val allNrsParN: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllParN(10)(List.fill(100)(prg))
10. ZIO-101: PROGRAMS
▸ ZIO programs are values
▸ Concurrency based on fibers (green threads)
val prg: ZIO[Console with Random, Nothing, Long] = for {
n <- random.nextLong // ZIO[Random, Nothing, Long]
_ <- console.putStrLn(s"Extracted $n ") // ZIO[Console, Nothing, Unit]
} yield n
val allNrs: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAll(List.fill(100)(prg))
val allNrsPar: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllPar(List.fill(100)(prg))
val allNrsParN: ZIO[Console with Random, Nothing, List[Long]] = ZIO.collectAllParN(10)(List.fill(100)(prg))
11. ZIO-101: R MEANS REQUIREMENT
val prg: ZIO[Console with Random, Nothing, Long] = ???
val autonomous: ZIO[Any, Nothing, Long] = ???
val getUserFromDb: ZIO[DBConnection, Nothing, User] = ???
12. ZIO-101: R MEANS REQUIREMENT
val prg: ZIO[Console with Random, Nothing, Long] = ???
val autonomous: ZIO[Any, Nothing, Long] = ???
val getUserFromDb: ZIO[DBConnection, Nothing, User] = ???
13. ZIO-101: R MEANS REQUIREMENT
val prg: ZIO[Console with Random, Nothing, Long] = ???
val autonomous: ZIO[Any, Nothing, Long] = ???
val getUserFromDb: ZIO[DBConnection, Nothing, User] = ???
14. ZIO-101: R MEANS REQUIREMENT
val prg: ZIO[Console with Random, Nothing, Long] = ???
val autonomous: ZIO[Any, Nothing, Long] = ???
val getUserFromDb: ZIO[DBConnection, Nothing, User] = ???
15. ZIO-101: REQUIREMENTS ELIMINATION
val getUserFromDb: ZIO[DBConnection, Nothing, User] = ???
val provided: ZIO[Any, Nothing, User] =
getUserFromDb.provide(DBConnection(...))
val user: User = Runtime.default.unsafeRun(provided)
16. ZIO-101: REQUIREMENTS ELIMINATION
val getUserFromDb: ZIO[DBConnection, Nothing, User] = ???
val provided: ZIO[Any, Nothing, User] =
getUserFromDb.provide(DBConnection(...))
val user: User = Runtime.default.unsafeRun(provided)
17. ZIO-101: REQUIREMENTS ELIMINATION
val getUserFromDb: ZIO[DBConnection, Nothing, User] = ???
val provided: ZIO[Any, Nothing, User] =
getUserFromDb.provide(DBConnection(...))
val user: User = Runtime.default.unsafeRun(provided)
18. ZIO-101: REQUIREMENTS ELIMINATION
val getUserFromDb: ZIO[DBConnection, Nothing, User] = ???
val provided: ZIO[Any, Nothing, User] =
getUserFromDb.provide(DBConnection(...))
val user: User = Runtime.default.unsafeRun(provided)
19. ZIO-101: MODULES
Example: a module to collect metrics1
type Metrics = Has[Metrics.Service]
object Metrics {
trait Service {
def inc(label: String): IO[Nothing, Unit]
}
//accessor method
def inc(label: String): ZIO[Metrics, Nothing, Unit] =
ZIO.accessM(_.get.inc(label))
}
}
1
ZIO 1.0.0-RC18
20. ZIO-101: MODULES
Example: a module to collect metrics1
type Metrics = Has[Metrics.Service]
object Metrics {
trait Service {
def inc(label: String): IO[Nothing, Unit]
}
//accessor method
def inc(label: String): ZIO[Metrics, Nothing, Unit] =
ZIO.accessM(_.get.inc(label))
}
}
1
ZIO 1.0.0-RC18
21. ZIO-101: MODULES
Example: a module to collect metrics1
type Metrics = Has[Metrics.Service]
object Metrics {
trait Service {
def inc(label: String): IO[Nothing, Unit]
}
//accessor method
def inc(label: String): ZIO[Metrics, Nothing, Unit] =
ZIO.accessM(_.get.inc(label))
}
}
1
ZIO 1.0.0-RC18
22. ZIO-101: MODULES
Example: a module for logging
type Log = Has[Log.Service]
object Log {
trait Service {
def info(s: String): IO[Nothing, Unit]
def error(s: String): IO[Nothing, Unit]
}
//accessor methods...
}
23. ZIO-101: MODULES
Write a program using existing modules
val prg: ZIO[Metrics with Log, Nothing, Unit] =
for {
_ <- Log.info("Hello")
_ <- Metrics.inc("salutation")
_ <- Log.info("Rotterdam")
_ <- Metrics.inc("subject")
} yield ()
24. ZIO-101: THE Has DATA TYPE
Has[A] is a dependency on a service of type A
val hasLog: Has[Log.Service] // type Log = Has[Log.Service]
val hasMetrics: Has[Metrics.Service] // type Metrics = Has[Metrics.Service]
val mix: Log with Metrics = hasLog ++ hasMetrics
//access each service
mix.get[Log.Service].info("Starting the application")
25. ZIO-101: THE Has DATA TYPE
Has[A] is a dependency on a service of type A
val hasLog: Has[Log.Service] // type Log = Has[Log.Service]
val hasMetrics: Has[Metrics.Service] // type Metrics = Has[Metrics.Service]
val mix: Log with Metrics = hasLog ++ hasMetrics
//access each service
mix.get[Log.Service].info("Starting the application")
26. ZIO-101: THE Has DATA TYPE
val mix: Log with Metrics = hasLog ++ hasMetrics
mix.get[Log.Service].info("Starting the application")
27. ZIO-101: THE Has DATA TYPE
val mix: Log with Metrics = hasLog ++ hasMetrics
mix.get[Log.Service].info("Starting the application")
▸ Is more powerful than trait mixins
28. ZIO-101: THE Has DATA TYPE
val mix: Log with Metrics = hasLog ++ hasMetrics
mix.get[Log.Service].info("Starting the application")
▸ Is more powerful than trait mixins
▸ Is backed by a heterogeneus map ServiceType -> Service
29. ZIO-101: THE Has DATA TYPE
val mix: Log with Metrics = hasLog ++ hasMetrics
mix.get[Log.Service].info("Starting the application")
▸ Is more powerful than trait mixins
▸ Is backed by a heterogeneus map ServiceType -> Service
▸ Can replace/update services
35. ZIO-101: ZLayer
Construct from function
val layer: ZLayer[Connection, Nothing, UserRepo] =
ZLayer.fromFunction { c: Connection =>
new UserRepo.Service
}
36. ZIO-101: ZLayer
Construct from effect
import java.sql.Connection
val e: ZIO[Connection, Error, UserRepo.Service]
val layer: ZLayer[Connection, Error, UserRepo] =
ZLayer.fromEffect(e)
37. ZIO-101: ZLayer
Construct from resources
import java.sql.Connection
val connectionLayer: ZLayer.NoDeps[Nothing, Has[Connection]] =
ZLayer.fromAcquireRelease(makeConnection) { c =>
UIO(c.close())
}
38. ZIO-101: ZLayer
Construct from other services
val usersLayer: ZLayer[UserRepo with UserValidation, Nothing, BusinessLogic] =
ZLayer.fromServices[UserRepo.Service, UserValidation.Service] {
(repoSvc, validSvc) =>
new BusinessLogic.Service {
// use repoSvc and validSvc
}
}
39. ZIO-101: ZLayer
Compose horizontally
(all inputs for all outputs)
val l1: ZLayer[Connection, Nothing, UserRepo]
val l2: ZLayer[Config, Nothing, AuthPolicy]
val hor: ZLayer[Connection with Config, Nothing, UserRepo with AuthPolicy] =
l1 ++ l2
40. ZIO-101: ZLayer
Compose vertically
(output of first for input of second)
val l1: ZLayer[Config, Nothing, Connection]
val l2: ZLayer[Connection, Nothing, UserRepo]
val ver: ZLayer[Config, Nothing, UserRepo] =
l1 >>> l2
41. ZIO-101: ZLayer
Create module instances
type UserRepo = Has[UserRepo.Service]
object UserRepo {
trait Service {
def getUser(userId: UserId): IO[DBError, Option[User]]
def createUser(user: User): IO[DBError, Unit]
}
val inMemory: ZLayer.NoDeps[Nothing, UserRepo] = ZLayer.succeed(
new Service {
/* impl */
}
)
val db: ZLayer[Connection, Nothing, UserRepo] = ZLayer.fromService { conn: Connection =>
new Service {
/* impl uses conn */
}
}
}
42. ZIO-101: ZLayer
Create module instances
type UserRepo = Has[UserRepo.Service]
object UserRepo {
trait Service {
def getUser(userId: UserId): IO[DBError, Option[User]]
def createUser(user: User): IO[DBError, Unit]
}
val inMemory: ZLayer.NoDeps[Nothing, UserRepo] = ZLayer.succeed(
new Service {
/* impl */
}
)
val db: ZLayer[Connection, Nothing, UserRepo] = ZLayer.fromService { conn: Connection =>
new Service {
/* impl uses conn */
}
}
}
43. ZIO-101: ZLayer
Create module instances
type UserRepo = Has[UserRepo.Service]
object UserRepo {
trait Service {
def getUser(userId: UserId): IO[DBError, Option[User]]
def createUser(user: User): IO[DBError, Unit]
}
val inMemory: ZLayer.NoDeps[Nothing, UserRepo] = ZLayer.succeed(
new Service {
/* impl */
}
)
val db: ZLayer[Connection, Nothing, UserRepo] = ZLayer.fromService { conn: Connection =>
new Service {
/* impl uses conn */
}
}
}
44. ZIO-101: ZLayer
Provide layers to programs
import zio.console.Console
val checkUser: ZIO[UserRepo with AuthPolicy with Console, Nothing, Boolean]
val liveLayer = UserRepo.inMemory ++ AuthPolicy.basicPolicy ++ Console.live
val full: ZIO[Any, Nothing, Boolean] = checkUser.provideLayer(
liveLayer
)
val partial: ZIO[Console, Nothing, Boolean] = checkUser.provideSomeLayer(
UserRepo.inMemory ++ AuthPolicy.basicPolicy
)
val updated: ZIO[Any, Nothing, Boolean] = checkUser.provideLayer(
liveLayer ++ UserRepo.postgres
)
45. ZIO-101: ZLayer
Provide layers to programs
import zio.console.Console
val checkUser: ZIO[UserRepo with AuthPolicy with Console, Nothing, Boolean]
val liveLayer = UserRepo.inMemory ++ AuthPolicy.basicPolicy ++ Console.live
val full: ZIO[Any, Nothing, Boolean] = checkUser.provideLayer(
liveLayer
)
val partial: ZIO[Console, Nothing, Boolean] = checkUser.provideSomeLayer(
UserRepo.inMemory ++ AuthPolicy.basicPolicy
)
val updated: ZIO[Any, Nothing, Boolean] = checkUser.provideLayer(
liveLayer ++ UserRepo.postgres
)
46. ZIO-101: ZLayer
Provide layers to programs
import zio.console.Console
val checkUser: ZIO[UserRepo with AuthPolicy with Console, Nothing, Boolean]
val liveLayer = UserRepo.inMemory ++ AuthPolicy.basicPolicy ++ Console.live
val full: ZIO[Any, Nothing, Boolean] = checkUser.provideLayer(
liveLayer
)
val partial: ZIO[Console, Nothing, Boolean] = checkUser.provideSomeLayer(
UserRepo.inMemory ++ AuthPolicy.basicPolicy
)
val updated: ZIO[Any, Nothing, Boolean] = checkUser.provideLayer(
liveLayer ++ UserRepo.postgres
)
47. ZIO-101: ZLayer
Provide layers to programs
import zio.console.Console
val checkUser: ZIO[UserRepo with AuthPolicy with Console, Nothing, Boolean]
val liveLayer = UserRepo.inMemory ++ AuthPolicy.basicPolicy ++ Console.live
val full: ZIO[Any, Nothing, Boolean] = checkUser.provideLayer(
liveLayer
)
val partial: ZIO[Console, Nothing, Boolean] = checkUser.provideSomeLayer(
UserRepo.inMemory ++ AuthPolicy.basicPolicy
)
val updated: ZIO[Any, Nothing, Boolean] = checkUser.provideLayer(
liveLayer ++ UserRepo.postgres
)
57. RAY TRACING
Options:
1. Compute all the rays (and discard most of
them)
2. Compute only the rays outgoing from the
camera through the canvas, and determine
how they behave on the surfaces
58. RAY
case class Ray(origin: Pt, direction: Vec) {
def positionAt(t: Double): Pt =
origin + (direction * t)
}
60. TRANSFORMATIONS MODULE
val rotatedPt =
for {
rotateX <- ATModule.rotateX(math.Pi / 2)
_ <- Log.info("rotated of π/2")
res <- ATModule.applyTf(rotateX, Pt(1, 1, 1))
} yield res
61. TRANSFORMATIONS MODULE
val rotatedPt: ZIO[ATModule with Log, ATError, Pt] =
for {
rotateX <- ATModule.rotateX(math.Pi / 2)
_ <- Log.info("rotated of π/2")
res <- ATModule.applyTf(rotateX, Pt(1, 1, 1))
} yield res
62. TRANSFORMATIONS MODULE - LIVE
val rotated: ZIO[ATModule, ATError, Vec] =
for {
rotateX <- ATModule.rotateX(math.Pi/2)
res <- ATModule.applyTf(rotateX, Pt(1, 1, 1))
} yield res
63. TRANSFORMATIONS MODULE - LIVE
val rotated: ZIO[ATModule, ATError, Vec] =
for {
rotateX <- ATModule.rotateX(math.Pi/2)
res <- ATModule.applyTf(rotateX, Pt(1, 1, 1))
} yield res
▸ Vec(x, y, z)
64. TRANSFORMATIONS MODULE - LIVE
val rotated: ZIO[ATModule, ATError, Vec] =
for {
rotateX <- ATModule.rotateX(math.Pi/2)
res <- ATModule.applyTf(rotateX, Pt(1, 1, 1))
} yield res
▸ Vec(x, y, z)
▸ Pt(x, y, z)⠀
65. TRANSFORMATIONS MODULE - LIVE
val rotated: ZIO[ATModule, ATError, Vec] =
for {
rotateX <- ATModule.rotateX(math.Pi/2)
res <- ATModule.applyTf(rotateX, Pt(1, 1, 1))
} yield res
▸ Vec(x, y, z)
▸ Pt(x, y, z)⠀
▸ ⠀
66. TRANSFORMATIONS MODULE - LIVE
val live: ZLayer[MatrixModule, Nothing, ATModule] =
ZLayer.fromService { matrixSvc =>
new Service {
def applyTf(tf: AT, vec: Vec) =
matrixSvc.mul(tf.direct, v)
/* ... */
}
}
70. WORLD
sealed trait Shape {
def transformation: AT
def material: Material
}
case class Sphere(transformation: AT, material: Material) extends Shape
case class Plane(transformation: AT, material: Material) extends Shape
71. WORLD
▸ Sphere.canonical
sealed trait Shape {
def transformation: AT
def material: Material
}
case class Sphere(transformation: AT, material: Material) extends Shape
case class Plane(transformation: AT, material: Material) extends Shape
72. WORLD
▸ Sphere.canonical
▸ Plane.canonical
sealed trait Shape {
def transformation: AT
def material: Material
}
case class Sphere(transformation: AT, material: Material) extends Shape
case class Plane(transformation: AT, material: Material) extends Shape
73. WORLD
▸ Sphere.canonical
▸ Plane.canonical
sealed trait Shape {
def transformation: AT
def material: Material
}
case class Sphere(transformation: AT, material: Material) extends Shape
case class Plane(transformation: AT, material: Material) extends Shape
74. WORLD
▸ Sphere.canonical
▸ Plane.canonical
sealed trait Shape {
def transformation: AT
def material: Material
}
case class Sphere(transformation: AT, material: Material) extends Shape
case class Plane(transformation: AT, material: Material) extends Shape
75. WORLD
▸ Sphere.canonical
▸ Plane.canonical
sealed trait Shape {
def transformation: AT
def material: Material
}
case class Sphere(transformation: AT, material: Material) extends Shape
case class Plane(transformation: AT, material: Material) extends Shape
76. WORLD
▸ Sphere.canonical
▸ Plane.canonical
sealed trait Shape {
def transformation: AT
def material: Material
}
case class Sphere(transformation: AT, material: Material) extends Shape
case class Plane(transformation: AT, material: Material) extends Shape
77. WORLD
MAKE A WORLD
object Sphere {
def make(center: Pt, radius: Double, mat: Material): ZIO[ATModule, ATError, Sphere] = for {
scale <- ATModule.scale(radius, radius, radius)
translate <- ATModule.translate(center.x, center.y, center.z)
composed <- ATModule.compose(scale, translate)
} yield Sphere(composed, mat)
}
object Plane {
def make(...): ZIO[ATModule, ATError, Plane] = ???
}
case class World(pointLight: PointLight, objects: List[Shape])
78. WORLD
MAKE A WORLD
object Sphere {
def make(center: Pt, radius: Double, mat: Material): ZIO[ATModule, ATError, Sphere] = for {
scale <- ATModule.scale(radius, radius, radius)
translate <- ATModule.translate(center.x, center.y, center.z)
composed <- ATModule.compose(scale, translate)
} yield Sphere(composed, mat)
}
object Plane {
def make(...): ZIO[ATModule, ATError, Plane] = ???
}
case class World(pointLight: PointLight, objects: List[Shape])
79. WORLD
MAKE A WORLD
object Sphere {
def make(center: Pt, radius: Double, mat: Material): ZIO[ATModule, ATError, Sphere] = for {
scale <- ATModule.scale(radius, radius, radius)
translate <- ATModule.translate(center.x, center.y, center.z)
composed <- ATModule.compose(scale, translate)
} yield Sphere(composed, mat)
}
object Plane {
def make(...): ZIO[ATModule, ATError, Plane] = ???
}
case class World(pointLight: PointLight, objects: List[Shape])
80. WORLD
MAKE A WORLD
object Sphere {
def make(center: Pt, radius: Double, mat: Material): ZIO[ATModule, ATError, Sphere] = for {
scale <- ATModule.scale(radius, radius, radius)
translate <- ATModule.translate(center.x, center.y, center.z)
composed <- ATModule.compose(scale, translate)
} yield Sphere(composed, mat)
}
object Plane {
def make(...): ZIO[ATModule, ATError, Plane] = ???
}
case class World(pointLight: PointLight, objects: List[Shape])
81. WORLD
MAKE A WORLD
object Sphere {
def make(center: Pt, radius: Double, mat: Material): ZIO[ATModule, ATError, Sphere] = for {
scale <- ATModule.scale(radius, radius, radius)
translate <- ATModule.translate(center.x, center.y, center.z)
composed <- ATModule.compose(scale, translate)
} yield Sphere(composed, mat)
}
object Plane {
def make(...): ZIO[ATModule, ATError, Plane] = ???
}
case class World(pointLight: PointLight, objects: List[Shape])
82. WORLD
MAKE A WORLD
object Sphere {
def make(center: Pt, radius: Double, mat: Material): ZIO[ATModule, ATError, Sphere] = for {
scale <- ATModule.scale(radius, radius, radius)
translate <- ATModule.translate(center.x, center.y, center.z)
composed <- ATModule.compose(scale, translate)
} yield Sphere(composed, mat)
}
object Plane {
def make(...): ZIO[ATModule, ATError, Plane] = ???
}
case class World(pointLight: PointLight, objects: List[Shape])
▸ Everything requires ATModule
83. WORLD RENDERING - TOP DOWN
RASTERING - GENERATE A STREAM OF COLORED PIXELS
type RasteringModule = Has[Service]
object RasteringModule {
trait Service {
def raster(world: World, camera: Camera):
Stream[RayTracerError, ColoredPixel]
}
}
84. WORLD RENDERING - TOP DOWN
RASTERING - Live
type CameraModule = Has[Service]
object CameraModule {
trait Service {
def rayForPixel(
camera: Camera, px: Int, py: Int
): UIO[Ray]
}
}
type WorldModule = Has[Service]
object WorldModule {
trait Service {
def colorForRay(
world: World, ray: Ray
): IO[RayTracerError, Color]
}
}
85. WORLD RENDERING - TOP DOWN
RASTERING - Live
▸ Camera module - Ray per pixel
type CameraModule = Has[Service]
object CameraModule {
trait Service {
def rayForPixel(
camera: Camera, px: Int, py: Int
): UIO[Ray]
}
}
type WorldModule = Has[Service]
object WorldModule {
trait Service {
def colorForRay(
world: World, ray: Ray
): IO[RayTracerError, Color]
}
}
86. WORLD RENDERING - TOP DOWN
RASTERING - Live
▸ Camera module - Ray per pixel
type CameraModule = Has[Service]
object CameraModule {
trait Service {
def rayForPixel(
camera: Camera, px: Int, py: Int
): UIO[Ray]
}
}
type WorldModule = Has[Service]
object WorldModule {
trait Service {
def colorForRay(
world: World, ray: Ray
): IO[RayTracerError, Color]
}
}
87. WORLD RENDERING - TOP DOWN
RASTERING - Live
▸ Camera module - Ray per pixel
type CameraModule = Has[Service]
object CameraModule {
trait Service {
def rayForPixel(
camera: Camera, px: Int, py: Int
): UIO[Ray]
}
}
type WorldModule = Has[Service]
object WorldModule {
trait Service {
def colorForRay(
world: World, ray: Ray
): IO[RayTracerError, Color]
}
}
88. WORLD RENDERING - TOP DOWN
RASTERING - Live
▸ Camera module - Ray per pixel
type CameraModule = Has[Service]
object CameraModule {
trait Service {
def rayForPixel(
camera: Camera, px: Int, py: Int
): UIO[Ray]
}
}
type WorldModule = Has[Service]
object WorldModule {
trait Service {
def colorForRay(
world: World, ray: Ray
): IO[RayTracerError, Color]
}
}
89. WORLD RENDERING - TOP DOWN
RASTERING - Live
▸ Camera module - Ray per pixel
type CameraModule = Has[Service]
object CameraModule {
trait Service {
def rayForPixel(
camera: Camera, px: Int, py: Int
): UIO[Ray]
}
}
▸ World module - Color per ray
type WorldModule = Has[Service]
object WorldModule {
trait Service {
def colorForRay(
world: World, ray: Ray
): IO[RayTracerError, Color]
}
}
90. WORLD RENDERING - TOP DOWN
RASTERING - Live
▸ Camera module - Ray per pixel
type CameraModule = Has[Service]
object CameraModule {
trait Service {
def rayForPixel(
camera: Camera, px: Int, py: Int
): UIO[Ray]
}
}
▸ World module - Color per ray
type WorldModule = Has[Service]
object WorldModule {
trait Service {
def colorForRay(
world: World, ray: Ray
): IO[RayTracerError, Color]
}
}
91. WORLD RENDERING - TOP DOWN
RASTERING - Live
▸ Camera module - Ray per pixel
type CameraModule = Has[Service]
object CameraModule {
trait Service {
def rayForPixel(
camera: Camera, px: Int, py: Int
): UIO[Ray]
}
}
▸ World module - Color per ray
type WorldModule = Has[Service]
object WorldModule {
trait Service {
def colorForRay(
world: World, ray: Ray
): IO[RayTracerError, Color]
}
}
92. WORLD RENDERING - TOP DOWN
RASTERING Live - MODULE DEPENDENCY
val chunkRasteringModule: ZLayer[CameraModule with WorldModule, Nothing, RasteringModule] =
ZLayer.fromServices[cameraModule.Service, worldModule.Service, rasteringModule.Service] {
(cameraSvc, worldSvc) =>
new Service {
override def raster(world: World, camera: Camera):
Stream[Any, RayTracerError, ColoredPixel] = {
val pixels: Stream[Nothing, (Int, Int)] = ???
pixels.mapM{
case (px, py) =>
for {
ray <- cameraModule.rayForPixel(camera, px, py)
color <- worldModule.colorForRay(world, ray)
} yield data.ColoredPixel(Pixel(px, py), color)
}
}
}
}
93. WORLD RENDERING - TOP DOWN
RASTERING Live - MODULE DEPENDENCY
val chunkRasteringModule: ZLayer[CameraModule with WorldModule, Nothing, RasteringModule] =
ZLayer.fromServices[cameraModule.Service, worldModule.Service, rasteringModule.Service] {
(cameraSvc, worldSvc) =>
new Service {
override def raster(world: World, camera: Camera):
Stream[Any, RayTracerError, ColoredPixel] = {
val pixels: Stream[Nothing, (Int, Int)] = ???
pixels.mapM{
case (px, py) =>
for {
ray <- cameraModule.rayForPixel(camera, px, py)
color <- worldModule.colorForRay(world, ray)
} yield data.ColoredPixel(Pixel(px, py), color)
}
}
}
}
94. WORLD RENDERING - TOP DOWN
RASTERING Live - MODULE DEPENDENCY
val chunkRasteringModule: ZLayer[CameraModule with WorldModule, Nothing, RasteringModule] =
ZLayer.fromServices[cameraModule.Service, worldModule.Service, rasteringModule.Service] {
(cameraSvc, worldSvc) =>
new Service {
override def raster(world: World, camera: Camera):
Stream[Any, RayTracerError, ColoredPixel] = {
val pixels: Stream[Nothing, (Int, Int)] = ???
pixels.mapM{
case (px, py) =>
for {
ray <- cameraModule.rayForPixel(camera, px, py)
color <- worldModule.colorForRay(world, ray)
} yield data.ColoredPixel(Pixel(px, py), color)
}
}
}
}
102. LIVE WorldModule
PhongReflectionModule
case class PhongComponents(
ambient: Color, diffuse: Color, reflective: Color
) {
def toColor: Color = ambient + diffuse + reflective
}
object PhongReflectionModule {
trait Service {
def lighting(
pointLight: PointLight, hitComps: HitComps,
inShadow: Boolean
): UIO[PhongComponents]
}
}
103. LIVE WorldModule
PhongReflectionModule
case class PhongComponents(
ambient: Color, diffuse: Color, reflective: Color
) {
def toColor: Color = ambient + diffuse + reflective
}
object PhongReflectionModule {
trait Service {
def lighting(
pointLight: PointLight, hitComps: HitComps,
inShadow: Boolean
): UIO[PhongComponents]
}
}
104. REFLECT THE LIGTHT SOURCE
Describe material properties
case class Material(
color: Color, // the basic color
ambient: Double, // ∈ [0, 1]
diffuse: Double, // ∈ [0, 1]
specular: Double, // ∈ [0, 1]
shininess: Double, // ∈ [10, 200]
)
105. LIVE PhongReflectionModule
WITH LightDiffusion AND LightReflection
object PhongReflectionModule {
trait Service { }
val live: ZLayer[ATModule
with LightDiffusionModule
with LightReflectionModule,
Nothing,
PhongReflectionModule]
}
114. CONCLUSION - ZLayer
▸ Dependency graph in the code
!
▸ Type safety, no magic
"
▸ Compiler helps to satisfy requirements
115. CONCLUSION - ZLayer
▸ Dependency graph in the code
!
▸ Type safety, no magic
"
▸ Compiler helps to satisfy requirements
▸ Try it out, and join ZIO Discord channel