Before starting the big work of porting my experimental #LiveCoding #uzulang #godwit 's #parser from #Alex and #Happy to #Parsec, I finally managed to get a snapshot working in #Termux on my phone by making a tarball including the generated #Haskell files on a machine where Alex and Happy were available and transferring it over network.
This isn't ideal as I can't edit the parser on my phone (no Alex/Happy there; at least not recent enough versions, old ones got via cjacker's Hugs 2019 improvement), so I still want to switch to Parsec which is not so horribly #GHC -only (Parsec has a version that works with #MicroHs and probably #Hugs #HaskellHugs too).
I put the snapshot at
https://mathr.co.uk/web/godwit.html#Download and meanwhile updated the bootstrap script as patching MicroHs isn't necessary any more.
switched from #Android app #UserLAnd to #Termux due to the promise of working sound via #portaudio , and also being generally much less outdated.
need to add a portaudio backend to clive (my thing for #LiveCoding #audio #dsp in the #C programming language) to be able to test it.
had hoped to test with #godwit (my #uzulang in progress) and classic Dirt sampler (which built in Termux with minor fixes), but compiling godwit depends on the #haskell programs alex and happy for generating the parser, and it seems Termux repos don't have them. nor is there darcs (also implemented in Haskell), which I'd need to get #HaskellHugs Hugs 2019 improvement (inc happy) working.
getting happy and alex working with #MicroHs is also far from trivial, even old versions depend on MagicHash and other ghc-isms.
I went to try acme-smuggler on MicroHs.
It doesn't compile, though:
Cannot satisfy constraint: (Exception Dynamic)
fully qualified: (Control.Exception.Internal.Exception Data.Dynamic.Dynamic)
today (thanks to augustss fixing some MicroHs bugs) I managed to get tidal-core working in MicroHs!
this is just the pattern language, not including live scheduler, OSC message sending, etc.
The next step is to combine this toot with previous toot and have a Tidal/Haskell thing running inside a web browser. But there's a lot of rest of owl before that will do anything useful.
I pushed my branch to Microsoft Github for ease of review:
https://github.com/claudeha/Tidal/tree/topic-microhs-compat
seems I somehow got #MicroHs #Haskell interpreter compiled and working in a browser using #Emscripten #WebDev
used a require.js I found online (from Tarp https://pixelsvsbytes.com/2013/02/js-require-for-browsers-better-faster-stronger/ ) and slighly patched for my use case / url layout, and some minimal #NodeModules folder (npm install --save path) with custom symlinks inside to choose the browser js.
the HTML from Emscripten is patched lightly to add the require script and a couple of require() calls. the standard library is included with preload file; the total size of the served folder is about 3.5MB.
the usability is terrible (have to enter input in a modal form with no history or completion etc, output goes to browser console) but it's a start!
tried TidalCycles tidal-core with MicroHs:
- MicroHs enables PatternSynonyms which steals syntax (the identifier `pattern` is now a keyword). solution, replace pattern with pattern_ everywhere it is used as an identifier
- MicroHs has no DeriveFunctor. solution, write manual Functor instances
- MicroHs Integral has no Enum superclass. solution, add Enum constraint
- MicroHs does not support polymorphic record update (yet?). solution, give up (for now?) https://github.com/augustss/MicroHs/issues/190
I started implementing some explorations in #Haskell but I had to ditch `data-memocombinators` because #MicroHs doesn't properly support #RankNTypes yet. Instead I'm doing manual #memoization with #array :
```
import Data.Array
-- memoized function, looks up in array
f :: Int -> Int -> Int -> Int
f = \x y z -> if inRange fBounds (x, y, z) then fArray ! (x, y, z) else 0
-- real algorithm, recursive calls use memoized function
f' :: Int -> Int -> Int -> Int
f' 1 1 1 = 1
f' a b c = sum [ f (a - 1) b c, f a (b - 1), f a b (c - 1) ]
-- array, generated with real algorithm
fArray :: Array (Int, Int, Int) [Bool]
fArray = array fBounds [ (i, f' x y z) | i@(x, y, z)<- range fBounds ]
-- array bounds
fBounds :: ((Int, Int, Int), (Int, Int, Int))
fBounds = ((1, 1, 1), (limit, limit, limit))
-- can be as large as necessary for the real problem,
-- but going too big consumes too much memory
limit :: Int
limit = 45
```
I wrote a script to install/update MicroHs (a small Haskell compiler) and Godwit (my Tidal-ish pattern language thing), because it's boring to keep doing the fair number of steps by hand:
https://mathr.co.uk/web/godwit.html#Bootstrap
Takes about 6mins on desktop, 45mins on tablet, haven't tried on phone yet. Doesn't including the once-only step of adding
```
if [ -d "$HOME/.mcabal/bin" ] ; then
PATH="$HOME/.mcabal/bin:$PATH"
fi
```
to ~/.profile or ~/.bashrc or similar...
Then to start making sounds you need classic Dirt(*) sampler with some samples:
(cd dirt && ./dirt ) &
cd godwit
make HC=mhs scheduler &
make HC=mhs repl
:set +l
hush
s [bd]
The first time you run the scheduler it spits out warnings about missing shared library until a pattern is entered in the repl, which is a bit distracting, I should fix that. To stop exit the repl with :q and then enter fg, ctrl-c, fg, ctrl-c to quit the scheduler and dirt.
#Haskell #MicroHs #TidalCycles #Godwit #LiveCoding
(*) 1/2