All Projects → Xython → pattern-matching

Xython / pattern-matching

Licence: MIT license
full-featured pattern-matching in python, however it's more likely to be dynamic contracts.

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to pattern-matching

Trivia
Pattern Matcher Compatible with Optima
Stars: ✭ 210 (+1066.67%)
Mutual labels:  pattern-matching
extractacy
Spacy pipeline object for extracting values that correspond to a named entity (e.g., birth dates, account numbers, laboratory results)
Stars: ✭ 47 (+161.11%)
Mutual labels:  pattern-matching
simplematch
Minimal, super readable string pattern matching for python.
Stars: ✭ 147 (+716.67%)
Mutual labels:  pattern-matching
Mlstyle.jl
Julia functional programming infrastructures and metaprogramming facilities
Stars: ✭ 223 (+1138.89%)
Mutual labels:  pattern-matching
csharp-workshop
NDC London 2019, Workshop: Become a better C# programmer: more Value, more Expressions, no Waiting
Stars: ✭ 21 (+16.67%)
Mutual labels:  pattern-matching
grime
A language for matching two-dimensional patterns, based on Boolean grammars.
Stars: ✭ 13 (-27.78%)
Mutual labels:  pattern-matching
Hexraystoolbox
Hexrays Toolbox - Find code patterns within the Hexrays AST
Stars: ✭ 202 (+1022.22%)
Mutual labels:  pattern-matching
montre
The original timed regular expression matcher over temporal behaviors
Stars: ✭ 14 (-22.22%)
Mutual labels:  pattern-matching
match
Pattern-Matching written by Dan Friedman, Erik Hilsdale and Kent Dybvig
Stars: ✭ 20 (+11.11%)
Mutual labels:  pattern-matching
asteroid
Asteroid is a modern, multi-paradigm programming language that supports first-class patterns.
Stars: ✭ 29 (+61.11%)
Mutual labels:  pattern-matching
Actor Framework
An Open Source Implementation of the Actor Model in C++
Stars: ✭ 2,637 (+14550%)
Mutual labels:  pattern-matching
dheater
D(HE)ater is a proof of concept implementation of the D(HE)at attack (CVE-2002-20001) through which denial-of-service can be performed by enforcing the Diffie-Hellman key exchange.
Stars: ✭ 142 (+688.89%)
Mutual labels:  overloading
chemin
🥾 A type-safe pattern builder & route matching library written in TypeScript
Stars: ✭ 37 (+105.56%)
Mutual labels:  pattern-matching
Patty
A pattern matching library for Nim
Stars: ✭ 214 (+1088.89%)
Mutual labels:  pattern-matching
sweet-egison
Haskell library for non-deterministic pattern matching
Stars: ✭ 15 (-16.67%)
Mutual labels:  pattern-matching
Zeallot
Variable assignment with zeal! (or multiple, unpacking, and destructuring assignment in R)
Stars: ✭ 204 (+1033.33%)
Mutual labels:  pattern-matching
when-switch
JavaScript functional implementation of switch/case
Stars: ✭ 20 (+11.11%)
Mutual labels:  pattern-matching
pmatch
Pattern matching DSL for R
Stars: ✭ 21 (+16.67%)
Mutual labels:  pattern-matching
egison-haskell
Template Haskell Implementation of Egison Pattern Matching
Stars: ✭ 31 (+72.22%)
Mutual labels:  pattern-matching
regexm
A Rust macro for writing regex pattern matching.
Stars: ✭ 46 (+155.56%)
Mutual labels:  pattern-matching

License PyPI version

Tail call optimization(TCO) has been removed from this package for following reasons:

  1. TCO is easy to implement.
  2. Guaranteeing TCO dynamically in any situations is really expensive.

If you do want to use TCO in Python, check https://zhuanlan.zhihu.com/p/42684997.

The documents have been migrated to README now:

Docs

These are all you need to import.

from pattern_matching import var, _, T, t, when, Match, overwrite

Type Matching

@when(var[T == int])
# T means the type would be capture.
def f(v, type_of_v):
    print(v, type_of_v)

f(1)
# => (1, int)

Remark: Using Match is similar to when/overwrite:

m = Match(1)
res = m.case(var[T == int])
if res:
    [a, b] = res.get
    assert [a, b] == [1, int]

If the pattern matched, Match.case returns a Result object.

class Result:
    __slots__ = 'get'

    def __init__(self, _):
        self.get = _

Otherwise the return is None.

Value Matching

@when(_ == 1)
def f():
    return 12

@when(_ == 2)
def f():
    return 0

@when(var)
def f(arg):
    return arg ** 3

f(1), f(2), f(3) # => 12, 0, 27

Wildcard for types

@when(var[t == float])
# the lowercase, "t", which indicates that the type just be matched without capture.
def f(v):
    print(v)
f(1.0)
# => 1.0

Wildcard for values

@when(_)
def f():
    return 1
f(1) == f("...") == f(1e-3)
# => True

Type Boundary

class MyList(list):
    pass
from collections import Iterable

@when(var[Iterable <= T <= MyList]
    .when(lambda x: 1 in x)
)
def f(x, T):
    return (x, T)

f([1, 2, 3])
# => ([1, 2, 3], list)

f({1, 2, 3})
# => UnsolvedCase: No entry for args<({1, 2, 3},)>, kwargs:<{}>

Overloading functions

Overloading functions are introduced through the following simple cases:

@overwrite(_ == [])
def summary():
    return 0

@when([var[int], *(_== [])])
def summary(head):
    return head

@when([var[int], *var[list]])
def summary(head, tail):
    return head + summary(tail)

summary([1, 2, 3])
# => 6

Note that above code is definitely useless for it doesn't use tail call optimization.

Union Type

@when(var[(t == int) | (t == str)])
def disp(x):
    print(x)
disp(1) # => 1
disp('1') # => '1'

Intersection Type

class A:
    pass
class B:
    pass
class C(A, B):
    pass

@when(_[(T == A) | (T == B)])
def disp(ty):
    print(ty)
disp(C()) # => <class __main__.C>

Difference Type

class A:
    pass
class B:
    pass
class C(A, B):
    pass

@when(_[T != A])
def disp(ty):
    print(ty)
disp(C()) # => <class __main__.C>
disp(B()) # => <class __main__.B>

disp(A())
# => UnsolvedCase: No entry for args<(<__main__.A object at ...>,)>, kwargs:<{}>

Type Contracts

You can apply .when(predicate) methods on pattern_matching.T/t .

For instance, to avoid subclassing, follow this:

class A:
    pass
class B:
    pass
class C(A, B):
    pass

@overwrite(_[T.when(lambda _: not issubclass(_, A))])
def disp(ty):
    print(ty)
disp(C()) # => <class __main__.C>
# => UnsolvedCase: No entry for args<(<__main__.C object at ...>,)>, kwargs:<{}>

Match Argument Numbers

@when(var/2)
def f(g):
    return g(1, 2)

f(lambda a, b: a + b) # => 3
f(lambda a, b, c: a + b)
# => UnsolvedCase: No entry for args<(<function <lambda> at ...>,)>, kwargs:<{}>

class F:
    def apply(self, arg):
        return arg + 1

@when(var/1)
def f2(g):
    return g(1)


f2(lambda a, b: a + b)
# => UnsolvedCase: No entry for args<(<function <lambda> at ...>,)>, kwargs:<{}>
f2(F().apply) # => 2
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].