SlideShare a Scribd company logo
1 of 37
Download to read offline
Dataflow
The declarative concurrent
   programming model
Larry Diehl

  {:larrytheliquid =>
   %w[.com
        github
        twitter]}
Outline

Purpose of presentation



Gradual explanation of concepts



Helpful tips
Purpose
Lexical Scope


foo = :foo
define_method :foo do
 foo
end
Dynamic Scope

def foo
 @foo
end
Mutability

def initialize
 @foo = :foo
end

def foo
 @foo
end
Mutability


def foo
 @foo = :foo
 @foo
end
Mutability+Concurrency

def initialize
 Thread.new { loop { @foo = :shazbot } }
end

def foo
 @foo = :foo
 @foo
end
The Declarative Model
Declarative Synchronous


my_var = :bound
my_var = :rebind # NOT ALLOWED!
Declarative Synchronous


local do |my_var|
  my_var.object_id # thread sleeps
end
Declarative Synchronous


local do |my_var|
  unify my_var, :bound
  unify my_var, :rebind # =>
  # Dataflow::UnificationError,
  # ":bound != :rebind"
end
Declarative Synchronous

class MyClass
 declare :my_var
 def initialize
  unify my_var, :bound
 end
end
Declarative Concurrent
     (MAGIC)
Declarative Concurrent


local do |my_var|
  Thread.new { unify my_var, :bound }
  my_var.should == :bound
end
Dependency Resolution

local do |sentence, middle, tail|
  Thread.new { unify middle, "base are belong #{tail}" }
  Thread.new { unify tail, "to us" }
  Thread.new { unify sentence, "all your #{middle}" }
  sentence.should == "all your base are belong to us"
end
Asynchronous Output
def Worker.async(output=nil)
 Thread.new do
  result = # do hard work
  unify output, result if output
 end
end

local do |output|
  Worker.async(output)
  output.should == # hard work result
end
Asynchronous Output
local do |output|
  flow(output) do
    # do hard work
  end
  output.should == # hard work result
end
Anonymous variables

{'google.com' => Dataflow::Variable.new,
 'bing.com' => Dataflow::Variable.new
}.map do |domain,var|
  Thread.new do
   unify var, open("http://#{domain}").read
  end
  var
end
need_later

%w[google.com bing.com].map do |domain|
 need_later { open("http://#{domain}").read }
end
Chunked Sequential Processing


 (1..100).each_slice(10).map do |chunk|
  sleep(1)
  chunk.inject(&:+)
 end.inject(&:+) # => ~10s
Chunked Parallel Processing


(1..100).each_slice(10).map do |chunk|
 need_later do
   sleep(1)
   chunk.inject(&:+)
 end
end.inject(&:+) # => ~1s
Leaving Declarative
    via Async
Ports & Streams

local do |port, stream|
  unify port, Dataflow::Port.new(stream)
  port.send 1
  port.send 2
  stream.take(2).should == [1, 2]
end
Ports & Streams (async)
local do |port, stream|
  unify port, Dataflow::Port.new(stream)
  Thread.new do
   stream.each do |message|
     puts "received: #{message}"
   end
  end
  %w[x y z].each do |letter|
    Thread.new{ port.send letter }
   end
  stream.take(3).sort.should == %w[x y z]
end
FutureQueue
local do |queue, first, second, third|
  unify queue, FutureQueue.new
  queue.pop first
  queue.pop second
  queue.push 1
  queue.push 2
  queue.push 3
  queue.pop third
  [first, second, third].should == [1, 2, 3]
end
Actors
Ping = Actor.new {                  Pong = Actor.new {
  3.times {                           3.times {
    case receive                        case receive
    when :ping                          when :pong
     puts "Ping"                         puts "Pong"
     Pong.send :pong                     Ping.send :ping
    end                                 end
  }                                   }
}                                   }



                  Ping.send :ping
by_need

def baz(num)
 might_get_used = by_need { Factory.gen }
 might_get_used.value if num%2 == 0
end
Tips
Modular

local do |my_var|
  Thread.new { unify my_var, :bound }
  # my_var.wait
  my_var.should == :bound
end
Debugging

local do |my_var|
  my_var.inspect
# => #<Dataflow::Variable:2637860 unbound>
end
Class/Module methods
Dataflow.local do |my_var|
 Dataflow.async do
  Dataflow.unify my_var, :bound
 end
 my_var.should == :bound
end
Use Cases
general purpose
   concurrency for elegant program structure with respect
   to coordination

   concurrency to make use of extra processors/cores
   (depending on Ruby implementation)

web development
  worker daemons

   concurrently munging together data from various rest
   api's
Ruby Implementations

Pure Ruby library, should work on any implementation


JRuby in particular has a great GC, no GIL, native threads,
and a tunable threadpool option.


Rubinius has more code written in Ruby, so it proxies more
method calls (e.g. Array#flatten).
class FutureQueue
 include Dataflow
 declare :push_port, :pop_port

 def initialize
  local do |pushed, popped|
    unify push_port, Dataflow::Port.new(pushed)
    unify pop_port, Dataflow::Port.new(popped)

   Thread.new {
     loop do
      barrier pushed.head, popped.head
      unify popped.head, pushed.head
      pushed, popped = pushed.tail, popped.tail
     end
   }
  end
 end

 def push(x) push_port.send x end
 def pop(x) pop_port.send x end
end
The End
sudo port install dataflow



   http://github.com
   /larrytheliquid
   /dataflow


freenode: #dataflow-gem

More Related Content

What's hot

Echtzeitapplikationen mit Elixir und GraphQL
Echtzeitapplikationen mit Elixir und GraphQLEchtzeitapplikationen mit Elixir und GraphQL
Echtzeitapplikationen mit Elixir und GraphQLMoritz Flucht
 
Concurrency in go
Concurrency in goConcurrency in go
Concurrency in goborderj
 
Real World Optimization
Real World OptimizationReal World Optimization
Real World OptimizationDavid Golden
 
Introduction to asynchronous DB access using Node.js and MongoDB
Introduction to asynchronous DB access using Node.js and MongoDBIntroduction to asynchronous DB access using Node.js and MongoDB
Introduction to asynchronous DB access using Node.js and MongoDBAdrien Joly
 
ECMAScript 6 and the Node Driver
ECMAScript 6 and the Node DriverECMAScript 6 and the Node Driver
ECMAScript 6 and the Node DriverMongoDB
 
Inheritance compiler support
Inheritance compiler supportInheritance compiler support
Inheritance compiler supportSyed Zaid Irshad
 
Hacking Go Compiler Internals / GoCon 2014 Autumn
Hacking Go Compiler Internals / GoCon 2014 AutumnHacking Go Compiler Internals / GoCon 2014 Autumn
Hacking Go Compiler Internals / GoCon 2014 AutumnMoriyoshi Koizumi
 
Dash Profiler 200910
Dash Profiler 200910Dash Profiler 200910
Dash Profiler 200910HighLoad2009
 
Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of GoFrank Müller
 
Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...
Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...
Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...andreaslubbe
 
Use of django at jolt online v3
Use of django at jolt online v3Use of django at jolt online v3
Use of django at jolt online v3Jaime Buelta
 
Simple Tips and Tricks with Ansible
Simple Tips and Tricks with AnsibleSimple Tips and Tricks with Ansible
Simple Tips and Tricks with AnsibleKeith Resar
 

What's hot (20)

Ruby 1.9
Ruby 1.9Ruby 1.9
Ruby 1.9
 
Internet of dusty things
Internet of dusty thingsInternet of dusty things
Internet of dusty things
 
Echtzeitapplikationen mit Elixir und GraphQL
Echtzeitapplikationen mit Elixir und GraphQLEchtzeitapplikationen mit Elixir und GraphQL
Echtzeitapplikationen mit Elixir und GraphQL
 
node ffi
node ffinode ffi
node ffi
 
Concurrency in go
Concurrency in goConcurrency in go
Concurrency in go
 
The low level awesomeness of Go
The low level awesomeness of GoThe low level awesomeness of Go
The low level awesomeness of Go
 
Real World Optimization
Real World OptimizationReal World Optimization
Real World Optimization
 
Introduction to asynchronous DB access using Node.js and MongoDB
Introduction to asynchronous DB access using Node.js and MongoDBIntroduction to asynchronous DB access using Node.js and MongoDB
Introduction to asynchronous DB access using Node.js and MongoDB
 
ECMAScript 6 and the Node Driver
ECMAScript 6 and the Node DriverECMAScript 6 and the Node Driver
ECMAScript 6 and the Node Driver
 
Donetsk.py - fabric
Donetsk.py -  fabricDonetsk.py -  fabric
Donetsk.py - fabric
 
Docopt
DocoptDocopt
Docopt
 
Inheritance compiler support
Inheritance compiler supportInheritance compiler support
Inheritance compiler support
 
Hacking Go Compiler Internals / GoCon 2014 Autumn
Hacking Go Compiler Internals / GoCon 2014 AutumnHacking Go Compiler Internals / GoCon 2014 Autumn
Hacking Go Compiler Internals / GoCon 2014 Autumn
 
Dash Profiler 200910
Dash Profiler 200910Dash Profiler 200910
Dash Profiler 200910
 
Ansible 202 - sysarmy
Ansible 202 - sysarmyAnsible 202 - sysarmy
Ansible 202 - sysarmy
 
Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of Go
 
Python Programming Essentials - M8 - String Methods
Python Programming Essentials - M8 - String MethodsPython Programming Essentials - M8 - String Methods
Python Programming Essentials - M8 - String Methods
 
Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...
Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...
Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...
 
Use of django at jolt online v3
Use of django at jolt online v3Use of django at jolt online v3
Use of django at jolt online v3
 
Simple Tips and Tricks with Ansible
Simple Tips and Tricks with AnsibleSimple Tips and Tricks with Ansible
Simple Tips and Tricks with Ansible
 

Similar to Dataflow: Declarative concurrency in Ruby

Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011Torquebox OSCON Java 2011
Torquebox OSCON Java 2011tobiascrawley
 
Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013
Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013
Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013Puppet
 
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code styleRuby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code styleAnton Shemerey
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slidesharetomcopeland
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)tarcieri
 
Incredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and GeneratorsIncredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and Generatorsdantleech
 
Douglas Crockford: Serversideness
Douglas Crockford: ServersidenessDouglas Crockford: Serversideness
Douglas Crockford: ServersidenessWebExpo
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 
name name2 n2
name name2 n2name name2 n2
name name2 n2callroom
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 

Similar to Dataflow: Declarative concurrency in Ruby (20)

Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
 
Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013
Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013
Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013
 
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code styleRuby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshare
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)
 
Tres Gemas De Ruby
Tres Gemas De RubyTres Gemas De Ruby
Tres Gemas De Ruby
 
Incredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and GeneratorsIncredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and Generators
 
Douglas Crockford: Serversideness
Douglas Crockford: ServersidenessDouglas Crockford: Serversideness
Douglas Crockford: Serversideness
 
ppt7
ppt7ppt7
ppt7
 
ppt2
ppt2ppt2
ppt2
 
name name2 n
name name2 nname name2 n
name name2 n
 
name name2 n2
name name2 n2name name2 n2
name name2 n2
 
test ppt
test ppttest ppt
test ppt
 
name name2 n
name name2 nname name2 n
name name2 n
 
ppt21
ppt21ppt21
ppt21
 
name name2 n
name name2 nname name2 n
name name2 n
 
ppt17
ppt17ppt17
ppt17
 
ppt30
ppt30ppt30
ppt30
 

Recently uploaded

GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 

Recently uploaded (20)

GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 

Dataflow: Declarative concurrency in Ruby