tag:blogger.com,1999:blog-18508356.post4718691580616017838..comments2023-05-21T09:53:50.042-04:00Comments on Just a little Python: Python Macros?Rick Copelandhttp://www.blogger.com/profile/11612114223288841087noreply@blogger.comBlogger22125tag:blogger.com,1999:blog-18508356.post-25742128308363382042012-10-28T00:20:41.829-04:002012-10-28T00:20:41.829-04:00Macros are for extending your compiler. I can imp...Macros are for extending your compiler. I can implement a syntax transformation that can drastically change the semantics of a certain piece of code, without having to actually go in and hack the compiler to support the new feature in question.<br /><br />For example, I hacked together a simple tail-recursion macro today just for the hell of it. <br /><br />https://gist.github.com/3967055<br /><br />Obviously pointless and just for fun, but I know of few languages that could support something like this without a new version number.<br />Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-18508356.post-45418683463856327762012-02-22T10:54:22.482-05:002012-02-22T10:54:22.482-05:00I've kind of abandoned this project (it's ...I've kind of abandoned this project (it's still available at http://code.google.com/p/metapython/ if anyone's interested in looking at/picking it up). For something like ifelse, recent versions of python gave you the ternary expression:<br /><br />t if cond else f<br /><br />which is marginally more readable (and more semantically correct) than the old <br /><br />cond and t or f<br /><br />Anyway, that's my $.02 worth.Rick Copelandhttps://www.blogger.com/profile/11612114223288841087noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-47867117505711476542012-02-21T21:48:24.885-05:002012-02-21T21:48:24.885-05:00I found this post because I wanted to implement fu...I found this post because I wanted to implement functional conditions so that I could use them in a lambda statement, because<br /><br />ifelse(cond, t, f)<br /><br />reads easier than<br /><br />cond and t or f<br /><br />People dont usually expect they will be used like that.<br /><br />The problem is that defining them as functions cause both t and f to be evaluated before the condition. All the arguments are executed, and the return values passed into the conditional function, where the cond is then used in an if, and the appropriate return is returned.<br /><br />Because of this, I realised that I wanted to use a macro to declare the function, using the and or trick.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-18508356.post-38609677164347707232010-07-01T08:20:24.920-04:002010-07-01T08:20:24.920-04:00I want to replace for with a parallel_for that doe...I want to replace for with a parallel_for that does something else with the block underneath the for. In order to do that with "with" I need to bracket the "for" with "withs"<br /><br />with parallel_sync():<br /> for i in range(0,4):<br /> with parallel_split():<br /> ...closure that will have each<br /> instance of the "for" run in<br /> ...parallel<br /><br />This is the only way I can know, <br />1)each time I enter and leave an individual loop of the for block<br />2)when I leave the entire for blockD Minorhttps://www.blogger.com/profile/12466427440382934673noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-28643814928186638212010-04-17T17:15:53.444-04:002010-04-17T17:15:53.444-04:00decent for macro'ed with a whiledecent for macro'ed with a whileAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-18508356.post-81056231543268433642010-03-13T17:36:17.998-05:002010-03-13T17:36:17.998-05:00http://www.cs.brown.edu/~sk/Publications/Talks/Swi...http://www.cs.brown.edu/~sk/Publications/Talks/SwineBeforePerl/<br /><br />Watch the presentation and the slides about implementing a Finite Automata using Scheme Macros.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-18508356.post-54428581679039851812009-11-18T09:50:50.911-05:002009-11-18T09:50:50.911-05:00@jeremy:
The way this is typically done in python...@jeremy:<br /><br />The way this is typically done in python is to write an assertion function (this is how the unittest module does it):<br /><br />assert_raises(ExceptionType, func, *args, **kwargs)<br /><br />where the assert_raises function is something like:<br /><br />def assert_raises(t, func, *args, **kwargs):<br /> try:<br /> func(*args, **kwargs)<br /> assert False, '%s not raised' % t<br /> except t:<br /> return<br /> except:<br /> raise<br /><br />But I can definitely see how macros could be useful, as well.Unknownhttps://www.blogger.com/profile/13530919414953298102noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-90163871207861772632009-11-17T23:57:13.523-05:002009-11-17T23:57:13.523-05:00I'm just starting Python, and I already found ...I'm just starting Python, and I already found a good use case for Macros.<br /><br />I want to run a test which is expected to raise an exception and write it like this:<br /><br />test-exn("exception content", func(args));<br /><br />Namely, I want this to expand to a try/catch statement without having to write the try/catch, and without having to write a class to encapsulate unit tests. These are for small scripts, but they're large enough that I want to have a small bit of regression testing. Perhaps I'm writing a miniature interpreter...<br /><br />Lisp macros can (and do) do this.j2kunhttps://www.blogger.com/profile/08041921049916424212noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-57619474837254144462009-11-07T18:16:37.322-05:002009-11-07T18:16:37.322-05:00...and now I see MetaPython... nice work! Don......and now I see MetaPython... nice work! Don't know if it's enough to keep me in Python-land for the long-term, but definitely cool.Cliff Wellshttps://www.blogger.com/profile/06819587790275503111noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-67237110088640234032009-11-06T18:23:58.251-05:002009-11-06T18:23:58.251-05:00The point of macros is that you can extend the lan...The point of macros is that you can extend the language without cooperation from the core developers. Consider the new Python "with" statement. If Python had macros, not only could this have been implemented outside the core (rather than waiting for a committee to debate it for months), it could easily be backported to older versions of Python. <br /><br />Python has such a rich array of features precisely because it must. Since it's impossible to extend the language in any significant sense, it must implement every useful feature it can. Some of us think of this as "bloat".Cliff Wellshttps://www.blogger.com/profile/06819587790275503111noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-8242411476265628202009-03-16T16:55:00.000-04:002009-03-16T16:55:00.000-04:00@Scott: I suppose I can see using macros to differ...@Scott: I suppose I can see using macros to differentiate between debug and optimized code, although it looks like you have a passable workaround with simple Python conditionals. It seems that a macro facility would probably make your "massive code project" code look cleaner (i.e. without the conditionals).<BR/><BR/>Between that example and collections.namedtuple, I'm just about convinced that macros could add something to Python. After reading the comments here, however, I am also convinced that Python needs them a lot less than a minimalist language like Lisp.Rick Copelandhttps://www.blogger.com/profile/11612114223288841087noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-30018183119291165932009-03-16T09:55:00.000-04:002009-03-16T09:55:00.000-04:00Macros are great for conditionally ignoring a sect...Macros are great for conditionally ignoring a section of code. The one particular use I have in mind is for debug logging. Our massive code project is littered with function calls to do debugging, protected by `if trace_level` conditionals to prevent evaluation of the function call and its (sometimes obscenely large) argument payload. Two of the most expensive things one can do in Python are create objects and call functions, and logging generally does both.Unknownhttps://www.blogger.com/profile/14683805670948376813noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-79545325045102417582009-03-13T22:00:00.000-04:002009-03-13T22:00:00.000-04:00Rick, it was good seeing you last night. I think P...Rick, it was good seeing you last night. I think Python and Lisp are pretty close in terms of expressiveness. They have different philosophies though, and it attributes to why/how they are different. I much prefer Python's syntax to Lisp - code is generally much more pleasant to read, which is a big win. On the other hand, I like the simplicity of Lisp, in that there's just not that much to it. Macro's are so powerful you can do almost anything with it. On the other hand in Python, you have a large set of tools at your disposal(metaclasses, decorators, generators, the *with* clause, etc.). There's more you need to learn and more to chose from. Also, since they are language features, you can't extend them yourself - we have to design them by committee. Python wasn't always this expressive - It took many years to get to this point. Lispers were already enjoying their Macros almost at the beginning. Back then, there was nothing close to it, so it's no wonder they are so enthusiastic about them. Things are a bit different now - other languages have caught up.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-18508356.post-17320248434556447222009-03-13T10:26:00.000-04:002009-03-13T10:26:00.000-04:00@Zellyn: I see what you're saying, and I agre...@Zellyn: I see what you're saying, and I agree that the type(...) approach can be off-putting, but I can also just write the following:<BR/><BR/>class Test(BrowserTestCase):<BR/> browser = browser<BR/>Test.__name__ = 'Test%s' % browser<BR/><BR/>In Python 2.6, I could even write a class decorator to clean it up:<BR/><BR/>@setname('Test%s' % browser)<BR/>class Test(BrowserTestCase):<BR/> browser = browser<BR/><BR/>where I have <BR/><BR/>def setname(name):<BR/> def inner(o):<BR/> o.__name__ = name<BR/> return o<BR/> return inner<BR/><BR/>Another thing I didn't like about the type(...) approach is that it doesn't account for metaclasses, but that's a minor pet peeve.<BR/><BR/>Actually, since you mentioned this, I can now think of a good use case for macros -- it would clean up the collections.namedtuple class generator quite a bit. Right now, it puts together a string and eval()s it. Kind of a poor man's macro anyway.Rick Copelandhttps://www.blogger.com/profile/11612114223288841087noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-49537029258386737282009-03-13T10:15:00.000-04:002009-03-13T10:15:00.000-04:00Macros allow your code-definition code to look mor...Macros allow your code-definition code to look more like regular code.<BR/><BR/>The type() example from last night's PyATL meetup is a good example:<BR/><BR/>class Test{BROWSER}(BrowserTestCase):<BR/> browser = {BROWSER}<BR/><BR/>looks a lot more like a normal Python class definition than:<BR/><BR/>type("Test%s" %(CLASSNAME, BROWSER), (BrowserTestCase,), dict(browser=BROWSER))Zellynhttps://www.blogger.com/profile/07004628970214511962noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-26996658430274830192009-03-12T15:17:00.000-04:002009-03-12T15:17:00.000-04:00I guess Lisp programmers when creating templating ...I guess Lisp programmers when creating templating or configuration languages want to keep programming in Lisp plus a few additions, whereas Python programmers either need something completely different so that a few macros would not help them much anyway or if they want Python they want to stay as close as possible to its syntax.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-18508356.post-73807574209701646492009-03-12T14:51:00.000-04:002009-03-12T14:51:00.000-04:00Yeah, I suppose you could -- I like the idea of a ...Yeah, I suppose you could -- I like the idea of a context manager approach -- in fact, I'll probably implement it that way sometime next week now that you point it out.<BR/><BR/>I think the original point probably still stands though -- any where you have a set of boiler-plate code, it may be nice to have macro support.<BR/><BR/>That said, as you've pointed out, it's nowhere near as important as in less flexible languages like C++!Chrishttps://www.blogger.com/profile/05755072772135183636noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-37296250488547632312009-03-12T13:57:00.000-04:002009-03-12T13:57:00.000-04:00@chphilli: I kind of see what you're saying, b...@chphilli: I kind of see what you're saying, but couldn't you achieve the same thing with either a decorator (to guard a function) or a context manager (to guard an arbitrary block of code)?<BR/><BR/>with logging_exceptions:<BR/> some<BR/> potentially<BR/> exception<BR/> raising<BR/> stuffRick Copelandhttps://www.blogger.com/profile/11612114223288841087noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-8209834705356437462009-03-12T12:37:00.000-04:002009-03-12T12:37:00.000-04:00A coworker and I were just discussing this the oth...A coworker and I were just discussing this the other day...<BR/><BR/>In C++ development at my previous employment, we used macros all the time, to reduce repeated code patterns. The most common example was in exception handling, for example, catching, logging, and then re-throwing an exception.<BR/><BR/>As I was writing "except Exception, e: ..." for yet another time the other day, I realized that with macros I could have avoided this repetition. Avoiding repetition means I only have to write it once, and thus, less potential for bugs!Chrishttps://www.blogger.com/profile/05755072772135183636noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-52388079533662912452009-03-12T11:45:00.000-04:002009-03-12T11:45:00.000-04:00@anonymous: Not that I think it's a good idea, bu...@anonymous: Not that I think it's a good idea, but you can actually do that <I>without</I> macros using <A HREF="http://www.voidspace.org.uk/python/articles/metaclasses.shtml#the-selfless-metaclass" REL="nofollow">metaclasses</A>.Rick Copelandhttps://www.blogger.com/profile/11612114223288841087noreply@blogger.comtag:blogger.com,1999:blog-18508356.post-37345233562303570202009-03-12T11:41:00.000-04:002009-03-12T11:41:00.000-04:00Macros could allow you to not use explicit self in...Macros could allow you to not use explicit self in every class method...Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-18508356.post-79519635943304099932009-03-12T11:21:00.000-04:002009-03-12T11:21:00.000-04:00I'm learning PLT Scheme right now and while the ID...I'm learning PLT Scheme right now and while the IDE is quite cool, I don't see much point to macros either.<BR/><BR/>I think macros could create idiosyncratic constructs, which not pythonic.Lucianhttps://www.blogger.com/profile/07775013906985712587noreply@blogger.com