Skip to content

RFC: Compiler improvements#373

Open
nbd168 wants to merge 2 commits intojow-:masterfrom
nbd168:compiler-improvements
Open

RFC: Compiler improvements#373
nbd168 wants to merge 2 commits intojow-:masterfrom
nbd168:compiler-improvements

Conversation

@nbd168
Copy link
Contributor

@nbd168 nbd168 commented Feb 11, 2026

Bring ucode closer to ECMAScript:

  1. allow export function without trailing semicolon
  2. add explicit function declaration syntax

@nbd168 nbd168 force-pushed the compiler-improvements branch 3 times, most recently from 26bd062 to 72f85f9 Compare February 11, 2026 08:45
@jow-
Copy link
Owner

jow- commented Feb 11, 2026

Export without trailing semicolon is fine, makes sense.

About the hoisting support; personally I am no fan of hoisting at all, it is confusing and counterintuitive and, as you've noticed with the compiler implementation, makes single-pass compilation impossible and requires juggling and swapping states.

I do agree that function hoisting for enabling mutual recursion is fine but things like

let x = foo();

function foo() {

}

Just do not feel right (yes I know it is established practise in JS / ECMA Script).
What I was considering the past is simple function forward declarations:

function foo;
let x = foo();

function foo() {

}

function is_odd;
function is_even(n) { return n == 0 ? true : is_odd(n - 1); }
function is_odd(n) { return n == 0 ? false : is_even(n - 1); }

print(is_even(4), "\n");
print(is_odd(3), "\n");

It is slightly more verbose but simplifies compiler implementation a lot and clearly communicates intent.

@nbd168
Copy link
Contributor Author

nbd168 commented Feb 11, 2026

Fair enough. So function foo; as an alternative for the currently used let foo; variant except with enforced function type, right? I can look into that.

@jow-
Copy link
Owner

jow- commented Feb 11, 2026

Yes, a not fully fleshed out proposal is:

  • function foo; reserves a slot and constrains foo to function type
  • treat as constant: function foo; foo = function() {} -> Syntax error: Invalid assignment to constant 'foo'
  • attempts to redeclare foo result in a syntax error: function foo; let foo = 1; => Syntax error: Function 'foo' redeclared as different kind of symbol or Syntax error: Function 'foo' redeclared
  • a function stub (forward declaration) might only be declared once:
    • function foo; function foo() {} -> okay
    • function foo; function foo() {}; function foo() {} -> Syntax error: Function 'foo' redeclared
  • multiple forward declarations: undecided. If we treat it like let and const, it would be disallowed (let x; let x; -> Syntax error: Variable 'x' redeclared), but given that function prototypes have special semantics it might make sense to allow multiple ones (function foo; function foo; function foo() {}), to also mimic the behavior of C somewhat
  • forward declaration after actual declaration: depends on what is decided for the previous point. Gut feeling would be to disallow (function foo() {}; function foo; -> Syntax error: Function 'foo' redeclared) but it would probably negatively impact the usefulness of forward declarations as "safe way" to mark an identifer as callable value implemented somewhere
  • Call on forward declaration never fully declared -> runtime error Type error: left-hand side is not a function like let foo; foo();

Like ECMAScript, treat `export function foo() {}` as a complete
statement that does not require a trailing semicolon.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Add `function foo;` as a forward declaration that reserves a constant
slot (initialized to null), later filled by a matching `function foo() {}`
definition. This enables mutual recursion between functions at the same
scope level without the `let foo; foo = function() {};` workaround.

Forward-declared bindings are constant, preventing reassignment and
redeclaration. Duplicate forward declarations, forward declarations
after definitions, and unfilled stubs called at runtime are all handled
with appropriate error messages.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
@nbd168 nbd168 force-pushed the compiler-improvements branch from 72f85f9 to d9e24e4 Compare February 11, 2026 17:50
@nbd168
Copy link
Contributor Author

nbd168 commented Feb 13, 2026

Does this look like what you wanted?

@jow-
Copy link
Owner

jow- commented Feb 13, 2026

Yes! I hope to merge it during the weekend, on a first glance it looks really good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants