Perhaps there are good reasons for it, but generally I prefer java's implicit 'this.'
class foo:
def __init__(self,val):
self.x=val
def square(self):
return self.x**2
#imperative way
imperative = [foo(x).square() for x in range(5)]
#functional way
s = foo.square
composed = lambda x: s(foo(x))
functional = map(composed,range(5))
print imperative==functional
The explicit self allows you to treat member functions as generic function and compose them in a functional way. Now, most functional programming isn't necessarily Pythonic. However, given a proper compose function, I could imagine it being useful to mix a long chain of function and member calls without needing to make a distinction between the two.Javascript: semicolon insertion
Erlang: periods, commas and semicolons
Clojure: not much, actually
PHP: ugh, nearly everything
Python: lambdas can only have a single expression
Everything except Lisps: expression/statement dichotomy
Haml: Hard to control whitespace around elements.
SQL: Can never remember which date functions go with which RDBMS.
If I could, I would make Python 5 (2+3=5), which is Python 3 but accepts all the legacy syntax of Python 2 (especially the print statement).
I'd solve the str/unicode problem by providing
bytes, str, unicode = python5.legacy_strings
or bytes, str, unicode = python5.modern_strings
that you would put at the top of the file. I'd make the modern strings builtin for system modules, or files with the .py5 extention. Problem solved.SQL - you SELECT fields before you specify what table they come from, so tooling is virtually impossible.
Javascript: Lacks support for 64-bit integers and arbitrary-precision decimals.
SQL: SQL injection.
I believe all of these three should give me os.path.isdir:
import os
import os.path
import os.path.isdir
os.path.isdir(...)
And to get isdir() directly, I would use either: from os.path import isdir
import os.path.isdir as isdir
This should work if path is either a package (a directory), a module (a file), or an object defined in os.py!Sometimes, for some reason if I only import a module, I can't use submodules. So `import os` wouldn't give `os.path.isdir`. I don't know when that occurs, maybe it was in an ancient version of python. But it leaves me with an uneasy feeling every time I use a submodule. Anyone know when this happens?
Last but not least, it should be easier to import stuff from above the script. If my script lives at ./tools/foobar.py, and I want to import ./helper.py, it should just be something like
# ./tools/foobar.py
from .. import helper
$ python ./tools/foobar.py # simple run-a-script syntax
and not $ python -m tools/foobar # hideous run-a-module syntax
or what I'm using now # ./tools/foobar.py
# hideous boilerplate header
import sys, os
SCRIPTDIR = os.path.relpath(os.path.dirname(__file__) or ".")
PARENTDIR = os.path.relpath(os.path.join(SCRIPTDIR, ".."))
sys.path.insert(0, PARENTDIR)
import helper
$ python ./tools/foobar.py # simple run-a-script syntax- Hardcoded recursion limit + no tail call optimization. I understand Guido's reasons for this but I find myself writing ugly code instead of beatiful code. (But maybe changing this would make Python's internals ugly.)
Mainly Python but other languages too. - Length of the collection: len(foo). String representation: str(foo). Why not foo.len() or foo.str(). Or even better: foo.len or foo.str. As a Python user, I'm not a fan of getters. I think we should use the "attribute syntax" to get data about and of the object/type/thing, regardless if it involves any computations or not. (but would probably generate more problems than solve little nitpicks)
[1]http://docs.python.org/2/library/sys.html#sys.setrecursionli...
As for tail-call optimization, here's Guido's opinion (which I agree): http://neopythonic.blogspot.pt/2009/04/tail-recursion-elimin...
(mapcar 'funcall (loop for x below 3 collecting (lambda () (print x))))
producing:
3 3 3 (3 3 3 )
OK, it is the loop DSL that chooses to rebind the same variable over which I closed, but loop is in the standard so I'll blame lisp. The syntax really looks like a fresh binding. Shucks, this is almost a bug: the loop implementation was allowed to leak into the loop semantics.
Also, Scheme cannot practically be used as an interactive command processor and file-name-space browser like a Unix shell can. (Yes, I know about scsh; I do not like it.)
NSString *result