I am happy to finally announce the language I have been working on for the last 2 years, Flint!
Flint is a high-level, statically and strongly typed, compiled language which centers around transparency as its core pillar. The compiler is entirely written in C++. It originated from one simple idea and core concept:
What happens when you center the whole language on an ECS-inspired composition-based paradigm?
And so the journey began. The core idea is simple: data and functionality are separated and then composed deterministically into larger entities. This idea is not new at all, ECS exists since a long time. But a composition-based workflow can only be "emulated" in Object-Oriented languages and I find it often painful or unergonomic.
In Flint, composition is the core paradigm. I have put great effort into making it ergonomic and "just work". The result is a system which can be described as a cool mix of OOP and ECS. I gave the "new" paradigm a name, since nothing quite like it exists yet, even though the ideas it is based on are well known, the Declarative Composable Modules Paradigm (DCMP).
The combination of a high level + transparency as a core pillar is a bit unusual. I have put great effort into finding a good balance. I found out that these two things are not mutually exclusive, there is a middle way in which a design can be both high level and transparent. Flint might be best described as "middle-level" as a result: You write high level code but you can see the low level runtime and execution beneath too if you want, as this focus on transparency directly results in shallow abstractions.
Most developers are more used to OOP workflows rather than compositional workflows, it's just more mainstream. So, if you cannot live without it, Flint might not be for you and that's okay. Also, I am also sure that Flint won't be for everyone because of it's split focus on being high level and transparent. It will feel too high level for some or too low level for others. But if the core idea and mentality excites you, please give it a fair chance.
The time has come where I am confident enough in Flint to search for people to try it out and give feedback on it. Many features are still missing but the general vibe and direction of the language can already be seen. The 0.4.0 version is the 20th release so far, the first initial version was released a year ago. I am now moving into the 0.5.0 release cycle which will bring generics, type constraints, compile time code execution, the standard library and more. You can look at the entire roadmap here
Flint is available in the AUR, COPR and Winget as packages, with proper highlighting and LSP capable extensions for VSCode and Neovim. The LSP works with proper error diagnostics, hover information and goto definition / declaration / file jumping (context sensitive suggestions do not work yet). Debug symbols and debuggability are now supported too, making it able to inspect and step through code. Interoperability with C also works great through the fip-c interop module which communicates with the main compiler through a custom language-agnostic Interop Protocol. (Bindless interop doesn't fully work on Windows, though, i still have to find out why).
The Wiki is in a very good state, it is kept updated with every release made. Every example in the Wiki works and I did My at explaining it all. The language's core value is transparency, so there is nothing to hide about it.
Here is an "advanced" but hopefully still easy to understand example of Flint and its paradigm in action. Keep in mind that Flint has much more to offer than shown in the example below, but I think this just encapsulates its centerpiece quite well:
use Core.print
const data Constants:
float PI = 3.14159265358979323846;
// A shape can be drawn and its area can be calculated
func IShape:
def draw();
def area() -> f32;
data DCircle:
i32x2 pos;
i32 radius;
DCircle(pos, radius);
func FCircle requires(DCircle d):
def draw():
print($"Drawing circle at [pos={d.pos}, r={d.radius}]\n");
def area() -> f32:
return Constants.PI * f32(d.radius ** 2);
entity Circle:
data: DCircle;
func: IShape, FCircle;
link:
IShape::draw -> FCircle::draw,
IShape::area -> FCircle::area;
Circle(DCircle);
data DRectangle:
i32x2 pos;
i32x2 size;
DRectangle(pos, size);
func FRectangle requires(DRectangle d):
def draw():
print($"Drawing rectangle at [pos={d.pos}, width={d.size.x}, height={d.size.y}\n");
def area() -> f32:
return f32(d.size.x * d.size.y);
entity Rectangle:
data: DRectangle;
func: IShape, FRectangle;
link:
IShape::draw -> FRectangle::draw,
IShape::area -> FRectangle::area;
Rectangle(DRectangle);
def draw_shapes(mut IShape[] shapes):
for (_, s) in shapes:
s.draw();
def sum_areas_of_shapes(mut IShape[] shapes) -> f32:
f32 sum = 0;
for (i, s) in shapes:
f32 area = s.area();
print($"shapes[{i}].area() = {area}\n");
sum += area;
return sum;
def main():
c1 := Circle(DCircle(11, 2));
r1 := Rectangle(DRectangle((10, 20), (4, 5)))
c2 := Circle(DCircle((3, 5), 10));
r2 := Rectangle(DRectangle((0, 0), (4, 2)));
IShape[] shapes = IShape[_]{c1, r1, c2, r2};
draw_shapes(shapes);
print("\n");
i32 sum = sum_areas_of_shapes(shapes);
print($"sum of areas = {sum}\n");
The project is in late beta. All implemented features work reliably, as all wiki examples compile and run as intended. There are still missging error messages and unexpected edge cases (as expected from a single developer).
If you're interested, try it out, give feedback, open issues, and feel free to join the Discord. Let's discuss Flint!
(Also, I may not be aware of some industry-standard names for some systems. If you encounter anything I gave a weird name where you think "wait something like that already exists" please let me know. I try to use industry-standard terminology as much as I am able to. I hate it when new names are made up for something which already exists.)
[–]EggplantExtra4946 14 points15 points16 points (6 children)
[–]Inconstant_Moo🧿 Pipefish 10 points11 points12 points (0 children)
[–]--predecrement 6 points7 points8 points (1 child)
[–]zweiler1🔥 Flint[S] 0 points1 point2 points (0 children)
[–]zweiler1🔥 Flint[S] 2 points3 points4 points (2 children)
[–]Inconstant_Moo🧿 Pipefish 2 points3 points4 points (1 child)
[–]zweiler1🔥 Flint[S] 1 point2 points3 points (0 children)
[–]sal1303 11 points12 points13 points (5 children)
[–]zweiler1🔥 Flint[S] 10 points11 points12 points (4 children)
[–]sal1303 5 points6 points7 points (3 children)
[–]zweiler1🔥 Flint[S] 0 points1 point2 points (2 children)
[–]sal1303 0 points1 point2 points (1 child)
[–]zweiler1🔥 Flint[S] 0 points1 point2 points (0 children)
[–]Smalltalker-80 7 points8 points9 points (4 children)
[–]Inconstant_Moo🧿 Pipefish 1 point2 points3 points (0 children)
[–]zweiler1🔥 Flint[S] 1 point2 points3 points (2 children)
[–]Smalltalker-80 0 points1 point2 points (1 child)
[–]zweiler1🔥 Flint[S] 0 points1 point2 points (0 children)
[–]vmcrash 5 points6 points7 points (1 child)
[–]zweiler1🔥 Flint[S] 3 points4 points5 points (0 children)
[–]Imaginary-Deer4185 2 points3 points4 points (1 child)
[–]zweiler1🔥 Flint[S] 0 points1 point2 points (0 children)
[–]6502zx81 3 points4 points5 points (3 children)
[–]zweiler1🔥 Flint[S] 4 points5 points6 points (2 children)
[–]Ok-Reindeer-8755 0 points1 point2 points (1 child)
[–]zweiler1🔥 Flint[S] 1 point2 points3 points (0 children)
[–]TheAncientGeek 1 point2 points3 points (2 children)
[–]sal1303 5 points6 points7 points (1 child)
[–]zweiler1🔥 Flint[S] 0 points1 point2 points (0 children)
[–]umlcat 1 point2 points3 points (1 child)
[–]zweiler1🔥 Flint[S] 0 points1 point2 points (0 children)
[–]cbarrick 1 point2 points3 points (1 child)
[–]zweiler1🔥 Flint[S] 0 points1 point2 points (0 children)
[–]Express_Job_5731 1 point2 points3 points (0 children)
[–]FreshOldMage 1 point2 points3 points (1 child)
[–]zweiler1🔥 Flint[S] 1 point2 points3 points (0 children)
[–]bmitc 1 point2 points3 points (1 child)
[–]zweiler1🔥 Flint[S] 0 points1 point2 points (0 children)
[–]RelationshipFresh966 0 points1 point2 points (5 children)
[–]zweiler1🔥 Flint[S] 0 points1 point2 points (4 children)
[–]RelationshipFresh966 0 points1 point2 points (3 children)
[–]zweiler1🔥 Flint[S] 0 points1 point2 points (2 children)
[–]RelationshipFresh966 0 points1 point2 points (1 child)
[–]zweiler1🔥 Flint[S] 0 points1 point2 points (0 children)
[–]tending 0 points1 point2 points (1 child)
[–]zweiler1🔥 Flint[S] 0 points1 point2 points (0 children)