# Can a program language be malleable enough to allow programs to extend language semantics

With reference to features in languages like ruby (and javascript), which allow a programmer to extend/override classes any time after defining it (including classes like String), is it theoretically feasible to design a language which can allow programs to later on extend its semantics.

ex: Ruby does not allow multiple inheritance, yet can I extend/override the default language behaviour to allow an implementation of multiple inheritance.

Are there any other languages which allow this? Is this actually a subject of concern for language designers? Looking at the choice of using ruby for building rails framework for web application development, such languages may be very powerful to allow designing frameworks(or DSLs) for wide variety of applications.

## migrated from cstheory.stackexchange.comApr 29 '12 at 3:29

This question came from our site for theoretical computer scientists and researchers in related fields.

• Do you count as semantic extensions Scheme's hygienic macros or newspeak's reflection that allow exceptions to be implemented as library code? What about syntactic extensions like Perligata:Romana? – Mike Samuel Apr 28 '12 at 22:55
• This seems to be a question asking for a list of languages rather than concepts. Pending edits changing the direction of the question, I virtually vote to close as offtopic. – Raphael Apr 29 '12 at 12:04
• If I remember correctly, even Java is going to get features that allow programs to extend the type system. – Raphael Apr 29 '12 at 12:05
• @Raphael, are you thinking of JSR 305? Java annotations were designed (in part) by Gilad Bracha who designed Newspeak which I linked in my answer below and also championed pluggable type systems. JSR 305 supplies type system annotations like @Nullable and @NonNull which are used by external checkers like findbugs. – Mike Samuel Apr 29 '12 at 17:55
• Unclear what is meant with "extending its semantics". If I look at Boost.Spirit, that is crossing my personal threshold of "extending semantics" already: The mathematical operators of C++ are used to describe a language syntax instead, which the compiler then turns into a parser for said language. I know this isn't what is meant by "extending language semantics" by the lab rats, but I think it is pretty impressive. – DevSolar May 3 '16 at 13:37

Converge has some pretty impressive meta-programming facilities.

At a simple level, this can be seen as a macro-like facility, although it is more powerful than most existing macro facilities as arbitrary code can be run at compile-time. Using this, one can interact with the compiler, and generate code safely and easily as ITrees (a.k.a. abstract syntax trees).

which is a step up from Scheme's hygienic macros that allow referentially transparent macro definitions.

Mechanisms like quasiliterals have allowed constructing and destructuring of parse trees in other languages, but those are more often used for interacting with domain-specific languages (DSLs) instead of self-modification.

Newspeak's reflection allow exceptions to be implemented as library code.

## 7.6 Exception Handling

Because Newspeak provides reflective access (7.2) to the activation records(3.6), exception handling is purely a library issue. The platform will provide a standard library that supports throwing, catching and resuming exceptions, much as in Smalltalk.

Perligata:Romana demonstrates how an entirely new syntax can be skinned onto a language.

This paper describes a Perl module -- Lingua::Romana::Perligata -- that makes it possible to write Perl programs in Latin.

Arguably not semantically significant, PyPy is an interpreter generator for languages whose semantics are specified in a highly statically-analyzable subset of Python, and they use it to experiment with new language constructs in Python like adding thunks to the language.

Also of interest might be Ometa.

This dissertation focuses on experimentation in computer science. In particular, I will show that new programming languages and constructs designed specifically to support experimentation can substantially simplify the jobs of researchers and programmers alike.

I present work that addresses two very different kinds of experimentation. The ﬁrst aims to help programming language researchers experiment with their ideas, by making it easier for them to prototype new programming languages and extensions to existing languages. The other investigates experimentation as a programming paradigm, by enabling programs themselves to experiment with different actions and possibilities— in other words, it is an attempt to provide language support for what if...? or possible worlds reasoning.

Alex Warth's dissertation demonstrates using an Ometa to define significantly new semantics (transactional semantics via worlds) in JavaScript+Ometa.

"Is it theoretically feasible?*

Of course, it is. One can always write an interpreter in a language ($L$) for another language ($S$), and write programs in the new language. People do not often do this because it might involve a lot of work to write such an interpreter and there will be a performance hit (a factor of 10-100) for the additional layer of interpretation.

Both the problems have solutions. The language $L$ can be designed with powerful metaprogramming facilities so that it is easy to implement interpreters. Languages like Scheme have this.

One can implement a partial evaluator so that the interpreter can be turned into a compiler (from $S$ to $L$). Then you don't get the performance hit because the additional interpretation layer is eliminated.

The new language might still run slowly if its run-time model is significantly different from the implementation language. In that case, bits of the interpreter will show up in the translated code and it will continue to run slow. However, if the new language is mostly the same as the original language, with only a few tweaks, then it should be possible to eliminate most of the interpreter bits in the target code by careful tuning of partial evaluation. Then the performance hit will be there for only the new features.

In effect, this is the "virtualization" technology for programming languages.

Historically, Lisp was the first major programming language to introduce metaprogramming facilities. Lisp's macro system allows the programmer to define new control structures, new data templates, etc. For example, the Common Lisp Object System can be defined entirely with macros above a core language that knows nothing about objects or classes. The macro system also allows the definition of domain-specific languages.

Ruby got a lot of inspiration from Lisp, including its capacity for reflectivity and metaprogramming. A lot of dynamically-typed languages have taken inspiration from Lisp in this respect. (Static typing complicates things, because many extensions do not fit in the original type system.)