Myriad Intro
@ 7sharp9 · Wednesday, Nov 6, 2019 · 2 minute read · Update at Nov 6, 2019

I released a new meta programming club video yesterday on my YouTube channel

I thought I would write a little about it here on my blog.

I recently did a little work to flesh out the plugin interface for Myriad. My friend Enrico Sada helped out with some of the fiddly MsBuild work in dotnet which can be a little confusing at times.

The gist of the plugin is that you must implement the following interface:

type IMyriadGenerator =
    abstract member Generate: namespace': string * ast:ParsedInput -> SynModuleOrNamespaceRcd

And annotate you type with the MyriadGeneratorAttribute specifying the name of your plugin so that it can be found.
Heres an example plugin from the Myriad repo:

[<MyriadGenerator("example1")>]
type Example1Gen() =
    interface IMyriadGenerator with
        member __.Generate(namespace', _ast) =

            let let42 =
                SynModuleDecl.CreateLet
                    [ { SynBindingRcd.Let with
                            Pattern = SynPatRcd.CreateLongIdent(LongIdentWithDots.CreateString "fourtyTwo", [])
                            Expr = SynExpr.CreateConst(SynConst.Int32 42) } ]

            let componentInfo = SynComponentInfoRcd.Create [ Ident.Create "example1" ]
            let nestedModule = SynModuleDecl.CreateNestedModule(componentInfo, [ let42 ])

            let namespaceOrModule =
                { SynModuleOrNamespaceRcd.CreateNamespace(Ident.CreateLong namespace')
                    with Declarations = [ nestedModule ] }

            namespaceOrModule

All this example does is generate a simple module like this:

module example1 =
    let fourtyTwo = 42

Ast Helping Hand

Unfortunately working with the AST can be quite verbose in Myriad I use FsAst which uses the record update syntax to aid in the construction of AST nodes by using the record update syntax so you don’t have to supply every parameter.

Take a Let binding AST element:

{SynBindingRcd.Let with
    Pattern = pattern
    Expr = expr }

If we did not use the record update syntax in SynBindingRcd then we would have to supply every parameter for the let binding:

{
    Access = None
    Kind = SynBindingKind.NormalBinding
    IsInline = false
    IsMutable = false
    Attributes = SynAttributes.Empty
    XmlDoc = PreXmlDoc.Empty
    ValData = SynValData(Some MemberFlags.InstanceMember, SynValInfo.Empty, None)
    Pattern = pattern
    ReturnInfo = None
    Expr = expr
    Range = range.Zero
    Bind = SequencePointInfoForBinding.NoSequencePointAtInvisibleBinding }

Which is not exactly fun, the record update syntax makes these type of things easy to define and compose together.


The new version of Myriad can be found on Nuget here or at its repo.

I hope you enjoyed the video and this brief blog!

Until next time!

Dave Thomas
7sharp9's blog
A cup of tea would restore my normality. - Douglas Adams
agents ast async concurrency csharp elixir elm fable fsharp functional-programming fuse games ios javascript mac mailboxprocessor metaprogramming microsoft mono monodevelop monogame monotouch myriad performance quotations running sockets threading tpl tpl-dataflow typeproviders videos xamarin youtube

© 2011 - 2020 7sharp9

Powered by Hugo with theme Dream.

About Me

Hi, my name is Dave Thomas and Im a software engineer from the Uk. I work primarily in F# but also like to tinker with pretty much any interesting language. Im drawn to more functional languages like F#, Swift and Rust.

Have questions or suggestions? Feel free to ask me on Twitter.

Thanks for reading!