thautwarm / MLStyle.jl

Julia functional programming infrastructures and metaprogramming facilities
https://thautwarm.github.io/MLStyle.jl/latest/
MIT License
404 stars 39 forks source link

UPW[WIP]: faster, lightweight, more flexible and concisely implemented pattern matching #83

Closed thautwarm closed 4 years ago

thautwarm commented 4 years ago
  1. generating more stably typed code, hence sometimes can be ~x2 faster than the the previous

    • [x] bottom-up type info propagation via tagless final
    • [ ] top-down propagation
  2. MLStyle as a dev-only dep

    • [x] generating quite readable and concise code
    • [ ] generating julia code requring no runtime support(any Expr to julia code library?)
  3. more intuitive pattern objects(top-level first-class patterns)

    • pattern_compile(::Type{P}, self::Function, type_params, type_args, args) pattern_uncall(::Type{P}, self::Function, type_params, type_args, args)

      Defining pattern_compile pattern_uncall for type P will control the code generation when P is used as a pattern.

      self is given by our compiler, and self(::Expr) will return a pattern.

      Within the following code, pattern syntax (a, b, c) will be equivalent to MyTuplePat(a, b, c).

      struct MyTuplePat end
      MLStyle.pattern_uncall(::Type{MyTuplePat}, self, _, _, args) =
          Expr(:tuple, args...) |> self
      
      @match (1, 2, 3) begin
          MyTuplePat(a, b, c) => a + c + b
          _ => error("anyway")
      end # => 6
    • is_enum

      In the following code, pattern S is equivalent to S():

      struct S end
      MLStyle.is_enum(::Type{S}) = true
      
      pattern_uncall(::Type{S}, self, _, _, _) =
          :(::$S) |> self
      
      @match S() begin
          S => 1
      end # => 1

    Above designs deprecate some redundant/non-intuitive things, e.g., MLStyle Extension List

  4. new features

    • [x] according to real world practice, things like @switch can be productive:
      @switch val begin
           @case pat1
                stmt1
                stmt2
           @case pat2
                ...
      end

Breakage&Deprecation

Before merging this, we shall make sure all of the downstream uses of MLStyle are concerned and well compatible. If not, workaround PRs should be created for fixing the corresponding issues.

Most stuffs can be compatible, except the following ones need attentions:

  1. the internal APIs def_pattern, def_app_pattern, etc., will be removed.
  2. scoping specifiers for data type definitions: @data public, @data internal, etc., will be deprecated as they now just do nothing. The new visibility is the same as julia scopes, i.e, an object implements pattern_compile is visible in current module, you can use it as a pattern when matching.
  3. defining view patterns(active patterns) doesn't need @active macro. Using @active to define view patterns will be deprecated, and note that the view patterns defined by @active cannot be statically generated, i.e., if you use @active, you cannot use MLStyle as a dev-only dependency.
thautwarm commented 4 years ago

add pattern_unref, which provides the capability to overload code generation for patterns like A[...]

thautwarm commented 4 years ago

uncomprehension patterns [pat for value in seq] => seq becomes orders of magnitude faster due to the better use of type information.

codecov[bot] commented 4 years ago

Codecov Report

Merging #83 into master will increase coverage by 7.00%. The diff coverage is 85.09%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #83      +/-   ##
==========================================
+ Coverage   78.57%   85.57%   +7.00%     
==========================================
  Files          20       31      +11     
  Lines         658     1442     +784     
==========================================
+ Hits          517     1234     +717     
- Misses        141      208      +67     
Impacted Files Coverage Δ
src/AbstractPatterns/Print.jl 0.00% <0.00%> (ø)
src/AbstractPatterns/structures/Print.jl 0.00% <0.00%> (ø)
src/MLStyle.jl 100.00% <ø> (ø)
src/MatchCore.jl 86.23% <ø> (ø)
src/Render.jl 3.12% <3.12%> (-68.75%) :arrow_down:
src/Extension.jl 50.00% <50.00%> (-32.36%) :arrow_down:
src/Sugars.jl 66.66% <66.66%> (ø)
src/AbstractPatterns/impl/BasicPatterns.jl 68.23% <68.23%> (ø)
src/AbstractPatterns/DataStructure.jl 70.00% <70.00%> (ø)
...c/AbstractPatterns/structures/TypeTagExtraction.jl 74.07% <74.07%> (ø)
... and 40 more

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 536566c...808804b. Read the comment docs.

thautwarm commented 4 years ago

I'd merge it to master to show the dev status.