HaxeFoundation / HaxeFoundation/haxe

[Suggestion] Allow a single non-extern overload

Open
#13,009 3 comments 3 reactions 0 assignees View on GitHub
Dominant language
Haxe
Stars
6.9k
Forks
715
Avg merge
2d 2h
Merged PRs (30d)
11

Description

I would love it if every overloaded method was allowed one overload that was not `inline extern`, meaning one overload is actually compiled into the source, and available at runtime.

## Example
```hx
class Test {
static function main() {
final tiles = new TileGrid(4, [1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1]);
trace(tiles.get(0, 3));
}
}

class TileGrid {
final columns:Int;
final data:Array;

public function new(columns:Int, ?data:Array) {
this.columns = columns;
this.data = data ?? [];
}

inline public function getIndex(x:Int, y:Int) {
return y * columns + x;
}

overload public function get(index:Int) {
return data[index];
}

overload public inline extern function get(x:Int, y:Int) {
return get(getIndex(x, y));
}
}
```

## Reasons

Often my pattern for overloads is to have various `foo()` overloads and a non-inlined `fooHelper()` that all of the overloads ultimately call. This is fine for the most part but adds obfuscation. There's a secret private method that devs need to use, for reflection, hscript, or overriding the behavior.

One of my go-to ways of changing the functionality of an outdated or badly formed method in flixel, while respecting semver is to overload it and deprecating the old one, however, this is actually a breaking change for the above stated reasons: overrides will throw an error, and hscript will no longer work. People using reflection know they're in dangerous territory, but since most flixel devs don't know how to code without reflection and will resort to shadowing classes without a second thought to remove breaking overloads.

## Implementation
In my limited compiler knowledge, giving clear error messages seems like the real challenge here. We need to remove the Error for `Invalid modifier: overload is only supported on extern functions`, ignore the first non-extern overload method of a certain name and give a new error on the second. I have no idea how hard this is, but I'm banking on the idea that this might be easy, it might be covered by the `Duplicate class field declaration : Type.func` error with some special check for the overload modifier allowing the compiler to specify both offending signatures

## Impact on existing code
None

## Confusion around Extern
I'm also somewhat confused by the extern modifier requirement on all overloads. Granted, I'm confused by the [extern doc](https://haxe.org/manual/class-field-extern.html) to begin with: I'm under the impression that all inlined methods are not generated, but this suggests some are, with no examples, given. Many overloads just call other methods, so calling them "extern" seems fitting, but what about methods that do not? does it make sense to allow the omission of extern in those?

Contributor guide

Open the contributing guide

Research direction

Start by locating the compiler validation that emits “Invalid modifier: overload is only supported on extern functions” and the duplicate class field declaration diagnostic. Define and test the rule for one non-extern overload per method name, including the error for a second one and the existing extern overload behavior; the issue’s TileGrid example provides the intended successful case.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.