Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spec language on eager vs. lazy evaluation should be clarified #784

Closed
catamorphism opened this issue May 6, 2024 · 5 comments · Fixed by #901
Closed

Spec language on eager vs. lazy evaluation should be clarified #784

catamorphism opened this issue May 6, 2024 · 5 comments · Fixed by #901
Labels
blocker-candidate The submitter thinks this might be a block for the Technology Preview editorial LDML46.1 MF2.0 Draft Candidate

Comments

@catamorphism
Copy link
Collaborator

In #753 , @echeran brought up the example of a custom function getSystemTimeInMillisNow() that would return the current time.

In the spec intro we currently have the language:

"This specification does not require either eager or lazy expression resolution of message parts; do not construe any requirement in this document as requiring either."

Consider the following example (which formats to a string with the current time repeated twice... or does it?):

.local $x = {:getSystemTimeInMillisNow}
{{{$x} {$x}}}

In an eager implementation, this is guaranteed to print the same time twice.

In a lazy call-by-need implementation, where the right-hand side of $x is guaranteed to be evaluated at most once, it's also guaranteed to print the same time twice.

In a lazy call-by-name implementation, it may print out two different times.

In general, custom functions might have side effects observable by MF2, and getting the current time is a reasonable example of one. That means one can't assume that call-by-need and call-by-name are going to be equivalent.

I think all that's needed is an editorial note pointing out that depending on the contents of the custom function registry, call-by-need and call-by-name may be observably different and the implementor should think about which one is the least surprising.

@catamorphism catamorphism added editorial LDML46 LDML46 Release (Tech Preview - October 2024) labels May 6, 2024
@echeran
Copy link
Collaborator

echeran commented May 9, 2024

One thought about what to say to users in the spec text: it's not just the laziness that users should consider from side-effecting functions (which is more about exactly when to evaluate), but also whether they want to memoize those functions (that is, cache the function result per each distinct set of input given), which would be more about giving consistent output across invocations of such a function.

Also thanks to @catamorphism since this well written issue follows from his comment over on #753:

This is indeed an important point, and not just an implementation detail IMO.
...
maybe it should be noted somewhere in the spec that if custom functions with observable side effects exist, then careful thought should be put into lazy implementations.

@catamorphism
Copy link
Collaborator Author

One thought about what to say to users in the spec text: it's not just the laziness that users should consider from side-effecting functions (which is more about exactly when to evaluate), but also whether they want to memoize those functions (that is, cache the function result per each distinct set of input given), which would be more about giving consistent output across invocations of such a function.

That's right -- there are two different ways to implement laziness, one by using memoization (aka call-by-need) and one without, and the thing to explain is that the difference between the two is actually observable from a message, if certain custom function implementations exist.

@mihnita mihnita added the blocker-candidate The submitter thinks this might be a block for the Technology Preview label Aug 28, 2024
@aphillips
Copy link
Member

(as contributor)

Note this text in the specification:

However, when an expression is resolved, it MUST behave as if all preceding declarations affecting variables referenced by that expression have already been evaluated in the order in which the relevant declarations appear in the message.

This suggests that the example message resolves the value of $x once, even though it is done lazily.


(chair 🎩 on)

We're at the point of releasing v46 Tech Preview. If you think a change is needed in the text of the specification, please make a PR.

@aphillips aphillips added LDML46.1 MF2.0 Draft Candidate and removed LDML46 LDML46 Release (Tech Preview - October 2024) labels Sep 16, 2024
@aphillips
Copy link
Member

Moving to 46.1

@aphillips
Copy link
Member

Does this need a PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocker-candidate The submitter thinks this might be a block for the Technology Preview editorial LDML46.1 MF2.0 Draft Candidate
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants