Earlier quoted context omitted.
> There's something more constricting about there being one function to bootstrap everything than there is about one file. As a compiler author, there are a bunch of nasty surprises to this approach. If you execute a file line-by-line, then functions only exist once you "reach" them. If you write: def a(): b() a() def b(): ... ...then a() needs to crash when first called, because b() hasn't been declared yet. So your…
> ...then a() needs to crash when first called, because b() hasn't been declared yet. Why would it “need to” crash? If it is easier to implement to not crash and the developer intention is clear why would you define your new programing language such that it “needs to crash” in this situation? It is as if you go to your garden to pick tomatoes, but you trip over a rake you intentionally put in your way and then as you…
Well, let me come up with another example:
def a(x=SIZE): ...
a()
let SIZE = 16*1024
When we call a(), we need the value of SIZE to provide the a default value for x. But SIZE isn't computed yet. We could try to "hoist" SIZE, but normally that just means we have: let SIZE = undefined
def a(x=SIZE): ...
a()
SIZE = 16*1024
And sure, you could invent a rule to "fix" this case, too. (It depends on how you implement default arguments efficiently.) But next week, you'll encounter another headache, and another. I've literally been through this a couple of times working on LISP compilers. "Executional" semantics are common in custom Lisp dialects, and it's a huge amount of work to get them right.The price you end up paying is lower program performance and higher compiler complexity. Oh, and importantly, you normally wind up with slower load times. A compiled program is "ready to run", and can be loaded efficiently using mmap() and maybe some linking. But a program where you "execute" the top level needs to run all those top-level definitions on each load. So then you're like, "I know! I'll write a heap dumper/undumper", aka "unexec". Which will fix this problem but cause 5 more.
And so it goes. This is one of those ideas that seems clever but leads to bitter regrets, at least in high performance languages.