<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta>
      <journal-title-group>
        <journal-title>Journal of Object</journal-title>
      </journal-title-group>
    </journal-meta>
    <article-meta>
      <article-id pub-id-type="doi">10.1145/2048066.2048138</article-id>
      <title-group>
        <article-title>Challenges of Transpiling Smalltalk to JavaScript</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Noury Bouraqadi</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Dave Mason</string-name>
          <xref ref-type="aff" rid="aff2">2</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>IMT Nord Europe, Institut Mines-Télécom, Univ. Lille, Centre for Digital Systems</institution>
          ,
          <addr-line>F-59000, Lille</addr-line>
          ,
          <country country="FR">France</country>
        </aff>
        <aff id="aff1">
          <label>1</label>
          <institution>NOOTRIX</institution>
          ,
          <country country="FR">France</country>
        </aff>
        <aff id="aff2">
          <label>2</label>
          <institution>Toronto Metropolitan University</institution>
          ,
          <addr-line>Toronto</addr-line>
          ,
          <country country="CA">Canada</country>
        </aff>
      </contrib-group>
      <pub-date>
        <year>2025</year>
      </pub-date>
      <volume>21</volume>
      <fpage>959</fpage>
      <lpage>972</lpage>
      <abstract>
        <p>Since Smalltalk has a great development environment, but somewhat limited deployment models, and JavaScript has ubiquitous deployment opportunities, but a relatively impoverished development environment it seems to be very advantageous to combine them. The aspiration is to “develop in Smalltalk, run in JavaScript”. While there are a number of projects targeting transpiling Smalltalk to JavaScript and there are some interesting success stories, no solution fully realizes the potential for this model. Currently, no description exists of how to approach a Smalltalk to JavaScript transpiler, and challenges that need to be overcome. In this paper, we discuss challenges to transpiling Smalltalk applications to JavaScript, and more specifically EcmaScript 6, based on insights we have acquired in the process of developing PharoJS.</p>
      </abstract>
      <kwd-group>
        <kwd>eol&gt;Transpilation</kwd>
        <kwd>Smalltalk</kwd>
        <kwd>JavaScript</kwd>
      </kwd-group>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. Introduction</title>
      <p>Smalltalk run-time related implicit dependencies are: a class can have up to only 1 superclass, all entities
are objects - instances of some class, and all variables initially reference the undefined object nil .</p>
      <p>
        Although JavaScript was created as a prototype-based language, it has evolved to support a
classbased programming style starting from version 6 of the ECMAScript standard. This reduces the gap with
Smalltalk [
        <xref ref-type="bibr" rid="ref11">11</xref>
        ]. However, there are still several significant challenges to address when implementing a
Smalltalk to JavaScript transpiler.
      </p>
      <p>
        Focus. In this paper, we discuss challenges to transpiling Smalltalk applications to JavaScript. This
analysis is based on insights we have acquired in the process of developing PharoJS [
        <xref ref-type="bibr" rid="ref11 ref12 ref13">12, 13, 11</xref>
        ]. We
more specifically target EcmaScript 6 (ES6) as we showed in previous work [
        <xref ref-type="bibr" rid="ref11">11</xref>
        ] that ES6 support for
classes allows for better performance of code generated by the transpiler.
      </p>
      <p>Paper outline. First, in section 2 we catalog challenges that will be faced by any attempt to produce
a high-fidelity transpilation from Smalltalk to JavaScript. While some items are adequately described
there, others require more detail and are examined in the following sections (3 to 7): diferences between
low-level primitives and types in the two languages; messages; block closures; classes; and reflective
operations. While some of these challenges are quite straightforward to address, others have significant
nuances and limitations for achieving perfect alignment between the languages as summarized in
section 8. Finally, section 9 draws some conclusions and identifies aspects that are beyond the scope of
this paper.</p>
    </sec>
    <sec id="sec-2">
      <title>2. Challenges Catalog Overview</title>
      <p>We have identified 5 families of challenges that need to be addressed when transpiling Smalltalk to
JavaScript.</p>
      <p>Primitive Types and Literals. Smalltalk and JavaScript belong to the same family of Object-Oriented
dynamic languages. Nevertheless, they difer even at the level of primitive types and literals.
Messages. Smalltalk messages can be reified, enabling support for custom dynamic type error handing
by redefining the doesNotUnderstand: method. Beyond this reflective feature missing in
JavaScript, there are other basic issues related to messages such as Smalltalk support for
nonalphanumeric characters in selectors, or JavaScript math-like message priorities.</p>
      <p>Block Closures. JavaScript anonymous functions only partially map to Smalltalk blocks. Thus,
transpilers need to address challenges resulting from blocks supporting non-local returns and the
fact that they always return a value.</p>
      <p>Classes. Here are some class related concepts that only exist in Smalltalk: traits, class variables, shared
pool variables, class initialization upon loading the class, as well as operations performed upon
image startup and shutdown.</p>
      <p>Reflection. Smalltalk provides multiple reflective features that are either not supported or only
partially supported by JavaScript. For example, Smalltalk reified multiple concepts such as slots,
execution contexts accessible via the thisContext pseudo-variable, as well as messages upon
handling errors ( cannotInterpret: and doesNotUnderstand: ). Smalltalk also provides
some reflective operations for which there is no direct mapping in JavaScript. Examples include
pointer manipulation methods ( forwardBecome: and become: ).</p>
      <p>In the following sections, we will expand on this catalog. Each family encompasses a set of challenges
that we describe and illustrate with examples.</p>
    </sec>
    <sec id="sec-3">
      <title>3. Primitive Types and Literals</title>
      <p>Although both Smalltalk and JavaScript are dynamic object-oriented languages, they difer in the way
they handle primitive types and literals. This includes, primitive types such as numbers, strings, and
undefined objects. Smalltalk always relies on message sends (i.e. call methods) to perform any operation,
including ones involving primitive types, literals, and operations such as basic arithmetic.</p>
      <p>Diferences between Smalltalk and JavaScript require transpilers to address the following challenges:
• JavaScript undefined and null are not objects.
• JavaScript has an impoverished numeric stack.
• Smalltalk automatically moves between small integers and large integers.
• Smalltalk supports fixed-point arithmetic.</p>
      <p>• Smalltalk has literal symbols.</p>
      <sec id="sec-3-1">
        <title>3.1. JavaScript undefined and null are Not Objects</title>
        <p>In Smalltalk, every entity, including primitive types, is an object. In JavaScript, primitive types are
automatically wrapped into full-fledged objects, so we can safely handle them just like in Smalltalk
objects. The only exceptions are undefined and null .</p>
        <p>Conceptually undefined and null are equivalent to Smalltalk’s nil object. However, they
are not objects and cannot be sent messages as objects. So, a transpiler needs to convert Smalltalk
messages in a way that handles the case when the receiver (i.e. the object performing the method call)
is nil . Furthermore the wrapped objects sufer a considerable performance penalty, so for optimal
performance normal JavaScript operator syntax is preferred.</p>
      </sec>
      <sec id="sec-3-2">
        <title>3.2. JavaScript has an Impoverished Numeric Stack</title>
        <p>Smalltalk has a rich numeric stack including SmallInteger , LargeInteger , Float , Fraction ,
and ScaledDecimal , with smooth transitions among them. JavaScript, in contrast, has only numbers.
JavaScript numbers are specified as IEEE 64-bit floating-point values, although internally most JavaScript
engines do use small integers where possible. While the other Smalltalk numeric types could be emulated,
it would be at considerable performance cost and smooth inter-operation is a daunting task.</p>
      </sec>
      <sec id="sec-3-3">
        <title>3.3. Smalltalk Automatically Moves Between Small Integers and Large Integers</title>
        <p>In Smalltalk, small and large integers are tightly integrated. On the one hand, when the result of an
operation involving small integers is bigger than the largest small integer, we obtain a large positive
integer. Similarly, when the result goes below the minimum small integer, we get a large negative
integer. Conversely, if the result of an operation on large integers result in a valid small integer, that is
what is returned.</p>
        <p>On the other hand, 253 = 9007199254740992 is the end of the contiguous range of integers that
can be exactly represented in JavaScript1, so if we assigned x=9007199254740992 then x==x-1 is
false, but x==x+1 is true!</p>
        <p>JavaScript has a class named BigInt to deal with large integers. However the conversion has to
be done manually on some JavaScript runtimes. Besides, JavaScript has a diferent syntax for creating
large integers. For example, 100n creates an instance of a BigInt even if the number is small.</p>
      </sec>
      <sec id="sec-3-4">
        <title>3.4. Smalltalk Supports Fixed-Point Arithmetic</title>
        <p>Smalltalk allows writing arithmetic expressions with fixed-point numbers. Those are numbers with a
ifxed number of digits in their fractional part. They are instances of the ScaledDecimal class.
1there are many larger integers that can be exactly represented, but this is the end of the contiguous set</p>
        <p>Smalltalk also supports a literal syntax for fixed-point numbers. For example, 0.128s + 1.0s will
result in 1.128s , while with floating-point numbers, the result would be 1.1280000000000001 .</p>
        <p>JavaScript has no syntax to express fix point numbers as literals. However, JavaScript numbers
understand the toFixed() message that returns a string with the desired number of digits after the
point. For example, the above Smalltalk operation on fixed-point numbers needs to be converted to the
following JavaScript expression Number.parseFloat((0.128 + 1.0).toFixed(3))</p>
      </sec>
      <sec id="sec-3-5">
        <title>3.5. Smalltalk has Literal Symbols.</title>
        <p>
          Smalltalk symbols are strings that are unique in the whole Smalltalk image/program [
          <xref ref-type="bibr" rid="ref14">14</xref>
          ]. One creates
a symbol by writing a sequence of alphanumeric characters preceded by a hash, as in #odyssey2021 .
So, the expression #odyssey2021 == #odyssey2021 equals true . It means those are the same
object, since in Smalltalk, == means identical. This is always true even if the symbol is created in
diferent parts of a program or in diferent points in time. For comparison, two strings that are made of
the exact same sequences of characters but created in diferent methods are diferent objects.
        </p>
        <p>JavaScript does not have literal symbols despite having a builtin Symbol class. JavaScript
Symbol.for is a function that creates unique Symbol associated with a particular string and
Symbol.keyFor is a function that retrieves the string value. Unlike its Smalltalk counterpart, the
JavaScript Symbol class is unrelated to the String class but is simply about uniqueness. Instances
of JavaScript Symbol miss string operations such as concatenation or counting elements. Therefore,
these possibly could be used to emulate the Smalltalk functionality, but smooth inter-operation with
strings is dificult to achieve.</p>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>4. Messages</title>
      <p>Smalltalk messages are equivalent to JavaScript method calls. A message has a selector, which is the
name of the called method. Although we find the same concepts in both languages, transpilers should
address the following diferences:
• Non-alphanumeric characters in Smalltalk message selectors;
• JavaScript math-like message priorities;
• Smalltalk message cascading.</p>
      <sec id="sec-4-1">
        <title>4.1. Non-Alphanumeric Characters in Smalltalk Message Selectors</title>
        <p>Smalltalk binary and keyword messages selectors need special handling to be transpiled to valid
JavaScript method names. Binary selectors are made of non-alphanumeric characters, such as + or &lt; .
Such characters are considered invalid in JavaScript method and function names.</p>
        <p>Smalltalk message keywords, are sequences of alphanumeric characters ending with a colon ( : ). A
keyword message selector is made of the concatenation of 1 or more keywords, including the colon
characters. Consider the following Smalltalk code snippet. Two temporary variables a and b are
declared and initialized with diferent integer arrays. The last line sends a message with selector
with:collect: to the array referenced by a . The message has two arguments: b and a block i.e.
a lambda function.</p>
        <p>| a b |
a := #(98 45 66 73).
b := #(12 35 55 21).</p>
        <p>a with: b collect: [:aElement :bElement | aElement + bElement ]</p>
        <p>Just as with binary selectors, keyword selectors have characters that are forbidden in JavaScript
method and function names. So, a transpiler must handle them properly. Simply skipping the forbidden
characters in the generated JavaScript is not an option. It might result in empty JavaScript identifiers
when converting binary selectors or in collisions with other identifiers when converting keyword
selectors.</p>
      </sec>
      <sec id="sec-4-2">
        <title>4.2. JavaScript Math-Like Message Priorities</title>
        <p>In Smalltalk all operations, including infix (typical math operations) are treated the same and sent
as messages. When transpiling to JavaScript, the same approach could be used, i.e. all operations
could be implemented as method calls, since JavaScript primitive types are automatically wrapped into
full-fledged objects on a method call 2, but there is a significant performance cost, so it is important to
use JavaScript expression syntax where possible.</p>
        <p>Infix messages are always performed from left to right in Smalltalk, while JavaScript follows math
priorities. So, an expression such as 2+2/4 will evaluate to 1 in Smalltalk while it evaluates to 2.5
in JavaScript. Thus, a transpiler must introduce parenthesis into the generated JavaScript code to ensure
the consistency of transpiled math messages.</p>
      </sec>
      <sec id="sec-4-3">
        <title>4.3. Smalltalk Message Cascading</title>
        <p>Smalltalk allows sending several messages to the same receiver. For example consider the
following Smalltalk listing. It shows a cascade of 4 messages ( loadStops , computeRoute ,
displayMap , listPointsOfInterest ). They all share the same receiver, which is a new
instance of TripPlanner .</p>
        <p>TripPlanner new
loadStops;
computeRoute;
displayMap;
listPointsOfInterest
let planner = new TripPlanner();
planner loadStops;
planner computeRoute;
planner displayMap;
planner listPointsOfInterest;</p>
      </sec>
    </sec>
    <sec id="sec-5">
      <title>5. Block Closures</title>
      <p>There is no syntactic equivalent to this message cascading in JavaScript. A transpiler has to convert
each message cascade to a sequence of basic independent messages. It also has to capture the value of
the original target so the the same object is referenced, regardless of side-efects of the messages.</p>
      <p>Transpiling the Smalltalk code for the trip planner example, would result in the following JavaScript.
Note that we need to introduce variable planner to ensure all messages share the same receiver.
Smalltalk blocks, which is short for block closures, are lambda functions. They are required to write
any basic Smalltalk program. Blocks are for example used in conditionals and loops.</p>
      <p>Transpiling Smalltalk blocks to JavaScript requires addressing the following challenges:
• Smalltalk blocks always bind the outer context;
• Smalltalk blocks always evaluate to some value;
• Smalltalk blocks support non-local returns.</p>
      <sec id="sec-5-1">
        <title>2except, as mentioned earlier, undefined and null</title>
        <sec id="sec-5-1-1">
          <title>5.1. Smalltalk Blocks Always Bind the Outer Context</title>
          <p>Smalltalk blocks are by definition anonymous. They can refer to external variables (such as self the
equivalent of this in JavaScript) from their context.</p>
          <p>The following example provides an illustration. Class A defines a block method that answers a
block that refers to self . The last line of the script creates an instance of A , obtains the block and
evaluates it. It shows that the block can capture the receiver from its context via the pseudo-variable
self .</p>
          <p>A &gt;&gt; #answerToEverything</p>
          <p>^ 42
A &gt;&gt; #block</p>
          <p>^[Transcript show: self answerToEverything]</p>
          <p>A new block value</p>
          <p>To transpile a such code to JavaScript, we need to analyze the two ways to implements functions as
provided by JavaScript:
• Functions defined using the function keyword can be anonymous. However, they do not bind
the pseudo-variable this .</p>
          <p>• Arrow functions are functions defined using the =&gt; character. They are always anonymous.</p>
          <p>The following example shows an arrow block successfully referencing the receiver, while an
anonymous function raises a run-time error.</p>
          <p>class A {
answerToEverything() {
return 42;
};
}</p>
          <p>};
}
blockFromArrowFunction() {
return () =&gt; {</p>
          <p>console.log(this.answerToEverything())
}
blockFromAnonymousFunction() {
return function () {</p>
          <p>console.log(this.answerToEverything())
}
let a = new A();
let block1 = a.blockFromArrowFunction();
block1(); // 42 is displayed
let block2 = a.blockFromAnonymousFunction();
block2(); // Runtime error</p>
          <p>JavaScript arrow functions are more appropriate to transpile Smalltalk blocks than anonymous
functions. However, they do not match all block features as shown in sections 5.2 and 5.3.</p>
        </sec>
        <sec id="sec-5-1-2">
          <title>5.2. Smalltalk Blocks Always Evaluate to Some Value</title>
          <p>When evaluating a Smalltalk block, unless it ends in a return (described in section 5.3), the result of the
last expression is the value of the block. An empty block value is nil . To achieve the same behavior,
transpilers must convert each block to a JavaScript arrow function ending with a return statement.</p>
        </sec>
        <sec id="sec-5-1-3">
          <title>5.3. Smalltalk Blocks Support Non-Local Returns</title>
          <p>Smalltalk blocks can be used to perform a return from the defining method. To illustrate this, consider
a class A with the following two methods.</p>
          <p>A &gt;&gt; #m1: aBlock</p>
          <p>Transcript cr; show: ’Before block value’.
aBlock value.</p>
          <p>Transcript cr; show: ’After block value’
A &gt;&gt; #m2</p>
          <p>Transcript cr; show: ’Before m1’.
self m1: [ ^ 42 ].</p>
          <p>Transcript cr; show: ’After m1’</p>
          <p>Evaluating A new m2 will send the message value to the block [^42] within m1: . Since the
block returns, it will terminate both the execution of m1: and m2 . As a result, the Transcript will
display only the following:
Before m1
Before block value</p>
          <p>Conversely, returns in JavaScript arrow functions only provide a value to the statement where they
are performed. Consider the following class.</p>
          <p>class A {
m1(aBlock) {
console.log("Before block value");
aBlock();
console.log("After block value");
}
m2() {
console.log("Before m1");
this.m1(() =&gt; {return 42});
console.log("After m1");
}</p>
          <p>}
Before m1
Before block value
After block value</p>
          <p>After m1</p>
          <p>Evaluating new A().m2() will evaluate the arrow function within m1 , then proceed with the
execution of the last statements of m1 and m2 . The console will display all four lines:</p>
          <p>With careful attention to detail, this non-local-return behavior can be replicated in JavaScript with
try - catch and throw .</p>
        </sec>
      </sec>
    </sec>
    <sec id="sec-6">
      <title>6. Classes</title>
      <p>Transpiling Smalltalk classes to JavaScript requires dealing with the following challenges:
• Smalltalk has class variables;
• Smalltalk has pool variables;
• Smalltalk methods always have a return value;
• Smalltalk methods can have pragmas;
• Smalltalk primitive pragmas refer to the virtual machine;
• Smalltalk class initialization and startup/shutdown lists;
• Smalltalk supports class extensions;
• Smalltalk supports traits.</p>
      <sec id="sec-6-1">
        <title>6.1. Smalltalk has Class Variables</title>
        <p>These are variables shared among the defining class, its instances, its subclasses, and their respective
instances. JavaScript has no support for class variables. Using static variables as discussed below
only partially solves the issue.</p>
        <p>For example, consider the Smalltalk code for a drawing app below. Class Shape defines
a class variable DefaultFillColor , that can be changed using a class-side setter method
setDefaultFillColor: . Each instance of Shape has a fill color, represented by InstVar
fillColor . It can reference an arbitrary color. Message resetFillColor allows reverting it
to the default color from class variable DefaultFillColor .</p>
        <p>Object subclass: #Shape
instanceVariableNames: ’fillColor’
classVariableNames: ’DefaultFillColor’
poolDictionaries: ’’
category: ’Demo’
Shape class &gt;&gt; #setDefaultFillColor: aColor</p>
        <p>DefaultFillColor := aColor
Shape class &gt;&gt; #getDefaultFillColor</p>
        <p>^DefaultFillColor
Shape &gt;&gt; #resetFillColor
fillColor := DefaultFillColor
An equivalent JavaScript code for this example is the following.
class Shape extends Object {
static setDefaultFillColor(aColor){</p>
        <p>this.DefaultFillColor = aColor;
static getDefaultFillColor(){</p>
        <p>return Shape.DefaultFillColor;
}
resetFillColor(){</p>
        <p>this.fillColor = Shape.DefaultFillColor
}
}</p>
        <p>}</p>
        <p>It is important to hardwire the reference to the class Shape in the static setter instead of using
this . The rational is that class variables are shared with subclasses and subclass instances. Using
this would instead create another static variable in the subclass.</p>
        <p>It is worth noting that mapping class variables to JavaScript static variables is not enough. We
need to avoid potential naming collisions with metaclass InstVars. Smalltalk metaclass InstVars are
indeed mapped to static variables too.</p>
      </sec>
      <sec id="sec-6-2">
        <title>6.2. Smalltalk has Pool Variables</title>
        <p>Smalltalk allows having variables shared among diferent unrelated classes and their instances. These
variables are defined in pools, that are referenced by classes. JavaScript lacks pool variables.</p>
        <p>However, pool variables are a special case of class variables. Therefore, a solution exists based on an
emulation similar to the one discussed in section 6.1.</p>
      </sec>
      <sec id="sec-6-3">
        <title>6.3. Smalltalk Methods Always Have a Return Value</title>
        <p>When source code for a Smalltalk method does not end with an explicit return statement, the compiler
supplies byte code to return the receiver. This behavior needs to be replicated when transpiling Smalltalk
code to JavaScript by appending a return this when there is no explicit return.</p>
      </sec>
      <sec id="sec-6-4">
        <title>6.4. Smalltalk Methods can Have Pragmas</title>
        <p>Smalltalk has a mechanism to provide annotations on methods, which are called “pragmas”. Originally
these were just mechanisms to access primitive operations such as arithmetic, and block evaluation (see
section 6.5). They are now more broadly used to inform the compiler and reflective tools in Smalltalk.</p>
        <p>But, JavaScript has no support for pragmas or any annotations for that matter. However, JavaScript
objects structure can be extended with new properties. Since functions are objects, it is possible to
extend their structure with pragmas as extra properties. This extension needs to be carefully performed
to :
• distinguish pragmas for other properties, and
• avoid naming collisions with other properties</p>
      </sec>
      <sec id="sec-6-5">
        <title>6.5. Smalltalk Primitive Pragmas Refer to the Virtual Machine</title>
        <p>Some Smalltalk method bodies include a primitive pragma. This is a call to functionality of the Virtual
Machine (VM), such as basic math operations, or input/output routines.</p>
        <p>Analyzing how to transpile each Smalltalk primitive is beyond the scope of this paper. Sufice to
say that there is no common solution to transpile all of them to JavaScript. Some, do not even have
an equivalent in JavaScript. Examples are forcing garbage collection, swapping object identities (i.e.
become: ), suspending/resuming processes, or reading/writing compiled methods literals.</p>
      </sec>
      <sec id="sec-6-6">
        <title>6.6. Smalltalk Class Initialization and Startup/Shutdown Lists</title>
        <p>Smalltalk persists the content of RAM into a file called the image. It includes all objects, including
classes. This is why the class initialization/finalization process is split in 2 parts. One is done upon
loading/deleting classes to/from the image. The second is done upon each startup and shutdown, and
often involves caches or resources outside the image.</p>
        <p>Classes in the startup list perform some actions at the beginning of each session, right after the
Smalltalk image is loaded in RAM. Classes in the shutdown list perform some actions at the end of each
session, right before the Smalltalk image is unloaded from RAM.</p>
        <p>Since JavaScript lacks an image, classes are reloaded upon each run. So, upon transpilation, we
need to ensure useful startup operations are performed by the generated code for JavaScript class
initialization. This can be done immediately after all class initialize methods have been called.
We also need to provide a solution to perform shutdown actions in JavaScript.</p>
        <p>It is worth noting that Smalltalk startup and shutdown actions are mostly related to image persistence.
So, there is room for optimization by skipping operations that are useless in the absence of an image.</p>
      </sec>
      <sec id="sec-6-7">
        <title>6.7. Smalltalk Supports Class Extensions</title>
        <p>
          It is common practice in Smalltalk to introduce extra methods into classes from another project or
library. Such methods can for example be introduced in core classes such as Object , to introduce
application specific behaviors. This feature also supports polymorphism and helps in writing cleaner
code. For example, it can be used to implement design patterns such Visitor, where many objects from
diferent classes have to provide the same API [
          <xref ref-type="bibr" rid="ref15">15</xref>
          ].
        </p>
        <p>In JavaScript one can create a function, then add it to an existing class. This practice called ‘Monkey
Patching’ is discouraged in the JavaScript community. More importantly, JavaScript forbids creating
functions that send messages to the super pseudo-variable.</p>
        <p>Method name collision is yet another issue when extending existing JavaScript classes with methods
from Smalltalk. The transpiler should avoid accidentally overwrite a symbol in an existing JavaScript
class with a method from Smalltalk, so must make the Smalltalk name unique - such as adding an
unusual prefix to Smalltalk names.</p>
      </sec>
      <sec id="sec-6-8">
        <title>6.8. Smalltalk Supports Traits</title>
        <p>
          Traits [
          <xref ref-type="bibr" rid="ref16 ref17 ref18 ref19 ref20">16, 17, 18, 19, 20</xref>
          ] were introduced as an alternative to multiple class inheritance. They enable
code reuse in unrelated class hierarchies.
        </p>
        <p>Just like a class, a trait can define methods and instance variables. Various operators allow developers
to decide how to combine diferent, potentially conflicting traits into a given class.</p>
        <p>While invented in the context of Smalltalk, traits have been adopted by other languages such as PHP
and Python. However, JavaScript has no explicit support for traits. From a code reuse perspective, this
is not an issue since methods defined in traits can simply be duplicated in all JavaScript classes that
reuse them.</p>
        <p>However this solution is not satisfactory from a reflection perspective. Traits have no existence in
JavaScript, and one can not navigate the inheritance hierarchy and discover relationships between
classes and traits.</p>
        <p>
          For a full trait support, traits need to be reified in JavaScript. This is possible as shown by Van Cutsem
and Miller [
          <xref ref-type="bibr" rid="ref21">21</xref>
          ]. With a such implementation, transpilation would require mapping Smalltalk traits to
the JavaScript traits implementation.
        </p>
      </sec>
    </sec>
    <sec id="sec-7">
      <title>7. Reflection</title>
      <p>
        Reflection is the ability of a system to observe or modify its structure or its behavior [
        <xref ref-type="bibr" rid="ref22">22</xref>
        ]. Smalltalk
has a rich Meta-Object Protocol, and many reflective abilities that we would like to account for when
transpiling to JavaScript. Many concepts such as classes, methods, blocks, and contexts are reified in
Smalltalk, materialized as classes that make up the Smalltalk kernel. These are critical to Smalltalk,
because most implementations are live coding environments and the live coding tools are developed
within the systems themselves.
      </p>
      <p>Reflection is very limited in JavaScript. While there can be somewhat-live implementations, they
are implemented outside the language itself. As in Smalltalk, JavaScript classes and methods are
firstclass objects and it is possible to parallel Smalltalk’s class-metaclass inheritance hierarchies. What is
more dificult (or impossible) is mapping Smalltalk’s run-time reflection behavior such as contexts,
doesNotUnderstand: , et cetera.</p>
      <p>The following Smalltalk reflective features are the most dificult ones to address upon transpilation:
• Pharo Smalltalk reifies slots;
• Pharo Smalltalk classes define object formats, i.e. memory layout for their instances;
• Smalltalk reifies messages upon handling type errors;
• Smalltalk reifies execution contexts;
• Smalltalk and JavaScript have diferent solutions for intercepting method evaluation.</p>
      <sec id="sec-7-1">
        <title>7.1. Pharo Smalltalk Reifies Slots</title>
        <p>
          Slots are one of the new meta-level features introduced by Pharo Smalltalk [
          <xref ref-type="bibr" rid="ref23">23, 24</xref>
          ] that has no equivalent
in JavaScript. Pharo extends class definitions to allow choosing the class for each slot. By default, the
Smalltalk-80 instance variables behavior applies. But one can use or introduce subclasses of Slot to
define custom access to individual slots. For example, some slots can be virtual - that is their values
are computed upon access. Other examples are slots that keep the history of their values or notify
observers upon changes.
        </p>
      </sec>
      <sec id="sec-7-2">
        <title>7.2. Pharo Smalltalk Classes Define Object Formats</title>
        <p>Developers can also define objects format, that is the objects memory layout to optimize or adapt it to
their specific need. That is they define the structure of slots containers. For example, one can optimize
the memory footprint of objects of some class to store slots in bytes or 32 bit words. Such layout would
reduce the space occupied by boolean slots.</p>
        <p>JavaScript lacks support for reified properties and their memory layout. Nevertheless, it allows some
degree of property behavior customization through the meta operation Object.defineProperty .
It allows hiding a property or making it read-only. It also supports the definition of meta-level get()
and set(newValue) methods that intercept property reads and assignments.</p>
      </sec>
      <sec id="sec-7-3">
        <title>7.3. Smalltalk Reifies Messages Upon Handling Type Errors</title>
        <p>Both Smalltalk and JavaScript are dynamically typed languages. So, when an object receives a message
that does not match any method, a runtime exception is thrown.</p>
        <p>In Smalltalk, a type error occurs and the VM reifies the faulty message, and passes it as a parameter of
a method named doesNotUnderstand: . The reified message is an instance of class Message that
provides the message’s selector as well as its arguments. The default implementation of this method
as provided by the Object class, raises an exception. But subclasses can override it to introduce
arbitrary code. This is often used as a technique to enable behavioral reflection by controlling message
reception [25, 26].</p>
        <p>Smalltalk flavors like Pharo that rely on the OpenSmalltalk VM have an extra layer for type error
handling. "During the method lookup, if the method dictionary of one class in the class hierarchy of the
receiver is nil , the VM sends the message cannotInterpret: aMessage to the receiver. Contrary
to normal messages, the lookup for the method cannotInterpret: starts in the superclass of the
class whose method dictionary was nil." [27]</p>
        <p>In JavaScript the exception to signal type error is created by the VM. It is an instance of class
TypeError that provides only explanatory messages intended to help a human debug the error.
Given how frequently this is used in Smalltalk, support for a feature like doesNotUnderstand: is
important. The only known way to eficiently handle this in JavaScript is to define, in Object , fallback
methods for every possible message send. For this to work with perform: a method needs to be
created at runtime if the perform selector does not already have a fallback method.</p>
      </sec>
      <sec id="sec-7-4">
        <title>7.4. Smalltalk Reifies Execution Contexts</title>
        <p>In Smalltalk, the state related to the execution of compiled code is materialized as instances of class
Context . These objects can be accessed at runtime through a pseudo-variable named thisContext
that references the run-time context of the code being executed. Reified contexts are used to implement
continuations that are central to the Seaside web server framework [28].</p>
        <p>A context references diferent objects such as the program counter, the method being executed,
its receiver ( self ) and its arguments, as well as the current block closure if any. The context also
references the parent context. So, it is possible to navigate the whole execution stack. This feature eases
the implementation of debugging tools.</p>
        <p>JavaScript lacks such a powerful construct. Nevertheless, it provides a pseudo-variable named
arguments that references runtime objects that contain values of arguments passed to methods. An
arguments object also references the method being executed through a property named callee .
However, this property is deprecated.</p>
      </sec>
      <sec id="sec-7-5">
        <title>7.5. Smalltalk and JavaScript Have Diferent Solutions for Intercepting Method</title>
      </sec>
      <sec id="sec-7-6">
        <title>Evaluation</title>
        <p>Each Smalltalk class has a dictionary which maps selectors to methods. The Virtual Machine (VM)
assumes that methods are instances of the CompiledMethod class. These objects include byte-codes
to be executed by the VM as well as other meta-data used for reflective operations.</p>
        <p>An efective technique to intercept method evaluation relies on so called Method Wrappers [29].
The OpenSmalltalk VM supports method wrappers. It enables intercepting method evaluations by
replacing compiled methods in the method dictionary, by interceptor objects, i.e. method
wrappers. The actual format of interceptor objects. The VM only assumes that they understand the
run: oldSelector with: arguments in: aReceiver message. For example consider the
following example of a Smalltalk method evaluation interceptor.</p>
        <p>Universe &gt;&gt; #answer: anyQuestion</p>
        <p>^42
Object subclass: #MethodEvaluationLogger
instanceVariableNames: ’targetMethod’
classVariableNames: ’’
poolDictionaries: ’’
category: ’Demo’
MethodEvaluationLogger &gt;&gt; #targetMethod: aMethod</p>
        <p>targetMethod := aMethod
MethodEvaluationLogger &gt;&gt; #run: oldSelector with: arguments in: aReceiver
Transcript
cr; show: ’Performing method: ’, targetMethod selector;
cr; show: ’Receiver: ’, aReceiver asString;
cr; show: ’Arguments: ’, arguments asString.</p>
        <p>^aReceiver withArgs: arguments executeMethod: targetMethod
| selector method interceptor |
selector := #answer:.
method := Universe compiledMethodAt: selector.
interceptor := MethodEvaluationLogger new.
interceptor targetMethod: method.</p>
        <p>Universe methodDict at: selector put: interceptor.</p>
        <p>Universe new answer: ’How many years before nuclear fusion?’.</p>
        <p>In the first part of the script, class MethodEvaluationLogger is defined with instance method
#run: oldSelector with: arguments in: . It logs information about the call, and evaluates
the target method.</p>
        <p>In the last part of the script, we first install an interceptor on method #answer: from class
Universe . Then, we send the #answer: message to an instance of Universe . The
interceptor logs the call information, then performs the target method and returns the result.</p>
        <p>A similar behavior can be implemented in JavaScript using instances of the builtin Proxy class.
Each proxy links a target object on which the interception should be performed to a handler object.
Interceptions are specified by methods supported by the handler.</p>
        <p>For a proxy to intercept a method call, the target object should be a method. Additionally, the
handler must understand the apply(targetMethod, receiver, arguments) method as in the
following example.</p>
        <p>class Universe{
answer(anyQuestion){</p>
        <p>return 42;
}</p>
        <p>}
class MethodEvaluationLogger{
apply(targetMethod, receiver, argumentsList){
console.log("Performing method: ", targetMethod.name);
console.log("Receiver: ", receiver);
console.log("Arguments: ", argumentsList);
return targetMethod.apply(receiver, argumentsList);
}
}
const answerMethod = Universe.prototype.answer;
const proxy = new Proxy(answerMethod, new MethodEvaluationLogger());
Universe.prototype.answer = proxy;
(new Universe().answer("How many years before nuclear fusion?"));</p>
      </sec>
    </sec>
    <sec id="sec-8">
      <title>8. Challenges Dificulty Summary</title>
      <p>Challenges in the above catalog are more or less dificult. We measure this dificulty based on the
existence of a solution, its completeness, and its eficiency. Using these criteria, we defined a challenge
ranking scale, that has the following levels:
0. Solved: A solved challenge is a one for which there exist an eficient solution that addresses all
cases.
1. Complex: A complex challenge is one for which there exist a solution, but it is is either dificult to
implement or computationally demanding
2. Hard: A hard challenge is one for which we have a partial solution covering only a subset of possible
cases.
3. Open: An open challenge is one for which there exist no known realistic solution except
reimplementing a Smalltalk interpreter in JavaScript.</p>
      <p>Table 8 provides a summary of all challenges discussed in this paper. Each challenge has a score
based on its dificulty levels introduced above. The higher the score, the more dificult is the challenge.</p>
    </sec>
    <sec id="sec-9">
      <title>9. Conclusion</title>
      <p>Achieving perfect fidelity between Smalltalk and JavaScript via transpilation is impossible. If exact
ifdelity is a requirement, then the Smalltalk interpreter approach of SqueakJS[ 30] appears to be the only
option. However, many of the more dificult aspects of fidelity are relatively rare elements of Smalltalk
code, so with care many useful programs can be written in Smalltalk and deployed in JavaScript.</p>
      <p>Of the challenges outlined in 2, the first four ( Primitive Types and Literals, Objects Structure,
Messages, and Block Closures) are the most critical for most programs. If a program doesn’t use
Primitive Types and Literals</p>
      <p>Comment
0. Solved
0. Solved
0. Solved
0. Solved
0. Solved
0. Solved
0. Solved
0. Solved
0. Solved
0. Solved
3. Open
2. Hard
0. Solved
2. Hard
3. Open
3. Open
2. Hard
3. Open
1. Complex</p>
      <p>Computational overhead
Incomplete solution
Computational overhead
Incomplete solution
Complex JS code
Requires porting traits to JS
Incomplete solution
number classes other than SmallInteger and Float , they are also relatively straight-forward to
implement, especially if execution performance is not critical. Fortunately, a great deal of engineering
efort has gone into making JavaScript runtimes run very fast, so this will mask most of such issues.</p>
      <p>The story is not so positive for the last two challenges, Classes and Reflection . There are several
capabilities that can be routinely used in Smalltalk, that cannot efectively be implemented in JavaScript.</p>
      <p>There are also several issues that are relevant but outside the scope of this paper. Most of these are
doable, and will be described in future work:
• reusing JavaScript libraries (code + globals) in code transcribed from Smalltalk;
• Smalltalk and JavaScript run-time interoperability in production
• Smalltalk and JavaScript run-time interoperability in development, particularly supporting
livecoding from the Smalltalk side - to the degree possible;
• transpiling Smalltalk to produce JavaScript libraries for consumption by 3rd parties.</p>
    </sec>
    <sec id="sec-10">
      <title>Declaration on Generative AI</title>
      <sec id="sec-10-1">
        <title>The authors have not employed any Generative AI tools.</title>
      </sec>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1] PharoJS: Develop in Pharo, Run on Javascript,
          <year>2023</year>
          . URL: https://pharojs.org/, [Online; accessed 2023-
          <volume>11</volume>
          -08].
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <surname>CodeParadise</surname>
          </string-name>
          ,
          <year>2025</year>
          . URL: https://github.com/ErikOnBike/CodeParadise, [Online; accessed 2025-
          <volume>05</volume>
          -14].
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <surname>SmallJS</surname>
          </string-name>
          ,
          <year>2025</year>
          . URL: https://small-js.org/Home/Home.html, [Online; accessed 2025-
          <volume>05</volume>
          -14].
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>Egg</given-names>
            <surname>Smalltalk</surname>
          </string-name>
          ,
          <year>2025</year>
          . URL: https://github.com/powerlang/egg, [Online; accessed 2025-
          <volume>05</volume>
          -31].
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>Amber</given-names>
            <surname>Smalltalk</surname>
          </string-name>
          ,
          <year>2025</year>
          . URL: https://amber-lang.net/, [Online; accessed 2025-
          <volume>05</volume>
          -31].
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <surname>Apptivegrid</surname>
          </string-name>
          : Digitise your processes today,
          <year>2023</year>
          . URL: https://en.apptivegrid.de, [Online; accessed 2023-
          <volume>11</volume>
          -15].
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>N.</given-names>
            <surname>Bouraqadi</surname>
          </string-name>
          ,
          <article-title>Plc3000: All-in-one solution for teaching factory automation</article-title>
          ,
          <year>2024</year>
          . URL: https: //plc3000.com/, [Online; accessed 2024-
          <volume>03</volume>
          -21].
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>D.</given-names>
            <surname>Mason</surname>
          </string-name>
          , Covid-
          <volume>19</volume>
          tracker,
          <year>2023</year>
          . URL: https://covid.cs.ryerson.ca/compare/, [Online; accessed 2023-
          <volume>11</volume>
          -15].
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <surname>Pharojs</surname>
            <given-names>success stories</given-names>
          </string-name>
          ,
          <year>2024</year>
          . URL: https://pharojs.org/successStories.html, [Online; accessed 2024-
          <volume>03</volume>
          -21].
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <given-names>C.</given-names>
            <surname>Haider</surname>
          </string-name>
          , Covid-19
          <source>charts: Do not trust the numbers!</source>
          ,
          <year>2023</year>
          . URL: https://covidcrt.uber.space, [Online; accessed 2023-
          <volume>11</volume>
          -15].
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <given-names>N.</given-names>
            <surname>Bouraqadi</surname>
          </string-name>
          , D. Mason,
          <article-title>PharoJS: Transpiling Pharo Classes to JS - ECMAScript 5 versus ECMAScript 6</article-title>
          , in: S. Ducasse, G. Rakic (Eds.),
          <source>IWST'23: Proceedings of the International Workshop on Smalltalk Technologies</source>
          ,
          <string-name>
            <surname>ESUG</surname>
          </string-name>
          , CEUR Workshop Proceedings, Lyon, France,
          <year>2023</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <string-name>
            <given-names>N.</given-names>
            <surname>Bouraqadi</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Mason</surname>
          </string-name>
          , Mocks, Proxies, and
          <article-title>Transpilation as Development Strategies for Web Development</article-title>
          , in: J.
          <string-name>
            <surname>Laval</surname>
            ,
            <given-names>A</given-names>
          </string-name>
          . Etien (Eds.),
          <source>IWST'16: Proceedings of the 11th edition of the International Workshop on Smalltalk Technologies</source>
          ,
          <string-name>
            <given-names>ESUG</given-names>
            , Association for Computing Machinery, New York, NY,
            <surname>United</surname>
          </string-name>
          <string-name>
            <surname>States</surname>
          </string-name>
          , Prague, Czech Republic,
          <year>2016</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [13]
          <string-name>
            <given-names>N.</given-names>
            <surname>Bouraqadi</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Mason</surname>
          </string-name>
          ,
          <article-title>Test-Driven Development for Generated Portable JavaScript Apps</article-title>
          ,
          <source>Science of Computer Programming</source>
          <volume>161</volume>
          (
          <year>2018</year>
          )
          <fpage>2</fpage>
          -
          <lpage>17</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          [14]
          <string-name>
            <given-names>A.</given-names>
            <surname>Goldberg</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Robson</surname>
          </string-name>
          , Smalltalk
          <volume>80</volume>
          , volume
          <volume>1</volume>
          -
          <string-name>
            <given-names>The</given-names>
            <surname>Language</surname>
          </string-name>
          and its Implementation, AddisonWesley,
          <year>1983</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          [15]
          <string-name>
            <given-names>E.</given-names>
            <surname>Gamma</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Helm</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Johnson</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J. M.</given-names>
            <surname>Vlissides</surname>
          </string-name>
          , Design Patterns:
          <source>Elements of Reusable ObjectOriented Software</source>
          , 1 ed.,
          <string-name>
            <surname>Addison-Wesley Professional</surname>
          </string-name>
          ,
          <year>1994</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          [16]
          <string-name>
            <given-names>N.</given-names>
            <surname>Schärli</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Ducasse</surname>
          </string-name>
          ,
          <string-name>
            <given-names>O.</given-names>
            <surname>Nierstrasz</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A. P.</given-names>
            <surname>Black</surname>
          </string-name>
          , Traits:
          <article-title>Composable units of behavior</article-title>
          ,
          <source>in: Proceedings of European Conference on Object-Oriented Programming</source>
          , volume
          <volume>2743</volume>
          <source>of LNCS</source>
          , Springer Verlag,
          <year>2003</year>
          , pp.
          <fpage>248</fpage>
          -
          <lpage>274</lpage>
          . doi:
          <volume>10</volume>
          .1007/b11832.
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          [17]
          <string-name>
            <given-names>S.</given-names>
            <surname>Ducasse</surname>
          </string-name>
          ,
          <string-name>
            <given-names>O.</given-names>
            <surname>Nierstrasz</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Schärli</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Wuyts</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A. P.</given-names>
            <surname>Black</surname>
          </string-name>
          ,
          <article-title>Traits: A mechanism for fine-grained reuse</article-title>
          ,
          <source>ACM Transactions on Programming Languages and Systems (TOPLAS) 28</source>
          (
          <year>2006</year>
          )
          <fpage>331</fpage>
          -
          <lpage>388</lpage>
          . doi:
          <volume>10</volume>
          .1145/1119479.1119483.
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          [18]
          <string-name>
            <given-names>O.</given-names>
            <surname>Nierstrasz</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Ducasse</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Schärli</surname>
          </string-name>
          , Flattening Traits,
          <source>Journal of Object Technology</source>
          <volume>5</volume>
          (
          <year>2006</year>
          )
          <fpage>129</fpage>
          -
          <lpage>148</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref19">
        <mixed-citation>
          [19]
          <string-name>
            <given-names>A.</given-names>
            <surname>Bergel</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Ducasse</surname>
          </string-name>
          ,
          <string-name>
            <given-names>O.</given-names>
            <surname>Nierstrasz</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Wuyts</surname>
          </string-name>
          ,
          <article-title>Stateful traits and their formalization</article-title>
          ,
          <source>Journal of Computer Languages, Systems and Structures</source>
          <volume>34</volume>
          (
          <year>2008</year>
          )
          <fpage>83</fpage>
          -
          <lpage>108</lpage>
          . doi:
          <volume>10</volume>
          .1016/j.cl.
          <year>2007</year>
          .
          <volume>05</volume>
          . 003.
        </mixed-citation>
      </ref>
      <ref id="ref20">
        <mixed-citation>
          [20]
          <string-name>
            <given-names>P.</given-names>
            <surname>Tesone</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Ducasse</surname>
          </string-name>
          ,
          <string-name>
            <given-names>G.</given-names>
            <surname>Polito</surname>
          </string-name>
          ,
          <string-name>
            <given-names>L.</given-names>
            <surname>Fabresse</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Bouraqadi</surname>
          </string-name>
          ,
          <article-title>A new modular implementation for stateful traits</article-title>
          ,
          <source>Science of Computer Programming</source>
          (
          <year>2020</year>
          ).
        </mixed-citation>
      </ref>
      <ref id="ref21">
        <mixed-citation>
          [21]
          <string-name>
            <surname>T. Van Cutsem</surname>
            ,
            <given-names>M. S.</given-names>
          </string-name>
          <string-name>
            <surname>Miller</surname>
            ,
            <given-names>Traits.</given-names>
          </string-name>
          <article-title>js: robust object composition and high-integrity objects for ecmascript 5</article-title>
          ,
          <source>in: Proceedings of the 1st ACM SIGPLAN international workshop on Programming language and systems technologies for internet clients</source>
          ,
          <year>2011</year>
          , pp.
          <fpage>1</fpage>
          -
          <lpage>8</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref22">
        <mixed-citation>
          [22]
          <string-name>
            <given-names>P.</given-names>
            <surname>Maes</surname>
          </string-name>
          ,
          <article-title>Concepts and Experiments in Computational Reflection</article-title>
          ,
          <source>in: Proceedings of OOPSLA'87</source>
          ,
          <string-name>
            <surname>ACM</surname>
          </string-name>
          , Orlando, Florida,
          <year>1987</year>
          , pp.
          <fpage>147</fpage>
          -
          <lpage>155</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref23">
        <mixed-citation>
          [23]
          <string-name>
            <given-names>T.</given-names>
            <surname>Verwaest</surname>
          </string-name>
          ,
          <string-name>
            <given-names>C.</given-names>
            <surname>Bruni</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Lungu</surname>
          </string-name>
          ,
          <string-name>
            <given-names>O.</given-names>
            <surname>Nierstrasz</surname>
          </string-name>
          ,
          <article-title>Flexible object layouts: enabling lightweight language extensions by intercepting slot access</article-title>
          ,
          <source>in: Proceedings of 26th International Con-</source>
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>