Announcement: Bang, a drum DSL for Haskell

Hi haskell-cafe, I've been working on "Bang" on and off for about a month or two now, and finally thought it was "good enough" to open-source and show to the public! I've been having fun with it, and hopefully some of you will, too. It currently supports basically all of the primitive transformations that I could think of doing on a drum sequence, such as reversing, mirroring, changing duration and tempo. There are a bunch of operators built in that make it easy to write things like polyrhythms, and infinite sequences of notes are possible as well. The source code and basic tutorial are up on Github: https://github.com/5outh/Bang And the package + more detailed documentation is up on Hackage: http://hackage.haskell.org/package/Bang Let me know if you have any questions, comments, and/or suggestions. I'd love to hear them. Thanks! 5outh?

Benjamin J Kovach
nice. - two thoughts: * the basic object is a sequence of (MIDI) events, where duration is always implicit (computed by concatenation)? It might be useful to have explicit duration, so you can have an event "with (later) echoes" that still acts as just one event in concatenations (the echoes overlap with the following events - so you can say "apply echo to this drum" without destroying the timing of the pattern.) * (as with all Haskell EDSLs for music) a basic inconvenience in writing and reading is that the "space" symbol is application, while we actually want it for concatenation, to write a sequence of events without extra syntax (concatenation operators, or commas in list literals). I guess this requires a parser (as 'tidal' does it), or even template haskell (because we want to refer to user-defined Haskell values from inside the pattern). - J.W.

On 10/06/2014, at 8:15 PM, J. Waldmann wrote:
* (as with all Haskell EDSLs for music) a basic inconvenience in writing and reading is that the "space" symbol is application, while we actually want it for concatenation, to write a sequence of events without extra syntax (concatenation operators, or commas in list literals).
So you can't write a, a b, a b c, a b c d, and so on meaning concatenation every time, but can't you use the ideas of http://okmij.org/ftp/Haskell/polyvariadic.html#polyvar-fn to write f a, f a b, f a b c, f a b c d, and so on?

Richard A. O'Keefe wrote:
On 10/06/2014, at 8:15 PM, J. Waldmann wrote:
* (as with all Haskell EDSLs for music) a basic inconvenience in writing and reading is that the "space" symbol is application, while we actually want it for concatenation, to write a sequence of events without extra syntax (concatenation operators, or commas in list literals).
So you can't write a, a b, a b c, a b c d, and so on meaning concatenation every time, but can't you use the ideas of http://okmij.org/ftp/Haskell/polyvariadic.html#polyvar-fn to write f a, f a b, f a b c, f a b c d, and so on?
You can do something similar without type classes, as I learned from http://www.cs.uu.nl/wiki/Afp/Assignments#Assignment_2 : begin cont = cont (return ()) a m cont = cont (m >> putStrLn "a") b m cont = cont (m >> putStrLn "b") c m cont = cont (m >> putStrLn "c") end m = m main = begin a b c a b a end Cheers, Bertram

On Wed, Jun 11, 2014 at 01:25:48AM +0200, Bertram Felgenhauer wrote:
Richard A. O'Keefe wrote:
On 10/06/2014, at 8:15 PM, J. Waldmann wrote:
* (as with all Haskell EDSLs for music) a basic inconvenience in writing and reading is that the "space" symbol is application, while we actually want it for concatenation, to write a sequence of events without extra syntax (concatenation operators, or commas in list literals).
So you can't write a, a b, a b c, a b c d, and so on meaning concatenation every time, but can't you use the ideas of http://okmij.org/ftp/Haskell/polyvariadic.html#polyvar-fn to write f a, f a b, f a b c, f a b c d, and so on?
You can do something similar without type classes, as I learned from http://www.cs.uu.nl/wiki/Afp/Assignments#Assignment_2 :
begin cont = cont (return ()) a m cont = cont (m >> putStrLn "a") b m cont = cont (m >> putStrLn "b") c m cont = cont (m >> putStrLn "c") end m = m
main = begin a b c a b a end
This is fantastic!

Tom Ellis wrote:
On Wed, Jun 11, 2014 at 01:25:48AM +0200, Bertram Felgenhauer wrote:
begin cont = cont (return ()) a m cont = cont (m >> putStrLn "a") b m cont = cont (m >> putStrLn "b") c m cont = cont (m >> putStrLn "c") end m = m
main = begin a b c a b a end
This is fantastic!
Unfortunately this causes performance problems with ghc's type checker: main = begin a a a a a a a a a a a a a a a a a end takes more than a second to type-check under ghc 7.8.2, and every additional 'a' adds a factor of two. Interestingly, ghc 7.6.3 does not show this behaviour. Note that the instantiated types of 'a' grow exponentially: The first 'a' in 'begin a end' and 'begin a a end' have types M -> (M -> M) -> M and M -> (M -> (M -> M) -> M) -> (M -> M) -> M respectively, where 'M' abbreviates IO (), and each additional 'a' turns M -> r into M -> (M -> r) -> r, doubling the type's size. Cheers, Bertram P.S. a related way for causing bad type checking performance is the innocent looking main = id id id id id id id id id id id id id id id id id id id id id id (return ()) where again, the type of the first 'id' grows exponentially in the number of 'id' calls. In this case, ghc-7.6.3 performs just as badly as ghc-7.8.2.
participants (5)
-
Benjamin J Kovach
-
Bertram Felgenhauer
-
J. Waldmann
-
Richard A. O'Keefe
-
Tom Ellis