User defined atoms are specified using a small collection of C-functions. Take you inspiration from any of the pre-defined types shown below.
MODULE color;
COMMAND color.blue(X_0:color):int;
COMMENT "";
COMMAND color.cb(X_0:color):int;
COMMENT "";
COMMAND color.color(X_0:str):color;
COMMENT "";
COMMAND color.cr(X_0:color):int;
COMMENT "";
COMMAND color.green(X_0:color):int;
COMMENT "";
COMMAND color.hsv(X_0:flt, X_1:flt, X_2:flt):color;
COMMENT "";
COMMAND color.hue(X_0:color):flt;
COMMENT "";
COMMAND color.hue(X_0:color):int;
COMMENT "";
COMMAND color.luminance(X_0:color):int;
COMMENT "";
COMMAND color.red(X_0:color):int;
COMMENT "";
COMMAND color.rgb(X_0:int, X_1:int, X_2:int):color;
COMMENT "";
COMMAND color.saturation(X_0:color):flt;
COMMENT "";
COMMAND color.saturation(X_0:color):int;
COMMENT "";
COMMAND color.str(X_0:color):str;
COMMENT "";
COMMAND color.value(X_0:color):flt;
COMMENT "";
COMMAND color.value(X_0:color):int;
COMMENT "";
COMMAND color.ycc(X_0:int, X_1:int, X_2:int):color;
COMMENT "";
MODULE batcolor;
COMMAND batcolor.blue(X_0:bat[:color]):bat[:int];
COMMENT "";
COMMAND batcolor.cb(X_0:bat[:color]):bat[:int];
COMMENT "";
COMMAND batcolor.color(X_0:bat[:str]):bat[:color];
COMMENT "";
COMMAND batcolor.cr(X_0:bat[:color]):bat[:int];
COMMENT "";
COMMAND batcolor.green(X_0:bat[:color]):bat[:int];
COMMENT "";
COMMAND batcolor.hsv(X_0:bat[:flt], X_1:bat[:flt], X_2:bat[:flt]):bat[:color];
COMMENT "";
COMMAND batcolor.hue(X_0:bat[:color]):bat[:flt];
COMMENT "";
COMMAND batcolor.hue(X_0:bat[:color]):bat[:int];
COMMENT "";
COMMAND batcolor.luminance(X_0:bat[:color]):bat[:int];
COMMENT "";
COMMAND batcolor.red(X_0:bat[:color]):bat[:int];
COMMENT "";
COMMAND batcolor.rgb(X_0:bat[:int], X_1:bat[:int], X_2:bat[:int]):bat[:color];
COMMENT "";
COMMAND batcolor.saturation(X_0:bat[:color]):bat[:flt];
COMMENT "";
COMMAND batcolor.saturation(X_0:bat[:color]):bat[:int];
COMMENT "";
COMMAND batcolor.str(X_0:bat[:color]):bat[:str];
COMMENT "";
COMMAND batcolor.value(X_0:bat[:color]):bat[:flt];
COMMENT "";
COMMAND batcolor.value(X_0:bat[:color]):bat[:int];
COMMENT "";
COMMAND batcolor.ycc(X_0:bat[:flt], X_1:bat[:flt], X_2:bat[:flt]):bat[:color];
COMMENT "";
MODULE blob;
COMMAND blob.blob(X_0:blob):blob;
COMMENT "";
COMMAND blob.blob(X_0:str):blob;
COMMENT "";
COMMAND blob.nitems(X_0:blob):int;
COMMENT "";
COMMAND blob.prelude():void;
COMMENT "";
COMMAND blob.toblob(X_0:str):blob;
COMMENT "";
MODULE batblob;
PATTERN batblob.nitems(X_0:bat[:blob]):bat[:int];
COMMENT "";
PATTERN batblob.nitems(X_0:bat[:blob], X_1:bat[:oid]):bat[:int];
COMMENT "";
MODULE inet;
COMMAND inet.!=(X_0:inet, X_1:inet):bit;
COMMENT "";
COMMAND inet.<(X_0:inet, X_1:inet):bit;
COMMENT "";
COMMAND inet.<<(X_0:inet, X_1:inet):bit;
COMMENT "";
COMMAND inet.<<=(X_0:inet, X_1:inet):bit;
COMMENT "";
COMMAND inet.<=(X_0:inet, X_1:inet):bit;
COMMENT "";
COMMAND inet.=(X_0:inet, X_1:inet):bit;
COMMENT "";
COMMAND inet.>(X_0:inet, X_1:inet):bit;
COMMENT "";
COMMAND inet.>=(X_0:inet, X_1:inet):bit;
COMMENT "";
COMMAND inet.>>(X_0:inet, X_1:inet):bit;
COMMENT "";
COMMAND inet.>>=(X_0:inet, X_1:inet):bit;
COMMENT "";
COMMAND inet.abbrev(X_0:inet):str;
COMMENT "";
COMMAND inet.broadcast(X_0:inet):inet;
COMMENT "";
COMMAND inet.host(X_0:inet):str;
COMMENT "";
COMMAND inet.hostmask(X_0:inet):inet;
COMMENT "";
COMMAND inet.isnil(X_0:inet):bit;
COMMENT "";
COMMAND inet.masklen(X_0:inet):int;
COMMENT "";
COMMAND inet.netmask(X_0:inet):inet;
COMMENT "";
COMMAND inet.network(X_0:inet):inet;
COMMENT "";
COMMAND inet.new(X_0:str):inet;
COMMENT "";
COMMAND inet.setmasklen(X_0:inet, X_1:int):inet;
COMMENT "";
COMMAND inet.text(X_0:inet):str;
COMMENT "";
MODULE uuid;
COMMAND uuid.isaUUID(X_0:str):bit;
COMMENT "";
UNSAFE COMMAND uuid.new():uuid;
COMMENT "";
UNSAFE COMMAND uuid.new(X_0:int):uuid;
COMMENT "";
COMMAND uuid.str(X_0:uuid):str;
COMMENT "";
COMMAND uuid.uuid(X_0:str):uuid;
COMMENT "";
MODULE batuuid;
COMMAND batuuid.isaUUID(X_0:bat[:str]):bat[:bit];
COMMENT "";
UNSAFE COMMAND batuuid.new(X_0:bat[:int]):bat[:uuid];
COMMENT "";
MODULE url;
COMMAND url.getAnchor(X_0:url):str;
COMMENT "";
COMMAND url.getBasename(X_0:url):str;
COMMENT "";
COMMAND url.getContext(X_0:url):str;
COMMENT "";
COMMAND url.getDomain(X_0:url):str;
COMMENT "";
COMMAND url.getExtension(X_0:url):str;
COMMENT "";
COMMAND url.getFile(X_0:url):str;
COMMENT "";
COMMAND url.getHost(X_0:url):str;
COMMENT "";
COMMAND url.getPort(X_0:url):str;
COMMENT "";
COMMAND url.getProtocol(X_0:url):str;
COMMENT "";
COMMAND url.getQuery(X_0:url):str;
COMMENT "";
COMMAND url.getRobotURL(X_0:url):str;
COMMENT "";
COMMAND url.getUser(X_0:url):str;
COMMENT "";
COMMAND url.isaURL(X_0:str):bit;
COMMENT "";
COMMAND url.new(X_0:str, X_1:str, X_2:str):url;
COMMENT "";
COMMAND url.new(X_0:str, X_1:str, X_2:int, X_3:str):url;
COMMENT "";
COMMAND url.url(X_0:str):url;
COMMENT "";
COMMAND url.url(X_0:url):url;
COMMENT "";
MODULE xml;
COMMAND xml.aggr(X_0:bat[:xml]):xml;
COMMENT "";
COMMAND xml.attribute(X_0:str, X_1:str):xml;
COMMENT "";
COMMAND xml.comment(X_0:str):xml;
COMMENT "";
COMMAND xml.concat(X_0:xml, X_1:xml):xml;
COMMENT "";
COMMAND xml.content(X_0:str):xml;
COMMENT "";
COMMAND xml.document(X_0:str):xml;
COMMENT "";
COMMAND xml.element(X_0:str, X_1:xml, X_2:xml, X_3:xml):xml;
COMMENT "";
COMMAND xml.element(X_0:str, X_1:xml):xml;
COMMENT "";
COMMAND xml.epilogue():void;
COMMENT "";
PATTERN xml.forest(X_0:xml...):xml;
COMMENT "";
COMMAND xml.isdocument(X_0:str):bit;
COMMENT "";
COMMAND xml.parse(X_0:str, X_1:str, X_2:str):xml;
COMMENT "";
COMMAND xml.pi(X_0:str, X_1:str):xml;
COMMENT "";
COMMAND xml.prelude():void;
COMMENT "";
COMMAND xml.root(X_0:xml, X_1:str, X_2:str):xml;
COMMENT "";
COMMAND xml.str(X_0:xml):str;
COMMENT "";
COMMAND xml.subaggr(X_0:bat[:xml], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:xml];
COMMENT "";
COMMAND xml.subaggr(X_0:bat[:xml], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:xml];
COMMENT "";
COMMAND xml.text(X_0:xml):str;
COMMENT "";
COMMAND xml.xml(X_0:str):xml;
COMMENT "";
MODULE batxml;
COMMAND batxml.attribute(X_0:str, X_1:bat[:str]):bat[:xml];
COMMENT "";
COMMAND batxml.comment(X_0:bat[:str]):bat[:xml];
COMMENT "";
COMMAND batxml.concat(X_0:bat[:xml], X_1:bat[:xml]):bat[:xml];
COMMENT "";
COMMAND batxml.content(X_0:bat[:str]):bat[:xml];
COMMENT "";
COMMAND batxml.document(X_0:bat[:str]):bat[:xml];
COMMENT "";
COMMAND batxml.element(X_0:str, X_1:xml, X_2:xml, X_3:bat[:xml]):bat[:xml];
COMMENT "";
COMMAND batxml.element(X_0:str, X_1:bat[:xml]):bat[:xml];
COMMENT "";
PATTERN batxml.forest(X_0:bat[:xml]...):bat[:xml];
COMMENT "";
COMMAND batxml.isdocument(X_0:bat[:str]):bat[:bit];
COMMENT "";
COMMAND batxml.options(X_0:str, X_1:str, X_2:bat[:xml]):bat[:xml];
COMMENT "";
COMMAND batxml.parse(X_0:str, X_1:bat[:str], X_2:str):bat[:xml];
COMMENT "";
COMMAND batxml.pi(X_0:str, X_1:bat[:xml]):bat[:xml];
COMMENT "";
COMMAND batxml.root(X_0:bat[:xml], X_1:str, X_2:str):bat[:xml];
COMMENT "";
COMMAND batxml.serialize(X_0:bat[:xml]):bat[:str];
COMMENT "";
COMMAND batxml.str(X_0:bat[:xml]):bat[:str];
COMMENT "";
COMMAND batxml.text(X_0:bat[:xml]):bat[:str];
COMMENT "";
COMMAND batxml.xml(X_0:bat[:str]):bat[:xml];
COMMENT "";
COMMAND batxml.xquery(X_0:bat[:str], X_1:str):bat[:xml];
COMMENT "";