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

Enhance current Numeric Literal features #972

Open
5 tasks done
gusty opened this issue Jan 27, 2021 · 2 comments
Open
5 tasks done

Enhance current Numeric Literal features #972

gusty opened this issue Jan 27, 2021 · 2 comments

Comments

@gusty
Copy link

gusty commented Jan 27, 2021

Enhance current functionality that allows custom numeric literals.

The existing way of approaching this problem in F# is using the existing feature as it is by opening a NumericLiteral module containing some specific static methods, but it has many limitations:

  • It doesn't work with float-like numbers
  • It evaluates the literal each time
  • It works with a predefined set of suffixes but it doesn't allow to redefine existing literals or the default literal (without suffix).
  • It doesn't allow to restrict the domain, e.g. forbid negatives

The proposal:

  • Allow the user opening a module NumericLiteralX even when X is already in use e.g. f
  • Allow the user opening a module NumericLiteralD (where D stands for default) which will be called when no suffix is used in number literals. Or just NumericLiteral alone
  • Allow the user to define the default constraint, which will in anycase make the language more consistent. This is important to deal with generic numbers, in order to make them easy to default to let's say integers.
  • Introduce an optional method to interpret float-like literals, something like FromDecimal which would return a tuple of two BigIntegers, the first element being the number before the '.' and the second the decimal part.
  • Implement this optimization Warn on implicit type functions, or an attribute to memoize them using type-indexed table [ RFC FS-1038 ] #602 (comment) to avoid recomputing literals twice at runtime. We assume literals can't have side-effects.
  • Currently unary operators are applied to the literal before computing it. This means that for instance doing a FromInt over -5N will return -5. This behavior is a bit unexpected, it should ideally return 5 and then once the literal is resolved, apply (if defined) the unary - operator. Correcting this will allow restricting our custom number domain to positives.

Pros and Cons

The advantages of making this adjustment to F# are:

  • Allow user to completely change behavior of standard literals
  • Better performance for custom literals, right now they are computed each time
  • Allow customization of decimal-like number literals
  • Provide a way to represent literals for restricted domains, which makes it easy to model business rules
  • This will also allow a library to define something like Generic Literal numbers in a concise and efficient way. F# doesn't come with Generic Number Literals out of the box as it was already decided in F# 1.0 so adding them would be a breaking change, but allowing a library to provide them won't affect existing code at all, and in scenarios where numeric code is central, it would lot of noise, like unnecessary conversions, suffixes like L, .0 or .0m and excessive overload of operators.
  • Finally we can say that this would "finish" the original feature, in the sense that it feels a bit half-way. e.g. the sole fact that it doesn't allow you to deal with float-like numbers makes you feel it's not complete.

The disadvantages of making this adjustment to F# are:

  • It's work
  • Bad use of this feature might result in obscure code

Extra information

Estimated cost (XS, S, M, L, XL, XXL): M

Related suggestions:

Affidavit (please submit!)

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.

Please tick all that apply:

  • This is not a breaking change to the F# language design
  • I or my company would be willing to help implement and/or test this

For Readers

If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.

@bmitc
Copy link

bmitc commented Mar 11, 2023

I would love to see some of these features implemented. Is it possible that they could be staged and done in a piecemeal fashion? For example, I think

Allow the user opening a module NumericLiteralX even when X is already in use e.g. f

is essential for the NumericLiteral feature. At present, being limited to only a handful of capital letters make the feature not usable for many applications. For example, I would like to implement a literal for dual numbers, but none of the available capital characters work for such a use case.

Also, supporting FromFloat and FromFloat32 are essential as well.

But both of these features seem to me like they could be implemented independently. With some guidance, I would be willing to try and tackle this.

@bmitc
Copy link

bmitc commented Mar 11, 2023

It looks like the float conversion has already been suggested and approved in principle in #445.

@dsyme dsyme mentioned this issue Apr 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants