
Kit Programming Language - BerislavLopac
https://www.kitlang.org/
======
forgotpwd16
>designed with game development in mind

What design decision and features were made according to that? Basically, what
"designed for game development" means?

Also checking the commit history, first commit [1] says that it is after a
rewrite in Haskell. What was the original language and why made the change?

[1]:
[https://github.com/kitlang/kit/commit/4d3de98f218f2427529ac4...](https://github.com/kitlang/kit/commit/4d3de98f218f2427529ac4af098d8398434ebbef)

~~~
bendmorris
Hi, creator here.

>Basically, what "designed for game development" means?

I've been doing a lot of work in Haxe, but have struggled with performance
issues due to GC and memory churn. I wanted a lower level language with more
control, but without sacrificing the ergonomics and abstractions I'm used to.
Term rewriting and implicits are examples of features that let me layer
abstractions onto a language but still maintain complete control.

>What was the original language and why made the change?

It's not up on GitHub, but the prototype was begun in Rust. Ultimately I found
I'm much more productive in Haskell and made the switch.

------
annywhey
This looks like it takes influences variously from Haxe, Rust, and Haskell,
which are all great in my book. But the first thing that crossed my mind was,
"could it compile to other languages besides C?"

The reason being that I think the way to really move up the baseline is to
take another page from Haxe and aim for cross-compatibility between different
systems languages, becoming a "language that unites them all". So that could
mean relatively new and hip ones like Rust, D or Zig, or older ones like
Pascal(Delphi), Fortran, Cobol...

And those are niches relative to C, but they're nearly unserved niches AFAIK.

~~~
flohofwoe
AFAIK languages "compile to C" mainly because they use C as an intermediate
representation and the C compiler as the last stage of the compile/link
process, so kitlang itself doesn't need to support code generation for various
CPUs, and also doesn't need to implement an LLVM frontend. Instead it uses the
target platform's C compiler, which is a lot less work but has basically no
downsides.

Also the C IR code might make it easier to interop with other languages, since
C is basically the 'lingua franca' that all other languages can talk to in
some form.

~~~
kibwen
_> Instead it uses the target platform's C compiler, which is a lot less work
but has basically no downsides._

The downsides of leveraging a platform's given C compiler as your backend is
that now you'll be spending a large chunk of time learning the hard way about
all the various incompatibilities in C compilers, and adding workarounds in
your frontend for the otherwise-unpatchable behavior encountered in every old
version of every major compiler on every platform you wish to support.

Conversely, the advantage of using a single known backend is that you can
automatically know what code your users are running when they submit a bug
report, and you can fork and ship the patch yourself rather than trying to
convince an upstream C compiler to accept the patch, then convince the
upstream distro to ship the new version of the compiler, then convincing all
your users to update their platform C compiler.

Walter Bright concurs:
[https://news.ycombinator.com/item?id=16195031](https://news.ycombinator.com/item?id=16195031)

Kit may have an easier time of it if it's intended only for games, since that
narrows down its supported target platforms substantially. The harsh truth is
that most game devs only care about one platform (Windows) and one toolchain
(MSVC), so at least it can tailor its output to appease MSVC specifically.

~~~
rurban
No, I'm targetting C89 (because of msvc) and there almost no platform quirks
than some line length limit on msvc. c99 would be nicer of course.

------
xtrapolate
> "Memory management in Kit is manual (no automatic garbage collection), with
> some convenience features to make this easier."

I was curious, but there aren't any examples of this on
[https://www.kitlang.org/examples.html](https://www.kitlang.org/examples.html)

------
rishav_sharan
I am far more interested in the comparison between kit and Zig.

~~~
bendmorris
I'm planning to get a more detailed comparison with languages in the same
space. Kit and Zig overlap quite a bit; the main difference I see is
philosophical. A major goal in Kit is to be concise, expressive and eliminate
boilerplate; Zig perfers to be straightforward and readable, where a function
call at runtime always looks like a function call in your code. Term rewriting
and implicits are examples of features in Kit that probably wouldn't be
implemented in Zig. Also, Zig aims to replace and compete with C, Kit just
wants to leverage it, so the scopes are quite different.

Zig is awesome - I've used it and would use it again, I'm funding the creator
on Patreon, and I see these two languages as filling slightly different niches
and having different pros and cons.

~~~
danbolt
Jai is another popular one that originally compiled to C and is aimed at game
development. Any thoughts on that?

EDIT: Your responses in these threads have been great, by the way!

~~~
zem
it's a bit of an overstatement to call jai popular, seeing as how it hasn't
benen released yet. but yes, it's a very interesting looking language, and the
development notes are great.

------
openbasic
I like how clean the lexer is:
[https://github.com/kitlang/kit/blob/master/src/Kit/Parser/Le...](https://github.com/kitlang/kit/blob/master/src/Kit/Parser/Lexer.x)

------
ndh2
Ben, could you go a little into detail on what you had in mind with the term
rewriting system? The sin/cos example seems a little underwhelming, since
these should be evaluated at compile-time in the first place.

They seem like a variant on C macros, but without the restriction on function
syntax. Maybe one could implement Python's with statement in userland, which
is very nice.

It also seems to me that you could replace C++ templates, yet you do have
generics. How come? What's the difference?

My intuition is that ambiguities are at least possible, so what about
precedence, which AST term is evaluated first? I'm thinking of some situation
where two subtrees match the rule, but you end up with different results
depending on which is transformed first. E. g. if you were to define a cross
product rule, and apply it to a × b × c.

What about infinite loops in rule sets? What about recursion?

What about a situation where multiple rules could be applied? Is there any way
to debug the transformations? Is that what the `using` scopes are for? If the
compiler was to detect ambiguities, that seems pretty expensive, because it
would need to match every rule to every subtree, right?

This thing seems very, very powerful, I just find it a bit hard to grasp what
you can do with it in practice, and what the limitations are. I would be very
interested to hear what you ran into so far.

~~~
bendmorris
I think this thread captures a more interesting application of term rewriting:
[https://twitter.com/bendmorris/status/1041130408463687681](https://twitter.com/bendmorris/status/1041130408463687681)

>My intuition is that ambiguities are at least possible, so what about
precedence, which AST term is evaluated first? I'm thinking of some situation
where two subtrees match the rule, but you end up with different results
depending on which is transformed first. E. g. if you were to define a cross
product rule, and apply it to a × b × c.

This is absolutely a potential issue, and the examples I have up now are quite
bad. This is why it's important for rules to be strictly scoped. The only
rules that can affect an expression are the ones you've explicitly brought in
with a "using" block, or those that are defined for the types you're directly
working with. Given the scoping, I think overlapping rule applications will be
uncommon in practice.

>What about infinite loops in rule sets? What about recursion?

There's a sanity limit on the number of times an expression can be rewritten,
and it'll show an error in that case which displays the transformations that
triggered the limit (including the first, last, and any non-repeating
transformations going backward from the last - so it should be very clear.)

>Is there any way to debug the transformations?

This is definitely an area for improvement. I'm planning to (1) add enforced
"rewrite this" metadata that will fail to compile if the expression isn't
rewritten, and (2) enable dumping not only the final AST but also all of the
transformations that occurred.

~~~
forgotpwd16
It seems you've independently rediscovered extensible programming which had
seen much research in the past and again a few years back. There have been a
number of languages that did same thing as in your tweet (e.g. [1]) but most
aren't developed anymore.

[1]:
[http://seed7.sourceforge.net/examples/declstat.htm](http://seed7.sourceforge.net/examples/declstat.htm)

~~~
ndh2
Neat, another one for my list. Seed7 allows the extension of the grammar [1].
The compiler understands a simple EBNF which doesn't distinguish between
different non-terminals. The semantic checks and the transformation into a
known AST are deferred to another stage.

[1]:
[http://seed7.sourceforge.net/manual/syntax.htm](http://seed7.sourceforge.net/manual/syntax.htm)

------
rafaelvasco
Well designed language! I particularly like that you took great features from
Haxe such as Abstracts. So far i didn't see any WTF!?'s in the language
syntax, which is rare these days. People these days can get too inventive when
designing new languages. I like that you kept things readable (looking at you
Rust :) . Nice work!

------
CyberDildonics
How is this better than Clay, other than the fact it is being maintained?

[http://claylabs.com/clay/](http://claylabs.com/clay/)

[https://github.com/jckarter/clay/wiki/Avoiding-generic-
progr...](https://github.com/jckarter/clay/wiki/Avoiding-generic-programming-
pitfalls)

------
dvfjsdhgfv
Anyone is actually using it? If so, could you compare it to Nim that also
compiles to C?

------
grok2
If it is truly embeddable in a C program (there was some note about using this
as a library in a C program), then this would be a fantastic way to augment
development of software in C -- it seems to improve on the C programming
language. I like the support for generics and type inference and have always
wished C had that. The C interop story looks very good too.

------
sullyj3
This seems to be competing in a similar space to Zig, and especially Jai. How
does it compare to them?

~~~
bendmorris
I commented on Zig elsewhere in this thread. Since Jai is unreleased I don't
know a lot about it, but their AoS/SoA convertibility was an interesting
feature (you can do this in user space in Kit via term rewriting) and I wanted
to make it similarly ergonomic to pass around custom allocators.

------
cptwunderlich
Interesting language! I saw a "throw" in an example, but I don't see exeptions
mentioned anywhere? Woulb be interesting to know why a language with
performance focus has exceptions (or are they implemented differently?).

~~~
bendmorris
Good "catch" ;) "throw" in Kit is vestigial; there's no error handling
mechanism implemented yet, and I've gone back to the design phase to consider
some alternatives.

------
dvh
This is the first language posted on HN I like. Really nice. How is utf8
supported. What about graphical apps? Android? Web server? How's the
performance?

------
bitmadness
This looks amazing! Does it support parallel/multicore programming?

------
ionforce
Ben, would you cite Scala at all as a source for inspiration?

~~~
bendmorris
Certainly. I don't used Scala much but the inspiration is probably easy to
see.

------
tauk
Any examples of games that were created using Kit lang?

~~~
forgotpwd16
It seems it is a very new language, started only few months ago so probably
there is nothing created with it yet.

------
kakashi19
Kit looks interesting. But i am going to stick with Haskell.

------
CoderCV
Another programming language. God! I have no idea - what's happening to the
world?

Are people not skilled enough to propose or send commits to an existing or
alternative programming language?

There is Rust, Go, Julia, Clojure, and many other...

What is the primary reason to create a new programming language?

~~~
flohofwoe
Rust, Go, Swift, etc... are like super-tankers compared to those small
"better-C" languages. IMHO, having a number of small languages that can be
learned in an afternoon is _much_ better than yet another super-tanker
designed by huge consensus-driven committees/communities that try to do
everything for everybody.

~~~
carlmr
Rust has safety and zero-cost abstractions at it's core, they provide a by now
quite stable interface. You can't just move fast and break things. You need to
stabilize at some point or it's impossible to use it in real world projects
that are also commitments of a certain kind. And for that stability you need
some kind of consensus of what to work on and what not to do.

I think the primary value of these new toy languages is they can explore
aspects freely that can't just be explored in a more mature language.
Sometimes after a concept has proven useful a mature language might be willing
to incorporate it.

But I wouldn't use them on a serious project, because there will probably be
few libraries and maybe no long term support for it.

~~~
bendmorris
These are valid concerns, particularly stability and long term support.
Availability of libraries applies less to Kit or Zig thanks to first-class
interoperability with C. I think this is the way forward for small new
languages; you can avoid the challenge of creating an entire ecosystem for
your language, and just fit it into an existing one.

