Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Macros can provide a lot of syntactic convenience over those first-class functions, especially with heavily nested structures. For example, I can replace this monadic parser definition...

    function SpecDeclP()Parser{
      return Bind(SeqRight(MyKeywordP, IdentifierP), function(nm interface{})Parser{
        return Bind(BetweenParensP(IdentifierP), function(parm interface{})Parser{
          return Bind(SetSwitchUserStateP, function(_ interface{})Parser{
            return Bind(BlockP, function(bod interface{})Parser{
              return Result("func " + nm.(string) + "(" + parm.(string) + ")" + bod.(string))
            })
          })
        })
      })
    }
...with this more readable version if I have a recursively defined "macro" called doparse...

    doparse{
      nm   <- SeqRight(MyKeywordP, IdentifierP)
      parm <- BetweenParensP(IdentifierP)
      SetSwitchUserStateP
      bod  <- BlockP
      Result("func " + nm.(string) + "(" + parm.(string) + ")" + bod.(string))
    }
This requirement arose in Haskell for its Parsec before it became a part of the syntax, then again later with the Arrow library which later also added it to the syntax. Whenever new abstractions are discovered/created, a macroing facility, whether for lisp-like syntax or some other, helps makes all the nested functions more readable.


I'm fairly sure that Haskell had do notation before Parsec.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: