Welcome to Meta.

Meta From The Bottom Up: Example Programs

One of the central aims of Meta is the augmententation of pre-existing languages, where augmentation means numerous things (more readable code, more expressive code, more concise code, new features and idioms, etc.). This augmentation is provided by introducing a family of new languages that each extend an underlying pre-existing language with new syntax and associated semantics. Thus, Meta<C++> is a programming language that extends C++ (and provides a concrete set of object-oriented features whether or not they exist natively within C++). Meta<C++> shares certain syntax in common with C++ (statement-level syntax and below), but introduces new syntax for concepts above the level of statements (e.g. for defining fields, methods, classes, namespaces and everything else outside of a method body). Similarly, Meta<Java> is a programming language that extends Java (and provides a concrete set of features whether or not they exist natively within Java). High-level language features (the same ones guaranteed by Meta<C++>). Meta<Java> shares some syntax in common with Java (statement-level syntax and below), and introduces new syntax for concepts above the level of statements. In general, for any existing base language L supported by Meta, Meta defines Meta<L>, which provides guarantees about the existence of certain language features whether or not they exist natively within L, and introduces new syntax (shared across all Meta<L> languages) for high-level concepts.

Figure 2: Example Meta<C++> code.

Figure 1: Example Meta<Python> code.

Another of the central aims of Meta is the unification of families of languages. Consider the family of object-oriented programming languages. C++ is an object-oriented programming language with a certain set of features and capabilities. Java is also an object-oriented programming language, with some features in common with C++, and some differences. The same is true of Python, Perl, Javascript and all the other languages with object-oriented features. Each language has its only set of strengths and weaknesses, some shared features, idioms and syntax, and various differences. As mentioned above, Meta<L> shares statement level syntax with base language L, but what allows Meta to act as a unifier of languages is that the new syntax introduced by Meta<L> (for syntax above the level of statements) is exactly the same as for Meta<L'>. The way one defines a field, a method, a class, a namespace (and many other syntactic and semantic concepts associated with object-oriented programming languages) is exactly the same in Meta<C++> as it is in Meta<Java> as it is in Meta<Python>; it is unified across an entire family of languages. This has an important role in how quickly one can learn a new language, to addressing legacy code issues to creating multi-language libraries (more on these and more later).

Figure 1 shows a toy Meta<Python> program, and Figure 2 shows the same program written in Meta<C++>. Note that both programs are exactly the same except in lines 15-17 and 24-25. Those lines consist of statement-level syntax, and a Meta<Python> program shares statement-level syntax with Python, while a Meta<C++> program shares statement-level syntax with C++. A person familiar with object-oriented concepts (classes/methods/fields, visibility/inheritance/invocation, etc.) can easily understand the basics of these programs even without any discussion of the semantics behind the syntax (that is, the syntax is intuitive), but the structure of the syntax makes it easy to document every aspect of Meta and make it easy to discover. A person familiar with C++ can be writing Meta<C++> code in minutes, and the same is true for someone familiar with Python starting to write Meta<Python>, etc. [1] , but the rest of the program is the same in Meta<Python> and Meta<C++>, even though the syntax used to define classes, methods, fields, etc. in Python and C++ is very different (an example of Meta's goal to provide language unification).

Meta Syntax

Meta syntax consists of exactly one self-contained syntactic construct, referred to simply as a construct. There are different kinds of constructs (fields, methods, classes, namespaces, and many others), but every construct has the same overall structure; each construct is a collection of attributes followed by an (often optional) construct terminator.

In Meta, an attribute is a key/value pair, coupled with meta-information that influences how an attribute is parsed. For example, each attribute value has a type that influences how it is tokenized, some attribute keys are optional, some attribute values are optional, some attribute keys have aliases/abbrevs by which they can be referenced, etc. Attributes comes in three flavors:

  1. feature attributes:
    • Keys are always optional
    • Values come from a pre-defined fixed set of words
    • These attributes always appear before the primary attribute
    • Example: the visibility attribute is defined on various Meta constructs, with values limitied to (for example), public, protected and private.

  2. primary attribute:
    • The primary attribute key is the name of a construct, and is always present (it or an alias), as it defines what other attributes are legal.
    • The primary attribute value is a unique identifier for this construct (unique only amongst all over constructs at the same block level). Some constructs have optional primary values (if not provided, Meta auto-assigns a unique id).
    • Each construct has exactly one primary attribute.
    • Examples include class Person, field weight, and method BMI.

  3. secondary attributes:
    • Keys are usually required but sometimes optional.
    • Values can vary from a simple identifier to a complex block containing arbitrarily nested sub-constructs).
    • Secondary attributes always appear after the primary attribute.
    • A simple example is the returns secondary attribute of the method construct, whose value is a Meta type (more on types in Meta later).
    • A more complex example is the scope secondary attribute, whose value is a block of zero or more constructs. The type of this attribute is referred to as a complex-block to distinguish it from something like the comment secondary attribute whose value is a block of zero or more lines of arbitrary text, referred to as a simple-block.
    • Meta provides various secondary attribute value types, ranging from ids to words to strings to lists of ids to simple-blocks and complex-blocks.
In Figure 1 and 2, some of the syntactic aspects of Meta are highlighted via color coding: primary attribute keys, secondary attribute keys, feature attribute values, Meta primitive types, and constructor terminators. The entirety of Figure 1 is a single instance of the class construct, and its id (primary attribute value) is Person. Two of the secondary attributes defined on class constructs are comment (whose value is a "simple block", an arbitrary collection of lines of text) and scope (whose value is a "complex block" containing zero or more construct instances). In our example, the comment attribute has as a value a single line of text ("A simple Person class."), and the scope attibute has as a value a list of 6 constructs (5 fields, 1 initializer, and 1 method). Block-valued attributes (simple or complex) can be indicating one of two ways, via indentation (ala python) or by using block-start/end syntax (curly braces ala C++, Java, etc.). This example uses the indentation-based approach, which is generally more readable.

The Meta Compiler

Meta provides a compiler that converts a Meta<L> program into a program written entirely in base language L. Thus, a Meta<C++> program is compiled into a C++ program, a Meta<Java> program is compiled into Java, etc.

Compiling a Meta<C++> program involves generating C++ code. For statement-level code, this is trivial (code within Meta<C++> methods are C++ code, and are copied verbatim). For higher-level meta syntax (definitions of classes, methods, fields, etc.), appropriate C++ is generated by the metac compiler. Similarly, compiling Meta<Python> code involves generating Python code. In general, compiling Meta<L> involves generating base language L code.

A particular base language may not directly support a particular feature guaranteed by Meta, but such features can always be emulated in any turing-complete language with enough effort (although doing so efficiently is sometimes another matter).

Meta From The Top Down

Meta is:

  • a high-level source-based programming environment for augmenting and unifying families of languages.
  • a flexible, unified, general-purpose syntax for describing data and code.
  • a collection of meta-languages, each of which represents a hierarchy of languages for capturing the similiarites between members of a family of related languages.

Meta is a hierarchy of languages built on top of pre-existing languages that provides:

  • Increased expressivity (more impact, less code)
  • Augmentation
  • Unification
  • Readability
  • Writability

Meta Languages

Meta is not just about object-oriented languages. Consider the family of type-setting languages (HTML, TeX, wiki markup, Markdown, etc.). Meta can do for type-setting languages the same thing it does for object-oriented languages (augmentation and unification). That is, it can provide Meta<HTML> to augment HTML, Meta<TeX> to augment TeX, and so on. These new languages share some syntax in common with their base language, and share some syntax in common with one another. More generally, Meta provides facilitiates for augmenting and unifying any family of languages.

The syntax/semantics needed for object-oriented programming languages (classes, methods, fields, etc.) is obviously quite different than the syntax needed for type-setting languages (articles, chapters, sections, etc.), which leads us to the concept of a Meta-language. At a high-level, Meta provides a mechanism for defining Meta-languages, where a Meta-language is a hierarchy of languages built on top of a family of pre-existing languages that augment and unify those pre-existing languages. Each Meta-language identifies the set of features it deems canonical, and ensures that those features are available to users regardless of whether a particular base language has that feature. Each Meta-language also defines new syntax that can be shared amongst all of its augmented languages (more on this below).

One such Meta-language is denoted Meta(Oopl), which augments and unifies the family of Object-Oriented Proramming Languages. Meta(Oopl) identifies a supported set of base languages (e.g. C++, Java, Python, Perl, Javascript, with more added incrementally over time), and defines augmented versions of each (Meta<C++>, Meta<Java>, etc.) that ensure support for a long list of object-oriented features regardless of whether the base languages themselves do. Another Meta-language is denoted Meta(Doc), which augments and unifies the family of type-setting languages. Meta(Doc) identifies a supported set of base languages (e.g. HTML, latex, Markdown, with more added incrementally over time), and defines augmented versions of each (Meta<HTML>, Meta<LaTeX>, Meta<Markdown>, etc.) that ensure support for a long list of type-setting featues regardless of whether the base languages themselves do.

Note that Meta<C++> is more properly denoted Meta(Oopl)<C++>, Meta<Java> is more properly denoted Meta(Oopl)<Java>, etc., but one can usually establish the Meta-language from the base language alone, so it is easy to see that Meta<C++> refers to Meta(Oopl)<C++> and that Meta<HTML> refers to Meta(Doc)<HTML>.

Figure 4: Example Meta(Oopl)* code.

Figure 3: Example Meta<Python|C++> code.

The Meta(Oopl) Language Hierarchy

As already mentioned, the Meta<C++> syntax used to define a class, or method, or field (or various other high-level construct needed in an object-oriented programming language) is exactly the same as that used in Meta<Python> or Meta<Java> or Meta<L> (for any object-oriented baselanguage L' that Meta supports). That is, high-level syntax is unified across all base languages in a family of languages. What this means is that a program written in, for example, Meta<Python> is implicitly also partially implemented in Meta<Java>, Meta<C++>, etc. Specifically, although a Meta<Python> program does not provide any statement-level information about the corresponding Meta<Java> or Meta<C++> implementation, the Meta<Python> program does provide complete information about the overall structure of each class (its methods and fields, what namespace it belongs to, its inheritance hierarchy, etc.) in Meta<C++>, Meta<Java> or arbitrary Meta<L>.

The above observation, and, more viscerally, the similarity between Figure 1 and Figure 2, suggests a way in which Meta could do even more in its goal to augment and unify languages. What if there was a means of specifying statement-level Python and C++ (and any base language L) code in the same Meta program? This would have significant benefits in any situation where code is being maintained in dual languages (for example, rapid prototyping in one language followed by formal implementation in another more efficient language, implementing "native" C++ methods in a Java or Python or Perl program, legacy code migration, etc.) and makes cross-language libraries (we might even call these ... meta-libraries) a real possibility.

Figure 3 shows how Meta can accomplish this, by adding one simple extension to its syntax. By allowing attribute keys to be qualified by a base-language indicator, we can provide base-language specific values for any attribute, including the crucial scope attribute which defines (for the method construct) the body of the method. The resulting program can be referred to as a Meta<Python|C++> program to indicate that it has both Python and C++ code. The meta compiler can thus be invoked on this single program and compiled into either C++ and Python at the user's discretion.

This in turn suggests an entire hierarchy of Meta languages. In addition to Meta<Python|C++> there is Meta<Perl|Java> and Meta<Javascript|Ruby> and Meta<C++|Java|Python> and Meta<C++|Java|Python|Javascript|Perl> and every other combination of the base languages Meta provides support for.

Being able to specify statement-level code in multiple base languages at the same time within a single Meta program obviously suggests yet another level of potential language unification. If Meta were to define its own syntax for statements, there would be no need to provide base-language-specific statements, and yet the Meta compiler would be able to compile the program into any base language supported by Meta. This language is denoted as Meta(Oopl)*, and Figure 4 shows an example.

Meta(Oopl)* is the fixed-point closure language of Meta(Oopl) at the top of the language hierarchy formed by base languages L, L', L'', ... (at the bottom), Meta<L>, Meta<L'>, Meta<L''>, ... (at the second level), Meta<L|L'>, Meta<L|L''>, ... (at the third level), Meta (at higher levels), and finally Meta(Oopl)* at the top of the hierarchy. Figure 5 summarizes this language hierarchy for Meta(Oopl).

Although Meta(Oopl)* offers a significant benefit in situations where the exact same code is desired in many languages at the same time, there is a downside of Meta(Oopl)* ... the conciseness with which statement-level syntax can be specified in Meta(Oopl)*, constrained as it is by the simple everything-is-a-construct attribute key/value paradigm, does not always compare favorable with the equivalent base-language statement-level syntax (this is problematic because statement-level syntax is the most heavily used and thus most important to be concise). This lack-of-conciseness of Meta(Oopl)* for statement-level constructs is in contrast to its syntax for higher-level constructs (methods, fields, classes, etc.), which usually compares very favorably with respect to conciseness relative to the equivalent syntax in base languages.

Consider Figure 4. One of the secondary attributes of the initializer construct is scope<*>, whose value is a complex-block (a block containing zero or more statement-level meta constructs). In our example, we need to invoke three setter methods to initialize the name, height and weight fields respectively. The first line in the scope shows the verbose version of the call construct, which makes clear the key/value attribute pairs making up the construct. In particular, the primary key is call and its value is a unique identifier for that call-site within its calling scope (we use '_' in the example). The call defines (amongst others) the following secondary attributes:

  • on, which specifies the receiver of the message.
  • message, which specifies the name of the method being invoked.
  • arglist, which specifies the args to the list.
  • ... various other attributes to handle more complex calls, for example when an argument is another method invocation, etc.

The second line of this method shows how the hyper-verbose syntax of the first line can be improved, by:

  • By providing the abbrev @ for call, we can indicate the call construct with a single character.
  • By allowing for optional attribute values, Meta can support situations where the primary attribute value (the id) is optional (when not explicitly provided, a unique id is auto-assigned by the Meta compiler). Although being able to identify a particular call-site by name is sometimes useful, it is rarely needed, so auto-assignment of unique ids works well here.
  • By providing the abbrev . for message, we get to use familar syntax common to most OO languages.
  • By providing the abbrev ( for arglist, we get what looks like a simple parethesized list while still abiding by our everything-is-a-construct syntax.
  • By providing a special secondary attribute endarglist with abbrev ) and optional value, we can finish the parethensized list started above. This is admittedly rather ... "esoteric" aka hacky, but allows us to get close to the syntax used in most programming languages).

The third line of this method shows a few final improvements in syntax:

  • By allowing for optional attribute keys, Meta can support situations where the on attribute key is not present.
  • By not requiring whitespace between tokens when they can be uniquely identified without whitespace, we manage to get syntax that is only one character more verbose than exists in most languages. However, this only applies for trivial method invocations. For more complex invocations where the receiver or args are themselves method calls or expressions, Meta(Oopl)* syntax is inevitable more cumbersome than base-language syntax.

Figure 5: The Meta(Oopl)* language hierarchy.

The method construct also supports the complex-block-valued secondary attribute scope<*>, and the code in Figure 4 highlights where Meta(Oopl)* syntax can be more cumbersome than its base-language equivalent. A simple expression in C++ or Java may need to be broken up into multiple statements to get it into a form supportable by Meta. However, continued improvements in how Meta can support concise readable familiar statement-level syntax while keeping the "everything-is-a-construct" rule will make Meta(Oopl)* more and more convenient as the implemention evolves.

Fortunately, an implementation in Meta(Oopl)* is often unnecessary, or can at least be delayed and incrementally moved toward. In fact, there is a very natural incremental transition possible from implementations in languages at the bottom of the hierarchy to successively higher languages. For example, a Python program can be easily (and to a large part automatically) converted into a Meta<Python> program, which can easily (and incrementally) be converted into a Meta<Python|C++> program, which can easily (and incrementally) be converted into a Meta(Oopl)* program if there is benefit to do so.

The Meta Library

One area where Meta(Oopl)* programs are especially powerful is when one wants to define the exact same code in multiple languages at the same time. Such "multi-language" libraries have a huge benefit when it comes to increasing programmer productivity. Once a programmer knows a few languages, picking up the syntax of a new language is straightforward. It isn't proficiency with language syntax that separates novice programmers from experienced programmers, it is the depth of knowledge one has of the libraries and idioms of the language.

Meta makes it easier to work in multiple languages in two core ways. First, if one knows Python, learning Meta<Python> is trivial, and it is much easier to learn Meta<C++> based on Meta<Python> than it is to learn C++ based on Python, because all of the esoteric C++ syntax above the level of statements is hidden away behind Meta<C++> syntax (the exact same syntax as used in Meta<Python>). Second, if one knows Meta<Python>, it means one knows the Meta Library (a collection of classes and APIs providing useful general-purpose functionality) ... and the Meta Library is implemented in Meta(Oopl)*, which means the exact same library from Meta<Python> is available in Meta<C++>, so the programmer already knows the Meta<C++> library.

The Meta Library can be interpreted in two ways. It is a library provided by Meta (more accurately, by Meta(Oopl). It is also "meta" in that it is language-independent ... the same code and APIs in multiple languages at the same time.


Here are some implications/ramifications of Meta's aim to augment and unify existing languages:

  1. Meta<L> is a proper superset of base language L (it can do everything L can, and also guarantees various features/concepts/idioms regardless of whether they exist natively within L.
  2. Meta<L> can do more while writing less. This has impacts on both readability and writability of code.
  3. A program written in Meta<L>, for some base language L, is also implicitly partially implemented in Meta<L'> (for any other base language L' supported by Meta). For example, a program written in Meta<Java> defines namespaces, classes, methods, fields and various other concepts, and it is only the statements within methods that use Java syntax ... everything else in the program uses Meta<Java> syntax, which is Meta<C++>

Meta From The Middle Ground

Meta provides a very diverse collection of features, some of which are discussed below. Here is a quick summary:

  • Source Code Configuration and Canonicalization
  • The Meta Type System
    • Type Syntax
    • Native Types
  • The Meta Library
  • Meta Schemas: Meta in Meta
  • Native Methods
  • Unit Tests
  • Operators
Augmentation ideas that come from base languages:
  • Java: ability to run code associated with arbitrary class, throws in signatures
  • Python: indentation-based syntax, interactive shell, keyword parameters
  • C++: type system
  • Perl: regexp support
  • Smalltalk: method categories
  • Eiffel: pre and post conditions
  • Tcl: upvar, wish
  • Beta: sub extend, monands

Consistent, Intuitive, Expressive, Readable, Writable, Concise Syntax

The syntax that Meta introduces is designed to be consistent, intuitive, expressive, readable, and concise. But most languages have at least some of these same goals, so how does Meta differ?

Concise and Consistent: One Syntactic Construct

Many languages find that conciseness, consistency and expressivity are sometimes at odds with one another. Even if a language starts out with these as goals, as the language evolves and new syntax is added, some of these goals often suffer.

Meta addresses these issues by have exactly one syntactically legal construct. Everything that can be defined in Meta is a construct. Every construct is a collection of attributes. Syntactically, every construct consists of a key (a single word, often a single character) and a value (the type of which is defined by Meta for the construct in question, and can vary from an identifier to a block of arbitrarily nested constructs). Which attribute keys are legal for a given construct, and which constructs exist, are dictated by the meta-language in question (Meta(Oopl), Meta(Doc), etc), but in all cases, everything is a construct, and every construct is simply a collection of attribute key/value pairs. As such, the consistency of meta syntax is future-proofed ... extensions to the language involve adding new attributes, or extended the type of existing attribute values, but the basics of how one writes a Meta program never changes.

Conciseness is achieved in Meta primarily thru support for source code customization (see the next section), which allows one to introduce arbitrary aliases for existing attribute keys and values. As well, Meta provides support for certain attribute keys being optional (feature attribute keys are always optional, and some secondary keys can be optional as well, depending on context).

Expressivity: Code merging

One of the aims of Meta is to be able to express more with less code. Any non-trivial program written in Meta<L> will involve less code than in the resulting base language L code produced by compilation. For example, in C++, best practice suggests that every class have at least two files files (a header file and a source file). Although there are excellent reasons for this (efficient separate compilation, separation of interface and implementation, etc.), the two-files-per-class idiom puts an unnecessary burden on programmers, as one must edit multiple files (often repeating changes in various places with various minor tweaks). On the other hand, not only is a Meta<C++> class defined in only one file, a meta file can contain an arbitary number of classes from an arbitrary number of namespaces. When the file is compiled, the appropriate per-class header and source files are automatically generated by the Meta<C++> compiler. The redundancy inherent in C++ method declarations vs method definitions, and numerous other subtleties of C++ implementation, are entirely hidden away in Meta<C++> implementations.

Another example of code redundancy has to do with unit testing. Each method should have one or more unit tests, testing the various control flows thru the method. In base languages, these tests are placed in separate files, but in Meta the unit testing code is integrated into the source code; every method construct has a complex-block-valued tests attribute that allows unit tests to be defined adjacent to the code being tested. As well, every class construct has a complex-block-valued tests attribute that allows one to define unit-testing service methods, and every namespace/span> construct has a complex-block-valued tests that allows one to define unit-testing classes. All of the work involved in setting up the proper unit-testing infrastructure is provided by the Meta compiler, across every base language.

In existing languages, comments are often treated as second class citizens, being loosely coupled with the code they are nominally associated with (does this collection of comments refer to the code below, or the code above?). Furthermore, it is easy for comments to get separated from the code being documented. Meta addresses these issues by ensuring that every kind of construct has a simple-block-valued comment attribute that unambiguously identifies which code the comment is associated with and makes it impossible to move the construct without also moving the comment. Furthermore, Meta can properly add comments into multiple places (for example, C++ declaration and definition files, in code and unit tests, etc.), and can auto-generate C++ doxygen, Java javadoc, Perl pod, Python docstrs and all the other base-language documentation idioms ... all without requiring the user to know anything about these low-level issues.

Intuitive, Readable and Writable: Source Code Customization and Canonicalization

The problem with most languages when it comes to intuitive and readable syntax is that different people find different things to be intuitive and readable, whereas most languages offer only a single canonical syntax. One size does not necessarily fit all programmers, but most languages force the same "synactic size" upon them. Meta addresses this by allowing individuals a great deal of customization over the syntax of a Meta program. If you prefer to define your methods using def and/or sub instead of method, you can customize Meta to understand this. Or if you prefer to use the keyword slot and/or property and/or instance_variable and/or data_member instead of field, Meta can allow this. Meta(Oopl) introduces 20+ constructs, 75+ attribute keys, and 100+ feature attribute values (with the number steadily increasing over time) and the user can provide their own abbreviations/aliases/alternatives for any or all of them.

One of the big disadvantages of this kind of "personalized syntax", however, is that it decreases the ease with which another person can read the code. Put another way, one of the advantages of a canonical syntax is that different people can all read the same source code. How can we offer the benefits of personalized syntax without its downsides? This is where Meta's source code canonicalization comes into play. Although a person can dramatically change the overall look and feel of a Meta(Oopl) program, every construct, attribute key and feature value has a canonical representation, and any Meta program can be converted from a personalized syntax to this canonical representation and back again ... or into someone else's personalized syntax. In a multi-person coding project, the canonical representation of the Meta program would be stored in the shared code repository, and individuals would then convert this canonical representation to their personal representation on the fly as desired.

Meta from the top down

Meta-Languages and Base-languages

Meta is a collection of Meta-Languages. A meta-language consists of:

  • a collection of related and similar pre-existing languages (base languages).
  • a schema for describing Meta-level constructs for writing code that can be "compiled" down into base languages.
  • a collection of features guaranteed to be available in the Meta version of a base language, even if it isn't available in the base language itself.

Examples of Meta-Languages one can define in Meta:

  • Oopl: the family of object-oriented programming languages. Base languages include: C++, Java, Python, Perl, etc.
  • Func: the family of functional programming languages. Base languages include: Lisp, Haskel, Erlang, Scheme, etc.
  • Proc: the family of procedural programming languages. Base languages include: C, Pascal, Fortran, Cobol, etc.
  • Doc: the family of type-setting languages. Base languages include: LaTeX, HTML, Markdown, Wiki markup, etc.
  • ...


Meta(Oopl) is one of the meta-languages defined by Meta. It represents a family of object-oriented programming languages and the concepts associated with object-oriented programming.

A program written in Meta(Oopl) is guaranteed to have the following concepts available to it, regardless of whether the baselanguages making up Meta(Oopl) directly support the concept.

  • Constructs
    • namespace
    • class, method, initializer, field
    • category, remark, var, native accessor, assoc
    • test
  • Attributes (commonly appearing in many constructs)
    • comment
    • scope
    • tests
    • config
  • Types
    • Meta Types vs BaseLang Types
    • Passing Semantics
      • by-value
      • by-reference
      • by-pointer
    • class-based enums
  • Inheritance
  • Meta-classes
  • Polymorphism
    • Single-receiver dispatch
    • Multi-method dispatch

Meta-Languages and Base-languages

What follows is really a discussion of Meta(Oopl), but Meta(Oopl) is so central to what Meta is that we will often refer to Meta(Oopl)it as just Meta. Later, we will discuss ways that Meta(Oopl) can be generalized (leading to a more accurate description of what Meta offers).

  • Programming Environment: Meta is a programming environment that augments and unifies families of existing programming languages. Meta is a hierarchy of high-level programming languages. A program written in Meta can be "compiled" down into various pre-existing "base languages".
  • A Set of Meta Languages: Meta is a collection of meta-languages, where each meta-language represents a family of related "base" languages. e.g. One core meta-language of Meta is Meta(Oopl), the family of class-based object-oriented programming languages. Another is Meta(Doc), the family of type-setting languages. Meta makes it easy to define new meta-languages, varying from the very specialized to the very general.
  • A Unifying Syntax on top of existing languages: Meta introduces a very basic syntax ... everything syntactically expressible in Meta is represented by a construct. A construct consists of one or more attributes. An attribute is a key/value pair.
  • A Language Augmenter: Meta is a means of adding new features to a language using existing features of that language.
  • A Language Unifier: Meta is a means of unifying existing languages. Programs written in Meta can a language using existing features of that language.
  • An experiment: Meta is an experiment exploring just how true the old adage "every problem in computing science can be solved with another level of abstraction".

What is Meta(Oopl)?

Meta(Oopl) is what Meta was originally designed for: a means of augmenting and unifying object-oriented programming languages. Meta has since grown beyond its original conception, but its roots as a means of implementing more while coding less are still central.

The collection of all (most) object-oriented programming languages have a number of things in common with one another. They have classes (either as explicit concepts, or as something that can be easily emulated). They have methods


Enter some Meta code in the area below and click Submit.

What base language do you want to compile into?