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

Add a modified total precision option. #138

Closed
oscbyspro opened this issue Jul 30, 2022 · 5 comments
Closed

Add a modified total precision option. #138

oscbyspro opened this issue Jul 30, 2022 · 5 comments
Labels
enhancement improvements n' stuff
Milestone

Comments

@oscbyspro
Copy link
Owner

oscbyspro commented Jul 30, 2022

Introduction

Integers can specify precision in terms of a total number of digits. This is because integer precision is implemented and it happens to be the same thing for integer numbers. It should be possible, however, to implement a dynamic solution that enables the corresponding behavior for floating point numbers as well.

Why total and not significant digits?

Because, well, significant digits suck. Image this Float16 number: 0.00[0220]00. Float16 has 3 decimal digits of precision; the number is valid but entries outside the brackets are invalid, or have otherwise unpredictable behavior from the perspective of the user. To make the input experience intuitive, the input space starts at zero and expands contiguously from there to the maximum number of digits.

Why modified total and not total digits?

Because ignoring the leading zero in 0.[333] makes sense. The intuitive input rule should really be restated as: expand from the fraction separator up to maximum precision, and allow an integer zero by convention / for aesthetic reasons.

Proposal(s)

A) An enum with dynamic behavior.
B) A precision protocol with existential box.

@oscbyspro oscbyspro added the enhancement improvements n' stuff label Jul 30, 2022
@oscbyspro
Copy link
Owner Author

oscbyspro commented Jul 30, 2022

As far as I can tell, it appears that Foundation.NumberFormatStyleConfiguration.Precision wraps an enum rather than an existential box. Just interesting to see, as it’s the closest comparable item. I assume an enum is more performant, and what I will end up using as well. I kinda wish I had a real reason to use any, however, as it’s basically the same thing but without switches (from my point of view).

@oscbyspro
Copy link
Owner Author

oscbyspro commented Jul 30, 2022

I wish Swift had an enum any construct for when conformances are enumerable:

protocol Brrr {
    func brrr()
}

enum PseudoEnumAnyBrrr {
    case foo(Foo) // where Foo: Brrr
    case bar(Bar) // where Bar: Brrr
    case baz(Baz) // where Baz: Brrr
    
    func brrr() {
        switch self {
        case .foo(let foo): foo.brrr()
        case .bar(let bar): bar.brrr()
        case .baz(let baz): baz.brrr()
        }
    }
}

Maybe enum protocol would make more sense?
Such that any [enum protocol] is enum-based.

@oscbyspro
Copy link
Owner Author

oscbyspro commented Jul 31, 2022

[DEFERRED] Precision should be clamped lazily.

  • It’s pointless to clamp precision unless the style resolves.
  • It is more performant to delay this operation until it's needed.

@oscbyspro oscbyspro added this to the v5.0.0 milestone Jul 31, 2022
@oscbyspro
Copy link
Owner Author

oscbyspro commented Aug 1, 2022

I spent a lot of time debugging the stupidest thing and arrived at:

import Foundation

let formatter = IntegerFormatStyle<Int>.Currency(
code: "USD", locale: Locale(identifier: "en_US"))

formatter.precision(.integerLength(1 ..<  999)).format(123) // "$123.00"
formatter.precision(.integerLength(1 ..< 1000)).format(123) // "123" ⚠️
formatter.precision(.integerLength(1 ..< 1001)).format(123) // "123" ⚠️

formatter.precision(.integerLength(1 ...  999)).format(123) // "$123.00"
formatter.precision(.integerLength(1 ... 1000)).format(123) // "$123.00"
formatter.precision(.integerLength(1 ... 1001)).format(123) // "$123.00"

@oscbyspro
Copy link
Owner Author

oscbyspro commented Aug 1, 2022

Added in 099cb6b.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement improvements n' stuff
Projects
None yet
Development

No branches or pull requests

1 participant