Introducing Stat. A Higher Level Programming Language
Discover a new era of programming with Stat, designed to empower developers with unparalleled simplicity and efficiency. Dive into a world where coding is intuitive, fast, and cross-platform, all while maintaining type safety and minimizing bugs.
Works on Linux
Works on Mac
Works on Windows
Simple, easy to learn syntax
The Stat Programming Language offers a syntax that is both simple and easy to learn. The syntax prioritizes readability and simplicity ensuring that your code is not only easy to write, but also easy to understand and maintain.
// The "Hello World" program for Stat MAIN let out = open console "Hello World" -> out
Works in Your Favorite Code Editor
Stat includes a built-in language server that seamlessly integrates with a wide range of IDEs and code editors. Enjoy real-time feedback, intelligent code completion, error detection, syntax highlighting, and more across platforms and editors.
And more soon to come…
If your IDE supports the Language Server Protocol we are probably working on a plugin for it
Native support for enhanced JSX syntax
If you’ve ever worked with React, then you’ll know what JSX Syntax is. JSX lets you write HTML-like markup inside your source code files. While other languages like JavaScript allow JSX syntax, they don’t support it natively. This means you must transpile your code before running it. With Stat, you can write JSX and run it as is. Plus, we’ve enhanced it so there are some things that you can do in Stat that you can’t do in normal JSX for JavaScript.
// JSX syntax example IMPORTS a img MAIN let result = <a href="index.html"> <img src="image.jpg" /> </a>
Modern Number System and Fractional Math Engine
Goodbye floating point math
Say goodbye to precision loss, rounding errors, and issues with comparisons and equality tests. Math always works the way you’d expect it to.
// Math examples MAIN // This equals 0.3, exactly let result = 0.1 + 0.2 // This equals one third // exactly, not 0.333333... result = 1 / 3 // You can even use fraction literals // This equals one and four ninths result = 1 1/3 + 1/9
Goodbye number limits
The number system isn’t limited to 64 bits like other languages. It works with any number no matter how large (As long as it fits into memory)
// Number examples MAIN // Support for really large numbers let result = 1000000000000000000000 // This equals 5000000000000000000000 // exactly, no loss of precision result *= 5 // You can even use fraction literals // with really large numbers let largeFraction = result + 1 1/3
Type Safe with native type support
Stat is a strongly typed programming language that is type safe and has native support for type syntax. Unlike TypeScript where you need to compile to remove type hints, Stat runs as is without any need to compile.
Wide range of built in types
- string
- binary
- int
- fraction
- bool
- regExp
- range
- enum
- any
- empty
- alias
- [list]
- {struct}
- <stream>
// Native data types MAIN // A string type hint let greeting: string = "Hello" // An optional string let maybeName: string? = "Joe" // A list of strings let stringList: [string] = ["Hello", "World"] // A struct (object) with 2 keys let person: {name: string, age: int} = { name = "John", age = 25 } // Every variable has a type, which // means it can be used in type hints let jane: person = { name = "Jane", age = 22 } let people: [person] = [person, jane]
Stat Translates to your 2nd favorite language
Stat source files can easily be translated to many popular programming languages without any loss of functionality and with the exact same behavior across languages. This means that you can write once in Stat, test once in Stat, and convert to multiple other languages knowing that it’ll behave exactly the same every time.
JavaScript
Python
PHP
Java
Swift
$ Stat --action translateToJs --file path/to/file.stat
All values are immutable
Since all values are immutable, you no longer need to worry that the value will change. If you pass a value to a function, that value will be the same value that was passed in when the function returns. This guarantees that there are no race conditions, side effects, or unpredictable behavior. Once a value is created, it never changes.
- You can still reassign variables
- You can still add and subtract
- You can still multiply and divide
- You can add objects to create new ones
- You can add lists to create new ones
- You can add strings to create new ones
MAIN // Once a value is created, it never changes let jane = {name = "Jane", age = 22} // This is a syntax error jane.age = 26Invalid Operator // To change a property, you must create // a new value with the modified property let olderJane = jane + {age = 26} // You can reassign variables, but // you can't change the underlying value olderJane = jane // Now olderJane and jane point to the // same underlying value olderJane += {age = 26} // jane.age is still 22 // while olderJane.age is 26
Equal means equal
The equality operator works the way you’d expect it to. Two values are equal if they are the same type and same value. And it works recursively through data structures.
MAIN let person1 = { name = "Jack", age = 22 aliases = ["Jack", "Jim"] } let person2 = { age = 22 aliases = ["Jack", "Jim"], name = "Jack" } // This will be true even though // they are 2 different objects. // The == operator compares values recursively let isEqual = person1 == person2 // This will be false. The === operator // makes sure 2 objects are the same instance isEqual = person1 === person2
Convert at will
Converting between two value types is easy and straight forward. No need to call complex conversion functions or walk through data structures.
// Converting values is easy MAIN // age is an integer let age = 22 // To convert age to a string // Use the "to" operator let ageString = age to: string // To convert it back to an integer // you have to convert it to an optional // because a string may not contain a number let maybeAge = ageString to: int? // You can even convert collections // like lists, dictionaries, and structs // to other types recursively let numbers = [3, 102, -5] let strings = numbers to: [string] let maybeNumbers = strings to: [int?]
Flexible function calls
No matter how you want to call your functions, Stat understands what you mean. Whether you want to call functions normally, in object oriented style, or in JSX style, Stat has you covered.
- Call functions normally
- Call functions in object oriented style
- Chain object oriented function calls
- Use JSX style function calls
- Even nest JSX and non JSX function calls
IMPORTS createPerson scramble MAIN // Function arguments are always named let john = createPerson(name = "John", age = 25) // And they can be passed in any order let jane = createPerson(age = 22, name = "Jane") // Functions can be called in object oriented style let scrambled = jane.name.scramble() // Or they can be called in JSX style scrambled = <scramble value=jane.name /> // This is the same as the last 2 statements scrambled = scramble(value = jane.name) // Some other ways to create jane same as above jane = "Jane".createPerson(age = 22) jane = 22.createPerson(name = "Jane") jane = <createPerson name="Jane" age=22 /> // You can also pass the return value of one // function to an argument of another function // by chaining function calls like so scrambled = jane.name.scramble().scramble()
Strings are now powerful
Finally a language with the flexibility to handle complex interpolations including function calls, value conversions, and even nested strings with their own interpolations.
- Strings can be multi-line
- Strings support complex interpolation
- Call functions inside interpolations
- Do value conversions inside interpolations
- You can even nest interpolations
IMPORTS div MAIN // Strings can be multi-line, and they // still maintain correct indentation let stringValue = "Line 1 Line 2 Line 3" // This results in the same string as above stringValue = "Line 1\nLine 2\nLine 3" // Interpolate values into strings using \{} let string2 = "Prefix \{stringValue} Suffix" // You can even call functions in your interpolations // And you can make complex and even nested interpolations let complex = "Prefix \{div(id = "child\{1 to: string}")} Suffix"
Built-in Debugging Engine
Stat comes with a built-in debugging engine that supports the Debug Adapter Protocol with full support for stepping in, over, and out of functions, conditional breakpoints, and fully inspecting values and types.
All I/O is handled via streams
Input and output is handled via streams using a simple syntax instead of built in functions. Streams are much more powerful than what is shown in the example here. They can have custom input and output types which allow you to send not just strings to a stream, but objects, data structures, functions, and more.
There is also a plugin system that allows custom streams to be created which simplifies everything. This allows us to extend the language to communicate with pretty much anything all by using the simple streams syntax.
- Stream syntax is simple yet powerful
- Send custom data structures to streams
- Read custom data structures from streams
- Plugin system to create custom streams
// Streams example MAIN // The open operator opens a stream let terminal = open console // Use the -> operator to write a stream "Hello World\n" -> terminal // Or use the <- operator if you want // to put the stream first terminal <- "Hello Again\n" // To read from a stream, use the <- operator let response = <- terminal // The close operator closes a stream close terminal // An example of writing to a file let fileStream = open file path/to/file.txt "Contents" -> fileStream close fileStream
Built-in code coverage reporting
No need to instrument your files or install additional software. Code coverage is built in.$ Stat path/to/file.stat --coverage
{ "file": { "execution": [ { "type": "variableDefinition", "indent": 1, "startPos": 123, "endPos": 141, "count": 3 } ], "branches": [ { "type": "comparisonExpression", "indent": 1, "startPos": 261, "endPos": 282, "trueCount": 1, "falseCount": 2 } ] } }
A ton more features
But wait, there’s more. Stat has even more awesome features for developers.
Built-in code linter
The Stat code linter automatically finds potential bugs as you code and reports them in real time to your IDE using the Language Server Protocol. Embrace a smoother development process with fewer bugs and focus on what truly matters — Building great software.
No crashes
Stat is designed to ensure that crashes are a thing of the past. By preventing you from executing any code that could potentially fail, it guarantees a smooth experience. The robust type safety system and integrated code linter both safeguard your work and help you code with confidence.
No built-in functions
Stat has no built-in functions which means no bloat. There is a foundation package which includes functions like toLowerCase, toUpperCase, trim, split, indexOf, sort
etc… you know, all the functions that other languages have built in. The difference is that these are open source, coded in Stat, and you could easily code your own functions with similar functionality and use those instead.
Robust event handling system
Stat has a powerful event handling system that allows developers to hook into functions and change input argument values as well as return values.
Functions can opt into or out of event handling as required.
- Handle function enter events
- Handle function exit events
- Use
continue
to exit from a handler early - Use
final
to unhook a handler - Use
break
to exit and unhook a handler
IMPORTS createPerson MAIN // Use the "on" operator to hook a function let hook = on enter createPerson // Do something // Use the "off" operator to unhook a function off hook // You have access to arguments and can modify them on enter createPerson args (name, age) name += " Doe" age += 1 // Use "break" within the handler to unhook // Once break is called, this handler will no longer run break // You even have access to the return value on exit createPerson return person // Use "final" within the handler to unhook // however, the handler will continue to run final // Use "continue" to stop execution of the handler // but without unhooking it if person.age < 21 continue // Simply modify the return value to // change what is returned to the caller person += {age = 30}
Automatic Multi-Threading
Stat can run multiple threads at the same time automatically without any additional coding required to manage threads. How you ask? It can do this because all values are immutable which eliminates race conditions and unpredictable behavior that’s typically associated with multi-threading.
- Multiple function calls run at the same time
- No additional coding required
- No complex thread handling logic
- Ability to wait for functions to return
- Functions can opt into or out of multi-threading
IMPORTS doSomething MAIN // These 2 statements run at the same time let result = doSomething() let result2 = doSomething() // This statement also runs at the same time // as the 2 above. But we can wait for it let result3 = await doSomething() // This wont't run until the first 3 calls finish let result4 = doSomething()
Stat is Currently in Private Beta
We’re still working on some of the final touches of Stat. Most of the hard work is completed, but there are still features to add, IDE plugins to finalize, and bugs to fix… we’re almost there. That being said, if you’re a proficient coder and would like to take Stat for a test drive, we’d like to invite you to apply for the private beta program in exchange for your feedback.