Skip to content

Instantly share code, notes, and snippets.

@ELLIOTTCABLE
Created February 16, 2010 05:03
Show Gist options
  • Save ELLIOTTCABLE/305304 to your computer and use it in GitHub Desktop.
Save ELLIOTTCABLE/305304 to your computer and use it in GitHub Desktop.
Operator dynamism
-----------------
### Level 0 (Haskell)
- Allow users to define operators
- Defined outside the language itself
- The operation that changes operators’ status has no semantic meaning; is
simply preprocessor directive
- Defined globally
- Applies identically regardless of values
#define_operator foo left 2
a foo b
// processes into `foo(a, b)` (procedural lang) or `a.foo(b)` (objective
// lang)
### Level 1
- Allows users to define operators
- Defined outside the language itself
- The operation that changes operators’ status has very little semantic
meaning; is simply preprocessor directive
- Defined in lexical scopes
- Applies identically regardless of values
#define_operator foo left 2
a foo b
// processes into `foo(a, b)` (procedural lang) or `a.foo(b)` (objective
// lang)
new_scope {
#define_operator foo right 2
c foo d
// processes into `foo(d, c)` (procedural lang) or `d.foo(c)`
// (objective lang)
}
### Level 2
- Allows users to define operators
- Defined inside the conceptual framework of the language
- The operation that changes operators’ status has some semantic
meaning; it is a function (or something similar) within the framework of the
language, just like any other one of those things (function?) within the
language
- Defined in dynamic scopes
- Applies identically regardless of values
define_operator('foo', :left, 2)
a foo b
// calls `foo` with the values of `a` and `b` as arguments (procedural
// lang or objective lang)
new_scope {
define_operator('foo', :right, 2)
c foo d
// calls `foo` with the values of `d` and `c` as arguments (procedural
// lang or objective lang)
}
### Level 3 (Only relevant to an user-typed/objective language)
- Allows users to define operators
- Defined inside the conceptual framework of the language
- The operation that changes operators’ status has full semantic
meaning; it is a function (or something similar) within the framework of the
language, just like any other one of those things (function?) within the
language
- Defined in dynamic scopes
- Applies differently to each possible value
a = Thing new()
a foo is_operator = false
a foo b
// looks up `foo` on the value of `a`, then looks up `b` on the value of
// `foo` (i.e. ‘normal’ handling for this example-language, no ‘operator’
// handling at all)
new_scope {
a = Thing new()
a foo is_operator = true; a foo associativity = :right; a foo arity = 1
b foo a
// looks up `foo` on the value of `a`, calls it with no arguments, and
// looks up the result on `b`
o = Thing new()
o foo is_operator = true; o foo associativity = :right; o foo arity = 2
100 times {
if(rand(100) < 50) {
it = a
} else {
it = o
}
something foo it
// half the time, will end up looking up `foo` on `a`/`it`, calling it
// with no arguments, then looking up the result on `something`
// the rest of the time, will end up looking up `foo` on `b`/`it`, and
// calling it with `something` as an argument.
}
}
Implementations
===============
### Solution A
First off, the Haskell-esque solution. At pre-compilation-parse-time, we can
pull out some sort of special keyword/directive that changes how pre-
compilation parsing happens; specifically, it changes the handling of a
specific string of words, such that they become a ‘call’ instead of the series
of words they are in the source code.
- Can provide Level 1 dynamism
- Provides a completely static parse tree; once the preprocessing is complete,
the series of words/calls is the same as any other series of words/calls,
and cannot be changed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment