Warning: readfile(/var/www/header.html) [function.readfile]: failed to open stream: No such file or directory in /var/www/website/fragments/fragments.inc on line 6
12 Dylan Fragments: Macros
Warning: readfile(/var/www/menu.html) [function.readfile]: failed to open stream: No such file or directory in /var/www/website/fragments/fragments.inc on line 8

[ All Fragments ]

Macros

Dylan allows you to create new control constructs and other high-level forms. They can be used to automatically release resources, simplify class creation, or adapt Dylan for a specific problem domain.

In the following example, we create a with-mutex statement that automatically acquires and releases a POSIX mutex. Once again, we import the necessary functions from C.

Dylan macros are part of the compiler, not a preprocessor. This means that they can pay attention to the grammar of the language. They're also hygienic, which means they can't suffer name clashes with surrounding code. (In the example below, mutex in the macro expansion would not be seen by the expressions in ?code.)

define interface
  #include "pthread.h",
    import: {"pthread_mutex_t",
	     "pthread_mutex_init",
	     "pthread_mutex_destroy",
	     "pthread_mutex_lock",
	     "pthread_mutex_unlock"};
end interface;

define function check-error(errno :: <integer>) => ()
  if (errno < 0)
    error("POSIX error %d occured in pthreads wrapper", errno);
  end if;
end function;

define macro with-mutex
  { with-mutex (?mutex:expression) ?code:body end }
    => { let mutex = ?mutex;
	 check-error(pthread-mutex-lock(mutex));
	 block ()
	   ?code
	 cleanup
	   check-error(pthread-mutex-unlock(mutex));
	 end block; }
end with-mutex;

define variable mutex = make(<pthread-mutex-t>);
check-error(pthread-mutex-init(mutex, null-pointer));

with-mutex (mutex)
  format(*standard-output*, "The mutex is locked.\n");
end;

check-error(pthread-mutex-destroy(mutex));