[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