Skip to content

Alternative extractor implementation#116

Merged
gafter merged 38 commits into
mainfrom
nn-extract-type
Nov 25, 2024
Merged

Alternative extractor implementation#116
gafter merged 38 commits into
mainfrom
nn-extract-type

Conversation

@nystrom

@nystrom nystrom commented Nov 14, 2024

Copy link
Copy Markdown
Collaborator

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

@codecov

codecov Bot commented Nov 14, 2024

Copy link
Copy Markdown

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.

Comment thread src/binding.jl Outdated
Comment thread src/binding.jl Outdated
Comment thread src/binding.jl Outdated
Comment thread src/pretty.jl
Comment thread src/binding.jl Outdated
@nystrom
nystrom requested a review from gafter November 18, 2024 14:54
@nystrom

nystrom commented Nov 18, 2024

Copy link
Copy Markdown
Collaborator Author

@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

gafter commented Nov 20, 2024

Copy link
Copy Markdown
Member

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

gafter commented Nov 20, 2024

Copy link
Copy Markdown
Member

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

nystrom commented Nov 21, 2024

Copy link
Copy Markdown
Collaborator Author

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

nystrom commented Nov 21, 2024

Copy link
Copy Markdown
Collaborator Author

@gafter I've implemented arity support.

@gafter

gafter commented Nov 21, 2024

Copy link
Copy Markdown
Member

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

nystrom commented Nov 21, 2024

Copy link
Copy Markdown
Collaborator Author

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).

@gafter gafter left a comment

Copy link
Copy Markdown
Member

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.

Comment thread src/Match.jl Outdated
Comment thread src/Match.jl Outdated
Comment thread src/binding.jl Outdated
Comment thread src/binding.jl Outdated
Comment thread src/binding.jl Outdated
Comment thread src/binding.jl
Comment thread src/bound_pattern.jl Outdated
Comment thread src/binding.jl Outdated
@nystrom
nystrom requested a review from gafter November 24, 2024 18:14

@gafter gafter left a comment

Copy link
Copy Markdown
Member

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
@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