473,804 Members | 3,748 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Other notes

Here are some questions and suggestions of mine that I've collected in
the last weeks on the language (please note that some (most?) of them
are probably wrong/useless/silly, but I've seen that such notes help me
understand a lot of things and to find my weak spots.)

1) I've seen that list pop/append is amortised to its tail, but not for
its head. For this there is deque. But I think dynamical arrays can be
made with some buffer at both head and tail (but you need to keep an
index S to skip the head buffer and you have to use this index every
access to the elements of the list). I think that the most important
design goal in Python built-in data types is flexibility (and safety),
instead of just speed (but dictionaries are speedy ^_^), so why there
are deques instead of lists with both amortised tail&tail operations?
(My hypothesis: to keep list implementation a bit simpler, to avoid
wasting memory for the head buffer, and to keep them a little faster,
avoiding the use of the skip index S).
2) I usually prefer explicit verbose syntax, instead of cryptic symbols
(like decorator syntax), but I like the infix Pascal syntax ".." to
specify a closed interval (a tuple?) of integers or letters (this
syntax doesn't mean to deprecate the range function). It reminds me the
.... syntax sometimes used in mathematics to define a sequence.
Examples:

assert 1..9 == tuple(range(1,1 0))
for i in 1..12: pass
for c in "a".."z": pass
3) I think it can be useful a way to define infix functions, like this
imaginary decorator syntax:

@infix
def interval(x, y): return range(x, y+1) # 2 parameters needed

This may allow:
assert 5 interval 9 == interval(5,9)
4) The printf-style formatting is powerful, but I still think it's
quite complex for usual purposes, and I usually have to look its syntax
in the docs. I think the Pascal syntax is nice and simpler to remember
(especially for someone with a little Pascal/Delphi experience ^_^), it
uses two ":" to format the floating point numbers (the second :number
is optional). For example this Delphi program:

{$APPTYPE CONSOLE}
const a = -12345.67890;
begin
writeln(a);
writeln(a:2:0);
writeln(a:4:2);
writeln(a:4:20) ;
writeln(a:12:2) ;
end.

Gives:
-1.2345678900000 0E+0004
-12346
-12345.68
-12345.678900000 00000000000
-12345.68
(The last line starts with 3 spaces)
5) From the docs about round:
Values are rounded to the closest multiple of 10 to the power minus n;
if two multiples are equally close, rounding is done away from 0 (so.
for example, round(0.5) is 1.0 and round(-0.5) is -1.0).
Example:
a = [0.05 + x/10.0 for x in range(10)]
b str(round(x, 1))
for x in a: print x,
print
for x in a: print str(round(x, 1)) + " ",

Gives:
0.05 0.15 0.25 0.35 0.45 0.55 0.65 0.75 0.85 0.95
0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

But to avoid a bias toward rounding up there is another way do this:
If the digit immediately to the right of the last sig. fig. is more
than 5, you round up.
If the digit immediately to the right of the last sig. fig. is less
than 5, you round down.
If the digit immediately to the right of the last sig. fig. is equal to
5, you round up if the last sig. fig. is odd. You round down if the
last sig. fig. is even. You round up if 5 is followed by nonzero
digits, regardless of whether the last sig. fig. is odd or even.
http://www.towson.edu/~ladon/roundo~1.html
http://mathforum.org/library/drmath/view/58972.html
http://mathforum.org/library/drmath/view/58961.html
6) map( function, list, ...) applies function to every item of list and
return a list of the results. If list is a nested data structure, map
applies function to just the upper level objects.
In Mathematica there is another parameter to specify the "level" of the
apply.

So:
map(str, [[1,[2]], 3])
==>
['[1, [2]]', '3']

With a hypothetical level (default level = 1, it gives the normal
Python map):

map(str, [[1,[2]], 3], level=1)
==>
['[1, [2]]', '3']

map(str, [[1,[2]], 3], level=2)
==>
['1', '[2]', '3']

I think this semantic can be extended:
level=0 means that the map is performed up to the leaves (0 means
infinitum, this isn't nice, but it can be useful because I think Python
doesn't contain a built-in Infinite).
level=-1 means that the map is performed to the level just before the
leaves.
Level=-n means that the map is performed n levels before the leaves.
7) Maybe it can be useful to extended the reload(module) semantic:
reload(module [, recurse=False])
If recurse=True it reloads the module and recursively all the modules
that it imports.
8) Why reload is a function and import is a statement? (So why isn't
reload a statement too, or both functions?)
9) Functions without a return statement return None:
def foo(x): print x
I think the compiler/interpreter can give a "compilatio n warning" where
such function results are assigned to something:
y = foo(x)
(I know that some of such cases cannot be spotted at compilation time,
but the other cases can be useful too).
I don't know if PyChecker does this already. Generally speaking I'd
like to see some of those checks built into the normal interpreter.
Instructions like:
open = "hello"
Are legal, but maybe a "compilatio n warning" can be useful here too
(and maybe even a runtime warning if a Verbose flag is set).
10) There can be something in the middle between the def statement and
the lambda. For example it can be called "fun" (or it can be called
"def" still). With it maybe both def and lambdas aren't necessary
anymore. Examples:
cube = fun x:
return x**3
(the last line is indented)

sorted(data, fun x,y: return x-y)
(Probably now it's almost impossible to modify this in the language.)
11) This is just a wild idea for an alternative syntax to specify a
global variable inside a function. From:

def foo(x):
global y
y = y + 2
(the last two lines are indented)

To:

def foo(x): global.y = global.y + 2

Beside the global.y, maybe it can exist a syntax like upper.y or
caller.y that means the name y in the upper context. upper.upper.y etc.
12) Mathematica's interactive IDE suggests possible spelling errors;
this feature is often useful, works with builtin name functions too,
and it can be switched off.
In[1]:= sin2 = N[Sin[2]]
Out[1]= 0.909297

In[2]:= sina2
General::"spell 1": "Possible spelling error: new symbol name "sina2"
is similar to existing symbol "sin2".
Out[2]= sina2

I don't know if some Python IDEs (or IPython) do this already, but it
can be useful in Pythonwin.
13) In Mathematica language the = has the same meaning of Python, but
:= is different:

lhs := rhs assigns rhs to be the delayed value of lhs. rhs is
maintained in an unevaluated form. When lhs appears, it is replaced by
rhs, evaluated afresh each time.

I don't know if this can be useful...
------------------

14) In one of my last emails of notes, I've tried to explain the
Pattern Matching programming paradigm of Mathematica. Josiah Carlson
answered me:

http://groups-beta.google.com/group/...5600094cb281c1
In the C/C++ world, that is called polymorphism.
You can do polymorphism with Python, and decorators may make it

easier...

This kind of programming is like the use of a kind regular expression
on the parameters of functions. Here are some fast operators, from the
(copyrighted) online help:

_ or Blank[ ] is a pattern object that can stand for any Mathematica
expression.
For example this info comes from:
http://documents.wolfram.com/mathema...unctions/Blank
This is used for example in the definition of functions:
f[x_] := x^2

__ (two _ characters) or BlankSequence[ ] is a pattern object that can
stand for any sequence of one or more Mathematica expressions.

___ (three _ characters) or BlankNullSequen ce[ ] is a pattern object
that can stand for any sequence of zero or more Mathematica
expressions.
___h or BlankNullSequen ce[h] can stand for any sequence of expressions,
all of which have head h.

p1 | p2 | ... is a pattern object which represents any of the patterns
pi

s:obj represents the pattern object obj, assigned the name s. When a
transformation rule is used, any occurrence of s on the right*hand
side is replaced by whatever expression it matched on the left*hand
side. The operator : has a comparatively low precedence. The expression
x:_+_ is thus interpreted as x:(_+_), not (x:_)+_.

p:v is a pattern object which represents an expression of the form p,
which, if omitted, should be replaced by v. Optional is used to specify
"optional arguments" in functions represented by patterns. The pattern
object p gives the form the argument should have, if it is present. The
expression v gives the "default value" to use if the argument is
absent. Example: the pattern f[x_, y_:1] is matched by f[a], with x
taking the value a, and y taking the value 1. It can also be matched by
f[a, b], with y taking the value b.

p.. is a pattern object which represents a sequence of one or more
expressions, each matching p.

p... is a pattern object which represents a sequence of zero or more
expressions, each matching p.

patt /; test is a pattern which matches only if the evaluation of test
yields True.
Example: f[x_] := fp[x] /; x > 1 defines a function in the case when a.
lhs := Module[{vars}, rhs /; test] allows local variables to be shared
between test and rhs. You can use the same construction with Block and
With.

p?test is a pattern object that stands for any expression which matches
p, and on which the application of test gives True. Ex:
p1[x_?NumberQ] := Sqrt[x]
p2[x_?NumericQ] := Sqr[x]

Verbatim[expr] represents expr in pattern matching, requiring that expr
be matched exactly as it appears, with no substitutions for blanks or
other transformations . Verbatim[x_] will match only the actual
expression x_. Verbatim is useful in setting up rules for transforming
other transformation rules.

HoldPattern[expr] is equivalent to expr for pattern matching, but
maintains expr in an unevaluated form.

Orderless is an attribute that can be assigned to a symbol f to
indicate that the elements a in expressions of the form f[e1, e2, ...]
should automatically be sorted into canonical order. This property is
accounted for in pattern matching.

Flat is an attribute that can be assigned to a symbol f to indicate
that all expressions involving nested functions f should be flattened
out. This property is accounted for in pattern matching.

OneIdentity is an attribute that can be assigned to a symbol f to
indicate that f[x], f[f[x]], etc. are all equivalent to x for the
purpose of pattern matching.

Default[f], if defined, gives the default value for arguments of the
function f obtained with a _. pattern object.
Default[f, i] gives the default value to use when _. appears as the
i-th argument of f.

Cases[{e1, e2, ...}, pattern] gives a list of the a that match the
pattern.
Cases[{e1, e2, ...}, pattern -> rhs] gives a list of the values of rhs
corresponding to the ei that match the pattern.

Position[expr, pattern] gives a list of the positions at which objects
matching pattern appear in expr.

Select[list, crit] picks out all elements a of list for which crit[ei]
is True.

DeleteCases[expr, pattern] removes all elements of expr which match
pattern.
DeleteCases[expr, pattern, levspec] removes all parts of expr on levels
specified by levspec which match pattern.
Example : DeleteCases[{1, a, 2, b}, _Integer] ==> {a, b}

Count[list, pattern] gives the number of elements in list that match
pattern.

MatchQ[expr, form] returns True if the pattern form matches expr, and
returns False otherwise.

It may look strange, but an expert can even use it to write small full
programs... But usually they are used just when necessary.
Note that I'm not suggesting to add those (all) into python.

------------------

15) NetLogo is a kind of logo derived from StarLogo, implemented in
Java.
http://ccl.northwestern.edu/netlogo/
I think it contains some ideas that can be useful for Python too.
- It has built-in some hi-level data structures, like the usual turtle
(but usually you use LOTS of turtles at the same time, in parallel),
and the patch (programmable cellular automata layers, each cell can be
programmed and it can interact with nearby cells or nearby turtles)
- It contains built-in graphics, because it's often useful for people
that starts to program, and it's useful for lots of other things. In
Python it can be useful a tiny and easy "fast" graphics library
(Tkinter too can be used, but something simpler can be useful for some
quick&dirty graphics. Maybe this library can also be faster than the
Tkinter pixel plotting and the pixel matrix visualisation).
- It contains few types of built-in graphs to plot variables, etc. (for
python there are many external plotters).
- Its built-in widgets are really easy to use (they are defined inside
NetLogo and StarLogo source), but they probably look too much toy-like
for Python programs...
- This language contains lots of other nice ideas. Some of them
probably look too much toy-like, still some examples:
http://ccl.northwestern.edu/netlogo/models/
Show that this language is only partially a toy, and it can be useful
to understand and learn nonlinear dynamics of many systems.

This is a source, usually some parts of it (like widget positioning and
parameters) are managed by the IDE:
http://ccl.northwestern.edu/netlogo/...logy/Fur.nlogo
Bye,
bear hugs,
Bearophile

Jul 18 '05
22 1941
Mike Meyer wrote:
Steve Holden <st***@holdenwe b.com> 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
Jul 18 '05 #11

"Steven Bethard" <st************ @gmail.com> wrote in message
news:TLqAd.7193 31$mD.298058@at tbi_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.deq ue (sp?) in 2.4.

Terry J. Reedy

Jul 18 '05 #12

"Mike Meyer" <mw*@mired.or g> wrote in message
news:86******** ****@guru.mired .org...
Steve Holden <st***@holdenwe b.com> 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

Jul 18 '05 #13
On Wed, 29 Dec 2004 11:42:00 -0600, Mike Meyer <mw*@mired.or g> wrote:
be************ @lycos.com 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_INCL UDING. 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_modul e.infix. y
for
my_infix_module .infix(x, y)

or to illustrate expression generality ridiculously,

a = x .my_infix_modul e.tricky_func_f actory_dict[random.choice(r ange(4))](time.time()). y

for
a = my_infix_module .tricky_func_fa ctory_dict[random.choice(r ange(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__.na me -- 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
Jul 18 '05 #14
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
da***@dalkescie ntific.com

Jul 18 '05 #15
On Wed, 29 Dec 2004 13:11:43 -0500, Steve Holden <st***@holdenwe b.com> wrote:
Mike Meyer wrote:
be************@ lycos.com 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_CUS TOM_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.chai n. 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.

Associativit y 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
Jul 18 '05 #16
On Thu, 30 Dec 2004 03:37:38 GMT, Andrew Dalke <da***@dalkesci entific.com> 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__('t ime').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
Jul 18 '05 #17
On Thu, 30 Dec 2004 03:55:12 GMT, bo**@oz.net (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
Jul 18 '05 #18
On Thu, 30 Dec 2004 04:46:25 GMT, bo**@oz.net (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
Jul 18 '05 #19
Bengt Richter wrote:
On Wed, 29 Dec 2004 13:11:43 -0500, Steve Holden <st***@holdenwe b.com> 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_CUS TOM_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.chai n. 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
Jul 18 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
5022
by: NickBlooruk | last post by:
Hello, I have successfully linked a Lotus Notes server to our SQL Server database using an ODBC connection. This works fine when wanting to select records eg openquery(LOTUSNOTES2, 'select * from Person' ) The problem I have is when I try to update the record I get an error eg update openquery(LOTUSNOTES, 'select * from Person where
3
1809
by: Jim Cobban | last post by:
I have a set of web pages that are organized in pairs. One of each pair contains a graphic and the other is an extended description of the graphic. I am trying to set it up that selecting a single hyperlink causes the correct pair of web pages to be loaded into two windows. My current approach is to specify an onload action in the <BODY> tag of one of the pages that requests that the corresponding description page be loaded into the...
9
2040
by: bojan.pikl | last post by:
Hi, I am making a simple calendar. I would like to have the ability of notes. I was thinking of using this kind of notes.xml file. I am not sure how to operate with nodes. I just need to access something like SelectNode("/NOTES/y"+Year+"/m"+Month+"/d"+Day); (I'd get /NOTES/y2006/m5/d18) and than I'd read what is in there. Can anyone help please? <NOTES> <y2006> <m4> <DAYS>1,2,13</DAYS>
2
11849
by: charliej2001 | last post by:
Hi all I'm trying to set up an Access database that will be able to import contact information from the lotus notes 6.5 Address book. The idea is that the code runs from access to import all of the contacts, using COM. I've written the following vba code so far to import the contacts
1
13052
by: Joe | last post by:
HI Has anyone been able to work with lotus notes automation classes??? Can you post sample code of how to use these classes. I have setup in VB but I am not able to port to C# This is what I have so far - I cannot create a session and not sure how to setup From/Subject
4
9989
by: navyliu | last post by:
I want send Lotus Notes Email automatic in my Application.I googled this topic but I can't find the solution. Does anyone have ever use this function?Can you give me some advice? Thanks a lot!
4
9726
by: Bob Alston | last post by:
I am trying to access data in a Lotus Notes database, from Access. The Notes database is release R5. I installed NotesSQL 8.x and have it working. However it chokes on one of the tables and references problems with the dates. If I create a query, without these dozen or so dates, I can access all the data. However I am guessing that most of the dates are correct and only some are bad.
0
9584
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10583
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10337
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10323
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
7622
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6854
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5525
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
3822
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2995
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.