Hi Chinmay,

Thank you for providing answers. Please see my comments in-line.

Thank you,

Vlad


On 1/18/16 01:00, Chinmay Kolhatkar wrote:
Hi Vlad,

Please find the answers inline.

Thanks,
Chinmay.


On Mon, Jan 18, 2016 at 1:26 AM, Vlad Rozov <[email protected]> wrote:

I have few concerns regarding the proposal, so my vote is -0 till they are
resolved

1. Usage of quasi-Java proprietary language. Even though most of the
syntax adheres to Java, usage of ${} invalidates ability to use general
IDEs to develop expressions. Debugging and verifying correctness of any
complex expression becomes a non trivial task for application developers.

    [CK] ${} is used so as to identify the operands and replace it when
correct variables/getter methods. Though, the interface is created in such
a way that one can override this. So top level interfaces are:
     Expression - Object of executable expression.
     ExpressionParser - One which parses expression.  Comcrete example is
JavaExpressionParser
     ExpressionEvaluator - One which converts parsed expression into an
executable expression. ExpressionParser goes as a plugin to
ExpressionEvaluator. Concrete impl is JavaExpressionEvaluator.

    Because of this interface one is free to override the parsing and
evaluation logic.
    Also JavaExpressionParser has a setter method using which one can
override the regex for ${}.
[VR] My concerns are mostly for concrete Expression language proposal - namely quasi-Java expression language as I did not have a chance to look into ExpressionParser/ExpressionEvaluator interface proposal.

Is it mandatory to have ${...} to identify the operands? I understand that in some cases it is necessary to provide hints to a parser, but in all your examples usage of ${...} seems to be unnecessary. For example it should be equally possible to parse input1.field1 and ${input1.field1}. In addition, if there is no need to support multiple POJOs, "input1" is not necessary as well.


2. What other languages were considered for expressions? Why quasi-Java was
selected in favor of for example SQL syntax?

   [CK] The aim of choosing quasi-Java language is to provide and complete
functionality as well as performance.
     As per the interface defined above, one can very well chose to override
the ExpressionParser and ExpressionEvalator to even have a SQL based
implementation for expression.
[VR] OK, let me rephrase the question. Why are we starting with quasi-Java language implementation and not with SQL like language?


3. Separating imports from expressions seems as inconvenience to
expression developers to me. Why imports can't be specified as part of
expression definition?

   [CK] The purpose of imports is to have some public static method to be
part of expression. For eg. java.util.Math.* is statically imported by
default. This gives expression writer a freedom to use the static methods
present in java.util.Math  out of the box in expression.
      One can very well chose to have imports in expression itself.
      For eg. Following is a valid expression and respective import in
expression will also be considered:

      import org.apache.x.y.z;
      <expression>
[VR] What was the selection criteria to include certain classes/packages into default import? Why for example org.apache.commons.lang3.StringUtils is included, but org.apache.commons.lang3.math.NumberUtils is not. Note that this is just an example and for any set of default imports somebody will always raise a question unless there is clear selection criteria.

4. Where multiple POJOs come from? If assumption is that different POJOs
come from different input ports, how tuples from different ports are
synchronized?

   [CK] Honestly, I don't have a usecase where multiple POJOs will become
part of a single expression. I've done this for a purpose of completion of
expression language. Of course, I would love to get some feedback from
community if there is a possible usecase for this.
[VR] OK, so I guess we don't need this functionality at least for now.


5. Are we supporting both POJOUtils and ExpressionEvaluator? If not, what
is the plan to deprecate POJOUtils? If yes, syntax of POJOUtils and
ExpressionEvaluator don't seem to be compatible.

   [CK] I haven't though about PojoUtils deprecation yet. In my opinion, it
should not be done. PojoUtils has its own purpose. It deals with POJOs and
simple operation which require faster interface to access variables from
POJO. If that is the usecase one should use PojoUtils. ExpressionEvaluator
is to support expression based execution.
    But I'm open to thoughts here.
    About incompatibility, we can make it compatible. Can you please share
where it is different? Is it the operand syntax you're talking about ${} of
Expression vs {}  of PojoUtils. I'll happy to make Expression to be
compatible with PojoUtils for the same.
[VR] PojoUtils provide similar functionality and I don't see much difference in a way how PojoUtils and ExpressionEvaluator may be used. They clearly have an overlapping use cases and overlapping functionality. IMO, it will be better to have the same syntax for both, or to be more precise extend PojoUtils to support not only getters and setters, but also expressions.

6. POJOUtils supports both getters and setters, what is the plan to support
setters in ExpressionEvaluator?

   [CK]  I'm not sure functionality of ExpressionEvalutor can be encompassed
within getter/setter. ExpressionEvaluator lets one execute a given
expression and provide a value returned by Expression.


Thank you,

Vlad

On 1/13/16 22:52, Chinmay Kolhatkar wrote:

Hi All,

I'm working on APEXCORE-1972 which adds support for a quasi-Java
Expression
Language and its expression evaluator.

All the detailed functionality and design details along with examples are
present in Jira.

I've summarized the ExpressionEvaluator feature & Expression language
below.

The pull request created for this at here:
https://github.com/apache/incubator-apex-malhar/pull/170

Please share your thought on this.

Thanks,
Chinmay.


*Summary of functionality of ExpressionEvaluator:*

     1. Support quasi-Java Expression which defines a single line
executable
     expression
     2. Support for quasi-Java expression based function code, which will
be
     compiled on the fly and made available for execution.
     3. Should support accessing multiple fields from multiples input POJOs
     while addressing the conversion of private variables to public getter
     method for all levels.
     4. Should support nested field support
     5. quasi-Java expressions should support operands to be mentioned in
     following ways:
        - ${input.fieldName}
           - Access fieldName via a object name.
        - ${fieldName}
           - Accessing fieldName directly when a single object is
registered
           for operation.
        - ${input}
           - Accessing object variable directly
        - ${input.fieldName.internalField}
           - Accessing nested fields
        6. There should be some predefined function provided to expression
     writer which one can directly use in expression for invoking certain
     functionality.
     7. These are simple String based, Date time based etc functions.
     8. On-need-basic one should be able to easily update Expression
     Evaluator to easily add new predefined functions to be made available
for
     expression writer.
     9. User of ExpressionEvaluator should be able to add a custom method
     externally to be made available to in expression.
     10. Though operands are defined, placeholder for the operand in
     expression should be allowed to be overridden. By default, expression
     language should support bash type syntax for operand - {…}
     11. The library should not introduce any serialization related issues.
     12. All the java operators should be supported.

​

*The examples of quasi-Java Expression:*

     - ${inp.field1}
        - Will return value of field1 from registered input POJO.
     - ${inp.field1} + ${inp.field2}
        - Will return sum of field1 & field2 from given POJO
     - ${field1} + ${field2}
        - Equivalent to above
     - ${inpA.field1} > ${inpA.field2} ? ${inpA.field3} : ${inpB.field3}
        - Executes ternary expression and returns value accordingly. Works
on
        2 POJOs. inpA & inpB are two placeholder registered for given POJO
with
        ExpressionEvaluator library.
     - pow(${inpA.field1}, ${inpB.field2})
        - Executes pow function coming from java.lang.Math library. This
and
        other with lot other basic functions is available to expression
writer out
        of the box to use in expression.
     - ${inpA.field1} > 0 ? ${inpB.innerPOJO.field3} :
     ${inpA.innerPOJO.field3}
        - Shows how nested POJOs can be accessed in expression. The
variables
        will evaluate to correct public getter method is required.
     - ${inp.firstname} + “ “ + ${inp.lastname}
        - Generate the full name as per given expression from firstname and
        lastname field.
     - long retVal=1; for (int i=0; ${inpF.value1}; i++) {retVal = retVal *
     ${inpF.value1}; } return retVal;
        - This tells a complete method content to ExpressionEvaluator. The
        library create an executable and compiled method using this
expression.

​



Reply via email to