• TheCPUWizard (unregistered)

    " we're working with parts in the scale of millimeters and in this function, we're doing our units in meters." -- ALWAY?S ALWAYS ALWAYS work with canonical units [meters] for numeric quantities... otherwise, somewhere, some time, someone will add X+Y where X is in cm and Y is in mm....

  • TheCPUWizard (unregistered)

    " we're working with parts in the scale of millimeters and in this function, we're doing our units in meters." -- ALWAY?S ALWAYS ALWAYS work with canonical units [meters] for numeric quantities... otherwise, somewhere, some time, someone will add X+Y where X is in cm and Y is in mm....

  • I'm not a robot (unregistered) in reply to TheCPUWizard

    I don't know the specifics of the Length type in Kotlin, but I'd imagine that its job is to take care of things like that.

  • gigimava (unregistered)

    To be honest, I prefer the original approach to the generation of a full list of diameters.

  • (author) in reply to gigimava

    I'd argue that the advantage of the list of diameters (which I wouldn't generate, given my druthers, but load from an external data source) is that a data-driven search is simple; and given the small number of entries, a linear search is entirely reasonable. If I build a pile of conditional logic, it's going to be more specific to the set of data I'm working with, while the list-driven version can work with any arbitrary set of diameters.

  • (author) in reply to TheCPUWizard

    That's why you don't store lengths or other similar quantities using numeric types- you always store them in a type that contains unit information. lengthIn_mm + lengthIn_m should either be a compile error or an implicit conversion to the same units. While std::chrono has some warts on it, it's got the right idea about tracking data with associated units.

  • (nodebb) in reply to TheCPUWizard

    Yeah agreed. If you mix units together, you end up with rockets exploding (https://spacemath.gsfc.nasa.gov/weekly/6Page53.pdf).

  • Wyatt (unregistered) in reply to Remy Porter

    I agree, because now when you end up out of stock on 70mm tubing, you can just have update a file someplace to remove it as an option rather than changing business logic.

  • (nodebb)

    While I like the idea of a special "wrapper type" (like a struct in C#) to specify the units, in my actual experience it's usually pretty easy to just follow a simple rule to use "double" type and store the value in the corresponding canonical unit - meter, meter squared, etc.

    Having said all that, for the challenge in the article, I would like to have an entity-type approach, something like PackageType, with a Dimension property, and then a lookup is used (like SELECT in SQL or a code-based solution) to find the needed tube or what not. I don't like the idea of hard coding the specific sizes altogether, regardless of how it's done.

  • (nodebb) in reply to TheCPUWizard

    otherwise, somewhere, some time, someone will add X+Y where X is in cm and Y is in mm....

    Strictly conforming to a standardized unit system internally helps avoid that. Until someone doesn't... Plus, it does nothing to avoid situations where someone messes up more badly and adds square-meters and cubic-meters together; Based on a recounting of my project manager.

    Sadly, tracking unit information cleanly isn't the norm. Part of it comes from performance requirements in e.g. simulation code. C++ has Boost.Units, which as I understand should take care of it without performance overhead, but at the same time the people programming this kind of software are often mathematicians/mechanical engineers/physicists/whatever field that does some programming first, programmers second, and software-engineers only maybe, so the chances of having enough awareness why the syntactic overhead is worthwhile cannot be assumed.

    Outside of C++, the issue becomes worse, as I am not aware of any other language that has sufficient capabilities to handle unit systems at compile-time. When speaking about simulation code, the runtime overhead can be prohibitive. It also doesn't help, that often mixed-unit vectors and matrices are defined, which removes the possibility for many high-level optimizations.

    There's also the issue of odd edge-cases like angles, that present somewhat... unique... challenges. In various formalisms, the information whether an rotation rate is given as "angle per second" or "rounds per second" is lost, leading to discussions like this.

  • (nodebb) in reply to Mr. TA

    While I like the idea of a special "wrapper type" (like a struct in C#) to specify the units, in my actual experience it's usually pretty easy to just follow a simple rule to use "double" type and store the value in the corresponding canonical unit - meter, meter squared, etc.

    NASA learned the hard way, that "canonical unit" is a case of domain knowledge. C++ has Boost.Units, Python as libraries like pint.

    Handling units as explicit information in the code ads protections you otherwise wouldn't have, akin to using enum types instead of plain integers (assuming the language actually type-checks them...).

    Even on paper, using SI-units over say cgs-units or some ad-hoc problem-specific rescaling to dimensionless factors, gives error checking somewhat similar to static type checking; It doesn't guarantee the result is correct, it adds overhead while working with it, but it points out certain classes of errors that may have happened along the way.

  • holy shit now I'm actually commenting here... (unregistered) in reply to R3D3

    https://docs.rs/dimensioned/latest/dimensioned/

  • cellocgw (unregistered) in reply to R3D3
    someone messes up more badly and adds square-meters and cubic-meters together;
    Hey, you never heard of "space-filling curves" ? :-)
  • (nodebb)
    someone messes up more badly and adds square-meters and cubic-meters together

    Not a problem -- you know about space-filling curves, right? So here we have 2-D objects filling 3D space. /s

  • a cow (not a robot) (unregistered)

    fun tubeDiameter(partDiameter: Length):

    Yes, it's actually fun enough...

  • a cow (not a robot) (unregistered) in reply to TheCPUWizard

    I hope you will soon have to code something for something on the quark scale. Or astronomical...

  • (nodebb) in reply to cellocgw

    Not a problem -- you know about space-filling curves, right? So here we have 2-D objects filling 3D space. /s

    I'm not sure though if we should want space-filling curves in the description of a gearbox though XD

  • (nodebb) in reply to holy shit now I'm actually commenting here...

    holy shit now I'm actually commenting here... (unregistered) in reply to R3D3 2023-05-11: https://docs.rs/dimensioned/latest/dimensioned/

    I want it for Fortran too :( But Fortran lacks the necessary language capabilities.

    Also: If you're taken aback by commenting here, wait until you start submitting :)

  • (nodebb)

    That last paragraph from the article: kotlin already has List<T?>.binarySearch() in the stdlib... Please tell me you didn't rewrite your own version. That would be another WTF.

  • (nodebb) in reply to Ralf

    Ralf wrote:

    kotlin already has List<T?>.binarySearch() in the stdlib... Please tell me you didn't rewrite your own version. That would be another WTF.

    Submitter wrote:

    I have also been somewhat new to Kotlin and highly motivated and replaced the implementation of fun tubeDiameter with an overly complicated binary search on defaultTubeDiameters, but that is for my successor to complain about :) At least it works as expected (more often than before).

    I'm pretty sure we have both the answer and the excuse :)

  • Alex Jhon (unregistered)
    Comment held for moderation.
  • Emil Helg (unregistered)
    Comment held for moderation.
  • Craig (unregistered) in reply to R3D3

    Any object-oriented language with operator overloading can handle unit tracking at the type level relatively seamlessly. Generics can make it easier to implement.

Leave a comment on “Going Tubing”

Log In or post as a guest

Replying to comment #:

« Return to Article