Extreme orthogonality is when everything is as consistent as possible even if it's different.
:-)
For example, LISP seems to want everything to be lists, and for
the calling syntax to be the same for all features, i.e.
(FUNCTIONNAME param1 param2 ...)
; LISP: do something with the 2nd item in array. (do-something-with (aref myarray 2))For readability and terseness (and maybe for typechecking?) some people might prefer the code
// C/C++: do something with the 2nd item in array. do_something_with(myarray[2]);or the code
# Python: do something with the 2nd item in array. do_something_with(myarray[2])even though it is less consistent: accessing an element of the array does not use the same syntax as calling the function do_something_with does.
On the other hand, the rejection of orthogonality in favor of terseness can be taken rather far. For example, Perl (which for most of the popular history of the WWW has probably been the most-used scripting language for generating webpages) has an amazing number of special uses of special characters and special variables in special circumstances.
while (<>) { # A Perl programmer is expected to remember # that the default input to the line-input operator <> # is STDIN, and that the default place for a line # of data that was read in to be stored is $_. if ($_ > 0) { do_something_for_the_number($_) } if ($_ =~ /^\s+(\w+)/o { do_something_for_the_letters_numerals_and_or_underlines($1); # =~ is the pattern match operator. # // surrounds a pattern. # In a pattern match, ^ indicates the beginning # of a line or of the string, depending... # \s indicates whitespace. # + indicates repeated one or more times. # \w indicates a letter, numeral, or underline. # $1 is the string matched by the first substring surrounded by () # within the pattern match. } }Perl is probably second (third?) only to Intercal and APL as languages likely to be mistaken for line noise. It often does permit extreme terseness.
For readability, some people might somewhat prefer the Python:
import re # for regular expressions package. ... pat = re.compile(r'^\s+(\w+)') # This regexp syntax standard is Perl's fault, or to Perl's credit. while 1: # Python won't let us do variable assignment iline = raw_input() # within a conditional, to prevent accidental = for ==. if raw_input > 0: do_something_for_the_number(iline) matchobj = pat.match(iline) if matchobj != None: do_something_for_the_letters_numerals_and_or_underlines(matchobj.groups[1])The Python is longer, but to a novice it would be more readable. Some lessons we can take from this? Admittedly, it's well-known that regular expression matching is almost an area of obsession with the designers and many users of Perl. It's not surprising that the Perl code is shorter. But it's far too easy to write Perl code that's not readable except to a fanatic, with its weird proliferation of special cases and weird character meanings.
... if weight > 2500 : print "weight is excessively high." raise MyWeightError(2500) do_next_thing(some_var) ...
if 1900 < year < 2100 and 1 <= month <= 12 \ and 1 <= day <= 31 and 0 <= hour < 24 \ and 0 <= minute < 60 and 0 <= second < 60: # Looks like a valid date return 1
month_names = ['Januari', 'Februari', 'Maart', # These are the 'April', 'Mei', 'Juni', # Dutch names 'Juli', 'Augustus', 'September', # for the months 'Oktober', 'November', 'December'] # of the year
if ( 1900 < year < 2100 and 1 <= month <= 12 and 1 <= day <= 31 and 0 <= hour < 24 and 0 <= minute < 60 and 0 <= second < 60 ): # Looks like a valid date return 1
// OK C++ : if (c = getc(f)) { ... # Bad Python! Won't run! if (c = f.read(1)) : ... # Good Python: c = f.read(1) if (c) : ...
# "Hello, world" program. print "Hello, world."
>>> 1j * 1J (-1+0j) >>> 1j * complex(0,1) (-1+0j)
>>> s = "format:\n vcheck [driveletter]" >>> print s format: vcheck [driveletter]
>>> s = r" 0 --- / \" >>> print s 0 --- / \
>>> s = """State-run lotteries: >>> a "tax" on mathematical illiterates. >>> Still think millions of people can't be wrong?""" >>> print s State-run lotteries: a "tax" on mathematical illiterates. Still think millions of people can't be wrong?
>>> s1 = u'\u10e7\u0020\ua09f' >>> s2 = u'Hello\u0020world.' >>> print s2 Hello world.
a = ['Mike', u'\u10e7\u0020\ua09f', 1, 1234]
point1 = 5, 16, 73 # A geometric point specified in x, y, z coordinates.
>>> word = 'Help' + 'A' >>> print word[4] A >>> print word[0:2] He >>> print word[2:4] lp >>> print word[:2] He >>> print word[2:10000] lpA >>> garbage = ['banana peel', 'cardboard', 'paper', 'can', 'bus transfer'] >>> print garbage[1:3] ['cardboard', 'paper'][Thanks to the audience member who pointed out that I needed to fix one of the above examples. I entered the example into a Python interpreter displayed on the projection screen, just to prove that he was right. :-) ]
STRING: LIST: TUPLE: ------------------------------------------------------------------------------- Operation operation operation | interpretation s1 + s2 L1 + L2 t1 + t2 | Concatenation s1 * 3 L1 * 3 t1 * 3 | Repeat s1[i] L1[i] t1[i],t2[i][j] | Index s1[i:j] L1[i:j] t1[i:j] | Slice len(s1) len(L1) len(t1) | Length for x in s1 for x in L1 for x in t1 | Iteration 'm' in s1 3 in L1 for 3 in t1 | Membership |
p = 1 print "Let's keep doubling a number until it becomes fifty or more." while p < 50: print p p *= 2
a = ['fish', 'alligator', 29] for x in a: print xYields the output:
fish alligator 29
s = 'allligator' ells = 0 for c in s: if c == 'l': ells += 1 print "There are " + str(ells) + " l's in " + s + "."Yields the output:
There are 2 l's in alligator.
foods = ['alligator', 'gopher', 'apples', 'juicy grubs'] for x in foods: print "I eat " + x + "." if x == 'catfish': print "I am allergic to catfish! I die!" break else: print "HURRAY!\nI ate no catfish, so I survived!"Yields the output:
I eat alligator. I eat gopher. I eat apples. I eat juicy grubs. HURRAY! I ate no catfish, so I survived!
foods = ['alligator', 'gopher', 'apples', 'juicy grubs'] for x in foods: print "I eat " + x + "." if x == 'catfish': print "I am allergic to catfish! I die!" break else: print "HURRAY!\nI ate no catfish, so I survived!"Yields the output:
I eat alligator. HURRAY! I ate no catfish, so I survived! I eat gopher. HURRAY! I ate no catfish, so I survived! I eat apples. HURRAY! I ate no catfish, so I survived! I eat juicy grubs. HURRAY! I ate no catfish, so I survived!
def fib(n): # write Fibonacci series up to n """Print a Fibonacci series up to n.""" a, b = 0, 1 while b < n: print b, # Comma puts next output on same line. a, b = b, a+b return b fib(2000)Yields the output:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
def make_incrementor(n): return lambda x: x + n f = make_incrementor(100) print f(5) print f(200)Yields the output:
105 300
import re # import module pat = re.compile(r'^\s+(\w+)')
The python.org website is a great resource. It includes Guido van Rossum's Python Tutorial.
Python Warts, by A.M. Kuchling
"While I think Python has a very elegant design that successfully straddles the fine line between the minimalism of Lisp and the rococo complexities of Perl, it's certainly not perfect. There are various design features that are ugly, or at least suboptimal in some way. This essay will examine the most significan problems in Python, as I perceive them, assisted by suggestions from the comp.lang.python crowd."
A Python/Perl phrasebook, by Jak Kirman