[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 19:46:00 CEST 2015
'is_email_address' is a special tuple which contains functions.
(is_email_address[0] returns is_string)
For help, it's a feature I've not implemented but it's easy to return the
help of each function, plus details as each function has an object
representing it's signature.
For traceback mangling, I don't see what is the problem.
When you call is_email_address(something) it pretty like if you've called:
def is_email_address(value):
is_string(value)
has_char('@', value)
has_user(value)
has_domain(value)
return value
2015-05-11 19:08 GMT+02:00 Douglas La Rocca <larocca at abiresearch.com>:
> Operator overloading (>>) has intuitive readability but in my experience
> it's better have functions remain "ordinary" functions, not class
> instances so you know what to expect regarding the type and so on. The
> other downside is that with (>>) only the functions you wrap can play
> together.
>
>
> Leaving aside the readability concern, the really major problem is that
> your tracebacks are so badly mangled. And if your implementation of
> the composition function uses recursion it gets even worse.
>
>
> You also lose the benefits of reflection/inspection--for example, with
> the code below, what happens if I call help ?? in ipython on `
> is_email_address`?
>
>
> ------------------------------
> *From:* Python-ideas <python-ideas-bounces+larocca=
> abiresearch.com at python.org> on behalf of Gregory Salvan <apieum at gmail.com>
> *Sent:* Monday, May 11, 2015 12:13 PM
> *To:* Guido van Rossum
> *Cc:* python-ideas at python.org
> *Subject:* Re: [Python-ideas] Partial operator (and 'third-party methods'
> and 'piping') [was Re: Function composition (was no subject)]
>
> 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/2634e3d4/attachment.html>
More information about the Python-ideas
mailing list