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

Implicit conversion behaviour #90

Open
Kacarott opened this issue Apr 14, 2022 · 0 comments
Open

Implicit conversion behaviour #90

Kacarott opened this issue Apr 14, 2022 · 0 comments
Labels
improvement Improve existing behaviour or code v2 To be implemented for version 2

Comments

@Kacarott
Copy link
Collaborator

Kacarott commented Apr 14, 2022

The implicit behaviour of some parts of the library has been identified as an area which could use improvement. This thread aims to be a general place to discuss such issues and topics.

Currently there are two main sources of implicit conversions between JS Numbers, and ints encoded as LC Terms.

Number -> Term

Compiled LC terms, when accepting an input, will implicitly check if the input is a Number, and if so, automatically convert it to a term, before passing it to the function. Some of the reasons for this design decision were:

  • Number literals are a supported part of LC as a language. A function can be passed a number literal inside LC source with no problem, and so it feels intuitive to be able to also pass a number literal to the same function, in a JS context.
  • The vast majority of cases where numbers are passed to a term, will be expecting encoded numbers, for testing behaviour of developed functions. (eq. multiply(9)(7)). By allowing native JS Numbers to be passed and implicitly converted, makes the use of these functions (most of the time) much easier, and more readable.

The obvious downside, is when a user needs to pass a number in as-is. I would not expect such a case to happen very often, however it needs to be possible. In the LC library (but not exported) there is a function Primitive designed specifically to wrap a Number literal to allow it to be passed to a function, without conversion. One improvement (which is already planned) is to export this function, to make it useable.

Term -> Number

Currently, all compiled LC terms contain a .valueOf property which attempts to convert the term to a Number. This was also initially designed for convenience in writing tests and assertions, however since then was added assert.numEql, which solves the main use case of the property. Besides convenience, the logic behind the design decision, was that in LC, everything is of course a function. These functions often will be encodings of various data and data structures, however the only kinds of encodings supported directly by the compiler are number encodings. With that in mind, if there is ever an attempt to coerce a value out of an LC term, the only option for providing such a value, is to attempt to convert to a number.

Of course, there are also downsides. As with any implicit behaviour, it can lead to unexpected and confusing errors and problems. For example #89 where assert.equal produced unexpected behaviour, due to it implicitly calling .valueOf on its arguments, which of course tried to treat a normal function as a number.

How to improve

The point of this issue thread is to try to get opinions from people, identify specific problematic cases, and to try generate potential solutions and/or workarounds for problematic edge cases. Any planned changes resulting from this discussion will likely be scheduled for v2, since there is a good chance they will be breaking changes.

@Kacarott Kacarott added v2 To be implemented for version 2 improvement Improve existing behaviour or code labels Apr 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improvement Improve existing behaviour or code v2 To be implemented for version 2
Projects
None yet
Development

No branches or pull requests

1 participant