[jira] [Created] (JEXL-393) const must not be modifiable
Hussachai Puripunpinyo created JEXL-393: --- Summary: const must not be modifiable Key: JEXL-393 URL: https://issues.apache.org/jira/browse/JEXL-393 Project: Commons JEXL Issue Type: Bug Reporter: Hussachai Puripunpinyo The following code works with JEXL master (2022-02-21) when it's not supposed to. {code:java} const total = 0; if (true) { total = 1; } total; {code} At the end, this script yields 1 as total constant was treated as a variable. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Comment Edited] (JEXL-384) Improve control over JexlArithmetic null argument handling
[ https://issues.apache.org/jira/browse/JEXL-384?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17630185#comment-17630185 ] Hussachai Puripunpinyo edited comment on JEXL-384 at 11/8/22 5:31 AM: -- I think what I mentioned, you already addressed it in [992c8463|https://github.com/apache/commons-jexl/commit/992c8463f52880a9cb733c4ffac609ab5caff232]. I'd prefer the explicit passing the operator in the respective functions rather than detecting the class modification using reflection. IMO, it's just more natural to mock and test functions independently, but that's just my own preference. As long as it works as expected, it's good. Thanks for being on top of this. Cannot wait to pull 3.3 in when it's out :) was (Author: hussachai): I think what I mentioned, you already addressed it in [992c8463|https://github.com/apache/commons-jexl/commit/992c8463f52880a9cb733c4ffac609ab5caff232]. I'd prefer the explicit passing the operator in the respective functions rather than detecting the class modification using reflection. IMO, it's just more natural to test the function in a stateless manner, but that's just my own preference. As long as it works as expected, it's good. Thanks for being on top of this. Cannot wait to pull 3.3 in when it's out :) > Improve control over JexlArithmetic null argument handling > -- > > Key: JEXL-384 > URL: https://issues.apache.org/jira/browse/JEXL-384 > Project: Commons JEXL > Issue Type: Task >Affects Versions: 3.3 >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > > https://issues.apache.org/jira/browse/JEXL-359 > {quote}A typical case is '+' for string and null where one would like to > consider null as a valid argument even if arithmetic is strict. > {quote} > While the above reason is valid, the code introduced in JEXL-359 causes more > confusion, and the behavior is now inconsistent. > Also, I'd like to give some counter arguments about not supporting null + > string in the strict mode. If we want to make null + string works even if > arithmetic is strict, there will be no difference between "" + "ABC" and null > + "ABC" because both cases yield "ABC" in both strict and non-strict mode. In > our code base, we set the engine to be strict, so users have to be careful > about null since it can give an undesirable result. In a non-strict mode, we > don't have a way to distinguish whether the result is the combination of null > or empty string and a string. Users need to explicitly check for null, but > there will be no enforcement > which means nobody will do that check. That's why we prefer it to be strict > and a user has to check null before using or use some namespace functions > that we provide where null will be explicitly handled. Otherwise, the > exception will be thrown. > Let me elaborate why some part of JEXL-359 causes the behavior to be > inconsistent. > *Strict Mode* > {code:java} > var i = null; > i + 'ABC'; // This will throw an exception. > null + 'ABC'; // This yields 'ABC' - the same as non-strict mode. > {code} > > *Non Strict Mode* > {code:java} > var i = null; > i + 'ABC'; // This yields 'ABC'; > null + 'ABC'; // This also yields 'ABC'; > {code} > > You can see that the behavior of null + 'ABC' in the strict mode is not > consistent with the null variable. > Also, there is a way to allow string concatenation with null using a > namespace function in a strict mode, and I think JEXL shouldn't make an > exception for this one particular case. > I'd like to propose the PR with some regression tests that applies to only > null (literal) + string case. > [https://github.com/apache/commons-jexl/pull/136] > *Note:* I ignored one test *testNullArgs* because the feature doesn't seem to > be defined well. It won't work with numeric types. > I can pass around the JexlOperator to isStrict function everywhere to address > that, but I'm trying to refrain from changing things too much since you may > have some ideas and my code might get in the way. > Please let me know if I can help with that, or you can merge my PR, take part > of it or ignore it completely :) > My idea about fixing *testNullArgs* properly is that all toString, toDouble, > toBigDecimal functions should take an additional argument which is > JexlOperator where a user can override for specific operator as stated in > testNullArgs test. If that sounds right to you, I can help creating another > Jira and PR to tackle this. Thank you. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Commented] (JEXL-384) Improve control over JexlArithmetic null argument handling
[ https://issues.apache.org/jira/browse/JEXL-384?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17630185#comment-17630185 ] Hussachai Puripunpinyo commented on JEXL-384: - I think what I mentioned, you already addressed it in [992c8463|https://github.com/apache/commons-jexl/commit/992c8463f52880a9cb733c4ffac609ab5caff232]. I'd prefer the explicit passing the operator in the respective functions rather than detecting the class modification using reflection. IMO, it's just more natural to test the function in a stateless manner, but that's just my own preference. As long as it works as expected, it's good. Thanks for being on top of this. Cannot wait to pull 3.3 in when it's out :) > Improve control over JexlArithmetic null argument handling > -- > > Key: JEXL-384 > URL: https://issues.apache.org/jira/browse/JEXL-384 > Project: Commons JEXL > Issue Type: Task >Affects Versions: 3.3 >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > > https://issues.apache.org/jira/browse/JEXL-359 > {quote}A typical case is '+' for string and null where one would like to > consider null as a valid argument even if arithmetic is strict. > {quote} > While the above reason is valid, the code introduced in JEXL-359 causes more > confusion, and the behavior is now inconsistent. > Also, I'd like to give some counter arguments about not supporting null + > string in the strict mode. If we want to make null + string works even if > arithmetic is strict, there will be no difference between "" + "ABC" and null > + "ABC" because both cases yield "ABC" in both strict and non-strict mode. In > our code base, we set the engine to be strict, so users have to be careful > about null since it can give an undesirable result. In a non-strict mode, we > don't have a way to distinguish whether the result is the combination of null > or empty string and a string. Users need to explicitly check for null, but > there will be no enforcement > which means nobody will do that check. That's why we prefer it to be strict > and a user has to check null before using or use some namespace functions > that we provide where null will be explicitly handled. Otherwise, the > exception will be thrown. > Let me elaborate why some part of JEXL-359 causes the behavior to be > inconsistent. > *Strict Mode* > {code:java} > var i = null; > i + 'ABC'; // This will throw an exception. > null + 'ABC'; // This yields 'ABC' - the same as non-strict mode. > {code} > > *Non Strict Mode* > {code:java} > var i = null; > i + 'ABC'; // This yields 'ABC'; > null + 'ABC'; // This also yields 'ABC'; > {code} > > You can see that the behavior of null + 'ABC' in the strict mode is not > consistent with the null variable. > Also, there is a way to allow string concatenation with null using a > namespace function in a strict mode, and I think JEXL shouldn't make an > exception for this one particular case. > I'd like to propose the PR with some regression tests that applies to only > null (literal) + string case. > [https://github.com/apache/commons-jexl/pull/136] > *Note:* I ignored one test *testNullArgs* because the feature doesn't seem to > be defined well. It won't work with numeric types. > I can pass around the JexlOperator to isStrict function everywhere to address > that, but I'm trying to refrain from changing things too much since you may > have some ideas and my code might get in the way. > Please let me know if I can help with that, or you can merge my PR, take part > of it or ignore it completely :) > My idea about fixing *testNullArgs* properly is that all toString, toDouble, > toBigDecimal functions should take an additional argument which is > JexlOperator where a user can override for specific operator as stated in > testNullArgs test. If that sounds right to you, I can help creating another > Jira and PR to tackle this. Thank you. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Comment Edited] (JEXL-384) Revert null + String behavior
[ https://issues.apache.org/jira/browse/JEXL-384?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17629138#comment-17629138 ] Hussachai Puripunpinyo edited comment on JEXL-384 at 11/4/22 6:03 PM: -- [~henrib] It looks good. I still feel that the logic handling strict flag (controlNullOperand in JexlArithmetic) is not quite clean because the check is done beforehand. Thanks for working on this quickly. Do you have a rough estimate for 3.3 release? was (Author: hussachai): [~henrib] It looks good. I still feel that the logic handling control (controlNullOperand in JexlArithmetic) is not quite clean because the check is done beforehand. Thanks for working on this quickly. Do you have a rough estimate for 3.3 release? > Revert null + String behavior > - > > Key: JEXL-384 > URL: https://issues.apache.org/jira/browse/JEXL-384 > Project: Commons JEXL > Issue Type: Task >Affects Versions: 3.3 >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > > https://issues.apache.org/jira/browse/JEXL-359 > {quote}A typical case is '+' for string and null where one would like to > consider null as a valid argument even if arithmetic is strict. > {quote} > While the above reason is valid, the code introduced in JEXL-359 causes more > confusion, and the behavior is now inconsistent. > Also, I'd like to give some counter arguments about not supporting null + > string in the strict mode. If we want to make null + string works even if > arithmetic is strict, there will be no difference between "" + "ABC" and null > + "ABC" because both cases yield "ABC" in both strict and non-strict mode. In > our code base, we set the engine to be strict, so users have to be careful > about null since it can give an undesirable result. In a non-strict mode, we > don't have a way to distinguish whether the result is the combination of null > or empty string and a string. Users need to explicitly check for null, but > there will be no enforcement > which means nobody will do that check. That's why we prefer it to be strict > and a user has to check null before using or use some namespace functions > that we provide where null will be explicitly handled. Otherwise, the > exception will be thrown. > Let me elaborate why some part of JEXL-359 causes the behavior to be > inconsistent. > *Strict Mode* > {code:java} > var i = null; > i + 'ABC'; // This will throw an exception. > null + 'ABC'; // This yields 'ABC' - the same as non-strict mode. > {code} > > *Non Strict Mode* > {code:java} > var i = null; > i + 'ABC'; // This yields 'ABC'; > null + 'ABC'; // This also yields 'ABC'; > {code} > > You can see that the behavior of null + 'ABC' in the strict mode is not > consistent with the null variable. > Also, there is a way to allow string concatenation with null using a > namespace function in a strict mode, and I think JEXL shouldn't make an > exception for this one particular case. > I'd like to propose the PR with some regression tests that applies to only > null (literal) + string case. > [https://github.com/apache/commons-jexl/pull/136] > *Note:* I ignored one test *testNullArgs* because the feature doesn't seem to > be defined well. It won't work with numeric types. > I can pass around the JexlOperator to isStrict function everywhere to address > that, but I'm trying to refrain from changing things too much since you may > have some ideas and my code might get in the way. > Please let me know if I can help with that, or you can merge my PR, take part > of it or ignore it completely :) > My idea about fixing *testNullArgs* properly is that all toString, toDouble, > toBigDecimal functions should take an additional argument which is > JexlOperator where a user can override for specific operator as stated in > testNullArgs test. If that sounds right to you, I can help creating another > Jira and PR to tackle this. Thank you. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Commented] (JEXL-384) Revert null + String behavior
[ https://issues.apache.org/jira/browse/JEXL-384?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17629138#comment-17629138 ] Hussachai Puripunpinyo commented on JEXL-384: - [~henrib] It looks good. I still feel that the logic handling control (controlNullOperand in JexlArithmetic) is not quite clean because the check is done beforehand. Thanks for working on this quickly. Do you have a rough estimate for 3.3 release? > Revert null + String behavior > - > > Key: JEXL-384 > URL: https://issues.apache.org/jira/browse/JEXL-384 > Project: Commons JEXL > Issue Type: Task >Affects Versions: 3.3 >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > > https://issues.apache.org/jira/browse/JEXL-359 > {quote}A typical case is '+' for string and null where one would like to > consider null as a valid argument even if arithmetic is strict. > {quote} > While the above reason is valid, the code introduced in JEXL-359 causes more > confusion, and the behavior is now inconsistent. > Also, I'd like to give some counter arguments about not supporting null + > string in the strict mode. If we want to make null + string works even if > arithmetic is strict, there will be no difference between "" + "ABC" and null > + "ABC" because both cases yield "ABC" in both strict and non-strict mode. In > our code base, we set the engine to be strict, so users have to be careful > about null since it can give an undesirable result. In a non-strict mode, we > don't have a way to distinguish whether the result is the combination of null > or empty string and a string. Users need to explicitly check for null, but > there will be no enforcement > which means nobody will do that check. That's why we prefer it to be strict > and a user has to check null before using or use some namespace functions > that we provide where null will be explicitly handled. Otherwise, the > exception will be thrown. > Let me elaborate why some part of JEXL-359 causes the behavior to be > inconsistent. > *Strict Mode* > {code:java} > var i = null; > i + 'ABC'; // This will throw an exception. > null + 'ABC'; // This yields 'ABC' - the same as non-strict mode. > {code} > > *Non Strict Mode* > {code:java} > var i = null; > i + 'ABC'; // This yields 'ABC'; > null + 'ABC'; // This also yields 'ABC'; > {code} > > You can see that the behavior of null + 'ABC' in the strict mode is not > consistent with the null variable. > Also, there is a way to allow string concatenation with null using a > namespace function in a strict mode, and I think JEXL shouldn't make an > exception for this one particular case. > I'd like to propose the PR with some regression tests that applies to only > null (literal) + string case. > [https://github.com/apache/commons-jexl/pull/136] > *Note:* I ignored one test *testNullArgs* because the feature doesn't seem to > be defined well. It won't work with numeric types. > I can pass around the JexlOperator to isStrict function everywhere to address > that, but I'm trying to refrain from changing things too much since you may > have some ideas and my code might get in the way. > Please let me know if I can help with that, or you can merge my PR, take part > of it or ignore it completely :) > My idea about fixing *testNullArgs* properly is that all toString, toDouble, > toBigDecimal functions should take an additional argument which is > JexlOperator where a user can override for specific operator as stated in > testNullArgs test. If that sounds right to you, I can help creating another > Jira and PR to tackle this. Thank you. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Updated] (JEXL-384) Revert null + String behavior
[ https://issues.apache.org/jira/browse/JEXL-384?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Hussachai Puripunpinyo updated JEXL-384: Description: https://issues.apache.org/jira/browse/JEXL-359 {quote}A typical case is '+' for string and null where one would like to consider null as a valid argument even if arithmetic is strict. {quote} While the above reason is valid, the code introduced in JEXL-359 causes more confusion, and the behavior is now inconsistent. Also, I'd like to give some counter arguments about not supporting null + string in the strict mode. If we want to make null + string works even if arithmetic is strict, there will be no difference between "" + "ABC" and null + "ABC" because both cases yield "ABC" in both strict and non-strict mode. In our code base, we set the engine to be strict, so users have to be careful about null since it can give an undesirable result. In a non-strict mode, we don't have a way to distinguish whether the result is the combination of null or empty string and a string. Users need to explicitly check for null, but there will be no enforcement which means nobody will do that check. That's why we prefer it to be strict and a user has to check null before using or use some namespace functions that we provide where null will be explicitly handled. Otherwise, the exception will be thrown. Let me elaborate why some part of JEXL-359 causes the behavior to be inconsistent. *Strict Mode* {code:java} var i = null; i + 'ABC'; // This will throw an exception. null + 'ABC'; // This yields 'ABC' - the same as non-strict mode. {code} *Non Strict Mode* {code:java} var i = null; i + 'ABC'; // This yields 'ABC'; null + 'ABC'; // This also yields 'ABC'; {code} You can see that the behavior of null + 'ABC' in the strict mode is not consistent with the null variable. Also, there is a way to allow string concatenation with null using a namespace function in a strict mode, and I think JEXL shouldn't make an exception for this one particular case. I'd like to propose the PR with some regression tests that applies to only null (literal) + string case. [https://github.com/apache/commons-jexl/pull/136] *Note:* I ignored one test *testNullArgs* because the feature doesn't seem to be defined well. It won't work with numeric types. I can pass around the JexlOperator to isStrict function everywhere to address that, but I'm trying to refrain from changing things too much since you may have some ideas and my code might get in the way. Please let me know if I can help with that, or you can merge my PR, take part of it or ignore it completely :) My idea about fixing *testNullArgs* properly is that all toString, toDouble, toBigDecimal functions should take an additional argument which is JexlOperator where a user can override for specific operator as stated in testNullArgs test. If that sounds right to you, I can help creating another Jira and PR to tackle this. Thank you. was: https://issues.apache.org/jira/browse/JEXL-359 {quote}A typical case is '+' for string and null where one would like to consider null as a valid argument even if arithmetic is strict. {quote} While the above reason is valid, the code introduced in JEXL-359 causes more confusion, and the behavior is now inconsistent. Also, I'd like to give some counter arguments about not supporting null + string in the strict mode. If we want to make null + string works even if arithmetic is strict, there will be no difference between "" + "ABC" and null + "ABC" because both cases yield "ABC" in both strict and non-strict mode. In our code base, we set the engine to be strict, so users have to be careful about null since it can give an undesirable result. In a non-strict mode, we don't have a way to distinguish whether the result is the combination of null or empty string and a string. Users need to explicitly check for null, but there will be no enforcement which means nobody will do that check. That's why we prefer it to be strict and a user has to check null before using or use some namespace functions that we provide where null will be explicitly handled. Otherwise, the exception will be thrown. Let me elaborate why some part of JEXL-359 causes the behavior to be inconsistent. *Strict Mode* {code:java} var i = null; i + 'ABC'; // This will throw an exception. null + 'ABC'; // This yields 'ABC' - the same as non-strict mode. {code} *Non Strict Mode* {code:java} var i = null; i + 'ABC'; // This yields 'ABC'; null + 'ABC'; // This also yields 'ABC'; {code} You can see that the behavior of null + 'ABC' in the strict mode is not consistent with the null variable. Also, there is a way to allow string concatenation with null using a namespace function in a strict mode, and I think JEXL shouldn't make an exception for this one particular case. I'd like to propose the PR with some regression t
[jira] [Updated] (JEXL-384) Revert null + String behavior
[ https://issues.apache.org/jira/browse/JEXL-384?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Hussachai Puripunpinyo updated JEXL-384: Description: https://issues.apache.org/jira/browse/JEXL-359 {quote}A typical case is '+' for string and null where one would like to consider null as a valid argument even if arithmetic is strict. {quote} While the above reason is valid, the code introduced in JEXL-359 causes more confusion, and the behavior is now inconsistent. Also, I'd like to give some counter arguments about not supporting null + string in the strict mode. If we want to make null + string works even if arithmetic is strict, there will be no difference between "" + "ABC" and null + "ABC" because both cases yield "ABC" in both strict and non-strict mode. In our code base, we set the engine to be strict, so users have to be careful about null since it can give an undesirable result. In a non-strict mode, we don't have a way to distinguish whether the result is the combination of null or empty string and a string. Users need to explicitly check for null, but there will be no enforcement which means nobody will do that check. That's why we prefer it to be strict and a user has to check null before using or use some namespace functions that we provide where null will be explicitly handled. Otherwise, the exception will be thrown. Let me elaborate why some part of JEXL-359 causes the behavior to be inconsistent. *Strict Mode* {code:java} var i = null; i + 'ABC'; // This will throw an exception. null + 'ABC'; // This yields 'ABC' - the same as non-strict mode. {code} *Non Strict Mode* {code:java} var i = null; i + 'ABC'; // This yields 'ABC'; null + 'ABC'; // This also yields 'ABC'; {code} You can see that the behavior of null + 'ABC' in the strict mode is not consistent with the null variable. Also, there is a way to allow string concatenation with null using a namespace function in a strict mode, and I think JEXL shouldn't make an exception for this one particular case. I'd like to propose the PR with some regression tests that applies to only null (literal) + string case. [https://github.com/apache/commons-jexl/pull/136] *Note:* I ignored one test *testNullArgs* because the feature doesn't seem to be defined well. It won't work with numeric types. I can pass around the JexlOperator to isStrict function everywhere to address that, but I'm trying to refrain from changing things too much since you may have some ideas and my code might get in the way. Please let me know if I can help with that, or you can merge my PR, take part of it or ignore it completely :) was: https://issues.apache.org/jira/browse/JEXL-359 {quote}A typical case is '+' for string and null where one would like to consider null as a valid argument even if arithmetic is strict. {quote} While the above reason is valid, the code introduced in JEXL-359 causes more confusion, and the behavior is now inconsistent. Also, I'd like to give some counter arguments about not supporting null + string in the strict mode. If we want to make null + string works even if arithmetic is strict, there will be no difference between "" + "ABC" and null + "ABC" because both cases yield "ABC" in both strict and non-strict mode. In our code base, we set the engine to be strict, so users have to be careful about null since it can give an undesirable result. In a non-strict mode, we don't have a way to distinguish whether the result is the combination of null or empty string and a string. Users need to explicitly check for null, but there will be no enforcement which means nobody will do that check. That's why we prefer it to be strict and a user has to check null before using or use some namespace functions that we provide where null will be explicitly handled. Otherwise, the exception will be thrown. Let me elaborate why some part of JEXL-359 causes the behavior to be inconsistent. *Strict Mode* {code:java} var i = null; i + 'ABC'; // This will throw an exception. null + 'ABC'; // This yields 'ABC' - the same as non-strict mode. {code} *Non Strict Mode* {code:java} var i = null; i + 'ABC'; // This yields 'ABC'; null + 'ABC'; // This also yields 'ABC'; {code} You can see that the behavior of null + 'ABC' in the strict mode is not consistent with the null variable. Also, there is a way to allow string concatenation with null using a namespace function in a strict mode, and I think JEXL shouldn't make an exception for this one particular case. I'd like to propose the PR with some regression tests that applies to only null (literal) + string case. [https://github.com/apache/commons-jexl/pull/136] *Note:* I ignored one test *testNullArgs* because the feature doesn't seem to be defined well. It won't work with numeric types. I can pass around the JexlOperator to isStrict function everywhere to address that, but I'm trying
[jira] [Updated] (JEXL-384) Revert null + String behavior
[ https://issues.apache.org/jira/browse/JEXL-384?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Hussachai Puripunpinyo updated JEXL-384: Description: https://issues.apache.org/jira/browse/JEXL-359 {quote}A typical case is '+' for string and null where one would like to consider null as a valid argument even if arithmetic is strict. {quote} While the above reason is valid, the code introduced in JEXL-359 causes more confusion, and the behavior is now inconsistent. Also, I'd like to give some counter arguments about not supporting null + string in the strict mode. If we want to make null + string works even if arithmetic is strict, there will be no difference between "" + "ABC" and null + "ABC" because both cases yield "ABC" in both strict and non-strict mode. In our code base, we set the engine to be strict, so users have to be careful about null since it can give an undesirable result. In a non-strict mode, we don't have a way to distinguish whether the result is the combination of null or empty string and a string. Users need to explicitly check for null, but there will be no enforcement which means nobody will do that check. That's why we prefer it to be strict and a user has to check null before using or use some namespace functions that we provide where null will be explicitly handled. Otherwise, the exception will be thrown. Let me elaborate why some part of JEXL-359 causes the behavior to be inconsistent. *Strict Mode* {code:java} var i = null; i + 'ABC'; // This will throw an exception. null + 'ABC'; // This yields 'ABC' - the same as non-strict mode. {code} *Non Strict Mode* {code:java} var i = null; i + 'ABC'; // This yields 'ABC'; null + 'ABC'; // This also yields 'ABC'; {code} You can see that the behavior of null + 'ABC' in the strict mode is not consistent with the null variable. Also, there is a way to allow string concatenation with null using a namespace function in a strict mode, and I think JEXL shouldn't make an exception for this one particular case. I'd like to propose the PR with some regression tests that applies to only null (literal) + string case. [https://github.com/apache/commons-jexl/pull/136] *Note:* I ignored one test *testNullArgs* because the feature doesn't seem to be defined well. It won't work with numeric types. I can pass around the JexlOperator to isStrict function everywhere to address that, but I'm trying to refrain from changing things too much since you may have some ideas and my code might get in the way. was: https://issues.apache.org/jira/browse/JEXL-359 {quote}A typical case is '+' for string and null where one would like to consider null as a valid argument even if arithmetic is strict. {quote} While the above reason is valid, the code introduced in JEXL-359 causes more confusion, and the behavior is now inconsistent. Also, I'd like to give some counter arguments about not supporting null + string in the strict mode. If we want to make null + string works even if arithmetic is strict, there will be no difference between "" + "ABC" and null + "ABC" because both cases yield "ABC" in both strict and non-strict mode. In our code base, we set the engine to be strict, so users have to be careful about null since it can give an undesirable result. In a non-strict mode, we don't have a way to distinguish whether the result is the combination of null or empty string and a string. Users need to explicitly check for null, but there will be no enforcement which means nobody will do that check. That's why we prefer it to be strict and a user has to check null before using or use some namespace functions that we provide where null will be explicitly handled. Otherwise, the exception will be thrown. Let me elaborate why some part of JEXL-359 causes the behavior to be inconsistent. *Strict Mode* {code:java} var i = null; i + 'ABC'; // This will throw an exception. null + 'ABC'; // This yields 'ABC' - the same as non-strict mode. {code} *Non Strict Mode* {code:java} var i = null; i + 'ABC'; // This yields 'ABC'; null + 'ABC'; // This also yields 'ABC'; {code} You can see that the behavior of null + 'ABC' in the strict mode is not consistent with the null variable. Also, there is a way to allow string concatenation with null using a namespace function in a strict mode, and I think JEXL shouldn't make an exception for this one particular case. I'd like to propose the PR with some regression tests that applies to only null (literal) + string case. https://github.com/apache/commons-jexl/pull/136 > Revert null + String behavior > - > > Key: JEXL-384 > URL: https://issues.apache.org/jira/browse/JEXL-384 > Project: Commons JEXL > Issue Type: Task >Affects Versions: 3.3 >Reporter: Hussachai Puripunpinyo >Priority: Major > > https:
[jira] [Updated] (JEXL-384) Revert null + String behavior
[ https://issues.apache.org/jira/browse/JEXL-384?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Hussachai Puripunpinyo updated JEXL-384: Description: https://issues.apache.org/jira/browse/JEXL-359 {quote}A typical case is '+' for string and null where one would like to consider null as a valid argument even if arithmetic is strict. {quote} While the above reason is valid, the code introduced in JEXL-359 causes more confusion, and the behavior is now inconsistent. Also, I'd like to give some counter arguments about not supporting null + string in the strict mode. If we want to make null + string works even if arithmetic is strict, there will be no difference between "" + "ABC" and null + "ABC" because both cases yield "ABC" in both strict and non-strict mode. In our code base, we set the engine to be strict, so users have to be careful about null since it can give an undesirable result. In a non-strict mode, we don't have a way to distinguish whether the result is the combination of null or empty string and a string. Users need to explicitly check for null, but there will be no enforcement which means nobody will do that check. That's why we prefer it to be strict and a user has to check null before using or use some namespace functions that we provide where null will be explicitly handled. Otherwise, the exception will be thrown. Let me elaborate why some part of JEXL-359 causes the behavior to be inconsistent. *Strict Mode* {code:java} var i = null; i + 'ABC'; // This will throw an exception. null + 'ABC'; // This yields 'ABC' - the same as non-strict mode. {code} *Non Strict Mode* {code:java} var i = null; i + 'ABC'; // This yields 'ABC'; null + 'ABC'; // This also yields 'ABC'; {code} You can see that the behavior of null + 'ABC' in the strict mode is not consistent with the null variable. Also, there is a way to allow string concatenation with null using a namespace function in a strict mode, and I think JEXL shouldn't make an exception for this one particular case. I'd like to propose the PR with some regression tests that applies to only null (literal) + string case. https://github.com/apache/commons-jexl/pull/136 was: https://issues.apache.org/jira/browse/JEXL-359 {quote}A typical case is '+' for string and null where one would like to consider null as a valid argument even if arithmetic is strict. {quote} While the above reason is valid, the code introduced in JEXL-359 causes more confusion, and the behavior is now inconsistent. Also, I'd like to give some counter arguments about not supporting null + string in the strict mode. If we want to make null + string works even if arithmetic is strict, there will be no difference between "" + "ABC" and null + "ABC" because both cases yield "ABC" in both strict and non-strict mode. In our code base, we set the engine to be strict, so users have to be careful about null since it can give an undesirable result. In a non-strict mode, we don't have a way to distinguish whether the result is the combination of null or empty string and a string. Users need to explicitly check for null, but there will be no enforcement which means nobody will do that check. That's why we prefer it to be strict and a user has to check null before using or use some namespace functions that we provide where null will be explicitly handled. Otherwise, the exception will be thrown. Let me elaborate why some part of JEXL-359 causes the behavior to be inconsistent. *Strict Mode* {code:java} var i = null; i + 'ABC'; // This will throw an exception. null + 'ABC'; // This yields 'ABC' - the same as non-strict mode. {code} *Non Strict Mode* {code:java} var i = null; i + 'ABC'; // This yields 'ABC'; null + 'ABC'; // This also yields 'ABC'; {code} You can see that the behavior of null + 'ABC' in the strict mode is not consistent with the null variable. Also, there is a way to allow string concatenation with null using a namespace function in a strict mode, and I think JEXL shouldn't make an exception for this one particular case. I'd like to propose the PR with some regression tests that applies to only null (literal) + string case. > Revert null + String behavior > - > > Key: JEXL-384 > URL: https://issues.apache.org/jira/browse/JEXL-384 > Project: Commons JEXL > Issue Type: Task >Affects Versions: 3.3 >Reporter: Hussachai Puripunpinyo >Priority: Major > > https://issues.apache.org/jira/browse/JEXL-359 > {quote}A typical case is '+' for string and null where one would like to > consider null as a valid argument even if arithmetic is strict. > {quote} > While the above reason is valid, the code introduced in JEXL-359 causes more > confusion, and the behavior is now inconsistent. > Also, I'd like to give some counter arguments about not suppo
[jira] [Created] (JEXL-384) Revert null + String behavior
Hussachai Puripunpinyo created JEXL-384: --- Summary: Revert null + String behavior Key: JEXL-384 URL: https://issues.apache.org/jira/browse/JEXL-384 Project: Commons JEXL Issue Type: Task Affects Versions: 3.3 Reporter: Hussachai Puripunpinyo https://issues.apache.org/jira/browse/JEXL-359 {quote}A typical case is '+' for string and null where one would like to consider null as a valid argument even if arithmetic is strict. {quote} While the above reason is valid, the code introduced in JEXL-359 causes more confusion, and the behavior is now inconsistent. Also, I'd like to give some counter arguments about not supporting null + string in the strict mode. If we want to make null + string works even if arithmetic is strict, there will be no difference between "" + "ABC" and null + "ABC" because both cases yield "ABC" in both strict and non-strict mode. In our code base, we set the engine to be strict, so users have to be careful about null since it can give an undesirable result. In a non-strict mode, we don't have a way to distinguish whether the result is the combination of null or empty string and a string. Users need to explicitly check for null, but there will be no enforcement which means nobody will do that check. That's why we prefer it to be strict and a user has to check null before using or use some namespace functions that we provide where null will be explicitly handled. Otherwise, the exception will be thrown. Let me elaborate why some part of JEXL-359 causes the behavior to be inconsistent. *Strict Mode* {code:java} var i = null; i + 'ABC'; // This will throw an exception. null + 'ABC'; // This yields 'ABC' - the same as non-strict mode. {code} *Non Strict Mode* {code:java} var i = null; i + 'ABC'; // This yields 'ABC'; null + 'ABC'; // This also yields 'ABC'; {code} You can see that the behavior of null + 'ABC' in the strict mode is not consistent with the null variable. Also, there is a way to allow string concatenation with null using a namespace function in a strict mode, and I think JEXL shouldn't make an exception for this one particular case. I'd like to propose the PR with some regression tests that applies to only null (literal) + string case. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Updated] (JEXL-378) Incremental operator and decremental operator do not honor the side-effect flag
[ https://issues.apache.org/jira/browse/JEXL-378?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Hussachai Puripunpinyo updated JEXL-378: Description: I tested the new features (++/–-) and found that these operators do not honor the side-effect flag. I also have a very straightforward PR for this ticket: [https://github.com/apache/commons-jexl/pull/111] was:I tested the new features (++/–-) and found that these operators do not honor the side-effect flag. I also have a very straightforward PR for this ticket. > Incremental operator and decremental operator do not honor the side-effect > flag > --- > > Key: JEXL-378 > URL: https://issues.apache.org/jira/browse/JEXL-378 > Project: Commons JEXL > Issue Type: Bug >Reporter: Hussachai Puripunpinyo >Priority: Major > > I tested the new features (++/–-) and found that these operators do not honor > the side-effect flag. I also have a very straightforward PR for this ticket: > [https://github.com/apache/commons-jexl/pull/111] > -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Updated] (JEXL-378) Incremental operator and decremental operator do not honor the side-effect flag
[ https://issues.apache.org/jira/browse/JEXL-378?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Hussachai Puripunpinyo updated JEXL-378: Summary: Incremental operator and decremental operator do not honor the side-effect flag (was: Incremental operator and decremental operator do not honor side-effect flag) > Incremental operator and decremental operator do not honor the side-effect > flag > --- > > Key: JEXL-378 > URL: https://issues.apache.org/jira/browse/JEXL-378 > Project: Commons JEXL > Issue Type: Bug >Reporter: Hussachai Puripunpinyo >Priority: Major > > I tested the new features (++/–-) and found that these operators do not honor > the side-effect flag. I also have a very straightforward PR for this ticket. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Created] (JEXL-378) Incremental operator and decremental operator do not honor side-effect flag
Hussachai Puripunpinyo created JEXL-378: --- Summary: Incremental operator and decremental operator do not honor side-effect flag Key: JEXL-378 URL: https://issues.apache.org/jira/browse/JEXL-378 Project: Commons JEXL Issue Type: Bug Reporter: Hussachai Puripunpinyo I tested the new features (++/–-) and found that these operators do not honor the side-effect flag. I also have a very straightforward PR for this ticket. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Commented] (JEXL-367) Named function and fat-arrow (=>) lambda syntax
[ https://issues.apache.org/jira/browse/JEXL-367?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17533929#comment-17533929 ] Hussachai Puripunpinyo commented on JEXL-367: - [~henrib] Awesome. Thanks so much. Glad that I asked for this named function :) > Named function and fat-arrow (=>) lambda syntax > --- > > Key: JEXL-367 > URL: https://issues.apache.org/jira/browse/JEXL-367 > Project: Commons JEXL > Issue Type: Wish >Affects Versions: 3.2.1 >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > > The JEXL code surprisingly looks a lot like Javascript. I think this change > is a good transition for folks to update the code, and it's pretty fine if > they can tolerate using the deprecate syntax and don't mind seeing a warning > log pop up every time. > I'd like to propose supporting => and deprecate ->. > The reasons are > - JavaScript becomes very popular and many people are familiar with it. > - JEXL is more like for a quick short script. In many scenarios, the target > audiences are not a programer. They often mistake a language as a JavaScript > (from my experience). > - JEXL syntax already looks a lot like JavaScript > -- var for variable declaration (Java added in Java 10, but JavaScript > supports this from the beginning) > -- The function keyword > -- Implicit type coercion > -- Ternary operator > The proposed change. > * Support => in addition to -> > * Deprecate -> and show a warning log when it's used. -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Commented] (JEXL-342) Support for Java Optional.
[ https://issues.apache.org/jira/browse/JEXL-342?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17532656#comment-17532656 ] Hussachai Puripunpinyo commented on JEXL-342: - [~henrib] Let me put the note on the things that I had to change the visibility. It's hard for me to find it out right now. For optional, I did change Arithemtic, and we also changed getAttribute. I had to override the getAttribute function from the Interpreter for non-arithmetic context. We made it configurable because as you know we support various languages. There are many other classes that we can unwrap and I don't think that it should be part of JEXL. I feel like it's better if you can provide the callback function for the extension to override rather than putting the concrete implementation there. > Support for Java Optional. > -- > > Key: JEXL-342 > URL: https://issues.apache.org/jira/browse/JEXL-342 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Garret Wilson >Priority: Major > Fix For: Later > > > Does JEXL provide any native support for Java 8+ {{Optional<>}}? If not can > this this easily be added as some sort of plugin, or better yet can it be > added to the library? > h3. {{Optional}} Traversal > I need to create an API that works well for application developers as for > those using templates with JEXL expressions. Let's say that the {{Bar}} class > has a {{Bar.getName()}}. And the {{Foo}} class has this method: > {code:java} > Optional getBar(String barId); > {code} > In code getting the "test" foo-bar name would be like this: > {code:java} > String fooBarName=foo.getBar("test").map(Bar::getName).orElse(null); > {code} > I want the navigation across {{Optional<>}} to work just as if it were a > nullable variable. That is, I want the following JEXL expression to give the > same result as {{fooBarName}} above: > {code} > foo.bar("test").name > {code} > If {{Foo.getBar(String)}} returned a nullable rather than an {{Optional<>}}, > I think JEXL would work for this already. but the whole point of > {{Optional<>}} is that I keep nullables out of my code, so I don't want to > create inferior APIs inconsistent with the rest of my project just to work > with JEXL. > h3. {{Optional}} Getter Name > As icing on the cake, I would like to have {{Optional<>}} returning getter > discovery to recognize the {{findXXX}} pattern, as [Stephen Colebourne > suggested|https://blog.joda.org/2015/09/naming-optional-query-methods.html]. > I've been using this pattern for several years, and I really like it. Thus to > indicate that the {{Foo.getBar(String)}} "getter" doesn't return a nullable > but an {{Optional<>}}, I would name it {{Foo.findBar(String)}}, like this: > {code:java} > Optional findBar(String barId); > {code} > I would thus want the exact same JEXL expression above to still work: > {code} > foo.bar("test").name > {code} > Otherwise I'll have to forego use of modern Java constructs and make an > outdated style and less safe API just to get JEXL to work. -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Comment Edited] (JEXL-366) Fail to evaluate string and number comparison
[ https://issues.apache.org/jira/browse/JEXL-366?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17532645#comment-17532645 ] Hussachai Puripunpinyo edited comment on JEXL-366 at 5/6/22 5:02 AM: - [~henrib] Can you shed some light on why you want to avoid using BigDecimal? Your change has a flaw when it fallbacks to String comparison. The following method truncates the decimal point. {code:java} private long comparableLong(Object arg) throws NumberFormatException { if (arg instanceof String) { String s = (String) arg; return s.isEmpty()? 0 :(long) Double.parseDouble((String) arg); } else { return toLong(arg); } } {code} There is a bug when one operand is a string with decimal and another one is a numerable. For example "1.01" == 1 This will return true for your change when it should not. was (Author: hussachai): [~henrib] Can you shed some light on why you want to avoid using BigDecimal? Your change has a flaw when it fallbacks to String comparison. The following method truncate the decimal point. {code:java} private long comparableLong(Object arg) throws NumberFormatException { if (arg instanceof String) { String s = (String) arg; return s.isEmpty()? 0 :(long) Double.parseDouble((String) arg); } else { return toLong(arg); } } {code} There is a bug when one operand is a string with decimal and another one is a numerable. For example "1.01" == 1 This will return true for your change when it should not. > Fail to evaluate string and number comparison > - > > Key: JEXL-366 > URL: https://issues.apache.org/jira/browse/JEXL-366 > Project: Commons JEXL > Issue Type: Improvement >Affects Versions: 3.2.1 >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > Fix For: 3.3 > > > The comparison logic doesn't cover the case when one operand is a string and > another operand is a numerable type (int, short, long,..). > The expected result for '1.0' == 1 should be true but it fails because the > string comparison check is after the numerable type check. JEXL tries to > parse '1.0' using toLong function and it fails with this error message `For > input string: "1.0"` > Moving a string comparison up before other number type checks will not cover > some corner cases such as > '1.00' == 1.0 // String comparison will yield false but it obviously doesn't > make sense. > The proposed change is to add the following code to handle the corner case > when one operand is string and another operand is numerable. To cover this > corner case, we can apply toBigDecimal to both *lhs* and *rhs* since it > should cover any arbitrary number in a string form, and it handles other > number types well. > {code:java} > if (isNumberable(left) || isNumberable(right)) { > if (left instanceof String || right instanceof String) { > final BigDecimal l = toBigDecimal(left); > final BigDecimal r = toBigDecimal(right); > return l.compareTo(r); > } else { > // this code block remains the same > } > return 0; > } {code} > JEXL syntax is very similar to ECMA script except a few small set that are > not the same. So, I think following the ECMA spec for this comparison check > makes sense. > The following code is JavaScript and it can be used in the JEXL test to make > sure that the behavior of comparison are the same. > Note that '1.0' == 1 yields true > {code:java} > function assert(condition, source) { > if (!condition) { > throw `Assertion failed for ${source}`; > } > } > // Basic compare > let exprs = [ > "1 == 1", true, > "1 != 1", false, > "1 != 2", true, > "1 > 2", false, > "1 >= 2", false, > "1 < 2", true, > "1 <= 2", true, > // Int <-> Float Coercion > "1.0 == 1", true, > "1 == 1.0", true, > "1.1 != 1", true, > "1.1 < 2", true, > // numbers and strings > "'1' == 1", true, > "'' == 0", true, // empty string is coerced to zero (ECMA compliance) > "1.0 >= '1'", true, > "1.0 > '1'", false > ];for (e = 0; e < exprs.length; e += 2) { > let stext = exprs[e]; > let expected = exprs[e + 1]; > assert(eval(stext) == expected, stext); > > } {code} > -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Commented] (JEXL-366) Fail to evaluate string and number comparison
[ https://issues.apache.org/jira/browse/JEXL-366?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17532645#comment-17532645 ] Hussachai Puripunpinyo commented on JEXL-366: - [~henrib] Can you shed some light on why you want to avoid using BigDecimal? Your change has a flaw when it fallbacks to String comparison. The following method truncate the decimal point. {code:java} private long comparableLong(Object arg) throws NumberFormatException { if (arg instanceof String) { String s = (String) arg; return s.isEmpty()? 0 :(long) Double.parseDouble((String) arg); } else { return toLong(arg); } } {code} There is a bug when one operand is a string with decimal and another one is a numerable. For example "1.01" == 1 This will return true for your change when it should not. > Fail to evaluate string and number comparison > - > > Key: JEXL-366 > URL: https://issues.apache.org/jira/browse/JEXL-366 > Project: Commons JEXL > Issue Type: Improvement >Affects Versions: 3.2.1 >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > Fix For: 3.3 > > > The comparison logic doesn't cover the case when one operand is a string and > another operand is a numerable type (int, short, long,..). > The expected result for '1.0' == 1 should be true but it fails because the > string comparison check is after the numerable type check. JEXL tries to > parse '1.0' using toLong function and it fails with this error message `For > input string: "1.0"` > Moving a string comparison up before other number type checks will not cover > some corner cases such as > '1.00' == 1.0 // String comparison will yield false but it obviously doesn't > make sense. > The proposed change is to add the following code to handle the corner case > when one operand is string and another operand is numerable. To cover this > corner case, we can apply toBigDecimal to both *lhs* and *rhs* since it > should cover any arbitrary number in a string form, and it handles other > number types well. > {code:java} > if (isNumberable(left) || isNumberable(right)) { > if (left instanceof String || right instanceof String) { > final BigDecimal l = toBigDecimal(left); > final BigDecimal r = toBigDecimal(right); > return l.compareTo(r); > } else { > // this code block remains the same > } > return 0; > } {code} > JEXL syntax is very similar to ECMA script except a few small set that are > not the same. So, I think following the ECMA spec for this comparison check > makes sense. > The following code is JavaScript and it can be used in the JEXL test to make > sure that the behavior of comparison are the same. > Note that '1.0' == 1 yields true > {code:java} > function assert(condition, source) { > if (!condition) { > throw `Assertion failed for ${source}`; > } > } > // Basic compare > let exprs = [ > "1 == 1", true, > "1 != 1", false, > "1 != 2", true, > "1 > 2", false, > "1 >= 2", false, > "1 < 2", true, > "1 <= 2", true, > // Int <-> Float Coercion > "1.0 == 1", true, > "1 == 1.0", true, > "1.1 != 1", true, > "1.1 < 2", true, > // numbers and strings > "'1' == 1", true, > "'' == 0", true, // empty string is coerced to zero (ECMA compliance) > "1.0 >= '1'", true, > "1.0 > '1'", false > ];for (e = 0; e < exprs.length; e += 2) { > let stext = exprs[e]; > let expected = exprs[e + 1]; > assert(eval(stext) == expected, stext); > > } {code} > -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Comment Edited] (JEXL-367) Deprecate -> and support =>
[ https://issues.apache.org/jira/browse/JEXL-367?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17531494#comment-17531494 ] Hussachai Puripunpinyo edited comment on JEXL-367 at 5/4/22 6:08 AM: - [~henrib] We added a ton of things to JEXL. We also removed a lot of things from JEXL. For example, this one will work on our JEXL fork as well as JS {code:java} var list = [1, 2, 3]; var r = list.map(x => {return x * x}).reduce((acc, x) => { return acc + x}); console.log(r) {code} We have data binding for Scala and Kotlin. When the list literal above is used in Scala environment, it produces scala.immutable.List instead of java.util.List. The map, reduce, and other functions defined in JS work out of the box. We also unwrap Java Optional, Scala Option, Kotlin Arrow Option and other monadic types like Either and Try by default. The dot notation (object navigation) is null-safe by default. So, for the expression like a.b.c if a is null, it's still fine. If b is Option, it will be unwrapped. There is no other language can beat this succinctness :) My users understand that this is not JS and they actually like it more than JS. Like the above example. The return keyword can be omitted in JEXL but it's required in JS. The JSON navigation works out of the box and it doesn't matter what JSON library they are using, our JEXL fork understands their JSON tree and walks it as if it is a regular object. The code is hosted in my company private repo and I'm kinda believe that it's hard to request it to be open source due to security concerns. [~dmitri_blinov] You have a valid point, but I don't think it is good for JEXL to be a unique language by its own. Honestly, JEXL as a language doesn't stand a chance to compete with other languages out there. To be unique and making it worth learning must come with substantial benefits that users will gain. The key point is familiarity. Users tend to prefer utilizing existing knowledge if possible. I like that JEXL is similar to JS and it has some unique features that make it even better for quick and dirty scripting (JEXL is much better than Coffescript for example). My JEXL fork is also much more succinct than JS and it works well across different JVM languages. Thanks to the extensibility of JEXL. Before JEXL, we did use Nashorn as our javascript engine. It's not quite secure, and the performance is really poor. On top of that, Nashorn has its own types that we have to convert back and forth (We cannot create a native binding so there is a big overhead right there). We cannot reuse existing Java/Kotlin/Scala libraries there. Putting JS libraries and interpreting the whole thing takes enormous time and resource. So, we didn't even dare to think about doing it :D Later, Oracle announced that they would deprecate Nashorn in Java11, and it was the last string for us. We were uncertain with the future of the engine. So we dropped it and looked for another simple language to use. Luckily I found the hidden gem, JEXL. So, we extended it instead of building everything from scratch. Since Rhino is mentioned, I can tell you that Nashorn is slow but it's still way faster than Rhino. Using JS engine in JVM, it means we also have to deal with the platform compatibility and the code base that is way harder to comprehend than JEXL because the full JS implementation is very very complex. was (Author: hussachai): [~henrib] We added a ton of things to JEXL. We also removed a lot of things from JEXL. For example, this one will work on our JEXL fork as well as JS {code:java} var list = [1, 2, 3]; var r = list.map(x => {return x * x}).reduce((acc, x) => { return acc + x}); console.log(r) {code} We have data binding for Scala and Kotlin. When the list literal above is used in Scala environment, it produces scala.immutable.List instead of java.util.List. The map, reduce, and other functions defined in JS work out of the box. We also unwrap Java Optional, Scala Option, Kotlin Arrow Option and other monadic types like Either and Try by default. The dot notation (object navigation) is null-safe by default. So, for the expression like a.b.c if a is null, it's still fine. If b is Option, it will be unwrapped. There is no other language can beat this succinctness :) We also have some weird features that some objects can behave differently based on the context it is used. Some objects can yield a dynamically computed value instead of the object itself. My users understand that this is not JS and they actually like it more than JS. Like the above example. The return keyword can be omitted in JEXL but it's required in JS. The JSON navigation works out of the box and it doesn't matter what JSON library they are using, our JEXL fork understands their JSON tree and walks it as if it is a regular object. Unfortunately, the code is hosted in
[jira] [Commented] (JEXL-367) Deprecate -> and support =>
[ https://issues.apache.org/jira/browse/JEXL-367?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17531494#comment-17531494 ] Hussachai Puripunpinyo commented on JEXL-367: - [~henrib] We added a ton of things to JEXL. We also removed a lot of things from JEXL. For example, this one will work on our JEXL fork as well as JS {code:java} var list = [1, 2, 3]; var r = list.map(x => {return x * x}).reduce((acc, x) => { return acc + x}); console.log(r) {code} We have data binding for Scala and Kotlin. When the list literal above is used in Scala environment, it produces scala.immutable.List instead of java.util.List. The map, reduce, and other functions defined in JS work out of the box. We also unwrap Java Optional, Scala Option, Kotlin Arrow Option and other monadic types like Either and Try by default. The dot notation (object navigation) is null-safe by default. So, for the expression like a.b.c if a is null, it's still fine. If b is Option, it will be unwrapped. There is no other language can beat this succinctness :) We also have some weird features that some objects can behave differently based on the context it is used. Some objects can yield a dynamically computed value instead of the object itself. My users understand that this is not JS and they actually like it more than JS. Like the above example. The return keyword can be omitted in JEXL but it's required in JS. The JSON navigation works out of the box and it doesn't matter what JSON library they are using, our JEXL fork understands their JSON tree and walks it as if it is a regular object. Unfortunately, the code is hosted in my company private repo and I'm kinda believe that it's hard to request it to be open source due to security concerns. [~dmitri_blinov] You have a valid point, but I don't think it is good for JEXL to be a unique language by its own. Honestly, JEXL as a language doesn't stand a chance to compete with other languages out there. To be unique and making it worth learning must come with substantial benefits that users will gain. The key point is familiarity as most of my users do not want to be a JEXL expert. My target users are not even a software engineer. They want to get the job done with minimum effort. They usually don't care much about the beauty of code or how smart the language is. They just want to utilize their existing knowledge. I like that JEXL is similar to JS and it has some unique features that make it even better for quick and dirty scripting (JEXL is much better than Coffescript for example). My JEXL fork is also much more succinct than JS and it works well across different JVM languages. Thanks to the extensibility of JEXL. Before JEXL, we did use Nashorn as our javascript engine. It's not quite secure, and the performance is really poor. On top of that, Nashorn has its own types that we have to convert back and forth (We cannot create a native binding so there is a big overhead right there). We cannot reuse existing Java/Kotlin/Scala libraries there. Putting JS libraries and interpreting the whole thing takes enormous time and resource. So, we didn't even dare to think about doing it :D Later, Oracle announced that they would deprecate Nashorn in Java11, and it was the last string for us. We were uncertain with the future of the engine. So we dropped it and looked for another simple language to use. Luckily I found the hidden gem, JEXL. So, we extended it instead of building everything from scratch. Since Rhino is mentioned, I can tell you that Nashorn is slow but it's still way faster than Rhino. Using JS engine in JVM, it means we also have to deal with the platform compatibility and the code base that is way harder to comprehend than JEXL because the full JS implementation is very very complex. > Deprecate -> and support => > --- > > Key: JEXL-367 > URL: https://issues.apache.org/jira/browse/JEXL-367 > Project: Commons JEXL > Issue Type: Wish >Affects Versions: 3.2.1 >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > > The JEXL code surprisingly looks a lot like Javascript. I think this change > is a good transition for folks to update the code, and it's pretty fine if > they can tolerate using the deprecate syntax and don't mind seeing a warning > log pop up every time. > I'd like to propose supporting => and deprecate ->. > The reasons are > - JavaScript becomes very popular and many people are familiar with it. > - JEXL is more like for a quick short script. In many scenarios, the target > audiences are not a programer. They often mistake a language as a JavaScript > (from my experience). > - JEXL syntax already looks a lot like JavaScript > -- var for variable declaration (Java added in Java 10, but JavaSc
[jira] [Comment Edited] (JEXL-367) Deprecate -> and support =>
[ https://issues.apache.org/jira/browse/JEXL-367?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17531040#comment-17531040 ] Hussachai Puripunpinyo edited comment on JEXL-367 at 5/4/22 4:25 AM: - I know you are not asking me but since I like JEXL approach for the most part. So I'd like to voice my opinion a little bit here. Java is a statically typed language. JEXL is not built for a big sophisticate code. It's for a quick and probably dirty script that can get the job done. Statically type for this kind of job is overkill. Also, it's quite complex to built a statically typed language. Groovy has a very small user base. Many people don't even know that this language exists. The only thing that keeps it alive is gradle. I'm sure Kotlin will take over that space soon. and Grails is .. what is that? Python is not JVM. (I know there was Jython/JPython and it's long gone). Python is a dynamically typed language and it's very good for scripting too. Everything looks good except that indentations that can throw many people off. Also, It'll be very hard to embed python code in Java when multiline string is not supported (I know it's now possible with Java 15). I don't think there is anything so special about JS. It's just popular and a lot of people know it. I believe my PM can write a basic JS code. The documentation/books/tutorial are everywhere. Anyone can try it out quickly without installing anything. It's just about familiarity. I advertise my JEXL fork as a subset of JavaScript on steroid. We support a lot of JS functions and most of the time, JEXL code written by our users can be run in the web browser too. If JEXL is not resemble to JS, I'd have a question too. Why not JS? was (Author: hussachai): I know you are not asking me but since I like JEXL approach for the most part. So I'd like to voice my opinion a little bit here. Java is a statically typed language. JEXL is not built for a big sophisticate code. It's for a quick and probably dirty script that can get the job done. Statically type for this kind of job is overkill. Also, it's quite complex to built a statically typed language. Groovy has a very small user base. Many people don't even know that this language exists. The only thing that keeps it alive is gradle. I'm sure Kotlin will take over that space soon. and Grails is .. what is that? Python is not JVM. (I know there was Jython/JPython and it's long gone). Python is a dynamically typed language and it's very good for scripting too. Everything looks good exception indentations that can throw many people off. Also, It'll be very hard to embed python code in Java when multiline string is not supported (I know it's now possible with Java 15). I don't think there is anything so special about JS. It's just popular and a lot of people know it. I believe my PM can write a basic JS code. The documentation/books/tutorial are everywhere. Anyone can try it out quickly without installing anything. It's just about familiarity. I advertise my JEXL fork as a subset of JavaScript on steroid. We support a lot of JS functions and most of the time, JEXL code written by our users can be run in the web browser too. If JEXL is not resemble to JS, I'd have a question too. Why not JS? > Deprecate -> and support => > --- > > Key: JEXL-367 > URL: https://issues.apache.org/jira/browse/JEXL-367 > Project: Commons JEXL > Issue Type: Wish >Affects Versions: 3.2.1 >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > > The JEXL code surprisingly looks a lot like Javascript. I think this change > is a good transition for folks to update the code, and it's pretty fine if > they can tolerate using the deprecate syntax and don't mind seeing a warning > log pop up every time. > I'd like to propose supporting => and deprecate ->. > The reasons are > - JavaScript becomes very popular and many people are familiar with it. > - JEXL is more like for a quick short script. In many scenarios, the target > audiences are not a programer. They often mistake a language as a JavaScript > (from my experience). > - JEXL syntax already looks a lot like JavaScript > -- var for variable declaration (Java added in Java 10, but JavaScript > supports this from the beginning) > -- The function keyword > -- Implicit type coercion > -- Ternary operator > The proposed change. > * Support => in addition to -> > * Deprecate -> and show a warning log when it's used. -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Commented] (JEXL-367) Deprecate -> and support =>
[ https://issues.apache.org/jira/browse/JEXL-367?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17531040#comment-17531040 ] Hussachai Puripunpinyo commented on JEXL-367: - I know you are not asking me but since I like JEXL approach for the most part. So I'd like to voice my opinion a little bit here. Java is a statically typed language. JEXL is not built for a big sophisticate code. It's for a quick and probably dirty script that can get the job done. Statically type for this kind of job is overkill. Also, it's quite complex to built a statically typed language. Groovy has a very small user base. Many people don't even know that this language exists. The only thing that keeps it alive is gradle. I'm sure Kotlin will take over that space soon. and Grails is .. what is that? Python is not JVM. (I know there was Jython/JPython and it's long gone). Python is a dynamically typed language and it's very good for scripting too. Everything looks good exception indentations that can throw many people off. Also, It'll be very hard to embed python code in Java when multiline string is not supported (I know it's now possible with Java 15). I don't think there is anything so special about JS. It's just popular and a lot of people know it. I believe my PM can write a basic JS code. The documentation/books/tutorial are everywhere. Anyone can try it out quickly without installing anything. It's just about familiarity. I advertise my JEXL fork as a subset of JavaScript on steroid. We support a lot of JS functions and most of the time, JEXL code written by our users can be run in the web browser too. If JEXL is not resemble to JS, I'd have a question too. Why not JS? > Deprecate -> and support => > --- > > Key: JEXL-367 > URL: https://issues.apache.org/jira/browse/JEXL-367 > Project: Commons JEXL > Issue Type: Wish >Affects Versions: 3.2.1 >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > > The JEXL code surprisingly looks a lot like Javascript. I think this change > is a good transition for folks to update the code, and it's pretty fine if > they can tolerate using the deprecate syntax and don't mind seeing a warning > log pop up every time. > I'd like to propose supporting => and deprecate ->. > The reasons are > - JavaScript becomes very popular and many people are familiar with it. > - JEXL is more like for a quick short script. In many scenarios, the target > audiences are not a programer. They often mistake a language as a JavaScript > (from my experience). > - JEXL syntax already looks a lot like JavaScript > -- var for variable declaration (Java added in Java 10, but JavaScript > supports this from the beginning) > -- The function keyword > -- Implicit type coercion > -- Ternary operator > The proposed change. > * Support => in addition to -> > * Deprecate -> and show a warning log when it's used. -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Commented] (JEXL-367) Deprecate -> and support =>
[ https://issues.apache.org/jira/browse/JEXL-367?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17530481#comment-17530481 ] Hussachai Puripunpinyo commented on JEXL-367: - [~henrib] Fair enough. I've been thinking about this, and I think I agree with you on the feature control. I don't like two syntax doing the same thing like supporting both fat arrow and thin arrow at the same time. Even one is deprecated, users tend to ignore that and I feel like the code will be confusing. So, the feature control is a good idea. That's a great news to me to know that `let` is in your plan. We have a lot of JEXL scripts written by users and some script are really huge. One thing about `var`. If it's declared at the top level, it still won't be exported to the context. Is that intentional? Also, I know this is deviating from the original topic, but since I got your attention here. Do you plan to support the function declaration syntax like the following? {code:java} function name(args) { ... } {code} > Deprecate -> and support => > --- > > Key: JEXL-367 > URL: https://issues.apache.org/jira/browse/JEXL-367 > Project: Commons JEXL > Issue Type: Wish >Affects Versions: 3.2.1 >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > > The JEXL code surprisingly looks a lot like Javascript. I think this change > is a good transition for folks to update the code, and it's pretty fine if > they can tolerate using the deprecate syntax and don't mind seeing a warning > log pop up every time. > I'd like to propose supporting => and deprecate ->. > The reasons are > - JavaScript becomes very popular and many people are familiar with it. > - JEXL is more like for a quick short script. In many scenarios, the target > audiences are not a programer. They often mistake a language as a JavaScript > (from my experience). > - JEXL syntax already looks a lot like JavaScript > -- var for variable declaration (Java added in Java 10, but JavaScript > supports this from the beginning) > -- The function keyword > -- Implicit type coercion > -- Ternary operator > The proposed change. > * Support => in addition to -> > * Deprecate -> and show a warning log when it's used. -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Commented] (JEXL-367) Deprecate -> and support =>
[ https://issues.apache.org/jira/browse/JEXL-367?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17529792#comment-17529792 ] Hussachai Puripunpinyo commented on JEXL-367: - I raised this Jira because I think many people kinda prefer the fat arrow to the arrow. I think I have seen a PR for this change, but I understand that you want to maintain the backward compat. The feature controller will work. IMO, I'd prefer to have this not-configurable. It'll be less error prone that way. It's also hard to move the existing JEXL code base to the new one if we only support one syntax at a time. We probably need to have 2 engines, one for the old code and another one for the new code. We need to read AST just to determine what engine should be used, and it doesn't sound good for this complication. That's why I'd like to propose supporting both syntax at the same time and deprecate the old syntax. Maybe JEXL 4 or 5 can drop the support. or it can be like Thread.stop in Java where it will be deprecated forever :D > Deprecate -> and support => > --- > > Key: JEXL-367 > URL: https://issues.apache.org/jira/browse/JEXL-367 > Project: Commons JEXL > Issue Type: Wish >Affects Versions: 3.2.1 >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > > The JEXL code surprisingly looks a lot like Javascript. I think this change > is a good transition for folks to update the code, and it's pretty fine if > they can tolerate using the deprecate syntax and don't mind seeing a warning > log pop up every time. > I'd like to propose supporting => and deprecate ->. > The reasons are > - JavaScript becomes very popular and many people are familiar with it. > - JEXL is more like for a quick short script. In many scenarios, the target > audiences are not a programer. They often mistake a language as a JavaScript > (from my experience). > - JEXL syntax already looks a lot like JavaScript > -- var for variable declaration (Java added in Java 10, but JavaScript > supports this from the beginning) > -- The function keyword > -- Implicit type coercion > -- Ternary operator > The proposed change. > * Support => in addition to -> > * Deprecate -> and show a warning log when it's used. -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Commented] (JEXL-366) Fail to evaluate string and number comparison
[ https://issues.apache.org/jira/browse/JEXL-366?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17529782#comment-17529782 ] Hussachai Puripunpinyo commented on JEXL-366: - Got it :) . That's the reason why I use toBigDecimal which has the following logic that uses a configured math context. {code:java} return roundBigDecimal(new BigDecimal(string, getMathContext()));{code} I'd say the logic I want to add is kinda equivalent to the existing one. For example: '1.0' == 1b This expression will be evaluated by the first check because the right operand is BigDecimal {code:java} if (left instanceof BigDecimal || right instanceof BigDecimal) { final BigDecimal l = toBigDecimal(left); final BigDecimal r = toBigDecimal(right); return l.compareTo(r); } {code} As you can see, the right operand satisfies to the right check which means this '1.0' == 1b will be computed the same way as the logic I introduced. The difference in my case is that the int will be widen to BigDecimal and the following code will be used to convert the numerable to BigDecimal. It actually doesn't really do anything because numerable won't have any decimal value. I think that's the reason why the code for Character doesn't even care to apply the configured math context. {code:java} if (val instanceof Number) { return roundBigDecimal(new BigDecimal(val.toString(), getMathContext())); } or if (val instanceof Character) { final int i = ((Character) val); return new BigDecimal(i); }{code} Anyway, the caveat here is that the string "1.1" can be equal to 1 when the math context is configured like {code:java} new MathContext(1, RoundingMode.FLOOR) {code} But, this will fail the existing code as well. The existing logic will say that this is true '1.1' == 1b if the math context is configured as above. So, I'd say the logic I want to add pretty conforms to the existing behavior except that it won't fail when you do '1.0' == 1. > Fail to evaluate string and number comparison > - > > Key: JEXL-366 > URL: https://issues.apache.org/jira/browse/JEXL-366 > Project: Commons JEXL > Issue Type: Improvement >Affects Versions: 3.2.1 >Reporter: Hussachai Puripunpinyo >Priority: Major > > The comparison logic doesn't cover the case when one operand is a string and > another operand is a numerable type (int, short, long,..). > The expected result for '1.0' == 1 should be true but it fails because the > string comparison check is after the numerable type check. JEXL tries to > parse '1.0' using toLong function and it fails with this error message `For > input string: "1.0"` > Moving a string comparison up before other number type checks will not cover > some corner cases such as > '1.00' == 1.0 // String comparison will yield false but it obviously doesn't > make sense. > The proposed change is to add the following code to handle the corner case > when one operand is string and another operand is numerable. To cover this > corner case, we can apply toBigDecimal to both *lhs* and *rhs* since it > should cover any arbitrary number in a string form, and it handles other > number types well. > {code:java} > if (isNumberable(left) || isNumberable(right)) { > if (left instanceof String || right instanceof String) { > final BigDecimal l = toBigDecimal(left); > final BigDecimal r = toBigDecimal(right); > return l.compareTo(r); > } else { > // this code block remains the same > } > return 0; > } {code} > JEXL syntax is very similar to ECMA script except a few small set that are > not the same. So, I think following the ECMA spec for this comparison check > makes sense. > The following code is JavaScript and it can be used in the JEXL test to make > sure that the behavior of comparison are the same. > Note that '1.0' == 1 yields true > {code:java} > function assert(condition, source) { > if (!condition) { > throw `Assertion failed for ${source}`; > } > } > // Basic compare > let exprs = [ > "1 == 1", true, > "1 != 1", false, > "1 != 2", true, > "1 > 2", false, > "1 >= 2", false, > "1 < 2", true, > "1 <= 2", true, > // Int <-> Float Coercion > "1.0 == 1", true, > "1 == 1.0", true, > "1.1 != 1", true, > "1.1 < 2", true, > // numbers and strings > "'1' == 1", true, > "'' == 0", true, // empty string is coerced to zero (ECMA compliance) > "1.0 >= '1'", true, > "1.0 > '1'", false > ];for (e = 0; e < exprs.length; e += 2) { > let stext = exprs[e]; > let expected = exprs[e + 1]; > assert(eval(stext) == expected, stext); > > } {code} > -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Updated] (JEXL-367) Deprecate -> and support =>
[ https://issues.apache.org/jira/browse/JEXL-367?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Hussachai Puripunpinyo updated JEXL-367: Description: The JEXL code surprisingly looks a lot like Javascript. I think this change is a good transition for folks to update the code, and it's pretty fine if they can tolerate using the deprecate syntax and don't mind seeing a warning log pop up every time. I'd like to propose supporting => and deprecate ->. The reasons are - JavaScript becomes very popular and many people are familiar with it. - JEXL is more like for a quick short script. In many scenarios, the target audiences are not a programer. They often mistake a language as a JavaScript (from my experience). - JEXL syntax already looks a lot like JavaScript -- var for variable declaration (Java added in Java 10, but JavaScript supports this from the beginning) -- The function keyword -- Implicit type coercion -- Ternary operator The proposed change. * Support => in addition to -> * Deprecate -> and show a warning log when it's used. was: The JEXL code surprisingly looks a lot like Javascript. I think this change is a good transition for folks to update the code, and it's pretty fine if they can tolerate using the deprecate syntax and don't mind seeing a warning log pop up every time. I'd like to propose supporting => and deprecate ->. The reasons are - JavaScript becomes very popular and many people are familiar with it. - JEXL is more like for a quick short script. In many scenarios, the target audiences are not a programer. They often mistake a language as a JavaScript (from my experience). - JEXL syntax already looks a lot like JavaScript - var for variable declaration (Java added in Java 10, but JavaScript supports this from the beginning) - The function keyword - Implicit type coercion - Ternary operator The proposed change. * Support => in addition to -> * Deprecate -> and show a warning log when it's used. > Deprecate -> and support => > --- > > Key: JEXL-367 > URL: https://issues.apache.org/jira/browse/JEXL-367 > Project: Commons JEXL > Issue Type: Wish >Reporter: Hussachai Puripunpinyo >Priority: Major > > The JEXL code surprisingly looks a lot like Javascript. I think this change > is a good transition for folks to update the code, and it's pretty fine if > they can tolerate using the deprecate syntax and don't mind seeing a warning > log pop up every time. > I'd like to propose supporting => and deprecate ->. > The reasons are > - JavaScript becomes very popular and many people are familiar with it. > - JEXL is more like for a quick short script. In many scenarios, the target > audiences are not a programer. They often mistake a language as a JavaScript > (from my experience). > - JEXL syntax already looks a lot like JavaScript > -- var for variable declaration (Java added in Java 10, but JavaScript > supports this from the beginning) > -- The function keyword > -- Implicit type coercion > -- Ternary operator > The proposed change. > * Support => in addition to -> > * Deprecate -> and show a warning log when it's used. -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Commented] (JEXL-366) Fail to evaluate string and number comparison
[ https://issues.apache.org/jira/browse/JEXL-366?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17528354#comment-17528354 ] Hussachai Puripunpinyo commented on JEXL-366: - Thank you Henri. Yes, I do have a workaround, and I don't need this change. I created this Jira and PR because I think it doesn't look right that '1' == 1 works fine while '1.0' == 1 will blow up. So I assume it's a bug, but let me know if that's intended. > Fail to evaluate string and number comparison > - > > Key: JEXL-366 > URL: https://issues.apache.org/jira/browse/JEXL-366 > Project: Commons JEXL > Issue Type: Improvement >Affects Versions: 3.2.1 >Reporter: Hussachai Puripunpinyo >Priority: Major > > The comparison logic doesn't cover the case when one operand is a string and > another operand is a numerable type (int, short, long,..). > The expected result for '1.0' == 1 should be true but it fails because the > string comparison check is after the numerable type check. JEXL tries to > parse '1.0' using toLong function and it fails with this error message `For > input string: "1.0"` > Moving a string comparison up before other number type checks will not cover > some corner cases such as > '1.00' == 1.0 // String comparison will yield false but it obviously doesn't > make sense. > The proposed change is to add the following code to handle the corner case > when one operand is string and another operand is numerable. To cover this > corner case, we can apply toBigDecimal to both *lhs* and *rhs* since it > should cover any arbitrary number in a string form, and it handles other > number types well. > {code:java} > if (isNumberable(left) || isNumberable(right)) { > if (left instanceof String || right instanceof String) { > final BigDecimal l = toBigDecimal(left); > final BigDecimal r = toBigDecimal(right); > return l.compareTo(r); > } else { > // this code block remains the same > } > return 0; > } {code} > JEXL syntax is very similar to ECMA script except a few small set that are > not the same. So, I think following the ECMA spec for this comparison check > makes sense. > The following code is JavaScript and it can be used in the JEXL test to make > sure that the behavior of comparison are the same. > Note that '1.0' == 1 yields true > {code:java} > function assert(condition, source) { > if (!condition) { > throw `Assertion failed for ${source}`; > } > } > // Basic compare > let exprs = [ > "1 == 1", true, > "1 != 1", false, > "1 != 2", true, > "1 > 2", false, > "1 >= 2", false, > "1 < 2", true, > "1 <= 2", true, > // Int <-> Float Coercion > "1.0 == 1", true, > "1 == 1.0", true, > "1.1 != 1", true, > "1.1 < 2", true, > // numbers and strings > "'1' == 1", true, > "'' == 0", true, // empty string is coerced to zero (ECMA compliance) > "1.0 >= '1'", true, > "1.0 > '1'", false > ];for (e = 0; e < exprs.length; e += 2) { > let stext = exprs[e]; > let expected = exprs[e + 1]; > assert(eval(stext) == expected, stext); > > } {code} > -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Created] (JEXL-367) Deprecate -> and support =>
Hussachai Puripunpinyo created JEXL-367: --- Summary: Deprecate -> and support => Key: JEXL-367 URL: https://issues.apache.org/jira/browse/JEXL-367 Project: Commons JEXL Issue Type: Wish Reporter: Hussachai Puripunpinyo The JEXL code surprisingly looks a lot like Javascript. I think this change is a good transition for folks to update the code, and it's pretty fine if they can tolerate using the deprecate syntax and don't mind seeing a warning log pop up every time. I'd like to propose supporting => and deprecate ->. The reasons are - JavaScript becomes very popular and many people are familiar with it. - JEXL is more like for a quick short script. In many scenarios, the target audiences are not a programer. They often mistake a language as a JavaScript (from my experience). - JEXL syntax already looks a lot like JavaScript - var for variable declaration (Java added in Java 10, but JavaScript supports this from the beginning) - The function keyword - Implicit type coercion - Ternary operator The proposed change. * Support => in addition to -> * Deprecate -> and show a warning log when it's used. -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Commented] (JEXL-342) Support for Java Optional.
[ https://issues.apache.org/jira/browse/JEXL-342?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17528307#comment-17528307 ] Hussachai Puripunpinyo commented on JEXL-342: - We forked JEXL at my company and I'd say JEXL code is very extensible. We support Java Optional and other native bindings for Scala and Kotlin including JSON types in the respective languages. We rarely touch the JEXL code to make sure that we can sync the upstream when we need to. (The only thing that is unavoidable like changing the visibility of the functions and classes so that we can override). We change the language so much until it doesn't look like JEXL :) Anyway, I still think this is a useful feature. What about having extra package and it can be in a separate jar? > Support for Java Optional. > -- > > Key: JEXL-342 > URL: https://issues.apache.org/jira/browse/JEXL-342 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Garret Wilson >Priority: Major > Fix For: Later > > > Does JEXL provide any native support for Java 8+ {{Optional<>}}? If not can > this this easily be added as some sort of plugin, or better yet can it be > added to the library? > h3. {{Optional}} Traversal > I need to create an API that works well for application developers as for > those using templates with JEXL expressions. Let's say that the {{Bar}} class > has a {{Bar.getName()}}. And the {{Foo}} class has this method: > {code:java} > Optional getBar(String barId); > {code} > In code getting the "test" foo-bar name would be like this: > {code:java} > String fooBarName=foo.getBar("test").map(Bar::getName).orElse(null); > {code} > I want the navigation across {{Optional<>}} to work just as if it were a > nullable variable. That is, I want the following JEXL expression to give the > same result as {{fooBarName}} above: > {code} > foo.bar("test").name > {code} > If {{Foo.getBar(String)}} returned a nullable rather than an {{Optional<>}}, > I think JEXL would work for this already. but the whole point of > {{Optional<>}} is that I keep nullables out of my code, so I don't want to > create inferior APIs inconsistent with the rest of my project just to work > with JEXL. > h3. {{Optional}} Getter Name > As icing on the cake, I would like to have {{Optional<>}} returning getter > discovery to recognize the {{findXXX}} pattern, as [Stephen Colebourne > suggested|https://blog.joda.org/2015/09/naming-optional-query-methods.html]. > I've been using this pattern for several years, and I really like it. Thus to > indicate that the {{Foo.getBar(String)}} "getter" doesn't return a nullable > but an {{Optional<>}}, I would name it {{Foo.findBar(String)}}, like this: > {code:java} > Optional findBar(String barId); > {code} > I would thus want the exact same JEXL expression above to still work: > {code} > foo.bar("test").name > {code} > Otherwise I'll have to forego use of modern Java constructs and make an > outdated style and less safe API just to get JEXL to work. -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Created] (JEXL-366) Fail to evaluate string and number comparison
Hussachai Puripunpinyo created JEXL-366: --- Summary: Fail to evaluate string and number comparison Key: JEXL-366 URL: https://issues.apache.org/jira/browse/JEXL-366 Project: Commons JEXL Issue Type: Bug Reporter: Hussachai Puripunpinyo The comparison logic doesn't cover the case when one operand is a string and another operand is a numerable type (int, short, long,..). The expected result for '1.0' == 1 should be true but it fails because the string comparison check is after the numerable type check. JEXL tries to parse '1.0' using toLong function and it fails with this error message `For input string: "1.0"` Moving a string comparison up before other number type checks will not cover some corner cases such as '1.00' == 1.0 // String comparison will yield false but it obviously doesn't make sense. The proposed change is to add the following code to handle the corner case when one operand is string and another operand is numerable. To cover this corner case, we can apply toBigDecimal to both *lhs* and *rhs* since it should cover any arbitrary number in a string form, and it handles other number types well. {code:java} if (isNumberable(left) || isNumberable(right)) { if (left instanceof String || right instanceof String) { final BigDecimal l = toBigDecimal(left); final BigDecimal r = toBigDecimal(right); return l.compareTo(r); } else { // this code block remains the same } return 0; } {code} JEXL syntax is very similar to ECMA script except a few small set that are not the same. So, I think following the ECMA spec for this comparison check makes sense. The following code is JavaScript and it can be used in the JEXL test to make sure that the behavior of comparison are the same. Note that '1.0' == 1 yields true {code:java} function assert(condition, source) { if (!condition) { throw `Assertion failed for ${source}`; } } // Basic compare let exprs = [ "1 == 1", true, "1 != 1", false, "1 != 2", true, "1 > 2", false, "1 >= 2", false, "1 < 2", true, "1 <= 2", true, // Int <-> Float Coercion "1.0 == 1", true, "1 == 1.0", true, "1.1 != 1", true, "1.1 < 2", true, // numbers and strings "'1' == 1", true, "'' == 0", true, // empty string is coerced to zero (ECMA compliance) "1.0 >= '1'", true, "1.0 > '1'", false ];for (e = 0; e < exprs.length; e += 2) { let stext = exprs[e]; let expected = exprs[e + 1]; assert(eval(stext) == expected, stext); } {code} -- This message was sent by Atlassian Jira (v8.20.7#820007)
[jira] [Commented] (JEXL-336) Escape some control characters
[ https://issues.apache.org/jira/browse/JEXL-336?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17356985#comment-17356985 ] Hussachai Puripunpinyo commented on JEXL-336: - I'm not using JXLT and didn't know that it's broken. Sorry and thank you :) > Escape some control characters > -- > > Key: JEXL-336 > URL: https://issues.apache.org/jira/browse/JEXL-336 > Project: Commons JEXL > Issue Type: Bug >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > Fix For: 3.2 > > > I found that JEXL doesn't honor the escape control characters such as \n, \t. > To reproduce this is simply evaluate this string "a\t\b" and it will yield > "a\t\b" instead of "a b". > The test code can explain this better. Note that I have to escape twice > because one is for Java and another one is for JEXL. > {code:java} > String[][] strings = new String[][] { > new String[] {"a\nb\tc", "'a\nb\tc'"}, // we still honor the actual > characters > new String[] {"a\nb\tc", "'a\\nb\\tc'"}, > new String[] {"a\nb\tc", "\"a\\nb\\tc\""}, > new String[] {"\b\t\n\f\r", "'\\b\\t\\n\\f\\r'"}, > new String[] {"'hi'", "'\\'hi\\''"}, > new String[] {"\"hi\"", "'\"hi\"'"}, > new String[] {"\"hi\"", "'\"hi\"'"}, > }; > for(String[] pair: strings) { > String output = StringParser.buildString(pair[1], true); > Assert.assertEquals(pair[0], output); > }{code} > This change doesn't cover all control characters because it won't be used. I > follow the [ES5 JavaScript spec|http://es5.github.io/x7.html#x7.8.4] for the > control characters that it supports except \v which Java itself doesn't > support. I don't think it's being used that much anyway. Supporting \v is > tricky. We can represent it with the unicode value (\u000B) but JEXL is Java > and doing that in Java is not possible. Developers have to put the unicode in > the String anyway when it's used in the host language. That's why \v is not > included in the list. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (JEXL-336) Escape some control characters
[ https://issues.apache.org/jira/browse/JEXL-336?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17224831#comment-17224831 ] Hussachai Puripunpinyo commented on JEXL-336: - Thank you [~henrib]. > Escape some control characters > -- > > Key: JEXL-336 > URL: https://issues.apache.org/jira/browse/JEXL-336 > Project: Commons JEXL > Issue Type: Bug >Reporter: Hussachai Puripunpinyo >Assignee: Henri Biestro >Priority: Major > > I found that JEXL doesn't honor the escape control characters such as \n, \t. > To reproduce this is simply evaluate this string "a\t\b" and it will yield > "a\t\b" instead of "a b". > The test code can explain this better. Note that I have to escape twice > because one is for Java and another one is for JEXL. > {code:java} > String[][] strings = new String[][] { > new String[] {"a\nb\tc", "'a\nb\tc'"}, // we still honor the actual > characters > new String[] {"a\nb\tc", "'a\\nb\\tc'"}, > new String[] {"a\nb\tc", "\"a\\nb\\tc\""}, > new String[] {"\b\t\n\f\r", "'\\b\\t\\n\\f\\r'"}, > new String[] {"'hi'", "'\\'hi\\''"}, > new String[] {"\"hi\"", "'\"hi\"'"}, > new String[] {"\"hi\"", "'\"hi\"'"}, > }; > for(String[] pair: strings) { > String output = StringParser.buildString(pair[1], true); > Assert.assertEquals(pair[0], output); > }{code} > This change doesn't cover all control characters because it won't be used. I > follow the [ES5 JavaScript spec|http://es5.github.io/x7.html#x7.8.4] for the > control characters that it supports except \v which Java itself doesn't > support. I don't think it's being used that much anyway. Supporting \v is > tricky. We can represent it with the unicode value (\u000B) but JEXL is Java > and doing that in Java is not possible. Developers have to put the unicode in > the String anyway when it's used in the host language. That's why \v is not > included in the list. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Updated] (JEXL-336) Escape some control characters
[ https://issues.apache.org/jira/browse/JEXL-336?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Hussachai Puripunpinyo updated JEXL-336: Description: I found that JEXL doesn't honor the escape control characters such as \n, \t. To reproduce this is simply evaluate this string "a\t\b" and it will yield "a\t\b" instead of "a b". The test code can explain this better. Note that I have to escape twice because one is for Java and another one is for JEXL. {code:java} String[][] strings = new String[][] { new String[] {"a\nb\tc", "'a\nb\tc'"}, // we still honor the actual characters new String[] {"a\nb\tc", "'a\\nb\\tc'"}, new String[] {"a\nb\tc", "\"a\\nb\\tc\""}, new String[] {"\b\t\n\f\r", "'\\b\\t\\n\\f\\r'"}, new String[] {"'hi'", "'\\'hi\\''"}, new String[] {"\"hi\"", "'\"hi\"'"}, new String[] {"\"hi\"", "'\"hi\"'"}, }; for(String[] pair: strings) { String output = StringParser.buildString(pair[1], true); Assert.assertEquals(pair[0], output); }{code} This change doesn't cover all control characters because it won't be used. I follow the [ES5 JavaScript spec|http://es5.github.io/x7.html#x7.8.4] for the control characters that it supports except \v which Java itself doesn't support. I don't think it's being used that much anyway. Supporting \v is tricky. We can represent it with the unicode value (\u000B) but JEXL is Java and doing that in Java is not possible. Developers have to put the unicode in the String anyway when it's used in the host language. That's why \v is not included in the list. was: I found that JEXL doesn't honor the escape control characters such as \n, \t. To reproduce this is simply evaluate this string "a\t\b" and it will yield "a\t\b" instead of "a b". The test code can explain this better. Note that I have to escape twice because one is for Java and another one is for JEXL. {code:java} String[][] strings = new String[][] { new String[] {"a\nb\tc", "'a\nb\tc'"}, // we still honor the actual characters new String[] {"a\nb\tc", "'a\\nb\\tc'"}, new String[] {"a\nb\tc", "\"a\\nb\\tc\""}, new String[] {"\b\t\n\f\r", "'\\b\\t\\n\\f\\r'"}, new String[] {"'hi'", "'\\'hi\\''"}, new String[] {"\"hi\"", "'\"hi\"'"}, new String[] {"\"hi\"", "'\"hi\"'"}, }; for(String[] pair: strings) { String output = StringParser.buildString(pair[1], true); Assert.assertEquals(pair[0], output); }{code} This change doesn't cover all control characters because it won't be used. I follow the [ES5 JavaScript spec|http://es5.github.io/x7.html#x7.8.4] for the control characters that it supports except \v which Java itself doesn't support. I don't think it's being used that much anyway. Supporting \v is tricky. We can represent it with the unicode value (\u000B) but JEXL is Java and doing that in Java is not possible. Developers have to put the unicode in the String anyway when it's used in the host language. That's why \v is not included in the list. I'm currently using the fork version of JEXL at my company since a lot of things cannot be made without modifying the JEXL code. I'd like to push some of my changes back to the upstream because I think it's useful to others and it will make my life easier when I have to merge the upstream to my fork. There will be more coming if the first one goes well :) > Escape some control characters > -- > > Key: JEXL-336 > URL: https://issues.apache.org/jira/browse/JEXL-336 > Project: Commons JEXL > Issue Type: Bug >Reporter: Hussachai Puripunpinyo >Priority: Major > > I found that JEXL doesn't honor the escape control characters such as \n, \t. > To reproduce this is simply evaluate this string "a\t\b" and it will yield > "a\t\b" instead of "a b". > The test code can explain this better. Note that I have to escape twice > because one is for Java and another one is for JEXL. > {code:java} > String[][] strings = new String[][] { > new String[] {"a\nb\tc", "'a\nb\tc'"}, // we still honor the actual > characters > new String[] {"a\nb\tc", "'a\\nb\\tc'"}, > new String[] {"a\nb\tc", "\"a\\nb\\tc\""}, > new String[] {"\b\t\n\f\r", "'\\b\\t\\n\\f\\r'"}, > new String[] {"'hi'", "'\\'hi\\''"}, > new String[] {"\"hi\"", "'\"hi\"'"}, > new String[] {"\"hi\"", "'\"hi\"'"}, > }; > for(String[] pair: strings) { > String output = StringParser.buildString(pair[1], true); > Assert.assertEquals(pair[0], output); > }{code} > This change doesn't cover all control characters because it won't be used. I > follow the [ES5 JavaScript spec|http://es5.github.io/x7.html#x7.8.4] for the > control characters that it supports except \v which Java itself doesn't > support. I don't think it's being used that much anyway. Supporting \v is > tricky. We can represent it with the
[jira] [Commented] (JEXL-336) Escape some control characters
[ https://issues.apache.org/jira/browse/JEXL-336?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17224224#comment-17224224 ] Hussachai Puripunpinyo commented on JEXL-336: - The PR: https://github.com/apache/commons-jexl/pull/32 > Escape some control characters > -- > > Key: JEXL-336 > URL: https://issues.apache.org/jira/browse/JEXL-336 > Project: Commons JEXL > Issue Type: Bug >Reporter: Hussachai Puripunpinyo >Priority: Major > > I found that JEXL doesn't honor the escape control characters such as \n, \t. > To reproduce this is simply evaluate this string "a\t\b" and it will yield > "a\t\b" instead of "a b". > The test code can explain this better. Note that I have to escape twice > because one is for Java and another one is for JEXL. > {code:java} > String[][] strings = new String[][] { > new String[] {"a\nb\tc", "'a\nb\tc'"}, // we still honor the actual > characters > new String[] {"a\nb\tc", "'a\\nb\\tc'"}, > new String[] {"a\nb\tc", "\"a\\nb\\tc\""}, > new String[] {"\b\t\n\f\r", "'\\b\\t\\n\\f\\r'"}, > new String[] {"'hi'", "'\\'hi\\''"}, > new String[] {"\"hi\"", "'\"hi\"'"}, > new String[] {"\"hi\"", "'\"hi\"'"}, > }; > for(String[] pair: strings) { > String output = StringParser.buildString(pair[1], true); > Assert.assertEquals(pair[0], output); > }{code} > This change doesn't cover all control characters because it won't be used. I > follow the [ES5 JavaScript spec|http://es5.github.io/x7.html#x7.8.4] for the > control characters that it supports except \v which Java itself doesn't > support. I don't think it's being used that much anyway. Supporting \v is > tricky. We can represent it with the unicode value (\u000B) but JEXL is Java > and doing that in Java is not possible. Developers have to put the unicode in > the String anyway when it's used in the host language. That's why \v is not > included in the list. > I'm currently using the fork version of JEXL at my company since a lot of > things cannot be made without modifying the JEXL code. I'd like to push some > of my changes back to the upstream because I think it's useful to others and > it will make my life easier when I have to merge the upstream to my fork. > There will be more coming if the first one goes well :) > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Created] (JEXL-336) Escape some control characters
Hussachai Puripunpinyo created JEXL-336: --- Summary: Escape some control characters Key: JEXL-336 URL: https://issues.apache.org/jira/browse/JEXL-336 Project: Commons JEXL Issue Type: Bug Reporter: Hussachai Puripunpinyo I found that JEXL doesn't honor the escape control characters such as \n, \t. To reproduce this is simply evaluate this string "a\t\b" and it will yield "a\t\b" instead of "a b". The test code can explain this better. Note that I have to escape twice because one is for Java and another one is for JEXL. {code:java} String[][] strings = new String[][] { new String[] {"a\nb\tc", "'a\nb\tc'"}, // we still honor the actual characters new String[] {"a\nb\tc", "'a\\nb\\tc'"}, new String[] {"a\nb\tc", "\"a\\nb\\tc\""}, new String[] {"\b\t\n\f\r", "'\\b\\t\\n\\f\\r'"}, new String[] {"'hi'", "'\\'hi\\''"}, new String[] {"\"hi\"", "'\"hi\"'"}, new String[] {"\"hi\"", "'\"hi\"'"}, }; for(String[] pair: strings) { String output = StringParser.buildString(pair[1], true); Assert.assertEquals(pair[0], output); }{code} This change doesn't cover all control characters because it won't be used. I follow the [ES5 JavaScript spec|http://es5.github.io/x7.html#x7.8.4] for the control characters that it supports except \v which Java itself doesn't support. I don't think it's being used that much anyway. Supporting \v is tricky. We can represent it with the unicode value (\u000B) but JEXL is Java and doing that in Java is not possible. Developers have to put the unicode in the String anyway when it's used in the host language. That's why \v is not included in the list. I'm currently using the fork version of JEXL at my company since a lot of things cannot be made without modifying the JEXL code. I'd like to push some of my changes back to the upstream because I think it's useful to others and it will make my life easier when I have to merge the upstream to my fork. There will be more coming if the first one goes well :) -- This message was sent by Atlassian Jira (v8.3.4#803005)