Sun May 11 11:42:37 CEST 2008
documentation + presentation
Brood is a metaprogramming environment for deeply embedded
programming, starting with the idea: "How to modernize the tethered
Forth approach?". Forth is appropriate for programming small
computers, but too low-level for a host-side metaprogramming
framework. Scheme is ideal for this.
The second objective is to generalize this to special-purpose
problem description languages.
what is metaprogramming?
- use language A to generate code in language B
- A = B possible, but more likely A > B (more high level)
- partial evaluation of the usual language tower, to limit
complexity of on-target support code. (give up some generality)
- overall idea: use high level construct where possible, but
specialize to low-level where possible.
why are macros important?
- aren't functions enough?
- partial evaluation: separate compile and run time. (get extra cake
at compile time without giving up possibility to use highly specific
why these weird languages?
- scheme = clean lisp. lisp's strength:
* metacircular interpretation (language defined in itself)
* leads to easy metaprogramming (lisp macros)
* scheme: based on untyped lambda calculus = functional
programming with imperative extensions (environment model)
* due to the concatenative composition model, the language
itself is quite powerful in itself, despite its
simplicity. (even without dynamic memory management or garbage
collection. related to innate 'linearity')
* base language = static, suited for real-time applications
* efficient: thin machine model for simple sequential chips
(less efficient for pipelined number crunching processors: a
dataflow language would be better suited there).
* simple metaprogramming
* it has a purely functional + purely concatenative subset
different brood layers:
- PLT scheme module system + module languages
- SCAT: purely functional intermediate language implemented as
- MACRO: purely functional metalanguage on top of SCAT. a MACRO
program generates (symbolic assembly) code. it includes PAT which
combines code generation and peephole optimization.
- FORTH: syntax on top of SCAT or MACRO to provide the
non-concatenative part of Forth (parsing words like ':').
* target specific assembler generator
* target address expression language (= SCAT)
* standard n-pass branch instruction code relaxation
- LIVE: live target interaction / simulation framework.
why from scratch?
- to gain deeper understanding
- to find a natural modularity without tool-specific idiosyncrasies
can it use external tools?
- yes, but design is optimized for internal tools. (i.e. compiler
-> assembler interface uses structured data instead of text)
can it use different languages?
- interfacing on object level: no problem (not implemented yet though)
- since custom languages are the core business, i see little
advantage supporting standard languages (like "C") directly.
- however, purrr is a core component.
why not OO?
- FP is natural: compiler = a function. maps source code to object code.
- stateless code generation makes different code generation paths
easy to implement (output feedback without environment setup)
- easier to do OO in FP than vise versa.
different implementation language?
- Forth/C/C++: been there. too low-level while performance payoff
not so important.
- Perl: i tried before, but i prefer structured data to strings
- Java: too clumsy.
- Haskell: i'm tempted, but probably too little wiggle space to
evolve a design. The final impelementation however might work well
in Haskell. Scheme's approach is conceptually closer to
metaprogramming, also wrt. ML.
- other dynamic OO languages (Python,Ruby,Smalltalk,...): i'm not
particularly convinced they are better than a FP oriented