SlideShare a Scribd company logo
1 of 33
Download to read offline
Can be functional concurrent programming be liberated
from the monadic style
ScalaUA - 2020
// ruslan shevchenko: ruslan@shevchenko.kiev.ua //
work: robotsmom [ managing partner ]
zaka.io [R&D]
twitter: @rssh1
Problem statement:
cache.query[Property](sql,	args:	_*).	
						map(_.map(_.getValue).toList	
)
- typical enterprise application usually contains something like this
monads, monads, … monads everywhere
// are we really need this for fetching data ?
// why accidental complexity is so hight ?
or control flow, reduced to linear with control-flow DSL inside for …
for{	
				x	<-	doSomething()	
				y	<-	ifM(q)(	
												oneBranch()	
									)(	
										pure(x))	
}
Problem statement:
cache.query[Property](sql,	args:	_*).	
						map(_.map(_.getValue).toList	
)
			await	cache.query[Property](sql,	args:	_*)
Can we fix this ?
- Is this already exists in Scala ?
Make Scala programming great again ?
- Why it’s all unusable now ?
- What will changed in the future?
1. Introduction.
• Monads/Continuations/Concurrency
• async/await in different languages/runtimes
2. Current situation
• existing libraries
• why it not works (?)
3. Dotty-Cps-Async ( https://github.com/rssh/dotty-cps-async )
1. How implement ‘usual async/await’ ?
2. What to do with
• Higher-order functions ?
• Different monads ?
• Behind concurrency.
3. Tasty reflection in a large scale.
PLAN
Monads/Concurrency
1993. Koen Claessen. A Poor Man's Concurrency Monad.
// Journal of Functional Programming
https://pdfs.semanticscholar.org/d4e0/a8554588b91f7404a75bd79807c08771da22.pdf
EVALUATOR
INPUT QUEUE
M[X]
— submit to evaluator value.pure : x ⇒ M[X]
—
submit value and function to eval
map(x : M[X])( f : X ⇒ Y) ⇒ M[Y]
—
submit value and function
and resubmit result back
flatMap(x : M[X])( f : X ⇒ M[Y]) ⇒ M[Y]
SIDE EFFECTS
// it is possible to build concurrency primitives:
fork, queue, … etc
Monads/Concurrency
1993. Koen Claessen. A Poor Man's Concurrency Monad.
// Journal of Functional Programming
https://pdfs.semanticscholar.org/d4e0/a8554588b91f7404a75bd79807c08771da22.pdf
EVALUATOR
INPUT QUEUE
M[X]
SIDE EFFECTS
Any concurrency type <=> type of evaluator
Monad-like concurrency in Scala:
- evaluate later in one thread ….
- evaluate now in Execution Pool (Future) ….
Why we represent concurrency in monads ?
poor-mans concurrency…..
- processes [CTSS ~ 1960]
- isolated data, communication primitives provides by OS.
-
// Context switching and memory mapping is slow, let’s invent something more fine-grained
Why we represent concurrency in monads ?
poor-mans concurrency…..
- processes [CTSS ~ 1960]
- isolated data, communication primitives and scheduling provides by OS.
-
// Context switching and memory mapping is slow, let’s invent something more fine-grained
- kernel threads [OS360Task ~ 1971, SunOS Threads ~ 1993]
- shared data, communication primitives provided by library, scheduling - by OS.
-
// Context switching is slow,
// Dealing with shared data is hard
let’s invent something more fine-grained
Why we represent concurrency in monads ?
poor-mans concurrency…..
- processes [CTSS ~ 1960]
- isolated data, communication primitives and scheduling provides by OS.
-// Context switching and memory mapping is slow, let’s invent something more fine-grained
- kernel threads [OS360Task ~ 1971, SunOS Threads ~ 1993]
- shared data, communication primitives provided by library, scheduling - by OS.
-
// Context switching is slow,
// Dealing with shared data is hard
let’s invent something more fine-grained
- user-land threads, Fibers [JVM: Green Threads ~ 2000 , Loom ~ 2018 - 2020]
- shared data, communication primitives and scheduling provided by library/runtime
-
// Dealing with shared data is hard
// IO access with user scheduling is hard.
let’s invent something more simple
Why we represent concurrency in monads ?
poor-mans concurrency…..
- processes [CTSS ~ 1960]
- isolated data, communication primitives and scheduling provides by OS.
-// Context switching and memory mapping is slow, let’s invent something more fine-grained
- kernel threads [OS360Task ~ 1971, SunOS Threads ~ 1993]
- shared data, communication primitives provided by library, scheduling - by OS.
-
// Context switching is slow,
// Dealing with shared data is hard
let’s invent something more fine-grained
- user-land threads, Fibers [JVM: Green Threads ~ 2000 , Loom ~ 2018 - 2020]
- shared data, communication primitives and scheduling provided by library/runtime
-
// Dealing with shared data is hard
// IO access with user scheduling is hard.
let’s invent something more simple
- Callback hell, [Node.js: ~ 2009 , Reactive manifesto ~ 2019]
- shared data, communications primitives use callbacks to avoid scheduling.
-
User-level scheduling….
- Callback hell,
- shared data, communications primitives use callbacks to avoid scheduling.
-
- Functional Programming (Monads),
- communications primitives use hight-order functions instead callbacks
- which was invented to avoid scheduling.
- Concurrency Frameworks for Functional Programming,
- let’s write generic functional scheduler for better organising of hight-order functions
- which are here to avoid callbacks
- which are here to avoid generic user-land scheduling
- which are here to avoid thread context switching using OS scheduler
- which are here to avoid process context switching using OS scheduler
// Programming with callbacks is hard
// Functional Programming is hard
Let’s return to our monads….
M[X]
Concurrency (different types)
Distributed programming
(thread-level, fibers, …. etc)
Abstraction [free monad + interpreter]
Unmonad: f : X ⇒ M[X]
await[M] : M[X] → X
async[M] : (f : (X ⇒ Y)) ⇒ (f′ : (X ⇒ M[Y]))
await ⊏ f await /⊏ f′
Let’s return to out monads….
Unmonad:
await[M] : M[X] → X
async[M] : (f : (X ⇒ Y)) ⇒ (f′ : (X ⇒ M[Y]))
await /⊏ f′
async/await
Possible solutions:
lift/unlift
runtime: (Project Loom, specific case of concurrency.)
compile-time: (macros or compiler plugin)
effectfully/!
Idris bang notation
reset/shift
Let’s return to out monads….
Scala2 attempts:
• Scala-continuations.  
• http://infoscience.epfl.ch/record/149136/files/icfp113-rompf.pdf
• Scala-async:
•  https://github.com/scala/scala-async
• Storm-enroute coroutines: 
• http://storm-enroute.com/coroutines/
• https://drops.dagstuhl.de/opus/volltexte/2018/9208/pdf/LIPIcs-ECOOP-2018-3.pdf
• Thoughtworks DSL.scala:
• https://github.com/ThoughtWorksInc/Dsl.scala
• Monadless.io: 
• http://monadless.io/
• Effectfull:
•  https://github.com/pelotom/effectful
// different levels of usability, but all solutions are partial
Main techniques for transformation: State Machine CPS Transform
def	f(x:Int)	{	
				val	q	=	await(doSomething)	
				val	y	=	await(doOtherthing(x,q))		
				y	+	q	
}
class		f’	{	
		val	q	
		val	y	
		var	state	=	0	
		def	apply(x:Int)	{			
				state	match	{	
					case	0	=>	state=1	
									doSomething.flatMap(r	=>	{q=r;	this(x)})	
					case	1	=>	state=2	
									doOtherthing(x,q).flatMap(	r	=>	{	y=r;	this(x)	})	
					case	2	=>		
									monad.pure(y+q)			
		}	
}
State Machine
Main techniques for transformation: State Machine CPS Transform
def	f(x:Int):Int	{	
				val	q	=	await(doSomething)	
				val	y	=	await(doOtherthing(x,q))		
				y	+	q	
}
def	f’(x:Int,	cont[A]:	Int	=>	CpsMonad[A])	{	
		doSomething(	r	=>	
				val	q	=	r	
				doOtherthing(x,q,	r	=>	{		
						val	y	=	r	
						cont(y	+	q)	})		
		)		
}	
CPS Transform
Dotty / Scala3:
• New
• compile, syntax, macro system
Let’s made ideal async transformer
• Dotty-cps-async
• https://github.com/rssh/dotty-cps-async
• optimised monadic CPS transform.
• any monad
• (which implements needed facilities)
• full language
• (essential constructs)
• higher-order functions
• (need to implement helper typeclass)
• optimised monadic CPS transform.
def	f(x:Int):Int	{	
				val	q	=	await(doSomething)	
				val	y	=	await(doOtherthing(x,q))		
				y	+	q	
}
def	f’[F:AsyncMonad](x:Int):F[Int]	{	
		summon[F].flatMap(doSomething){	r	=>		
						val	q	=	r	
						summon[F].map(doOtherthing(x,q)){r	=>		
									val	y	=	r	
									y	+	q		
						}			
		}		
}
• optimised monadic CPS transform
• main constructions:
• Constant expression:
• Block(sequential composition)
• sync, sync:
• async, sync:
• async, async:
m.pure(x)x
{x;	y} m.pure({x;	y})
{await[M](x);	y} m.map(x)(_	=>	y)
{await[M](x);		
await[M](y)}
m.flatMap(x)(_	=>	y)
//Number of maps ~~ Number of awaits…
• Local values
• sync expr, sync tail
• async expr, async tail
m.map(vx){	r	=>	val	x	=	r;	y	}
					{val	x	=	vx;	…}		//unchanged..
{val	x	=	await(vx);	y}
• Loops
• l
while( )	{	
			 	
}		
conditionasync
bodyasync
def	whilefun()	=	{	
			m.flatMap(condition){	c	=>		
						if	( )		
									m.flatMap(body)(_	=>	
																										whilefun())	
						else	
									m.pure(())				
}		
c
async[F:AsyncMonad]		{	
		val	connection	=	await(receiveConnection)	
		try	
				while	{	
						val	command	=	readComand(connection)	
						val	reply	=	await(handleOperation(command))	
						Command	!=	Shutdown	
				}	do	()	
		finally	
					connection.close()	
}
m.flatMap(openConnection())(a	=>	{	
		val	connection:	Connection[F]	=	a	
		m.withAction({	
				def	_whilefun():	F[Unit]	=	
							m.flatMap(	
									m.flatMap(readCommand(connection))((a:	Command)	=>	{	
										val	command:	Command	=	a	
										m.flatMap(handle(command))((a:	Reply)	=>	{	
												val	reply:	Reply	=	a	
												m.flatMap(	
													if	(!reply.isMuted)	
															connection.send(reply.toBytes)	
													else	
															m.pure(())	
												)(	_	=>	m.pure(!command.isShutdown))	
						})	
				}))(c	=>	if	(c)	_whilefun()	else	m.pure(()))	
				_whilefun()	
		})(	
				m.pure(connection.close())	
		)	
})
async[F:AsyncMonad]		{	
		val	connection	=	await(receiveConnection)	
		try	
				while	{	
						val	command	=	readComand(connection)	
						val	reply	=	await(handleOperation(command))	
						Command	!=	Shutdown	
				}	do	()	
		finally	
					connection.close()	
}
m.flatMap(openConnection())(a	=>	{	
		val	connection:	Connection[F]	=	a	
		m.withAction({	
				def	_whilefun():	F[Unit]	=	
							m.flatMap(	
									m.flatMap(readCommand(connection))((a:	Command)	=>	{	
										val	command:	Command	=	a	
										m.flatMap(handle(command))((a:	Reply)	=>	{	
												val	reply:	Reply	=	a	
												m.flatMap(	
													if	(!reply.isMuted)	
															connection.send(reply.toBytes)	
													else	
															m.pure(())	
												)(	_	=>	m.pure(!command.isShutdown))	
						})	
				}))(c	=>	if	(c)	_whilefun()	else	m.pure(()))	
				_whilefun()	
		})(	
				m.pure(connection.close())	
		)	
})
What we need from monad ?
def pure[T](t:T):F[T]
def map[A,B](fa:F[A])(f: A=>B):F[B]
def flatMap[A,B](fa:F[A])(f: A=>F[B]):F[B]
for control flow
def error[A](e: Throwable): F[A]
def restore[A](fa: F[A])(fx:Throwable => F[A]): F[A]
for try/catch
def adoptCallbackStyle[A](source: (Try[A]=>Unit) => Unit):F[A]
def spawn[A](op: =>F[A]): F[A]
def fulfill[T](t:F[T], timeout: Duration): Option[Try[T]]
for integration
with other
async monads
?
Different monads in one expression:
async[ ]{	
			…	
			val	x	=	await[ ](something)	
			…		
}		
M1
M2
implicit	def	mc[A](x: [A]): [A]=	
		….
M2 M1
Possible, if we have implicit conversion:
Different monads in one expression:
async[M]{	
			…	
			val	x	=	await[M](something)	
			…		
}		
	LoggedM:	M	~>	Logged[M]	
		….
:
async[Logged[M]]{	
			…	
			val	x	=	await[M](something)	
			…		
}		 // now we can log context boundaries
Higher-order functions:
async	{	
		val	words	=	line.split("	")	
		for(w	<-	words)	{	
					await(channel.write(CountSignal.Data(w)))	
		}	
		await(channel.write(CountSignal.Finish))	
}
ArrayOps[String].foreach[U](String => U)
(String => M[U])
summon[CpsShifted[ArrayOps[String],M].foreach(words,m)
class ArrayOpsAsyncShift[A] extends AsyncShift[ArrayOps[A]] {
def foreach[F[_],U](arrayOps: ArrayOps[A], monad: AsyncMonad[F])(
f: A => F[U]): F[Unit] = {
var r:F[Unit] = monad.pure(())
arrayOps.foreach{ a =>
val b = f(a)
r = monad.flatMap(r)(_ => monad.map(b)(_ =>()) )
}
r
}
…….
inline given shiftedArrayOps[A] as _ <: AsyncShift[ArrayOps[A]] =
new cps.runtime.ArrayOpsAsyncShift[A]()
Define implicit helper typeclass
Implement ‘shiftedVersions’ of async
Higher-order functions:
• Shifted version for standard library
• Provide guidelines for library authors.
• Future:
• In theory it’s possible to generate ‘shifter’ versions automatically
• Dotty store a compiled AST for each method in .class .
• Current limitations:
• it is impossible to access one via compile-time reflection.
• Third-order shifted lambda-functions
• Possible to transform in-place
• Hard to find real-wold example.
• on practice: higher-order ~~ second-order
• Application code:
• usually have ‘monadic’ version as business logic.
• Can we apply async/await on other monad ?
Let’s await on space, instead await on time.
• Knight tour problem:
case	class	State(	
			currentPoint:	Point,	
			board:	Chessboard,	
			trace:	List[Point]	
)	
def nextMoves(state: State):List[State] = …..
def	findPath(initPos:Point,	state:	State):	List[State]	=	
async[List]{	
										val	nextState	=	await(nextMoves(state))	
										if	(board.isFull())	
												if	(initPos	==	nextState.currentPoint)	
															nextState	
												else	
															await(Nil)	
										else	
												await(findPath(initPos,nextState))	
}	
// complex backtracking algorithm become simple.
Current implementation:
https://github.com/rssh/dotty-cps-async
How can you help(?)
- implement missing parts (it's still a lot of work)
- provide a small examples
- trying to use in own dotty experiments
Thanks for attentions.
// Ruslan Shevchenko <ruslan@shevchenko.kiev.ua>
RobotsMom @rssh1 - twitter
@rssh - github
ScalaUA - 2020

More Related Content

More from Ruslan Shevchenko

SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.Ruslan Shevchenko
 
Few simple-type-tricks in scala
Few simple-type-tricks in scalaFew simple-type-tricks in scala
Few simple-type-tricks in scalaRuslan Shevchenko
 
Why scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with thisWhy scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with thisRuslan Shevchenko
 
Scala jargon cheatsheet
Scala jargon cheatsheetScala jargon cheatsheet
Scala jargon cheatsheetRuslan Shevchenko
 
Java & low latency applications
Java & low latency applicationsJava & low latency applications
Java & low latency applicationsRuslan Shevchenko
 
Csp scala wixmeetup2016
Csp scala wixmeetup2016Csp scala wixmeetup2016
Csp scala wixmeetup2016Ruslan Shevchenko
 
R ext world/ useR! Kiev
R ext world/ useR!  KievR ext world/ useR!  Kiev
R ext world/ useR! KievRuslan Shevchenko
 
Jslab rssh: JS as language platform
Jslab rssh:  JS as language platformJslab rssh:  JS as language platform
Jslab rssh: JS as language platformRuslan Shevchenko
 
Behind OOD: domain modelling in post-OO world.
Behind OOD:  domain modelling in post-OO world.Behind OOD:  domain modelling in post-OO world.
Behind OOD: domain modelling in post-OO world.Ruslan Shevchenko
 
scala-gopher: async implementation of CSP for scala
scala-gopher:  async implementation of CSP  for  scalascala-gopher:  async implementation of CSP  for  scala
scala-gopher: async implementation of CSP for scalaRuslan Shevchenko
 
Programming Languages: some news for the last N years
Programming Languages: some news for the last N yearsProgramming Languages: some news for the last N years
Programming Languages: some news for the last N yearsRuslan Shevchenko
 
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
JDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation streamJDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation stream
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation streamRuslan Shevchenko
 
Ruslan.shevchenko: most functional-day-kiev 2014
Ruslan.shevchenko: most functional-day-kiev 2014Ruslan.shevchenko: most functional-day-kiev 2014
Ruslan.shevchenko: most functional-day-kiev 2014Ruslan Shevchenko
 
Web architecture - overview of techniques.
Web architecture - overview of  techniques.Web architecture - overview of  techniques.
Web architecture - overview of techniques.Ruslan Shevchenko
 
Javascript in modern scala backend. [russian]
Javascript in modern scala backend.  [russian]  Javascript in modern scala backend.  [russian]
Javascript in modern scala backend. [russian] Ruslan Shevchenko
 
Implementation of 'go-like' language constructions in scala [english version]
Implementation of 'go-like' language constructions in scala [english version] Implementation of 'go-like' language constructions in scala [english version]
Implementation of 'go-like' language constructions in scala [english version] Ruslan Shevchenko
 
implementation of 'go'-like language constructions in scala (russian)
implementation of 'go'-like language constructions in scala (russian)implementation of 'go'-like language constructions in scala (russian)
implementation of 'go'-like language constructions in scala (russian)Ruslan Shevchenko
 

More from Ruslan Shevchenko (20)

SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.
 
Few simple-type-tricks in scala
Few simple-type-tricks in scalaFew simple-type-tricks in scala
Few simple-type-tricks in scala
 
Why scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with thisWhy scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with this
 
Scala jargon cheatsheet
Scala jargon cheatsheetScala jargon cheatsheet
Scala jargon cheatsheet
 
Java & low latency applications
Java & low latency applicationsJava & low latency applications
Java & low latency applications
 
Csp scala wixmeetup2016
Csp scala wixmeetup2016Csp scala wixmeetup2016
Csp scala wixmeetup2016
 
IDLs
IDLsIDLs
IDLs
 
R ext world/ useR! Kiev
R ext world/ useR!  KievR ext world/ useR!  Kiev
R ext world/ useR! Kiev
 
Jslab rssh: JS as language platform
Jslab rssh:  JS as language platformJslab rssh:  JS as language platform
Jslab rssh: JS as language platform
 
Behind OOD: domain modelling in post-OO world.
Behind OOD:  domain modelling in post-OO world.Behind OOD:  domain modelling in post-OO world.
Behind OOD: domain modelling in post-OO world.
 
scala-gopher: async implementation of CSP for scala
scala-gopher:  async implementation of CSP  for  scalascala-gopher:  async implementation of CSP  for  scala
scala-gopher: async implementation of CSP for scala
 
Programming Languages: some news for the last N years
Programming Languages: some news for the last N yearsProgramming Languages: some news for the last N years
Programming Languages: some news for the last N years
 
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
JDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation streamJDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation stream
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
 
Ruslan.shevchenko: most functional-day-kiev 2014
Ruslan.shevchenko: most functional-day-kiev 2014Ruslan.shevchenko: most functional-day-kiev 2014
Ruslan.shevchenko: most functional-day-kiev 2014
 
Web architecture - overview of techniques.
Web architecture - overview of  techniques.Web architecture - overview of  techniques.
Web architecture - overview of techniques.
 
R scala 17_05_2014
R scala 17_05_2014R scala 17_05_2014
R scala 17_05_2014
 
Javascript in modern scala backend. [russian]
Javascript in modern scala backend.  [russian]  Javascript in modern scala backend.  [russian]
Javascript in modern scala backend. [russian]
 
Osdn2013 rssh
Osdn2013 rsshOsdn2013 rssh
Osdn2013 rssh
 
Implementation of 'go-like' language constructions in scala [english version]
Implementation of 'go-like' language constructions in scala [english version] Implementation of 'go-like' language constructions in scala [english version]
Implementation of 'go-like' language constructions in scala [english version]
 
implementation of 'go'-like language constructions in scala (russian)
implementation of 'go'-like language constructions in scala (russian)implementation of 'go'-like language constructions in scala (russian)
implementation of 'go'-like language constructions in scala (russian)
 

Recently uploaded

Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfYashikaSharma391629
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 

Recently uploaded (20)

Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 

Can concurrent functional programming be liberated from monadic style

  • 1. Can be functional concurrent programming be liberated from the monadic style ScalaUA - 2020 // ruslan shevchenko: ruslan@shevchenko.kiev.ua // work: robotsmom [ managing partner ] zaka.io [R&D] twitter: @rssh1
  • 2. Problem statement: cache.query[Property](sql, args: _*). map(_.map(_.getValue).toList ) - typical enterprise application usually contains something like this monads, monads, … monads everywhere // are we really need this for fetching data ? // why accidental complexity is so hight ? or control flow, reduced to linear with control-flow DSL inside for … for{ x <- doSomething() y <- ifM(q)( oneBranch() )( pure(x)) }
  • 3. Problem statement: cache.query[Property](sql, args: _*). map(_.map(_.getValue).toList ) await cache.query[Property](sql, args: _*) Can we fix this ? - Is this already exists in Scala ? Make Scala programming great again ? - Why it’s all unusable now ? - What will changed in the future?
  • 4. 1. Introduction. • Monads/Continuations/Concurrency • async/await in different languages/runtimes 2. Current situation • existing libraries • why it not works (?) 3. Dotty-Cps-Async ( https://github.com/rssh/dotty-cps-async ) 1. How implement ‘usual async/await’ ? 2. What to do with • Higher-order functions ? • Different monads ? • Behind concurrency. 3. Tasty reflection in a large scale. PLAN
  • 5. Monads/Concurrency 1993. Koen Claessen. A Poor Man's Concurrency Monad. // Journal of Functional Programming https://pdfs.semanticscholar.org/d4e0/a8554588b91f7404a75bd79807c08771da22.pdf EVALUATOR INPUT QUEUE M[X] — submit to evaluator value.pure : x ⇒ M[X] — submit value and function to eval map(x : M[X])( f : X ⇒ Y) ⇒ M[Y] — submit value and function and resubmit result back flatMap(x : M[X])( f : X ⇒ M[Y]) ⇒ M[Y] SIDE EFFECTS // it is possible to build concurrency primitives: fork, queue, … etc
  • 6. Monads/Concurrency 1993. Koen Claessen. A Poor Man's Concurrency Monad. // Journal of Functional Programming https://pdfs.semanticscholar.org/d4e0/a8554588b91f7404a75bd79807c08771da22.pdf EVALUATOR INPUT QUEUE M[X] SIDE EFFECTS Any concurrency type <=> type of evaluator Monad-like concurrency in Scala: - evaluate later in one thread …. - evaluate now in Execution Pool (Future) ….
  • 7. Why we represent concurrency in monads ? poor-mans concurrency….. - processes [CTSS ~ 1960] - isolated data, communication primitives provides by OS. - // Context switching and memory mapping is slow, let’s invent something more fine-grained
  • 8. Why we represent concurrency in monads ? poor-mans concurrency….. - processes [CTSS ~ 1960] - isolated data, communication primitives and scheduling provides by OS. - // Context switching and memory mapping is slow, let’s invent something more fine-grained - kernel threads [OS360Task ~ 1971, SunOS Threads ~ 1993] - shared data, communication primitives provided by library, scheduling - by OS. - // Context switching is slow, // Dealing with shared data is hard let’s invent something more fine-grained
  • 9. Why we represent concurrency in monads ? poor-mans concurrency….. - processes [CTSS ~ 1960] - isolated data, communication primitives and scheduling provides by OS. -// Context switching and memory mapping is slow, let’s invent something more fine-grained - kernel threads [OS360Task ~ 1971, SunOS Threads ~ 1993] - shared data, communication primitives provided by library, scheduling - by OS. - // Context switching is slow, // Dealing with shared data is hard let’s invent something more fine-grained - user-land threads, Fibers [JVM: Green Threads ~ 2000 , Loom ~ 2018 - 2020] - shared data, communication primitives and scheduling provided by library/runtime - // Dealing with shared data is hard // IO access with user scheduling is hard. let’s invent something more simple
  • 10. Why we represent concurrency in monads ? poor-mans concurrency….. - processes [CTSS ~ 1960] - isolated data, communication primitives and scheduling provides by OS. -// Context switching and memory mapping is slow, let’s invent something more fine-grained - kernel threads [OS360Task ~ 1971, SunOS Threads ~ 1993] - shared data, communication primitives provided by library, scheduling - by OS. - // Context switching is slow, // Dealing with shared data is hard let’s invent something more fine-grained - user-land threads, Fibers [JVM: Green Threads ~ 2000 , Loom ~ 2018 - 2020] - shared data, communication primitives and scheduling provided by library/runtime - // Dealing with shared data is hard // IO access with user scheduling is hard. let’s invent something more simple - Callback hell, [Node.js: ~ 2009 , Reactive manifesto ~ 2019] - shared data, communications primitives use callbacks to avoid scheduling. -
  • 11. User-level scheduling…. - Callback hell, - shared data, communications primitives use callbacks to avoid scheduling. - - Functional Programming (Monads), - communications primitives use hight-order functions instead callbacks - which was invented to avoid scheduling. - Concurrency Frameworks for Functional Programming, - let’s write generic functional scheduler for better organising of hight-order functions - which are here to avoid callbacks - which are here to avoid generic user-land scheduling - which are here to avoid thread context switching using OS scheduler - which are here to avoid process context switching using OS scheduler // Programming with callbacks is hard // Functional Programming is hard
  • 12. Let’s return to our monads…. M[X] Concurrency (different types) Distributed programming (thread-level, fibers, …. etc) Abstraction [free monad + interpreter] Unmonad: f : X ⇒ M[X] await[M] : M[X] → X async[M] : (f : (X ⇒ Y)) ⇒ (f′ : (X ⇒ M[Y])) await ⊏ f await /⊏ f′
  • 13. Let’s return to out monads…. Unmonad: await[M] : M[X] → X async[M] : (f : (X ⇒ Y)) ⇒ (f′ : (X ⇒ M[Y])) await /⊏ f′ async/await Possible solutions: lift/unlift runtime: (Project Loom, specific case of concurrency.) compile-time: (macros or compiler plugin) effectfully/! Idris bang notation reset/shift
  • 14. Let’s return to out monads…. Scala2 attempts: • Scala-continuations.   • http://infoscience.epfl.ch/record/149136/les/icfp113-rompf.pdf • Scala-async: •  https://github.com/scala/scala-async • Storm-enroute coroutines:  • http://storm-enroute.com/coroutines/ • https://drops.dagstuhl.de/opus/volltexte/2018/9208/pdf/LIPIcs-ECOOP-2018-3.pdf • Thoughtworks DSL.scala: • https://github.com/ThoughtWorksInc/Dsl.scala • Monadless.io:  • http://monadless.io/ • Effectfull: •  https://github.com/pelotom/effectful // different levels of usability, but all solutions are partial
  • 15. Main techniques for transformation: State Machine CPS Transform def f(x:Int) { val q = await(doSomething) val y = await(doOtherthing(x,q)) y + q } class f’ { val q val y var state = 0 def apply(x:Int) { state match { case 0 => state=1 doSomething.flatMap(r => {q=r; this(x)}) case 1 => state=2 doOtherthing(x,q).flatMap( r => { y=r; this(x) }) case 2 => monad.pure(y+q) } } State Machine
  • 16. Main techniques for transformation: State Machine CPS Transform def f(x:Int):Int { val q = await(doSomething) val y = await(doOtherthing(x,q)) y + q } def f’(x:Int, cont[A]: Int => CpsMonad[A]) { doSomething( r => val q = r doOtherthing(x,q, r => { val y = r cont(y + q) }) ) } CPS Transform
  • 17. Dotty / Scala3: • New • compile, syntax, macro system Let’s made ideal async transformer
  • 18. • Dotty-cps-async • https://github.com/rssh/dotty-cps-async • optimised monadic CPS transform. • any monad • (which implements needed facilities) • full language • (essential constructs) • higher-order functions • (need to implement helper typeclass)
  • 19. • optimised monadic CPS transform. def f(x:Int):Int { val q = await(doSomething) val y = await(doOtherthing(x,q)) y + q } def f’[F:AsyncMonad](x:Int):F[Int] { summon[F].flatMap(doSomething){ r => val q = r summon[F].map(doOtherthing(x,q)){r => val y = r y + q } } }
  • 20. • optimised monadic CPS transform • main constructions: • Constant expression: • Block(sequential composition) • sync, sync: • async, sync: • async, async: m.pure(x)x {x; y} m.pure({x; y}) {await[M](x); y} m.map(x)(_ => y) {await[M](x); await[M](y)} m.flatMap(x)(_ => y) //Number of maps ~~ Number of awaits…
  • 21. • Local values • sync expr, sync tail • async expr, async tail m.map(vx){ r => val x = r; y } {val x = vx; …} //unchanged.. {val x = await(vx); y}
  • 22. • Loops • l while( ) { } conditionasync bodyasync def whilefun() = { m.flatMap(condition){ c => if ( ) m.flatMap(body)(_ => whilefun()) else m.pure(()) } c
  • 25. What we need from monad ? def pure[T](t:T):F[T] def map[A,B](fa:F[A])(f: A=>B):F[B] def flatMap[A,B](fa:F[A])(f: A=>F[B]):F[B] for control flow def error[A](e: Throwable): F[A] def restore[A](fa: F[A])(fx:Throwable => F[A]): F[A] for try/catch def adoptCallbackStyle[A](source: (Try[A]=>Unit) => Unit):F[A] def spawn[A](op: =>F[A]): F[A] def fulfill[T](t:F[T], timeout: Duration): Option[Try[T]] for integration with other async monads ?
  • 26. Different monads in one expression: async[ ]{ … val x = await[ ](something) … } M1 M2 implicit def mc[A](x: [A]): [A]= …. M2 M1 Possible, if we have implicit conversion:
  • 27. Different monads in one expression: async[M]{ … val x = await[M](something) … } LoggedM: M ~> Logged[M] …. : async[Logged[M]]{ … val x = await[M](something) … } // now we can log context boundaries
  • 29. class ArrayOpsAsyncShift[A] extends AsyncShift[ArrayOps[A]] { def foreach[F[_],U](arrayOps: ArrayOps[A], monad: AsyncMonad[F])( f: A => F[U]): F[Unit] = { var r:F[Unit] = monad.pure(()) arrayOps.foreach{ a => val b = f(a) r = monad.flatMap(r)(_ => monad.map(b)(_ =>()) ) } r } ……. inline given shiftedArrayOps[A] as _ <: AsyncShift[ArrayOps[A]] = new cps.runtime.ArrayOpsAsyncShift[A]() Define implicit helper typeclass Implement ‘shiftedVersions’ of async
  • 30. Higher-order functions: • Shifted version for standard library • Provide guidelines for library authors. • Future: • In theory it’s possible to generate ‘shifter’ versions automatically • Dotty store a compiled AST for each method in .class . • Current limitations: • it is impossible to access one via compile-time reflection. • Third-order shifted lambda-functions • Possible to transform in-place • Hard to find real-wold example. • on practice: higher-order ~~ second-order • Application code: • usually have ‘monadic’ version as business logic.
  • 31. • Can we apply async/await on other monad ? Let’s await on space, instead await on time.
  • 32. • Knight tour problem: case class State( currentPoint: Point, board: Chessboard, trace: List[Point] ) def nextMoves(state: State):List[State] = ….. def findPath(initPos:Point, state: State): List[State] = async[List]{ val nextState = await(nextMoves(state)) if (board.isFull()) if (initPos == nextState.currentPoint) nextState else await(Nil) else await(findPath(initPos,nextState)) } // complex backtracking algorithm become simple.
  • 33. Current implementation: https://github.com/rssh/dotty-cps-async How can you help(?) - implement missing parts (it's still a lot of work) - provide a small examples - trying to use in own dotty experiments Thanks for attentions. // Ruslan Shevchenko <ruslan@shevchenko.kiev.ua> RobotsMom @rssh1 - twitter @rssh - github ScalaUA - 2020