about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-11-08 20:26:13 -0800
committerKartik K. Agaram <vc@akkartik.com>2015-11-08 20:35:53 -0800
commite5302026cca04c23cba1431d5e0fceab8667bc08 (patch)
tree6a79d50a0e620503a8c53a4d92e9cdd827586395
parenta9a233715cbec202e90259ab95d97e35f143c146 (diff)
downloadmu-e5302026cca04c23cba1431d5e0fceab8667bc08.tar.gz
2401
I tried to not populate the type at an early stage, and to pull out the
type computations for all reagents into a separate transform grouped
with but before the other type deduction transforms. But it seemed less
readable to not mention types at all in layer 10. So we'll stick with
our current approach, but try to be disciplined about grouping all the
type transforms together, so that we can reason about whether a pass
belongs before or after type deduction. (Doesn't seem rigorous enough
for the name 'type inference'.) In particular, static dispatch and
specialization of generics (resolve_ambiguous_calls) needs to happen
after all type inference has completed, so that the only missing types
are the generic type ingredients.

In general I've been living in constant fear of the phase-ordering
problem. No matter how many tests I write, I can't be sure that there
isn't some corner case where my phases will be proven to be in a
sub-optimal ordering. When I build the mu compiler in mu I'll want to
also use the ability to perform static analyses in mu programs using mu
userland capabilities. That would allow me to be sure that no phase
writes to some field of reagent after some other purely checking phase
reads it. Then all you have to do is be disciplined about not doing
checking in mutating phases (which we currently aren't; hello
check_or_set_invalid_types).

Hmm, but I think this line of thought gives me some confidence now that
I'm ok so far. The only field of reagents being modified after
parsing/initialization is the type. So all I care about is whether each
transform happens before or after all types are available. If I later
start writing other fields or properties then I'll need to perform
similar analysis for them, and it might get complicated enough to need a
state diagram where partially filled out properties inhabit separate
states from completely inferred properties.
-rw-r--r--042name.cc2
-rw-r--r--048check_type_by_name.cc2
2 files changed, 2 insertions, 2 deletions
diff --git a/042name.cc b/042name.cc
index b66de8a2..b25ca533 100644
--- a/042name.cc
+++ b/042name.cc
@@ -18,7 +18,7 @@ recipe main [
 +error: main: use before set: y
 # todo: detect conditional defines
 
-:(after "Begin Transforms")
+:(after "Transform.push_back(check_or_set_invalid_types")  // there'll be other transforms relating to types; they all need to happen first
 Transform.push_back(transform_names);  // idempotent
 
 :(before "End Globals")
diff --git a/048check_type_by_name.cc b/048check_type_by_name.cc
index e9b65b8c..fff48395 100644
--- a/048check_type_by_name.cc
+++ b/048check_type_by_name.cc
@@ -14,7 +14,7 @@ recipe main [
 ]
 +error: main: x used with multiple types
 
-:(before "Transform.push_back(transform_names)")
+:(after "Transform.push_back(check_or_set_invalid_types)")
 Transform.push_back(check_types_by_name);  // idempotent
 
 :(code)