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

Add pattern matching to nim stdlib #17047

Closed
wants to merge 2 commits into from
Closed

Add pattern matching to nim stdlib #17047

wants to merge 2 commits into from

Conversation

haxscramper
Copy link
Contributor

@haxscramper haxscramper commented Feb 15, 2021

The whole idea behind nim-lang/RFCs#245 was that we have quite a number of pattern-matching libraries, and it would be a good idea to create a more or less standard implementation that would be bundled with nim by default, giving us pattern matching support in a language, by default, shipped with standard installation. But now, due to #16925 this is no longer the case, so I feel it is only logical to add matching to standard library directly.


From my perspective it is quite clear that if ecosystem has ~9 different libraries implementing partially overlapping features (and in case of gara/macroutils/nimtrs/patty/matsuri or definesugar/unpack/nimpylib(partially) - significantly overlapping) it is a sign that there is a demand for pattern matching.

In addition to consolidating syntax from 6+ different libraries (how many should we get until it becomes a real issue of choosing pattern matching library?) this RFC also provides support for rust-like if let, makes nim one step closer to being appealing for functional programmers, simplifies two very common use cases (writing macros and extracting/validating data from external sources), makes python-like sequence unpacking possible (there are two libraries for it already).

An increasing number of programming languages implement pattern matching support, and there is a big difference between something being implemented as a third-party module and being shipped with stdlib. Latter one is considered part of the language while the former is just "well, yeah, now I need to install the package manager, find out how to make it work, install the package itself etc."

Taken from this comment [almost] verbatim as nothing has changed in the ecosystem, so everything holds true still


Related

@haxscramper haxscramper marked this pull request as draft February 15, 2021 19:27
@haxscramper
Copy link
Contributor Author

haxscramper commented Feb 15, 2021

Converted to draft until syntax let expressions is finalized, will be used instead of current @capture syntax, for now I will continue working on fusion/matching.

@haxscramper
Copy link
Contributor Author

I've realized that current implementation can be improved in certain areas, and regardless whether we would get it into stdlib at some point, it would differ from this PR (since it also should make use of view types, "let expressions" etc.). Also, I'm much more inclined to support customCase or match syntax, instead of implicitly overloading case

@Araq
Copy link
Member

Araq commented Jul 22, 2021

Also, I'm much more inclined to support customCase or match syntax, instead of implicitly overloading case

Maybe implement it in the compiler directly then, I like case much moreso than customCase.

@haxscramper
Copy link
Contributor Author

haxscramper commented Jul 22, 2021

Why implement it directly in the compiler when it can clearly be done using a macro? I don't think "case looks better" is a valid justification. More - I can use keyword match if you like. Considering we are completely turning semantics of regular case this feels more than appropriate.

In addition to that - my close was prompted by a code example I made in discord. Someone asked whether nim can match AST in patterns directly, using @lhs + @rhs syntax instead of Infix[Ident(strVal: "+"), @lhs, @rhs]. I made an example macro for that, that simply compiled the pattern to the case statement. But I had to use name it matchAst, even though it could also be named case, because why not, since it looks better? And this will be a recurring problem - there can be only so much overloads for case (and not a lot of them would make sense - different keywords might be better suited), and implicit overloading that changes semantics of the built-in language construct is less than ideal, when we can just allow to indent of in compiler/parser.postExprBlocks and this would work.

macro withmatch(head: untyped): untyped =
  matchAst head:
    of @lhs + @rhs:
      echo "matched addition"

    of @lhs - @rhs:
      echo "matched substraction"

    of @head[@body]:
      echo "matched array access with one element"

    of @head[@head1, @head2]:
      echo "matched array access with two elements"

    of @call(@head), @call():
      echo "matched call with arguments"
      if head.isSome():
        echo "had one argument"

@Araq
Copy link
Member

Araq commented Jul 22, 2021

If it's builtin, it avoids the problem of

"In addition to consolidating syntax from 6+ different libraries (how many should we get until it becomes a real issue of choosing pattern matching library?)"

It seems you changed your mind completely on this topic. Which is not a bad thing, but then please be honest. ;-)

@haxscramper
Copy link
Contributor Author

haxscramper commented Jul 22, 2021

I don't follow how adding it as built-in compiler feature is considered consolidation while macro in stdlib isn't. I haven't changed my mind in the slightest, and I never said I want it as compiler built-in. Macro in the stdlib - yes, and preferably without relying on fragile and implicit overloading of case. I said it in the RFC for case renames (nim-lang/RFCs#332 (comment) "If those two are fixed, I would prefer customCase too, instead of caseStmtMacros"), I say the same thing now.

@haxscramper
Copy link
Contributor Author

I closed this PR because it think I've come up with much better design, so this +5k sloc does not make much sense anymore.

@haxscramper
Copy link
Contributor Author

The only part of my "honest" opinion that changed - it seems like fusion matching worked out just fine, at least for me, and while I would still prefer it to be a part of stdlib I personally don't care enough anymore to push for that if it would mean fighting with "let's make it compiler built-in instead".

@dom96
Copy link
Contributor

dom96 commented Jul 22, 2021

Maybe implement it in the compiler directly then, I like case much moreso than customCase.

I would say that match would be a good name. Overloading case is cool, but then how does someone not familiar with the language find info about this overloaded pattern matching? If you name the macro match you can easily find it's implementation at least.

@Araq
Copy link
Member

Araq commented Jul 22, 2021

if it would mean fighting with "let's make it compiler built-in instead".

It wouldn't mean that, it's just something I brought up.

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.

3 participants