Possibility to decorate single code line or code block?
Maybe it's a crazy idea, but what if we could decorate a single line of code? For example: @Timer a = time_consuming_function() This will be equivalent to using Steven's context manager, but the decorator is more simple to comment and uncomment. Maybe it could be possible to comment also code blocks: @parallel for x in y: do_something(x) now_something_completely_different(x) This could be a shortcut for multiprocessing.
Marco Sulla writes:
Maybe it's a crazy idea, but what if we could decorate a single line of code? For example:
@Timer a = time_consuming_function()
As syntax, I don't see the advantage over with ContextManagingTimer(): a = time_consuming_function() I don't understand the intended semantics. There's no there there to decorate. How do you propose to pick the sequence of bytecodes to decorate? What happens if the're not bytecodes and the machine code JIT optimizer (think common subexpression elimination) got hold of it before you decorated it?
This will be equivalent to using Steven's context manager, but the decorator is more simple to comment and uncomment.
To the extent that this abbreviated notation "does" something worth the needed mucking with decorator semantics, you're going to be doing it a lot, right? If so, why not tune your ContextManagingTimer to take a debug argument, store its results in a class attribute, etc, etc. Seems more straightforward to me.
Maybe it could be possible to comment also code blocks:
@parallel for x in y: do_something(x) now_something_completely_different(x)
If you can figure out what to decorate a simple statement, I don't see why you couldn't do it with a compound statement. However, Python has *suites* (loosely associated sequences of statements), not *blocks*. Why is that important? Well, suppose you want to identify the x in y that goes exponentially complex on you: for x in y: @ContextManagingTimer # creates a stack of results in Timer.out do_something(x); now_something_completely_different(x) but unfortunately we don't have blocks and semicolons don't work like that.
This could be a shortcut for multiprocessing.
I don't think there are any shortcuts for multiprocessing. ;-)
Hello, On Sat, 19 Dec 2020 03:52:46 +0100 Marco Sulla <Marco.Sulla.Python@gmail.com> wrote:
Maybe it's a crazy idea, but what if we could decorate a single line of code?
That's definitely useful, as a generic programming language concept. My favorite example is from (embedded) C, where I'd like to have per-callsite control of whether a function is inlines, or vice-versa, not inlined: (Using imaginary syntax which overloads C comments) /*#inline*/ foo() /*#noinline*/ foo() // Annotation is actually per-expression foo() + /*#inline*/bar() But I yet to see a compelling usecase for Python.
For example:
@Timer a = time_consuming_function()
Syntax-wise, I don't see any problems. As I mentioned in a recent mail, "@" here is effectively a prefix operator (unary in first approximation). But is that really compelling usecase? What if you want to time 2 statements?
This will be equivalent to using Steven's context manager, but the decorator is more simple to comment and uncomment.
Maybe it could be possible to comment also code blocks:
Definitely, if such a feature would be introduced, it would apply to any statement, whether simple or compound.
@parallel for x in y: do_something(x) now_something_completely_different(x)
This could be a shortcut for multiprocessing.
... Defining a semantics would be harder. Where @ operator applies now, it takes a "named suite" (class or function) and @deco NAMED_SUITE name is (roughly) equivalent to: NAMED_SUITE tmp name = deco(tmp) del tmp No specific semantics could be assigned to per-statement decorators, so the best idea is probably to treat such per-statement decorators as purely syntactic feature, a kind of macro. On AST level, it would produce something like ast.Decorated, to which statement(s) attached as children, so you would need to write an AST transformer, or just subclass bytecode compiler, to implement it. Bottom line: this should be doable, and should be doable easily enough by any interested party. [] -- Best regards, Paul mailto:pmiscml@gmail.com
Hello, On Sat, 19 Dec 2020 21:24:40 +0300 Paul Sokolovsky <pmiscml@gmail.com> wrote:
Hello,
On Sat, 19 Dec 2020 03:52:46 +0100 Marco Sulla <Marco.Sulla.Python@gmail.com> wrote:
Maybe it's a crazy idea, but what if we could decorate a single line of code?
[]
Bottom line: this should be doable, and should be doable easily enough by any interested party.
Just wanted to let know that poorman's version already works: $ cat example_stmt_deco.py import time class TimeIt: def __enter__(self): self.t = time.time() def __exit__(self, *args): delta = time.time() - self.t print("%ss" % delta) @TimeIt time.sleep(1) @TimeIt time.sleep(0.3); time.sleep(0.2) $ python3 -m imphook -i mod_stmt_deco -m example_stmt_deco 1.0011165142059326s 0.5011942386627197s -- Best regards, Paul mailto:pmiscml@gmail.com
Hi Paul I get a syntax error. The code won't even compile. I don't see how your code can avoid it. Are you sure your example works? $ python3.8 Python 3.8.0 (default, Oct 28 2019, 16:14:01) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information.
@TimeIt ... time.sleep(1) File "<stdin>", line 2 time.sleep(1) ^ SyntaxError: invalid syntax
By the way, I noticed that python 3.9 implements pep 614, but I don't see how that could allow your example to work. If I've made a stupid mistake, please be kind to me. -- Jonathan -- Jonathan
Jonathan, did you notice: python3 -m imphook -i mod_stmt_deco -m example_stmt_deco I suspect mod_stmt_deco is some code that Paul wrote. Guessing now, you can implement with with an import_hook, and I'm also guessing that that import hook translates: @TimeIt a_statement into something like: with TimeIt(): a_statement -CHB On Mon, Dec 21, 2020 at 12:24 PM Jonathan Fine <jfine2358@gmail.com> wrote:
Hi Paul
I get a syntax error. The code won't even compile. I don't see how your code can avoid it. Are you sure your example works?
$ python3.8 Python 3.8.0 (default, Oct 28 2019, 16:14:01) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information.
@TimeIt ... time.sleep(1) File "<stdin>", line 2 time.sleep(1) ^ SyntaxError: invalid syntax
By the way, I noticed that python 3.9 implements pep 614, but I don't see how that could allow your example to work.
If I've made a stupid mistake, please be kind to me.
-- Jonathan -- Jonathan
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/KFO2HB... Code of Conduct: http://python.org/psf/codeofconduct/
-- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
Hi Christopher I did notice the unusual command line, but didn't think any more of it. I thought everything I needed to look at was already in the message. A reference to https://pypi.org/project/importhook/ would have helped me. I don't see importhook providing a practical implementation of the original poster's request. Going back to that, I don't see why something like a = Timer(time_consuming_function)() shouldn't actually provide the semantics wanted for @Timer a = time_consuming_function() My preference is for code that's easier to read rather than quicker to type. It's said that easy reading is hard writing. https://quoteinvestigator.com/2014/11/05/hard-writing/ I'm also reminded of Einstein's (or is it?) Everything Should Be Made as Simple as Possible, But Not Simpler. https://quoteinvestigator.com/2011/05/13/einstein-simple/ -- Jonathan
On Mon, Dec 21, 2020 at 1:09 PM Jonathan Fine <jfine2358@gmail.com> wrote:
Going back to that, I don't see why something like a = Timer(time_consuming_function)() shouldn't actually provide the semantics wanted for @Timer a = time_consuming_function()
that was my first thought on this thread -- but it's not so simple. decorators work on functions (and classes) because they are special statements that both create an object and bind a name, so: @a_decorator def a_function(): ... is the same as: def a_function(): ... a_function = a_decorator(a_function). So we *could* have decoration syntax work for a certain subset of statements of the form: @a_decorator a_name = <something> would mean: a_name = <something> a_name = a_decorator(a_name) but that that would only work for simple assignments and I don't think it would work for the case at hand, as <something> would get evaluated before the reassignment. So I'm not sure what it *should* mean that would be useful. -CHB My preference is for code that's easier to read rather than quicker to
type. It's said that easy reading is hard writing. https://quoteinvestigator.com/2014/11/05/hard-writing/
I'm also reminded of Einstein's (or is it?) Everything Should Be Made as Simple as Possible, But Not Simpler. https://quoteinvestigator.com/2011/05/13/einstein-simple/
-- Jonathan
-- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
Hello, On Mon, 21 Dec 2020 12:43:39 -0800 Christopher Barker <pythonchb@gmail.com> wrote:
Jonathan, did you notice:
python3 -m imphook -i mod_stmt_deco -m example_stmt_deco
I suspect mod_stmt_deco is some code that Paul wrote.
Guessing now, you can implement with with an import_hook, and I'm also guessing that that import hook translates:
@TimeIt a_statement
into something like:
with TimeIt(): a_statement
Yes, that's it. It's all related to my earlier post on "dead simple import hooks" (which then can do transformations like that) https://mail.python.org/archives/list/python-ideas@python.org/thread/NIQQVA3... which in turn is related to the earlier discussion here https://mail.python.org/archives/list/python-ideas@python.org/thread/W2TMEUK... that anyone who has come up with a new syntactic/semantic idea for Python, should be easily enough able to implement it themselves (in pure Python), and be encouraged to do so. In this regard, I'm probing how my vision of implementation of that idea works with other people's ideas. As I mentioned, I don't consider statement-level annotations that useful (so far), but the point is that whoever has got such idea, should be able to try and play with it (and see in practice how useful it is). All that stuff is not ready for prime time yet, but as I mentioned that something works already here on the list, I now posted some early code also: https://github.com/pfalcon/python-imphook
-CHB
On Mon, Dec 21, 2020 at 12:24 PM Jonathan Fine <jfine2358@gmail.com> wrote:
Hi Paul
I get a syntax error. The code won't even compile. I don't see how your code can avoid it. Are you sure your example works?
$ python3.8 Python 3.8.0 (default, Oct 28 2019, 16:14:01) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information.
@TimeIt ... time.sleep(1) File "<stdin>", line 2 time.sleep(1) ^ SyntaxError: invalid syntax
By the way, I noticed that python 3.9 implements pep 614, but I don't see how that could allow your example to work.
If I've made a stupid mistake, please be kind to me.
-- Jonathan -- Jonathan
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/KFO2HB... Code of Conduct: http://python.org/psf/codeofconduct/
-- Christopher Barker, PhD
Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
-- Best regards, Paul mailto:pmiscml@gmail.com
Hello, On Sat, 19 Dec 2020 21:24:40 +0300 Paul Sokolovsky <pmiscml@gmail.com> wrote:
Hello,
On Sat, 19 Dec 2020 03:52:46 +0100 Marco Sulla <Marco.Sulla.Python@gmail.com> wrote:
Maybe it's a crazy idea, but what if we could decorate a single line of code?
For example:
@Timer a = time_consuming_function()
Syntax-wise, I don't see any problems. As I mentioned in a recent mail, "@" here is effectively a prefix operator (unary in first approximation).
But is that really compelling usecase? What if you want to time 2 statements?
Thinking about it more, that would require introducing some kind of "brackets" to delimit "decorated" statements, e.g.: @Timer{ foo bar @} And then it's just one step more to switch to brace-based alternative syntax altogether. Recent (of gazillion older) motion on that front: https://github.com/umlet/pwk [] -- Best regards, Paul mailto:pmiscml@gmail.com
participants (5)
-
Christopher Barker
-
Jonathan Fine
-
Marco Sulla
-
Paul Sokolovsky
-
Stephen J. Turnbull