Switch to a more conventional parameter-passing scheme by default?
Summary: Of all the features in QL, the way we handle parameters -- late-bound, instead of early-bound as in almost all languages -- has proven to be the most problematic. Can/should we change that?
The original reason for it was that we specifically needed late-bound for _sort()
, which was implemented quite early -- Querki being Querki, that decision was put into user-space.
But that may have been a bad choice. In practice, traditional parameter passing -- where the parameter is evaluated before calling the function -- is what folks usually expect. The current approach, which is basically an insufficiently-hygienic macro system, violates both programmer expectations and (I think) referential integrity, as well as causing a host of bugs in how it interacts with bound names. We have the ~!
workaround, but nobody (including me) ever remembers to use that, and it's probably incorrect for that to be a call-site operation: it should be decided declaration-site instead.
And it isn't clear that it is all that necessary. Internal methods like _sort()
are very explicit at the code level about how they deal with their parameters -- the QL defaults are, in practice, irrelevant.
So maybe we should just change this. Redoing the call handling, to process parameters at the callsite while also making the raw expression available, would fix a lot of bugs. We should have a mechanism for accessing the raw expression -- maybe some syntax other than the standard $_1
-- but that would be only used when you really wanted that sort of higher-level functionality.
How much havoc would this cause? I have no idea. There is some temptation to leave $_1
as it is, and choose something else for the conventionally-bound version, so that existing code would continue to work, and places that are found to be a problem can be easily fixed.