Meta

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 languageL
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:

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.

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
classPerson,
fieldweight,
and methodBMI.

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.

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.

Implications

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

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.

Meta<L> can do more while writing less. This has impacts on both
readability and writability of code.

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

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.

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.

Meta(Oopl)

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