{"id":801,"date":"2019-01-11T23:19:49","date_gmt":"2019-01-11T23:19:49","guid":{"rendered":"http:\/\/www.onux.com\/jspp\/blog\/?p=801"},"modified":"2019-01-12T01:03:56","modified_gmt":"2019-01-12T01:03:56","slug":"jspp-0-9-0-efficient-compile-time-analysis-of-out-of-bounds-errors","status":"publish","type":"post","link":"https:\/\/www.onux.com\/jspp\/blog\/jspp-0-9-0-efficient-compile-time-analysis-of-out-of-bounds-errors\/","title":{"rendered":"JS++ 0.9.0: Efficient Compile Time Analysis of Out-of-Bounds Errors"},"content":{"rendered":"<p>I promised a breakthrough for our next release.<\/p>\n<p>We are proud to announce JS++ efficiently analyzes and prevents out-of-bounds errors. An out-of-bounds error occurs when you attempt to access a container element that doesn&#8217;t exist in the container. For example, if an array has only three elements, accessing the tenth element is a runtime error.<\/p>\n<p>In C, you risk buffer overflows. In C++, you risk buffer overflows and exceptions. In Java and C#, you get an exception at runtime. If exceptions are uncaught, the application terminates. If segmentation faults occur, the application terminates. In the case of buffer overflows, you open your application to a variety of exploits.<\/p>\n<p>As we will show, we can perform out-of-bounds analysis with only a \u00b11-2ms (milliseconds) overhead on complex projects. There is virtually no effect on compile times with our invention.<\/p>\n<p>Out-of-bounds errors have plagued computer science and programming for decades. Detecting these errors at compile time has ranged from slow to impossible, depending on the language design. With that said, let&#8217;s first explore the problems which influenced the design.<\/p>\n<h3>Problems<\/h3>\n<p><strong>Basic Cases to Handle<\/strong><\/p>\n<p>In all of the following cases, you cannot predict the value at compile time:<\/p>\n<pre class=\"brush:jspp\">\r\nimport System;\r\n\r\nint[] arr = [ 1, 2, 3 ];\r\n\r\nConsole.log(arr[Math.random(1, 100)]);\r\nConsole.log(arr[getUserInput()]);\r\nConsole.log(arr[getValueFromFile()]);\r\nConsole.log(arr[API.getTweetLimit()]);\r\n<\/pre>\n<p>JS++ doesn&#8217;t stop at array indexes. Array indexes are limited to numeric values. What about arbitrary string keys on <code>System.Dictionary&lt;T&gt;<\/code>? Yes, we handle these too:<\/p>\n<pre class=\"brush:jspp\">\r\nimport System;\r\n\r\nauto dict = new Dictionary&lt;string&gt;();\r\n\r\nConsole.log(dict[Math.random(1, 100).toString()]);\r\nConsole.log(dict[getUserInput()]);\r\nConsole.log(dict[getTextFromFile()]);\r\nConsole.log(dict[API.getTwitterUsername()]);\r\n<\/pre>\n<p>These are the basic cases. It gets more complex with branching logic:<\/p>\n<pre class=\"brush:jspp\">\r\nimport System;\r\n\r\nDictionary&lt;string&gt; dict = {\r\n    \"1\":  \"a\",\r\n    \"10\": \"b\"\r\n};\r\n\r\nbool yes() {\r\n    return Math.random(0, 100) > 50;\r\n}\r\n\r\nif (yes()) {\r\n    dict[\"20\"] = \"c\";\r\n}\r\n\r\nstring key = Math.random(0, 100).toString();\r\nif (dict.contains(key)) {\r\n    Console.log(dict[key]);\r\n}\r\nelse {\r\n    Console.log(dict[key + \"0\"]);\r\n}\r\n<\/pre>\n<p>These are the very basic cases. There are more&#8230; a lot more. All the corner cases you need to explore are outside the scope of this announcement.<\/p>\n<p><strong>Compile Times <u>Must<\/u> Be Fast<\/strong><\/p>\n<p>Efficiency is the key. We can&#8217;t announce 30% faster compile times in <a href=\"https:\/\/www.onux.com\/jspp\/blog\/js-0-8-10-faster-compile-times-stacks-queues-unicode-base64-and-more\/\" rel=\"noopener\" target=\"_blank\">the previous release<\/a> and simultaneously promise a breakthrough that will cause compile times to explode exponentially.<\/p>\n<p>Clearly, following every branch, virtual function call, external function call, and then some would not be a realistic proposal.<\/p>\n<p>First, let&#8217;s look at a basic benchmark so we know what we&#8217;re comparing against. In the last release, 0.8.10, I measured &#8220;Hello World&#8221; compile times. With all of the analyses we added in 0.9.0 (the latest release), how much did it increase compile times for &#8220;Hello World&#8221;? A little under two (2) milliseconds:<\/p>\n<table>\n<thead>\n<tr>\n<th>Version<\/th>\n<th>Total Time<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>JS++ 0.8.10<\/td>\n<td>72.6ms<\/td>\n<\/tr>\n<tr>\n<td>JS++ 0.9.0<\/td>\n<td>74.2ms<\/td>\n<\/tr>\n<\/tbody>\n<tfoot>\n<tr>\n<td colspan=\"2\">(Lower is better)<\/td>\n<\/tr>\n<\/tfoot>\n<\/table>\n<p>The test system is the exact same as the one we used to measure compile times for 0.8.10:<\/p>\n<p>Intel Core i7-4790k<br \/>\n32gb DDR3 RAM<br \/>\nSamsung 960 EVO M.2 SSD<br \/>\nDebian Linux 9<\/p>\n<p>However, &#8220;Hello World&#8221; is not a perfect benchmark. How long does it take to compile real-world projects with thousands of lines of code that make <strong>lots of array and dictionary accesses<\/strong>? Here are three projects <em>before<\/em> we introduced compile-time analysis of out-of-bounds errors:<\/p>\n<table>\n<thead>\n<tr>\n<td colspan=\"3\">Compile times for 0.8.10 &#8211; before out-of-bounds checking<\/td>\n<\/tr>\n<tr>\n<th>Line Count<\/th>\n<th>Source Files Count<\/th>\n<th>Total Time<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>1,137 lines<\/td>\n<td>27 files<\/td>\n<td>124.8ms<\/td>\n<\/tr>\n<tr>\n<td>4,210 lines<\/td>\n<td>42 files<\/td>\n<td>164.4ms<\/td>\n<\/tr>\n<tr>\n<td>6,019 lines<\/td>\n<td>72 files<\/td>\n<td>224.6ms<\/td>\n<\/tr>\n<\/tbody>\n<tfoot>\n<tr>\n<td colspan=\"3\">(Lower is better)<\/td>\n<\/tr>\n<\/tfoot>\n<\/table>\n<p>Here are compile times after we introduced analysis of out-of-bounds errors:<\/p>\n<table>\n<thead>\n<tr>\n<td colspan=\"3\">Compile times for 0.9.0 &#8211; detection of out-of-bounds at compile time<\/td>\n<\/tr>\n<tr>\n<th>Line Count<\/th>\n<th>Source Files Count<\/th>\n<th>Total Time<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>1,140 lines<\/td>\n<td>27 files<\/td>\n<td>124.4ms<\/td>\n<\/tr>\n<tr>\n<td>4,148 lines<\/td>\n<td>41 files<\/td>\n<td>165.4ms<\/td>\n<\/tr>\n<tr>\n<td>5,942 lines<\/td>\n<td>71 files<\/td>\n<td>224.2ms<\/td>\n<\/tr>\n<\/tbody>\n<tfoot>\n<tr>\n<td colspan=\"3\">(Lower is better)<\/td>\n<\/tr>\n<\/tfoot>\n<\/table>\n<p>There&#8217;s a slight change in line and file counts due to the inclusion of a &#8216;Base64&#8217; library, which &#8211; during the 0.9.0 refactoring &#8211; I removed and replaced with the Standard Library&#8217;s System.Encoding.Base64. (The code is the exact same.)<\/p>\n<p>The above projects include both frontend and backend code. They include lots of modules, classes, arrays, dictionaries, and other complexities. I&#8217;ve included source file counts to account for disk I\/O.<\/p>\n<p>It can be observed that there is virtually no performance penalty for dealing with out-of-bounds errors at compile time. The results are within \u00b11ms (milliseconds).<\/p>\n<p><strong>Nullable Types are a Problem<\/strong><\/p>\n<p>Expressing nullability is important in computer programming. For example, a file might have a creation date and last access time. For a new file, there may never have been a &#8220;last access time&#8221;; thus, it might be ideal to use a nullable data type in this case.<\/p>\n<p>Nullable types are a solved problem in other languages. We considered having <code>Array&lt;T&gt;<\/code> return <code>T?<\/code>, but there would be issues with that as presented by Anton Rapetov, our lead compiler engineer:<\/p>\n<pre class=\"brush:jspp\">\r\nint[] intArr = [ 1, 2 ];\r\nint? intEl2 = intArr[2];\r\nif (intEl2 == null) {\r\n    Console.log(\"Definitely out of bounds\");\r\n}\r\n\r\nint?[] nullIntArr = [ 1, null ];\r\nint? nullIntEl2 = nullIntArr[2];\r\nif (nullIntEl2 == null) {\r\n    Console.log(\"Might be out of bounds, might just be an access of a null element\");\r\n}\r\n<\/pre>\n<p><strong>Usability<\/strong><\/p>\n<p>Even if returning nullable types worked, there would be significant usability issues. For example, the following is common code:<\/p>\n<pre class=\"brush:jspp\">\r\nint[] arr = [ 1, 2, 3 ];\r\nfor (int i = 0, len = arr.length; i < len; ++i) {\r\n    arr[i]++;\r\n    \/\/ or\r\n    arr[i] += 1;\r\n}\r\n<\/pre>\n<p>In the above code, it's clear an out-of-bounds access can <em>never<\/em> occur. Nonetheless, if an array access returns <code>T?<\/code>, type conversions would be necessary before the <code>++<\/code> or <code>+= 1<\/code> operations can occur so we aren't adding to a null value. We need a way to avoid making the user do this for common operations. In fact, for common operations, we want you to be able to write the code exactly as you would above.<\/p>\n<p><strong>Exceptions<\/strong><\/p>\n<p>In a statically-typed programming language, exceptions allow us to return <code>T<\/code> for an <code>Array&lt;T&gt;<\/code> without compromising correctness on an out-of-bounds access. For example, if we declare an <code>Array&lt;int&gt;<\/code>, a 'pop' method can only return a value of type <code>int<\/code> or throw an exception. If an exception is thrown, it is none of the concern of the type checker. At compile time, it would not be possible to determine whether or not the exception will be thrown. Yet, an uncaught exception will result in premature program termination at runtime.<\/p>\n<p>Here's an example of how exceptions might be implemented for a container in JS++:<\/p>\n<pre class=\"brush:jspp\">\r\nclass Array&lt;T&gt;\r\n{\r\n    var data = [];\r\n\r\n    T pop() {\r\n        if (this.data.length > 0) {\r\n            return this.data[this.data.length - 1];\r\n        }\r\n        else {\r\n            throw new OutOfBoundsException(\"Array is empty.\");\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>By using exceptions, we never sacrifice type checker performance and compile times. Bounds checking is still performed, but the dark side of exceptions is that it can terminate the application if uncaught.<\/p>\n<p>If we avoid throwing exceptions, and just let JavaScript return <code>undefined<\/code>, we'd be walking into TypeScript territory and just letting our type system become unsound because it would be \"practical.\" While you might convert <code>undefined<\/code> to <code>int<\/code> as zero, there aren't always sensible default values for all JS++ types (e.g. a callback type or a non-nullable class <code>Foo<\/code> with no default constructor). Speaking of default values...<\/p>\n<p><strong>Default Initialization<\/strong><\/p>\n<p>Facebook discovered a problem with C++ maps and default initialization in their code that can lead to bugs:<\/p>\n<pre class=\"brush:cpp\">\r\nstd::unordered_map&lt;std::string, int&gt; settings{};\r\n\r\n\/\/ ...\r\n\r\nstd::cout << \"Timeout: \" << settings[\"timeout\"] << std::endl;\r\n<\/pre>\n<p>In the above code, simply printing the value of \"timeout\" can cause it to be zero-initialized. This led us to conclude that default initialization of missing keys would not be a solution. Default initialization of a map of word counts to zero for missing words is innocuous, but an accidental initialization of timeout or price values to zero can lead to substantially different bug severities.<\/p>\n<h3>The Breakthrough: null vs undefined<\/h3>\n<p>We wanted to have nullable types in the language. We wanted programmers to be able to express the following:<\/p>\n<pre class=\"brush:jspp\">\r\nclass Person\r\n{\r\n    string firstName = \"\";\r\n    string? middleName = null;\r\n    string lastName = \"\";\r\n}\r\n<\/pre>\n<p>As of the latest release (0.9.0), the above code will work because we've introduced nullable types.<\/p>\n<p>However, I want to revisit an example on nullable types earlier. When we decided to move forward with nullable types, a suggestion was brought up to return <code>T?<\/code> from array accesses. This example was given as a counter-argument:<\/p>\n<pre class=\"brush:jspp\">\r\nint[] intArr = [ 1, 2 ];\r\nint? intEl2 = intArr[2];\r\nif (intEl2 == null) {\r\n    Console.log(\"Definitely out of bounds\");\r\n}\r\n\r\nint?[] nullIntArr = [ 1, null ];\r\nint? nullIntEl2 = nullIntArr[2];\r\nif (nullIntEl2 == null) {\r\n    Console.log(\"Might be out of bounds, might just be an access of a null element\");\r\n}\r\n<\/pre>\n<p>We keep a record of all our meetings. While we didn't explicitly discuss <code>undefined<\/code> at all, I was in a hurry and summarized our meeting as:<\/p>\n<blockquote><p>\n>>>> * There's a problem differentiating between 'null' and<br \/>\n>>>> 'undefined':<br \/>\n>>>><br \/>\n>>>> ```<br \/>\n>>>> Foo?[] arr = [new Foo(), null];<br \/>\n>>>> auto el1 = arr[1];<br \/>\n>>>> auto el2 = arr[2];<br \/>\n>>>> ```<br \/>\n>>>><br \/>\n>>>> el1 has type Foo?<br \/>\n>>>> el2 has type Foo?<br \/>\n>>>><br \/>\n>>>> el1 has value null \/\/ el1 exists but is null<br \/>\n>>>> el2 has value null \/\/ el2 does NOT exist but is also null<br \/>\n>>>><br \/>\n>>>> To deal with this, we can add a `hasIndex(int i)` method to<br \/>\n>>>> containers.\n<\/p><\/blockquote>\n<p>Subconsciously, this led to the realization that all we had to do was differentiate between <code>null<\/code> and <code>undefined<\/code> in our type system.<\/p>\n<h3>Introducing Existent Types<\/h3>\n<p>In JavaScript, <code>null<\/code> means that a value exists but is an \"empty value,\" and <code>undefined<\/code> means no value exists at all. A basic example is here:<\/p>\n<pre class=\"brush:js\">\r\nvar x = null;\r\nvar y;\r\n\r\nconsole.log(x); \/\/ null\r\nconsole.log(y); \/\/ undefined\r\n<\/pre>\n<p>This illustrates the basic concept; unfortunately, JavaScript is inconsistent:<\/p>\n<pre class=\"brush:js\">\r\nvar x = null;\r\nvar y;\r\nvar z = undefined;\r\n\r\nconsole.log(x); \/\/ null\r\nconsole.log(y); \/\/ undefined\r\nconsole.log(z); \/\/ undefined\r\n<\/pre>\n<p>JS++ has different semantics. First of all, in JS++, all variables must be initialized; therefore, you can't have a variable reference return <code>undefined<\/code>... ever. Secondly, <code>null<\/code> means \"empty value,\" but <code>undefined<\/code> in JS++ means \"out-of-bounds error.\"<\/p>\n<p>JS++ introduces existent types, which uses the <code>+<\/code> syntax, to describe container accesses:<\/p>\n<pre class=\"brush:jspp\">\r\nint[] arr = [ 7, 8, 9 ];\r\n\r\nint+ x = arr[0];\r\nint+ y = arr[1000];\r\n<\/pre>\n<p>We can think of existent types as the \"bounds-checked type.\" I'm a big believer in simplicity. Rather than trying to calculate whether the container access is within-bounds or out-of-bounds at compile time, we delay this check to runtime via the code generator. Existent types are not purely a type checking innovation. The type provides guidance to the code generator to generate code such as the following:<\/p>\n<pre class=\"brush:jspp\">\r\nint[] arr = [ 7, 8, 9 ];\r\n\r\nint+ x = 0 < arr.length ? arr[0] : undefined;\r\nint+ y = 1000 < arr.length ? arr[1000] : undefined;\r\n<\/pre>\n<p>We don't actually generate code this way, but it helps illustrate the concept for developers coming from backgrounds in C, C++, C#, Java, etc.<\/p>\n<p>By default, <code>int+<\/code> and <code>int<\/code> are not compatible types. I'll start by introducing the \"safe default operator\":<\/p>\n<pre class=\"brush:jspp\">\r\nint[] arr = [ 7, 8, 9 ];\r\n\r\nint+ x = arr[0];\r\nint+ y = arr[1000];\r\n\r\nint a = x ?? 0;\r\nint b = y ?? 1;\r\n<\/pre>\n<p>The \"safe default operator\" will check if the left-hand side is <code>undefined<\/code>. If the value is <code>undefined<\/code>, the evaluated value of the right-hand side of the ?? operator is returned. Otherwise, the left-hand side is returned. In the case of the example above, 'a' will have the value of 7 because 'x' was within-bounds. 'b' will have the value of '1' because 'y' was out-of-bounds, and, thus, the alternative value provided to the ?? operator was used.<\/p>\n<p><strong>T+ cannot be the element type<\/strong><\/p>\n<p>The problem with JavaScript is that you can have an array of <code>undefined<\/code> values:<\/p>\n<pre class=\"brush:js\">\r\nvar arr = [ undefined, undefined, undefined ];\r\n<\/pre>\n<p>In the above case, JavaScript would not be able to differentiate between a within-bounds <code>undefined<\/code> and an out-of-bounds <code>undefined<\/code>. In JS++, an existent type cannot be the element type of an array or other container:<\/p>\n<pre class=\"brush:jspp\">\r\nint+[] arr = []; \/\/ ERROR\r\n<\/pre>\n<p style=\"background:#2F3335;color:#D5D5D5;padding:4px;font-family:monospace;\"><span style=\"color:#ff0000;\">[  ERROR  ]<\/span> JSPPE5204: Existent type `int+' cannot be used as the element type for arrays<\/p>\n<p>Therefore, the invention of existent types cannot be retroactively applied to JavaScript.<\/p>\n<p>If you want to represent an array element as having an \"empty\" value, you have to use nullable types...<\/p>\n<p><strong>Nullable Types + Existent Types<\/strong><\/p>\n<p>The following describes the basic syntax for the nullable and existent types being introduced in version 0.9.0:<\/p>\n<pre class=\"brush:jspp\">\r\nint a = 1;  \/\/ 'int' only\r\nint? b = 1; \/\/ 'int' or 'null'\r\nint+ c = 1; \/\/ 'int' or 'undefined'\r\n<\/pre>\n<p>However, sometimes we want an array element to contain the \"empty\" value. In this case, we can <em>combine<\/em> nullable types with existent types using the following syntax:<\/p>\n<pre class=\"brush:jspp\">\r\nint?+ d = 1; \/\/ 'int' or 'null' or 'undefined'\r\n<\/pre>\n<p>In this way, JS++ doesn't have the ambiguity of an <code>undefined<\/code> value that can be a within-bounds access and also an out-of-bounds access.<\/p>\n<p><strong>Usage with Dictionaries<\/strong><\/p>\n<p>Existent types can also be used with System.Dictionary&lt;T&gt;. We just introduced how nullable and existent types can be combined so let's use the combination:<\/p>\n<pre class=\"brush:jspp\">\r\nimport System;\r\n\r\nDictionary&lt;bool?&gt; inviteeDecisions = {\r\n    \"Roger\": true,\r\n    \"Anton\": true,\r\n    \"James\": null, \/\/ James is undecided\r\n    \"Qin\": false\r\n};\r\n\r\nbool?+ isJamesAttending = inviteeDecisions[\"James\"]; \/\/ 'null'\r\nbool?+ isBryceAttending = inviteeDecisions[\"Bryce\"]; \/\/ 'undefined'\r\n<\/pre>\n<p>In the above code, we use the <code>?+<\/code> syntax to combine nullable and existent types. We're throwing a party, and we want to keep track of the decisions of our invitees. If the invitee's decision is <code>true<\/code>, he's coming to the party. If the invitee's decision is <code>false<\/code>, he won't be attending. If the invitee's decision is <code>null<\/code>, he is undecided. Finally, if the invitee's decision evaluates to <code>undefined<\/code>, he was not actually invited.<\/p>\n<p>Naturally, the operators that apply to nullable types and existent types (such as the <code>??<\/code> safe default operator) will also apply to the combined <code>?+<\/code> type as well. Code will just be generated to check for <code>null<\/code> <em>and<\/em> <code>undefined<\/code> when using the combined <code>?+<\/code> type.<\/p>\n<p>Beyond arrays and dictionaries, existent types can be applied to the other Standard Library containers (such as Stack&lt;T&gt; and Queue&lt;T&gt;) and even user-defined containers.<\/p>\n<p><strong>Safe Navigation Operator<\/strong><\/p>\n<p>Besides not being able to differentiate from a within-bounds <code>undefined<\/code> from an out-of-bounds <code>undefined<\/code>, JavaScript suffers from another problem:<\/p>\n<pre class=\"brush:js\">\r\nvar arr = [ 1 ];\r\nconsole.log( arr[1000].toString() );\r\nconsole.log( \"This will never get logged.\" );\r\n<\/pre>\n<p>The above code will never reach line 3. The reason is because arr[1000] evaluated to undefined, and you can't call the toString() method on undefined so you'll get a runtime 'TypeError'. In JS++, this isn't a problem because the compiler will detect your attempt to use the <code>.<\/code> operator and suggest for you to use the <code>?.<\/code> safe navigation operator instead:<\/p>\n<pre class=\"brush:jspp\">\r\nimport System;\r\n\r\nint[] arr = [ 1 ];\r\nConsole.log( arr[1000].toString() );\r\nConsole.log( \"This will eventually get logged.\" );\r\n<\/pre>\n<p style=\"background:#2F3335;color:#D5D5D5;padding:4px;font-family:monospace;\"><span style=\"color:#ff0000;\">[  ERROR  ]<\/span> JSPPE5200: The '.' operator cannot be used for nullable and existent types (`int+'). Please use the '?.' safe navigation operator instead at line 4 char 13<\/p>\n<p>If we refactor, we'll discover that, unlike the <code>??<\/code> safe default operator, <code>?.<\/code> can return undefined and evaluates to an existent type <code>T+<\/code>:<\/p>\n<pre class=\"brush:jspp\">\r\nimport System;\r\n\r\nint[] arr = [ 1 ];\r\nConsole.log( arr[1000]?.toString() );\r\nConsole.log( \"This will eventually get logged.\" );\r\n<\/pre>\n<p style=\"background:#2F3335;color:#D5D5D5;padding:4px;font-family:monospace;\"><span style=\"color:#ff0000;\">[  ERROR  ]<\/span> JSPPE5024: No overload for `System.Console.log' matching signature `System.Console.log(string+)' at line 4 char 0<\/p>\n<p>So one possible fix is to provide a default value:<\/p>\n<pre class=\"brush:jspp\">\r\nimport System;\r\n\r\nint[] arr = [ 1 ];\r\nConsole.log( arr[1000]?.toString() ?? \"out of bounds\" );\r\nConsole.log( \"This will eventually get logged.\" );\r\n<\/pre>\n<p>It finally compiles, and we get the following output:<\/p>\n<p style=\"background:#2F3335;color:#D5D5D5;padding:4px;font-family:monospace;\">\nout of bounds<br \/>\nThis will eventually get logged.\n<\/p>\n<p>No crashes and no exceptions can occur.<\/p>\n<p><strong>Inspecting 'undefined'<\/strong><\/p>\n<p>Oftentimes, when you encounter an out-of-bounds error, you might want to skip to the next iteration over the container or return from a function. Essentially, you want to \"skip\" code that was written for within-bounds accesses. In JS++, it's as simple as comparing against the <code>undefined<\/code> value:<\/p>\n<pre class=\"brush:jspp\">\r\nimport System;\r\n\r\nint[] arr = [ 1 ];\r\n\r\nfor (int i = 0; i < 10; ++i) {\r\n    int+ element = arr[i];\r\n    if (element == undefined) {\r\n        continue;\r\n    }\r\n\r\n    int x = (int) element;\r\n\r\n    Console.log(x + 1);\r\n    Console.log(x + 2);\r\n    Console.log(x + 3);\r\n}\r\n<\/pre>\n<p>The C-style cast to <code>int<\/code> is safe because we already checked for and skipped out-of-bounds accesses. We can also use the safe default operator instead in the code above.<\/p>\n<p>Finally, our output:<\/p>\n<p style=\"background:#2F3335;color:#D5D5D5;padding:4px;font-family:monospace;\">\n2<br \/>\n3<br \/>\n4\n<\/p>\n<p>This allows us to elegantly write large chunks of code for within-bounds accesses while skipping, returning, or just ignoring out-of-bounds accesses. We can even log the out-of-bounds error to stderr by using System.Console.error.<\/p>\n<h3>Downloads<\/h3>\n<p>We're providing download links for the latest release (0.9.0) and the previous version (0.8.10). We want you to be able to verify our claims and benchmarks.<\/p>\n<table>\n<thead>\n<tr>\n<th colspan=\"2\">JS++ 0.9.0 (latest) \u2013 includes out-of-bounds checking<\/th>\n<\/tr>\n<tr>\n<th>Platform<\/th>\n<th>Download Link<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Windows<\/td>\n<td><a href=\"https:\/\/onux.r.worldssl.net\/jspp\/downloads\/setup-JS++-0.9.0.exe\" target=\"_blank\">Download (32- and 64-bit)<\/a><\/td>\n<\/tr>\n<tr>\n<td>Mac OS X<\/td>\n<td><a href=\"https:\/\/onux.r.worldssl.net\/jspp\/downloads\/JS++-0.9.0-macosx.tar.gz\" target=\"_blank\">Download (32- and 64-bit)<\/a><\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">Linux<\/td>\n<td><a href=\"https:\/\/onux.r.worldssl.net\/jspp\/downloads\/JS++-0.9.0-linux_i386.tar.gz\" target=\"_blank\">Download (32-bit)<\/a><br \/><a href=\"https:\/\/onux.r.worldssl.net\/jspp\/downloads\/JS++-0.9.0-linux_x64.tar.gz\" target=\"_blank\">Download (64-bit)<\/a><\/td>\n<\/tbody>\n<\/table>\n<p><\/p>\n<table>\n<thead>\n<tr>\n<th colspan=\"2\">JS++ 0.8.10 \u2013 before out-of-bounds checking<\/th>\n<\/tr>\n<tr>\n<th>Platform<\/th>\n<th>Download Link<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Windows<\/td>\n<td><a href=\"https:\/\/onux.r.worldssl.net\/jspp\/downloads\/setup-JS++-0.8.10.exe\" target=\"_blank\">Download (32- and 64-bit)<\/a><\/td>\n<\/tr>\n<tr>\n<td>Mac OS X<\/td>\n<td><a href=\"https:\/\/onux.r.worldssl.net\/jspp\/downloads\/JS++-0.8.10-macosx.tar.gz\" target=\"_blank\">Download (64-bit)<\/a><\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">Linux<\/td>\n<td><a href=\"https:\/\/onux.r.worldssl.net\/jspp\/downloads\/JS++-0.8.10-linux_i386.tar.gz\" target=\"_blank\">Download (32-bit)<\/a><br \/><a href=\"https:\/\/onux.r.worldssl.net\/jspp\/downloads\/JS++-0.8.10-linux_x64.tar.gz\" target=\"_blank\">Download (64-bit)<\/a><\/td>\n<\/tbody>\n<\/table>\n<h3>What's Next?<\/h3>\n<p>Our first priority is to manage engineering complexity. We have to refactor our tests, and none of this will show up for you, the user. As I write this, I don't know what to expect. Existent types can bring demand for JS++, but we don't have the resources to manage this demand. Instead, we have to stay disciplined in sticking to our own internal schedules to ensure the long-term success of JS++. We listen to user input, but we don't (and can't) follow hype and trends. JS++ over the next 25 years will be more important than JS++ over the next 25 days. I point to Haskell as an example: it's a programming language that is well thought-out and has persisted for 29 years.<\/p>\n<p>We have users that have followed us for years, and we thank all of them for giving us the motivation to persist. If you're willing to be patient and watch JS++ evolve, I urge you to join our email list. The sign-up form for our email list can be found by scrolling to the bottom of this page.<\/p>\n<h3>Final Words<\/h3>\n<p>Existent types were co-invented by me and Anton Rapetov (lead compiler engineer for JS++).<\/p>\n<p>We solved compile-time analysis of out-of-bounds errors via traditional nominal typing. Thus, there is no performance difference for JS++ checking whether <code>int<\/code> can be assigned to <code>string<\/code> or whether <code>int+<\/code> can be assigned to <code>string<\/code>. This explains the \u00b1 1ms compile time difference for compile time out-of-bounds analysis.<\/p>\n<p>We place heavy emphasis on compile times because we know long compile times hurt developer productivity.<\/p>\n<p>When existent types are used correctly, you should never get premature or unexpected program termination.<\/p>\n<p>There is a full tutorial on nullable and existent types available <a href=\"https:\/\/www.onux.com\/jspp\/tutorial#Nullable-Existent-Types\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I promised a breakthrough for our next release. We are proud to announce JS++ efficiently analyzes and prevents out-of-bounds errors. An out-of-bounds error occurs when you attempt to access a container element that doesn&#8217;t exist in the container. For example, if an array has only three elements, accessing the tenth element is a runtime error. &hellip; <a href=\"https:\/\/www.onux.com\/jspp\/blog\/jspp-0-9-0-efficient-compile-time-analysis-of-out-of-bounds-errors\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;JS++ 0.9.0: Efficient Compile Time Analysis of Out-of-Bounds Errors&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[2,4],"tags":[],"_links":{"self":[{"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/posts\/801"}],"collection":[{"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/comments?post=801"}],"version-history":[{"count":180,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/posts\/801\/revisions"}],"predecessor-version":[{"id":982,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/posts\/801\/revisions\/982"}],"wp:attachment":[{"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/media?parent=801"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/categories?post=801"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/tags?post=801"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}