Rhine - FRP with type level clocks A tea tutorial Manuel Brenz 15. - - PowerPoint PPT Presentation

rhine frp with type level clocks
SMART_READER_LITE
LIVE PREVIEW

Rhine - FRP with type level clocks A tea tutorial Manuel Brenz 15. - - PowerPoint PPT Presentation

Setup Quick introduction to Rhine Lets hack! After the tutorial Rhine - FRP with type level clocks A tea tutorial Manuel Brenz 15. Januar 2020 Setup Quick introduction to Rhine Lets hack! After the tutorial cabal update git


slide-1
SLIDE 1

Setup Quick introduction to Rhine Let’s hack! After the tutorial

Rhine - FRP with type level clocks

A tea tutorial Manuel Bärenz

  • 15. Januar 2020
slide-2
SLIDE 2

Setup Quick introduction to Rhine Let’s hack! After the tutorial

cabal update git clone https://github.com/turion/rhine-tutorial/ cd rhine-tutorial cabal sandbox init cabal install --only-dependencies cabal configure cabal build cabal run rhine-tutorial Read documentation on http://hackage.haskell.org/package/rhine (version 0.1.0.0)!

slide-3
SLIDE 3

Setup Quick introduction to Rhine Let’s hack! After the tutorial Synchronous arrowized FRP

Dunai (Iván Pérez, Henrik Nilsson, MB)

data MSF m a b = MSF (a -> m (b, MSF m a b))

slide-4
SLIDE 4

Setup Quick introduction to Rhine Let’s hack! After the tutorial Synchronous arrowized FRP

Dunai (Iván Pérez, Henrik Nilsson, MB)

data MSF m a b = MSF (a -> m (b, MSF m a b))

  • - Control.Arrow

(>>>) :: MSF m a b -> MSF m b c -> MSF m a c (***) :: MSF m a b -> MSF m c d -> MSF m (a,c) (b,d) arr :: (a -> b) -> MSF m a b

slide-5
SLIDE 5

Setup Quick introduction to Rhine Let’s hack! After the tutorial Synchronous arrowized FRP

Dunai (Iván Pérez, Henrik Nilsson, MB)

data MSF m a b = MSF (a -> m (b, MSF m a b))

  • - Control.Arrow

(>>>) :: MSF m a b -> MSF m b c -> MSF m a c (***) :: MSF m a b -> MSF m c d -> MSF m (a,c) (b,d) arr :: (a -> b) -> MSF m a b

  • - only dunai

arrM :: (a -> m b) -> MSF m a b

slide-6
SLIDE 6

Setup Quick introduction to Rhine Let’s hack! After the tutorial Synchronous arrowized FRP

Dunai (Iván Pérez, Henrik Nilsson, MB)

data MSF m a b = MSF (a -> m (b, MSF m a b))

  • - Control.Arrow

(>>>) :: MSF m a b -> MSF m b c -> MSF m a c (***) :: MSF m a b -> MSF m c d -> MSF m (a,c) (b,d) arr :: (a -> b) -> MSF m a b

  • - only dunai

arrM :: (a -> m b) -> MSF m a b MSF (Reader Double) is a replacement for FRP.Yampa.SF.

slide-7
SLIDE 7

Setup Quick introduction to Rhine Let’s hack! After the tutorial Synchronous arrowized FRP

Dunai (Iván Pérez, Henrik Nilsson, MB)

data MSF m a b = MSF (a -> m (b, MSF m a b))

  • - Control.Arrow

(>>>) :: MSF m a b -> MSF m b c -> MSF m a c (***) :: MSF m a b -> MSF m c d -> MSF m (a,c) (b,d) arr :: (a -> b) -> MSF m a b

  • - only dunai

arrM :: (a -> m b) -> MSF m a b MSF (Reader Double) is a replacement for FRP.Yampa.SF. Other monads allow for concise FRP paradigms:

slide-8
SLIDE 8

Setup Quick introduction to Rhine Let’s hack! After the tutorial Synchronous arrowized FRP

Dunai (Iván Pérez, Henrik Nilsson, MB)

data MSF m a b = MSF (a -> m (b, MSF m a b))

  • - Control.Arrow

(>>>) :: MSF m a b -> MSF m b c -> MSF m a c (***) :: MSF m a b -> MSF m c d -> MSF m (a,c) (b,d) arr :: (a -> b) -> MSF m a b

  • - only dunai

arrM :: (a -> m b) -> MSF m a b MSF (Reader Double) is a replacement for FRP.Yampa.SF. Other monads allow for concise FRP paradigms:

State, Reader and Writer give global state variables.

slide-9
SLIDE 9

Setup Quick introduction to Rhine Let’s hack! After the tutorial Synchronous arrowized FRP

Dunai (Iván Pérez, Henrik Nilsson, MB)

data MSF m a b = MSF (a -> m (b, MSF m a b))

  • - Control.Arrow

(>>>) :: MSF m a b -> MSF m b c -> MSF m a c (***) :: MSF m a b -> MSF m c d -> MSF m (a,c) (b,d) arr :: (a -> b) -> MSF m a b

  • - only dunai

arrM :: (a -> m b) -> MSF m a b MSF (Reader Double) is a replacement for FRP.Yampa.SF. Other monads allow for concise FRP paradigms:

State, Reader and Writer give global state variables. List gives branching computations.

slide-10
SLIDE 10

Setup Quick introduction to Rhine Let’s hack! After the tutorial Synchronous arrowized FRP

Dunai (Iván Pérez, Henrik Nilsson, MB)

data MSF m a b = MSF (a -> m (b, MSF m a b))

  • - Control.Arrow

(>>>) :: MSF m a b -> MSF m b c -> MSF m a c (***) :: MSF m a b -> MSF m c d -> MSF m (a,c) (b,d) arr :: (a -> b) -> MSF m a b

  • - only dunai

arrM :: (a -> m b) -> MSF m a b MSF (Reader Double) is a replacement for FRP.Yampa.SF. Other monads allow for concise FRP paradigms:

State, Reader and Writer give global state variables. List gives branching computations. Either gives control flow!

slide-11
SLIDE 11

Setup Quick introduction to Rhine Let’s hack! After the tutorial Synchronous arrowized FRP

Dunai (Iván Pérez, Henrik Nilsson, MB)

data MSF m a b = MSF (a -> m (b, MSF m a b))

  • - Control.Arrow

(>>>) :: MSF m a b -> MSF m b c -> MSF m a c (***) :: MSF m a b -> MSF m c d -> MSF m (a,c) (b,d) arr :: (a -> b) -> MSF m a b

  • - only dunai

arrM :: (a -> m b) -> MSF m a b MSF (Reader Double) is a replacement for FRP.Yampa.SF. Other monads allow for concise FRP paradigms:

State, Reader and Writer give global state variables. List gives branching computations. Either gives control flow!

Support for (entering and leaving) monad transformers.

slide-12
SLIDE 12

Setup Quick introduction to Rhine Let’s hack! After the tutorial Synchronous arrowized FRP

Arrow syntax

{-# LANGUAGE Arrows #-} verboseSum :: MSF IO Int Int verboseSum = proc n -> do s <- sumS

  • < n

_ <- arrM print -< "The sum is now " ++ show s returnA

  • < s
slide-13
SLIDE 13

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

Clock type All relevant properties of the clock, such as ...

slide-14
SLIDE 14

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

Clock type All relevant properties of the clock, such as ... When, and how often, the clock should tick

slide-15
SLIDE 15

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

Clock type All relevant properties of the clock, such as ... When, and how often, the clock should tick Which monad the clock takes side effects in

slide-16
SLIDE 16

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

Clock type All relevant properties of the clock, such as ... When, and how often, the clock should tick Which monad the clock takes side effects in What additional data (besides a time stamp) the clock outputs

slide-17
SLIDE 17

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

Clock type All relevant properties of the clock, such as ... When, and how often, the clock should tick Which monad the clock takes side effects in What additional data (besides a time stamp) the clock outputs Clock value All information needed to run the clock

slide-18
SLIDE 18

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

Clock type All relevant properties of the clock, such as ... When, and how often, the clock should tick Which monad the clock takes side effects in What additional data (besides a time stamp) the clock outputs Clock value All information needed to run the clock E.g. physical device address, event socket

slide-19
SLIDE 19

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

Clock type All relevant properties of the clock, such as ... When, and how often, the clock should tick Which monad the clock takes side effects in What additional data (besides a time stamp) the clock outputs Clock value All information needed to run the clock E.g. physical device address, event socket Implementation choice

slide-20
SLIDE 20

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

Clock type All relevant properties of the clock, such as ... When, and how often, the clock should tick Which monad the clock takes side effects in What additional data (besides a time stamp) the clock outputs Clock value All information needed to run the clock E.g. physical device address, event socket Implementation choice Running clock Side-effectful stream of time stamps, tagged with additional info about the tick.

slide-21
SLIDE 21

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

Rhine

  • - simplified here

class Clock m cl where type Time cl -- time stamp type Tag cl -- additional information about tick initClock :: cl -> MSF m () (TimeInfo cl, Tag cl)

slide-22
SLIDE 22

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

Rhine

  • - simplified here

class Clock m cl where type Time cl -- time stamp type Tag cl -- additional information about tick initClock :: cl -> MSF m () (TimeInfo cl, Tag cl) data TimeInfo cl = {...}

  • - absolute and relative time, tag
slide-23
SLIDE 23

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

A clock produces side effects to... ... wait between ticks, ... measure the current time, ... produce additional data (e.g. events).

slide-24
SLIDE 24

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

A clock produces side effects to... ... wait between ticks, ... measure the current time, ... produce additional data (e.g. events).

Examples of clocks

Fixed sample rate (e.g. Millisecond n) Events (e.g. Stdin)

slide-25
SLIDE 25

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

type ClSF m cl a b = MSF (ReaderT (TimeInfo cl) m) a b

slide-26
SLIDE 26

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

type ClSF m cl a b = MSF (ReaderT (TimeInfo cl) m) a b

Lifting dunai concepts

arrMCl :: (a -> m b) -> SyncSF m cl a b ...

slide-27
SLIDE 27

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

type ClSF m cl a b = MSF (ReaderT (TimeInfo cl) m) a b

Lifting dunai concepts

arrMCl :: (a -> m b) -> SyncSF m cl a b ...

Time information

timeInfo :: ClSF m cl () (TimeInfo cl)

slide-28
SLIDE 28

Setup Quick introduction to Rhine Let’s hack! After the tutorial Clocks

type ClSF m cl a b = MSF (ReaderT (TimeInfo cl) m) a b

Lifting dunai concepts

arrMCl :: (a -> m b) -> SyncSF m cl a b ...

Time information

timeInfo :: ClSF m cl () (TimeInfo cl)

Basic signal processing

integral :: VectorSpace v => ClSF m cl v v ...

slide-29
SLIDE 29

Setup Quick introduction to Rhine Let’s hack! After the tutorial Exceptions and control flow

ExceptT...

data Either e a = Left e | Right a newtype ExceptT e m a = ExceptT (m (Either e a))

slide-30
SLIDE 30

Setup Quick introduction to Rhine Let’s hack! After the tutorial Exceptions and control flow

ExceptT...

data Either e a = Left e | Right a newtype ExceptT e m a = ExceptT (m (Either e a))

...control flow! (Thanks to Paolo Capriotti)

  • - dunai, rhine (simplified)

newtype ClSFExcept m cl a b e = ClSFExcept (SyncSF (ExceptT e m) cl a b)

slide-31
SLIDE 31

Setup Quick introduction to Rhine Let’s hack! After the tutorial Exceptions and control flow

ExceptT...

data Either e a = Left e | Right a newtype ExceptT e m a = ExceptT (m (Either e a))

...control flow! (Thanks to Paolo Capriotti)

  • - dunai, rhine (simplified)

newtype ClSFExcept m cl a b e = ClSFExcept (SyncSF (ExceptT e m) cl a b) instance Monad m => Monad (ClSFExcept m cl a b) throwOn' :: ClSF (ExceptT e m) cl (Bool, e) () try :: ClSF (ExceptT e m) cl a b

  • > ClSFExcept m cl a b e

safely :: ClSFExcept m cl a b Empty -> SyncSF m cl a b safe :: ClSF m cl a b -> SyncExcept m cl a b e

slide-32
SLIDE 32

Setup Quick introduction to Rhine Let’s hack! After the tutorial Exceptions and control flow

Hello World!

type SumClock = Millisecond 100 fillUp :: ClSF (ExceptT Double m) SumClock Double () fillUp = proc x -> do s <- integral -< x _ <- throwOn' -< (s > 5, s) returnA

  • < ()

helloWorld :: ClSFExcept IO SumClock () () Empty helloWorld = do try $ arr (const 1) >>> fillUp

  • nce_ $ putStrLn "Hello World!"

helloWorld main = flow $ safely helloWorld @@ waitClock

slide-33
SLIDE 33

Setup Quick introduction to Rhine Let’s hack! After the tutorial Exceptions and control flow

Clock safety

fastSignal :: ClSF m FastClock () a slowProcessor :: ClSF m SlowClock a b clockTypeError = fastSignal >>> slowProcessor PresentationExamples.hs:67:33: error:

  • Couldn't match type ‘SlowClock’ with ‘FastClock’
slide-34
SLIDE 34

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data Schedule m cl1 cl2

slide-35
SLIDE 35

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data Schedule m cl1 cl2

Binary schedules

Execute two different clocks simultaneously.

slide-36
SLIDE 36

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data Schedule m cl1 cl2

Binary schedules

Execute two different clocks simultaneously. Can be clock-polymorphic or specific to certain clocks.

slide-37
SLIDE 37

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data Schedule m cl1 cl2

Binary schedules

Execute two different clocks simultaneously. Can be clock-polymorphic or specific to certain clocks. (No implementation details here.)

slide-38
SLIDE 38

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data Schedule m cl1 cl2

Binary schedules

Execute two different clocks simultaneously. Can be clock-polymorphic or specific to certain clocks. (No implementation details here.) Some examples:

slide-39
SLIDE 39

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data Schedule m cl1 cl2

Binary schedules

Execute two different clocks simultaneously. Can be clock-polymorphic or specific to certain clocks. (No implementation details here.) Some examples:

concurrently :: Schedule IO cl1 cl2

slide-40
SLIDE 40

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data Schedule m cl1 cl2

Binary schedules

Execute two different clocks simultaneously. Can be clock-polymorphic or specific to certain clocks. (No implementation details here.) Some examples:

concurrently :: Schedule IO cl1 cl2 schedule :: Schedule (ScheduleT m) cl1 cl2

slide-41
SLIDE 41

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data ResamplingBuffer m cla clb a b = ResamplingBuffer { put :: TimeInfo cla -> a

  • > m (

ResamplingBuffer m cla clb a b) , get :: TimeInfo clb

  • > m (b, ResamplingBuffer m cla clb a b)

}

slide-42
SLIDE 42

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data ResamplingBuffer m cla clb a b = ResamplingBuffer { put :: TimeInfo cla -> a

  • > m (

ResamplingBuffer m cla clb a b) , get :: TimeInfo clb

  • > m (b, ResamplingBuffer m cla clb a b)

}

Resampling buffers

Buffer data at the boundary between two asynchronous systems.

slide-43
SLIDE 43

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data ResamplingBuffer m cla clb a b = ResamplingBuffer { put :: TimeInfo cla -> a

  • > m (

ResamplingBuffer m cla clb a b) , get :: TimeInfo clb

  • > m (b, ResamplingBuffer m cla clb a b)

}

Resampling buffers

Buffer data at the boundary between two asynchronous systems. Can be clock-polymorphic or specific to certain clocks.

slide-44
SLIDE 44

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data ResamplingBuffer m cla clb a b = ResamplingBuffer { put :: TimeInfo cla -> a

  • > m (

ResamplingBuffer m cla clb a b) , get :: TimeInfo clb

  • > m (b, ResamplingBuffer m cla clb a b)

}

Resampling buffers

Buffer data at the boundary between two asynchronous systems. Can be clock-polymorphic or specific to certain clocks. Some examples

slide-45
SLIDE 45

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data ResamplingBuffer m cla clb a b = ResamplingBuffer { put :: TimeInfo cla -> a

  • > m (

ResamplingBuffer m cla clb a b) , get :: TimeInfo clb

  • > m (b, ResamplingBuffer m cla clb a b)

}

Resampling buffers

Buffer data at the boundary between two asynchronous systems. Can be clock-polymorphic or specific to certain clocks. Some examples

collect :: ResamplingBuffer m cl1 cl2 a [a]

slide-46
SLIDE 46

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data ResamplingBuffer m cla clb a b = ResamplingBuffer { put :: TimeInfo cla -> a

  • > m (

ResamplingBuffer m cla clb a b) , get :: TimeInfo clb

  • > m (b, ResamplingBuffer m cla clb a b)

}

Resampling buffers

Buffer data at the boundary between two asynchronous systems. Can be clock-polymorphic or specific to certain clocks. Some examples

collect :: ResamplingBuffer m cl1 cl2 a [a] fifo :: ResamplingBuffer m cl1 cl2 a (Maybe a)

slide-47
SLIDE 47

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data ResamplingBuffer m cla clb a b = ResamplingBuffer { put :: TimeInfo cla -> a

  • > m (

ResamplingBuffer m cla clb a b) , get :: TimeInfo clb

  • > m (b, ResamplingBuffer m cla clb a b)

}

Resampling buffers

Buffer data at the boundary between two asynchronous systems. Can be clock-polymorphic or specific to certain clocks. Some examples

collect :: ResamplingBuffer m cl1 cl2 a [a] fifo :: ResamplingBuffer m cl1 cl2 a (Maybe a) keepLast :: a -> ResamplingBuffer m cl1 cl2 a a

slide-48
SLIDE 48

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

data ResamplingBuffer m cla clb a b = ResamplingBuffer { put :: TimeInfo cla -> a

  • > m (

ResamplingBuffer m cla clb a b) , get :: TimeInfo clb

  • > m (b, ResamplingBuffer m cla clb a b)

}

Resampling buffers

Buffer data at the boundary between two asynchronous systems. Can be clock-polymorphic or specific to certain clocks. Some examples

collect :: ResamplingBuffer m cl1 cl2 a [a] fifo :: ResamplingBuffer m cl1 cl2 a (Maybe a) keepLast :: a -> ResamplingBuffer m cl1 cl2 a a Linear interpolation, combinators to build your own. . .

slide-49
SLIDE 49

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

Asynchronous signal functions

data SN m cl a b -- Signal network type family In cl type family Out cl

slide-50
SLIDE 50

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

Asynchronous signal functions

data SN m cl a b -- Signal network type family In cl type family Out cl

A clocked reactive program

data Rhine m cl a b (...basically an SF and a matching clock!)

slide-51
SLIDE 51

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

Asynchronous signal functions

data SN m cl a b -- Signal network type family In cl type family Out cl

A clocked reactive program

data Rhine m cl a b (...basically an SF and a matching clock!)

Execution (reactimation)

flow :: Rhine m cl () () -> m ()

slide-52
SLIDE 52

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

Synchronous subsystems

cl :: MyClock sf :: ClSF m MyClock A B rhineCl :: Rhine m MyClock A B rhineCl = sf @@ cl

slide-53
SLIDE 53

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

Parallel composition

clL :: MyClockL clR :: MyClockR sfL :: ClSF m MyClockL C D sfR :: ClSF m MyClockR C D schedPar :: Schedule m MyClockL MyClockR rhinePar = sfL @@ clL **@ schedPar @** syncsfR @@ clR

slide-54
SLIDE 54

Setup Quick introduction to Rhine Let’s hack! After the tutorial Asynchronous FRP

Parallel composition

clL :: MyClockL clR :: MyClockR sfL :: ClSF m MyClockL C D sfR :: ClSF m MyClockR C D schedPar :: Schedule m MyClockL MyClockR rhinePar = sfL @@ clL **@ schedPar @** syncsfR @@ clR

Sequential composition

buf :: ResamplingBuffer m MyClock (In (..)) B C schedSeq :: Schedule m ... rhineSeq = rhineCl >-- buf -@- schedSeq --> rhineP

slide-55
SLIDE 55

Setup Quick introduction to Rhine Let’s hack! After the tutorial

The plan: A tea app

Run several tea timers in parallel Reactively read tea requests from the console

slide-56
SLIDE 56

Setup Quick introduction to Rhine Let’s hack! After the tutorial

The plan: A tea app

Run several tea timers in parallel Reactively read tea requests from the console Any questions before we start hacking?

slide-57
SLIDE 57

Setup Quick introduction to Rhine Let’s hack! After the tutorial

Have fun!

slide-58
SLIDE 58

Setup Quick introduction to Rhine Let’s hack! After the tutorial What Rhine can do

What else you could (easily) do with Dunai and Rhine

Simple arcade games (SDL, Gloss) Reactive console apps

slide-59
SLIDE 59

Setup Quick introduction to Rhine Let’s hack! After the tutorial What Rhine can do

What else you could (easily) do with Dunai and Rhine

Simple arcade games (SDL, Gloss) Reactive console apps

What should be doable, but I didn’t do yet because of lazyness

Webservers, server-side web apps Interactive File I/O GUI programs External devices (e.g. Kinect, Wiimote)

slide-60
SLIDE 60

Setup Quick introduction to Rhine Let’s hack! After the tutorial What Rhine can do

What else you could (easily) do with Dunai and Rhine

Simple arcade games (SDL, Gloss) Reactive console apps

What should be doable, but I didn’t do yet because of lazyness

Webservers, server-side web apps Interactive File I/O GUI programs External devices (e.g. Kinect, Wiimote)

What might eventually be feasible

Reactive audio synthesis, processing and analysis (performance...) Reactive web apps (GHCJS...) Android, embedded systems (recent GHC...)

slide-61
SLIDE 61

Setup Quick introduction to Rhine Let’s hack! After the tutorial Comparison to other frameworks

Framework Pro Rhine Contra Rhine Yampa, dunai Asynchronicity, clock types Performance Pipes, conduit FRP, clocks Performance? Most classical FRP frame- works No IO built in, clock types ? CλaSH General purpose No compilation to cir- cuits

slide-62
SLIDE 62

Setup Quick introduction to Rhine Let’s hack! After the tutorial More information

Dunai

slide-63
SLIDE 63

Setup Quick introduction to Rhine Let’s hack! After the tutorial More information

Dunai

github.com/ivanperez-keera/dunai

slide-64
SLIDE 64

Setup Quick introduction to Rhine Let’s hack! After the tutorial More information

Dunai

github.com/ivanperez-keera/dunai There’s a link to the article!

slide-65
SLIDE 65

Setup Quick introduction to Rhine Let’s hack! After the tutorial More information

Dunai

github.com/ivanperez-keera/dunai There’s a link to the article!

Rhine

slide-66
SLIDE 66

Setup Quick introduction to Rhine Let’s hack! After the tutorial More information

Dunai

github.com/ivanperez-keera/dunai There’s a link to the article!

Rhine

Article: github.com/turion/rhine#documentation

slide-67
SLIDE 67

Setup Quick introduction to Rhine Let’s hack! After the tutorial More information

Dunai

github.com/ivanperez-keera/dunai There’s a link to the article!

Rhine

Article: github.com/turion/rhine#documentation This tutorial: github.com/turion/rhine-tutorial/

slide-68
SLIDE 68

Setup Quick introduction to Rhine Let’s hack! After the tutorial More information

Dunai

github.com/ivanperez-keera/dunai There’s a link to the article!

Rhine

Article: github.com/turion/rhine#documentation This tutorial: github.com/turion/rhine-tutorial/ Checkout branch final for solutions

slide-69
SLIDE 69

Setup Quick introduction to Rhine Let’s hack! After the tutorial More information

Dunai

github.com/ivanperez-keera/dunai There’s a link to the article!

Rhine

Article: github.com/turion/rhine#documentation This tutorial: github.com/turion/rhine-tutorial/ Checkout branch final for solutions Documentation on hackage

slide-70
SLIDE 70

Setup Quick introduction to Rhine Let’s hack! After the tutorial More information

Dunai

github.com/ivanperez-keera/dunai There’s a link to the article!

Rhine

Article: github.com/turion/rhine#documentation This tutorial: github.com/turion/rhine-tutorial/ Checkout branch final for solutions Documentation on hackage Simple examples in github.com/turion/rhine/

slide-71
SLIDE 71

Setup Quick introduction to Rhine Let’s hack! After the tutorial What you can do

Use Rhine at the hackathon and win a nice bar of chocolate!

slide-72
SLIDE 72

Setup Quick introduction to Rhine Let’s hack! After the tutorial What you can do

Use Rhine at the hackathon and win a nice bar of chocolate! Create issues on github.com/turion/rhine/ and ask for your most needed clocks, schedules, resampling buffers etc.!

slide-73
SLIDE 73

Setup Quick introduction to Rhine Let’s hack! After the tutorial What you can do

Use Rhine at the hackathon and win a nice bar of chocolate! Create issues on github.com/turion/rhine/ and ask for your most needed clocks, schedules, resampling buffers etc.! Look at easy to solve issues on github.com/ivanperez-keera/dunai!