Why don't make "balance" attribute-type implicit? Why it needs to be defined explicitly?

I got this question on Telegram but my answer will be lost to Google searchers if I don't paste it here.

In TokenScript, for non-native tokens like ERC20, balance attribute type has to be explicitly defined. The question was: since balance seems to be defined the same in every TokenScript, shouldn't it be made implicit like ownerAddress, provided to the TokenScript user (e.g. JavaScript in <view>)?

If we do so, it will make it impossible for a contact to be developed without providing getBalance function. The short answer is: if Ethereum doesn't enforce every token contract to have getBalance function, TokenScript shouldn't. But let me elaborate with scenarios.

First, some tokens don't have a balance. They are typically delivery side tokens, like goods and services, digital assets or rights. examples:

  • tickets, with which numero (№) make more sense than 'balance', or;
  • pizzas, with which 'count' make more sense than balance.

There is also the argument that TokenScript is designed for cross-chain use which requires it blockchain agnostic. Some blockchain doesn't have currency (Fabric, 2nd popular right after Ethereum in enterprise adoption), therefore they are less influenced by the thinking that every token is a payment-side (not delivery-side) token like currency. Corda, as another example, doesn't enforce the data type for balance. It can be BigDecimal or double if you like.

There is also a third argument: if you enforce balance, what transformation rules do we use? always e18? Sangalli argued that DAI's choice of e18 is a problem by design, so if Sangalli goes ahead to not to use e18 transformation rule when he issues SangalliDAI, he will have to deal with incompatibility with others' way of using balance. For another example, the author of Office Entry Token, he might provide a getBalance that returns only 1 or 0, which he interprets as "have access" or "do not have access", then the transformation rule might be a mapping to boolean in TokenScript, incompatible with implicitly provided balance. (If the developer thinks in terms of Return Code instead of Return Value, then 0 represents have access and 1 represents not have access.)

Finally, if JavaScript developers believe there will always be a balance, it creates the situation that we can never get rid of it no matter how much a hurdle it is for the future. This situation can be compared to a modern-day cheque in the U.S. Some utility company asks for a cheque, since they believe all bank accounts by default issues cheques (the "getBalance" of the 18th century), forcing the banks to issue blank cheques to customers in the 21st century. The banks want to avoid cheques (to avoid overdraft entirely), but couldn't do so because it was an implicit rule. As a result, everybody has to bear the additional attack surface that someone might fake their cheque.