473,396 Members | 1,935 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

PEP 318

Hi

I have read some mail on the dev mailing list about PEP 318 and find the new
Syntax really ugly.

def foo[staticmethode](x, y): pass

I call this foo(1, 2), this isn't really intuitive to me!

Also I don't like the brackets.

def foo(x, y)[staticmethode]: pass

are better but still I used to see [] as list or access operator and the
don't? The original Syntax looks much cleaner to me.

def foo(x, y) as staticmethode: pass

Define foo with arguments x and y as staticmethode.

Is Python now C++? Mabe I miss something why this syntax is wrong.

regards

Marco
Jul 18 '05
68 4269
Ville Vainio <vi***@spammers.com> wrote in message news:<du****************@lehtori.cc.tut.fi>...
>> "Skip" == Skip Montanaro <sk**@pobox.com> writes:


Skip> It will probably be a BDFL pronouncement. After all, that's
Skip> why he's the

Of course it will - still, that didn't stop us from voting before :-).


Ick! Having passed through PEP 308, I just prefer directly agree with Guido's
decision without any votation at all ;)

Michele Simionato
Jul 18 '05 #51
David MacQuigg <dm*@gain.com> writes:
When you say "accessing" globals, we need to distinguish between
"referencing" and "setting".
Actually, I think that "referencing" works fine as it is. The problem
is that "setting" (at the moment) can either be "creating a new
binding" or "rebinding an existing name". Now, we have a way of
disambiguating this in the case of globals (the "global" keyword), but
there is no way of doing it for generally nested scopes. (Remember
that the "globals" keyword was introduced before nested scopes, so
(essentially) all possibilities were covered by it at the time it was
invented.)

But, yes, the problem is that we have one and the same syntax for
binding and re-binding.
I'm not feeling much need to set variables other than local or
global,


I think it is important to be able to rebind the currently visible
binding of any name, without having to know or care whether that
binding, is local, nested, or global (or even builtin, maybe)
.... while at the same time being able to create a new local binding,
without knowing or caring whether doing so shadows some other binding
to that same name.

All this can be achieved by the simple expedient of distinguishing
binding and re-binding. (Though I have no truly convincing suggestion
of how this distinction should be spelt in Python.)
If anyone cares to see a "gory details" explanation of binding vs
rebinding, read on ... otherwise I recommend you stop here :-)

================================================== ==================

For example, in the Lisp family of languages, new bindings (new
scopes) are introduced by function parameters and by "let" forms,
while _re_-bindings are performed by some sort of "set" forms.
Here I show the values bound to the names "a", "b" and "c" as the code
shown on the left is being executed.
a b c

(let ((a "a0") a0 New binding of "a"
(b "b0") a0 b0 New binding of "b"
(c "c0")) a0 b0 c0 New binding of "c"
(setq a "a1") a1 b0 c0 Rebinding "a"
(setq b "b1") a1 b1 c0 Rebinding "b"
(setq c "c1") a1 b1 c1 Rebinding "c"
(defun foo (a) Not executed until foo is called
(setq a "a2") ^
(setq b "b2") |
(setq c "c2") |
(let ((b "b3")) |
(setq a "a4") |
(setq b "b4") |
(setq c "c4")) |
(setq a "a5") |
(setq b "b5") V
(setq c "c5")) Not executed until foo is called
(setq a "a6") a6 b1 c1 Rebinding "a"
(setq b "b6") a6 b6 c1 Rebinding "b"
(setq c "c6")) a6 b6 c6 Rebinding "c"

Now, a call to "foo" such as this

(foo "aa")

runs in the lexical environment established above. Let's copy 'n'
paste the source code of foo, and inspect the bindings as the function
is executed. The outer bindings of the names "a", "b" and "c" are in
the state they were left in, at the time "foo" was defined, as shown
above.

Note that now we shadow outer bindings by creating inner bindings to
the same name (in which case two values are listed under a single name
- only the inner binding (the value shown on the right) is visible in
the program).

a b c

a6 b6 c6 Lexically visible bindings
(defun foo (a) a6 aa b6 c6 Shadow outer "a" with new binding
(setq a "a2") a6 a2 b6 c6 Rebind inner "a"
(setq b "b2") a6 a2 b2 c6 Rebind outer "b"
(setq c "c2") a6 a2 b2 c6 Rebind outer "c"
(let ((b "b3")) a6 a2 b2 b3 c6 Shadow outer "b" with new binding
(setq a "a4") a6 a4 b2 b3 c6 Rebind inner "a"
(setq b "b4") a6 a4 b2 b4 c6 Rebind inner "b"
(setq c "c4")) a6 a4 b2 b4 c4 Rebind outer "c"
a6 a4 b2 c4 Inner "b" goes out of scope
(setq a "a5") a6 a5 b5 c4 Rebind inner "a"
(setq b "b5") a6 a5 b5 c4 Rebind "b"
(setq c "c5")) a6 a5 b5 c5 Rebind "c"
a6 b5 c5 Inner "a" goes out of scope

In Python, both "let" and "setq" are spelt "=". However, in the case
of a global binding "(setq x y)" can be spelt "global x; x = y".

"let" and "setq" give us a way to express whether we want to rebind an
existing binding, or to create a new one.
Jul 18 '05 #52
Stephen Horne wrote:
On 22 Mar 2004 16:43:18 -0800, Paul Rubin
<http://ph****@NOSPAM.invalid> wrote:
DH <no@sp.am> writes:
Possible future Python example that uses "as" differently:

def foo(x as int, y as float) as int:
"this function returns an integer, and takes an int & float params"


I think I'd rather use colons for that, like Pascal does, e.g.

def foo:int (x: int, y: float)

hmm, the foo:int doesn't look too good.


In Ada, the type of a function return value is specified using an
explicit keyword ('returns' IIRC). I don't see the need for a unique
keyword just for that, but how about...

def foo (x: int, y: float) return int [decorators] :
def foo (x: int, y: float) yield int [decorators] :

I like :
def foo(x=42:int, y=3.14:float) [return(string)]:
def foo[return(string)](x=42:int, y=3.14:float):

looks strange to me. Its very unreadable. Its maybe the first time I really
disagree with a Idea of Guido. :-)

Jul 18 '05 #53
Joe Mason <jo*@notcharles.ca> wrote:
In article <89**************************@posting.google.com >, Eric wrote:
Joe Mason <jo*@notcharles.ca> wrote in message
news:<sl****************@gate.notcharles.ca>...
(The crux of the flamewar is that Condorcet tends to elect
"compromise candidates" who are few peoples' favourite but palatable to
most, while IRV is more likely to elect people that are the first choice
of a large block but hated by others. Which is preferable is a matter
of philosophy.)

<snip>
I cannot see how IRV and a Condorcet method would differ should a
certain candidate receive a large block of first place votes. For if a
certain Candidate is the first choice of a large block, it has a
distinct advantage in both IRV and Condorcet over all the other
candidates, but will not necessarily be the winner in either.


I think the contentious scenario was two large opposed blocks and a
small centrist block (C):

[redid the ballots to put them in a form accepted by online calculators]

49:A>C>B
48:B>C>A
3:C

In Condorcet, we get:
[snip]
So C is the winner. But, say the IRV proponents, only 3% of the
population actually want C to win!


Yes, I understand this is the claim that some IRV proponents would make.
However, no such definitive statement can honestly be asserted based on
those ballots. With most (if not all) ranked ballot methods (including
Condorcet and IRV), if a voter truly does not want a Candidate to win,
the way the indicate that is by leaving that Candidate unranked.

In this case, the A & B voters did not leave C unranked. Both groups
clearly stated that they preferred C to their primary opponent.

What we do not know, because neither IRV nor Condorcet collects the
strength of the preference (there are inherent problems with doing such
a thing which is beyond the scope of this message), is how strong the
preference is for the A & B voters for C rather then their primary
opponent.

For example, it could be that:
(The numbers in parenthesis indicate the strength of how much the
candidates are liked on a linear 0 - 100 scale)

49 A(100) > C(99) > B(0)
48 B(100) > C(99) > A(0)
3: C(100)

Should this be true, one would be hard pressed to develop a credible and
compelling argument that C should not be the winner.

However, it is also possible that:

49 A(100) > C(1) > B(0)
48 B(100) > C(1) > A(0)
3: C(100)

In which case, an argument can be made that C should not be the winner.

But, like I stated, neither IRV nor Condorcet collect such information,
so, what is the fairest way to deal with this?

Both IRV and Condorcet both assume that your top choice has a strength
of 100. However, they differ greatly in the assumptions made about lower
preferences.

With IRV, if your top choice is eliminated, your second choice is
automatically promoted to a strength of 100, regardless of how you
actually feel about that candidate. For example, say a voter had voted
(I've included theoretical preference strengths):

A(100) > B(1) > C(0)

but that A was eliminated. IRV recasts their vote as:

B(100) > C(0)

A Condorcet method assumes that the strengths of the preferences should
be distributed evenly among the ranked candidates. I find this
assumption to be far more compelling in the general case because it is
simply not believable that all the A & B voters in any genuine situation
would have the exact same feelings towards the other candidates.
Condorcet makes assumptions about the average feeling towards the other
candidates.

It is also interesting to note that nearly every other ranked ballot
method will also select C as the winner. IRV seems to stand alone in the
assertion that the winner should be someone other then C.

Based on:
http://cec.wustl.edu/~rhl1/rbvote/calc.html
http://condorcet.ericgorr.net/
http://www.duniho.com/remote-mamcalc.php
Anyway, the real question in this forum is whether Condorcet is a good
method for voting on a PEP.


If you would like to see how Condorcet and IRV behave with in genuine
ranked ballot elections, you can check out:

http://ericgorr.net/library/tiki-ind...BallotArchives

If anyone is aware of other places where ranked ballots from real
elections can be collected, let me know. I am working on collecting the
ranked ballots for the uk.* USENET hierarchy votes.


Jul 18 '05 #54
In article <1g****************************@verizon.net>, Eric wrote:
Yes, I understand this is the claim that some IRV proponents would make.
However, no such definitive statement can honestly be asserted based on
those ballots. With most (if not all) ranked ballot methods (including
Condorcet and IRV), if a voter truly does not want a Candidate to win,
the way the indicate that is by leaving that Candidate unranked.

In this case, the A & B voters did not leave C unranked. Both groups
clearly stated that they preferred C to their primary opponent.

What we do not know, because neither IRV nor Condorcet collects the
strength of the preference (there are inherent problems with doing such
a thing which is beyond the scope of this message), is how strong the
preference is for the A & B voters for C rather then their primary
opponent.
Well, not too much beyond: the inherent problem that I know is that
there's no incentive to put anything other than 100 or 0 to maximize the
strength of their vote. (After all, if you prefer A to C by 100 to 99,
but putting that you prefer it by 100 to 1 will get A elected, why not
do it? Lack of perfect information makes this kind of strategic voting
dangerous, but that doesn't mean people won't try it, and that
destabilizes elections.)
For example, it could be that:
(The numbers in parenthesis indicate the strength of how much the
candidates are liked on a linear 0 - 100 scale)

49 A(100) > C(99) > B(0)
48 B(100) > C(99) > A(0)
3: C(100)

Should this be true, one would be hard pressed to develop a credible and
compelling argument that C should not be the winner.

However, it is also possible that:

49 A(100) > C(1) > B(0)
48 B(100) > C(1) > A(0)
3: C(100)

In which case, an argument can be made that C should not be the winner.

But, like I stated, neither IRV nor Condorcet collect such information,
so, what is the fairest way to deal with this?
One interesting approach was brought up on the elections list just
before I stopped reading it. (Wait, don't I recognize your name from
there? You'd be more familiar with it than I, but I'll bring it up
anyway, on the assumption that there are other interested readers out
there.)

Add an implicit "none" candidate to separate rankings of actual
preferences from least of the evils. Your first case becomes "A > C >
none > B", and the second (probably) "A > none > C > B". So in the
latter case, the voter is saying that they prefer C to B, but only if
forced to choose between them due to overwhelming preference by the rest
of the electorate.

I'd be grateful if you can point me to a thorough analysis of this idea,
since it sounds reasonable to me but I don't really have the background
to evaluate it.
With IRV, if your top choice is eliminated, your second choice is
automatically promoted to a strength of 100, regardless of how you
actually feel about that candidate. For example, say a voter had voted
(I've included theoretical preference strengths):


Ah, thanks for pointing that out. I knew it sounded a little fishy.

(So much nicer to have nobody from the other side cluttering up the
debate...)

Joe
Jul 18 '05 #55
[Stephen Horne]:
Symbols (and worse, odd combinations of symbols where it's hard to
tell which symbols are part of the same syntax rule and which are not)
that you've not seen before tend not to suggest where in the manual to
look.
[David MacQuigg]:
We need a single unique symbol, one that doesn't conflict with
existing syntax, and has no special meaning itself. By using this
symbol for extensions of *many* statements, we minimize the amount of
new words or syntax users have to learn.
[Stephen Horne]:
So each statement will only ever be extended once, and for one
purpose?
[David MacQuigg]:
Using a symbol to introduce an extension doesn't mean we can't add
more extensions later. If we extend the def statement now with
$(staticmethod), that does not mean we can't later add $(accepts(int,
int), returns(float)) If the concern is flexibility for future
extensions, I would think we should *avoid* keywords like 'as' which
tend to *limit* the options. Note: The keywords in the $(...) phrase
are keywords *only* within this context, and do not limit the
extension as a whole. Within this limited context, we can be as
descriptive as we want with each keyword. A quick review of the
discussion on PEP 318 shows quite a collection already (staticmethod,
classmethod, onexit, singleton, accepts, returns, generator, ...).

[Stephen Horne]:If 'as' is too generic, then what about 'decorators'. That clearly
states what follows and can easily be looked up, making the 'RTFM'
attitude justifiable.
[David MacQuigg]:"Decorators" is clear as to its meaning, but a little too long,
especially if it causes statments with multiple decorators to run over
one line. It also limits the syntax to this one statement. You would
not want to extend the syntax of a print statement, for example, with
decorators=(separator = ' ', terminator = '\n').
[Stephen Horne]:If it's a secondary syntax, learned late and rarely used, then a long,
explicit keyword is just what is needed. You can look it up, of
course, but it is far better for readability if you don't need to - if
the explicit keyword is itself a sufficient reminder.
[David MacQuigg]:
The place for specific keywords is *inside* the general extension
syntax. There we have no restrictions on how specific we can get.

[Stephen Horne]:After all, it's
not just newbies that we should worry about - what about people like
me, who use several languages and sometimes go months without using
Python at all?
[David MacQuigg]:
Our goals are the same. My clients are some of the best IC designers
in the world, but they don't have time to learn another computer
language. What I can't pack into a two-day course on Python, I want
to "encapsulate" in a way that will not cause confusion later. I
expect they will learn the basic syntax on most of the Python
statements, but not the extensions. My "common-symbol-for-a
statement-extension" proposal is a way to encapsulate complexity.
Even if users never learn what is a 'generator', when they see that
word as part of a common extension syntax on a def statement, they
will not be discouraged from reading the def as they would a normal
function.

I think my recent experience in learning Python is typical of what we
can expect from IC designers. I was put off by statements like
"lambda", "yield", "staticmethod", even though from a users view, they
are not fundamentally different than the basic statements. Instead of
making lamda functions look like something new and wierdly different,
and mystifying the discussion with references to lambda calculus, it
would have been much better to use the standard function syntax and
substitute a "modified syntax" symbol for the function name.
Unglamorous, but very practical. The explanation would take about two
sentences, and a simple example of its use would be about a half-page.

I have high hopes for Python. If it continues to evolve in the right
direction, I can see it becoming the ultimate computer language for
non-programmer technical professionals. I've looked also at Ruby, and
I see that as the second most likely to become the ultimate language.
With a five-year hindsight advantage over Python, it has some
syntactic benefits, but it just doesn't have yet the critical mass of
libraries and general support enjoyed by Python and Perl.

[Stephen Horne]:As for the print statement, I wouldn't use a decorating approach at
all. And neither did you, for that matter - what you described could
not be implemented using decorator functions.
[David MacQuigg]:
I think I'm using the word 'decorator' in a more generic sense -
anything that 'decorates' or 'adds to' the basic syntax of a
statement.

[Stephen Horne]:What I might use is something like...

pragma printoptions ( separator = ' ', terminator = '\n' ) :
print "whatever"
print "something else"

...as a general way of providing standard-behaviour-overriding flags
for built-ins.
[David MacQuigg]:
I like this. It keeps the basic syntax of the print statement clean.
It avoids a lot of typing in situations where there is a repetition of
the same 'decoration' on many statemtents. The main drawback I see is
that in many situations, the modifcation is 'one time only'. Then we
have *three* statements instead of one. ( We need a statement to
restore the default printoptions.)

Using the "common-symbol-for-a statement-extension" syntax, we could
modify multiple statements without too much clutter using something
like:

opts = printoptions( separator = ' ', terminator = '\n' )
print @(opts) "whatever"
print @(opts) "something else"

[Stephen Horne]:Except that I don't see this as a real problem. Print works well as a
quick way to get results out of short scripts, where perfect
formatting of those results is unimportant. In more sophisticated
programs, other I/O mechanisms are better suited to the job.
[David MacQuigg]:

sys.stdout.write('%s %s %s\n' % (x, y, z) )

is enough of an inconvenience that many users are pushing for
something more. And when each extension is added, like 'print >> ...'
there are howls of protest from those who see it as a wart. Wouldn't
it be better if we introduce just one 'wart', a new symbol, that can
be used to solve this and many other problems. >> is a wart only
because it is unique to this one situation. If we use a syntax that
solves many similar problems, it becomes a feature, not a wart.

[Stephen Horne]:Not really. What happens when there are two different ways of
modifying the same syntax? When the first one was defined with no
awareness that another kind of modification might be needed later?


[David MacQuigg]:I guess I'll need an example here. Seems like the potential for
future incompatibilities is *greater* if the syntax itself has
"special meaning" ( e.g. "decorators" instead of [] ).


[Stephen Horne]:If a statement has a 'decorators' extension syntax, it can always add
a 'widget' or 'blodget' extension syntax later, being clear to both
the parser and the reader.
[David MacQuigg]:
So to make the example more concrete, I assume you would do something
like:

def func1( x, y, z ) decorators(staticmethod), blodgett(gradoo):

instead of:

def func1( x, y, z ) [staticmethod, gradoo]:

I think I'm missing something.

[Stephen Horne]:Contrast the case with a single extension-denoting symbol - '$'
perhaps. If it gets re-used for several extensions to the same
statement, you get the real possibility that the only way to tell the
different extensions apart is the ordering. Which, at the very least,
means a far greater probability of having to reread the documentation
to figure out what something means - ie bad readability.


[David MacQuigg]:
I would expect the def statement to grow the most number of extensions
[staticmethod, accepts(int, int), ...]. Even with dozen or more,
surely we can name them distinctly.

Hey - I appreciate your time in giving these issues some real thought.

-- Dave

Jul 18 '05 #56
Joe Mason <jo*@notcharles.ca> wrote:
One interesting approach was brought up on the elections list just
before I stopped reading it. (Wait, don't I recognize your name from
there? You'd be more familiar with it than I, but I'll bring it up
anyway, on the assumption that there are other interested readers out
there.)

Add an implicit "none" candidate to separate rankings of actual
preferences from least of the evils. Your first case becomes "A > C >
none > B", and the second (probably) "A > none > C > B". So in the
latter case, the voter is saying that they prefer C to B, but only if
forced to choose between them due to overwhelming preference by the rest
of the electorate.

I'd be grateful if you can point me to a thorough analysis of this idea,
since it sounds reasonable to me but I don't really have the background
to evaluate it.
You can find the full archives at:

http://lists.electorama.com/pipermai...lectorama.com/

I used the grep expression:
[\s]*none[\s]*>


to find various messages related to it.

It does seem to be an interesting idea and one that I was unfamiliar
with...I have not investigated it fully.

Off the top of my head, the only inherent problem with it that I see is
that what happens if 'NONE' turns out to be the Condorcet Winner?

An election is about finding a winner, providing for a result where this
would not occur seems problematic unless one is using a Condorcet method
where a strict (but not necessarily unique) ordering of the candidates
can be found, in which case one can just select the #2 person.

One such method that I am aware of is MAM
(http://www.alumni.caltech.edu/~seppley/).

Jul 18 '05 #57
In article <pr********************************@4ax.com>, David MacQuigg wrote:
descriptive as we want with each keyword. A quick review of the
discussion on PEP 318 shows quite a collection already (staticmethod,
classmethod, onexit, singleton, accepts, returns, generator, ...).


Those are identifiers, not keywords. They are the names of functions.

Joe
Jul 18 '05 #58
In article <1g****************************@verizon.net>, Eric wrote:
Off the top of my head, the only inherent problem with it that I see is
that what happens if 'NONE' turns out to be the Condorcet Winner?


Then the electorate has expressed its sincere opinion that no government
at all is better than any of the candidates. Government should be
immediately dissolved and anarchy instituted.

I have friends who would be delighted.

It just occured to me that this is the exact case we have for PEP's, but
with NONE as an explicit option.

Joe
Jul 18 '05 #59
On Thu, 25 Mar 2004 13:48:24 -0700, David MacQuigg <dm*@gain.com>
wrote:
[David MacQuigg]:
Using a symbol to introduce an extension doesn't mean we can't add
more extensions later. If we extend the def statement now with
$(staticmethod)
Ah - I see what you mean.

I'm not sure I'm convinced, but I get how this has better
compatibility (the name need not be a keyword or pseudo-keyword, for
instance, and cannot conflict with user identifiers).
[Stephen Horne]:
What I might use is something like...

pragma printoptions ( separator = ' ', terminator = '\n' ) :
print "whatever"
print "something else"

...as a general way of providing standard-behaviour-overriding flags
for built-ins.
[David MacQuigg]:
I like this. It keeps the basic syntax of the print statement clean.
It avoids a lot of typing in situations where there is a repetition of
the same 'decoration' on many statemtents. The main drawback I see is
that in many situations, the modifcation is 'one time only'. Then we
have *three* statements instead of one. ( We need a statement to
restore the default printoptions.)


No, we need two statements. There is no need to restore the default
printoptions - only to dedent out of the block where the non-default
printoptions are set. The implementation would have printoptions in a
stack structure, so the most recent override can always be easily
referenced.

The two-line format for isolated prints needing non-default options
isn't too bad as it would be a struggle to keep such print statements
on one line in practical cases anyway.

The biggest problem would be the case where there are prints dotted
throughout the code which all use the same nondefault options. And
even then, you could probably use something like...

pragma printoptions ( separator = ' ', terminator = '\n' ) :
main_program_call ()
Using the "common-symbol-for-a statement-extension" syntax, we could
modify multiple statements without too much clutter using something
like:

opts = printoptions( separator = ' ', terminator = '\n' )
print @(opts) "whatever"
print @(opts) "something else"
OK - this certainly has advantages. But it assumes that the only way
to extend a print statement would be to accept some kind of attributes
from a specified object.

If you're really doing named extensions, that should be...

opts = printoptions( separator = ' ', terminator = '\n' )
print @(printoptions: opts) "whatever"

Otherwise, your standard extensions symbol isn't standard - it is used
to do different things in different contexts, as its use to apply
decorators in def is fundamentally different to its use to apply
printoptions in print.

Alternately, instead of allowing your symbol to handle any new
extension syntax, it could just handle one syntax - applying
nonstandard options. In this case, the decorators example might become
something like...

def name (args) @{ "decorators" : [deco1, deco2, deco3]} :
pass

Or, for convenience...

opts = { "decorators" : [deco1, deco2, deco3]}

def name (args) @opts :
pass

Actually, I quite like this. I suspect that pretty much any extension
to a statement could be handled using a set of named options stored in
a dictionary.

[David MacQuigg]:
I guess I'll need an example here. Seems like the potential for
future incompatibilities is *greater* if the syntax itself has
"special meaning" ( e.g. "decorators" instead of [] ).
[Stephen Horne]:
If a statement has a 'decorators' extension syntax, it can always add
a 'widget' or 'blodget' extension syntax later, being clear to both
the parser and the reader.
[David MacQuigg]:
So to make the example more concrete, I assume you would do something
like:

def func1( x, y, z ) decorators(staticmethod), blodgett(gradoo):

instead of:

def func1( x, y, z ) [staticmethod, gradoo]:


No, if 'gradoo' is a kind of decorator I'd do something like...

def func1( x, y, z ) decorators(staticmethod, gradoo) :

And you'd presumably do something like...

def func1( x, y, z ) $(decorators: staticmethod, gradoo) :

But I thought you were suggesting something like...

def func1( x, y, z ) $ staticmethod, gradoo :

Looking back I think I just missed where you said your standard symbol
syntax would also name the extension. Then, taking the paragraph...
[David MacQuigg]:I guess I'll need an example here. Seems like the potential for
future incompatibilities is *greater* if the syntax itself has
"special meaning" ( e.g. "decorators" instead of [] ).


I was thrown by the "I guess I'll need an example here" with no
apparant example given, and by the "... if the syntax itself has
"special meaning"", which I took to mean you thought I shouldn't have
a name (ie shouldn't specify the special meaning) though now I see
that your suggestion names the extension too.

I'm still scratching my head a little, but at least now I know that I
was confused ;-)
--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
Jul 18 '05 #60
Joe Mason <jo*@notcharles.ca> wrote:
In article <1g****************************@verizon.net>, Eric wrote:
Off the top of my head, the only inherent problem with it that I see is
that what happens if 'NONE' turns out to be the Condorcet Winner?


Then the electorate has expressed its sincere opinion that no government
at all is better than any of the candidates. Government should be
immediately dissolved and anarchy instituted.

I have friends who would be delighted.

It just occured to me that this is the exact case we have for PEP's, but
with NONE as an explicit option.


Seems reasonable to me when taking no action is a reasonable option.

Jul 18 '05 #61
On Thu, 25 Mar 2004 00:24:34 GMT, Joe Mason <jo*@notcharles.ca> wrote:
In article <7n********************************@4ax.com>, David MacQuigg wrote:
By "modified syntax" I mean an extension of the current standard
syntax, e.g. the "decorators" we are now considering adding to the
current standard function definition syntax, or the extra "arguments"
we were discussing for the print statement.


Why is the current standard priveleged? A few years down the road, half
of the basic functionality of the language will have special symbols in
front of it, just because it was proposed after an arbitrary date. The
symbol wouldn't tell anything about the features it's attached to except
the relatively uninteresting fact of when they were added to the
language.


The key distinction is "basic" syntax vs "extensions". Every language
has to make tradeoffs - doing everything possible and satisfying every
special need vs. keeping things simple but more laborious for advanced
users. Things generally start simple, then as experience accumulates,
more stuff gets added. Thus the correlation with date you have
noticed.

My guess is that Python has maybe a dozen or so significant
"extensions" still to be added to the basic syntax. Even if it is
"half the functionality" still to come, as you envision, it won't be
the basic half, which is already in place.

Interestingly, my argument for a consistent extension syntax is
*stronger* the more numerous we assume these extensions will be.
Imagine a hundred new extensions, with mystifying names like 'lambda',
or 'staticmethod', each with a different syntax, all woven into the
basic syntax of the language. This would be a nightmare for new users
and those who can't spend a lot of time staying proficient.

Someone asked me in another discussion to name one feature that would
justify adding a symbol to the language. My answer was - I can't
imagine any single new feature that would be worth the cost of adding
a symbol. It only makes sense if the symbol is used in enough places
that it acquires a benefit for non-expert users - that benefit being a
clear signal that "This is an extension syntax. You can probably
understand this statement by ingoring the extension. You don't have
to learn it in your first use of the language."

With a good extension syntax, the tradeoffs will be easier. We can
satisfy more advanced requests, while not burdening the basic user.

"Second class" has negative connotations. A better description would


Yes, I used it deliberately. Singling out syntax as non-basic makes it
second class. What if you predict wrong? What if it catches on like
wildfire and gets taught in Day 2 of every class? Now your symbol has
no meaning at all, because it's part of what everybody considers basic.


We have to assume that the developers, guided by our wonderful
discussions, will make the right choices as to what is basic and what
is not. These decisions are made all the time in setting up defaults
for a module, chosing the most needed options in a print statement,
etc.

If it turns out that static methods become more popular than basic
methods, we have the same problem as chosing the wrong defaults in a
new module. The fact that it *might* happen is not a good argument
that we shouldn't even *try* to make a sensible choice. Presenting
all choices as being equal is *guaranteed* to be wrong.

Yep, I recall you bringing this up at the time and not convincing
anybody.


I'm glad Python development is guided by reason, not popular vote.
And I do appreciate your willingness to engage in reasoned discussion.

The key design goal is to *mimimize* the number of syntactic
variations we have to introduce as we extend the language. The
proposed @() syntax seems like it would work in *many* places, and it
always has the same general meaning -- "This is a modification of the
basic syntax you already understand." To learn the details of a


That's a meaning that's too general to be of any use. If the new syntax
is successful, it's no longer a modification, it's a basic syntax now,
so now @ means "this is either new, or not".
particular variation, you read the manual on the particular statement
where the variation occurs. @(staticmethod) - read about it under
"def". print @(...) - read the manual on 'print'.


People will recognize things they don't understand without an @ sign, by
virtue of not knowing what they are. @(staticmethod) won't tell me to
look under def any more than [staticmethod] will, and if I see something
I don't recognize near a print statement, I'll already know to read the
manual on 'print'.


It's not enough that the user recognize something he doesn't
understand and be able to find it in the docs. The number of these
things can be overwhelming. I remember the first time reading about
static methods, and not having enough time to really understand what
they were. The time was wasted, and had I needed to work with any
code having static methods, I would have given up.

The problem is that new users need guidance as to where they should
focus their efforts in learning the language. A properly-designed
nameless-function syntax would avoid the obfuscation of lambda
functions. Any user who understands basic functions would have no
difficulty with such an extension.

-- Dave

Jul 18 '05 #62
On Thu, 25 Mar 2004 22:26:01 GMT, Joe Mason <jo*@notcharles.ca> wrote:
In article <1g****************************@verizon.net>, Eric wrote:
Off the top of my head, the only inherent problem with it that I see is
that what happens if 'NONE' turns out to be the Condorcet Winner?


Then the electorate has expressed its sincere opinion that no government
at all is better than any of the candidates. Government should be
immediately dissolved and anarchy instituted.


Have you ever wondered why it is that anarchists have a symbol to unite
them? :)

Jul 18 '05 #63
[Stephen Horne]:
What I might use is something like...

pragma printoptions ( separator = ' ', terminator = '\n' ) :
print "whatever"
print "something else"

...as a general way of providing standard-behaviour-overriding flags
for built-ins.
[David MacQuigg]:
I like this. It keeps the basic syntax of the print statement clean.
It avoids a lot of typing in situations where there is a repetition of
the same 'decoration' on many statemtents. The main drawback I see is
that in many situations, the modifcation is 'one time only'. Then we
have *three* statements instead of one. ( We need a statement to
restore the default printoptions.) [Stephen Horne]:
No, we need two statements. There is no need to restore the default
printoptions - only to dedent out of the block where the non-default
printoptions are set. The implementation would have printoptions in a
stack structure, so the most recent override can always be easily
referenced.

The two-line format for isolated prints needing non-default options
isn't too bad as it would be a struggle to keep such print statements
on one line in practical cases anyway.

The biggest problem would be the case where there are prints dotted
throughout the code which all use the same nondefault options. And
even then, you could probably use something like...

pragma printoptions ( separator = ' ', terminator = '\n' ) :
main_program_call ()
[David MacQuigg]:
This last example takes care of the case where *every* print statement
needs the same options. I think what is more likely is having only
*some* print statements that need, for example, to be redirected to a
special file. Those statements are not likely to be neatly grouped,
so we will have to set a 'pragma' block on each one.

There may also be some objection to the fact that this use of
indentation (setting options) is inconsistent with every other use
(controlling program flow).
Using the "common-symbol-for-a statement-extension" syntax, we could
modify multiple statements without too much clutter using something
like:

opts = printoptions( separator = ' ', terminator = '\n' )
print @(opts) "whatever"
print @(opts) "something else"


OK - this certainly has advantages. But it assumes that the only way
to extend a print statement would be to accept some kind of attributes
from a specified object.

If you're really doing named extensions, that should be...

opts = printoptions( separator = ' ', terminator = '\n' )
print @(printoptions: opts) "whatever"

Otherwise, your standard extensions symbol isn't standard - it is used
to do different things in different contexts, as its use to apply
decorators in def is fundamentally different to its use to apply
printoptions in print.


The common concept is "syntax extension". This could be options in a
print statement ( print @opts ... ), decorators in a function def (
def f(x,y) @decs : ... ) or modifying the meaning of a return
statement in a generator ( @return ). With options and decorators we
have some additional commonality. In both these contexts, the @
symbol says "Look next for an object, or a tuple of objects meaningful
to this particular statement." In both cases we define that object
ourselves, and give it a name meaningful in our particular program.

squeeze = printoptions( separator = None )
noLF = printoptions( terminator = None )
print @squeeze x, y, z
....
print @noLF x, y, z

If either of these print statements is a "one-time-only", we could
stick the printoptions directly after the @ symbol. The token
following the @ symbol in a print statement is either a 'printoptions'
object, or just the keyword parameters used to construct such an
object. This dual syntax is used, for example in functions which can
accept a filename or a file object.
Alternately, instead of allowing your symbol to handle any new
extension syntax, it could just handle one syntax - applying
nonstandard options. In this case, the decorators example might become
something like...

def name (args) @{ "decorators" : [deco1, deco2, deco3]} :
pass

Or, for convenience...

opts = { "decorators" : [deco1, deco2, deco3]}

def name (args) @opts :
pass

Actually, I quite like this. I suspect that pretty much any extension
to a statement could be handled using a set of named options stored in
a dictionary.
It's even broader than that. Dictionaries or other special objects
could be associated with @ in certain statements. In others, like
using @ to introduce a nameless function, no special objects are
needed. We need not even put @ at the beginning of a keyword or
object to be modified. What if instead of 'yield' we used 'return@',
meaning "This is a normal return, except that execution will resume on
the next call, right here after the return." I'm not saying this has
any advantage over @return, just illustrating the flexibility in not
assigning any unecessary meaning or syntax to @.
I'm still scratching my head a little, but at least now I know that I
was confused ;-)


Aren't we all. It is fun, however, discussing ideas about the perfect
language. This is the best time to do it, while we are learning the
language. Later, we will forget the problems we had in learning. I've
already forgotten the hassle with 'self', but it is interesting to do
a Google search on "group:comp.lang.python insubject:self" 1080 hits
!! This is a problem which won't go away. Also one that could have
been solved with a special symbol, but if you want to get into that
discussion, I'll have to post under a different name. :>)

-- Dave

Jul 18 '05 #64
Stephen Horne wrote:
I would use the logic of 'preferring the return type at the end', and
perhaps cite Ada, Pascal, Modula 2, etc (Algol as well?) as examples
to follow. But then why do I have no problem with C, C++, Java, C# etc
where the type of the return value usually comes first?


I think, what makes
def foo[return(string)](x=42:int, y=3.14:float):
look so strange, is the fact that you have the function name, the
return type and after that the arguments

def [return (string)] foo(x=42:int, y=3.14:float):
looks more familar, if you concentrate on the 'foo'. But this style
seems to push the function's name into the middle of the declaration.

The fact that there's no problem with reading C, C++ etc comes from the
continuity of their declaration. you can read
void foo(int bar=42)
very fluently, and
def foo [return void] (bar=34:int)
not.

The problem is, that we are accustomated at having the function's name
right before the argumentlist, as it gets called
you don't write foo [x] = (32, 42) but x = foo(32, 42)

IMHO, if the function's name has to be right after the 'def', and 'def'
has to be the first command in a declaration, the return type has to
come last
Jul 18 '05 #65
DH
Christian wrote:
IMHO, if the function's name has to be right after the 'def', and 'def'
has to be the first command in a declaration, the return type has to
come last


I agree.

I think it is neat that function decorators may be used for specifying
argument types and the return types, but I don't think it should be THE
way to always do it, because it is pretty ugly. I still prefer
eventually adding an "as" keyword or some other different syntax from
the decorator syntax, like:

def foo(x as int, y as float) as string:
...

See: http://mail.python.org/pipermail/pyt...ry/042795.html

I know that is like Visual Basic, but it is readable and easier to
understand for novices. If you want to use x:int, y:float instead, you
might as well throw out the colon at the end of the def statement since
it defeats the purpose of it.
Jul 18 '05 #66
On Thu, 25 Mar 2004 00:24:34 GMT, Joe Mason <jo*@notcharles.ca> wrote:
Why is the current standard priveleged? A few years down the road, half
of the basic functionality of the language will have special symbols in
front of it, just because it was proposed after an arbitrary date. The
symbol wouldn't tell anything about the features it's attached to except
the relatively uninteresting fact of when they were added to the
language.

The only use I can see for such information is to mark features which
require a recent interpreter, and a single otherwise meaningless symbol
is a particulary ugly way to do it.


I largely agree, though there is one point worth making. This could be
seen as a 'trial feature' system. If the feature catches on and it
annoys people to use an 'extension' syntax, a non-extension syntax
could be added later. Thus features could be added in a standard way
without needing new syntax, kind of testing the waters.
--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
Jul 18 '05 #67
On Fri, 26 Mar 2004 13:55:04 -0600, DH <no@sp.am> wrote:
Christian wrote:
IMHO, if the function's name has to be right after the 'def', and 'def'
has to be the first command in a declaration, the return type has to
come last


I agree.

I think it is neat that function decorators may be used for specifying
argument types and the return types, but I don't think it should be THE
way to always do it, because it is pretty ugly.


It isn't really specifying anything. It is just validating, which we
can do already using normal code. Using decorators to validate
arguments/return types brings them to the front, thus making them more
useful as an example of self-documenting code, but while it's an
interesting application for decorators I don't think it should be
overemphasised.

Ensuring that a parameter has a specific type is often excessive in
Python - if another type supports the right methods in the right way,
it often makes sense to call the function with arguments of that type.
--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
Jul 18 '05 #68
On Fri, 26 Mar 2004 09:48:17 -0700, David MacQuigg <dm*@gain.com>
wrote:
There may also be some objection to the fact that this use of
indentation (setting options) is inconsistent with every other use
(controlling program flow).
I already gave my opinions on that issue elsewhere. First off, the
relative consistency in how Python uses blocks is a side-effect of an
unrelated principle, not a principle in itself - the 'right thing' can
still be to use block structure for other things. Secondly, Python
doesn't just use indented blocks purely to control program flow - it
is also used to define local contexts in the sense of local scopes
(class, def) so why not do the same, but with local options being the
local context?
This is the best time to do it, while we are learning the
language. Later, we will forget the problems we had in learning.


Actually, I've been using Python for about 7 years or so, on and off -
slightly longer than I've been using C++, and it's almost certainly my
record holder for the longest period of sustained more-or-less-regular
use (though sadly not for quantity). I first started with Python 1.4
on an iMac, as a result of a desperate search for languages I could
actually run on that thing.

To the extent that I'm still learning Python, I'll probably always
still be learning it ;-)
--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
Jul 18 '05 #69

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

Similar topics

3
by: William C. White | last post by:
Does anyone know of a way to use PHP /w Authorize.net AIM without using cURL? Our website is hosted on a shared drive and the webhost company doesn't installed additional software (such as cURL)...
2
by: Albert Ahtenberg | last post by:
Hello, I don't know if it is only me but I was sure that header("Location:url") redirects the browser instantly to URL, or at least stops the execution of the code. But appearantely it continues...
3
by: James | last post by:
Hi, I have a form with 2 fields. 'A' 'B' The user completes one of the fields and the form is submitted. On the results page I want to run a query, but this will change subject to which...
0
by: Ollivier Robert | last post by:
Hello, I'm trying to link PHP with Oracle 9.2.0/OCI8 with gcc 3.2.3 on a Solaris9 system. The link succeeds but everytime I try to run php, I get a SEGV from inside the libcnltsh.so library. ...
1
by: Richard Galli | last post by:
I want viewers to compare state laws on a single subject. Imagine a three-column table with a drop-down box on the top. A viewer selects a state from the list, and that state's text fills the...
4
by: Albert Ahtenberg | last post by:
Hello, I have two questions. 1. When the user presses the back button and returns to a form he filled the form is reseted. How do I leave there the values he inserted? 2. When the...
1
by: inderjit S Gabrie | last post by:
Hi all Here is the scenerio ...is it possibly to do this... i am getting valid course dates output on to a web which i have designed ....all is okay so far , look at the following web url ...
2
by: Jack | last post by:
Hi All, What is the PHP equivilent of Oracle bind variables in a SQL statement, e.g. select x from y where z=:parameter Which in asp/jsp would be followed by some statements to bind a value...
3
by: Sandwick | last post by:
I am trying to change the size of a drawing so they are all 3x3. the script below is what i was trying to use to cut it in half ... I get errors. I can display the normal picture but not the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
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,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.