Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Other notes

Reply
Thread Tools

Other notes

 
 
Steve Holden
Guest
Posts: n/a
 
      12-29-2004
Mike Meyer wrote:

> Steve Holden <(E-Mail Removed)> writes:
>

[...]
>>
>>Well, perhaps you can explain how a change that's made at run time
>>(calling the decorator) can affect the parser's compile time behavior,
>>then. At the moment, IIRC, the only way Python code can affect the
>>parser's behavior is in the __future__ module, which must be imported
>>at the very head of a module.

>
>
> By modifying the parsers grammer at runtime. After all, it's just a
> data structure that's internal to the compiler.
>

But the parser executes before the compiled program runs, was my point.
What strange mixture of compilation and interpretation are you going to
use so the parser actually understands that ".." (say) is an operator
before the operator definition has been executed?

regards
Steve
--
Steve Holden http://www.holdenweb.com/
Python Web Programming http://pydish.holdenweb.com/
Holden Web LLC +1 703 861 4237 +1 800 494 3119
 
Reply With Quote
 
 
 
 
Terry Reedy
Guest
Posts: n/a
 
      12-29-2004

"Steven Bethard" <(E-Mail Removed)> wrote in message
news:TLqAd.719331$mD.298058@attbi_s02...
> I'll second that. Please, "Bearophile", do us the courtesy of checking
>
> (1) Google groups archive of the mailing list:
> http://groups-beta.google.com/group/comp.lang.python
>
> and
>
> (2) The Python Enhancement Proposals:
> http://www.python.org/peps/
>
> before posting another such set of questions. While most of the people
> on this list are nice enough to answer your questions anyway, the answers
> are already out there for at least half of your questions, if you would
> do us the courtesy of checking first.


I also suggest perusing the archived PyDev (Python Development mailing
list) summaries for the last couple of years (see python.org). Every two
weeks, Brett Cannon has condensed everything down to a few pages. You can
easily focus on the topics of interest to you. For instance, there was
discussion of making lists truly double-ended, but it was decided to settle
for certain improvements in the list implementation while adding
collections.deque (sp?) in 2.4.

Terry J. Reedy



 
Reply With Quote
 
 
 
 
Terry Reedy
Guest
Posts: n/a
 
      12-29-2004

"Mike Meyer" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Steve Holden <(E-Mail Removed)> writes:
>> Well, perhaps you can explain how a change that's made at run time
>> (calling the decorator) can affect the parser's compile time behavior,
>> then. At the moment, IIRC, the only way Python code can affect the
>> parser's behavior is in the __future__ module, which must be imported
>> at the very head of a module.

>
> By modifying the parsers grammer at runtime. After all, it's just a
> data structure that's internal to the compiler.


Given that xx.py is parsed in its entirety *before* runtime, that answer is
no answer at all. Runtime parser changes (far, far from trivial) could
only affect the result of exec and eval.

Terry J. Reedy



 
Reply With Quote
 
Bengt Richter
Guest
Posts: n/a
 
      12-30-2004
On Wed, 29 Dec 2004 11:42:00 -0600, Mike Meyer <(E-Mail Removed)> wrote:

>(E-Mail Removed) writes:
>
>> @infix
>> def interval(x, y): return range(x, y+1) # 2 parameters needed
>>
>> This may allow:
>> assert 5 interval 9 == interval(5,9)

>
>I don't like the idea of turning words into operators. I'd much rather
>see something like:
>
>@infix('..')
>def interval(x, y):
> return range(x, y + 1)
>
>assert 5 .. 9 == interval(5, 10)
>

I like that for punctuation-character names.

OTOH, there is precedent in e.g. fortran (IIRC) for named operators of the
form .XX. -- e.g., .GE. for >= so maybe there could be room for both.

A capitalization _convention_ would make such infix operators pretty readable
even if the names were'nt always the best, e.g.,

for x in 5 .UP_TO_AND_INCLUDING. 9:
...

Hm, you could make

x .infix. y

syntactic sugar in general (almost like a macro) for

infix(x, y)

and you could generalize that to permit .expression. with no embedded spaces, e.g.,

x .my_infix_module.infix. y
for
my_infix_module.infix(x, y)

or to illustrate expression generality ridiculously,

a = x .my_infix_module.tricky_func_factory_dict[random.choice(range(4))](time.time()). y

for
a = my_infix_module.tricky_func_factory_dict[random.choice(range(4))](time.time())(x, y)

<aside>
I wonder if it's a good idea to post ridiculous but functionally illustrative uses
of possibly good ideas, or if the net effect detracts from the reception of the ideas.
Also verbiage like this ;-/
</aside>

If '..' were special-cased as a synonym for __nullname__ you could handle it
by def __nullname__(x, y): whatever, but since it's punctuation-only, your @infix('..')
seem preferable.

Hm, ... if single (to exlude .infix.) missing dotted names defaulted to __nullname__,
I wonder what that would open up obj. would be obj.__nullname__, which could be
defined as a concise way of referring to the one special attribute or property.
And .name would be __nullname__.name -- which with the approriate descriptor definition
in the function class could make .name syntactic sugar for self.name (or whatever the first arg
name was). ... just musing

>This would also allow us to start working on doing away with the magic
>method names for current operators, which I think would be an
>improvement.
>
>As others have pointed out, you do need to do something about operator
>precedence. For existing operators, that's easy - they keep their
>precedence. For new operators, it's harder.
>
>You also need to worry about binding order. At the very least, you
>can specify that all new operators bind left to right. But that might
>not be what you want.

Yes. My .expression. infix if implemented essentially as a left-right
rewrite-as-soon-as-you-recognize macro would create the precedence rules
of the macro-rewritten source. Which might cover a fair amount of useful
ground. Needs to be explored though. E.g.,

x .op1. y .op2. z => op2(op1(x, y), z)

But you could override with parens in the ordinary way:

x .op1. (y .op2. z) => op1(x, op2(y, z))

But
2 * x + 3 .op1. y => 2 * x + op1(3, y)

Etc. Well, something to think about


Regards,
Bengt Richter
 
Reply With Quote
 
Andrew Dalke
Guest
Posts: n/a
 
      12-30-2004
Bengt Richter:
> OTOH, there is precedent in e.g. fortran (IIRC) for named operators of the
> form .XX. -- e.g., .GE. for >= so maybe there could be room for both.


> Hm, you could make
>
> x .infix. y



> x .op1. y .op2. z => op2(op1(x, y), z)


The problem being that that's already legal syntax

>>> class Xyzzy:

.... def __init__(self):
.... self.op1 = self.op2 = self.y = self
.... self.z = "Nothing happens here"
....
>>> x = Xyzzy()
>>> x .op1. y .op2. z

'Nothing happens here'
>>>


Andrew
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
Bengt Richter
Guest
Posts: n/a
 
      12-30-2004
On Wed, 29 Dec 2004 13:11:43 -0500, Steve Holden <(E-Mail Removed)> wrote:

>Mike Meyer wrote:
>
>> (E-Mail Removed) writes:
>>
>>
>>>@infix
>>>def interval(x, y): return range(x, y+1) # 2 parameters needed
>>>
>>>This may allow:
>>>assert 5 interval 9 == interval(5,9)

>>
>>
>> I don't like the idea of turning words into operators. I'd much rather
>> see something like:
>>
>> @infix('..')
>> def interval(x, y):
>> return range(x, y + 1)
>>
>> assert 5 .. 9 == interval(5, 10)
>>
>> This would also allow us to start working on doing away with the magic
>> method names for current operators, which I think would be an
>> improvement.
>>

>Well, perhaps you can explain how a change that's made at run time
>(calling the decorator) can affect the parser's compile time behavior,
>then. At the moment, IIRC, the only way Python code can affect the
>parser's behavior is in the __future__ module, which must be imported at
>the very head of a module.

Good point, which I didn't address in my reply. (in fact I said I liked
@infix('..') for punctuation-char-named ops, but I was too busy with my
idea to think about that implementation

Potentially, you could do it dynamically with a frame flag (to limit the damage)
which said, check all ops against a dict of overloads and infix definitions while
executing byte code for this frame. Of course, the compiler would have to defer
some kinds of syntax error 'til run time. I.e., '..' would have to be translated
to OP_POSSIBLE_CUSTOM_INFIX or such. I doubt if it would be worth doing.

OTOH, I think my suggestion might be I.e., just do a macro-like (not a general
macro capability for this!!) translation of expressions with dots at both ends and
no embedded spaces (intial thought, to make things easier) thus:
x .expr. y => expr(x, y)

when expr is a simple name, you can use that expression format to call a two-arg function
of that name, e.g.,

def interval(x, y): return xrange(x, y+1)
for i in x .interval. y: print i, # same as for i in interval(x, y): print i,

but you could also write stuff like

def GE(x,y): return x is MY_INFINITY or x >= y
if x .GE. y: print 'x is greater than y'

The .expr. as expression would allow module references or tapping into general
expression and attribute magic etc. I.e., (untested)

from itertools import chain as CHAIN
for k,v in d1.items() .CHAIN. d2.items(): print k, v

or if you had itertools imported and liked verbose infix spelling:

for k,v in d1.items() .itertools.chain. d2.items(): print k, v

or define a hidden-attribute access operation using an object's dict

def HATTR(obj, i):
try: return vars(obj)[i]
except KeyError: raise AttributeError('No such attribute: %r', i)

if thing .HATTR. 2 == 'two': print 'well spelled'

or
from rational import rat as RAT

if x .RAT. y > 1 .RAT. 3: do_it()

or
your turn

>
>> As others have pointed out, you do need to do something about operator
>> precedence. For existing operators, that's easy - they keep their
>> precedence. For new operators, it's harder.
>>

>Clearly you'd need some mechanism to specify preference, either
>relatively or absolutely. I seem to remember Algol 68 allowed this.
>
>> You also need to worry about binding order. At the very least, you
>> can specify that all new operators bind left to right. But that might
>> not be what you want.
>>

>Associativity and precedence will also have to affect the parsing of the
>code, of course. Overall this would be a very ambitious change.
>

My suggestion if implemented with left-right priority would be easy to
implement (I think And you could always override order with parens.

Regards,
Bengt Richter
 
Reply With Quote
 
Bengt Richter
Guest
Posts: n/a
 
      12-30-2004
On Thu, 30 Dec 2004 03:37:38 GMT, Andrew Dalke <(E-Mail Removed)> wrote:

>Bengt Richter:
>> OTOH, there is precedent in e.g. fortran (IIRC) for named operators of the
>> form .XX. -- e.g., .GE. for >= so maybe there could be room for both.

>
>> Hm, you could make
>>
>> x .infix. y

>
>
>> x .op1. y .op2. z => op2(op1(x, y), z)

>
>The problem being that that's already legal syntax

D'oh

>
>>>> class Xyzzy:

>... def __init__(self):
>... self.op1 = self.op2 = self.y = self
>... self.z = "Nothing happens here"
>...
>>>> x = Xyzzy()
>>>> x .op1. y .op2. z

>'Nothing happens here'
>>>>


Ok, well, that's happened to me before
We'll have to find a way to make it illegal, but it's not likely to be quite as clean.

x ..OP y
x ./OP y
x .<OP y
x .<OP>. y
X ._OP_. y
x ..OP.. y # for symmetry

X .(OP). y # emphasizes the .expression. returning a function accepting two args

That might be the best one.

OTOH some time ago I was thinking of .(statements). as a possible tokenizer-time star-gate into
a default-empty tokenizer-dynamically-created module which would essentially exec the statements
in that module and return the value of the last expression as a string for insertion into the token
source code stream at that point being tokenized.

Thus e.g. you could have source that said

compile_time = .(__import__('time').ctime()).

and get a time stamp string into the source text at tokenization time.

I had also thought obj.(expr) could be syntactic sugar for obj.__dict__[expr]
but that would also interfere

So maybe .(OP). should for infix, and .[stargate exec args]. should be for that

Regards,
Bengt Richter
 
Reply With Quote
 
Bengt Richter
Guest
Posts: n/a
 
      12-30-2004
On Thu, 30 Dec 2004 03:55:12 GMT, (E-Mail Removed) (Bengt Richter) wrote:
[.. buncha stuff alzheimersly based on x<spaces>.attr not being parsed as x.attr ;-/ ]

> from rational import rat as RAT
>
> if x .RAT. y > 1 .RAT. 3: do_it()
>
>or
> your turn
>

Andrew got there first
Still, see my reply to his for more opportunities

Regards,
Bengt Richter
 
Reply With Quote
 
Bengt Richter
Guest
Posts: n/a
 
      12-30-2004
On Thu, 30 Dec 2004 04:46:25 GMT, (E-Mail Removed) (Bengt Richter) wrote:
[...]
>Ok, well, that's happened to me before
>We'll have to find a way to make it illegal, but it's not likely to be quite as clean.
>
> x ..OP y
> x ./OP y
> x .<OP y
> x .<OP>. y
> X ._OP_. y

Bzzzt! ;-/

> x ..OP.. y # for symmetry
>
> X .(OP). y # emphasizes the .expression. returning a function accepting two args
>
>That might be the best one.


Regards,
Bengt Richter
 
Reply With Quote
 
Steve Holden
Guest
Posts: n/a
 
      12-30-2004
Bengt Richter wrote:

> On Wed, 29 Dec 2004 13:11:43 -0500, Steve Holden <(E-Mail Removed)> wrote:
>

[...]
>>
>>Well, perhaps you can explain how a change that's made at run time
>>(calling the decorator) can affect the parser's compile time behavior,
>>then. At the moment, IIRC, the only way Python code can affect the
>>parser's behavior is in the __future__ module, which must be imported at
>>the very head of a module.

>
> Good point, which I didn't address in my reply. (in fact I said I liked
> @infix('..') for punctuation-char-named ops, but I was too busy with my
> idea to think about that implementation
>

Well, that explains the lack of detail. I realize that you are more
likely than most to be able to come up with an implementation.

> Potentially, you could do it dynamically with a frame flag (to limit the damage)
> which said, check all ops against a dict of overloads and infix definitions while
> executing byte code for this frame. Of course, the compiler would have to defer
> some kinds of syntax error 'til run time. I.e., '..' would have to be translated
> to OP_POSSIBLE_CUSTOM_INFIX or such. I doubt if it would be worth doing.
>

Right. I can't say I think deferring syntax errors until runtime is a
good idea.

> OTOH, I think my suggestion might be I.e., just do a macro-like (not a general
> macro capability for this!!) translation of expressions with dots at both ends and
> no embedded spaces (intial thought, to make things easier) thus:
> x .expr. y => expr(x, y)
>
> when expr is a simple name, you can use that expression format to call a two-arg function
> of that name, e.g.,
>
> def interval(x, y): return xrange(x, y+1)
> for i in x .interval. y: print i, # same as for i in interval(x, y): print i,
>
> but you could also write stuff like
>
> def GE(x,y): return x is MY_INFINITY or x >= y
> if x .GE. y: print 'x is greater than y'
>
> The .expr. as expression would allow module references or tapping into general
> expression and attribute magic etc. I.e., (untested)
>
> from itertools import chain as CHAIN
> for k,v in d1.items() .CHAIN. d2.items(): print k, v
>
> or if you had itertools imported and liked verbose infix spelling:
>
> for k,v in d1.items() .itertools.chain. d2.items(): print k, v
>
> or define a hidden-attribute access operation using an object's dict
>
> def HATTR(obj, i):
> try: return vars(obj)[i]
> except KeyError: raise AttributeError('No such attribute: %r', i)
>
> if thing .HATTR. 2 == 'two': print 'well spelled'
>
> or
> from rational import rat as RAT
>
> if x .RAT. y > 1 .RAT. 3: do_it()
>
> or
> your turn
>

Well, I can see that Fortran programmers might appreciate it . And I
suppose that the syntax is at least regular enough to be lexed with the
current framework, give or take. It would lead to potential breakage due
to the syntactic ambiguity between

module .function. attribute

and

module.function.attribute

though I don't honestly think that most people currently insert
gratuitous spaces into attribute references.

>

[precedence and associativity]
>
> My suggestion if implemented with left-right priority would be easy to
> implement (I think And you could always override order with parens.


Now you're just trying to make it easy

regards
Steve
--
Steve Holden http://www.holdenweb.com/
Python Web Programming http://pydish.holdenweb.com/
Holden Web LLC +1 703 861 4237 +1 800 494 3119
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Lotus Notes inotes/webmail Ron P Firefox 1 08-31-2007 03:41 PM
C# 2.0 (Lotus Notes 6 & 7) Create mail document in draft folder for Lotus Notes SteveM ASP .Net 5 08-28-2007 04:16 PM
Accessing email from Notes-mail-server without Lotus Notes installed Bjorn Jensen Perl 0 03-22-2005 01:44 PM
AM-Deadlink notes MsOsWin@anon.com Firefox 0 01-13-2005 12:41 AM
Re: Other notes Jp Calderone Python 11 01-08-2005 10:55 AM



Advertisments