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 more quantity types #6

Open
14 of 15 tasks
ianmackenzie opened this issue Sep 27, 2018 · 49 comments
Open
14 of 15 tasks

Add more quantity types #6

ianmackenzie opened this issue Sep 27, 2018 · 49 comments
Labels
Hacktoberfest help wanted Extra attention is needed

Comments

@ianmackenzie
Copy link
Owner

ianmackenzie commented Sep 27, 2018

Here's a list of modules that I'd like to add at some point - pull requests for any of these are welcome! (Take a look at existing modules for inspiration.) I've listed how I think each quantity's units should be defined, either as a base unit (Moles, Candelas, etc.) or as a rate/product of other units (in which case the units type will be a type alias of the form Rate x y or Product x y). Note that there are some dependencies here - can't add the VolumetricFlow modules without the Volume module, or LuminousIntensity without SolidAngle!

Kinematics/dynamics

  • AngularSpeed (RadiansPerSecond = Rate Radians Seconds) (thanks @katjam!)
  • AngularAcceleration (RadiansPerSecondSquared = Rate RadiansPerSecond Seconds) (thanks @katjam!)
  • Torque (NewtonMeters = Product Newtons Meters) (thanks @gampleman!)

Volume

  • Volume (Cubed Meters) (thanks @katjam!)
  • VolumetricFlow (CubicMetersPerSecond = Rate CubicMeters Seconds)
  • Density (KilogramsPerCubicMeter = Rate Kilograms CubicMeters) (thanks @katjam!)
  • SubstanceAmount (Moles) (thanks @ukarim!)
  • Molarity (MolesPerCubicMeter = Rate Moles CubicMeters) (claimed by @lenards)

Electromagnetism

  • Inductance (Henries = Rate Volts (Rate Amperes Seconds)) (thanks @ukarim!)
  • Capacitance (Farads = Rate Coulombs Volts) (thanks @ukarim!)

Photometry

  • SolidAngle (Steradians)
  • LuminousFlux (Lumens)
  • LuminousIntensity (Candelas = Rate Lumens Steradians)
  • Illuminance (Lux = Rate Lumens SquareMeters)
  • Luminance (Nits = Rate Candelas SquareMeters)
@ianmackenzie ianmackenzie added Hacktoberfest help wanted Extra attention is needed labels Sep 27, 2018
@katjam
Copy link
Contributor

katjam commented Oct 2, 2018

@ianmackenzie Thanks for the call out... I've set aside some days this month to contribute to hacktoberfest.

Not wishing to double up efforts with others - shall I have a go at Volume for starters? I think my maths will cope.

@ianmackenzie
Copy link
Owner Author

ianmackenzie commented Oct 2, 2018

@katjam Sure, sounds good, and thanks for checking first! Off the top of my head for volume units I'd suggest including (along with cubicMeters):

  • liters, milliliters
  • usLiquidGallons, usDryGallons, imperialGallons
  • usLiquidQuarts, usDryQuarts, imperialQuarts
  • usLiquidPints, usDryPints, imperialPints
  • usFluidOunces, imperialFluidOunces

Gotta love crazy non-metric units! In general I've tried to make all conversion constants in the elm-units source code exact, even if that means dividing by a constant or multiplying by a chain of constants instead of multiplying by a single constant. To the extent that this is possible for all the above units, that would be ideal.

It would be kinda nice to also include cooking units like teaspoons, tablespoons and cups, but those seem to vary wildly between countries without even standard names for the different versions, so I'd say leave them out.

@katjam
Copy link
Contributor

katjam commented Oct 2, 2018

Perfect. I'm getting Errors regarding comparable type in Quantity module when I try to compile. Is that expected?

e.g.

-- TYPE MISMATCH ------------------------------- ./../elm-units/src/Quantity.elm 

The 1st argument to function `min` is causing a mismatch. 
276|               Basics.min x y)                               
                                        ^ 
Function `min` is expecting the 1st argument to be:
     comparable 
But it is: 
    number 

Hint: Only ints, floats, chars, strings, lists, and tuples are comparable.

Yes - cooking units do seem to vary - maybe could identify differences by country code but I'll leave for now.

@ianmackenzie
Copy link
Owner Author

That's interesting, I don't get that compile error myself (even if I explicitly call Quantity.min) - you're not using Elm 0.18 or something, are you?

@katjam
Copy link
Contributor

katjam commented Oct 2, 2018

Oops! I'll upgrade. :)

@JoelQ
Copy link

JoelQ commented Oct 2, 2018

It would be kinda nice to also include cooking units like teaspoons, tablespoons and cups, but those seem to vary wildly between countries

Huh, I always thought one teaspoon was 5ml and a tablespoon was 15ml. A quick wikipedia search tells me that:

  • US tablespoon is ~ 14.8ml
  • Australian tablespoon = 20ml
  • Metric tablespoon = 15ml
  • probably more...

😰 😰 😰

@ianmackenzie
Copy link
Owner Author

I'm kind of surprised it even started compiling in 0.18 (hence my skepticism that that was the issue), given that there's no elm-package.json, just the new elm.json...but I guess if you were just compiling individual files or something maybe that works without a package file.

@ianmackenzie
Copy link
Owner Author

@JoelQ yeah, that's the Wikipedia page I was looking at when I basically threw my hands up and said "forget it". Fortunately it would be easy enough for someone else to create separate Cooking.US and Cooking.Australian etc. modules (in a separate package) with functions like tablespoons : Float -> Volume etc...but I think those are sufficiently fuzzy and ill-defined that they don't belong in the base elm-units package.

@ianmackenzie
Copy link
Owner Author

If there is one thing I have learned when making this package, it is that anything other than an SI unit is very likely to have multiple slightly-different versions in common, modern use. Tablespoons, gallons, horsepower, tons...

@katjam
Copy link
Contributor

katjam commented Oct 2, 2018

I made a little project that includes elm-units so I'd be more confident testing stuff.
I've sorted out the elm version issues - good excuse to upgrade my other projects too. :)

Yeah units are nuts. I guess cultures like to define their own standards.

@ianmackenzie
Copy link
Owner Author

Ahhh OK, that makes sense - so you were just including elm-units via source-directories from an Elm 0.18 project. Interesting that Elm 0.19 accepts that min code and Elm 0.18 doesn't! I guess there were some subtle changes to comparable to accept generic number values and not just specific Float or Int...I don't remember that being mentioned anywhere but I guess it would only affect a tiny number of use cases.

@katjam
Copy link
Contributor

katjam commented Oct 2, 2018

I had a quick google before I asked you too - because I thought maybe it was an 0.18 to 0.19 thing - but nada.

Anyway - all good now. Nearing supper time for me - but hopefully have something up tomorrow. I've taken scattered days off work this month so may be fits and starts.

@ianmackenzie
Copy link
Owner Author

No rush! I may very well end up releasing 1.0 with just the existing modules (I was planning on an initial release this week), but it was always the plan to steadily add more modules in minor releases post-1.0. So if you finish in a week or two there's no reason we couldn't immediately publish a 1.1.

@katjam
Copy link
Contributor

katjam commented Oct 2, 2018

Sounds good. 👍

@katjam
Copy link
Contributor

katjam commented Oct 2, 2018

Going to have trouble remembering to spell metres 'correctly' though. 😉

@ianmackenzie
Copy link
Owner Author

Hahaha fair point! I'm Canadian myself, and I do realize that 'metres' is the standard SI spelling of the unit. But it seems that American spelling (color etc.) is the de facto standard in programming, so I decided a long time ago to follow that for all my programming projects. It helps that American spellings tend to be a bit simpler (color vs colour) and more phonetic (meters vs metres), so it feels like an objectively reasonable choice and not just surrendering to the majority.

@ianmackenzie
Copy link
Owner Author

It heartens me to find out that the American spellings were due to a considered, deliberate effort to make spelling simpler and more regular: https://www.businessinsider.com/spelling-american-vs-british-noah-webster-2018-3

I think as programmers we can all appreciate a nice simplifying refactor!

@katjam
Copy link
Contributor

katjam commented Oct 3, 2018

Am I on the right track? Added cubed and cbrt to Quantity though not sure if you think it's helpful since not supported by Basics

master...katjam:6-add-volume-module

@ianmackenzie
Copy link
Owner Author

Looking pretty good! I have a few small thoughts/comments/questions but I think it would make sense to just open a pull request and we can discuss there - it's totally fine to open a pull request with partial work, you can keep pushing to your branch and those changes will show up in the pull request. But that way we can have a discussion there (and I can in fact go in and make small changes to your branch myself) without adding too many more comments to this issue.

@katjam
Copy link
Contributor

katjam commented Oct 7, 2018

Do you have a next priority in mind for the others? I'm happy to tackle any - once #9 goes in.

ianmackenzie added a commit that referenced this issue Oct 7, 2018
@ianmackenzie
Copy link
Owner Author

Awesome! I think AngularSpeed would probably be the next most fundamental (I can see that being useful for things like animations), and then perhaps AngularAcceleration for completeness. After that, maybe Density?

I'm personally most excited about the photometric units (I'm working on a 3D rendering package and I'd love to be able to specify lights in physical units like Lumens), but those are also by far the most confusing/mind-bending of the bunch - I'm still wrapping my head around Luminance vs Illuminance.

@katjam
Copy link
Contributor

katjam commented Oct 7, 2018

I'll go for AngularSpeed then.

@ianmackenzie
Copy link
Owner Author

Sounds good! I'm a bit conflicted on naming there - radiansPerSecond and degreesPerSecond seem obvious enough, and turnsPerSecond would then be consistent, but I'd also like to have revolutionsPerMinute (to match common usage) instead of turnsPerMinute. Could just switch to revolutions everywhere (including in the Angle module), but then that would be breaking with the names in the core Basics module...

@katjam
Copy link
Contributor

katjam commented Oct 7, 2018

I'll stick up a stub PR in a bit so we can continue the conversation there.

@katjam
Copy link
Contributor

katjam commented Oct 7, 2018

Philosophically - I prefer revolutions to (taking) turns...

@katjam
Copy link
Contributor

katjam commented Oct 13, 2018

I'll go for AngularAcceleration next.

@ianmackenzie
Copy link
Owner Author

Sounds good! I think for AngularAcceleration you could probably leave out revolutions per minute entirely - doesn't seem clear whether the corresponding acceleration unit would be revolutions per minute per minute or revolutions per minute per second. And any weird angular acceleration values like that can be constructed using Quantity.per anyways.

ianmackenzie added a commit that referenced this issue Oct 29, 2018
ianmackenzie added a commit that referenced this issue Nov 8, 2018
@katjam
Copy link
Contributor

katjam commented Nov 8, 2018

No promises on how fast I'll get to it, but I still have some time to take off work between now and Christmas... what's the next priority?

@ianmackenzie
Copy link
Owner Author

No promises on how fast I'll get to it, but I still have some time to take off work between now and Christmas... what's the next priority?

I'd be inclined to look at #10 and/or #19 next...either immediately start in on refactoring to use a Constants module (using the existing constant values), or look through the NIST/UK/DIN references and check:

  • if there are any units in elm-units that aren't listed in at least one of those sources
  • if there are any cases where a unit in elm-units has conflicting definitions in those sources

Thanks so much for all your continued contributions!

@katjam
Copy link
Contributor

katjam commented Nov 8, 2018

Thanks for letting me help. It's nice to have a project outside of work & personal to focus on. I guess it makes sense to do #19 with existing and then tidy it up with #10 if we need to alter anything?

I'll let you know before I start - making an initial WIP PR so we don't double up. Until I do - which should be within the next couple of weeks, you can assume I've done nothing.

@ianmackenzie
Copy link
Owner Author

Sounds good! I'll probably be focusing on elm-geometry for the next little while (just started a big refactor there), so I don't anticipate any conflicts.

@lenards
Copy link
Contributor

lenards commented Oct 3, 2019

@ianmackenzie - are Molarity, Torque, and VolumetricFlow still desired?

@ianmackenzie
Copy link
Owner Author

Hi @lenards yes, certainly! And I'm not aware of anyone else working on them if you want to start a PR =)

@katjam
Copy link
Contributor

katjam commented Oct 4, 2019

@lenards @ianmackenzie It's probably also a good time for me do some more stuff. Let me know where I can be most useful.

@lenards
Copy link
Contributor

lenards commented Oct 5, 2019

I'll take a crack at Molarity!

@katjam
Copy link
Contributor

katjam commented Oct 5, 2019

I'll go for Torque. It'll be nice to get this issue completed.

@ianmackenzie
Copy link
Owner Author

Thanks both! And yes it will be great to be able to close this one =)

@lenards
Copy link
Contributor

lenards commented Oct 7, 2019 via email

@jamessral
Copy link

Is it ok if I take VolumetricFlow? That one looks unclaimed. It would be a great way for me to get into some Elm!

@ianmackenzie
Copy link
Owner Author

@jamessral please do! I'll update the issue.

@lenards you may not be missing anything - it's entirely possible that there really are only one or two common ways of specifying molarity, I haven't really looked into it myself. If you want to open a PR with the basic constructor and in function and any interesting references you consulted, I'm happy to take a look.

@lenards
Copy link
Contributor

lenards commented Oct 13, 2019

I'm progressing on Molarity and additional definitions for SubstanceAmount.

lenards added a commit to lenards/elm-units that referenced this issue Oct 13, 2019
See ianmackenzie#6.

An SI unit, mole per cubic meter (mol/m3), `Molarity` is an amount of
substance divided by the volume of the mixture. Values stored in number
of mole per cubic meter. All `*PerLiter` definitions are defined in
terms of `decimolesPerLiter`. Why? This was done because a liter equal
to a cubic decimeter, and `mole per cubic meter` is a `Rate`. This may
make the various `*PerLiter` definition appear off by a factor of 10
because the definitions are in terms of decimoles per cubic decimeter
(same as `decimolesPerLiter`).
lenards added a commit to lenards/elm-units that referenced this issue Oct 13, 2019
Defined missing centimoles & decimoles in SubstanceAmount
module. Include in commit tests for fuzzing these and equal
pair comparisons.

See also ianmackenzie#6
@lenards lenards mentioned this issue Oct 13, 2019
10 tasks
lenards added a commit to lenards/elm-units that referenced this issue Oct 13, 2019
See ianmackenzie#6.

An SI unit, mole per cubic meter (mol/m3), `Molarity` is an amount of
substance divided by the volume of the mixture. Values stored in number
of mole per cubic meter. All `*PerLiter` definitions are defined in
terms of `decimolesPerLiter`. Why? This was done because a liter equal
to a cubic decimeter, and `mole per cubic meter` is a `Rate`. This may
make the various `*PerLiter` definition appear off by a factor of 10
because the definitions are in terms of decimoles per cubic decimeter
(same as `decimolesPerLiter`).
lenards added a commit to lenards/elm-units that referenced this issue Oct 13, 2019
Defined missing centimoles & decimoles in SubstanceAmount
module. Include in commit tests for fuzzing these and equal
pair comparisons.

See also ianmackenzie#6
@katjam
Copy link
Contributor

katjam commented Nov 8, 2019

@ianmackenzie Finally made some time to look at Torque. As per your description, I will define in terms of NewtonMeter, but do you think we should reference JoulePerRadian also or at least export a set of alias functions like we do in AngularSpeed for turns vs revolutions?

From my initial reading they are equally valid units - my simple understanding is that since Radian is unitless, JoulePerRadian is mathematically equivalent to NewtonMeter but conceptually different.

Please don't feel the need to take time out to explain. I can read more if I need to - just wanted to know if you want me to reference the Joule relationship in any way.

@ianmackenzie
Copy link
Owner Author

@katjam I think it's probably fine to leave out joules per radian for now (I think it's a different situation than angular speed - at least there everything is still conceptually "amount of rotation per unit time", just with different terminology).

There's a broader question here about how to deal with different, equivalent forms of the same quantity type - see #32.

@MartinSStewart
Copy link

Would it make sense to add hertz? I'm working on an audio package and hertz seems like an appropriate unit for describing the sample rate of a sound file.

@ianmackenzie
Copy link
Owner Author

Interesting! What operations do you think you'd want to perform on a Frequency value? I think the easiest would be to define Frequency as Quantity Float Hertz and Hertz as Rate Unitless Float, but it's not immediately obvious whether that would be a useful representation for the kinds of operations you might want to perform on frequencies.

@MartinSStewart
Copy link

For me it would probably be used in type alias AudioContext ={ sampleRate: Frequency }, samplesToDuration: AudioContext -> Quantity Int Samples -> Duration, and durationToSamples: AudioContext -> Duration -> Quantity Float Samples.

In other words, for my use case I can just write ~10 lines of code and have everything I need. I figured it was worth bringing up though because Frequency/Hertz seems to be a commonly used unit and I was surprised to not see it included here.

@ianmackenzie
Copy link
Owner Author

ianmackenzie commented Feb 22, 2020

Would it work in your case to define something like

type alias SamplesPerSecond =
    Rate Samples Seconds

type alias SampleRate =
    Quantity Float SamplesPerSecond

? Then durationToSamples is basically duration |> Quantity.at context.sampleRate (or equivalently context.sampleRate |> Quantity.for duration) and samplesToDuration is basically Quantity.toFloatQuantity numSamples |> Quantity.at_ context.sampleRate. Or is that what you meant by the ~10 lines?

I guess it just seems that in many cases (like this one) it makes sense to have a unit (like Samples) associated with a frequency, instead of Frequency being its own standalone quantity type. We could have it be a special quantity type that had its own type parameter, like

module Frequency exposing (Frequency)

type alias Frequency units =
    Quantity Float (Rate units Seconds)

but in a lot of ways it seems simpler just to treat it like a generic rate quantity.

@MartinSStewart
Copy link

Yeah, that's what I meant by 10 lines. It's not that Frequency/Hertz missing from elm-units is a problem for me. It's more that I figured this is an important kind of quantity that should be in elm-units.

As you mention though, it seems like Frequency doesn't need to be a standalone quantity as it can be represented with Rate. I think that answers my question then as to why I didn't see Frequency/Hertz present then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Hacktoberfest help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

6 participants