<div dir="ltr"><div><div><div>Hi Steve,<br></div>I'll give it a shot and implement a proof-of-concept icontrac-macro library based on macropy and see if that works. I'll keep you posted.<br><br></div>Cheers,<br></div>Marko<br><div><div><br></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, 25 Sep 2018 at 12:08, Stephen J. Turnbull <<a href="mailto:turnbull.stephen.fw@u.tsukuba.ac.jp">turnbull.stephen.fw@u.tsukuba.ac.jp</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Marko Ristin-Kaufmann writes:<br>
<br>
> Thanks a lot for pointing us to macropy -- I was not aware of the library,<br>
> it looks very interesting!<br>
> <br>
> Do you have any experience how macropy fit<br>
<br>
Sorry, no. I was speaking as someone who is familiar with macros from<br>
Lisp but doesn't miss them in Python, and who also has been watching<br>
python-dev and python-ideas for about two decades now, so I've heard<br>
of things like MacroPy and know how the core developers think to a<br>
great extent.<br>
<br>
> I'm also a bit worried how macropy would work out in the libraries<br>
> published to pypi -- imagine if many people start using contracts.<br>
> Suddenly, all these libraries would not only depend on a contract library<br>
> but on a macro library as well.<br>
<br>
That's right.<br>
<br>
> Is that something we should care about?<br>
<br>
Yes. Most Pythonistas (at least at present) don't much like macros.<br>
They fear turning every program into its own domain-specific language.<br>
I can't claim much experience with dependency hell, but I think that's<br>
much less important from your point of view (see below).<br>
<br>
My point is mainly that, as you probably are becoming painfully aware,<br>
getting syntax changes into Python is a fairly drawnout process. For<br>
an example of the kind of presentation that motivates people to change<br>
their mind from the default state of "if it isn't in Python yet,<br>
YAGNI" to "yes, let's do *this* one", see<br>
<a href="https://www.python.org/dev/peps/pep-0572/#appendix-a-tim-peters-s-findings" rel="noreferrer" target="_blank">https://www.python.org/dev/peps/pep-0572/#appendix-a-tim-peters-s-findings</a><br>
<br>
Warning: Tim Peters is legendary, though still active occasionally.<br>
All he has to do is post to get people to take notice. But this<br>
Appendix is an example of why he gets that kind of R-E-S-P-E-C-T.[1]<br>
<br>
So the whole thing is a secret plot ;-) to present the most beautiful<br>
syntax possible in your PEP (which will *not* be about DbC, but rather<br>
about a small set of enabling syntax changes, hopefully a singleton),<br>
along with an extended example, or a representative sample, of usage.<br>
Because you have a working implementation using MacroPy (or the less<br>
pretty[2] but fewer dependencies version based on condition strings<br>
and eval) people can actually try it on their own code and (you hope,<br>
they don't :-) they find a nestful of bugs by using it.<br>
<br>
> Potential dependency hell? (I already have a bad feeling about<br>
> making icontract depend on asttokens and considerin-lining<br>
> asttokens into icontract particularly for that reason).<br>
<br>
I don't think so. First, inlining an existing library is almost<br>
always a bad idea. As for the main point, if the user sticks to one<br>
major revision, and only upgrades to compatible bugfixes in the<br>
Python+stdlib distribution, I don't see why two or three libraries<br>
would be a major issue for a feature that the developer/project uses<br>
extremely frequently. I've rarely experienced dependency hell, and in<br>
both cases it was web frameworks (Django and Zope, to be specific, and<br>
the dependencies involved were more or less internal to those<br>
frameworks). If you or people you trust have other experience, forget<br>
what I just said. :-)<br>
<br>
Of course it depends on the library, but as long as the library is<br>
pretty strict about backward compatibility, you can upgrade it and get<br>
new functionality for other callers in your code base (which are<br>
likely to appear, you know -- human beings cannot stand to leave a<br>
tool unused once they install it!)<br>
<br>
> > Note that this means *you cannot use macros in a file that is run<br>
> > directly*, as it will not be passed through the import hooks.<br>
><br>
> That would make contracts unusable in any stand-alone script,<br>
> right?<br>
<br>
Yes, but really, no:<br>
<br>
# The run.py described by the MacroPy docs assumes a script that<br>
# runs by just importing it. I don't have time to work out<br>
# whether that makes more sense. This idiom of importing just a<br>
# couple of libraries, and then invoking a function with a<br>
# conventional name such as "run" or "process" is quite common.<br>
# If you have docutils install, check out rstpep2html.py.<br>
<br>
import macropy.activate<br>
from my_contractful_library import main<br>
main()<br>
<br>
and away you go. 5 years from now that script will be a badge of<br>
honor among Pythonic DbCers, and you won't be willing to give it up!<br>
Just kidding, of course -- the ideal outcome is that the use case is<br>
sufficiently persuasive to justify a syntax change so you don't need<br>
MacroPy, or, perhaps some genius will come along and provide some<br>
obscure construct that is already legal syntax!<br>
<br>
HTH<br>
<br>
Footnotes: <br>
[1] R.I.P. Aretha!<br>
<br>
[2] Urk, I just realized there's another weakness to strings: you get<br>
no help on checking their syntax from the compiler. For a proof-of-<br>
concept that's OK, but if you end up using the DbC library in your<br>
codebase for a couple years while the needed syntax change gathers<br>
support, that would be really bad.<br>
<br>
</blockquote></div>