Recent from talks
Nothing was collected or created yet.
| JS++ | |
|---|---|
| Paradigm | Multi-paradigm: Imperative, structured, object-oriented, functional, generic |
| Family | ECMAScript |
| Designed by | Roger Poon, Anton Rapetov |
| Developer | Onux |
| First appeared | October 8, 2011 |
| Stable release | 0.10.0
/ December 10, 2021 |
| Typing discipline | Gradual, static, dynamic |
| Scope | lexical |
| License | BSD |
| Filename extensions | .jspp, .js++, .jpp |
| Website | www |
| Influenced by | |
| C, C++, C#, Java, JavaScript | |
JS++ is a programming language for web development that extends JavaScript with a sound type system. It includes imperative, object-oriented, functional, and generic programming features. It is free and open-source software released under a BSD license.
History
[edit]JS++ first appeared on October 8, 2011.[1][2][3] The modern implementation was announced at DeveloperWeek 2016[4] and released on May 31, 2016.[5][6][7][8] The language is designed by Roger Poon and Anton Rapetov.
Features
[edit]Sound gradual type system
[edit]Since JS++ is a superset of JavaScript, declaring data types for variables is optional. However, when types are declared, the types are enforced at both compile time and runtime.
Type annotations in JS++ use the traditional C/C++ syntax:
int x = 1;
var y = 2;
bool z = true;
Notably, this differs from TypeScript and ActionScript, which use a more verbose style:
var x: number = 1;
var y: any = 2;
var z: boolean = true;
The type system in JS++ is sound for ECMAScript and DOM API corner cases, including host objects, dynamic key-value pairs, Comet, JScript conditional compilation, dynamic return types, ActiveX, ECMAScript for XML, web browser garbage collector and cyclic reference counting bugs, conditional logic, and other edge and corner cases.[9][10] This differs from other JavaScript supersets where types are optional and discarded at runtime via type erasure, such as in TypeScript.[11][12]
Importing JavaScript libraries
[edit]JS++ can use JavaScript libraries using the one-line external statement as in the following example from the homepage of JS++:
import System;
// Import JavaScript libraries in one line of code
external jQuery, $;
class Example {
public Example() {
// Nearly NO learning curve
// You can keep writing regular JavaScript
var a = 0, random = Math.random();
// Integer types and other primitives
// ... enable fast (optimized) and clear code
byte[] rgbColors = [ 0xFF, 0xFA, 0xFF ];
}
public void showMessage(int id, string text) {
// 100% compatible with regular JavaScript
jQuery("#msgbox").show();
$("#msgbox").text(id.toString() + text);
}
}
Object-oriented programming
[edit]While classes in JavaScript (ECMAScript 6) are syntactic sugar for prototypes under the hood,[13] JS++ classes resemble the classes found in classical programming languages such as C++, Java, and C# in terms of memory layout, performance, and semantics. "Classes" are a static concept, and they cannot be altered at runtime (during program execution) as is the case for JavaScript, Smalltalk, Lisp, and TypeScript, which rely on prototypes.[14] For example, private methods are private at both compile time and runtime, and external JavaScript objects cannot access private JS++ fields or methods—even if a reference to a JS++ object is obtained from JavaScript.
Example: object-oriented sorting
[edit]The following source code illustrates object-oriented sorting in JS++ using the IComparable<T> interface and Comparison enumeration for type-safe and readable comparisons.[15] The custom sorting logic is one line of code in the overridden compare method below:
import System;
class Employee : IComparable<Employee> {
private string firstName;
private string lastName;
public Employee(string firstName, string lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public override Comparison compare(Employee that) {
// Sort by employee surname
return this.lastName.compare(that.lastName);
}
public override string toString() {
return this.firstName + " " + this.lastName;
}
}
Employee zig = new Employee("Zig", "Ziglar");
Employee john = new Employee("John", "Smith");
Employee abe = new Employee("Abe", "Lincoln");
Employee[] employees = [ zig, john, abe ];
employees.sort();
Console.log(employees.join(", "));
// Output:
// Abe Lincoln, John Smith, Zig Ziglar
Thus, in the code above, the custom sorting logic provided is:
return this.lastName.compare(that.lastName);
Likewise, to call the sort:
employees.sort();
For printing the sorted results:
Console.log(employees.join(", "));
Example: encapsulation by default
[edit]JS++ provides encapsulation by default. In the following example, the fields x and y are private by default, even if no access modifier is specified. The methods getX() and getY() are public by default. This enables a more concise class definition syntax, as illustrated in the Point class below:[16]
class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
int getX() {
return this.x;
}
int getY() {
return this.y;
}
}
Out-of-bounds analysis
[edit]An out-of-bounds access usually occurs with arrays and other containers. For example, when we access the 100th element of a 3-element array, we have an out-of-bounds access:
int[] arr = [ 1, 2, 3 ];
Console.log(arr[100]); // out-of-bounds access, 'arr' does not have an element at index 100
In Java and C#, this can result in an exception and program termination. In C, this can result in buffer overflows or segmentation faults. C++ has varying semantics, such as default initialization, exceptions, segmentation faults, or buffer overflows.[17][18]
JS++ can efficiently analyze and prevent out-of-bounds errors at compile time.[19][20][21]
JavaScript has the notion of null and undefined values, where null means a value is present but it's an empty value, and undefined means there isn't a value there at all. JS++ extends this intuition further to differentiate between empty values and out-of-bounds accesses.[21]
Consider the following code, with a nullable int type represented with int?:
int[] a = [ 1, 2 ];
int? value1 = a[2];
if (value1 == null) {
Console.log("Definitely out of bounds");
}
int?[] b = [ 1, null ];
int? value2 = b[2];
if (value2 == null) {
Console.log("Might be out of bounds, might just be an access of a null element");
}
While nullable types can represent an out-of-bounds access, it falls apart when the array might contain nullable values as illustrated above. Instead, JS++ introduces an additional concept in addition to null values: undefined values. Recall that JS++ extends the JavaScript notion that null means a value is present but is an empty value, while an undefined value means a value does not exist at all. JS++ uses the concept of "a value does not exist at all" to mean an out-of-bounds access has occurred, and this concept is known in JS++ as "existent types."[21]
Therefore, the previous example can be amended. The existent type int+ means "int or out of bounds" and int?+ means "int, null, or out of bounds":
int[] a = [ 1, 2 ];
int? value1 = a[2];
if (value1 == undefined) {
Console.log("Definitely out of bounds");
}
int?[] b = [ 1, null ];
int?+ value2 = b[2];
if (value2 == undefined) {
Console.log("Definitely out of bounds");
}
Intuitively, this means existent types cannot be used as the underlying type for array elements. JS++ enforces this at compile time:
int+[] arr = []; // ERROR
[ ERROR ] JSPPE5204: Existent type `int+' cannot be used as the element type for arrays
Instead of following every conditional branch or virtual method call path, which would result in path explosion and exponential compile times, existent types have essentially the same compile-time analysis cost as int, bool, and other primitive types. Consequently, compile times have been shown to be unaffected (±1-2ms) by the introduction of existent types.[21] Since existent types are used for all array and container types in JS++ (such as hash maps, Stack<T>, and Queue<T>), JS++ containers are thus guaranteed to not have out-of-bounds errors.
In JS++, undefined is a value that cannot be changed. In JavaScript (ECMAScript 3), undefined is a mutable property of the global object, resulting in circumstances where "undefined" can be "defined."[22] Thus, existent types would not have been possible in pure JavaScript, as arrays can contain elements with the undefined value, undefined can be defined, or other edge and corner cases that are prevented in JS++.[21][23]
Also, in comparison to Java and early object-oriented languages such as Eiffel,[24][25] JS++ does not default initialize objects to null.[21] Instead, the compiler enforces initialization by the programmer:
class Car {}
Car car;
[ ERROR ] JSPPE6000: Variable `car' is not initialized at line 3 char 4
Therefore, since existent types are deeply embedded into the language, JS++ can guarantee that out-of-bounds errors never occur.[26][10]
Databases
[edit]The concept of existent types can be extended outside of containers. For example, in MySQL, columns can be nullable.[27][28] If the row does not exist for a specified condition (e.g. WHERE clause), the undefined value can be returned. However, if the row does exist but the value at the column is empty, a null value can be returned instead. This can simplify the code and interfaces to the data access layer.
Integer types
[edit]JS++ provides 8-bit, 16-bit, 32-bit, and 64-bit integer types as well as floating point types:
byte b1 = 0xFF; // unsigned 8-bit
signed byte b2 = -1; // signed 8-bit
short s1 = 1; // signed 16-bit
unsigned short s2 = 1; // unsigned 16-bit
int x1 = 0; // signed 32-bit
unsigned int x2 = 0; // unsigned 32-bit
long z1 = 1; // signed 64-bit
unsigned long z2 = 1; // unsigned 64-bit
float f = 0.5; // single-precision floating point
double d = 0.5; // double-precision floating point
From the project homepage:
// You're not required to declare the type for a variable and you can just
// keep writing regular JavaScript (again, NO learning curve):
var offset = 0;
// But, if you do, this next variable will always remain an 'unsigned int' - even at runtime.
// You'll never see NaN ("Not a Number") runtime errors again.
// This variable is 'unsigned' so it's also guaranteed to never be negative.
unsigned int pageHeight = $(document).height();
Block scoping
[edit]All variables in JS++ are block-scoped, including the JavaScript var statement.[29][30][31] Thus, there is no need for two different variable declaration keywords with different scoping rules, such as var and let co-existing simultaneously in JavaScript (ECMAScript 6).
Development tools
[edit]Compiler
[edit]The JS++ compiler is available for Windows, macOS, and Linux. It is a source-to-source compiler which emits JavaScript source code as an intermediate representation.
The compiler is developed with C/C++, and the developers claim there are "fewer than 10 open bug reports in the core compiler" after 3.5 years of engineering and 400,000 lines of code.[31][32]
Editor integration
[edit]JS++ integrates with various code editors including Visual Studio Code, Atom, and Sublime Text.[33][34][35]
Build tools
[edit]JS++ can be integrated with third-party build tools like Webpack.[36]
Release history
[edit]| Version number | Release date | Changes |
|---|---|---|
| 0.01 | 8 October 2011 | Alpha version, initial release |
| 0.011 | 10 October 2011 | Alpha version |
| 0.012 | 25 October 2011 | Alpha version |
| 0.013 | 29 January 2012 | Alpha version |
| 0.014.1 | 15 August 2012 | Alpha version |
| 0.4.1 | 31 May 2016 | Beta version, array and callback types, character literals, integral suffixes, removed ECMAScript ASI |
| 0.4.2 | 18 October 2016 | Modules, function overloading, dead code elimination, editor integrations |
| 0.4.2.1 | 24 October 2016 | Bug fixes |
| 0.4.2.2 | 17 November 2016 | Source map debugging |
| 0.4.2.4 | 25 December 2016 | Support for Mac OS X, C-style casts, callback and array conversions |
| 0.5.0 | 13 March 2017 | Classes |
| 0.5.1 | 26 March 2017 | 'foreach' loops |
| 0.5.2 | 27 July 2017 | BSD License, Interfaces, Abstract Classes, Virtual Methods, Auto-boxing |
| 0.7.0 | 27 October 2017 | All ECMAScript 3 features via Array<T> and Standard Library |
| 0.8.0 | 15 March 2018 | Generic programming, Dictionary<T>, multi-line strings, .js++ file extension |
| 0.8.1 | 27 March 2018 | auto, catch-all clauses, standard library modules for handling time, bug fixes |
| 0.8.4 | 23 May 2018 | New string functions, advanced generics, bug fixes, standard library expansion |
| 0.8.5 | 2 June 2018 | Bug fixes |
| 0.8.10 | 24 November 2018 | Faster compile times, stacks, queues, Unicode, Base64, generic default constraint rules |
| 0.9.0 | 11 January 2019 | Efficient compile time out-of-bounds error analysis |
| 0.9.1 | 1 July 2019 | Bug fixes |
| 0.9.2 | 18 October 2019 | Final (immutable) variables and default to 64-bit for macOS Catalina |
See also
[edit]References
[edit]- ^ "JavaScript++: New, Powerful Language for Better Web Development". 17 October 2011. Archived from the original on 17 October 2011.
- ^ "C++ et Javascript = Javascript++". La ferme du web. 12 October 2011. Archived from the original on 12 October 2011.
- ^ "Index of /downloads". 18 October 2011. Archived from the original on 18 October 2011.
- ^ "JavaScript Conference - DeveloperWeek 2016 - February 12–18". 13 February 2016. Archived from the original on 13 February 2016.
- ^ Poon, Roger (May 31, 2016). "JS++ Goes Into Public Beta". Onux.com.
- ^ Handy, Alex (June 1, 2016). "Onux seeks to fix JavaScript's lack of type safety". SD Times.
- ^ Krill, Paul (June 6, 2016). "New compiler tackles JavaScript's weak typing". InfoWorld.
- ^ Cimpanu, Catalin (June 9, 2016). "jQuery 3.0 Released and Other JavaScript News". Softpedia.
- ^ "The JS++ Type System, Appendix B: Problems (Why was this hard to solve?)". Retrieved 10 February 2020.
- ^ a b US patent 10296313, Roger Poon, "Safely consuming dynamically-typed code from a statically-typed programming language", published 2019-05-21
- ^ Bridgwater, Adrian (June 13, 2016). "Onux JS++, an answer to JavaScript 'brittle' type safety?". Computer Weekly. Archived from the original on 2016-07-22.
- ^ "The JS++ Type System". Onux.com.
- ^ "Classes". MDN Web Docs. Retrieved 2025-06-20.
- ^ Meyer, Bertrand (1988). Object-Oriented Software Construction. pp. 94, 100.
- ^ Poon, Roger (May 28, 2019). "Tips & Tricks: Object-oriented Sorting in JS++ with IComparable<T>". Retrieved June 20, 2025.
- ^ Poon, Roger (June 10, 2018). "Tips & Tricks: Only Fields are 'private' by Default". Retrieved June 20, 2025.
- ^ "std::unordered_map<Key,T,Hash,KeyEqual,Allocator>::operator[] - cppreference.com". en.cppreference.com. Retrieved June 20, 2025.
- ^ "std::unordered_map<Key,T,Hash,KeyEqual,Allocator>::at - cppreference.com". en.cppreference.com. Retrieved June 20, 2025.
- ^ Díaz, Fabio (January 23, 2019). "JS++, the JavaScript superset, is getting rid of out-of-bounds errors". Akuaroworld. Archived from the original on February 1, 2019. Retrieved February 1, 2019.
- ^ Cardoza, Christina (January 16, 2019). "JS++ programming language looks to solve out-of-bounds errors". SD Times.
- ^ a b c d e f Poon, Roger (January 11, 2019). "JS++ 0.9.0: Efficient Compile Time Analysis of Out-of-Bounds Errors". Onux.com.
- ^ "ECMAScript Language Specification" (Document). Ecma International. March 24, 2000. p. 86.
- ^ "Compatibility with JavaScript - JS++ & JavaScript Documentation". Retrieved June 20, 2025.
- ^ Meyer, Bertrand (1988). Object-Oriented Software Construction. pp. 70–77.
- ^ "Void-safety: Background, definition, and tools". Eiffel. Retrieved June 24, 2025.
- ^ US patent 11023214, Roger Poon & Anton Rapetov, "Preventing runtime out-of-bounds errors and exceptions with nominal types", published 2021-06-01
- ^ "MySQL :: MySQL 8.4 Reference Manual :: 13.6 Data Type Default Values". MySQL. Retrieved June 20, 2025.
- ^ "MySQL :: MySQL 8.4 Reference Manual :: 5.3.4.6 Working with NULL Values". MySQL. Retrieved June 20, 2025.
- ^ "Scoping - JS++ & JavaScript Documentation". Retrieved June 24, 2025.
- ^ "Compatibility with JavaScript - JS++ & JavaScript Documentation". Retrieved June 24, 2025.
- ^ a b "JS++ 0.9.1: Bug Fixes". July 2019.
- ^ Poon, Roger (October 9, 2019). "Compiler Software Engineering Methods". Retrieved June 24, 2025.
- ^ "JavaScript superset JS++ adds dead code elimination and more". Computerworld. October 19, 2016.
- ^ Cardoza, Christina (October 19, 2016). "JS++ 0.4.2 released with code editor integrations, modules and dead code elimination". SD Times.
- ^ Clark, Geneva (October 20, 2016). "JS++ 0.4.2 Release - Upgraded With Modular Design, Dead Code Elimination, and Multiple Code Editors". Zeomag.
- ^ Phoenix, Ingwie (7 December 2018). "Proof of Concept: Using JS++ with WebPack". GitHub. Ingwie Phoenix.
unsigned int), elimination of runtime type errors, full compatibility with existing JavaScript environments—including edge cases like ActiveX objects, cross-browser DOM inconsistencies, and iframes—and support for imperative, object-oriented, and functional programming paradigms.[1] The language compiles to ECMAScript 3-compliant JavaScript, ensuring broad compatibility from legacy browsers like Internet Explorer 6 to modern ones, and includes a standard library with classes, data structures, algorithms, and utilities, alongside tools like a documentation generator that produces pages from source code comments.[1] Backed by years of scientific research and developed by a team with experience dating to the early World Wide Web, JS++ emphasizes reliability in production environments, particularly when interfacing with third-party untyped code, and remains available for free download via its official compiler.[2]
Overview
Description and Purpose
JS++ is a statically-typed, optional-type programming language designed as a superset of JavaScript that compiles to plain JavaScript, targeting ECMAScript 3 (ES3)-compatible output with a sound gradual typing system to provide compile-time and runtime type correctness.[4][5] This approach ensures compatibility with existing JavaScript environments while introducing robust type guarantees that prevent subtle errors inherent in JavaScript's dynamic typing.[6] The primary purposes of JS++ are to enhance JavaScript's reliability and developer productivity by incorporating type safety mechanisms that catch common issues, such as type mismatches and NaN propagation, at both compile time and runtime, all while retaining the language's dynamic scripting flexibility for rapid prototyping and iteration.[4][7] By addressing these pain points, JS++ enables the creation of more maintainable and error-resistant codebases without requiring a complete rewrite of existing JavaScript applications.[8] Unique to JS++, its design is grounded in years of scientific research tackling JavaScript's shortcomings in large-scale software engineering, including the brittleness of type systems in competing supersets like TypeScript, and it prioritizes web development across client-side browsers and server-side environments through full Node.js compatibility.[4][8] This foundation allows JS++ to handle obscure edge cases, such as cross-browser DOM inconsistencies, that often plague untyped JavaScript in production.[6] JS++ targets developers seeking enhanced typing similar to TypeScript, with a sound type system for integrating untyped legacy code into typed systems for scalable web projects. Its sound gradual type system permits seamless mixing of typed and untyped code, ensuring type safety without forcing full adoption upfront.[4] Development of JS++ appears to have ceased around 2018, with no major updates since then (as of November 2025).[5]Compatibility and Compilation
JS++ source code is transpiled to standard ECMAScript 3 (ES3)-compatible JavaScript, ensuring it can execute in any JavaScript runtime environment, such as web browsers or Node.js, without requiring additional runtime dependencies.[9][7] The compilation process, performed via thejs++ command-line tool, generates standalone .js files from .jspp sources, allowing seamless deployment in legacy environments like Internet Explorer 6 as well as modern ones.[9] This approach prioritizes broad compatibility while leveraging the host environment's native execution capabilities.
As a superset of JavaScript, JS++ accepts all valid JavaScript code as syntactically correct, facilitating incremental adoption where developers can gradually introduce typed elements into existing untyped codebases without full rewrites.[7] Automatic type inference assigns the unified external type to undeclared variables (using var), while coercion mechanisms handle conversions between typed JS++ code and untyped JavaScript, such as appending "" for string promotion from external types.[10] The generated JavaScript output incorporates runtime type checks and lightweight conversions only in regions with declared types, optimizing performance by avoiding unnecessary overhead in untyped sections.[7] Support for ES5 and ES6+ features is achieved through transpilation to ES3 when targeting older runtimes.[6]
A key compatibility feature is the unified external type, which encapsulates all untyped JavaScript values into a single category, isolating JS++'s sound internal type system from potential errors in external code, such as propagation of undefined or null values into typed contexts.[10] This isolation enforces explicit conversions at boundaries, preventing runtime failures like type mismatches or unexpected mutations, while maintaining interoperability with JavaScript libraries declared via external statements.[7] By design, this mechanism ensures type soundness without compromising the dynamic nature of integrated JavaScript portions.[10]
History and Development
Origins and Design
JS++ was developed by Onux, a technology company founded in London, UK, with operations extending to San Francisco, California, and Silicon Valley, beginning in 2011 as an exploration of advanced type inference and gradual typing mechanisms for JavaScript.[11][7] The project originated from the need to mitigate the pitfalls of JavaScript's dynamic typing, such as runtime errors that proliferate in large-scale codebases and enterprise applications, while overcoming limitations in existing supersets like TypeScript, which do not provide full type soundness when interacting with untyped code.[7] Onux, established by Roger Poon, drew on the team's extensive experience—spanning over two decades and dating back to the early days of the World Wide Web—to focus on enhancing reliability for web development in production environments.[1][11] The core motivations behind JS++ centered on delivering a dependable superset of JavaScript that enforces engineering rigor without sacrificing compatibility or ease of adoption. Unlike prior attempts at typed JavaScript variants, which often resulted in brittle type safety or incomplete error detection, JS++ aimed to eliminate common issues like out-of-bounds errors through innovative approaches, including the invention of "existent types" by co-lead Anton Rapetov.[11][12] This effort was grounded in a scientific foundation, incorporating research-inspired type systems and compiler techniques to ensure provable guarantees against type-related failures.[1] Key design principles of JS++ emphasize soundness, defined as comprehensive type safety verified at both compile-time and runtime, enabling gradual typing where developers can incrementally add types to existing JavaScript code without a steep learning curve.[1][7] The language maintains full backward compatibility with legacy JavaScript, including seamless integration of untyped libraries via a unified external type mechanism that isolates typed regions while enforcing correctness across boundaries. Over years of iteration, the initial prototype evolved to simplify complex typing challenges, such as runtime enforcement and type preservation, resulting in a system that compiles to efficient, typed JavaScript while preserving the original ecosystem's flexibility.[7] This approach reflects the team's background in systems programming, algorithms, and compiler engineering, with contributions from patented innovations in type systems.[11]Release History
Development of JS++ began with alpha releases in 2011 and 2012, including version 0.013 on January 29, 2012, and 0.014.1 on August 15, 2012. JS++ entered open beta on June 7, 2016, introducing a typed superset of JavaScript with initial support for basic type checking and incremental typing for existing codebases.[2] At launch, the language targeted ES3 compatibility while emphasizing runtime type safety through a patent-pending unified external type system.[2] Later in 2016, version 0.4.2 was released on October 19, adding object-oriented programming features such as classes and the "module" keyword for modular code organization, alongside dead code elimination to optimize compilation by excluding unused functions and overloads. This update also enhanced integration with editors like Visual Studio Code and improved Windows support. Version 0.4.2.2 followed on November 21, 2016, incorporating in-browser debugging capabilities via source maps for setting breakpoints and logging.[13] Minor releases through 2017 and 2018 primarily addressed type system refinements, bug fixes, and compatibility improvements, with no major feature additions documented publicly.[5] The project's GitHub repository reflects updates ceasing around 2018, though official releases continued thereafter. The most recent version, 0.10.0, was released on December 10, 2021, under the BSD License, with the compiler remaining available for download from the official Onux website.[1] As of November 2025, JS++ operates in maintenance mode, with no new major versions or significant updates since version 0.10.0.[1]Language Features
Type System
JS++ employs a sound gradual type system that allows developers to optionally specify static types while maintaining compatibility with untyped JavaScript code. This approach enables a seamless transition from dynamic typing to full static typing, where variables can be declared with explicit types such asint x = 5; or left untyped using var for dynamic fallback. Unlike purely dynamic languages, JS++ provides compile-time guarantees that prevent type errors from propagating when mixing typed and untyped regions, ensuring runtime safety without requiring annotations for all code.[10]
The type system categorizes types into internal and external varieties to distinguish between JS++'s safe, statically checked constructs and JavaScript's dynamic behaviors. Internal types include primitives like int, unsigned int, string, and bool, as well as object types derived from classes and collections such as arrays and dictionaries. External types, represented by a unified external type (via keywords like external or var), abstract all JavaScript values into a single compile-time category, allowing automatic inference from context in mixed scenarios. For instance, a function parameter declared as external can accept any JavaScript input without immediate type checking, while internal types enforce strict validation.[10][14]
Soundness is achieved through a combination of compile-time checks and runtime guards that isolate typed JS++ code from untyped JavaScript. At compile time, the system detects mismatches, such as assigning a string to an int variable, halting compilation to prevent errors. Runtime guards employ the unified external type to handle untyped inputs safely; for example, invalid JavaScript values are converted to safe defaults like 0 for numeric types, avoiding crashes or unexpected behaviors. This mechanism ensures no type errors escape into execution, providing stronger guarantees than unsound systems.[10][14]
Unique to JS++, the type system eliminates common JavaScript pitfalls like NaN and undefined propagation by enforcing automatic conversions to predictable values during type transitions. It also supports custom type conversions for user-defined types, allowing developers to define how internal objects interact with external JavaScript data. In contrast to TypeScript, which relies on an any type that can introduce false negatives, JS++ proves soundness by isolating regions and avoiding unchecked unions, ensuring all type checks are verifiable without human-provided annotations.[10]
Object-Oriented Programming
JS++ supports object-oriented programming through a class-based system that emphasizes type safety and compile-time checks, distinguishing it from JavaScript's prototypal inheritance. This system was introduced in post-beta releases around 2016, enabling developers to define structured, reusable code with single inheritance and runtime polymorphism.[15] Classes in JS++ are declared using theclass keyword, creating user-defined types with typed fields and methods. Fields are declared with their types, and constructors initialize instances. For example, a basic Point class can be defined as follows:
class Point {
int x;
int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
class Point {
int x;
int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
new keyword, such as Point p = new Point(3, 4);. Inheritance is achieved via the extends keyword for single inheritance, allowing subclasses to inherit and override members while supporting polymorphism through virtual methods resolved at runtime. The super keyword accesses parent class members, and the final modifier prevents further subclassing or overriding to enforce design contracts.[16][17]
Encapsulation in JS++ defaults to private visibility for all members, reducing accidental exposure in large codebases and promoting data hiding. Explicit access modifiers like public, protected, and private provide fine-grained control. Getters and setters enable controlled access to private fields. Consider this BankAccount example demonstrating encapsulation:
class BankAccount {
private int balance;
BankAccount(int initialBalance) {
this.balance = initialBalance;
}
public int getBalance() {
return this.balance;
}
public void deposit(int amount) {
if (amount > 0) {
this.balance += amount;
}
}
public void withdraw(int amount) {
if (amount > 0 && amount <= this.balance) {
this.balance -= amount;
}
}
}
class BankAccount {
private int balance;
BankAccount(int initialBalance) {
this.balance = initialBalance;
}
public int getBalance() {
return this.balance;
}
public void deposit(int amount) {
if (amount > 0) {
this.balance += amount;
}
}
public void withdraw(int amount) {
if (amount > 0 && amount <= this.balance) {
this.balance -= amount;
}
}
}
balance is private, accessible only through public methods that enforce business rules.[15]
To illustrate polymorphism in practice, JS++ allows defining comparable classes for sorting. A Sortable base class with a compare method can be extended, enabling type-safe sorting implementations. For instance:
class Sortable {
public virtual int compare(Sortable other) {
// Default comparison; subclasses override
return 0;
}
}
class Person extends Sortable {
string name;
int age;
Person(string name, int age) {
this.name = name;
this.age = age;
}
public override int compare(Sortable other) {
Person p = (Person) other;
if (this.age < p.age) return -1;
if (this.age > p.age) return 1;
return 0;
}
}
// Usage in a sorting function (assuming a typed [array](/page/Array))
Person[] people = new Person[2] { new Person("Alice", 30), new Person("Bob", 25) };
// Sort using compare method (implementation via [standard library](/page/Standard_library) or custom sorter)
class Sortable {
public virtual int compare(Sortable other) {
// Default comparison; subclasses override
return 0;
}
}
class Person extends Sortable {
string name;
int age;
Person(string name, int age) {
this.name = name;
this.age = age;
}
public override int compare(Sortable other) {
Person p = (Person) other;
if (this.age < p.age) return -1;
if (this.age > p.age) return 1;
return 0;
}
}
// Usage in a sorting function (assuming a typed [array](/page/Array))
Person[] people = new Person[2] { new Person("Alice", 30), new Person("Bob", 25) };
// Sort using compare method (implementation via [standard library](/page/Standard_library) or custom sorter)
import and export statements akin to ES6 modules but with static type verification across boundaries. For example, a class can be exported from one module and imported into another, maintaining type integrity for large-scale applications.[19]
Control Structures and Data Types
JS++ introduces enhancements to JavaScript's control flow mechanisms and primitive data types, providing stricter scoping and precise numeric handling to mitigate common pitfalls in untyped JavaScript code.[20] These features leverage the language's static type system to enable compile-time verification, ensuring more reliable program behavior in web applications.[21]Data Types
JS++ supports a range of primitive data types, with a particular emphasis on integer types for accurate arithmetic operations. Theint type is a 32-bit signed two's-complement integer, ranging from -2,147,483,648 to 2,147,483,647, while unsigned int is a 32-bit unsigned integer ranging from 0 to 4,294,967,295.[22][23] Unlike JavaScript's Number type, which uses 64-bit IEEE 754 double-precision floating-point representation with only 53 bits of integer precision, JS++ integers provide exact representation for values within their range, avoiding precision loss in computations such as large integer additions or multiplications.[22] For example:
int x = 2147483647; // Maximum int value
unsigned int y = 4294967295; // Maximum unsigned int value
int result = x + 1; // Wraps around to -2147483648 due to overflow
int x = 2147483647; // Maximum int value
unsigned int y = 4294967295; // Maximum unsigned int value
int result = x + 1; // Wraps around to -2147483648 due to overflow
bool for boolean values and string for text, all integrated with the type system for compile-time checks.[24]
Control Structures
Control structures in JS++ build on JavaScript's syntax but incorporate block scoping and type awareness to prevent common errors like variable hoisting. All variables declared within blocks, such asint i = 0;, are strictly scoped to that block, akin to let and const in modern JavaScript, ensuring they cannot be accessed outside their defining scope and eliminating hoisting-related issues associated with var.[20] For instance:
{
int i = 0; // Scoped only to this block
// i is incremented here
}
// i is inaccessible outside, preventing unintended reuse
{
int i = 0; // Scoped only to this block
// i is incremented here
}
// i is inaccessible outside, preventing unintended reuse
if, else if, and else for branching based on boolean expressions, and switch for multi-way selection using strict equality matching (equivalent to ===).[25][26] The switch statement requires explicit break statements to avoid fallthrough, with the compiler issuing warnings for missing breaks, and supports a default case for unmatched values. Loops such as for, while, do...while, for...in, and foreach allow iteration, with declarations inside loops benefiting from block scoping and type enforcement—for example, a for loop can declare a typed counter like for (int i = 0; i < 10; ++i).[27][26] These structures integrate with JS++'s type system (detailed separately) to catch type mismatches at compile time, such as assigning a non-integer to a loop variable.
Safety Features
JS++ incorporates several built-in safety features that extend beyond its type system to prevent common runtime errors prevalent in plain JavaScript, such as out-of-bounds accesses and null/undefined mishandling, through compile-time static analysis and targeted runtime checks. These mechanisms aim to prove the absence of specific error classes at compile time, reducing reliance on dynamic error handling and enabling safer code generation that compiles to efficient ECMAScript 3 JavaScript. Unlike JavaScript's dynamic checks, which can lead to unpredictable runtime failures, JS++'s analyses ensure deterministic behavior while maintaining full compatibility with existing JavaScript environments. These features were introduced in JS++ 0.9.0 (2019); the latest version, 0.10.0, was released on December 10, 2021.[28][1] A core safety feature is the out-of-bounds analysis introduced in JS++ 0.9.0, which performs efficient compile-time detection of invalid array, string, and object accesses to prevent buffer overflows or undefined value returns that could crash applications. This analysis leverages existent types (denoted asT+), which distinguish in-bounds values of type T from out-of-bounds accesses that would otherwise yield undefined in JavaScript. For instance, in the code int[] arr = [7, 8, 9]; int+ x = arr[0];, the compiler confirms x is an in-bounds int, while int+ y = arr[1000]; flags the out-of-bounds access at compile time, allowing safe fallback handling like int b = y ?? 1;. The compiler generates minimal runtime bounds checks only when necessary, adding negligible overhead (e.g., 1-2 ms on benchmarks for projects up to 6,000 lines), and extends to dictionary (object) key accesses and conditional branching logic. This static proof of bounds safety eliminates entire classes of errors without the performance cost of pervasive dynamic checks in other languages like Java or C#.[28]
Null and undefined safety is enhanced through nullable types (T?) and combined existent-nullable types (T?+), which explicitly model empty or non-existent values, preventing ambiguous runtime errors common in JavaScript. For example, int?+ d = 1; can hold an integer, null (an empty but existent value), or undefined (non-existent), allowing the compiler to track and enforce safe handling. JS++ supports optional chaining via the safe navigation operator (?.) and nullish coalescing (??), enabling expressions like Console.log(arr[1000]?.toString() ?? "out of bounds"); to avoid exceptions on invalid accesses. These features integrate with the type system to eliminate obscure JavaScript edge cases, such as unreliable instanceof checks across execution frames, by resolving type identities statically during compilation.[28][10]
For enforcing program invariants, JS++ provides runtime assertions through the System.Assert module in its standard library, which includes methods to verify conditions at execution time and throw an AssertError if violated. These assertions complement compile-time checks, allowing developers to validate assumptions like data integrity or external library behaviors, such as Assert.isTrue(condition, "Invariant failed");. In web database code, frameworks like Altitude leverage JS++'s type-safe data access layers for MySQL and similar databases, ensuring typed query results handle nulls and prevent pointer-like exceptions through compile-time validation of result types. This typed approach indirectly mitigates risks like SQL injection by promoting parameterized queries via safe, typed interfaces, though primary prevention relies on database library implementations.[29][30]
Interoperability
Importing JavaScript Libraries
JS++ facilitates the integration of existing untyped JavaScript libraries by allowing developers to declare them as external symbols, enabling seamless interoperability while providing optional type safety. The primary mechanism is theexternal statement, which imports JavaScript identifiers into the JS++ scope without requiring type definition files or build tools. This declaration assumes the JavaScript library is loaded in the runtime environment, such as via a <script> tag in browsers or require in Node.js, making JS++ compatible with the vast JavaScript ecosystem.[9][31]
The syntax for the external statement is straightforward: external identifier; or external identifier = initializer;, where multiple identifiers can be comma-separated. For instance, to import the jQuery library, one declares external jQuery, $;, which brings the global $ and jQuery objects into scope. This allows direct usage in JS++ code, such as string src = $("#logo").attr("src");, where the selector returns a typed string at compile time. Without explicit typing, these symbols adopt the unified external type, a special type in JS++ that encompasses all possible JavaScript values, ensuring sound static analysis across varying JavaScript implementations.[31][10]
Handling untyped JavaScript code involves wrapping library functions and objects with the unified external type, which provides a safe typed interface for calls while abstracting platform-specific behaviors. Automatic coercion occurs during compilation to JavaScript, converting JS++ types (e.g., int or string) to compatible JavaScript equivalents, such as numbers or strings. If a library returns an unexpected type, JS++ isolates errors at runtime without propagating to typed code, maintaining isolation through the external wrapper; for example, invoking an untyped jQuery method on invalid input triggers a standard JavaScript error, but typed parameters prevent compile-time issues. Developers can enhance safety by adding type annotations, such as using typed variables for parameters like byte for RGB values (0-255).[9][10]
// Example: Typed jQuery usage
external jQuery, $;
// Typed selector and attribute access
string url = $("#logo").attr("src"); // Compile-time type: string
if (url == "/images/logo.png") {
alert("Logo found");
}
// Example: Typed jQuery usage
external jQuery, $;
// Typed selector and attribute access
string url = $("#logo").attr("src"); // Compile-time type: string
if (url == "/images/logo.png") {
alert("Logo found");
}
external declarations for quick integration, then refine with specific types for critical APIs to catch errors early; for complex libraries, create JS++ wrapper modules that export typed interfaces, allowing progressive adoption without rewriting the entire codebase. This approach leverages JS++'s optional typing to bridge untyped JavaScript while minimizing runtime surprises. As of 2025, JS++ development appears inactive since its last update in 2019.[9][10][28]
External Interactions
JS++ provides typed interfaces for core browser objects such asdocument and window, enabling developers to interact with the Document Object Model (DOM) and other Web APIs while benefiting from compile-time type checking. These interfaces account for variations in browser implementations, including support for non-standard features like ActiveX objects in Internet Explorer, ensuring consistent behavior without requiring manual type guards. For instance, the type system safeguards against garbage collection bugs and unpredictable data formats in host objects, promoting portability across environments from legacy browsers like IE6 to modern ones.[4]
In cross-context scenarios, such as iframes, JS++ addresses challenges with operators like instanceof by enforcing safe type resolution across frames, which prevents runtime type errors and security issues in modular web applications. Event handling in these contexts is similarly protected, allowing reliable propagation without explicit checks for frame boundaries. This built-in analysis extends to edge cases in legacy browser quirks, such as inconsistent event bubbling or property access, ensuring code runs portably without additional runtime guards.[4]
For server-side development, JS++ maintains compatibility with Node.js through its compilation to ECMAScript 3 JavaScript, supporting typed modules for operations like file I/O and HTTP requests. Developers can import Node.js modules using the external statement, such as external require; external fs = require("fs"); for safe file operations with error handling, or integrate HTTP clients via external libraries with type safeguards against common pitfalls like unhandled asynchronous errors. These features enable robust server-side code with compile-time verification of interactions with Node.js APIs.[31]
Development Tools
Compiler
The JS++ compiler, distributed as the command-line executablejs++, serves as the primary tool for transpiling JS++ source files into optimized, executable JavaScript. It processes JS++ code by parsing the syntax, enforcing optional static type checking, and generating standard JavaScript that maintains compatibility with existing JavaScript environments and libraries. This compilation ensures type guarantees at both compile-time and runtime, enabling developers to integrate JS++ seamlessly with untyped JavaScript without runtime errors from type mismatches.[1][32]
Basic usage of the compiler involves invoking it from the terminal or command prompt with the source file as input. For example, js++ main.jspp compiles the file and outputs main.js by default, while specifying an output file uses the -o flag: js++ -o output.js input.jspp. Additional flags include --execute to compile and immediately run the resulting JavaScript in a Node.js environment, and -O levels (e.g., -O2) to enable optimization passes for performance tuning. Debug information can be retained via appropriate flags during development, though strict mode enforcement is handled implicitly through type annotations rather than a dedicated flag. The compiler is freely downloadable from the official site at onux.com/jspp, with binaries provided for Windows (via setup.exe installer), macOS, and Linux.[9][33][1]
Architecturally, the JS++ compiler operates in multiple passes: an initial parsing phase to build an abstract syntax tree from JS++ source, followed by a typing pass for static type inference and checking, an analysis pass for optimizations and error detection, and a final code generation pass to produce JavaScript output. Dead code elimination is integrated into the analysis phase, automatically removing unused functions, variables, and overloads to reduce bundle sizes and improve runtime efficiency— a feature unique to JS++ and not applicable to plain JavaScript. This modular design supports handling large codebases effectively, with incremental compilation capabilities introduced in the 2016 beta release to recompile only modified modules, minimizing build times for extensive projects.[32][33][1]
During the typing and analysis passes, the compiler performs safety analyses to detect potential runtime issues, such as out-of-bounds access, contributing to JS++'s sound type system (detailed further in the Safety Features section).[32]