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

v5: Wishlist for breaking changes #180

Closed
11 of 13 tasks
angularsen opened this issue Aug 17, 2016 · 16 comments · Fixed by #982
Closed
11 of 13 tasks

v5: Wishlist for breaking changes #180

angularsen opened this issue Aug 17, 2016 · 16 comments · Fixed by #982
Labels

Comments

@angularsen
Copy link
Owner

angularsen commented Aug 17, 2016

Although there are no immediate plans to do a vNext, this issue serves as a wishlist/reminder of what to consider changing in case we need to bump the major version in the future.

To clarify

These are some things we should figure out before finalizing version 4.

A common denominator for design choices is binary size.
The library was nearing the 1MB mark and the majority of that is the large number of methods and properties for all our 700+ units. In particular number extension methods add 8 methods per unit (!). With some clever hacks we brought this back to 600kB without any breaking changes, but we want to keep binary size in mind for any new changes we introduce.

TODO Clean up and organize this brain dump:

  • Numeric type for value representation: Keep double? Switch to decimal? Offer both? Separate nugets? What about float?
  • Base types: To make it easier working with quantities generically, accessing value and unit, get units and their abbreviations, parsing and ToString() without know the quantity type in advance.
  • struct vs class: Weigh all the pros and cons, performance (stack vs heap), inheritance vs interface
    • class: Can support all number types (float, double, decimal) without increasing binary size N times (discussion)
    • struct: More suitable for performance and memory constrained applications (what is the impact in practice?), avoids pressure on garbage collector, quantities match the semantics of being a value type

List of breaking changes to make

Removing things

  • 7a455f0: Remove default Temperature arithmetic, it is not correct (made this breaking change already, due to existing behavior not being correct).
  • Remove UnitClass type, replaced by QuantityType
  • Remove nullable From factory methods causing N additional methods for N units, see comment
  • Remove == != and Equals(object) and Equals<T>(T) since they don't take a max error argument and is prone to floating point rounding issues, instead users should use Equals() methods that take a max error argument
  • Remove code marked as [Obsolete], such as Volume.Teaspoon unit that was too ambiguous
  • Remove static methods on UnitSystem, should use UnitSystem.Default instead
  • Remove unnecessary overloads on number types (8 overloads for each of the 700+ units) Proposal: Reducing size of library (WIP) #372

Changing behavior

Renaming

Fixing

  • Search for any TODO comments in the code to address, remove comment and either fix or create issue
@angularsen
Copy link
Owner Author

Ping @JKSnd @eriove @ferittuncer to subscribe to updates to this thread.

Question: Should we change this

TemperatureDelta.FromDegreesCelsiusDelta(50);

to this

TemperatureDelta.FromDegreesCelsius(50);

Delta is already covered by the quantity, so it feels redundant. Just noticed this when reviewing https://github.com/angularsen/UnitsNet/pull/324/files#diff-1067499ac8bb37a45676058d184d0547R55

@eriove
Copy link
Contributor

eriove commented Nov 27, 2017

Yes, that sounds like a good change. We could add the new function and mark the old one as obsolete immediately. That would make the migration easier

@gojanpaolo
Copy link
Contributor

gojanpaolo commented Jan 9, 2018

Please add this to wishlist: Correct SingularName for some Flow unit definitions.

see #360

@bplubell
Copy link
Contributor

I propose making parsing stricter:

  • Fail when parsing with multiple sets of units.
    • Passing example: Length.Parse("2.3 m")
    • Failing example: Length.Parse("2.3 m and 200mm")
  • Special handling for FeetInches.
    • Passing example: Length.Parse("1ft 5.5in") and Length.Parse("1\"5.5'")
    • Failing example: Length.Parse("1ft and 4in")

This would be more in consistent with framework parsing methods (like double.Parse), which are not very lenient. The burden lies with the consumer to provide data that is not ambiguous.

See #343 for additional context.
Related PRs from originally allowing multiple units:
#64
#81
#254

@angularsen
Copy link
Owner Author

angularsen commented Jan 13, 2018

@bplubell How about we actually have a separate parsing method for the feet-inch special case? Something like Length.ParseFeetInches(string) ? I think maybe it is reasonable to make it explicit that we are expecting such input, as opposed to having this special case as part of Length.Parse().
Or maybe this just complicates things from the consuming side of things.. I'm not sure.

@gojanpaolo
Copy link
Contributor

Remove inconsistent abbreviation for cubic feet cf/hr in Flow (See #361 (review))

@bplubell
Copy link
Contributor

@angularsen Re: ParseFeetInches. That might work, though I am wondering about passing in a value that a user has input (like from a form). Should UnitsNet be responsible for parsing all valid input (even special cases), or should the code calling into UnitsNet be responsible for knowing the special cases and calling the right parsing method?
I lean toward the first one, though if we do that we would very likely want an internal method like Length.ParseFeetInches that is called after we determine that it is a special case. Something along the lines of:

Public bool TryParse(string value, out Length length)
{
    if (!QuantityParser.TryParseExact(value, out length))
    {
        if (!Length.TryParseFeetInches(value, out length))
        {
            return false;
        }
        // else if over additional special cases if necessary
    }
    return true;
}

@angularsen
Copy link
Owner Author

angularsen commented Jan 20, 2018

@bplubell Good example. I favor keeping it simple from the user's stand point, so that Length.Parse() and Length.TryParse() internally tries a series of special cases in sequence, as you propose here, so that it "just works" as before with strings like 1' 4" and 1 ft 4 in, but the same does not work for other quantities unless explicitly added as special cases. I do want to be a lot stricter on the allowed variants of these foot-inch inputs so we only allow well-formed inputs that are actually widely used.

@angularsen
Copy link
Owner Author

angularsen commented Mar 7, 2018

I have created a new branch v4 that we will target the pull requests in this wishlist, and any other changes we want to include in only v4 and not in 3.x versions.

It will be a fairly big undertaking to complete all this, but I propose we start on this before the list grows unmanageable and the jump from 3.x to 4.x becomes too great from the consuming side.

@tmilnthorp
Copy link
Collaborator

Acceleration units missing plural s in Meters is fixed in #434

@angularsen
Copy link
Owner Author

Updated the checklist

@tmilnthorp
Copy link
Collaborator

I guess we should have bumped the major number for that eh :)

@angularsen
Copy link
Owner Author

Right, my bad, I thought we obsoleted the old units. We should probably add the old ones back and mark them obsolete.

@angularsen
Copy link
Owner Author

vNext is long overdue now, I muted thousands of build warnings about obsolete code earlier because they just spammed the build log and we don't take any dependencies I expect to be obsoleted anytime soon.

@angularsen
Copy link
Owner Author

Added to list:

  • Remove nullable From factory methods causing N additional methods for N units, see comment

And organized list into category of changes.

@angularsen
Copy link
Owner Author

Closing this since most of the discussions above are covered in v4 #487.
Creating new discussions for the remaining topics, such as changing from struct to class.

angularsen added a commit that referenced this issue Dec 16, 2018
# 4.0.0 Release
This PR will serve as the list of items to complete and it will be updated to show the progress before finally merged into `master` when completed. We all have busy schedules, so **if you want to help move this work forward then that is much appreciated!** 

## The main theme is to reduce binary size
In two years it has grown from 280 kB to 1.4 MB and a lot of it is due to unnecessary syntactic sugar with many method overloads for various number types and nullable types - for every of our 800+ units! It simply adds up to a big total.

These items are chosen from #180, trying to include as many of the low hanging fruits as possible, while still keeping the list short and realistic to complete in a reasonably short time - we are all busy in our daily lives. We can always have more major version bumps later than trying to perfect it all now.

## Feature complete before November, merged before mid-December
I would like to aim for a "beta" pre-release nuget sometime in October with all the items completed, so we can have some time to test it before releasing the final, stable 4.0.0 version before Christmas holidays.
We should have the work items list more or less final before Monday, October 8th.

## Changes
#### Added
- [x] UnitSystem with a different meaning, now defines the base units for a unit system (#524)

#### Removed
- [x] Replace netstandard1.0 target with netstandard2.0, to avoid the extra dependencies (#477)
- [x] Remove code marked as `[Obsolete]`, such as `VolumeUnit.Teaspoon`  (#490)
- [x] Remove nullable `From` factory methods (#483)
- [x] Remove extension methods on _nullable_ number types (#483)
- [x] Remove all number extension methods (#497)
- [x] Remove `Length2d`, replaced by `Area` (#501)
- [x] Remove static methods on `UnitSystem`, should use `UnitSystem.Default` instead (#496)
- [x] Remove unit parameter from `ToString()` methods (#546)

#### Changed
- [x] Throw exception on NaN values in static constructor methods, like `FromMeters()` (#502, see #176 (comment))
- [x] Throw if unit was not specified when constructing quantities, (#499 - #389 (comment))
- [x] Stricter parsing (#343 and #180 (comment))
- [x] Remove unit parameter from `ToString()` methods (#546)
- [x] Change Temperature arithmetic back to use base unit Kelvin (#550, see #518)

#### Renamed
- [x] Correct SingularName for some Flow unit definitions (#494, see #360)
- [x] Split/rename UnitSystem into UnitParser, GlobalConfiguration, UnitAbbreviationsCache (#511)

#### Fixed
- [x] Search for any TODO comments in the code to address, remove comment and either fix or create issue (5d24432)
- [x] Update README with v4 changes #498
- [x] Do not try/catch in UnitConverter.Try-methods (#506)
- [x] Do not try/catch in `Length.TryParse()` and for other quantities (#507)
- [x] Add/update changelog in wiki for v4 with some summary copied from this issue, some v3 to v4 migration instructions and briefly explain why some stuff were removed

## Milestones
- [x] Finalize work items list (Monday, October 8)
- [x] Release 4.0.0-beta1, feature complete (Wednesday, October 31)
- [ ] ~Show release notes and upgrade guide when upgrading to 4.x nuget, if possible~
- [x] Release 4.0.0 (Monday, December 17)
@angularsen angularsen mentioned this issue Nov 2, 2021
angularsen added a commit that referenced this issue Nov 29, 2022
Fixes #180 

Merging the v5 release branch.

It is still in alpha, but it is functional, nugets are published and there are not many planned breaking changes left.
By merging, all efforts moving forward are targeting v5 and this reduces friction:

- No more merge conflicts trying to forward port all changes to v5, instead cherry pick new units and fixes to v4 until v5 is fully stable.
- Contributors are having trouble building v4 locally due to `net40`, `net47` and Windows Runtime Component targets.


## 💥 Breaking changes
Default number format should be CultureInfo.CurrentCulture, not CurrentUICulture (#795)
Use CurrentCulture rather than CurrentUICulture (#986)
Return `QuantityValue` in `IQuantity` properties instead of `double` (#1074)
Return `decimal` in properties of `Power`, `BitRate` and `Information` quantities (#1074)
Fix singular name VolumeFlow.MillionUsGallonsPerDay

## 🔥 Removed 
Remove targets: net40, net47, Windows Runtime Component.
Remove `Undefined` enum value for all unit enum types
Remove QuantityType enum
Remove IQuantity.Units and .UnitNames
Remove IQuantity.ToString() overloads
Remove IEquatable<T> and equality operators/methods 
Remove GlobalConfiguration
Remove obsolete and deprecated code.
Remove Molarity ctor and operator overloads
Remove MinValue, MaxValue per quantity due to ambiguity
Remove string format specifiers: "v", "s"
json: Remove UnitsNetJsonConverter

## ✨ New
QuantityValue: Implement IEquality, IComparable, IFormattable
QuantityValue: 16 bytes instead of 40 bytes (#1084)
Add `[DataContract]` annotations (#972)

## ♻️ Improvements
Upgrade CodeGen, tests and sample apps to net6.0.

## 📝 JSON unit definition schema changes
Rename `BaseType` to `ValueType`, for values "double" and "decimal".
Rename `XmlDoc` to `XmlDocSummary`.

## TODO
Add back `IEquatable<T>`, but implement as strict equality with tuple of quantity name + unit + value.
#1017 (comment)

## Postponed for later
#1067
@angularsen angularsen changed the title vNext: Wishlist for breaking changes v5: Wishlist for breaking changes Apr 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants