Skip to content

Instantly share code, notes, and snippets.

@emberian
Last active August 29, 2015 13:57
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emberian/9521747 to your computer and use it in GitHub Desktop.
Save emberian/9521747 to your computer and use it in GitHub Desktop.
PL Theory etc
(On http://siek.blogspot.com/2012/07/crash-course-on-notation-in-programming.html)
cmr | " It's generally understood that parentheses are allowed in any language. "
cmr | Is this true in practice?
cmr | ski: how is the down-arrow in that post read as? I read it as "e evaluates to i", not sure if that's very precise or if there's a better interpretation.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ski | yes "e evaluates to i" is a fine rough way to think about it
ski | "It's generally understood that parentheses are allowed in any language."
ski | usually, in PL theory, it's true
cmr | swag
ski | strictly speaking, grammars deal with words/strings (sequences of symbols/tokens)
cmr | yeah I know a bit about parsing.
ski | which in case of a programming language corresponds to the *concrete* syntax of the language
ski | however, the BNF-like notation used in PLT usually really talk about *abstract* syntax (trees), and hence explicit brackets aren't need
ski | ed
ski | do you know any functional programming language ?
cmr | handful of scheme, spattering of haskell.
ski | ok, do you understand basic data types in Haskell ?
cmr | scheme I picked up working through the first ~third of sicp, Haskell I've been slowly working through in spare time.
cmr | such as Int?
ski | like e.g. defining binary trees of integers
cmr | yes.
ski | ok, fine
ski | then, think of
ski | e ::= i
ski | | - e
ski | | e + e
ski | as defining abstract syntax trees, like a data type definition
ski | data Expr = Literal Integer
ski | | Negate Expr
ski | | Add Expr Expr
cmr | makes sense.
ski | in practice, we could write
ski | e ::= lit(i)
ski | | neg(e)
ski | | add(e,e)
ski | (and some do)
ski | but we usually prefer looking at the "sugared" view above
ski | with the understanding that we should insert bracketting wherever needed, for complex expression (trees)
ski | iow, we can't say
ski | 2 + 3 + - 4
ski | we'd have to say
ski | ((2 + 3) + (- 4))
ski | e.g., if we mean that
ski | well, strictly speaking, perhaps even
ski | (((2) + (3)) + (- (4)))
ski | but we quickly decide on the convention that we don't wrap "atomic" subexpressions in brackets
ski | quickly followed by the convention that we don't both to wrap the whole expression in brackets either (unless we use it inside some other kind of formula, in which case we might still nee
| those)
ski | so, then we'd write
ski | (2 + 3) + (- 4)
ski | to describe which abstract syntax tree we mean
ski | cmr : makes sense ?
cmr | ski: yes, thanks!
ski | in short, the BNF-like notation used in PLT (usually) isn't actually about strings (like BNF in grammar normally is about), but rather *trees*
ski | and therefore we don't need an explicit case for bracketting
ski | because if we draw them as trees, visually, we don't need any brackets
ski | we only need them when we want to, unambiguously, represent such a tree in linear text, e.g. like the text in this IRC channel
ski | in we had subtraction, we might agree that if we write `e_0 - e_1 - e_2', then we mean the tree `(e_0 - e_1) - e_2' rather than the tree `e_0 - (e_1 - e_2)' (here which abbrviation convention
| choice we make, if any, affects the result we get, starting from a not fully bracketted linear portrayal of some expression tree)
ski | similarly, we may decide `e_0 + e_1 + e_2' means `(e_0 + e_1) + e_2' rather than `e_0 + (e_1 + e_2)' -- in this case, which choice we make (if any) doesn't affect the result value, starting
| from a linearized, not-fully-bracketted, expression
ski | still, as trees, those two are difference, so we need to distinguish them, because one means something like `add(add(e_0,e_1),e_2)' and the other means `add(e_0,add(e_1,e_2))' and those two
| abstract syntax trees are distinguishable, even though we intend to evaluate or reduce them to the same ultimate result value
ski | cmr : these latter points may be more or less obvious to you. i mention them in case it wasn't fully clear
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment