Cat Graphics and Effect Systems

I am currently working on a graphics module for Cat. I wanted the graphics module to be easy to use and cross-platform so I settled on generating postscript and pdf files. For example:

 square

This was generated using the following program:

define draw_square {
  [
    dup
    halve dup move
    [dup 90 turn line_forward] 4 repeat
    pop
  ]
  draw_closed_path
}  

define demo {
  new_page
  [2 draw_square 15 turn] 7 repeat
  show_page
}

The way it works is that new_page redirects the standard output to a temporary postscript file, and show_page converts the postscript file to a PDF file and opens it using the default viewer in the shell. So those of you who remember Logo, should immediately see the inspiration for the system.

I figure that most computers have either a Postscript viewer or a PDF viewer, and that I can bundle the open-source ghost script package with the Cat download.

This has been an interesting exercise in that because it involves IO and stream redirection it has forced me to think more in depth about the effect system, and whether it is complete. In Cat functions either have side-effects or they don’t. Any function containing a side-effect has a side-effect, and can’t be moved or rewritten by the optimizer. However the compiler can still break functions up into effect and non-effect components. This is due to the property of Cat that any function can be broken up into two valid functions between any two top-level (non-quoted) terms. In other words { f1 f2 f3 } is the same as { (f1 f2) f3 } and is the same as { f1 (f2 f3) }.

I have been considering the fact that side effects can be easily classified into three categories:

  • local - to a scope, block, function, object, thread, or module
  • global - to the entire program (effects that mess with the entire program … yuck)
  • universal - to the external world

This is not a completely fleshed out hypothesis, but the core of the idea rests on the observation that most of the time IO operations must all follow in sequence to make sense. However when two modules allow state manipulation but are self-contained, it doesn’t matter if I affect module A and module B at the same time. If module A and B ever have universal effects, they have to be coordinate to some degree, with each other (or at least synchornized to the universal effect flow).

All of this seems to have a parallel with concurrency and data flow. In my imagination there is a flow chart of effects, where independant modules have separate paths and module effects occur at key points along the path. Universal effects are like a single path that other paths have to coordinate with at key points. I know it is vague and abstract, but it might give you some ideas what I am dealing with.

I’d be interested in hearing other people’s thoughts on the subject of effect systems.

Leave a Reply

You must be logged in to post a comment.