Stabel: A pure, concatenative and statically typed programming language
fossils.stabel-lang.org
fossils.stabel-lang.org
Concatenative programming is interesting in that the arguments, in and out, are implicit because they typically reside on some form of stack or as objects on a stack. (implementation details)
It might sound useless but one benefit is it simplifies factoring code greatly. If you see a common phrase in your code repeated many times, you can just cut it, paste it into a new definition, replace all the instances of the common phrase with the new definition and everything still works as before.
This is a profound distillation of the essence of Forth. You can stop repeating yourself without the need to work out all the parameters, variables, return values, etc.
My experience is that when it doesn't work, it might indicate that the code is fighting with how Forth is easiest to use.
I try to use Forth per Chuck Moore's philosophy and use many small definitions. This makes the code more like functional programming such that even data is handled by code snippets. When I get this right, factoring becomes trivial.
Experienced Forth users seldom have that particular argument count problem but all the other mistakes in programming are on the table. There is no free lunch.
The Forth coding process involves using interactive testing of your code as you write it. Every variable, constant, data-structure and sub-routine can be easily verified at the interpreter. And... given what you said it is advisable to do it. :)
ANS Forth supports local variables for those times when "stackrobatics" might make you crazy.
Although small, the Forth community has made good progress in this alternative way to code. Some of the newer concatenitive languages working with a clean slate have gone farther in improving the programmer interface. Forth remains at its core close to the metal.
Is a 1.2 million LOC large enough? https://ribccs.com/solutions/solution-candy Written in MPE VFX Forth, native code compiler for Windows.
*I have no connection to MPE UK but have used their cross-compilers in the past.
I would say that the most interesting thing you should know about them is that practically everything they do is manipulating a stack (actually, there are usually two stacks, I don't know if this is the case for Stabel).
What I find more interesting about them is their simplicity (comparable only to Lisp), which makes possible writing a basic interpreter in only a few lines of code. Being more concrete, an important property of concatenative languages is that they allow a point-free programming style, which gets a bit to get used to but really makes you think in a different way.
If you already feel curious, I would suggest the book "Starting FORTH" before looking into more modern (and practical) alternatives.
For example, the definition of a cube function, and using it, in forth
: cube dup dup * * ;
3 cube .
27def: main : 3 cube
def: cube
type: Int -- Int
: dup dup * *Not sure. Ad-hoc polymorphism is currently in the design-phase and I'm looking at many possible solutions. But before I get to that point I still have a lot of stuff to implement first.
Stabel allows you to define structs and unions, which gives you a lot of flexibility.
I just like to minimize exceptions to rules and this seems a weird one to me. But probably has reasons I am unaware of (besides subjective readability which is, of course a very good reason).
[0] https://gist.github.com/tluyben/16ee2645c4c8aed813005d51488d...
[ dup + ] \ writes a lambda function to heap and push ptr
: double ; \ : writes the next symbol as a string to heap and push ptr
\ ; is define, writes definition into dict
The reason Forth did it the classic Forth way originally, I suspect, is because Forth's parser needs to be told to switch modes. Stop executing words directly and start compiling them. There isn't really anywhere to store a temporary string, so you need to tell it to start writing into the dictionary entry before you give it the string. In my language, using [ ] for quotations starts writing to the heap, which is also where strings go. This has the same practical effect.The stdlib will get more datastructures (Array, Dict, Set, Result, Triple...), some basic side effects (randomness, time) and functions to map to wasm intrinsics like bit-shift and math operations.
My aim is to keep the stdlib relatively small and portable between wasi and browser environments.
I'm a minimalist, I'm not fond of languages that grow and grow and grow with features. So my goal is to create the smallest language that is still flexible enough to solve most of my day-to-day problems (I use Elm and Kotlin for work), and a language which is easy to reason about.
For more on how Elm inspired Stabel, read this: https://fossils.stabel-lang.org/compiler/wiki?name=How+Elm+i...
Note: It's Stabel, not Stable. Stabel is norwegian and means stack.
Also, what "ring of complexity" does Stabel's type system live in, i.e. does it support rank-n polymorphism?
Kitten allows infix operators, from what I've seen, which IMHO reduces one of the benefits of the Forth-like syntax: factorability. It also has custom syntax for if's and matches. Stabel is more minimal in this sense.
Stabel also has unions, instead of ADTs. This means, among other things, that you don't need to wrap a `String` into `Just String`, you can just use `String` directly on any function that takes in a `Maybe String`. This let's you change how a function works without breaking call-sites (`String` -> `Maybe String` isn't necessarily breaking) and performance is better since you need less boxing. Type inference takes a hit, though. The list `[ 1, "two", 3.0 ]` is suddenly valid as the type is inferred to be a union of Int, String and Float.
rank-n polymorphism is not implemented. Might come later. Currently the focus is to get Stabel to the point where it can solve the same set of problems as Elm and once I reach that point I'll start looking at fancier things.
Have you seen http://conal.net/papers/compiling-to-categories/ ?
(Also s/mayor/major/ )
For me as a working programmer: What would you say is the main benefit of Stable, how does it relate to the above mentioned languages?
Are there specific use-cases for the language that you think are exceptional?
What is the general mindset that a Stable user has, what is important to you and what isn't?
[0] https://en.wikipedia.org/wiki/Joy_(programming_language)
I'm kinda hoping that Stabel will fill the same niche as Elm, but also be able to run outside the browser so you can use the same benefits for other things than just making SPAs.
If you are a little aquinted with Elm, you can read this article about how Elm inspired Stabel: https://fossils.stabel-lang.org/compiler/wiki?name=How+Elm+i...
I think that the WebAssembly world needs more programming languages that produce short byte code to be useful in browsers (and that's why I thing Go with its stdlib is not an appropriate source language for the browser environment). Do you think that Stabel could fit that area?
Stabel is also aimed at backends and CLI tools.
v0.2.0-alpha released. Module support has landed.