Tidal icon indicating copy to clipboard operation
Tidal copied to clipboard

Binary distribution - next step?

Open yaxu opened this issue 3 years ago • 7 comments

Thanks to @polymorphicengine we have a tidal-listener building into a relocatable binary, great ! We should make use of this for the next tidal release.

We could distribute a ghci drop-in replacement. @jwaldmann already made this: https://github.com/jwaldmann/safe-tidal-cli . It looks good and is safe for exposing to untrusted users (e.g via flok), although doesn't support definitions with let.

Or we could skip that and prioritise editor support for the OSC API.

I quite like the idea of turning tidal-listener into a multi-function tidal engine, that can act like a ghci session, act as an OSC API over UDP, or run a web server serving up a codemirror based interface, depending on what parameters are given..

yaxu avatar Nov 07 '21 21:11 yaxu

turning tidal-listener into a multi-function tidal engine

sounds like a good idea!

polymorphicengine avatar Nov 07 '21 22:11 polymorphicengine

We could distribute a ghci drop-in replacement. @jwaldmann already made this: https://github.com/jwaldmann/safe-tidal-cli . It looks good and is safe for exposing to untrusted users (e.g via flok), although doesn't support definitions with let.

On feedforward I implemented a way to interpret haskell code thorough hint, and it supports let for sure, not sure about the other constructs. This functions gets tidal code and evaluate it, I use(d) it to load shortcuts into the interpreter, don't know if it can be usable in the tidal-listener context https://github.com/yaxu/feedforward/blob/master/src/TidalHint.hs#L68

ndr-brt avatar Nov 08 '21 08:11 ndr-brt

A note on this - currently tidal-listener restarts the interpreter when an exception is raised. I'm not sure when this happens, it shouldn't on a type error as the typeChecksWithDetails call should detect that before the code is interpreted. If/when it does happen though, any definitions would be lost.

yaxu avatar Nov 08 '21 08:11 yaxu

Well I guess if it type checks, there shouldn't be a problem with interpreting the code.

yaxu avatar Nov 08 '21 08:11 yaxu

Well I guess if it type checks, there shouldn't be a problem with interpreting the code.

As far as I know it does a lazy type-check. So in an expression like s "bd sn*" it would type check it to ControlPattern, even though the parser will fail to parse the expression and raise an exception.

polymorphicengine avatar Nov 08 '21 08:11 polymorphicengine

Ah yes I see. If I do this:

import Sound.OSC.FD as O
udp <- udpServer "127.0.0.1" 6012
r <- openUDP  "127.0.0.1" 6011
sendMessage r $ Message "/code" [string "hello", string "sound \"bd sn*\""]

The interpreter thread doesn't crash, but the whole of tidal-listener does! So the exception isn't raised in the interpreter (good) but later, when the parsec parser is invoked on the mininotation. So we want some exception handling elsewhere, probably similar to how Sound.Tidal.Stream works, where it catches an exception it returns to the previous pattern.

We should also try to make things as strict as possible so we can catch these errors before updating the pattern state. Just forcing the first cycle to be calculated would be fine.

Or we could probably do something fancy with template haskell, so that the parsec parsing is done during typechecking.

yaxu avatar Nov 08 '21 08:11 yaxu

Ah yes I see. If I do this:

import Sound.OSC.FD as O
udp <- udpServer "127.0.0.1" 6012
r <- openUDP  "127.0.0.1" 6011
sendMessage r $ Message "/code" [string "hello", string "sound \"bd sn*\""]

The interpreter thread doesn't crash, but the whole of tidal-listener does! So the exception isn't raised in the interpreter (which is what we want) but later, when the parsec parser is invoked on the mininotation. So we want some exception handling elsewhere, probably similar to how Sound.Tidal.Stream works, where it catches an exception it returns to the previous pattern.

We should also try to make things as strict as possible so we can catch these errors before updating the pattern state. Just forcing the first cycle to be calculated would be fine.

Or we could do probably something fancy with template haskell, so that the parsec parsing is done during typechecking.

yaxu avatar Nov 08 '21 08:11 yaxu