User:Rspeer/SyntaxHighlight

Hey. I don't know if this is an appropriate use of userspace or not. I'm just using MediaWiki to get some free syntax highlighting.

Hello World
Scheme:

Python:

Recursion vs. Iteration
Many of Python's constructs are built around iteration, while Scheme's are built around recursion. You can iterate in Scheme and recurse in Python, but it's messier.

Python has built-in syntax for iterating over a list, for ... in .... In fact, other kinds of iteration, such as over a sequence of numbers, are expressed in terms of this. Here's an example of iteration:

Consider this factorial code in Scheme:

You could translate it literally into Python like this:

But the more efficient and natural way to write it is by iterating over a  of numbers.

gives you the numbers from 1 (inclusive) to x+1 (exclusive). For example,  is (1, 2, 3). The endpoint is omitted so that the difference between the end and start is the number of items you get in the range.

More things you can do with lists
You index lists with the  operator. Indices start at 0. So  is , and   is.

You can also get a slice of a list, using a range of indices that acts much like the  function above. Again, it includes the starting point, and excludes the endpoint. is.

Tuples contain separate items just like lists do, but they are immutable; their contents never change. >>> the_tuple = (3, 4, 5) >>> the_tuple[1] = 6 Traceback (most recent call last): File " ", line 1, in TypeError: 'tuple' object does not support item assignment

Dictionaries
Dictionaries are another kind of data structure. They contain values like lists do, but they are unordered, and you can use any immutable object as the index.

List comprehensions
In Scheme, you would often use  and   to operate on lists.

Python has special syntax that incorporates both  and , called "list comprehensions".

Modules and inline help
Python comes with a standard library with many useful functions and classes. They don't clutter up the global namespace; instead, they are in modules that you can load:

When you're at an interactive Python prompt, you can get help on any module, class, or function just by running  on it: >>> import math >>> help(math) Help on module math:

NAME math

FILE /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-dynload/ math.so

MODULE DOCS http://www.python.org/doc/current/lib/module-math.html

DESCRIPTION This module is always available. It provides access to the mathematical functions defined by the C standard.

FUNCTIONS acos(...) acos(x) Return the arc cosine (measured in radians) of x.

[...and many pages more...]

If you are running  as your interactive Python interpreter, you can also get a brief summary of what an object is by typing , and see its source code by typing. ipython can be a great way of experimenting with Python code. Type  for a summary of what ipython can do.

Classes
In addition to the basic data structures such as lists, tuples, and dictionaries, you can also define new object-oriented data structures. (In fact, even lists, tuples, and dictionaries are object-oriented.)

Lexical scope
You may remember the concept of "lexical scope" from Scheme. Every function and let statement introduces a new scope where variables can be defined. When looking up the value of a variable, Scheme starts from the current scope (or "frame"), then looks outward to the scope containing that one, and so on until it reaches the global environment.

That lets you do neat tricks like this, creating a function that saves state from one call to the next:

Python only has two scopes: global and local. Each function has its own local scope. Whenever you assign to a variable using =, you're assigning to a local variable.

(You can use the global keyword to get a global variable that you can assign to, but if you have to assign to a global variable from within a function, it's a good sign that you're doing things wrong.)

This means that, even though Python also has nested functions that can be returned as values, the direct translation of the Scheme code above won't quite work:

To do this, we would need to pass the variable "count" into the inner function. One way to do that is like this, where we define an inner variable named "count" whose default value is the other "count" to bridge the gap:

But this is clunky. In Python, when you want a function to keep state with it, you often do that by making it a method on a class:

But you can also use a generator, which is essentially a function that remembers its state and can return multiple times. You turn a function into a generator by using the  keyword inside it.

That's all
I leave you with an Easter egg in Python that explains a bit of its design philosophy: >>> import this The Zen of Python, by Tim Peters

Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!