SlideShare a Scribd company logo
F# Quotations:
“Code as Data”
Jack Pappas
Dmitry Morozov
SkillsMatter Progressive F# Tutorials NYC
September 19th, 2013
Code as Data
• Code & Data – What is the difference?
• Is there a difference?
• Programs exist to process data
– The F# compiler processes data (your source
code)
• Source code is no different than other kinds of
data
This Session
• What is a “quoted expression”?
– A simple, immutable data structure
– Represents a fragment of F# code
• Syllabus
– Background
– Working with Quotations
– Manipulating Quotations
– Applications of Quotations
Background
• The idea of treating code as data first
appeared in Lisp
Lisp F#
Code (1 2 3) [1; 2; 3]
Code as Data ‘(1 2 3) <@ [1; 2; 3] @>
Background
• A language that has the natural ability to
manipulate itself is extremely powerful
• “Amplify” a developer’s productivity using
metaprogramming techniques
Background
• Other languages can manipulate their own
code
– clang: C++ program, manipulates C++
– Roslyn: C# library, manipulates C#
– f2c: C program, manipulates FORTRAN and C
• What makes Lisp and F# different?
– Reflective meta-programming
– Built-in language feature vs. external
functionality
Background
• Now that we can manipulate code as data,
what can we do with it?
• Transform
– modify, convert, translate
• Analyze
– Static analysis
– Advanced testing techniques (e.g., verification)
– Collect and record code metrics (e.g., complexity)
Background
• Execute
– Interpret the code/data
– Translate to another lang., compile, execute
– Specialized hardware (e.g., GPU, FPGA)
– Specialized execution (e.g., auto-parallelization)
– Execute remotely (e.g., web service)
– Some combination of the above
– (Rarely) execute in same context, e.g., by
translating to IL and executing
Use Cases
• LINQ support in F#
– Extension of this idea:
Cheney, Lindley, Wadler.
“The essence of language-integrated query”
• Use as an IL when developing type providers
– Quotations much easier to work with
– Create quotations, translate to IL
Use Cases
• Testing
– Moq/Foq/Unquote
• GPU programming
– Compute: FSCL, QuantAlea
– Graphics: SharpShaders (F# -> HLSL)
• Web Development (F# -> JavaScript)
– WebSharper
– FunScript
– PitFw
Comparing Alternatives
• What alternatives exist to quotations?
– F# AST
– LINQ Expression Trees
– CIL (MSIL)
• Imperative: Expression Trees, CIL
– C# lambdas compiled into Expression Trees by
the C# compiler
• Functional: F# AST, Quotations
Comparing Alternatives
• F# AST
– Designed for the compiler’s internal use
– Carries more information than quotations
– Requires additional library
– Unwieldy for simple use cases
Comparing Alternatives
• LINQ Expression Trees
– Introduced in .NET 3.5; initially somewhat limited
– Expanded in .NET 4.0; now roughly 1:1 with CIL
– Doesn’t support certain functional features like
closures
Comparing Alternatives
• Common Intermediate Language (CIL)
– Low-level; relatively difficult to work with
– Supports all CLR features
– F# Quotations don’t support all CLR features
●
Notably, throw and rethrow – these need to be
wrapped in a function and compiled using the proto
compiler
●
No fault/filter clauses
• F# Quotations don’t support open generics
Quotations: How-To
• Open some namespaces
• Define a module, then some functions within
the module
open System.Reflection
open Microsoft.FSharp.Reflection
open Microsoft.FSharp.Quotations
module Foo =
let addTwo x = x + 2
Quotations: How-To
• Apply [<ReflectedDefinition>] to your function
– Or, apply it to your module as a shortcut for applying it to
all functions in the module
module Foo =
/// Dummy class used to retrieve
/// the module type.
type internal Dummy = class end
[<ReflectedDefinition>]
let addTwo x = x + 2
Quotations: How-To
• Using Reflection, get the MethodInfo for your
function
• Call Expr.TryGetReflectedDefinition with the
MethodInfo to get the Expr for the method
Quotations: How-To
[<EntryPoint>]
let main argv =
let fooType = typeof<Foo.Dummy>.DeclaringType
let addTwoMethodInfo =
match fooType.GetMethod "addTwo" with
| null -> None
| x -> Some x
addTwoMethodInfo
|> Option.map Expr.TryGetReflectedDefinition
|> Option.iter (printfn "addTwo: %A")
Quotations: How-To
• For each active pattern in Quotations.Patterns,
there is a corresponding static member of the
Expr type.
– These are used to construct and destructure each
quotation “case”.
• Two types of quotations: typed and untyped
– Typed: Expr<‘T>
– Untyped: Expr
Quotations: How-To
• Expr<‘T> is just a wrapper around Expr
– Use the .Raw property for Expr<‘T> -> Expr
– Use the Coerce pattern for Expr -> Expr<‘T>
• Quoting an expression
– Typed: <@ fun x -> x + 2 @>
– Untyped: <@@ fun x -> x + 2 @@>
Quotations: How-To
• “Splicing” – a way to combine quotations
– Inserts one quotation into another
– Typed:
let bar = <@ 3 + "Blah".Length @>
let foo = <@ fun x -> x + %bar @>
– Untyped:
let bar = <@@ 3 + "Blah".Length @@>
let foo = <@@ fun x -> x + %%bar @@>
Quotations: How-To
• Note: You don’t always need
[<ReflectedDefinition>] to use quotations
• Using our previous example, this is equivalent
let addTwo = <@ fun x -> x + 2 @>
Computations on Trees
• When working with Quotations, it’s critical
you’re comfortable with trees and recursion
• Tree computations in imperative languages
usually built around the “visitor” pattern
– Visitor class usually holds private, mutable state
– Often implemented as an abstract base class per
tree type, and one virtual method per node type
– Mechanics of the traversal intermixed with
computation happening at nodes
Computations on Trees
• Possible to implement a functional alternative
to the “visitor” pattern?
• Knuth did – decades ago!
• Introducing “attribute grammars”
– Initially used as a means of describing how LL/LR
parsers annotate a parse tree
– Later, used to describe how “attributes” are
computed from on tree
Computations on Trees
• Attribute grammars are declarative
– They do not define any traversal order
• Attribute grammars allow you to define purely
functional, monadic computations over trees
– For those familiar with Haskell – attribute
evaluation is actually co-monadic
• AGs on ASTs (or Quotations) can be used to
implement purely functional AOP
Computations on Trees
• Three main kinds of attributes
• Inherited (L-attributes)
– Attribute “inherited” from parent node
– Compare to the reader workflow
• Synthesized (S-attributes)
– Attribute “synthesized” by a child node, passed
back up to parent node
– Compare to the writer workflow
Computations on Trees
• Threaded (SL-attributes)
– Attribute value inherited from parent node,
modified by child, then passed back up to parent
– Combination of Inherited and Synthesized
– Compare to the state workflow
• Attribute values can be int, string, UDTs, etc.
• They can also be tree nodes
– We can use this to define tree transformations
Exercises
• Implement a function(s) which, given an Expr:
– Print the equiv. F# source code
– Invert the mathematical operators (+)/(-), (*)/(/)
– Compute the set of methods called by the Expr
●
Bonus: Compute this transitively
– Determine if the Expr can ever raise an exn
– Determine if the Expr is pure (side-effect free)
– Rewrite it so all strings are passed through
String.Intern

More Related Content

What's hot (20)

PPTX
Introduction to F# 3.0
Talbott Crowell
 
PDF
C# 9 and 10 - What's cool?
Christian Nagel
 
PDF
Swift vs. Language X
Scott Wlaschin
 
PPTX
History of F#, and the ML family of languages.
Rachel Reese
 
PPT
F# and the DLR
Richard Minerich
 
PDF
Create Your Own Language
Hamidreza Soleimani
 
KEY
Using Aspects for Language Portability (SCAM 2010)
lennartkats
 
PPTX
c# usage,applications and advantages
mohamed drahem
 
PDF
LIL Presentation
badsectoracula
 
ODP
Character sets and iconv
Daniel_Rhodes
 
PDF
The Spoofax Language Workbench (SPLASH 2010)
lennartkats
 
PPTX
C programming language
Maha lakshmi
 
PDF
F# for Scala developers
Alfonso Garcia-Caro
 
PPTX
C languaGE UNIT-1
Malikireddy Bramhananda Reddy
 
PPTX
Procedure oriented programming
MrShahbazRafiq
 
KEY
Language Engineering in the Cloud
lennartkats
 
PPT
Lexical1
ASHOK KUMAR REDDY
 
PPTX
Async programming in f
BeauLiu
 
PDF
Sparklis exploration et interrogation de points d'accès sparql par interactio...
SemWebPro
 
PDF
The GNOME way - What can we learn from and within the Open Documentation World
Radina Matic
 
Introduction to F# 3.0
Talbott Crowell
 
C# 9 and 10 - What's cool?
Christian Nagel
 
Swift vs. Language X
Scott Wlaschin
 
History of F#, and the ML family of languages.
Rachel Reese
 
F# and the DLR
Richard Minerich
 
Create Your Own Language
Hamidreza Soleimani
 
Using Aspects for Language Portability (SCAM 2010)
lennartkats
 
c# usage,applications and advantages
mohamed drahem
 
LIL Presentation
badsectoracula
 
Character sets and iconv
Daniel_Rhodes
 
The Spoofax Language Workbench (SPLASH 2010)
lennartkats
 
C programming language
Maha lakshmi
 
F# for Scala developers
Alfonso Garcia-Caro
 
Procedure oriented programming
MrShahbazRafiq
 
Language Engineering in the Cloud
lennartkats
 
Async programming in f
BeauLiu
 
Sparklis exploration et interrogation de points d'accès sparql par interactio...
SemWebPro
 
The GNOME way - What can we learn from and within the Open Documentation World
Radina Matic
 

Similar to Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations code as-data for f# (20)

PDF
The Fuss about || Haskell | Scala | F# ||
Ashwin Rao
 
PDF
F# and Reactive Programming for iOS
Brad Pillow
 
PDF
Cross platform native development in f#
David Kay
 
PPTX
F# intro
Alexey Raga
 
DOCX
In the Notes on Programming Language Syntax page, an example par.docx
mecklenburgstrelitzh
 
PDF
Template Haskell
Sergey Stretovich
 
PDF
Functional programming with F#
Remik Koczapski
 
PPTX
Functional Programming Fundamentals
OleksiyTereshchenko
 
PDF
Introduction to clojure
Abbas Raza
 
PPTX
Write Your Own Compiler in 24 Hours
Phillip Trelford
 
PDF
Clojure class
Aysylu Greenberg
 
PDF
The Next Great Functional Programming Language
John De Goes
 
PDF
Diving into Functional Programming
Lev Walkin
 
PDF
7li7w devcon5
Kerry Buckley
 
PPTX
F# for functional enthusiasts
Jack Fox
 
PDF
Programming Languages: some news for the last N years
Ruslan Shevchenko
 
PPTX
Functional programming in f sharp
chribben
 
PPTX
24 Hours Later - NCrafts Paris 2015
Phillip Trelford
 
PDF
The Rust Programming Language 2nd Edition Steve Klabnik
urbuuawara
 
PPTX
F sharp _vs2010_beta2
Eriawan Kusumawardhono
 
The Fuss about || Haskell | Scala | F# ||
Ashwin Rao
 
F# and Reactive Programming for iOS
Brad Pillow
 
Cross platform native development in f#
David Kay
 
F# intro
Alexey Raga
 
In the Notes on Programming Language Syntax page, an example par.docx
mecklenburgstrelitzh
 
Template Haskell
Sergey Stretovich
 
Functional programming with F#
Remik Koczapski
 
Functional Programming Fundamentals
OleksiyTereshchenko
 
Introduction to clojure
Abbas Raza
 
Write Your Own Compiler in 24 Hours
Phillip Trelford
 
Clojure class
Aysylu Greenberg
 
The Next Great Functional Programming Language
John De Goes
 
Diving into Functional Programming
Lev Walkin
 
7li7w devcon5
Kerry Buckley
 
F# for functional enthusiasts
Jack Fox
 
Programming Languages: some news for the last N years
Ruslan Shevchenko
 
Functional programming in f sharp
chribben
 
24 Hours Later - NCrafts Paris 2015
Phillip Trelford
 
The Rust Programming Language 2nd Edition Steve Klabnik
urbuuawara
 
F sharp _vs2010_beta2
Eriawan Kusumawardhono
 
Ad

More from Skills Matter (20)

PDF
5 things cucumber is bad at by Richard Lawrence
Skills Matter
 
ODP
Patterns for slick database applications
Skills Matter
 
PDF
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Skills Matter
 
ODP
Oscar reiken jr on our success at manheim
Skills Matter
 
PDF
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Skills Matter
 
PDF
Cukeup nyc peter bell on getting started with cucumber.js
Skills Matter
 
PDF
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Skills Matter
 
ODP
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Skills Matter
 
ODP
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Skills Matter
 
PDF
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Skills Matter
 
PDF
A poet's guide_to_acceptance_testing
Skills Matter
 
PDF
Russ miles-cloudfoundry-deep-dive
Skills Matter
 
KEY
Serendipity-neo4j
Skills Matter
 
PDF
Simon Peyton Jones: Managing parallelism
Skills Matter
 
PDF
Plug 20110217
Skills Matter
 
PDF
Lug presentation
Skills Matter
 
PPT
I went to_a_communications_workshop_and_they_t
Skills Matter
 
PDF
Plug saiku
Skills Matter
 
PDF
Huguk lily
Skills Matter
 
PDF
Bootstrapping a-devops-matter
Skills Matter
 
5 things cucumber is bad at by Richard Lawrence
Skills Matter
 
Patterns for slick database applications
Skills Matter
 
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Skills Matter
 
Oscar reiken jr on our success at manheim
Skills Matter
 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Skills Matter
 
Cukeup nyc peter bell on getting started with cucumber.js
Skills Matter
 
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Skills Matter
 
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Skills Matter
 
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Skills Matter
 
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Skills Matter
 
A poet's guide_to_acceptance_testing
Skills Matter
 
Russ miles-cloudfoundry-deep-dive
Skills Matter
 
Serendipity-neo4j
Skills Matter
 
Simon Peyton Jones: Managing parallelism
Skills Matter
 
Plug 20110217
Skills Matter
 
Lug presentation
Skills Matter
 
I went to_a_communications_workshop_and_they_t
Skills Matter
 
Plug saiku
Skills Matter
 
Huguk lily
Skills Matter
 
Bootstrapping a-devops-matter
Skills Matter
 
Ad

Recently uploaded (20)

PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PPTX
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PDF
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
PDF
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
PPTX
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 
PDF
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
PDF
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PDF
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
PDF
Biography of Daniel Podor.pdf
Daniel Podor
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
Biography of Daniel Podor.pdf
Daniel Podor
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 

Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations code as-data for f#

  • 1. F# Quotations: “Code as Data” Jack Pappas Dmitry Morozov SkillsMatter Progressive F# Tutorials NYC September 19th, 2013
  • 2. Code as Data • Code & Data – What is the difference? • Is there a difference? • Programs exist to process data – The F# compiler processes data (your source code) • Source code is no different than other kinds of data
  • 3. This Session • What is a “quoted expression”? – A simple, immutable data structure – Represents a fragment of F# code • Syllabus – Background – Working with Quotations – Manipulating Quotations – Applications of Quotations
  • 4. Background • The idea of treating code as data first appeared in Lisp Lisp F# Code (1 2 3) [1; 2; 3] Code as Data ‘(1 2 3) <@ [1; 2; 3] @>
  • 5. Background • A language that has the natural ability to manipulate itself is extremely powerful • “Amplify” a developer’s productivity using metaprogramming techniques
  • 6. Background • Other languages can manipulate their own code – clang: C++ program, manipulates C++ – Roslyn: C# library, manipulates C# – f2c: C program, manipulates FORTRAN and C • What makes Lisp and F# different? – Reflective meta-programming – Built-in language feature vs. external functionality
  • 7. Background • Now that we can manipulate code as data, what can we do with it? • Transform – modify, convert, translate • Analyze – Static analysis – Advanced testing techniques (e.g., verification) – Collect and record code metrics (e.g., complexity)
  • 8. Background • Execute – Interpret the code/data – Translate to another lang., compile, execute – Specialized hardware (e.g., GPU, FPGA) – Specialized execution (e.g., auto-parallelization) – Execute remotely (e.g., web service) – Some combination of the above – (Rarely) execute in same context, e.g., by translating to IL and executing
  • 9. Use Cases • LINQ support in F# – Extension of this idea: Cheney, Lindley, Wadler. “The essence of language-integrated query” • Use as an IL when developing type providers – Quotations much easier to work with – Create quotations, translate to IL
  • 10. Use Cases • Testing – Moq/Foq/Unquote • GPU programming – Compute: FSCL, QuantAlea – Graphics: SharpShaders (F# -> HLSL) • Web Development (F# -> JavaScript) – WebSharper – FunScript – PitFw
  • 11. Comparing Alternatives • What alternatives exist to quotations? – F# AST – LINQ Expression Trees – CIL (MSIL) • Imperative: Expression Trees, CIL – C# lambdas compiled into Expression Trees by the C# compiler • Functional: F# AST, Quotations
  • 12. Comparing Alternatives • F# AST – Designed for the compiler’s internal use – Carries more information than quotations – Requires additional library – Unwieldy for simple use cases
  • 13. Comparing Alternatives • LINQ Expression Trees – Introduced in .NET 3.5; initially somewhat limited – Expanded in .NET 4.0; now roughly 1:1 with CIL – Doesn’t support certain functional features like closures
  • 14. Comparing Alternatives • Common Intermediate Language (CIL) – Low-level; relatively difficult to work with – Supports all CLR features – F# Quotations don’t support all CLR features ● Notably, throw and rethrow – these need to be wrapped in a function and compiled using the proto compiler ● No fault/filter clauses • F# Quotations don’t support open generics
  • 15. Quotations: How-To • Open some namespaces • Define a module, then some functions within the module open System.Reflection open Microsoft.FSharp.Reflection open Microsoft.FSharp.Quotations module Foo = let addTwo x = x + 2
  • 16. Quotations: How-To • Apply [<ReflectedDefinition>] to your function – Or, apply it to your module as a shortcut for applying it to all functions in the module module Foo = /// Dummy class used to retrieve /// the module type. type internal Dummy = class end [<ReflectedDefinition>] let addTwo x = x + 2
  • 17. Quotations: How-To • Using Reflection, get the MethodInfo for your function • Call Expr.TryGetReflectedDefinition with the MethodInfo to get the Expr for the method
  • 18. Quotations: How-To [<EntryPoint>] let main argv = let fooType = typeof<Foo.Dummy>.DeclaringType let addTwoMethodInfo = match fooType.GetMethod "addTwo" with | null -> None | x -> Some x addTwoMethodInfo |> Option.map Expr.TryGetReflectedDefinition |> Option.iter (printfn "addTwo: %A")
  • 19. Quotations: How-To • For each active pattern in Quotations.Patterns, there is a corresponding static member of the Expr type. – These are used to construct and destructure each quotation “case”. • Two types of quotations: typed and untyped – Typed: Expr<‘T> – Untyped: Expr
  • 20. Quotations: How-To • Expr<‘T> is just a wrapper around Expr – Use the .Raw property for Expr<‘T> -> Expr – Use the Coerce pattern for Expr -> Expr<‘T> • Quoting an expression – Typed: <@ fun x -> x + 2 @> – Untyped: <@@ fun x -> x + 2 @@>
  • 21. Quotations: How-To • “Splicing” – a way to combine quotations – Inserts one quotation into another – Typed: let bar = <@ 3 + "Blah".Length @> let foo = <@ fun x -> x + %bar @> – Untyped: let bar = <@@ 3 + "Blah".Length @@> let foo = <@@ fun x -> x + %%bar @@>
  • 22. Quotations: How-To • Note: You don’t always need [<ReflectedDefinition>] to use quotations • Using our previous example, this is equivalent let addTwo = <@ fun x -> x + 2 @>
  • 23. Computations on Trees • When working with Quotations, it’s critical you’re comfortable with trees and recursion • Tree computations in imperative languages usually built around the “visitor” pattern – Visitor class usually holds private, mutable state – Often implemented as an abstract base class per tree type, and one virtual method per node type – Mechanics of the traversal intermixed with computation happening at nodes
  • 24. Computations on Trees • Possible to implement a functional alternative to the “visitor” pattern? • Knuth did – decades ago! • Introducing “attribute grammars” – Initially used as a means of describing how LL/LR parsers annotate a parse tree – Later, used to describe how “attributes” are computed from on tree
  • 25. Computations on Trees • Attribute grammars are declarative – They do not define any traversal order • Attribute grammars allow you to define purely functional, monadic computations over trees – For those familiar with Haskell – attribute evaluation is actually co-monadic • AGs on ASTs (or Quotations) can be used to implement purely functional AOP
  • 26. Computations on Trees • Three main kinds of attributes • Inherited (L-attributes) – Attribute “inherited” from parent node – Compare to the reader workflow • Synthesized (S-attributes) – Attribute “synthesized” by a child node, passed back up to parent node – Compare to the writer workflow
  • 27. Computations on Trees • Threaded (SL-attributes) – Attribute value inherited from parent node, modified by child, then passed back up to parent – Combination of Inherited and Synthesized – Compare to the state workflow • Attribute values can be int, string, UDTs, etc. • They can also be tree nodes – We can use this to define tree transformations
  • 28. Exercises • Implement a function(s) which, given an Expr: – Print the equiv. F# source code – Invert the mathematical operators (+)/(-), (*)/(/) – Compute the set of methods called by the Expr ● Bonus: Compute this transitively – Determine if the Expr can ever raise an exn – Determine if the Expr is pure (side-effect free) – Rewrite it so all strings are passed through String.Intern