Conversation
This looks like a super useful feature 🔥 But maybe what would be nice is to split the object into separate arguments, so it doesn't needlessly add runtime overhead. If we are talking about logging use-case, I think this is an important point. Also, for the cases I personally see, I think in the beginning, it would be best to simply include the prepared path to the function call like: |
@DZakh thanks for the feedback! The current object is bloated, I agree, but I don't see where runtime performance would be an issue here...? Could you expand on that part? More opinions on what to include/not include would be good. cc @cknitt @fhammerschmidt @cometkim @tsnobip Also, there's an alternative solution where we could just allow all the constants ( |
Awesome work! I agree with @DZakh. While it can be nice in some situations to get everything in a single object, efficiency-wise it is not ideal, e.g. for a logger. Personally, for a logger, I would like to be able to obtain the |
So, how about this:
This gives a compact represenation (less bundle bloat, no uneccessary allocation of objects) while preserving the usefulness to the consumer, with the cost of running a function like What do you think? |
One concern: Bundling error messages or source information from libraries used in the critical path is not a good idea and should be treated as a development-only feature. As we don't have such a flag, as other compilers have a
Some critical JS libraries (especially for the Web) have an additional compilation step for similar cases, like invariant. |
I think for some cases stripping it out of release builds makes sense, but there are plenty of cases where it doesn't (like a logger you use in production). Voiding the string itself in build probably makes the most sense, we can't really change the fn signature depending on build env. Anyway, I lean towards saying that this is a separate issue since we don't have that type of setup today. For this particular feature we just need to decide whether to include it or not, and if so in which form. |
100% inspired by MoonBit's autofill
SourceLoc
function argument, this makes it possible to inject a labelled argument to any function, and as long as it's optionak, has the type ofsourceLocPos
and/orsourceLocValuePath
(builtin types), and has a default value of%autoFill
. Then each call to that function will inject information about the call site, without needing to pass those argument explicitly.This is useful in many different scenarios, like for example logging (see
rescript-logger
which does the same, but with a PPX), tests, error reporting, and so on.Example:
Tst.res
OtherFile.res
sourceLocValuePath
is a string at runtime in the form ofPath.To.Module.value
. So, if you'reMyModule
inSomeFile.res
, and inside of a let binding calledmyFunction
, you'll getSomeFile.MyModule.myFunction
.sourceLocPos
is a string at runtime in the form of<filename>;<startLine>;<startCol>;<endLine>;<endCol>
.Both are abstract types, and soon I'll add tools and functions that can be used to work with those abstract types.
Questions
Are what I've added so far enough? Do we want more/less information? Other things to think/worry about?
Things left to figure out
Figure out the editor tooling - do we just hide injectable args?Fixed by enforcing an optional arg instead of required.sourceLoc
which is a builtin