From 1f1f4a62775dfc536f8971f3c177b59c7624807b Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 25 Aug 2022 17:00:29 -0700 Subject: [PATCH] Add normative convention about order of operations Triggered by the discussion in https://github.com/tc39/proposal-temporal/pull/2377#discussion_r948263720 Arguments should consistently be processed in order. --- normative-conventions.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/normative-conventions.md b/normative-conventions.md index cd55a78..83d98dc 100644 --- a/normative-conventions.md +++ b/normative-conventions.md @@ -37,3 +37,30 @@ For the purposes of this guideline `-0` is considered to be an integral number ( Some APIs intentionally round non-integral inputs, for example as an attempt to provide a best-effort behavior, rather than because the API fundamentally only makes sense with integers. This guideline does not apply to those cases. NB: This convention is new as of 2024, and most earlier parts of the language do not follow it. + +### Order of observable operations when processing arguments + +When writing the algorithm steps for the implementation of a JS built-in function or method, this order should be followed: + +1. If applicable, process and validate the receiver. +1. Process and validate each argument, in order. +1. Perform validation of any other preconditions, if any. +1. Perform the actual work of the function. + +Validating the arguments includes type checking, but also unobservable things like supplying default arguments. +So, for a fictitious `addTwoNumbersThatArentTooFarApart(a, b = 42)` function, the algorithm steps could look like this: + +> 1. If _a_ is not a Number, throw a **TypeError** exception. +> 1. Let _firstOperand_ be ℝ(_a_). +> 1. If _b_ is **undefined**, then +> 1. Let _secondOperand_ be 42. +> 1. Else, +> 1. If _b_ is not a Number, throw a **TypeError** exception. +> 1. Let _secondOperand_ be ℝ(_b_). +> 1. If abs(_firstOperand_ - _secondOperand_) > 10, throw a **RangeError** exception. +> 1. Return 𝔽(_firstOperand_ + _secondOperand_). + +The first four steps process and validate each argument in order; Step 5 validates the other precondition that the numbers aren't too far apart; and Step 6 does the actual work. + +NB: This convention is new as of 2022. +However, many parts of the language do already follow it.