Psyche consists of a small number of Python modules. These modules and a short description of them are described in Table 4.1.
Python 2.2.1 (#1, Apr 21 2002, 08:38:44) [GCC 2.95.4 20011002 (Debian prerelease)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from psyche.interpreter import Interpreter >>> i = Interpreter() >>> i.eval('(define (square x) (* x x))') >>> i.eval('(square 5)') 25 >>> i.eval('(square -1)') 1 >>> i.eval('(square "hello")') Traceback (most recent call last): ... TypeError: unsupported operand type(s) for *: 'str' and 'str' >>>
Let's step through this example and see what happens.
The first statement imports the Interpreter into our namespace. The second statement creates an actual Interpreter object and names it i.
The other statements use the eval method to execute Scheme commands. eval is the most interesting method in the Interpreter; it expects a string containing a legal Scheme command, evaluates the command and returns the result of the evaluation.
The third statement evaluates the Scheme command (define...). The fourth and fifth statements again evaluate a Scheme expression, using the square procedure defined in the third statement.
At this point, two interesting observations can be made. Firstly, notice how the interpreter keeps its state; in the fourth and fifth statements, it remembers the definition of square from the third statement.
Secondly, the latter two evaluations print a (correct) return value, while the first evaluation does not. Understanding this requires some knowledge the Scheme specification, which explicitly states the return values of each Scheme command. However, for some commands such as define, the R5RS specifies that the return value is undefined. In these cases, Psyche will return None, which is silently ignored by the Python shell.
The last statement tries to evaluate a Scheme expression resulting in an error. Psyche uses the Python exception handling mechanism to signal errors. In this case, a TypeError is raised.