# Asymptote FAQ - Section 7
Questions about programming

- Q7.1. Is Asymptote an interpreter or a compiler?
- Q7.2. What is the difference between a frame and a picture?
- Q7.3. What is the difference between a path and a guide?
- Q7.4. What is a convenient way to declare and initialize an array of pictures?
- Q7.5. Is there a way to define functions that act on arrays in general (i.e. work for arrays of any type)?
- Q7.6. Is there any way to declare structures ahead of their definition, e.g. where struct A performs some operation on struct B, but B contains an A member?
- Q7.7. Where are static variables in for loops allocated?
- Q7.8. Is there a debugger for asy?
- Q7.9. Do you accept patches for Asymptote?

## Question 7.1. Is Asymptote an interpreter or a compiler?

Asymptote compiles Asymptote commands into its own virtual machine code. It then runs this pseudocode on a virtual machine to produce PostScript code.

## Question 7.2. What is the difference between a frame and a picture?

Frames are canvases for drawing in PostScript coordinates. While working with frames directly is occasionally necessary for constructing deferred drawing routines, pictures are usually more convenient to work with. See Q8.8 `In MetaPost, it is possible to have a drawing remain the same size in different pictures by defining a unit `u` and explicitly multiply all the coordinates by `u`. Is there a better way to do this in Asymptote?'.

## Question 7.3. What is the difference between a path and a guide?

A path is a cubic spline with fixed endpoint conditions.

A guide is an unresolved cubic spline (list of cubic-spline nodes and control points). A guide is like a path except that the computation of the cubic spline is deferred until drawing time (when it is resolved into a path); this allows two guides with free endpoint conditions to be joined together smoothly.

## Question 7.4. What is a convenient way to declare and initialize an array of pictures?

You could write yourself a routine such as:

    picture[] picture(int n) {
      picture[] pic;
      for(int i=0; i < n; ++i) {
        pic[i]=new picture;
        size(pic[i],19cm,0);
      }
      return pic;
    }

    picture[] pic=picture(6);

## Question 7.5. Is there a way to define functions that act on arrays in general (i.e. work for arrays of any type)?

Generic types aren't yet implemented.

But for now you can at least say

    typedef string T;
    include F;

    typedef real T;
    include F;

where `F.asy` contains some type-dependent code like

    T[] operator $(T A, T B) {return new T[] {A,B};}

## Question 7.6. Is there any way to declare structures ahead of their definition, e.g. where struct A performs some operation on struct B, but B contains an A member?

Asymptote does not support forward declaration of types. You can, however, nest structures, so that both types are visible for parts of the bodies of both structure definitions. For example:

    struct B {
      typedef void someroutine(B b);

      static struct A {
        someroutine routine;
        void operator init(someroutine routine) {
          this.routine=routine;
        }
      }

      string test="Testing";
    }

    typedef B.A A;

    A a=B.A(new void(B b){write(b.test);});

    B b;
    a.routine(b);

## Question 7.7. Where are static variables in for loops allocated?

In the example

    void f() {
      for(int i=0; i < 3; ++i) {
        static int n;
        ++n;
        write(n);
      }
    }

    f(); // Writes 1, 2, 3

the static qualifier means that `n` is allocated not just outside of the for loop, but also outside the function. This is clear if you call `f` multiple times; there is still only one instance of `n`.

The "level" of a variable (where it is allocated) has nothing to do with the "scope" of a variable (how long it can be referred to by name). The curly braces enclosing a block affect only a variable's scope, not its level.

Static modifiers are meaningless at the top level; they generate a warning and are simply ignored:

    for(int i=0; i < 3; ++i) {
      static int n;
      ++n;
      write(n);
    }
    // Writes warning about top-level static modifier and then 1, 1, 1

Since version 1.22, non-static variables allocated in a loop body are allocated anew every iteration. This is only noticable in obscure cases where a variable in a loop is accessed in the closure of a function defined in the loop:

    int f();

    for(int i=0; i < 10; ++i) {
      int j=10*i;
      if(i == 5)
        f=new int() {return j;};
    }

    write(f()); // Writes 50

Variables in the body of a loop last as long as that iteration of the loop, unless they are kept alive by a function closure as in the example above. In a function body, variables will last at least as long as the function call, though because of closures and garbage collection, they may last longer than that. If defined at the top level of a file or at the interactive prompt, they will last at least until the end of the file or prompt's run.

## Question 7.8. Is there a debugger for asy?

Yes, Asymptote includes a line-based debugger:

https://asymptote.sourceforge.io/doc/Debugger.html

## Question 7.9. Do you accept patches for Asymptote?

Yes, in fact we would prefer that users submit patches for customized features (to http://sourceforge.net/tracker/?atid=685685&group_id=120000) instead of relying on us to do all of the coding. Development will proceed faster that way.

Next: Questions about differences between Asymptote and MetaPost.
Back: Questions about 2D graphs.
Return to contents.

Extracted from Asymptote Frequently Asked Questions, Copyright © 2026 .