What is a scripting language?
Have you ever stumbled upon job offers where companies are looking for “coders” or “scripters”? Every time I see those, I ask myself: what is the difference exactly? How can “scripting” or “coding” be different from programming? Is there even a difference? I could keep listing questions, but I am sure you get my point. With this in mind, I got asked a few times why I am using the term “scripting language” and “programming language” interchangeably, since they represent different concepts. But wait, are they or are they not the same thing? In order to answer this question, we are going to explore what academia has to say about it and combine it with the perspective of a game programmer. Now, what is a scripting language according to academia?
What is a scripting language?
One of the pioneers of the term scripting language is the inventor of Tlc John Ousterhout [1]. Ousterhout defines scripting languages (SL) as programming languages that are intended to work with modules defined in other low-level languages such as C. Moreover, Ousterhout states that they are not meant to be used to write a whole application from scratch. In fact, scripting languages are more often used for plug-and-play situations to enable systems to communicate with each other. The use case of plug and play separates scripting languages from system programming languages [1].
From a game programmer perspective
Ousterhout’s explanation aligns with how the game industry looks at scripting languages, where an SL is defined as a programming language which primary purpose is to permit to control and customize the behavior of the underlaying application (game/game engine). Therefore an SL is a high-level programming language implemented in a lower level language, which exposes most of the application (game engine) features to the developer [9, pp. 954-955].
Based on Ousterhout’s point of view, an SL is just a sub form of a programming language which is defined in a lower level programming language. Following this logic, we can argue that C, for example, is a scripting language, since it is just a syntactic sugar of Assembly. But that is a discussion for another time. If you are interested in this topic, you might want to check Dino Oliva et al. C–: A Portable Assembly Language research paper [2] or Moron Why C Is Not Assembly by James Iry [3]. Anyways, let’s get back to the original question: if an SL is just a programming language, what makes it so different than C, for example? Ousterhout’s states that the main difference is that SLs are interpreted languages while languages like C or Rust are system programming languages.
What is a system programming language?
System programming languages are designed to construct data structures and algorithms from scratch to represent an application. C or Rust are great examples for such languages, since they can be used to construct all possible sorts of data structures due to the fact that essentially, they are a composition of primitive building blocks. Therefore, system programming languages are usually very low level and can represent the most primitive computer elements: words of memory [1]. Moreover, Ousterhout characterizes them as being typed and principally compiled. At the same time, scripting languages are mainly dynamic typed or untyped, and interpreted. [1]
What is an interpreted language?
Interpreted languages differ from compiled languages in that they are not compiled from one language into another language. Compiled languages are in general directly executed on the CPU [4, pp. 1–23]. On the other hand, Linda Torczon & Keith Cooper define an interpreter as a system that “takes as input an executable specification and processes as output the result of executing the specification” [4, p. 3]. Moreover, Linda Torczon & Keith Cooper state that some languages such as Java or Lua use a hybrid approach[4, pp. 1–23]. They compile their source input to a bytecode representation which then gets interpreted by an interpreter, commonly called virtual machine (VM). This mixed-method (also called hybrid method) combines the best of both worlds and can be found in many modern scripting languages [4, pp. 1–23] ,[5, pp. 155–179].
From a game programmer perspective
Hybrid languages are interesting for the game industry since the game industry is pushes computer hardware to its limits to reach maximum performance. This hunt after performance leads to extreme code optimization to keep up with the competition [5, pp. 155–179]. The need for high performance is one of the reasons why languages that are using a mixed-method (hybrid language), such as Lua, are more often used than others.
What are hybrid languages?
Hybrid languages are more performant than purely interpreted languages [5, pp. 155–179] [6, pp. 25–26]. A purely interpreted language consumes more memory and may require pointer traversal. Traversing pointers may lead to random memory access and cache misses. On the contrary, compiling the source code to bytecode - a compact representation of source code - leads to dense and linear instructions [5, pp. 155–179]. CPUs prefer those kinds of instructions since they can be loaded quicker into cache lines [5, pp. 155–179] [7, pp. 1–24]. The structure of bytecode leads to higher performance than the purely interpreted language since they are better accessible to the CPU.
The hybrid method should not be confused with two of the commonly used compilation methods: just in time compilation (JIT) and ahead of time (AOT) compilation. System programming languages are using AOT compilation while most interpreted languages (such as scripting languages) are often using either JIT or AOT. When compiling with AOT, everything gets compiled before running any function and is therefore known to the program. This also means that if something changes, the entire file needs to be recompiled. JIT, on the other hand, means that functions are compiled on demand, i.e. when they are run first. This reduces the load times of an executable [8]. Lua, for example, supports both: standard Lua is AOT while LuaJit is as the name suggested, a JIT Compiler. Therefore AOT and JIT are different methods of compiling code rather than a classification of different methods of language interpretation.
From a game programmer perspective
Out of multiple reasons, it is important to know the kind of compilation method a language supports. First, the game industry tries to get the maximum out of the hardware [5, pp. 155–179], which means that performance is very important, as previously mentioned. Looking at AOT and JIT compilation methods, JIT seems appealing since it might reduce the loading times [8]. The problem is that JIT compilation might not work on all platforms the game is shipping on. Some specific platforms such as game consoles might forbid this technique in their technical requirement checklist (TRC). Therefore, compiling everything in advance might be preferred for such platforms. On the other hand, AOT compilation can also enable transpiling, the possibilities to compile to native code or just to C or C++ code that in return can be compiled. The factors if a language is compiling AOT or JIT are important for choosing the right language to solve a problem.
What does it mean if a Scripting Language is a “extension language”?
Interpreted SL are widely used in other areas than game development, such as artificial intelligence and web development. Python [10] and JavaScript [11] are great examples for such languages. Python is often used for data processing, such as artificial intelligence [12], while JavaScript is commonly used in web development [11]. Besides, JavaScript is used more frequently in game development [13 , 12]. Both Python and JavaScript are part of the evolution of modern scripting languages from simple command-based languages such as Tcl, a pioneer of scripting languages [1], towards complex, nearly general-purpose scripting languages [14]. SL have been greatly evolving ever since their initial introduction, and their use cases vary from the web to artificial intelligence.
Scripting languages can be separated into subcategories such as extension languages or extensible languages. An extensible language is defined as a language that can be extended through external modules in different languages [14]. In contrast, an extension language defines a scripting language that only works within an embedded environment, which is usually called the host program or host application. Often SL offer support for both types. There are more categories than extension and extensible languages such as shell languages [1, 15 ,16], which are not covered, due the focus on game industry relevance. Further research might be needed to establish whether the choice of other subcategories than extension languages has a significant impact within the game industry when it comes to usage as scripting language for game logic or other internal logic.
Extension languages are used to extend the host application with extra functionality [14]. The ability to extend the host program requires customization points within the language itself. These customization points enable the host program to provide custom actions within the embedded language. For this reason, extension languages provide next to their own syntax an application program interface (API), which the host application can use to interact with the embedded language [14,15].
An excellent example for such languages is Lua. The creators R. Ierusalimschy et al, describe Lua as an extensible extension language [15]. Lua allows the host application to communicate with it via its C API and vice versa. Lua can also be extended by the host application with extra functionality [17]. This is also true for other languages such as wren, angelscript or daScript. They all allow the host application to communicate to the VM layer and vice versa. Some of them even offer native code generation.
From a game programmer perspective
The ability to extend the language based on the requirements of the game is important since every game has different requirements. Game engines might want to expose certain functionality to the scripting runtime to empower the scripting environment to communicate to the world created in a higher-level language [9, pp. 954-955]. Lua is a great example for that – on its own, Lua is rather “simple” but once extended, and with its all functionality being exposed from the engine/game to the scripting environment, the language can become extremely powerful and flexible.
Scripting languages ARE programming languages
The conclusion, based on what academia shows about scripting languages, is that they ARE programming languages. They are just a subcategory of programming languages such as system programming languages. We are heavily exposed to scripting languages since they are used on a daily basis to orchestra different tasks and glue code from different worlds together.
References
[1] J. K. Ousterhout, “Scripting: Higher-level programming for the 21st century,” Computer (Long. Beach. Calif)., vol. 31, no. 3, pp. 23–30, 1998, doi: 10.1109/2.660187.
[2] C-: A Portable Assembly Language Dino Oliva, T. Nordin,Simon Peyton Jones Proceedings of the 1997 Workshop on Implementing Functional Languages | January 1997 Published by Springer Verlag
[3] Moron Why C Is Not Assembly by James Iry (Accessed 07.04.2022)
[4] L. Torczon and K. Cooper, Engineering A Compiler, 2nd ed. San Francisco, CA, USA: Morgan Kaufmann Publishers Inc., 2007.
[5] R. Nystrom, “Game Programming Patterns,” in Game Programming Patterns, Genever Benning, 2014.
[6] G. Melchiorri, C. Castagna, R. Sorge, and M. Bonifazi, Game Scripting Mastery, vol. 24, no. 10. 2010.
[7] R. Fabian, Data-Oriented Design: Software Engineering for Limited Resources and Short Schedules. 2018.
[8] Introducing LuaJIT (Accessed 07.04.2022)
[9] J. Gregory, Game Engine Architecture, Second Edition, 2nd ed. USA: A. K. Peters, Ltd., 2014.
[10] P. S. Foundation, “Python.” https://www.python.org/ (Accessed 07.04.2022)
[11] Mozilla, “JavaScript.” https://developer.mozilla.org/en-US/docs/Web/JavaScript (Accessed 07.04.2022)
[12] P. S. Foundation, “Python Applications.” https://www.python.org/about/apps/ (Accessed 07.04.2022)
[13] A. Andrade, “Game engines: a survey,” EAI Endorsed Trans. Game-Based Learn., vol. 2, no. 6, p. 150615, 2015, doi: 10.4108/eai.5-11-2015.150615
[14] H. Muhammad and R. Ierusalimschy, “C APIs in extension and extensible languages,” J Univers. Comput. Sci., vol. 13, no. 6, pp. 839–853, 2007.
[15] R. Ierusalimschy, L. H. De Figueiredo, and W. C. Filho, “SPE paper Lua – an extensible extension language,” vol. 6, no. 1996, pp. 635–652, 2015.
[16] R. Ierusalimschy, L. De Figueiredo, and W. Celes, “The evolution of an extension language: A history of Lua,” Proc. V Brazilian Symp. Program. Lang., vol. 1, no. 1, pp. 1–16, 2001, [Online]. Available: [http://www.lua.org/history.html%0Ahttp://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.15.9210&rep=rep1&type=pdf](http://www.lua.org/history.html http:/citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.15.9210&rep=rep1&type=pdf). (Accessed 07.04.2022)
[17] R. Ierusalimschy, L. H. de Figueiredo, and W. Celes, “Passing a Language through the Eye of a Needle,” Queue, vol. 9, no. 5, pp. 20–29, 2011, doi: 10.1145/1978862.1983083.