Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternative extractor implementation #116

Merged
merged 38 commits into from
Nov 25, 2024
Merged

Alternative extractor implementation #116

merged 38 commits into from
Nov 25, 2024

Conversation

nystrom
Copy link
Collaborator

@nystrom nystrom commented Nov 14, 2024

This is an alternative implementation of extractors that uses Type rather than Val{<:Symbol} as in #114 for the dispatch. If the extract method is defined for the given type, the extractor pattern is used; otherwise, the struct pattern is used.

Fixes #92

Copy link

codecov bot commented Nov 14, 2024

Codecov Report

Attention: Patch coverage is 75.64103% with 19 lines in your changes missing coverage. Please review.

Project coverage is 98.29%. Comparing base (4cbd3fd) to head (8cd29d0).
Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
src/binding.jl 80.95% 12 Missing ⚠️
src/pretty.jl 0.00% 6 Missing ⚠️
src/Match.jl 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##              main     #116      +/-   ##
===========================================
- Coverage   100.00%   98.29%   -1.71%     
===========================================
  Files           12       12              
  Lines         1049     1113      +64     
===========================================
+ Hits          1049     1094      +45     
- Misses           0       19      +19     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

src/binding.jl Outdated Show resolved Hide resolved
src/binding.jl Outdated Show resolved Hide resolved
src/binding.jl Outdated Show resolved Hide resolved
src/pretty.jl Show resolved Hide resolved
src/binding.jl Outdated Show resolved Hide resolved
@nystrom nystrom requested a review from gafter November 18, 2024 14:54
@nystrom
Copy link
Collaborator Author

nystrom commented Nov 18, 2024

@gafter Sorry I forgot to mark the PR a draft, so you were reviewing a bit prematurely as I was working out the semantics. This new version uses the extractor function, if it exists (even if it fails), then uses the struct type. I think this is less prone to user error.

@gafter
Copy link
Member

gafter commented Nov 20, 2024

I love the idea of using the type instead of a token, for exactly the reason you mention. I will look at this (from scratch) today or tomorrow.

@gafter
Copy link
Member

gafter commented Nov 20, 2024

One thing occurs to me. Extractors in this version pay no attention to the arity of the pattern. So, for example, the following would fail

    AddExpr(_, _, _) => true

even though the struct type has three fields, because the extractor produces two values, not three.

Is this a problem? Should the extractor specify the arity of the tuple it will produce? If so, would that interfere with the use of named tuples?

@nystrom
Copy link
Collaborator Author

nystrom commented Nov 21, 2024

Right, one issue with extractors is that you lose all the nice error checking on the subpatterns. I was thinking you could pass in the expected arity to the extractor:

# called for pattern AddExpr(x, y)
function extract(::Type{AddExpr}, ::Val{2}, v)
   return (v.left, v.right,)
end

But, I didn't want to complicate things too much.

In the case of named arguments, you could pass in the desired field names (as Val):

# called for pattern AddExpr(left=x, right=y)
function extract(::Type{AddExpr}, ::Val{:left}, ::Val{::right}, v)
    return (; left = v.left, right = v.right)
end

I fear this is getting much too complicated, however.

@nystrom nystrom mentioned this pull request Nov 21, 2024
@nystrom
Copy link
Collaborator Author

nystrom commented Nov 21, 2024

@gafter I've implemented arity support.

@gafter
Copy link
Member

gafter commented Nov 21, 2024

My point about the named tuples is that if you have the function specify the arity, then we can handle things like Foo(1, 2, 3) nicely (using the type pattern because the user-specified pattern doesn't match the arity). However, if we extend type patterns to handle "keyword argument"-like things like Foo(1, 2; y=7), we can't easily extend this scheme to handle that very well (what is its arity? two? three? what should the function return?).

I'm probably overthinking this.

@nystrom
Copy link
Collaborator Author

nystrom commented Nov 21, 2024

I'm not sure how Foo(1, 2; y=7) works when Foo is just a struct. Would you look for a constructor?
I suppose you could make it equivalent to Foo(1,2) && Foo(y=7).

Copy link
Member

@gafter gafter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please bump the version number to 2.3.0 (in Project.toml) as this adds a feature.

src/Match.jl Outdated Show resolved Hide resolved
src/Match.jl Outdated Show resolved Hide resolved
src/binding.jl Outdated Show resolved Hide resolved
src/binding.jl Outdated Show resolved Hide resolved
src/binding.jl Outdated Show resolved Hide resolved
src/binding.jl Show resolved Hide resolved
src/bound_pattern.jl Outdated Show resolved Hide resolved
src/binding.jl Outdated Show resolved Hide resolved
@nystrom nystrom requested a review from gafter November 24, 2024 18:14
Copy link
Member

@gafter gafter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@gafter gafter merged commit 538097b into main Nov 25, 2024
7 checks passed
@gafter gafter deleted the nn-extract-type branch November 25, 2024 00:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support ML-style active patterns
2 participants