How To Sessions

From Macaulay2
Jump to: navigation, search

Friday, October 30, 2009

  • Dan needs to not answer questions, except on google groups and if it is totally inappropiate
  • Get the community using the group!
  • Search the M2 wikis
  • What about a continuing wikis? (Group is a conversation, not a documentation)
  1. Link top M2 doc page to M2 wiki for developing doc
  • Subscribe to RSS feed and use google reader
  • Reading page put a link that drops into a wiki page, edit happens and then?
  • Suggestions for doc
  • bugs
  • Submit your packages to JSAG
  • How to use google reader to follow the google group:
  1. Get google reader
  2. go to Macaulay 2 google group -> scroll down -> click on XML
  3. choose RSS (choose how much you will see after being absent 15/50 msgs-15/50 topics)
  4. add to google reader
  • Overview on google reader:
  1. All items shows all new items chronologically
  2. After looking at one entry, it vanishes. If you add a star you can search for starred items.

Thursday, October 29, 2009

Questions for today:

  • Discuss promote vs lift vs substitute

Wednesday, October 28, 2009

Functions and methods with no arguments

  • Functions with no arguments is easy. An example follows.

g = () -> print "hi there"

  • Methods with no arguments is requires a bit more. However, in the future it may (is intended) to work as above. An example of the current work around follows.

installMethod(h, () -> print "hi there")
installMethod(h, ZZ => () -> 12)

where the first is a basic method h with no specification of the type of output.

installMethod(h, ZZ, ZZ => x -> x+12)

The example above has an argument of type ZZ and output of type ZZ and is an alternative code for the more common
h = method()
h(ZZ) := ZZ => x -> x+12
so it is not really an example of a method with no arguments but serves to illustrate alternative code.

Documenting different output types and different input types

There are two ways to specify the type of output for a method.

  1. One is to use f(ZZ) := ZZ => x -> x+1 where the first ZZ specifies the input as an Integer and the second ZZ specifies the expected output of this function to be an integer. If f is a method we can also do, then f(RR) := RR => x -> x+1 as part of the same method f = method()
  2. The other is to use TypicalValue, as in f = method(TypicalValue => ZZ)

Using TypicalValue applies the typing to ALL the methods belonging to f whereas the first approach allows different implementations of the method f to have different output types.

When writing documentation the different possible output types are dealt with as follows. The first is in "simple doc" notation and the second is in the Macaulay2 language. Due to a lack of knowledge of the wiki, we note that in the first example, the information after Outputs should really be on a new line and indented. The second one should not have the backslashes.

  1. Outputs ZZ or @ofClass RR @
  2. Outputs => \{{ofClass ZZ, " or ", ofClass ZZ, " text."}\}

loadPackage, installPackage, needsPackage, and load

Philosophically, one should basically always use needsPackage.

  • When developing new packages, using restart with needsPackage is best. Using loadPackage without restarting will overwrite variables set by a previous loadPackage while needsPackage won't, so if changes are made one needs to either restart (often, if not always a good idea when needing to reload variables) or use loadPackage to see changes.
  • When writing a package that requires functions and variables from another package, one should use needsPackage (NOT loadPackage, so that the package is only loaded if needed) after the newPackage command. This usage will only allow the variables/functions in the other package to be used locally. If you write a package that needs new types defined in another package then your new package also must have a needsPackage command BEFORE (as well as after) the newPackage command. You will get errors when loading if you do not do this.
  • The function load is good for individual use when working with files that are not packages and the user wants to assign all of the variables in that file (e.g. execute all the lines in the file -- assumes all the lines are executable).
  • The function installPackage is good when a package is complete as it runs all the documentation and tests. The documentation provided with a package will not appear for the user in a browser until after installPackage is invoked. When developing a package, the package is not finished until installPackage runs without error. installPackage catches errors in the documentation and tests whereas loadPackage does not necessarily.

Sequence vs. List

A sequence is "more bare bones" and a list is "more complicated" in the internal structure. So a sequence is using less memory as it has less information assigned to it. However, a list has clear syntax using {} and sequence is not as convenient sometimes as it is not obvious how to get a sequence of length one since (12) returns just 12, not as a sequence.

There is a clear usage difference when working with functions. For example the sequence (1,2,3,4) gives 4 arguments to a function, but {1,2,3,4} is seen as a single argument. For example a function f = (x,y) -> x+y is a function with 2 arguments, but f = L -> L/sqrt is a function with a single argument that is a list and f computes the square root of each entry of L. Sequences are also good for multiple assignment like (x,y,z) = (1,2,3) which assigns x to 1, y to 2, and z to 3. Similarly f = x -> (x,x^2,x^3), then we might do (u,v,w) = f 100 which assigns u to 100, v to 10000 and w to 1000000.

A discussion on list formation

The following are different ways of forming a list and a discussion of their relative value follows the list, but we note here that #3 and #5 are the most efficient.

  1. Use append to attach one element at a time: L = {1}, L = append(L,2), L = append(L,3), ...
  2. Build a deeply nested sequence, then use deepSplice to flatten it and toList, if having the List type is important: L = (1), L = (L,2), L = (L,2), ... using deepSplice and toList afterwards.
  3. Make a MutableList, x = new MutableList, and assign entries as needed as follows.
    • x#100 = null This creates a mutable list of length 100 with all entries null. This is quite efficient as a single assignment is made for the list. Then the entries can be changed using an expression like x#2 = 9 which sets the second entry in the list to be 9.
    • x##x = 1, x##x = 2, etc. This sets successive entries to be 1, 2, etc. Again, only the one mutable list is formed which is more efficient than the first two options.
  4. Make a MutableHashTable. A MutableHashTable is more flexible than a MutableList, but requires more memory. More discussion on this below. Assignment and creation of a MutableHashTable is not unlike that in a MutableList, but if X is a MutableHashTable then keys don't have to be integers. The example below builds a MutableHashTable with 2 keys, a and cow which point to a set with b in it and the integer 12.
    • X = new MutableHashTable
    • X#a = set {b}
    • X#cow = 12
  5. Use "for" with "list".
    • for i from 1 to 100 list (if isPrime(i) then continue else i)

These are the most common usages with the two best, at this time, probably being MutableList and "for with list". For example, MutableHashTable uses more memory because each key uses a new block of memory, whereas in a MutableList there is a single block of memory with slots and only uses more memory when the list grows. Also, MutableList gives the ability to form a long list only once with changeable entries. Scan has been generally replaced by "for with list" and apply meaning that these serve the same purpose and are considerably more efficient. Also, MutableList and "for with list" use considerably less memory (and time?) than the first two ideas listed and leave less potential for assignments not cleared in garbage collection. While the first two work, when writing packages one should strive to use MutableList or "for with list."

We note here that peek can be useful for seeing the keys and assignments, or elements of a MutableList or MutableHashTable.

How to intersect lists and other objects

In fact to intersect just about anything (this assumes that intersection makes sense, which it may not, for example with two ideals with generating sets that are not necessarily comparable) called L and M use the following

set L * set M

Quarantine Information for OSX 10.5 or later

Users of OSX 10.5 or later must "un-quarantine" the disk image before it is unpacked. There are 2 ways to do this.

  • Before the disk image is mounted (accomplished by choosing to save the image rather than open it, or unmount it after it is opened and before it is installed) go to a command line, cd into the directory where the disk image is saved (~/Downloads on many 10.5 or later machines) and type

xattr -d Macaulay2*.dmg

  • Alternatively, it is possible to "un-quarantine" the files after installation. In this case cd to your Macaulay2-1.3/ directory (/Applications/Macaulay2-1.3/ on most machines) and type

find . -type f|xargs xattr -d

or you can simply type

find /Applications/Macaulay2-1.3/ -type f|xargs xattr -d

from any directory, but this still assumes that this is where you put Macaulay2-1.3 and you simply need to make sure the directory is correct for your machine.

Tuesday, October 27, 2009

New code should be formulated into a package format. Below is some information that may be helpful in building careful packages.


  • Several very good examples of well constructed packages are available at Journal of Software for Algebra and Geometry. All of these packages are refereed and checked by editors. For this reason they receive a certification shown in the documentation when users install the package.
  • ReesAlgebra is a package distributed with Macaulay2 and is a good example of using the new documentation format (more below).


The easiest way to write documentation is to use the new "SimpleDoc" format. Typing

  • print docTemplate

in Macaulay2 shows exactly the key pieces of a documentation node. All of the documentation in ReesAlgebra gives good examples of how to actually use each node.

  • print docExample

also gives very useful information for writing documentation in the new simpler format. To get similar information for package format and templates type

  • print docExample

again ReesAlgebra is one example of a package and Journal of Software for Algebra and Geometry has 3 good examples.

Clearing Memory

  • clearAll is a function that clears all variables and output lines
  • to reset or clear just one variable use symbol. For example, if x has been used in any number of ways, typing either QQ[symbol x] allows creation of a ring with x as a cleared variable or x = symbol x and QQ[x] does the same thing.
  • apropos "clear" returns all functions that use the word clear. This is case sensitive, so to get all functions that use the world clear or Clear type apropos "[cC]lear".