[Python-ideas] Partial operator (and 'third-party methods' and 'piping') [was Re: Function composition (was no subject)]
Gregory Salvan
apieum at gmail.com
Mon May 11 18:13:28 CEST 2015
I don't want to insist and I respect your point of view, I just want to
give a simplified real life example to show that function composition can
be less painful than another syntax.
When validating a lot of data you may want to reuse parts of already writen
validators. It can also be a mess to test complex data validation.
You can reduce this mess and reuse parts of your code by writing atomic
validators and compose them.
# sorry for using my own lib, but if I make no mistakes this code
functions, so...
import re
from lawvere import curry # curry is an arrow without type checking,
inherits composition, mutiple dispatch
user_match =
re.compile("^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*$").match
domain_match =
re.compile("^(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$").match
strict_user_match =
re.compile("^[a-z0-9][a-z0-9_-]+(?:\.[a-z0-9_-]+)*$").match
@curry
def is_string(value):
assert isinstance(value, str), '%s is not a string' %value
return value
@curry
def apply_until_char(func, char, value):
func(value[:value.index(char)])
return value
@curry
def apply_from_char(func, char, value):
func(value[value.index(char) + 1:])
return value
@curry
def has_char(char, value):
assert value.count(char) == 1
return value
@curry
def assert_ends_with(text, value):
assert value.endswith(text), '%s do not ends with %s' % (value, text)
return value
@curry
def assert_user(user):
assert user_match(user) is not None, '%s is not a valid user name' %
value
return user
@curry
def assert_strict_user(user):
assert strict_user_match(user) is not None, '%s is not a valid strict
user' % value
return user
@curry
def assert_domain(domain):
assert domain_match(domain) is not None, '%s is not a valid domain
name' % value
return domain
# currying (be made with partial)
has_user = apply_until_char(assert_user, '@')
has_strict_user = apply_until_char(assert_strict_user, '@')
has_domain = apply_from_char(assert_domain, '@')
# composition:
is_email_address = is_string >> has_char('@') >> has_user >> has_domain
is_strict_email_address = is_string >> has_char('@') >> has_strict_user >>
has_domain
# we just want org adresses ?
is_org_addess = is_email_address >> assert_ends_with('.org')
I found a lot of interest in this syntax, mainly for testing purpose,
readability and maintenability of code.
No matters if I'm a fish out of python waters. :)
2015-05-11 16:41 GMT+02:00 Guido van Rossum <guido at python.org>:
> As long as I'm "in charge" the chances of this (or anything like it) being
> accepted into Python are zero. I get a headache when I try to understand
> code that uses function composition, and I end up having to laboriously
> rewrite it using more traditional call notation before I move on to
> understanding what it actually does. Python is not Haskell, and perhaps
> more importantly, Python users are not like Haskel users. Either way, what
> may work out beautifully in Haskell will be like a fish out of water in
> Python.
>
> I understand that it's fun to try to sole this puzzle, but evolving Python
> is more than solving puzzles. Enjoy debating the puzzle, but in the end
> Python will survive without the solution.
>
> --
> --Guido van Rossum (python.org/~guido)
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150511/b49a50a3/attachment.html>
More information about the Python-ideas
mailing list