What Programming Language is Gini Built With?
Provably Secure. Unlike the "monolithic blobs" of Bitcoin and other cryptocurrencies, Gini's systems are designed to be provably secure, which means it will be possible to employ mathematical analysis of Gini's systems to provide quantifiable assurances that the software source code can perform as expected within specific statistical thresholds of security and reliability. This is possible primarily because Gini's systems and architecture are created with the Haskell programming language, which has many unique technical benefits. This is why Haskell is used by NASA, Lockheed Martin, Boeing, and many other aerospace and defense companies that must build safe and secure systems for airplanes, satellites, space shuttles, and other mission-critical systems that must perform at an exceptional level of safety, security, and reliability.
High-Reliability Gini Code. Since the core Gini components (Gini Settlement Layer and Gini Computation Layer) are produced with Haskell, which is classified as a "functional programming language," Gini's software source code is up to 80% more time- and cost-efficient than it would be if we used other imperative (aka, procedural or object-oriented) languages like C++, C#, Java, and most other languages. Haskell dramatically reduces the number of bugs and security holes throughout a software program’s lifecycle. Haskell also results in much more elegant and maintainable code, which results in substantially more reliable and cost-effective systems. (Here are some good technical overviews from Microsoft and the Quora Community about the benefits of functional programming languages.)
A few more technical bullet points about Haskell:
Haskell is a "functional programming language," which means virtually everything in Haskell is based on function definitions. This makes code more organized and readable and forces the coder to think about solving problems in a deeper and more intuitive way, rather than giving the computer a long series of tedious, decontextualized commands to accomplish the same behavior. It also means that coding in Haskell is focused on describing what data/functions are much more than what they should do. This has many interesting and significant implications for every aspect of the coding process.
Everything in Haskell is "immutable," which means: Once a value is set for a given variable, constant or function, that value is set forever (or as long as the program is running). Immutability is what prevents many bugs because it prevents variables and functions that are changed in some local scope from creating unintended/unexpected side-effects globally in other functions that depend on the same variable/function throughout the program.
In fact, Haskell technically doesn't have "variables"; it has "constants" (values) and "functions" (which are also treated as values) that never change. The only way to update a constant/function in Haskell is to define a new constant/function. However, the scope of a constant matters. For example, a constant declared at the global level can be re-declared as a different value within another function that handles I/O operations, but that new value only exists within the local scope of that I/O function. It does not change the value of the constant at the global scope or within the local scope of any other function.
Immutability makes refactoring Haskell code really fast and efficient because there's no possibility for unexpected gotchas (i.e., side-effects and state changes) that might cause a program to crash or create unexpected security vulnerabilities. In Haskell, the value of functions, variables, and constants can't be changed during run-time after they've already been declared, which simplifies source code analysis during the refactoring process. This eliminates one of the most tedious parts of refactoring and optimizing code: function performance profiling. Thus, it's much easier to maintain, update, and continuously improve all our Haskell-based Gini systems over time.
Haskell has referential transparency, which means the functions in Haskell expressions and their output values can be used interchangeably without changing the program’s behavior. This is related to immutability, but referential transparency refers to the fact that functions will always produce the same result given the same input, which is a very useful property when it comes to debugging, security audits, parallelization, concurrency, and code optimization. This is why Haskell typically performs exceptionally well in high-volume, high-throughput, concurrent network applications. In contrast, functions in imperative languages often depend on the state of other functions and variables, which can change at any time depending on the state of other components of a program. This creates many risks and uncertainties that make it much more difficult to ensure the security and integrity of programs written in non-functional languages.
In Haskell, we say "functions are first-class citizens." This means that functions can be passed as a parameter/argument to other functions just like any other variable or value. This opens up a vast amount of creative possibilities to write clean, efficient, reliable, and elegant code, which non-functional languages cannot replicate.
Intelligent Typeclass Inference & Compile-Time Error Detection. Haskell is widely regarded as having the most intelligent typeclass system of any programming language. This means data types (e.g., strings, integers, booleans, lists, and many others) are automatically and correctly detected by Haskell's type system and intelligently inferred from how the functions interact with the values that are passed between functions. For this reason, many computer scientists say, "In Haskell, if it compiles, it's correct." This may seem like a boring, arcane concept, but it's actually one of the most significant reasons why programs built with Haskell are so reliable and secure.
In fact, typeclass errors and associated bugs frequently cause software programs to crash when they're written in other languages because the compilers and interpreters for those other languages often allow disparate data types to interact with one another, which can cause unexpected results. For example, if a function passes a string type (e.g., "four") to another function, but the receiving function is expecting an integer type (e.g., 4), the receiving function will choke because it doesn't know what "four" actually means. This type of scenario causes many programs to crash, but Haskell completely prevents these crashes by catching type errors or intelligently inferring typeclass membership for a given value before a program is even deployed to a live environment.
Recursion is used often. This creates more powerful and efficient functions with less code, but nested recursive functions can be confusing to Haskell newbies because the code tends to be more abstract than code in imperative languages.
Code abstraction is a byproduct of Haskell's extremely intelligent compiler. The Haskell compiler intuits many actions and contextual factors that reduce the total code required to produce a given program behavior by up to 70% (or even more if function composition is used). This is one of the primary reasons why the Haskell-based Web server ("Warp") can be written in less than 1,000 lines of code while the Apache Web Server requires about 1.5 million lines of code. And Warp is over 100x faster than Apache and much less vulnerable to many bugs and security hacks. (Of course, all benchmarks depend on how each system is configured, but in general, Warp's per-CPU HTTP request processing is at least two orders of magnitude faster than a similarly powered server running Apache without any load-balancing and caching techniques.)
Haskell has no "for" or "while" loops or "variables" in the common sense, but it does have constants and very powerful recursion and pattern-matching features. These replace the need for for/while loops and mutable variables. In fact, recursion and pattern-matching are much more efficient tools to accomplish the same tasks, which is why the Haskell programming language does not include for/while loops.
Haskell is lazy. Being lazy is not always a virtue, but in this case, it means that Haskell always consumes the least amount of resources (CPU, memory, and thus, electricity) possible. Specifically, Haskell doesn't force a computer to execute more CPU cycles or consume more memory than is needed at the moment of each function's execution. For example, in Haskell we can define an infinite list of data objects at any time, but a Haskell program will not traverse the entire list because that would quickly consume all system resources and cause it to crash. Instead, a Haskell function will only traverse an infinite list until it finds the value it's looking for based on the efficient pattern-matching functions that Haskell provides. (See note 4 for a special exception to Haskell's laziness.)
In Summary: Haskell's approach to system resource management and its intelligent typeclass system alone eliminate many (50-70%) of all the bugs and security vulnerabilities that typically plague code written in other programming languages. Haskell's virtuous lazy processing prevents many stack and heap buffer overflows and corresponding system crashes caused by unintended infinite loops, which are often caused by poorly designed code in non-functional programming languages. Haskell's succinct syntax and well-organized functional design philosophy enforce good coding habits, which also eliminates many bugs.
Haskell provides many other benefits, but the benefits listed above are several of the most significant reasons why we chose to build Gini's systems with Haskell. To learn a lot more about Haskell, visit the Haskell Language page.
2. Some open source software libraries that are integrated into Gini's systems (including certain well-known cryptography packages like the Blake2 hashing function and the Argon2 key derivation function) are written in C, C++, and Java and we occasionally need to build interfaces between them and our Haskell components. However, we strive to use Haskell for as many Gini components as possible; and over time, we will replace non-Haskell open source libraries with Haskell-based open source libraries and/or our own Haskell-based components whenever we believe it would make our systems more secure and reliable.
4. There are two exceptions to the lazy feature in Haskell: Strict Bytestrings and Lazy Bytestrings. Strict Bytestrings represent data as 8-bit (1-byte) data chunks that are not lazy, but they're used in special cases where large data files must be processed more efficiently than the typical lazy processing. In contrast, Lazy Bytestrings represent data as 64K-byte data chunks, the first of which is processed immediately like Strict Bytestrings, but all subsequent 64K-byte data chunks within a given file (or data stream) are processed lazily, i.e., processing is deferred until the data is actually needed for a given function.
Gini is doing very important work that no other organization is willing or able to do. Please support us by joining the Gini Newsletter below to be alerted about important Gini news and events and follow Gini on Twitter.