One can use arrow notation in a language for hosting arrow notation module management and macros. Ideally, one would lift arrow notation to the host via a macro and then use it twice with different semantics: one for the internal DSL and again for the macro system.
The following is a Haskell proof of concept.
exampleModule :: ArrowLangModule
exampleModule = let
-- Imports, declare all functions.
f = require (Generator "f" 3 2)
g = require (Generator "g" 2 1)
-- Module definitions.
def1 = arrowLang ["a","b","c"]
$ Statement f ["a","b","c"] ["x","y"]
$ Statement g ["a","y"] ["d"]
$ Return ["x","y","d"]
def2 = arrowLang ["x","y"]
$ Statement def1 ["x","y","x"] ["u","v","w"]
$ Statement f ["x","y","x"] ["u","v"]
$ Return ["u"]
-- Composition macro
composition f g = arrowLang xs
$ Statement f xs ys
$ Statement g ys zs
$ Return zs
where
-- would be better managed by explicit fresh name generation
xs = take (source f) freshNames
ys = take (target f) (drop (source f) freshNames)
zs = take (target g) (drop (source f) (drop (target f) freshNames))Note that the Haskell implementation of do-notation would not work as expected here.
example4 :: ArrowLang (Generator String)
example4 = do
def1 <- ArrowLang ["a","b","c"]
$ Statement (Generator "f" 3 2) ["a","b","c"] ["x","y"]
$ Statement (Generator "g" 2 1) ["a","y"] ["d"]
$ Return ["x","y","d"]
def2 <- ArrowLang ["x","y"]
$ Statement def1 ["x","y","x"] ["u","v","w"]
$ Return ["u"]
return def2Instead of using the Kleisli category of the monad of arrow notation, we may want to implicitly use its category of algebras, which is cartesian, as a copy-discard category.
Tags: programming languages, arrow notation.