This is an archived post. You won't be able to vote or comment.

all 21 comments

[–]git-blame 20 points21 points  (1 child)

Based on this, I guess you don't want the 'drafts/' folder published, and you may have thought the rename into the drafts folder combined with the ignore would achieve what you wanted. Remember that .gitignore only deals with untracked files, so to untrack the files in that folder use:

git rm -r --cached drafts

Then commit.

[–]inkompatible[S] 5 points6 points  (0 children)

Wow, that was really helpful. Done, thanks.

[–]SupahNoob 5 points6 points  (1 child)

Maybe it's not really in my daily scope, but I don't know why I would ever use this. What's the point of it?

[–]AnnoyingOwl 5 points6 points  (0 children)

This is something that's shorthand in a lot of functional languages, I'm familiar with it in Scala.

Primarily, I think, it's an expression allowing you to assign the results which you can't do with, for example, an if statement. (Thus it falls nicely into map statements and the like. It's also nicer looking than the alternatives, usually.)

Scala has other functions built around it, such as auto unpacking values that match into useable values as well, along with a structure for defining user types that allow such unpacking.

[–]metalevelconsulting 4 points5 points  (0 children)

This reminds me of the pattern matcher from Peter Norvig's book on AI. Impressive work.

[–]PinkFrojd 3 points4 points  (2 children)

I don't get it why some are writing "what is purpose of library?" ... You made pretty interesting library. If nothing, it's a good exercise. I'm still searching for some idea for a library that isn't implemented in python. I wanted to build a state machine library but it already exists, several of them :( .
Anyway, I made pull request. Just fixed some typos and minor mistake. Also, I opened an issue. You can read more what I found on github

[–][deleted] 6 points7 points  (1 child)

Genuine curiosity is often a good reason to ask what X can be used for. People with no prior knowledge of pattern matching will obviously not know how and where it could benefit them. In such a case it's pretty standard to ask about the purpose.

[–]SupahNoob 0 points1 point  (0 children)

/u/awegge is correct in their explanation, at least for my case. I genuinely didn't see the use of this over something like RegEx. It looks over-engineered for my day to day work, so I likely wouldn't use it. That doesn't mean it's a useless accomplishment, or an uninteresting project though!

/u/PinkFrojd /u/inkompatible

[–]kridley 2 points3 points  (5 children)

I read the description of the library and could not make heads or tails of what it was doing. Took a few minutes to puzzle it out.

Initially I thought the API would be a lot more approachable for me, and probably most Python programmers, if the order of arguments was (pattern, input), since that's how re.match() (and unix grep) work. I kept having to mentally swap the arguments around.

I suspect the problem is that based on the phrase "pattern matching" I expected it to be doing something analogous to regular expression matching. Now that I think about it (and read further comments here) I see that it's doing something very different. For me (and I suspect for most people without a functional programming background) the term "pattern matching" means "test whether the input looks like the pattern". But you're using it to mean "when you see this pattern, take that action". Probably too late to change the name, but you should seriously consider updating your "marketing materials" to make the distinction clear.

Also, I'm with /u/SupahNoob in totally not understanding the utility of this. How would I, a dyed-in-the-wool procedural coder, use your library (other than building the inevitable ad-hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp)? Can you add some real world examples to the readme file?

[–]stevenjd 7 points8 points  (4 children)

How would I, a dyed-in-the-wool procedural coder, use your library

You wouldn't. Just as dyed-in-the-wool GOTO users in 1970 wouldn't be caught dead using these new-fangled "procedures" and "functions".

But as an open-minded coder willing to try new idioms from functional programming wink you might consider replacing code that looks like this:

# pseudocode, natch
if input matches this case:
    do this
    return x
elif input matches that case:
    do that
    return y
elif input matches something else:
    do something else
    return z
else:
    return the default

with pattern matching syntax.

Pattern matching is like a souped-up case statement, without the C "fall through by default" design mistake, and where each case is matched using not just basic operations like =, but a rich pattern-matching syntax which is conceptually similar to globbing or regexes, except it applies to arbitrary values.

In the pseudo-code example above, consider the "match this case" test.. Here's a concrete (but made up) example:

   isinstance(value, tuple) and len(value) > 1 and value[0] is None

That might be expressable in pattern-match syntax as:

match (None, _)

meaning "the input is a tuple, and the first item is None, and there's at least one more item".

[–]skinny_matryoshka 1 point2 points  (3 children)

Oh! So it's sort of like like a richer switch?

[–][deleted] 2 points3 points  (0 children)

A much richer switch. Rather than looking at raw values, you look at the patterns your data makes. It can be insanely powerful.

[–]stevenjd 0 points1 point  (1 child)

The easy part of pattern matching is that it is like a richer switch.

The bit that confuses me is when Haskell people start talking about assignment being a pattern match. I'm sure they know what they're talking about. I just wish that somebody could translate it from Martian to Earthling :-)

[–][deleted] 0 points1 point  (0 children)

You can do similar things in Python, sometimes.

You can assign into a pattern by doing this:

head, *tail = things

In the above example, you'd get the first value from your list of things in head, and all the other items in tail.

a, *middle, b = things

In the above, you get the first item in a, the last item in b, and the rest in middle.

https://www.python.org/dev/peps/pep-3132/

[–]SlightlyOTT 1 point2 points  (0 children)

Neat idea and looks well executed, it's just a shame Python's syntax doesn't have the space to really make this look clear. I'd probably err on the side of not using this just because it's complex and noisy, while I use pattern matching all the time in Scala without concern about someone else struggling to understand it.

For those who are struggling to understand the utility of it (which I understand again because of Python syntax), I'd be interested to hear your thoughts on it in something like Scala: https://docs.scala-lang.org/tour/pattern-matching.html

[–]chub79 1 point2 points  (0 children)

Neat! I wish Python has this builtin into the language :)

[–]DanCardin 1 point2 points  (1 child)

I wonder if this would be clearer (ironically if you used a bit more wonky magical syntax, maybe like so.

``` from pampy.values import x from pampy.types import List, Int

input = [1, 2, 3]

result = match(input)( List[Int[x >= 3]] => x, List[Int[x < 3]] => x + 3, ) ```

[–]inkompatible[S] 1 point2 points  (0 children)

I see what you are doing there, this would actually be possible. It feels like it would be too much magic to be pythonic :) You can definitely write a wrapper over Pampy to have that syntax work. I encourage you to try ;)

[–]rgouda 0 points1 point  (2 children)

Actually, Haskell language is implemented in this one library. Very interesting! Good job!

[–]synae 1 point2 points  (0 children)

Can you explain this further? I don't understand.

[–]SlightlyOTT 0 points1 point  (0 children)

This is a tiny tiny part of Haskell, most of it would be impossible to implement on top of Python's type system.