473,322 Members | 1,314 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,322 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 #1
68 4257


Marco> def foo(x, y)[staticmethode]: pass
... vs ...
Marco> def foo(x, y) as staticmethode: pass

Marco> Define foo with arguments x and y as staticmethode.

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

I believe the "as wrap1, wrap2, ..." form is one of the alternatives under
consideration, though current sentiment seems to be in favor of the
list-like syntax.

Python has a long history of borrowing good ideas from other languages. I'm
not aware that any of this is being borrowed from C++, no matter that it has
some syntactic similarities to stuff C++ does. Note in particular that the
construct is much more general than applying the currently available
staticmethod and classmethod builtins. The end result need not even be a
function or class (there has been some discussion about applying this
construct to classes, but it's not as obviously valuable). See recent
discussion in the python-dev archives for some other ideas.

Skip

Jul 18 '05 #2
"Marco Bubke" <ma***@bubke.de> wrote in message
news:c3*********@graf.cs.uni-magdeburg.de...
Hi

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


There doesn't seem to be a really beautiful
syntax for this. That's the reason it wasn't
in 2.2.

My personal opinion is that I'll take whatever
the core developers decide is best.

John Roth
Jul 18 '05 #3
Marco Bubke wrote:
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.


Personnally, I prefer the "as" syntax to the other proposed (and by a
large margin). However, I feel that it is making the language more
complex and I'm far from sure it's worth the effort. I've given some
Python courses, and the first reaction when showing a class with some
methods is something like "so I guess when the first parameter is not
named 'self' it makes a class method?". So I have to explain it's not
the case, etc.

If easing the creation of class methods is so important, I would prefer
a more radical approach with a end result that would be more intuitive
to newcomers:
- Give a warning for all methods with first parameter not named "self"
in next versions of Python.
- In a future major version of Python, 3 or 4, self becomes a keyword
and a first parameter named otherwise implies a class method (I
understand it could mean a lot of changes in code not using self).

Regards,

Nicolas
Jul 18 '05 #4
"Nicolas Fleury" <ni******@yahoo.com_removethe_> wrote in message
news:Xj******************@weber.videotron.net...
Marco Bubke wrote:
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.


Personnally, I prefer the "as" syntax to the other proposed (and by a
large margin). However, I feel that it is making the language more
complex and I'm far from sure it's worth the effort. I've given some
Python courses, and the first reaction when showing a class with some
methods is something like "so I guess when the first parameter is not
named 'self' it makes a class method?". So I have to explain it's not
the case, etc.

If easing the creation of class methods is so important, I would prefer
a more radical approach with a end result that would be more intuitive
to newcomers:
- Give a warning for all methods with first parameter not named "self"
in next versions of Python.
- In a future major version of Python, 3 or 4, self becomes a keyword
and a first parameter named otherwise implies a class method (I
understand it could mean a lot of changes in code not using self).

Regards,

Nicolas


I personally think that self not only should be a keyword,
it should not be among the parameters at all. However, I
seem to be in a distinct minority about that.

However, I think you've got class methods mixed up with
static methods. Class methods require the first parameter
to be the class (sometimes spelled klas for some reason),
while static methods are the ones that don't have either an
instance or a class as the first parameter.

John Roth
Jul 18 '05 #5
Nicolas Fleury <ni******@yahoo.com_removethe_> wrote...
Personnally, I prefer the "as" syntax to the other proposed (and by a
large margin). However, I feel that it is making the language more
complex and I'm far from sure it's worth the effort.


I'd +1 for the 'as' syntax too, it's more descriptive and feels
'pythonic' (much as the term disgusts me) in its verbosity.

Personally, I think for the meager benefit this new syntax brings, it
appears to be a rather large and incompatible waste of time. With the
exception of syntactic beauty, does this really add anything to
Python? It gives programmers two ways of doing something very basic
indeed. Both proposed syntaxes will inevitably break existing source
analysers, etc.

Even preferring the 'as' syntax, 'def foo(x) as bar' doesn't really
make that much sense to me. staticmethods are wrapper objects and much
better expressed as 'foo = staticmethod(foo)', where you at least know
some kind of layering or transformation is being applied to foo (if
there isn't, why is this person using the same variable name? etc).
With 'as', it suggests some kind of aliasing is taking place, or some
kind of different type of object creation, which isn't the case.

It's also very specific syntax, I'd have hoped big language changes
like this would be reserved for larger, more fundamental, and general
changes that everyone can find useful. Did I say I didn't think it's
worth it already? :)
David.
Jul 18 '05 #6
John Roth wrote:
I personally think that self not only should be a keyword,
it should not be among the parameters at all. However, I
seem to be in a distinct minority about that.
But how could that be changed/introduced?
However, I think you've got class methods mixed up with
static methods. Class methods require the first parameter
to be the class (sometimes spelled klas for some reason),
while static methods are the ones that don't have either an
instance or a class as the first parameter.


Ok, I wrote static method everywhere in my message and changed for class
method after reading the PEP... so my first idea was right;)

Regards,

Nicolas
Jul 18 '05 #7
>>>>> "David" == David M Wilson <dw***********@botanicus.net> writes:

David> Personally, I think for the meager benefit this new syntax
David> brings, it appears to be a rather large and incompatible
David> waste of time. With the exception of syntactic beauty, does
David> this really add anything to

The current foo=staticmethod(foo) makes the Python 'staticmethod' seem
like a hack. Many users of staticmethod won't even need to know that
wrapping takes place. It certainly discourages people from using the
feature in the first place.

And when did syntactic beauty stop mattering?

--
Ville Vainio http://tinyurl.com/2prnb
Jul 18 '05 #8
Ville Vainio <vi***@spammers.com> writes:
The current foo=staticmethod(foo) makes the Python 'staticmethod' seem
like a hack. Many users of staticmethod won't even need to know that
wrapping takes place. It certainly discourages people from using the
feature in the first place.

And when did syntactic beauty stop mattering?


"def foo() as staticmethod" certainly looks best to me aesthetically.
The syntax can be extended, i.e. "def foo() as generator" looks to me
to be a lot more explicit than "def foo()" followed by having the
compiler search the function body for a yield statement in order
to decide if it's a generator.
Jul 18 '05 #9
"John Roth" <ne********@jhrothjr.com> writes:
I personally think that self not only should be a keyword,
it should not be among the parameters at all. However, I
seem to be in a distinct minority about that.


The existence of C++ or Java coding guidelines which advocate the
universal use of this->member or the use of m_member for all member
data and function names, is (to me) evidence of the necessity of self.

Also, ask an average[*] C++ programmer whether the following functions
have the same type:

void A::foo(void);
void B::foo(void);

(where A and B are both classes).

In my experience[+], they will, typically, be adamant that the types
are identical. If they have been exposed to Python, then you have more
than a fair chance that they will understand that the types are, in
fact, different.

Python's explicit passing of self makes people understand what is
going on, much better ... and I think that is a very valuable thing.

[*] And we all know just how dangerous "average" C++ programmers are.

[+] You probably don't want to know why I have had ample opportunity
to ask this question, in real life.
Jul 18 '05 #10
Nicolas Fleury <ni******@yahoo.com_removethe_> writes:
I've given some Python courses, and the first reaction when showing
a class with some methods is something like "so I guess when the
first parameter is not named 'self' it makes a class method?".
Just as a point of information:

I teach Python courses ... hands-on interactive style ... class size =
12 ... I've given 8 of these so far ... I have _never_ had this
reaction. (80% of the students have previous C++ and/or Java
experience, and usually someone asks "How do I do class/static
methods?".)

Maybe the reason nobody believes this is because, fairly early on in
the treatment of classes, I point out that there is nothing special
about the name "self", but I usually ask the students what they make
of it, before offering any of my own comments.
If easing the creation of class methods is so important, I would
prefer a more radical approach with a end result that would be more
intuitive to newcomers:
While I agree that there is a lot to be said for Python being guided
by the principle of least surprise, I would argue against letting
Python be shaped by the expectations of people whose expectations have
been moulded by Java and C++, as those expectations are typically
fundamentally flawed, and certainly inappropriate to Python. (For
example, most (Java and C++ people, and hence generally most) people
expect there to be access control, and hundreds of getters and setters
all over the place. We do _not_ want this in Python. Etc., etc..
- Give a warning for all methods with first parameter not named "self"
in next versions of Python.
That would be acceptable ...
- In a future major version of Python, 3 or 4, self becomes a keyword
and a first parameter named otherwise implies a class method (I
understand it could mean a lot of changes in code not using self).


.... that would (IMHO) not.
Jul 18 '05 #11
Paul Rubin <http://ph****@NOSPAM.invalid> writes:
Ville Vainio <vi***@spammers.com> writes:
The current foo=staticmethod(foo) makes the Python 'staticmethod' seem
like a hack. Many users of staticmethod won't even need to know that
wrapping takes place. It certainly discourages people from using the
feature in the first place.

And when did syntactic beauty stop mattering?

Most importantly, the current style separates the unambiguous
information that the method is a static or class method from the "def"
which starts the method's definition, by far too much.
"def foo() as staticmethod" certainly looks best to me aesthetically.


My only slight reservation is the increased "keyword overloading". For
example ... "static" has something like 7 distinct meanings in C++ (at
last count), and I find that this has a detremental effect on
discussions with colleagues. I hope that Python will be able to avoid
such problems.
Jul 18 '05 #12
On Sun, 21 Mar 2004 17:53:11 +0100, Marco Bubke <ma***@bubke.de>
wrote:
are better but still I used to see [] as list


Surely it *is* a list - a list of modifier functions to apply to the
original function.

To me, the 'as' syntax is misleading. It implies that the syntax is
asserting a type, style or similar attribute of the function. That may
be the expected normal use, with 'staticmethod' etc, but my
understanding is that it is meant to be more general than that. You
can apply any translation or any sequence of translations that you
choose.

Not that I care either way, just being pointlessly pedantic really.
--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
Jul 18 '05 #13
Jacek Generowicz <ja**************@cern.ch> writes:
And when did syntactic beauty stop mattering?


Most importantly, the current style separates the unambiguous
information that the method is a static or class method from the "def"
which starts the method's definition, by far too much.


Oh, it's not that big a deal. Anyway, look at the situation with
generator functions. ;-)
Jul 18 '05 #14
On Sun, 21 Mar 2004 14:45:39 -0500, Nicolas Fleury
<ni******@yahoo.com_removethe_> wrote:
- Give a warning for all methods with first parameter not named "self"
in next versions of Python.
- In a future major version of Python, 3 or 4, self becomes a keyword
and a first parameter named otherwise implies a class method (I
understand it could mean a lot of changes in code not using self).


The main problem I have with that is that some people find typing
'self.' over and over in member functions pretty annoying. I have
quite recently voiced the opinion that because 'self' is just a
convention, that it can reasonably be abbreviated to become something
like 's' or 'm', so that 'm.' in Python code plays much the same role
as 'm_' in common use as a prefix for member variable names in C++.

As I said then, I'm not that bothered about 'self.' - keeping to the
well-known convention and the principle of least surprise is to me
well worth pressing a few more keys. But I may have to deal with a few
grumpy people if that suggestion turns out bad :-(

If a more radical change is needed, then I would say we need an
alternative to the 'def' keyword. It could be justified as 'def just
defines normal functions - we can define them as class members and we
have a convenient system for using them as if they were methods but
that doesn't mean they really are methods'. 'True' methods would then
be defined using a 'method' keyword, and within a method 'self' might
be a pseudo-keyword.

In Python 3000, 'def' for member functions might then be deprecated.

Very unlikely, though.
--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
Jul 18 '05 #15
On 21 Mar 2004 23:03:24 -0800, Paul Rubin
<http://ph****@NOSPAM.invalid> wrote:
The syntax can be extended, i.e. "def foo() as generator" looks to me
to be a lot more explicit than "def foo()" followed by having the
compiler search the function body for a yield statement in order
to decide if it's a generator.


Good point. Though to me, it isn't that it's a pain for the compiler
to search for the 'yield' - I don't care about the compilers pain. The
problem is that *I* have to look for the yield and might not notice
it.
--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
Jul 18 '05 #16
Stephen Horne <st***@ninereeds.fsnet.co.uk> writes:
Good point. Though to me, it isn't that it's a pain for the compiler
to search for the 'yield' - I don't care about the compilers pain. The
problem is that *I* have to look for the yield and might not notice it.


Well, yes. It wouldn't have occurred to me to care about the
compiler's pain ;-).
Jul 18 '05 #17
On 22 Mar 2004 11:11:26 +0100, Jacek Generowicz
<ja**************@cern.ch> wrote:
My only slight reservation is the increased "keyword overloading". For
example ... "static" has something like 7 distinct meanings in C++ (at
last count), and I find that this has a detremental effect on
discussions with colleagues. I hope that Python will be able to avoid
such problems.


Which is worse? Keyword overloading, or wierd pattern-of-symbols
overloading?

Personally, I'd hate to see nouns or verbs 'overloaded'. But why
shouldn't prepositions be used in a wide variety of contexts in
Python? They are in spoken languages, after all.
--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
Jul 18 '05 #18
On 22 Mar 2004 03:02:49 -0800, Paul Rubin
<http://ph****@NOSPAM.invalid> wrote:
Stephen Horne <st***@ninereeds.fsnet.co.uk> writes:
Good point. Though to me, it isn't that it's a pain for the compiler
to search for the 'yield' - I don't care about the compilers pain. The
problem is that *I* have to look for the yield and might not notice it.


Well, yes. It wouldn't have occurred to me to care about the
compiler's pain ;-).


We're such an unfeeling bunch, aren't we ;-)
--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
Jul 18 '05 #19
Stephen Horne wrote:
On Sun, 21 Mar 2004 17:53:11 +0100, Marco Bubke <ma***@bubke.de>
wrote:
are better but still I used to see [] as list


Surely it *is* a list - a list of modifier functions to apply to the
original function.


If it's a list, then just as surely a tuple should be allowed in its
place, as in every (?) other such case in Python that I can think of.
Would that be part of the proposal? (I haven't read the full PEP, sorry.)

(I know, "foolish consistency is the hobgoblin blah blah..." :-)

-Peter
Jul 18 '05 #20
Ville Vainio <vi***@spammers.com> wrote...
The current foo=staticmethod(foo) makes the Python 'staticmethod' seem
like a hack. Many users of staticmethod won't even need to know that
wrapping takes place.
I find myself in diametric opposition here. :)

Users (read: developers) /should/ know how staticmethod is working
under it's skin, that's (and hopefully no-one here disagrees) a bloody
good thing. The fact that defining a static method is a simple
assignment tells the developer a lot more about Python's internal
workings than extra syntax does. It's far more general, it's explicit,
and it's readable.

I can't see at all how it can be considered a hack.

If at some future date, staticmethod becomes intrinsicly linked to the
Python core in some magical way, then I can see an argument for extra
syntax, but as it stands, staticmethod is a wrapper, defining a
staticmethod is equivalent to "foo = staticmethod(foo)", and "def foo
as staticmethod" is in my books rather ambiguous.

It certainly discourages people from using the
feature in the first place.
Again, I can't see how.

And when did syntactic beauty stop mattering?


Don't get me wrong, I love lovely looking code, but I don't like code
that wears makeup, which is what this is. We can already do this via
another, simple, more descriptive means.
David.
Jul 18 '05 #21
"Jacek Generowicz" <ja**************@cern.ch> wrote in message
news:ty*************@pcepsft001.cern.ch...
Nicolas Fleury <ni******@yahoo.com_removethe_> writes:
I've given some Python courses, and the first reaction when showing
a class with some methods is something like "so I guess when the
first parameter is not named 'self' it makes a class method?".


Just as a point of information:

I teach Python courses ... hands-on interactive style ... class size =
12 ... I've given 8 of these so far ... I have _never_ had this
reaction. (80% of the students have previous C++ and/or Java
experience, and usually someone asks "How do I do class/static
methods?".)

Maybe the reason nobody believes this is because, fairly early on in
the treatment of classes, I point out that there is nothing special
about the name "self", but I usually ask the students what they make
of it, before offering any of my own comments.


Excellent class design! When I was doing classes, I found
one of the most important questions I could ask myself in
the after-the-class analysis was "what could I have said
earlier that would have dealt with this question / confusion?"
If easing the creation of class methods is so important, I would
prefer a more radical approach with a end result that would be more
intuitive to newcomers:


While I agree that there is a lot to be said for Python being guided
by the principle of least surprise, I would argue against letting
Python be shaped by the expectations of people whose expectations have
been moulded by Java and C++, as those expectations are typically
fundamentally flawed, and certainly inappropriate to Python. (For
example, most (Java and C++ people, and hence generally most) people
expect there to be access control, and hundreds of getters and setters
all over the place. We do _not_ want this in Python. Etc., etc..
- Give a warning for all methods with first parameter not named "self"
in next versions of Python.


That would be acceptable ...


Only if the intention is to move to making it a built-in. Otherwise there
really are people who use some other name than self (usually to save
keystrokes.)
- In a future major version of Python, 3 or 4, self becomes a keyword
and a first parameter named otherwise implies a class method (I
understand it could mean a lot of changes in code not using self).


... that would (IMHO) not.


John Roth
Jul 18 '05 #22

On 22-mrt-04, at 13:51, David M. Wilson wrote:
Ville Vainio <vi***@spammers.com> wrote...
The current foo=staticmethod(foo) makes the Python 'staticmethod' seem
like a hack. Many users of staticmethod won't even need to know that
wrapping takes place.


I find myself in diametric opposition here. :)

Users (read: developers) /should/ know how staticmethod is working
under it's skin, that's (and hopefully no-one here disagrees) a bloody
good thing. The fact that defining a static method is a simple
assignment tells the developer a lot more about Python's internal
workings than extra syntax does. It's far more general, it's explicit,
and it's readable.


It's only readable in very small examples, if you have functions that
are longer than 10 lines it is no longer obvious that the assigment has
anything to do with the function above.

To play devil's advocate, 'class Foo: pass' is also syntactic sugar,
having explicit calls to type also tells a developer more about the
inner workings of Python but that is not necessarily a good idea.

Ronald
--
X|support bv http://www.xsupport.nl/
T: +31 610271479 F: +31 204416173
Jul 18 '05 #23
"John Roth" <ne********@jhrothjr.com> writes:
"Jacek Generowicz" <ja**************@cern.ch> wrote in message
news:ty*************@pcepsft001.cern.ch...
Nicolas Fleury <ni******@yahoo.com_removethe_> writes:
I teach Python courses ...
[...]
fairly early on in the treatment of classes, I point out that
there is nothing special about the name "self", but I usually ask
the students what they make of it, before offering any of my own
comments.


Excellent class design! When I was doing classes, I found
one of the most important questions I could ask myself in
the after-the-class analysis was "what could I have said
earlier that would have dealt with this question / confusion?"


[...]
- Give a warning for all methods with first parameter not named "self"
in next versions of Python.


That would be acceptable ...


Only if the intention is to move to making it a built-in. Otherwise there
really are people who use some other name than self (usually to save
keystrokes.)


.... just after I say that there is nothing special about "self" (in my
Python courses), I plead that, even though you are allowed to use any
name you like, you should use "self", and nothing but "self", on the
grounds that this will ensure that other Python programmers (which
includes yourself at a later date) will immediately understand what
you are doing; while you are likely to cause lots of confusion if you
use anything other than "self". At this point I usually re-iterate
that clearly showing your intentions, is very much good Python
style. (If I'm feeling in "that sort of mood" I might even point out
that if you want to save keystrokes, then you know where you can find
Perl.)

If a warning such as Nicolas proposes were introduced, I hope that it
would be suppressable. If so, I suspect that it would be a very useful
feature. I think that making the name "self" obligatory would run very
much against some of the basic Python philosophies.
Jul 18 '05 #24
- Give a warning for all methods with first parameter not named "self"
in next versions of Python.
Jacek> That would be acceptable ...

I suggest you see if PyChecker already does this.
- In a future major version of Python, 3 or 4, self becomes a keyword
and a first parameter named otherwise implies a class method (I
understand it could mean a lot of changes in code not using self).


Jacek> ... that would (IMHO) not.

(I'm not picking on Jacek here. I just chose to reply to his post.)

Everybody seems to be fixated on how best to spell "make this function a
class or static method". If that was all we were interested in, something
more syntacically restrictive would be fine. That's not all PEP 318 allows
though. It proposes syntax (and eventually semantics) for a general
function decorator capability.

I almost wish Python didn't already have staticmethod() and classmethod()
builtins so people wouldn't get so hung up on the most economical way to
spell them.

I suggest people google for

site:mail.python.org python-dev PEP 318

and look at some of the other ideas people have had or examples proposed of
how to (ab)use this feature. It's applicability is much broader than just
declaring methods to be "static" or "class".

Skip

Jul 18 '05 #25
On Mon, 22 Mar 2004 03:19:46 -0800 (PST), Eyal Lotem
<gn*******@yahoo.com> wrote:

[snip motivation for changing the scope rules]
A) Only get rid of the assignment-makes-local
heuristic, by changing the meaning of the "global"
keyword:

def f():
global.a = 1 # Assigns to the module.a
a = 2 # Assigns to a local variable

This allows accessing globals, and IMO serves for
better explicitness about variables which is very
desirable and consistent with instance variable
access.
I'm not seeing much advantage over:
global a; a = 1
When you say "accessing" globals, we need to distinguish between
"referencing" and "setting". Referencing globals is already
automatic. Setting globals needs special syntax. For the few times I
need to set global variables, I'm not feeling much need for
streamlining the existing syntax. Most of my use of global variables
is global within a named module. In this case, I refer explicitly to
the module name. e.g. M1.a = 1 So the improvement above would apply
only to the case where you need to set global variables in the main
module.

[snip how to migrate old code]
B) Create a hierarchy of "locals" for nested scopes,
which are accessible via an overloaded or new keyword
thus:

I)
b = 1
def f():
a = 2
def g():
global.a = 3
global.global.b = 4
Ugh!!
II)
b = 1
def f():
a = 2
def g():
parent.a = 3
global.b = 4


What about aunts and uncles? :>)

I'm not feeling much need to set variables other than local or global,
but I can see where this might be useful to someone. The tradeoff is
convenience for a few vs a mess from lots of users who will abuse the
flexibility. (The same kind of tradeoff as with the GOTO statement.)
I would not give up *essential* flexibility for this reason, but we
are talking here of just a convenience.

If we want to set variables in intermediate scopes, I would prefer a
syntax like:

b = 1
def f():
a = 2
def g():
global.f.a = 3
global.b = 4

Of course, this means we also have to allow functions to have
attributes.

If we are going to make one more change in the scope rules, I would
like to see a grand simplification -- the current rules are good, just
extend them to *any* nested scopes. If I set up a hierarchy of 7
nested classes, I should be able to reference variables at a higher
level without fully qualified names. Again, this is just a
convenience. Mainly, it would make teaching Python simpler.

-- Dave

Jul 18 '05 #26
On Mon, 22 Mar 2004 07:33:08 -0500, Peter Hansen <pe***@engcorp.com>
wrote:
Surely it *is* a list - a list of modifier functions to apply to the
original function.
If it's a list, then just as surely a tuple should be allowed in its
place, as in every (?) other such case in Python that I can think of.
Would that be part of the proposal? (I haven't read the full PEP, sorry.)


I don't think tuples were mentioned in the PEP, though I only skimmed
through it quickly. But, well...
(I know, "foolish consistency is the hobgoblin blah blah..." :-)


Yes, I have to agree.

The list-like syntax isn't too confusing in this context. A
tuple-based context would be. With parens, it would look a lot like
having too lists of arguments. Without, well, IMO it'd be even worse.

Which still shouldn't be read as me expressing a preference - the 'as'
syntax is roughly equally good IMO.
--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
Jul 18 '05 #27
Nicolas Fleury <ni******@yahoo.com_removethe_> wrote...
Marco Bubke wrote:
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.


Personnally, I prefer the "as" syntax to the other proposed (and by a
large margin). However, I feel that it is making the language more
complex and I'm far from sure it's worth the effort. I've given some
[snip
If easing the creation of class methods is so important, I would prefer


Just done a quick check:

$ find /lib/python2.3/ -name "*.py" -exec egrep
"(class|static)method\W" {} ';' | wc --lines
49

Not all of them are calls, and all this in 773 *.py files. I guess
this says something about importance...

Cheers,

AdSR
Jul 18 '05 #28
On 22 Mar 2004 11:25:01 -0800, ar**********@yahoo.com (AdSR) wrote:
Just done a quick check:

$ find /lib/python2.3/ -name "*.py" -exec egrep
"(class|static)method\W" {} ';' | wc --lines
49

Not all of them are calls, and all this in 773 *.py files. I guess
this says something about importance...


Actually, given that support for staticmethod and classmethod is very
recent, it is rather surprising that it appears in that many places.

I wouldn't expect existing libraries to be updated just to make use of
'staticmethod' or whatever. New features mainly get used in new code,
and even then there is the drag factor as people take time to adopt
them.
--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
Jul 18 '05 #29
If easing the creation of class methods is so important, I would prefer


AdSR> Just done a quick check:

AdSR> $ find /lib/python2.3/ -name "*.py" -exec egrep
AdSR> "(class|static)method\W" {} ';' | wc --lines
AdSR> 49

AdSR> Not all of them are calls, and all this in 773 *.py files. I guess
AdSR> this says something about importance...

Not necessarily. Certainly there's the fact that class and static methods
will be less frequently used than normal methods. However, there are also
another mitigating factors as I see it, neither classmethod() nor
staticmethod() have been around all that long (2.2 timeframe).

I will reiterate my comment from before: PEP 318 is about more than just
static and class methods. Here are a few examples from the python-dev
discussion.

1. From Fred Drake:

As an (admittedly trivial) example, I'd be quite happy for:

class Color [valuemap]:
red = rgb(255, 0, 0)
blue = rgb(0, 255, 0)
green = rgb(0, 0, 255)

to cause the name Color to be bound to a non-callable object. Why must
the decorators be required to return callables? It will not make sense
in all circumstances when a decorator is being used.

2. From Anders Munch:

Given that the decorator expression can be an arbitrary Python
expression, it _will_ be used as such. For example:

def foo(arg1, arg2) as release(
version="1.0",
author="me",
status="Well I wrote it so it works, m'kay?",
warning="You might want to use the Foo class instead"):

3. From Shane Hathaway:

Ooh, what about this:

def singleton(klass):
return klass()

class MyThing [singleton]:
...

That would be splendid IMHO.

There are plenty of other examples. Browse the archives.

think-outside-the-bun-(tm)-ly, y'rs,

Skip

Jul 18 '05 #30

"David MacQuigg" <dm*@gain.com> wrote in message
news:bl********************************@4ax.com...
If we want to set variables in intermediate scopes, I would prefer a
syntax like:

b = 1
def f():
a = 2
def g():
global.f.a = 3
global.b = 4

Of course, this means we also have to allow functions to have
attributes.


Hi.
I know what you meant but, technically, functions can and do have
attributes, just not the kind you've mentioned (where the locals become
attributes of their function):
def f(): pass .... f.a = "A"
f.a 'A'


Just so things are clear for those following along ...

Sean
Jul 18 '05 #31
JCM
Sean Ross <sr***@connectmail.carleton.ca> wrote:
"David MacQuigg" <dm*@gain.com> wrote in message
news:bl********************************@4ax.com...

If we want to set variables in intermediate scopes, I would prefer a
syntax like:

b = 1
def f():
a = 2
def g():
global.f.a = 3


Locals inside functions are unique to a function invocation (not the
function object). More than one may be active at any given time,
either through recursion or by creating closures.
Jul 18 '05 #32
Paul Rubin <http://ph****@NOSPAM.invalid> wrote in message news:<7x************@ruckus.brouhaha.com>...

"def foo() as staticmethod" certainly looks best to me aesthetically.
The syntax can be extended, i.e. "def foo() as generator" looks to me
to be a lot more explicit than "def foo()" followed by having the
compiler search the function body for a yield statement in order
to decide if it's a generator.


True, but if a method were both generator and static, then we would
have:

def foo() as generator staticmethod:
...

Add another keyword for thread behavior:

def foo() as synchronized generator staticmethod:
....

And another keyword for privacy:

def foo() as private synchronized generator staticmethod:
....

And your language become pretty close to... Java! :)

Or, following C#, you can also specify some attributes:

[attr1=2,
attr2=3
attr3="Hello"]
def foo():
....

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

Of course there must be some reasonable compromise. I am coming from
the other end of the spectrum: meta-programming. In modern software
development, especially for large and complex systems,
meta-programming becomes more and more essential. If your language is
to grow with time, more and more keywords does not seem to be the way
to go. In some message-based languages like Io, even the if-statements
and the for-loops are not keywords: they are methods.

In the old days, when OOP just appeared, you used to see constructors
with long list of parameters. Nowadays it is much more common to see
things like SetAttribute() to change the behavior of an object. That
is, things are becoming more dynamic.

Metaprogramming is an unavoidable trend, in my opinion. In Java/C# you
use code generators. In C++ you use macros and templates. In Python
the staticmethod() can be interpreted also as a small metaprogramming
statement, not as a declaration of method type.

I am not against the "def foo() as staticmethod" syntax. I am just
bringing up a perspective on possible future problems. It is a little
bit like database table design: you could keep adding new columns to
your table for every new attribute, or you could normalize the table
by allowing a column to specify the attribute name/index, and a
different column for the value. In the first approach, you need to
modify the table definition and your programs when you want to add one
more feature. In the second approach, it becomes easy to add more and
more features, without redefining the table or modifying your program.

regards,

Hung Jung
Jul 18 '05 #33
Skip Montanaro <sk**@pobox.com> wrote...
I will reiterate my comment from before: PEP 318 is about more than just
static and class methods. Here are a few examples from the python-dev
discussion.


You (and Stephen Horne) got your point.

Passing that grep over 3rd party packages might be interesting too...

On other note, regarding the initial subject of this thread: Is there
going to be any voting poll about the syntax in foreseeable future? My
preferred style would be the "standard" one proposed in the PEP.

Cheers,

AdSR
Jul 18 '05 #34

Hung Jung> Paul Rubin <http://ph****@NOSPAM.invalid> wrote in message news:<7x************@ruckus.brouhaha.com>...
"def foo() as staticmethod" certainly looks best to me aesthetically.
The syntax can be extended, i.e. "def foo() as generator" looks to me
to be a lot more explicit than "def foo()" followed by having the
compiler search the function body for a yield statement in order to
decide if it's a generator.


Hung Jung> True, but if a method were both generator and static, then we
Hung Jung> would have:

Hung Jung> def foo() as generator staticmethod:
Hung Jung> ...

Hung Jung> Add another keyword for thread behavior:

Gotta stop thinking of decorators as keywords. That would be a complete
non-starter. It would be both inflexible (need to modify the parser every
time a new one was added) and constraining (require everyone to use the same
small set of "approved" decorators). Decorators are variables referencing
objects which are located at function/method/class definition time.

Hung Jung> def foo() as synchronized generator staticmethod:
Hung Jung> ....

Hung Jung> And another keyword for privacy:

Hung Jung> def foo() as private synchronized generator staticmethod:
Hung Jung> ....

Hung Jung> And your language become pretty close to... Java! :)

And gets fairly unreadable because of the lack of punctuation. I think
square brackets and commas improve readability a bit for those nearly
unreadable long sequences of decorators:

def foo() [private, synchronized, generator, staticmethod]:

Skip

Jul 18 '05 #35

AdSR> On other note, regarding the initial subject of this thread: Is
AdSR> there going to be any voting poll about the syntax in foreseeable
AdSR> future? My preferred style would be the "standard" one proposed in
AdSR> the PEP.

It will probably be a BDFL pronouncement. After all, that's why he's the
BDFL. I have a modified version of PEP 318 in my mailbox I need to read,
edit and check in. I'll try to get to it later today.

Skip

Jul 18 '05 #36
I'll preface by saying that I haven't fully grokked all the possible
uses of decorators. Also, I can sympathize with the complaints about
seeing a function definition and then seeing a classmethod call on
that function 50 lines later (actually that seems like a case for
refactoring but never mind). b-)

The brackets and the 'as' both seem awkward to me. Also, introducing
a requirement that definition and decoration take place on the same
line seems to limit the the possibilities of decoration. Perhaps my
class wants to offer several faces of the same method:

class foo(object):
def __foo_method(...)
....
bar = decorator1(__foo_method)
baz = decorator2(__foo_method, arg1, arg2)

I can't imagine the exact use for this, but I can imagine that there
could be a use. If the syntax remains as it is, that is. This PEP
seems to shoot itself in the foot in this respect.

later,
Jess
Jul 18 '05 #37
DH
Paul Rubin wrote:
"def foo() as staticmethod" certainly looks best to me aesthetically.


It does look better with simple examples. But think of other potential
uses for an "as" keyword, and it might have problems.
Visual Basic uses "as" in function declarations to declare types, not
for function decorators.
VB example:
Function foo (x as Integer, y as Float) as Integer

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"

If we use the list syntax for decorators instead of "as", we might be
able to do something like:

def foo(x as int, y as float) [synchronized, classmethod] as int:
...

See this thread:
http://mail.python.org/pipermail/pyt...ead.html#42780
Jul 18 '05 #38
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.
If we use the list syntax for decorators instead of "as", we might be
able to do something like:

def foo(x as int, y as float) [synchronized, classmethod] as int:


That's sort of nice.
Jul 18 '05 #39
>>>>> "Stephen" == Stephen Horne <st***@ninereeds.fsnet.co.uk> writes:
The syntax can be extended, i.e. "def foo() as generator" looks to me
to be a lot more explicit than "def foo()" followed by having the
compiler search the function body for a yield statement in order to
decide if it's a generator.


Stephen> Good point. Though to me, it isn't that it's a pain for the
Stephen> compiler to search for the 'yield' - I don't care about the
Stephen> compilers pain. The problem is that *I* have to look for the
Stephen> yield and might not notice it.

I disagree. It's not just the compile which has to search for that yield
keyword, we human being reading other's uncommented code (or mis-commented
code) also has to do the same. It would do much good if the completely
different call convention of generator is made much more explicit in the
definition of the function.

Regards,
Isaac.
Jul 18 '05 #40

DH> Possible future Python example that uses "as" differently:

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

With no extension beyond the current PEP 318 proposal, you might postulate
returns() and accepts() decorators:

def foo(x, y) [accepts(int, float), returns(int)]:
...

which extend foo() with code to enforce input and output types. Further,
function attributes could be added which could be used by tools like
pychecker for intermodule type checking.

Skip

Jul 18 '05 #41
>>>>> "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 :-).

There should be a kind of "standard voting system" for PEPs, w/o
administration overhead of occasional seperate vote. It would be a
data point, if nothing else. The result of the vote could be stored
together w/ the accepted/approved pep.

Actually, any third party could whip out the voting system, but the
illusion of authority would be more convincing if PSF was involved.
It would be fun, esp. if it was easier than the conditional expression
vote of yore :-).

FWIW, I prefer

def f(x,y) [wrapper,wrapper...]:
pass

or

def f(x,y) as iterable:
pass

and would oppose

def f [wrapper, wrapper...] (x,y):
pass

Like others, I want to see the param list right next to the function
name.

--
Ville Vainio http://tinyurl.com/2prnb
Jul 18 '05 #42
On Mon, 22 Mar 2004 20:48:18 +0000 (UTC), JCM
<jo******************@myway.com> wrote:
Sean Ross <sr***@connectmail.carleton.ca> wrote:
"David MacQuigg" <dm*@gain.com> wrote in message
news:bl********************************@4ax.com...

If we want to set variables in intermediate scopes, I would prefer a
syntax like:

b = 1
def f():
a = 2
def g():
global.f.a = 3


Locals inside functions are unique to a function invocation (not the
function object). More than one may be active at any given time,
either through recursion or by creating closures.


Oops. This could get messy. Let's not worry about *how* to do
intermediate scopes until we see a good use case for *why* we want to
do it.

-- Dave

Jul 18 '05 #43
Skip Montanaro <sk**@pobox.com> wrote in message news:<ma************************************@pytho n.org>...
I will reiterate my comment from before: PEP 318 is about more than just
static and class methods. Here are a few examples from the python-dev
discussion.

1. From Fred Drake:

As an (admittedly trivial) example, I'd be quite happy for:

class Color [valuemap]:
red = rgb(255, 0, 0)
blue = rgb(0, 255, 0)
green = rgb(0, 0, 255)

to cause the name Color to be bound to a non-callable object. Why must
the decorators be required to return callables? It will not make sense
in all circumstances when a decorator is being used.
Ok.
2. From Anders Munch:

Given that the decorator expression can be an arbitrary Python
expression, it _will_ be used as such. For example:

def foo(arg1, arg2) as release(
version="1.0",
author="me",
status="Well I wrote it so it works, m'kay?",
warning="You might want to use the Foo class instead"):
Nice,
3. From Shane Hathaway:

Ooh, what about this:

def singleton(klass):
return klass()

class MyThing [singleton]:
...

That would be splendid IMHO.
This one I don't like (not the syntax, the implementation).
I want my singleton to be a class I can derive from.
This can be done by using a metaclass as decorator
(I posted an example months ago).
There are plenty of other examples. Browse the archives.

think-outside-the-bun-(tm)-ly, y'rs,

Skip

And don't forget Ville Vanio's idea of using the new syntax to
implement multimethods:

def __mul__(self,other) as multimethod(Matrix,Matrix):
...

def __mul__(self,other) as multimethod(Matrix,Vector):
...

def __mul__(self,other) as multimethod(Matrix,Scalar):
...

def __mul__(self,other) as multimethod(Vector,Vector):
...

def __mul__(self,other) as multimethod(Vector,Scalar):
...

etc.

Way cool, actually :)
Michele Simionato
Jul 18 '05 #44

On 23-mrt-04, at 1:15, Jess Austin wrote:
I'll preface by saying that I haven't fully grokked all the possible
uses of decorators. Also, I can sympathize with the complaints about
seeing a function definition and then seeing a classmethod call on
that function 50 lines later (actually that seems like a case for
refactoring but never mind). b-)

The brackets and the 'as' both seem awkward to me. Also, introducing
a requirement that definition and decoration take place on the same
line seems to limit the the possibilities of decoration. Perhaps my
class wants to offer several faces of the same method:

class foo(object):
def __foo_method(...)
....
bar = decorator1(__foo_method)
baz = decorator2(__foo_method, arg1, arg2)

I can't imagine the exact use for this, but I can imagine that there
could be a use. If the syntax remains as it is, that is. This PEP
seems to shoot itself in the foot in this respect.


The syntax in PEP318 is syntactic sugar for the most common use of
function decorators, the current syntax would still be supported.

Ronald
Jul 18 '05 #45
In article <ma************************************@python.org >, Skip Montanaro wrote:

DH> Possible future Python example that uses "as" differently:

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

With no extension beyond the current PEP 318 proposal, you might postulate
returns() and accepts() decorators:

def foo(x, y) [accepts(int, float), returns(int)]:
...

which extend foo() with code to enforce input and output types. Further,
function attributes could be added which could be used by tools like
pychecker for intermodule type checking.


Not a big fan of that syntax - I have to keep the parameter names and
types in sync by counting.

def foo(x [accepts(int)], y [accepts(float)]) [returns(int)]:

is a little better, except now we're getting very verbose.

For decorators in general, I like

def foo() as [decor1, decor2, decor3]:

You get an explicit list syntax, but it's set off by a keyword so they don't
run together to the eye. Because the keyword keeps it unambiguous, you
could even allow a tuple instead of a list: "def foo() as (x, y, z)".

So I definitely favour a keyword, but perhaps "as" is to generic. What
about "has" or "with"?

Joe
Jul 18 '05 #46
In article <sl****************@gate.notcharles.ca>, Joe Mason wrote:
Not a big fan of that syntax - I have to keep the parameter names and
types in sync by counting.

def foo(x [accepts(int)], y [accepts(float)]) [returns(int)]:

is a little better, except now we're getting very verbose.

For decorators in general, I like

def foo() as [decor1, decor2, decor3]:

You get an explicit list syntax, but it's set off by a keyword so they don't
run together to the eye. Because the keyword keeps it unambiguous, you
could even allow a tuple instead of a list: "def foo() as (x, y, z)".

So I definitely favour a keyword, but perhaps "as" is to generic. What
about "has" or "with"?


Come to think of it, the verbose example with "has" becomes (assuming a
shorter decorator name):

def foo(x has sig(int), y has sig(float)) has returns(int):

Since you might not need the full list syntax for a single decorator.
That's not too bad looking.

(No, I'm not seriously proposing decorators on parameters at this point.)

Joe
Jul 18 '05 #47
On Tue, 23 Mar 2004 11:27:57 +0800, Isaac To <kk**@csis.hku.hk> wrote:
>> "Stephen" == Stephen Horne <st***@ninereeds.fsnet.co.uk> writes: >> The syntax can be extended, i.e. "def foo() as generator" looks to me
>> to be a lot more explicit than "def foo()" followed by having the
>> compiler search the function body for a yield statement in order to
>> decide if it's a generator.


Stephen> Good point. Though to me, it isn't that it's a pain for the
Stephen> compiler to search for the 'yield' - I don't care about the
Stephen> compilers pain. The problem is that *I* have to look for the
Stephen> yield and might not notice it.

I disagree. It's not just the compile which has to search for that yield
keyword, we human being reading other's uncommented code (or mis-commented
code) also has to do the same. It would do much good if the completely
different call convention of generator is made much more explicit in the
definition of the function.


Why say "I disagree" if you actually agree with me? As I said...

"""
The problem is that *I* have to look for the yield and might not
notice it.
"""
--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
Jul 18 '05 #48
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] :
--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
Jul 18 '05 #49
On Tue, 23 Mar 2004 08:39:19 GMT, Joe Mason <jo*@notcharles.ca> wrote:
Come to think of it, the verbose example with "has" becomes (assuming a
shorter decorator name):

def foo(x has sig(int), y has sig(float)) has returns(int):
<snip>
(No, I'm not seriously proposing decorators on parameters at this point.)


Damn - I thought it was a cool idea!

After all, in implementation terms it means little more than a few
extra statements at the top of the function - apart from being more
clearly associated with the call parameters in the definition, there
is nothing much new.

I'd just like to assert that more than one decorator may be needed,
perhaps in cases such as...

def foo ( x [accepts(int), inrange(0,100)] ) [returns(int)] :

And assuming that these are mainly self-documentation and aids to
debugging and testing, it could be quite useful to get rid of most of
the overhead by perhaps having an option to ignore specified
decorators at compile time.
--
Steve Horne

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

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: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.