2021 International STEM Education Conference (iSTEM-Ed 2021)
November 10-12, 2021, Pattaya, THAILAND
MiniScript: A New Language for Computer
Programming Education
Joseph Strout
Luminary Apps, LLC
joe@[Link]
Abstract—Computer programming is fundamental The first and third points are somewhat related; an
to modern STEM (science, technology, engineering, & easily embeddable language is likely to be small, and
math) education and industry. Visual programming a small language is more likely (though not certain) to
environments such as Scratch provide a gentle be simple. The second point is somewhat in
introduction to the topic for young children, but the opposition to the first two; simple, easily embedded
transition to text-based languages such as Python or C# languages tend to be less expressive than large,
can be a difficult leap. A new scripting language, complex ones.
MiniScript, has been designed to fill this gap. It uses
minimal syntax and a carefully selected small set of This paper introduces a new programming
language features to present a less intimidating language designed to meet all three criteria. The
challenge for the learner. At the same time, the language, MiniScript, is a small language designed for
language is complete enough to be used for sophisticated learning and teaching, with implementations
games and other programs. Finally, MiniScript itself is optimized for embedding in C# or C++ games.
lightweight and designed to be embedded into other
software written in either C# or C/C++, making it more II. RELATED WORK
likely that children will encounter the language in the
context of games, thus providing self-motivated learning
MiniScript has been influenced by many
opportunities. predecessor languages, but two languages present
particularly important comparisons: Python, for its
Keywords—programming, scripting, education, elegant syntax and handling of both lists and maps;
embedded languages and Lua, for its small size and ease of embedding.
I. INTRODUCTION Python, first released in 1991, has become popular
as both a production language and a teaching language
Computer programming, or more generally [1]. Studies such as [2] have shown that novice
computational thinking, is a foundational skill in students learn better with a simple language such as
science, technology, engineering, and math (STEM) Python, than with a more complex one like Java. Like
fields. For young children, studies have shown that MiniScript, Python is a dynamically-typed language
visual languages such as Scratch provide an effective with a well-developed read/eval/print loop (REPL),
introduction to programming skill. However, when and it features sophisticated handling of both lists
the learner is ready to move beyond visual languages (ordered sequences of values) and maps (sets of key/
and start working with text-based programming value pairs). However, at over 661 thousand lines in
languages, it may be a difficult leap. 718 source files, building Python can be challenging
[3]; and it is not designed for embedding in other
The ideal first text-based language would have the
software (though doing so is not impossible). Python
following characteristics:
has gone through three major revisions, with a
1) Simplicity: a language designed with minimal difficult transition from version 2 to 3 resulting in
syntax, a minimal but complete set of flow- many users failing to upgrade or replace deprecated
control constructs, and a small set of intrinsic APIs [4].
functions (all features of visual languages like
Lua was first released in 1993, and has become a
Scratch).
popular language for embedding in other software,
2) Expressiveness: the language should support especially games [5]. More than an order of
all common software paradigms seen in magnitude smaller than Python, Lua was designed
production languages, including recursion, from the beginning as an extension language, though
object-oriented programming, first-class recent versions include a REPL as well [6]. Lua uses
functions, and proper handling of Unicode text. one data type, table, to represent both sequences and
maps, leading to some common errors [7]; and it lacks
3) Ubiquity: the language should appear in the slice semantics commonly used in Python. Also
many contexts that may be intrinsically notable in Lua is that all variables are global by
motivating to the user, for example, as an in-
default (a special local keyword is used to declare a
game or modding language in video games.
local variable).
978-0-7381-1380-7/21/$31.00 ©2021 IEEE
2021 International STEM Education Conference (iSTEM-Ed 2021)
November 10-12, 2021, Pattaya, THAILAND
MiniScript shares many features with these earlier TABLE 1. COMPARISONS WITH PYTHON AND LUA.
languages, but has some important differences too. In Python Lua MiniScript
handling of lists and maps, it is most similar to Source Lines 661,775 29,469 13,752
Python; but instead of indentation-based code blocks Source Files 718 62 46
it uses block keywords, similar to Lua. While both Data Types 34 8 6
Python and Lua predate widespread adoption of Intrinsics 69 242 53
Unicode, MiniScript was created with Unicode Table 1. Comparison of Python, Lua, and MiniScript on four
support throughout. In terms of size, MiniScript is measures of size: C/C++ source code lines; source code files;
even smaller than Lua (see Table 1). Finally, while number of data types; and number of standard intrinsic
Python and Lua are both written in C, MiniScript functions.
comes with two functionally equivalent reference Like Python 2, MiniScript does not need
implementations: one in lightweight C++ (eschewing parentheses around the argument to the print
the Standard Template Library) and one in C#. This statement. That feature was lost in Python 3, in order
enables MiniScript to be easily embedded even in
applications written in C#, such as games using the to make print more consistent with other functions.
popular Unity engine. In MiniScript, omitting the parentheses is already
consistent; they can (and should) be omitted any time
III. LANGUAGE FEATURES a function call is the statement itself, rather than part
of some larger expression. They are also omitted any
In this section, an overview of the language is time the argument list is empty. For example,
provided. The purpose of this is to give the reader a consider:
quick sense of the style and capabilities of MiniScript.
For a more complete description, please refer to the print ceil(rnd * 10)
MiniScript manual.
In this complete MiniScript statement, print,
MiniScript is a procedural, object-oriented, ceil, and rnd are all functions, but only ceil
prototype-based language. Compared to most other requires parentheses (because it takes arguments but is
programming languages, MiniScript uses relatively not the statement root). The result of this policy is
little punctuation, particularly in basic control flow clean, syntax-light code characterized by very little
statements; it needs no parentheses around the punctuation. It also makes the difference between
condition in if or while statements, for example, computed and stored properties an implementation
and code blocks are delimited by keywords rather than detail, rather than something that concerns the users of
curly braces or parentheses. (See Listing 1.) a class or module.
Mathematical operators are the same ones MiniScript uses three control flow constructs: if/
common to most modern languages: +, -, *, and /, else, while, and for. It also supports continue
plus % for mod and ^ for exponentiation. The logical and break for skipping to the next iteration or
operators are keywords and, or, and not; jumping out of a loop.
comparison operators are as in C or Python (==, !=,
MiniScript has exactly six data types:
>=, etc.). Operator precedence is in standard algebra,
with parentheses used only as needed for grouping 1) Numbers are stored in full-precision format,
subexpressions. and are also used to store true (1) and false
(0).
2) Strings are immutable runs of Unicode
// print a countdown characters, and support both iteration and slicing.
for i in range(3,1) 3) Lists reference mutable, ordered sequences of
print "Ready in " + i arbitrary values. Like strings, lists support
wait iteration and slicing, but (unlike strings) lists can
end for be modified in place.
4) Maps reference mutable collections of key/
// pick a random number value pairs. Keys within a map are unique; both
num = round(100 * rnd) keys and values may be any type. Maps also
// loop until input is correct form the basis of the class/object system, and
while true support single inheritance.
x = input("Your guess?").val 5) Functions reference compiled subprograms.
if x == num then Functions in MiniScript are first-class objects and
print "Correct!" may be stored in variables, passed as parameters,
break // exit loop etc.
else if x > num then
print "Too high." 6) Null is a special data type with only one value
else (the constant null).
print "Too low." Examples of all six types are shown in Table 2.
end if
The MiniScript core contains 53 intrinsic methods,
end while
many of which are overloaded to work on multiple
Listing 1. A sample MiniScript program.
2021 International STEM Education Conference (iSTEM-Ed 2021)
November 10-12, 2021, Pattaya, THAILAND
TABLE 2. MINISCRIPT DATA TYPES (WITH EXAMPLES). similar to indexing into a list or string. However,
MiniScript maps support an additional feature: any
Data Type Sample Usage string key that is a valid identifier may also be
Number e = 2.718 accessed via dot syntax, i.e. a map reference, followed
String s = "Hello World" by a dot operator (period), and then the key. This is
seq = [1, 2, "three"] mostly equivalent to the normal square-bracket
List syntax, unless the value of associated with the key is a
s[0] = "first"
function reference (more on this later). This dot
m = {five":5} notation is often a convenient alternative to square-
Map m["six"] = 6 bracket indexing, and helps prepare the learner for
[Link] = 7 similar syntax in other languages; it also has
dist = function(x,y) additional semantics when referencing a function or in
Function return sqrt(x^2 + y^2) the presence of inheritance, as described below.
end function Functions are unnamed, first-class objects that can
Null x = null take any number of parameters (with default values),
and return a single result value (which may be null).
types. For example, the len intrinsic will return the Variables within a function are always local by
number of Unicode characters in a string, the number default, but function code may read variables in the
of elements in a list, or the number of key/value pairs calling scope or in the global scope as well. Assigning
in a map. The intrinsics support use of the core data to values in these higher scopes can be done via the
types as many of the common data structures in outer and global keywords. This default-local
computer science: e.g., to use a list as a stack or a scoping is common in modern languages (though
queue, or to use a map as a set. differs from Lua), and helps avoid a proliferation of
Indexing and slice syntax are very similar to global variables.
Python: an element of a list or string is obtained by Functions are invoked by evaluating any variable
placing the index within square brackets after the list that refers to them. This works both for simple
or string reference, and a sublist or substring results variables, like f, as well as map properties referenced
from specifying a range via a colon. For example, if s via dot syntax, such as m.f. When a function is
is a string, then s[3] returns character 3 (counting invoked via dot syntax, it gets an implicit argument
the first character as 0), and s[3:5] returns the self that refers to the map on which it was invoked.
substring from character 3 up to but not including Note that unlike Python, this self parameter is not
character 5. Either index may be negative, in which part of the function parameter list; it is inserted
case it counts backwards from the end of the string; or implicitly by the invocation. Listing 2 illustrates the
omitted, in which case the range implicitly starts or use of maps and functions.
ends at the beginning or end of the string, respectively.
Thus, s[-3:] returns the last three characters of a string. Several additional features support object-oriented
Lists work in exactly the same way, with the programming (OOP) via prototype-based inheritance.
additional feature that elements (but currently not A map can be made to derive from a base map by
ranges) may be assigned new values, mutating the list. creating it with the new operator, which sets a special
Map syntax is inspired by Python as well; a map “__isa” key. When the dot operator is evaluating the
literal uses key:value pairs separated by commas, and key (i.e. the right-hand side identifier), it will walk
enclosed in curly braces. Once a map is created, keys this __isa chain until a match is found. This allows
may be specified in square brackets in a manner very derived maps to be used as subclasses or instances,
overriding only the functions or other values needed,
Shape = {"sides": 0, "color": "blue"} Square = new Shape
[Link] = function() [Link] = 4
return 180 * ([Link] - 2) [Link] = "square"
end function [Link] =
[Link] = function() function(capitalize=false)
return [Link] + "-sided shape" [Link] capitalize
end function print " (my favorite shape)"
[Link] = function(caps=false) end function
s = "a "+[Link]+" "+[Link]
if caps then s = [Link] mySquare = new Square
print s [Link] = "yellow"
end function
[Link] = 3 print [Link]
print [Link] [Link]
[Link] true OUTPUT:
OUTPUT: 360
180 a yellow square
A BLUE 3-SIDED SHAPE (my favorite shape)
Listing 2. Illustration of map, function, and dot syntax. Listing 3. Subclassing and instantiation. (Append to Listing 2.)
2021 International STEM Education Conference (iSTEM-Ed 2021)
November 10-12, 2021, Pattaya, THAILAND
commonPrefix = function(strList)
if not strList then return null
// find the shortest and longest strings (without sorting)
shortest = strList[0]
longest = strList[0]
for s in strList
if [Link] < [Link] then shortest = s
if [Link] > [Link] then longest = s
end for
if [Link] < 1 then return ""
// now find how much of the shortest matches the longest
for i in range(0, [Link]-1)
if shortest[i] != longest[i] then return shortest[:i]
end for
return shortest
end function
items = ["interspecies", "interstellar", "interstate"]
print commonPrefix(items)
Listing 4. Function to find the longest common prefix of a list of strings.
and inheriting the rest from the base map. Finally, Its minimal syntax, combined with modern features
within a function, a special super keyword allows such as inheritance, first-class functions, default-local
reference to the base map of the map on which the variables, and Unicode support, make it an appealing
function was found; this supports the common pattern choice for both teaching and learning.
of invoking a base-class method from within derived- The primary drawback to MiniScript is that, as a
class code. Listing 3, which should be read as an very new language, it is not yet widely known or used.
extension of Listing 2, illustrates some of these OOP H o w e v e r, w i t h l i g h t - w e i g h t , o p e n - s o u r c e
features. implementations in both C++ and C# — the languages
This overview concludes with two more realistic used by the highly popular Unreal and Unity game
examples, taken from the Rosetta Code website [8]. engines — there is reason to believe this may change
Listing 4 finds the longest common prefix of a list of in the future.
strings; and Listing 5 shows both iterative and
recursive methods to find a Fibonacci number. ACKNOWLEDGMENT
The author wishes to thank Georg Becker for
IV. CONCLUSION helpful coments on the manuscript.
MiniScript is poised to become a useful new
alternative for a language used to teach programming. REFERENCES
1. C. S. Miller, A. Settle, and J. Lalor, “Learning object-oriented
programming in Python: Towards an inventory of difficulties
// Fibonacci number (recursive) and testing pitfalls,” Proceedings of the 16th Annual
rfib = function(n) Conference on Information Technology Education, pp. 59-64,
if n < 1 then return 0 2015.
if n == 1 then return 1 2. L. Mannila, M. Peltomäki, and T. Salakoski, “What about a
simple language? Analyzing the difficulties in learning to
return rfib(n-1) + rfib(n-2) program,” Computer Science Education, vol.16, no. 3, pp.
end function 211-227, 2006.
3. V. Boykis, “It's still hard for beginners to get started with
// Fibonacci number (iterative) Python,” [Link]
python-is-hard , 2018.
ifib = function(n)
4. J. Wang, L. Li, K. Liu, and H. Cai, “Exploring how
if n < 2 then return n deprecated Python library APIs are (not) handled,”
n1 = 0 Proceedings of the 28th ACM Joint Meeting on European
n2 = 1 Software Engineering Conference and Symposium on the
for i in range(n-1, 1) Foundations of Software Engineering, pp. 233-244, 2020.
ans = n1 + n2 5. R. Ierusalimschy, L. H. De Figueiredo, and W. C. Filho, “Lua
—an extensible extension language,” Software: Practice and
n1 = n2 Experience, vol. 26, no. 6, pp. 635-652, 1996.
n2 = ans 6. R. Ierusalimschy, L. H. De Figueiredo, and C. Waldemar, Lua
end for 5.1 reference manual, 2006.
return ans 7. “Avoiding gaps in tables used as arrays,” https://
end function [Link]/lua/example/8360, retrieved May 2020.
8. “Category: MiniScript”, [Link]
print "Recursive: " + rfib(6) Category:MiniScript, retrieved May 2020.
print "Iterative: " + ifib(6)
Listing 5. Fibonacci number, with recursion and iteration.