Levels of Dynamic behavior in Modal
Modal is a highly flexiable language. It's rewriting evaluation combined with runtime rule creation and deletion allows for it to be a powerful tool for crating DSLs. However, when it comes to compiling and optimizing the runtime, these behaviors prove tricky. Thus, I propose a modal that classifies Modal into different layers of dynamic behavior.
Levels
Level 0 -- Static Modal
Static Modal has the least runtime behavior and can thus be optimized the tightest. Each level after Static Modal removes a restriction defined here. Static Modal satifies the following requirements:
- No rule is ever created at runtime and no rule is bound after data is supplied.
- No lambdas are used.
- No new string is ever created.
- This restriction allows for a static string internment, it brings the following restrictions:
- No reading input.
- No concatenative (e.g
<> (?x) (?x?x))
- No reading read, explode, unpack, and unwrap.
- No rule is ever deleted.
?~
, explode ?*
, unpack ?.
, join ?^
). Information can however be emitted (send ?:
) and destroy.
Level 1 -- Destructive Modal
Destructive Modal removes the restriction on rule deletion. Rules are allowed to be deactived. However, no rules can be created. Thus destroying a rule is a permanent action.
Tho, in theory you could allow rules to be re-activated using ?((?: ?0) ?:) activate-rule (foo)
.
Level 2 -- Constructive Modal
The restriction on constructing new strings is lifted. Thus, the string interning is allowed to change. This is the first level that requires some kind of basic memory management. The pool needs to be reallocated if resources run out.
Level 3 -- Lambda Modal
The restriction on lambda creation is lifted. This is the first section that needs a mechanism for constructing or evaluting runtime created code. It may be possible to statically compile some lambdas ahead of time.
Level 4 -- Dynamic Modal
Final restriction is lifted. Rules can now be created at runtime. Static rules can be "late-bounded" and a system of activating them must be implemented. This is effectively the same as shipping an interpreter with static rules embedded in it.
Writing an Optimizing Compiler
An idea program for an optimizing compiler is Level 0. It allows for the leanest possible runtime; no memory management of lambdas, rules, and interned strings; and, no overhead to manage active rules. Additionally, at both Level 0 and Level 1 it's safe to do dead rule elimination. If a rule contains a token that is never produced in the RHS of a rule and is not in the program queue, it can be erased.
Additionally, the compiler of a modal program could use a modal interpreter to run the program for a set number of cycles. This would allow rewrite rules a chance to trigger and possibly produce a new program that's more friendly to compilation. An example of this would be removing rules designed to define a custom syntax.