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
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.
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. :-)
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.
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
[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
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/).
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
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
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
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.
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
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? :) [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
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
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.
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
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
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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)...
|
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...
|
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...
|
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.
...
|
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...
|
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...
|
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
...
|
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...
|
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...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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...
|
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
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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...
|
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,...
|
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,...
|
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...
| |