Skip to content

[Suggestion] Allow a single non-extern overload #13009

Description

@Geokureli

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

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<Int>;

	public function new(columns:Int, ?data:Array<Int>) {
		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 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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions