[ 
https://issues.apache.org/jira/browse/METRON-1277?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16223677#comment-16223677
 ] 

ASF GitHub Bot commented on METRON-1277:
----------------------------------------

Github user jjmeyer0 commented on the issue:

    https://github.com/apache/metron/pull/814
  
    Also, I don't think there is an issue with the map function directly. It's 
actually an issue with the logical_expression `var1` and using/not using a 
`default` branch. It seems like the stack isn't properly being managed. For 
example things are being pushed (eg. when a logical_expr is just `var1`) when 
they shouldn't and popped  when they shouldn't be (eg. when there is no 
default?). I haven't pin pointed it directly yet, but I hope this helps 
somewhat. Below are a few example tests that I have created. 
    
    ```java
    // Here there is a null on the stack
    @Test
    @SuppressWarnings("unchecked")
    public void test1FailsWithMoreOnStack() {
        Assert.assertEquals("a",  run("match{ foo : 'a' }",
                new HashMap() {{
                    put("foo", true);
                }}));
    }
    ```
    
    // Here it's an empty stack when we expect 'a' i believe.
    ```java
    @Test
    @SuppressWarnings("unchecked")
    public void test1FailsEmptyStack() {
        Assert.assertEquals("a",  run("match{ foo == true : 'a' }",
                new HashMap() {{
                    put("foo", true);
                }}));
    }
    ```
    
    ```java
    // This is *not* properly handled
    @Test
    @SuppressWarnings("unchecked")
    public void test1Passes() {
        Assert.assertEquals("a",  run("match{ foo : 'a', default: 'b' }",
                new HashMap() {{
                    put("foo", true);
                }}));
    }
    ```
    
    ```java
    // This is properly handled
    @Test
    @SuppressWarnings("unchecked")
    public void test1Passes() {
        Assert.assertEquals("a",  run("match{ foo == true : 'a', default: 'b' 
}",
                new HashMap() {{
                    put("foo", true);
                }}));
    }
    ```
    
    ```java
    // Example where map works
    @Test
    @SuppressWarnings("unchecked")
    public void workingMatchWithMap() {
       Assert.assertEquals(Arrays.asList("OK", "HAHA"),  run("match{ foo > 100 
: THROW('oops'), foo > 200 : THROW('oh no'), foo >= 50 : MAP(['ok', 'haha'], 
(a) -> TO_UPPER(a)), default: 'a' }",
              new HashMap() {{
                put("foo", 50);
              }}));
    }
    ```


> STELLAR Add Match functionality to language
> -------------------------------------------
>
>                 Key: METRON-1277
>                 URL: https://issues.apache.org/jira/browse/METRON-1277
>             Project: Metron
>          Issue Type: New Feature
>            Reporter: Otto Fowler
>            Assignee: Otto Fowler
>
> From dev list:
> ------------
> Hi All, 
> It's high time that Stellar supports some form of conditional that is 
> beyond if/then/else. Right now, the way to do fall-through conditionals is: 
> if x < 10 then 'info' else if x >= 10 && x <= 20 then 'warn' else 'critical' 
> That becomes non-scalable very quickly. I wanted to facilitate a 
> discussion with the community on the syntax. I'll give a few options and 
> you guys/gals can come up with your own suggestions too, but I wanted to 
> frame teh conversation. 
> *MAP-BASED SWITCH* 
> With the advent of METRON-1254 (https://github.com/apache/metron/pull/801), 
> we could enable (from a language perspective in Stellar) multi-part 
> conditionals or switch/case style statements. To wit: 
> MAP_GET(true, { x < 10 : 'info', x >= 10 && x <= 20 : 'warn', x > 20 : 
> 'critical' }) 
> Or, with a convenience function: 
> CASE( { x < 10 : 'info', x >= 10 && x <= 20 : 'warn', x > 20 : 'critical' } 
> ) 
> The issue with this is that the last true condition wins because we're 
> using a map. 
> *LIST-BASED SWITCH* 
> We could correct this by adding a list of pairs construction to stellar: 
> CASE( [ x < 10 : 'info', x <= 20 : 'warn'], 'critical') 
> This would enable us to allow the first true condition to win, so the 
> second condition can be simpler and we could pass a default return value as 
> the final argument. 
> The downside to this, is that it requires a language enhancement (the list 
> of pairs construction you see there). 
> *LAMBDA FUNCTION-BASED SWITCH* 
> Some of the problems with the previous statements are that every 
> conditional has to be evaluated and there is no opportunity to short 
> circuit. They're all evaluated at parse-time rather than execution time. 
> We could, instead, construct a lambda function approach to this and support 
> short-circuiting in even complex conditionals: 
> CASE( real_variable_name, [ x -> x < 10 ? 'info', x -> x <= 20 ? 'warn' ], 
> 'critical') 
> or 
> CASE( real_variable_name, [ x -> if x < 10 then 'info', x -> if x <= 20 
> then 'warn' ], 'critical') 
> This would require lessening ?: (if/then/else) syntax to support to enable 
> just if without else conditions. This also has the benefit of allowing 
> simplifying the expression due to lambda function variable renaming 
> (real_variable_name can be much more complex (or even an expression) than 
> 'x'. 
> Creative other approaches to this are appreciated! 
> Thanks, 
> Casey 
> ----------------
> and ->
>  
> How about this:
> match(VAR_TO_VAL_ASSIGNMENT+) { BOOLEAN_STATEMENT(VALS) : LAMBDA(VALS), 
> BOOLEAN_STATEMENT(VALS) : LAMBDA(VALS) , LAMBDA(VALS)}
> * match = new keyword
> * match takes variable number of assignments, where the val assigned to is 
> available in the evaluation and the lambdas
> * match {} contains comma separated list of a statement that evaluates to a 
> boolean and a lambda
> * LAMBDA is executed on match, and it’s value is returned
> * no matches returns null or return of optional final statement, which is a 
> LAMBDA without a BOOLEAN_STATEMENT



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to