Eike Welk wrote:
Instead of a specification in BNF, here is a function written with the proposed pattern matching syntax.
My BNF is weak -- thanks for the code!
Proposed Syntax ---------------
def foo(x): match x with | 1 -> # Equality print("x is equal to 1") | a:int -> # Type check print("x has type int: %s" % a) | (a, b) -> # Tuple unpacking print("x is a tuple with length 2: (%s, %s)" % (a, b)) | {| a, b |} -> # Attribute existence and access print("x is an object with attributes 'a' and 'b'.") print("a=%s, b=%s" % (a, b))
# Additional condition | (a, b, c) with a > b -> print("x is a tuple with length 3: (%s, %s, %s)" % (a, b, c)) print("The first element is greater than the second element.")
# Complex case | {| c:int, d=1 |}:Foo -> print("x has type Foo") print("x is an object with attributes 'c' and 'd'.") print("'c' has type 'int', 'd' is equal to 1.") print("c=%s, d=%s" % (c, d))
# Default case | _ -> print("x can be anything")
I am unfamiliar with OCAML -- if x can match more than one condition, will it match all possible, or just the first one? If just the first one, the python code below can be simplified by ditching the while loop, removing the breaks, and using elif and else. def foo(x): # Equality if x == 1: print("x is equal to 1") # Type check elif isinstance(x, int): a = x print("x is an integer: %s" % a) # Tuple unpacking elif isinstance(x, tuple) and len(x) == 2: a, b = x print("x is a tuple with length 2: (%s, %s)" % (a, b)) # Attribute existence testing and access elif hasattr(x, "a") and hasattr(x, "b"): a, b = x.a, x.b print("x is an object with attributes 'a' and 'b'.") print("a=%s, b=%s" % (a, b)) # Additional condition elif isinstance(x, tuple) and len(x) == 3: a, b, c = x if a > b : print("x is a tuple with length 3: (%s, %s, %s)" % (a, b, c)) print("The first element is greater than the second " "element.") # Complex case elif isinstance(x, Foo) and hasattr(x, "c") and hasattr(x, "d"): c, d = x.c, x.d if isinstance(c, int) and d == 1: print("x has type Foo") print("x is an object with attributes 'c' and 'd'.") print("'c' has type 'int', 'd' is equal to 1.") print("c=%s, d=%s" % (c, d)) # Default case else: print("x can be anything") One of the things I like about Python is it's readability. While the OCAML inspired version is much more concise, I don't see it as significantly easier to read -- and at this point I don't see any place where I would make use of it myself. Here's a bit of code that might be convertable: result = [] for i, piece in enumerate(pieces): if '-' in piece: piece = piece.replace('-',' ') piece = '-'.join(NameCase(piece).split()) elif alpha_num(piece) in ('i', 'ii', 'iii', 'iv', 'v', 'vi', \ 'vii', 'viii', 'ix', 'x', 'pc', 'llc') \ or piece.upper() in job_titles \ or i and piece.upper() in deg_suffixi: piece = piece.upper() elif piece in ('and', 'de', 'del', 'der', 'el', 'la', 'van', ): pass elif piece[:2] == 'mc': piece = 'Mc' + piece[2:].title() else: possible = mixed_case_names.get(piece, None) if possible is not None: piece = possible else: piece = piece.title() if piece[-2:].startswith("'"): piece = piece[:-1] + piece[-1].lower() result.append(piece) Ugly, I know -- but the question is: how would 'match' handle things like '-' in piece piece.upper() in .... piece in (....) piece[:2] = 'mc' in other words, would match save me much in this circumstance, and would it be easier to read? -1 ~Ethan~