Comp allows defining a hierarchy of named values that can be used anywhere in the namespace. These are called tags and have several useful properties.
Comp uses tags almost like keywords throughout the language. The builtin boolean types true are and false are just regular tags. Even flow control statements like skip and stop (known as continue and break in many other languages) are just tags.
Tags are defined in a module as a simple hierarchy. Hierarchies from other modules can be extended within an internal module.
!tag severity {high medium low}
!tag comp.bool {maybe}
Comp namespaces work in that any definition can be referenced by its fully qualified name or as just the leaf portion of the name that is non ambiguous. So maybe works just as well as bool.maybe inside of our namespace.
In this case we've extended bool with our own crazy value. But the original module has no knowledge of our extensions. This allows us to extend but not pollute tag hierarchies.
There's a mountain of other details. Tags are the quick and easy way to avoid strings to define types or behaviors. A list of other places tags have an influence on the language.
- Tags are used to define units, which we've already seen in values like
24#secondor"select verion()"#sql. - Tags have a high precedence when morphing structs to shapes, something to demonstrate in a future post.
- This has a profoundly useful impact on assigning parameters to function calls.
- Tags are both shapes and singleton values, which gives them a dual role.
- Tags from unknown modules can be serialized and used as a "raw tag", which can be promote later given a module that can define them.
Top comments (0)