JuliaServices / Match.jl

Advanced Pattern Matching for Julia
https://juliaservices.github.io/Match.jl/latest/
Other
240 stars 22 forks source link

@ismatch || only populates variables in both arguments #98

Closed Lincoln-Hannah closed 9 months ago

Lincoln-Hannah commented 10 months ago

variables not in both options are not populated

@ismatch [1,2] ( [1,A] || [1,B] )

`A` not defined
`B` not defined

I tried a solution. Though it matches both variables to the same value.

binding.jl line 298

    elseif is_expr(source, :(||), 2)
        # disjunction: `(a || b)` where `a` and `b` are patterns.
        subpattern1 = source.args[1]
        subpattern2 = source.args[2]

        #### As is, this assigns both :A and :B to the same variable - not sure how to change this ####
        bp1, assigned1 = bind_pattern!(location, subpattern1, input, binder, assigned)
        bp2, assigned2 = bind_pattern!(location, subpattern2, input, binder, assigned)

        # compute the common assignments.
        both = union(keys(assigned1), keys(assigned2))               #### change intersect to union
        assigned = ImmutableDict{Symbol, Symbol}()
        for key in both
            v1 = get( assigned1, key, missing )           ####  add missing default
            v2 = get( assigned2, key, missing )           ####  add missing default

           if ismissing(v2)                                         #### new case
                assigned = ImmutableDict{Symbol, Symbol}(assigned, key, v1)
           elseif ismissing(v1)                                     #### new case
                assigned = ImmutableDict{Symbol, Symbol}(assigned, key, v2)

            elsif v1 == v2

            #### same from here on
gafter commented 10 months ago

This is intentional behavior.

Your proposed solution would cause the code to treat missing input values differently from other values, in some cases incorrectly. The current implementation treats missing just like any other value.

Lincoln-Hannah commented 10 months ago

ok. So to populate all variables in the selected option I need to do something like this:

x= [1,2,3]

(  @ismatch x  [1,A,B]   ) ||
(  @ismatch x  [1,A]      )

which is fine. Just not quite as neat as

  @ismatch x  ( 
           [1,A,B]        ||
           [1,A]                
   )