Python Macros

  • Thread starter Arich Chanachai
  • Start date
A

Arich Chanachai

How hard/easy is it to extend the Python syntax? Perhaps there are
macro facilities for this? I'd like to add messages and message
passing, for example.

Thanks.
 
M

Michael Sparks

Arich said:
How hard/easy is it to extend the Python syntax?

It's not that hard to do, but involves changing the compiler and if done
properly a whole slew of other things. If you want non-functional syntax
changes it's fairly trivial - just change the Grammar file and rebuild.
If you want a checklist of things you might want to look at when changing
the syntax you could look at this patch : http://www.python.org/sf/1013835

It's worth noting that this would probably result in a local overhead for
yourself in maintaining a private branch of python however - since this
changes your python in a fairly fundamental manner. I don't know what your
use case is though - if it's experimentation then I suspect that you'd be
happy with that :)
Perhaps there are macro facilities for this?

Not that I'm aware of. (At least not as far as I know in the lisp or C
meanings of the term)
I'd like to add messages and message passing, for example.

Why do you feel you need to extend the language for this? Why not (for
example) overload <<, >> and similar operators? __lshift__, __rshift__ etc.
I'd really recommend not extending the language unless you really don't have
any option - unless that's what you're specifically interested in :)

Regards,


Michael.
 
A

Arich Chanachai

Michael said:
Arich Chanachai wrote:




It's not that hard to do, but involves changing the compiler and if done
properly a whole slew of other things. If you want non-functional syntax
changes it's fairly trivial - just change the Grammar file and rebuild.
If you want a checklist of things you might want to look at when changing
the syntax you could look at this patch : http://www.python.org/sf/1013835
Are there tutorials on this?
It's worth noting that this would probably result in a local overhead for
yourself in maintaining a private branch of python however - since this
changes your python in a fairly fundamental manner. I don't know what your
use case is though - if it's experimentation then I suspect that you'd be
happy with that :)
:Local overhead??? Private branch??? How come? I'm extending the
language not adding another Python interpreter.
Not that I'm aware of. (At least not as far as I know in the lisp or C
meanings of the term)
I was thinking Scheme.
Why do you feel you need to extend the language for this? Why not (for
example) overload <<, >> and similar operators? __lshift__, __rshift__ etc.
I'd really recommend not extending the language unless you really don't have
any option - unless that's what you're specifically interested in :)
Not sure I understand you here. I want to implement messages like in
ObjC where if you send a msg to an object and that object does know what
to do with it, it can send the obj automatically to another object which
might know what to do with it.

Anyhow, there are other reasons as well.
 
D

Diez B. Roggisch

:Local overhead??? Private branch??? How come? I'm extending the
language not adding another Python interpreter.

In fact, you do. As long as you don't implement it as mere preprocessor -
then of course, you can do what you want.
I was thinking Scheme.

Nope, there is no such thing - if you want it, use scheme/lisp.
Not sure I understand you here. I want to implement messages like in
ObjC where if you send a msg to an object and that object does know what
to do with it, it can send the obj automatically to another object which
might know what to do with it.

Not sure what you mean by this, as I never used ObjC - I suppose you wanted
to say "that object does *not* know what to do with it". Unless you get a
bit more specific, I can't suggest something more concrete, but I bet
metaclasses can come handy here - after all, writing delegating classes in
python using them (and other techniques) is easy and sounds like an
approach to what you might want.
 
J

Josiah Carlson

Not sure I understand you here. I want to implement messages like in
ObjC where if you send a msg to an object and that object does know what
to do with it, it can send the obj automatically to another object which
might know what to do with it.

Anyhow, there are other reasons as well.

What are called "messages" in ObjC, are generally known as "instance
methods" in Python.

I would imagine in ObjC you would do something like the following:

object.send('operation', arg1, arg2, arg3,...)
send(object, 'operation', arg1, arg2, arg3,...)

In Python, that becomes:

object.operation(arg1, arg2, arg3,...)


"Messages" in ObjC are really just a metaphor, one that is shared by
Smalltalk, but not many other object-oriented languages.

- Josiah
 
M

Michael Sparks

Arich said:
I was thinking Scheme. ....
Really?  I read that Python was just like Scheme in that it had macro 
facilities.

Ahh... I see where you're coming from. Unfortunately you've been misled on
this point - python does not have those sorts of macros. As a result if you
want to extend the language, ...
:Local overhead??? Private branch??? How come? I'm extending the
language not adding another Python interpreter.

.... the only way to do this is to modify the python interpreter itself,
which is why I gave the reference I did (since I've had experience lately
of doing this :). ie you can't do this and not add another Python
interpreter.

The reason I suggested this is an overhead is because if you did that you
would end up with your own customised version of the python compiler-
something it sounds like you don't want. (not suprising) Furthermore there
aren't any tutorials that I'm aware of on doing this, which is why I
pointed you at one example of doing this :) (If only because it lets you
know what sort of what hoops you need to jump through to do it without
using a preprocessor, tokeniser, etc)

As a result your options are:
* Implement your own pre-processor - either using the tokeniser module or
using a full blown parser like PLY, SPARK, etc.
* Implement the functionality you want using usual classes. You may or
may not like that approach.
* Find an existing macro pre-processor and modify it to do what you want.

Personally I'd choose option 2 here.
Not sure I understand you here. I want to implement messages like in
ObjC where if you send a msg to an object and that object does know what
to do with it, it can send the obj automatically to another object which
might know what to do with it.

I've not used ObjC - a code fragment with a brief explanation would
probably help. (That description matches too many possible use cases
and solutions... :) Posting a fragment *might* also jog someone's memory
to be able to say "that's already implemented -- here" :)
Anyhow, there are other reasons as well.

Without knowing these it's difficult to help more. (And since you're asking
for tutorials it's not clear at all where to point you to without seeing
something concrete.

Regards,


Michael.
 
C

Carlos Ribeiro

What are called "messages" in ObjC, are generally known as "instance
methods" in Python.

I would imagine in ObjC you would do something like the following:

object.send('operation', arg1, arg2, arg3,...)
send(object, 'operation', arg1, arg2, arg3,...)

In Python, that becomes:

object.operation(arg1, arg2, arg3,...)

"Messages" in ObjC are really just a metaphor, one that is shared by
Smalltalk, but not many other object-oriented languages.

There are many things that can be done to mimic it. Instance methods
in Python are pretty powerful -- they can be handled like normal
objects, copied, passed as parameters, and even bound to other classe.
You can also use descriptors in Python to do something similar. More
details would be needed though for better discussion.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: (e-mail address removed)
mail: (e-mail address removed)
 
P

Paul Foley

Not sure I understand you here. I want to implement messages like in
ObjC where if you send a msg to an object and that object does know what
to do with it, it can send the obj automatically to another object which
might know what to do with it.

Write: object.message()
 
A

Arich Chanachai

I've not used ObjC - a code fragment with a brief explanation would
probably help. (That description matches too many possible use cases
and solutions... :) Posting a fragment *might* also jog someone's memory
to be able to say "that's already implemented -- here" :)
Code fragment:

[Dog fetch:cat] ---> Dog doesn't know how to fetch cat ---> Dog
passes message to human and essentially makes the following call --->
[Human fetch:cat] ----> and so forth
 
J

Jacek Generowicz

Josiah Carlson said:
"Messages" in ObjC are really just a metaphor, one that is shared by
Smalltalk, but not many other object-oriented languages.

_Most_ object-oriented languages support object orientation via the
message passing paradigm. Python included.

It's just that in Smalltalk the word "message" plays a more central
role in the (natural) language used to talk about the (programming)
language. In other (programming) languages, terms such as "method" and
"member function" tend to be used to describe the same concept.
 
J

Jacek Generowicz

Bruno Desthuilliers said:
Well, I'd rather say that *all* OOPLs support message passing.

Not all. Common Lisp, for example does not support message pasing out
of the box (even though it's easy to implement a message-passing
object system yourself, in CL). The Common Lisp Object System (CLOS)
is based on generic functions.
 
H

has

Arich Chanachai said:
Not sure I understand you here. I want to implement messages like in
ObjC where if you send a msg to an object and that object does know what
to do with it, it can send the obj automatically to another object which
might know what to do with it.

You can implement this behaviour using Python's magic __getattr__
method and getattr function to request an attribute from another
object. See:

http://www.python.org/doc/2.3.4/ref/attribute-access.html

For real macros, you'll have to go to Lisp or Lisp derivatives such as
Dylan. The rest of the programming world is still catching up to 1958.
:p
 
B

Bruno Desthuilliers

Josiah said:
What are called "messages" in ObjC, are generally known as "instance
methods" in Python.

I would imagine in ObjC you would do something like the following:

object.send('operation', arg1, arg2, arg3,...)
send(object, 'operation', arg1, arg2, arg3,...)

In Python, that becomes:

object.operation(arg1, arg2, arg3,...)


"Messages" in ObjC are really just a metaphor, one that is shared by
Smalltalk, but not many other object-oriented languages.

Well, I'd rather say that *all* OOPLs support message passing. What we
call 'methods' are just a way to implement a specific response to a message.

Given the following code :

"a b c d".split()

What we're really doing - from an OO POV - is not calling the split()
instance method of class str, but sending the 'split' message to a str
object. The fact that doing so result in calling the split() instance
method of the str class is just a side effect !-)

just-playing-with-words-ly y'rs
Bruno
 
A

Andrew Dalke

has said:
For real macros, you'll have to go to Lisp or Lisp derivatives such as
Dylan. The rest of the programming world is still catching up to 1958.
:p

http://www.dreamsongs.com/NewFiles/Hopl2.pdf
] Macros appear to have been introduced into Lisp by Timothy
] P. Hart in 1963 in a short MIT AI Memo [Hart, 1963]

So we've got an extra 5 years to spare ;)

Andrew
(e-mail address removed)
 
A

Andrew Dalke

Jacek said:
_Most_ object-oriented languages support object orientation via the
message passing paradigm. Python included.

Translating the Smalltalk notation to Python -- what are
the messages? Is it that

x.y(z)

means "send the __call__ (z)" message to the result of
the "z __getattr__ 'y'" message?

Andrew
(e-mail address removed)
 
G

gabriele renzi

Michael Sparks ha scritto:

Why do you feel you need to extend the language for this? Why not (for
example) overload <<, >> and similar operators? __lshift__, __rshift__ etc.

ah, so the OP is asking about Higher Order Messages a-la F-Script? (or
hyper ops a-la perl6)

I don't think this can be done in pure python. You can do half of it, say:
collection >> stuff # map the stuff over the collection
or
collection >> operator << othercollection

but you cant do

stuff operator << collection
 
G

gabriele renzi

Jacek Generowicz ha scritto:
_Most_ object-oriented languages support object orientation via the
message passing paradigm. Python included.

I disagree slightly.
I think the difference is really subtle, but there are some dict-based
languages like python and some message-based like smalltalk.
Actually I think the discriminating is having a doesNotUnderstand:-like
facility versus a __getattr__ one.
 
C

Carlos Ribeiro

Code fragment:

[Dog fetch:cat] ---> Dog doesn't know how to fetch cat ---> Dog
passes message to human and essentially makes the following call --->
[Human fetch:cat] ----> and so forth

Other posters have already pointet out to you some alternatives. If
Dog and Human are both classes, there are many things you can do.

-- If the classes are related in a hierarchy, then the descendent
class will call the superclass method (as in any sane OOP language,
mind you);

-- By providing your own __getattr__ function, you can put yourself in
the position to decide who must fetch the cat. In this case, a code
like this (untested) will do it:

class Human:
def fetch(self, thing):
print "Asked to fetch '%s'" % thing
class Dog:
def __init__(self, owner=None):
self.owner = owner
def __getattr__(self, attrname):
# self.__dict__ contains the local dict of Dog
message = getattr(self.__dict__, attrname, None)
if message:
# message is really a method, anyway...
return message
else:
# asks the owner if it supports the message
return getattr(self. owner, attrname)
Asked to fetch 'cat'

The problem with the code above is that joe.fetch() does not know that
the message 'fetch' was deferred from the dog (the value of self is
bound to the 'joe' instance when the object is created). Of course,
there is a lot of things that you can do to solve this problem; for
example, the 'ownership' relationship could be implemented
bidirectionally, so the owner would know that his dog could be asking
him a favour. Another idea is to use MixIns -- classes that than be
added to another class to provide some functionality, but that leads
to a different type of solution architecturally speaking.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: (e-mail address removed)
mail: (e-mail address removed)
 
M

Michele Simionato

Jacek Generowicz said:
_Most_ object-oriented languages support object orientation via the
message passing paradigm. Python included.

In my mind I have the equation "message passing = single dispatching"
as opposed to multiple dispatching (generic functions). IOW, it seems
to me that all OOP systems based on single dispatching are more or less
the same and it is just a matter of terminology ("passing a message to
an object" = "calling a method of an object").
Am I right in this simplification? Or the terms has a much more
precise meaning? Just for my personal edification,

Michele Simionato
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top