I'm playing around making a language.<p>I'm a firm believer that recursion is good, but there's a lot going in in `let foo = () => foo;`.<p>First, I think `let foo` is interpreted, and `foo` is immediately hoisted, as it will be defined.<p>Second, the value of foo is known to be a function.<p>That function code isn't evaluated at all, and here's where I have several thoughts going through my head.<p>I was wondering, at compile-time, should a language bother checking identifiers? I don't particularly like hoisting and think values should be evaluated before declaration begins to take place. I've always liked recursion, but at the moment I thought: "if I want to do recursion, I shouldn't implement any id-validity checking in functions."<p>Let's say,
let bar = () => foo();
(function() {
window.foo = () => console.log("hi");
}());
bar(); // console logs "hi"<p>So, at compile-time it seems complicated to check for the existence of "foo" in the function "bar". I mean- sure, it's possible- but it seems like a losing battle for a compiler to chase identifiers all around the program, simply to check if they will exist when they are needed.<p>So I suppose one solution is to just let undefined identifiers slide unchecked until runtime.
Another solution is to check as much as possible, unless or until the existence of an identifier could potentially come to being during input.<p>For example, the compiler could see that an array of links in a search-robot might be built after visiting a url that has n links. Perhaps a function is generated for each link, so the compiler might see `links[i].visit()` and think, "Well, that function 'visit' isn't ever created, but links is an object populated by a resource, and maybe that resource provides the necessary API at runtime to make ..visit() defined." Designing a compiler like that seems.. not simple.<p>So ya, idk. Thoughts?