From d41269d176e1ef9266c1f17e6ddf050198677528 Mon Sep 17 00:00:00 2001 From: Apprentice-Alchemist <53486764+Apprentice-Alchemist@users.noreply.github.com> Date: Sat, 1 Oct 2022 14:10:34 +0200 Subject: [PATCH 01/10] Initial draft. --- proposals/0000-track-caller.md | 80 ++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 proposals/0000-track-caller.md diff --git a/proposals/0000-track-caller.md b/proposals/0000-track-caller.md new file mode 100644 index 0000000..465b4a4 --- /dev/null +++ b/proposals/0000-track-caller.md @@ -0,0 +1,80 @@ +# Caller tracking. + +* Proposal: [HXP-NNNN](NNNN-filename.md) +* Author: [Zeta](https://github.com/Apprentice-Alchemist) + +## Introduction + +`@:trackCaller` metadata + `haxe.Magic.callLocation()` as a replacement for `?pos:haxe.PosInfos`. + +## Motivation + +The magic `?pos:haxe.PosInfos` argument does not work with rest arguments. + +## Detailed design + +```hx +@:trackCaller +function foo() { + trace(haxe.Magic.callLocation()); +} + +foo(); + +// turns into + +function foo(caller:haxe.PosInfos) { + trace(caller); +} + +foo(haxe.Magic.currentLocation()); +``` +When rest arguments are involved, the exact implementation depends on how rest arguments are implemented. + +When `@:trackCaller` is applied to interface methods, abstract methods or methods that will be overriden, +the implementors/overriders inherit the attribute. + +`var closureOfTrackCallerFun = foo` turns into `var closureOfTrackCallerFun = foo.bind(haxe.Magic.currentLocation())`. + +`haxe.Magic.callLocation()` returns the position of the last call of a `@:trackCaller` function in a non-trackcaller functions. + +For example: +```hx +@:trackCaller +function bar() { + foo(); +} + +@:trackCaller +function foo() { + trace(haxe.Magic.callLocation()); +} + +// turns into + +function bar(caller: haxe.PosInfos) { + foo(caller); +} + +function foo(caller:haxe.PosInfos) { + trace(caller); +} +``` + +## Impact on existing code + +None. + +## Drawbacks + +None. + +## Alternatives + +The magic `?pos:haxe.PosInfos` argument could be made even more magic by being allowed after Rest arguments. + +## Opening possibilities + +## Unresolved questions + +Where to put the `callLocation` function. From 09e8c983acc0c14b018e70631744a2964cf66c66 Mon Sep 17 00:00:00 2001 From: Apprentice-Alchemist <53486764+Apprentice-Alchemist@users.noreply.github.com> Date: Sat, 1 Oct 2022 18:57:10 +0200 Subject: [PATCH 02/10] More alternatives. --- proposals/0000-track-caller.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/proposals/0000-track-caller.md b/proposals/0000-track-caller.md index 465b4a4..8cd1447 100644 --- a/proposals/0000-track-caller.md +++ b/proposals/0000-track-caller.md @@ -73,6 +73,15 @@ None. The magic `?pos:haxe.PosInfos` argument could be made even more magic by being allowed after Rest arguments. +Walking up the stack in `callLocation` is also a possibility, but would break when inlining is involved. +It also requires generation of some kind of debug info. + +Make the compiler allow `callLocation` in default arguments eg `pos:haxe.PosInfos = callLocation()`. +Would break in the case `(pos:haxe.PosInfos = callLocation(), ...rest:haxe.PosInfos)`. + +Make `@:callerLocation` meta on default argument eg `@:callerLocation pos:haxe.PosInfos = cast null`. +Would break in the case `(@:callerLocation pos:haxe.PosInfos = cast null, ...rest:haxe.PosInfos)` unless magic semantics are given to the default argument when annoated with `@:callerLocation`. + ## Opening possibilities ## Unresolved questions From 1af447d258b7bd36a97884fce7cb41bbf8634a9b Mon Sep 17 00:00:00 2001 From: Apprentice-Alchemist <53486764+Apprentice-Alchemist@users.noreply.github.com> Date: Sat, 1 Oct 2022 18:57:35 +0200 Subject: [PATCH 03/10] Leave interaction with interfaces/abstract/overriden methods as an unresolved question. --- proposals/0000-track-caller.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/proposals/0000-track-caller.md b/proposals/0000-track-caller.md index 8cd1447..a4b8a22 100644 --- a/proposals/0000-track-caller.md +++ b/proposals/0000-track-caller.md @@ -31,9 +31,6 @@ foo(haxe.Magic.currentLocation()); ``` When rest arguments are involved, the exact implementation depends on how rest arguments are implemented. -When `@:trackCaller` is applied to interface methods, abstract methods or methods that will be overriden, -the implementors/overriders inherit the attribute. - `var closureOfTrackCallerFun = foo` turns into `var closureOfTrackCallerFun = foo.bind(haxe.Magic.currentLocation())`. `haxe.Magic.callLocation()` returns the position of the last call of a `@:trackCaller` function in a non-trackcaller functions. @@ -87,3 +84,5 @@ Would break in the case `(@:callerLocation pos:haxe.PosInfos = cast null, ...res ## Unresolved questions Where to put the `callLocation` function. + +How this would work with interfaces and abstract/overriden methods. \ No newline at end of file From 3a5c3af90b31b3bf8822ce78f24ab05ac062e9cd Mon Sep 17 00:00:00 2001 From: Apprentice-Alchemist <53486764+Apprentice-Alchemist@users.noreply.github.com> Date: Sat, 1 Oct 2022 19:04:33 +0200 Subject: [PATCH 04/10] Fix typo. --- proposals/0000-track-caller.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0000-track-caller.md b/proposals/0000-track-caller.md index a4b8a22..cf37ae2 100644 --- a/proposals/0000-track-caller.md +++ b/proposals/0000-track-caller.md @@ -77,7 +77,7 @@ Make the compiler allow `callLocation` in default arguments eg `pos:haxe.PosInfo Would break in the case `(pos:haxe.PosInfos = callLocation(), ...rest:haxe.PosInfos)`. Make `@:callerLocation` meta on default argument eg `@:callerLocation pos:haxe.PosInfos = cast null`. -Would break in the case `(@:callerLocation pos:haxe.PosInfos = cast null, ...rest:haxe.PosInfos)` unless magic semantics are given to the default argument when annoated with `@:callerLocation`. +Would break in the case `(@:callerLocation pos:haxe.PosInfos = cast null, ...rest:haxe.PosInfos)` unless magic semantics are given to the default argument when annotated with `@:callerLocation`. ## Opening possibilities From 497cc9fedbde9d9efd1b68db0555a7f2899abacc Mon Sep 17 00:00:00 2001 From: Apprentice-Alchemist <53486764+Apprentice-Alchemist@users.noreply.github.com> Date: Sat, 1 Oct 2022 19:45:22 +0200 Subject: [PATCH 05/10] Rename `callLocation` to `callerLocation`. --- proposals/0000-track-caller.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/proposals/0000-track-caller.md b/proposals/0000-track-caller.md index cf37ae2..28bc477 100644 --- a/proposals/0000-track-caller.md +++ b/proposals/0000-track-caller.md @@ -5,7 +5,7 @@ ## Introduction -`@:trackCaller` metadata + `haxe.Magic.callLocation()` as a replacement for `?pos:haxe.PosInfos`. +`@:trackCaller` metadata + `haxe.Magic.callerLocation()` as a replacement for `?pos:haxe.PosInfos`. ## Motivation @@ -16,7 +16,7 @@ The magic `?pos:haxe.PosInfos` argument does not work with rest arguments. ```hx @:trackCaller function foo() { - trace(haxe.Magic.callLocation()); + trace(haxe.Magic.callerLocation()); } foo(); @@ -33,7 +33,7 @@ When rest arguments are involved, the exact implementation depends on how rest a `var closureOfTrackCallerFun = foo` turns into `var closureOfTrackCallerFun = foo.bind(haxe.Magic.currentLocation())`. -`haxe.Magic.callLocation()` returns the position of the last call of a `@:trackCaller` function in a non-trackcaller functions. +`haxe.Magic.callerLocation()` returns the position of the last call of a `@:trackCaller` function in a non-trackcaller functions. For example: ```hx @@ -44,7 +44,7 @@ function bar() { @:trackCaller function foo() { - trace(haxe.Magic.callLocation()); + trace(haxe.Magic.callerLocation()); } // turns into @@ -70,11 +70,11 @@ None. The magic `?pos:haxe.PosInfos` argument could be made even more magic by being allowed after Rest arguments. -Walking up the stack in `callLocation` is also a possibility, but would break when inlining is involved. +Walking up the stack in `callerLocation` is also a possibility, but would break when inlining is involved. It also requires generation of some kind of debug info. -Make the compiler allow `callLocation` in default arguments eg `pos:haxe.PosInfos = callLocation()`. -Would break in the case `(pos:haxe.PosInfos = callLocation(), ...rest:haxe.PosInfos)`. +Make the compiler allow `callerLocation` in default arguments eg `pos:haxe.PosInfos = callerLocation()`. +Would break in the case `(pos:haxe.PosInfos = callerLocation(), ...rest:haxe.PosInfos)`. Make `@:callerLocation` meta on default argument eg `@:callerLocation pos:haxe.PosInfos = cast null`. Would break in the case `(@:callerLocation pos:haxe.PosInfos = cast null, ...rest:haxe.PosInfos)` unless magic semantics are given to the default argument when annotated with `@:callerLocation`. @@ -83,6 +83,6 @@ Would break in the case `(@:callerLocation pos:haxe.PosInfos = cast null, ...res ## Unresolved questions -Where to put the `callLocation` function. +`haxe.Magic` is a bit too magic. Where should the `callerLocation` function live? How this would work with interfaces and abstract/overriden methods. \ No newline at end of file From 9174624df0c9b5d3c70ce9d269acb08cc17ccaf9 Mon Sep 17 00:00:00 2001 From: Apprentice-Alchemist <53486764+Apprentice-Alchemist@users.noreply.github.com> Date: Sat, 1 Oct 2022 19:53:30 +0200 Subject: [PATCH 06/10] Add opening possibilites. --- proposals/0000-track-caller.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/0000-track-caller.md b/proposals/0000-track-caller.md index 28bc477..d0e538e 100644 --- a/proposals/0000-track-caller.md +++ b/proposals/0000-track-caller.md @@ -81,6 +81,9 @@ Would break in the case `(@:callerLocation pos:haxe.PosInfos = cast null, ...res ## Opening possibilities +Turn `trace` into `@:trackCaller function trace(...args:Dynamic)`. +Then the only magic left would be auto-importing it everywhere. + ## Unresolved questions `haxe.Magic` is a bit too magic. Where should the `callerLocation` function live? From 7731ac21b921d343852958155927c8bd7b14ad76 Mon Sep 17 00:00:00 2001 From: Apprentice-Alchemist <53486764+Apprentice-Alchemist@users.noreply.github.com> Date: Sat, 1 Oct 2022 20:10:23 +0200 Subject: [PATCH 07/10] Use `$currentLocation` to represent "current location". --- proposals/0000-track-caller.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/0000-track-caller.md b/proposals/0000-track-caller.md index d0e538e..fad088e 100644 --- a/proposals/0000-track-caller.md +++ b/proposals/0000-track-caller.md @@ -27,11 +27,11 @@ function foo(caller:haxe.PosInfos) { trace(caller); } -foo(haxe.Magic.currentLocation()); +foo($currentLocation); ``` -When rest arguments are involved, the exact implementation depends on how rest arguments are implemented. +When rest arguments are involved, the exact implementation may be different (possibly depending on how they are implemented on the target). -`var closureOfTrackCallerFun = foo` turns into `var closureOfTrackCallerFun = foo.bind(haxe.Magic.currentLocation())`. +`var closureOfTrackCallerFun = foo` turns into `var closureOfTrackCallerFun = foo.bind($currentLocation)`. `haxe.Magic.callerLocation()` returns the position of the last call of a `@:trackCaller` function in a non-trackcaller functions. From fe2feba41b0088f77e1c603d02256475655e40ba Mon Sep 17 00:00:00 2001 From: Apprentice-Alchemist <53486764+Apprentice-Alchemist@users.noreply.github.com> Date: Sat, 1 Oct 2022 20:11:09 +0200 Subject: [PATCH 08/10] Mention how propagation of the caller location could be turned off. --- proposals/0000-track-caller.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/0000-track-caller.md b/proposals/0000-track-caller.md index fad088e..289aad8 100644 --- a/proposals/0000-track-caller.md +++ b/proposals/0000-track-caller.md @@ -34,6 +34,7 @@ When rest arguments are involved, the exact implementation may be different (pos `var closureOfTrackCallerFun = foo` turns into `var closureOfTrackCallerFun = foo.bind($currentLocation)`. `haxe.Magic.callerLocation()` returns the position of the last call of a `@:trackCaller` function in a non-trackcaller functions. +This behaviour could be then be turned off by using `@:trackCaller(noPropagate)`. For example: ```hx @@ -81,7 +82,7 @@ Would break in the case `(@:callerLocation pos:haxe.PosInfos = cast null, ...res ## Opening possibilities -Turn `trace` into `@:trackCaller function trace(...args:Dynamic)`. +Turn `trace` into `@:trackCaller(noPropagate) function trace(...args:Dynamic)`. Then the only magic left would be auto-importing it everywhere. ## Unresolved questions From 123ae725da4e93e312bcfc51e43ff5fcbcfd15ec Mon Sep 17 00:00:00 2001 From: Apprentice-Alchemist <53486764+Apprentice-Alchemist@users.noreply.github.com> Date: Sat, 1 Oct 2022 20:22:35 +0200 Subject: [PATCH 09/10] Propose something for where `callerLocation` should live. --- proposals/0000-track-caller.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0000-track-caller.md b/proposals/0000-track-caller.md index 289aad8..2100e9e 100644 --- a/proposals/0000-track-caller.md +++ b/proposals/0000-track-caller.md @@ -87,6 +87,6 @@ Then the only magic left would be auto-importing it everywhere. ## Unresolved questions -`haxe.Magic` is a bit too magic. Where should the `callerLocation` function live? +`haxe.Magic` is a bit too magic. Where should the `callerLocation` function live? A module-level function in `haxe.PosInfos`? How this would work with interfaces and abstract/overriden methods. \ No newline at end of file From 0f1decb97289bc0c60ccd752ba505cc699fd7ff4 Mon Sep 17 00:00:00 2001 From: Apprentice-Alchemist <53486764+Apprentice-Alchemist@users.noreply.github.com> Date: Sat, 1 Oct 2022 20:27:53 +0200 Subject: [PATCH 10/10] Add `noPropagate` to unresolved questions. --- proposals/0000-track-caller.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/0000-track-caller.md b/proposals/0000-track-caller.md index 2100e9e..9320e78 100644 --- a/proposals/0000-track-caller.md +++ b/proposals/0000-track-caller.md @@ -89,4 +89,6 @@ Then the only magic left would be auto-importing it everywhere. `haxe.Magic` is a bit too magic. Where should the `callerLocation` function live? A module-level function in `haxe.PosInfos`? -How this would work with interfaces and abstract/overriden methods. \ No newline at end of file +How this would work with interfaces and abstract/overriden methods. + +Is `noPropagate` the best name to disable propagation? Maybe `@:trackCaller(ignorePropagation)` is better? \ No newline at end of file