Ken Tilton wrote: > [EMAIL PROTECTED] wrote: > > > > Code is data is code > > I was hoping no one would make that mistake. :) macros are all about > code is data, but code is not data in Python* so the two words code and > data serve to differentiate them for Pythonistas. >
I disagree. I frequently write data-driven algorithms in C and Python (data is code). I occasionally write code-generators too (code is data). Just because the representation is different between code and data in those languages doesn't mean that you can't use data as code (interpreter style) or generate code as data (compiler style). (I won't bother boring you with the Python bytecode hacks or the parser module, because I think those are not terribly practical.) It's very elegant that Lisp makes the representations between code and data so similar, but it looks like you know the mantra and not the meaning if you can't apply that principle in other languages. BTW... Even in Scheme, I have to use syntax-object->datum and it's inverse to switch between the two. I suspect this has something to do with the other context that must be associated with the data to turn it into code. Probably at least the enclosing environment for lexical scoping and the line numbers for debugging or exception handling. Does Common Lisp maintain this information with it's macro expansions? If so, you have a slight difference between code and data too. If not, how do you get the line number when a problem happens in a nested macro? Moreover, if you really want to be pedantic about what "is" means in "code is data", then you have to acknowledge that data is a superset of code, since all code is obviously data, but there are plenty of types of data that aren't used as code. Or are they? :-) > * Taking questions after a keynote to ILC200? where he reiterated that > Python was the same as Lisp for all intents and purposes: > > Norvig: "Yes, John?" > McCarthy: "Is code also data in Python?" > Norvig: "No." > > End of exchange. :) > Really? You're relying on an appeal to authority? Ok, I'm going to start arguing by analogy then... > > def reverse(cls, *args): > > # I didn't understand what your code was doing > > yeah, and god forbid you should ask. :) this is the crux of the matter! > > Actually, it is kinda cool that you and Greg are semi-identifying the > crux by saying "this is the only bit I do not get, I'll skip this, move > on, nothing to see here". > Ok, I'll bite. What does it do? I read through it, and it looks the code you're passing to the macro does some things like calculating the number of decimal digits and generating a 2 + a random number of that many digits to find a divisor or something. It also looks like you have some "string interpolation" to substitute names in your text, but as a whole, I really don't have any clue what it's all about. It looks like the macro itself is building some names on the fly and defining methods (new specializations for multimethods?) with those names. So I'm sure I'm missing something, but there is almost certainly a readable equivalent in Python (and even C). If you really want to generate dynamic names for functions, you can do that in Python by modifying the class or globals hash or whatever. A more standard way might be to be have members in the base class. There is even a multi-methods module in Python, but I've never used it. I'd guess you could add to that dynamically too. > > > > That would be a reasonable place for a "pie decorator" on a class, but > > I guess that's not allowed. > > Hmmm. Actually, that is the whole point, all of Python is allowed. > decorators were used in PyCells, but I never got much of an idea what > they did. Is there a moral equivalent of a macroexpansion for decorators > so you can show the before and after? > It's Python that doesn't allow you to decorate classes. (You can decorate functions, but not classes...) I made this comment as a criticism of Python since it seems like a non-orthogonal corner... It would have fit in this case. Decorators are pretty simple: @foo def bar(): pass is equivalent to: def bar(): pass bar = foo(bar) The callable foo can use whatever it wants to inspect, modify, or wrap the function bar. but: @foo class bar: pass is not currently allowed, so you have to do class bar: pass bar = foo(bar) > > exactly what we are looking for in this cultural exchange: how would > Python handle what I am doing with macros in the reverse functions? Make > it as slick and programmer-friendly (cuz I may get to a hundred of these > before I am done with Algebra I) as possible. When all the Pythonistas > proclaim it optimal, then we compare and contrast. > > This, btw, is the Tilton Test for language comparison: Not measurements > of programmer effort, rather examination of perfect equivalent code. > PyCells vs Cells would be an amazing case, because that is some hairy > functionality. > That seems like a fine strategy. I fall more on the programmer effort side. I want to write as little code as possible in a readable way such that it meets the requirements. I'm not a particularly good ambassador for Python. I know Python much better than Lisp (Scheme), but I already think Scheme is a better language. Macros are part of that. I'm mostly playing devil's advocate here because I don't think your example really brings it home. I've got limited time that I'm willing to invest in learning your algebra system, but I haven't seen (understood, if you insist) anything yet that couldn't be done readably in Python. If you want Common Lisp to win in your language battle against the Pythonistas, you're going to need to break out with something stronger. Then again, you're probably pissing into the wind anyway. Cheers, -Scott -- http://mail.python.org/mailman/listinfo/python-list