# Sage Idiosyncrasies

## Sage Idiosyncrasies

This page will point out interesting or odd behaviors of Sage and areas where it is either helpful or causes issues.

### Return Type of integral and integrate

Depending on the value of the integral of a symbolic expression the return type will differ.

For example lets say we had the function f(x) = x2 + 1 and we call the integral function on it.

The Sage code would look like this:

f = x^2 + 1
result = integral( f )


The result is obviously $\frac{{x}^{3} }{3} + x$

We can check the type of result by using the type function:

type( result )


If you input it into Sage you will see that the type is sage.calculus.calculus.SymbolicArithmetic.

Now let's look at another example where $f(x) = \frac{1}{x}$

Here the integral is ln(x)

Sage code would look like this:

f = 1 / x
result = integral( f )
type( result )


Here the type of result is sage.calculus.calculus.SymbolicComposition which differs from our previous example.

#### Why this is a problem

Sage's Maxima interface provides a variety of pattern matching functions, one of which is called freeof. freeof takes a pattern and an expression and returns true if the pattern is not found in the expression.

Sage code could look something like this:

f = x^2 + 1
maxima.freeof( x^3, integral( f ) )


Since the integral( f ) = $\frac{{x}^{3} }{3} + x$ maxima returns false like you would expect.

Now let's try it with our other example f(x) = 1 / x

f = 1 / x
maxima.freeof( x^3, integral( f ) )


Since integral( f ) is log(x) it should return true, instead it appears the freeof function doesn't understand SymbollicComposition variables and Sage hangs requiring you to quit the worksheet before you can perform anymore calculations.

### Parameter Passing and Graphics Objects

In Python parameter passing of objects is done by reference. So if you pass a mutable object to a function and modify that object then the original is modified. This only applies to mutable objects such as a list or dictionary. Strings and tuples are immutable and therefore any modification made to them in the function must make a copy since the original does not allow change.

Example: A function that appends an item to a list

def addItem( ls, item ):
ls += item

myList = [1,2]
print myList
#Output: [1,2,3]


Example 2: A function that appends to a string

def appendString( s, addition )

myString = 'hello '
appendString( myString, ' joe')
print myString
#Output: hello


Even though the += operator is thought of as modifying the original since strings in Python are immutable += is actually creating a new string object containing the string referenced by lhs concatenated with the string referenced by rhs and assigning the reference of the string newly created string to the lhs.

#### The Graphics Object

Here is Sage's description of the Graphics Object:

The Graphics object is an empty list of graphics objects
It is useful to use this object when initializing a
for loop where different graphics object will be added
to the empty object.


Based on this description you would think that a Graphics object was mutable since they encourage use of the += operator and with enough objects contained in a graphics object repeated copying could become an expensive process.

However after testing the behavior it appears that Graphics objects are immutable and += is actually making a copy.

Example:

def addLine( g ):
g += line( [ (0,0),(1,1) ] )

g = Graphics()
print g
#output Graphics object consisting of 0 graphics primitives


As you can see passing a graphics object to a function and using the += operator did not modify the original. This means that for a function to modify a Graphics object it must return back the copy created.

def addLine( g ):
g += line( [ (0,0),(1,1) ] )
return g

g = Graphics()