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

Surprising parse behavior of quotient units. #249

Closed
wnreynoldsWork opened this issue Aug 21, 2019 · 10 comments
Closed

Surprising parse behavior of quotient units. #249

wnreynoldsWork opened this issue Aug 21, 2019 · 10 comments
Labels

Comments

@wnreynoldsWork
Copy link

I would expect the unit string 'm/s/s' to have dimensions L/T^2, but instead it has dimension L. I understand that there is ambiguity in the order of evaluation of the '/' operators. If we evaluate the '/' right to left, then s/s = 1, and m/1 = m, with dimensions L, whereas if we evaluate the '/' left to right, then we have (m/s)/s = m/s^2, with dimensions L/T^2.

I admit that there is a formal problem with m/s/s, but I am (very) certain that every scientist and engineer who sees (or enters into software) the string 'm/s/s', would expect the resulting unit to have dimensions L/T^2. I request that the quotient operators be evaluated left to right, thus preserving the principle of least surprise.

@keilw keilw added the analysis label Aug 21, 2019
@keilw
Copy link
Member

keilw commented Aug 21, 2019

Which UnitFormat implementation did you use?

@wnreynoldsWork
Copy link
Author

SimpleUnitFormat

@keilw
Copy link
Member

keilw commented Aug 21, 2019

Did you try others like EBNFUnitFormat? As the name suggests the SimpleUnitFormat is a slightly simplified implementation while several others apply the Extended Backus-Naur Form.

@wnreynoldsWork
Copy link
Author

Simple class demonstrating behavior. Output is '[L]'l instead of expected '[L]/[T]^2'

`import tech.units.indriya.format.SimpleUnitFormat;

/**

  • Simple demo of strange unit parse behaviour by SimpleUnitFormat

  • @author Bill Reynolds wnreynolds AT stellarscience DOT com
    */
    public class FunnyParseBehavior {

    public static void main(String[] args) {

     SimpleUnitFormat unitParser = SimpleUnitFormat.getInstance(SimpleUnitFormat.Flavor.ASCII);
     System.out.println(unitParser.parse("m/s/s").getDimension());
     System.out.println(unitParser.parse("m/(s*s)").getDimension());
    

    }

}`

@wnreynoldsWork
Copy link
Author

EBNFFormat works, but it does not have the 'alias' capability of SimpleUnitFormat, which is critical for my application.

`import tech.units.indriya.format.EBNFUnitFormat;

/**

  • Demo showing that EBNFUnitFormat gets quotient units right.

  • @author Bill Reynolds wnreynolds AT stellarscience DOT com
    */
    public class FunnyParseBehavior {

    public static void main(String[] args) {

     //SimpleUnitFormat unitParser = SimpleUnitFormat.getInstance(SimpleUnitFormat.Flavor.ASCII);
     EBNFUnitFormat unitParser = EBNFUnitFormat.getInstance();
     System.out.println(unitParser.parse("m/s/s").getDimension());
     System.out.println(unitParser.parse("m/(s*s)").getDimension());
    

    }

}
`

@wnreynoldsWork
Copy link
Author

Ok, based on your comments, I've figured out how to do aliases using EBNFFormat:

`import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Locale;
import java.util.ResourceBundle;

import tech.units.indriya.format.EBNFUnitFormat;
import tech.units.indriya.format.SymbolMap;
import tech.units.indriya.unit.Units;

/**

  • Simple code to demonstrate use of aliases with the EBNFUnitFormat
    */
    public class TestEBNF {

    private static final String BUNDLE_NAME = "tech.units.indriya.format.messages"; //$NON-NLS-1$

    /**

    • @param args the command line arguments
      */
      public static void main(String[] args) throws UnsupportedEncodingException {
      // TODO code application logic here
      SymbolMap map = SymbolMap.of(ResourceBundle.getBundle(BUNDLE_NAME, Locale.ROOT));
      map.alias(Units.WATT, "watt");

      EBNFUnitFormat unitParser = EBNFUnitFormat.getInstance(map);

      unitParser.parse("watt");
      PrintStream utfOut = new PrintStream(System.out, true, "UTF-8");
      utfOut.println("Dimension of watt: " + unitParser.parse("watt").getDimension());
      utfOut.println("Dimension of m/s/s: " + unitParser.parse("m/s/s").getDimension());

    }

}
`

Thank you. It turns out that this leads to a new problem, EBNFUnitParser won't accept a unit alias called 'e'. I'll post a second report on this problem.

@wnreynoldsWork
Copy link
Author

see issue #250 for the problem with using the alias 'e' in the EBNFUnitParser.

@keilw
Copy link
Member

keilw commented Aug 22, 2019

If you're happy to use the mentioned demo as a basis for demos in https://github.com/unitsofmeasurement/uom-demos/tree/master/console/basic/src/main/java/tech/uom/demo/format, feel free to propose a PR or we could also do that. Can this ticket otherwise be closed? I saw the other one, similar to using "1" as a unit it may be a bit trickier because "e" is a regular part of very large or small numbers.

@wnreynoldsWork
Copy link
Author

Go ahead and close the ticket. I'm not quite understanding the question about a PR - do you mean add the simple demo I posted above as an addition to the demo/format directory as a PR? If that's the question, I'd be happy to do it, otherwise let me know what you'd like.

@keilw
Copy link
Member

keilw commented Aug 23, 2019

Yes, uom-demos, but we can do that if you don't. Unlike the main RI code here everyone is free to participate in the demos and other projects. Only the parts that make up the JSR (API, RI and TCK) are a little more restricted for contribution without contributor agreements because of JCP requirements.

@keilw keilw closed this as completed Aug 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants