r/ProgrammingLanguages 1d ago

Language announcement The gab programming language

Hi all!

I am a long-time lurker of this sub, and a language enthusiast. I have been working on my own programming language for several years, and I finally worked up the courage to post it.

The language is called gab. I'm heavily inspired by lua, clojure, and smalltalk.

All the code is on github here and I've built a small website for the language here.

The language design, runtime, and standard library are all entirely my own work without the use of an LLM. However, I did consult LLMs occasionally when I wanted to research certain subjects (such as the difference between c11 atomics on x86 and arm).

I'm looking for any kind of feedback on the language, its goals/ergonomics, and the website itself.

Thank you for taking a look!

40 Upvotes

38 comments sorted by

11

u/AustinVelonaut Admiran 1d ago

I initially looked at the github sources, and not finding an /examples directory look at the code in /bench. I was confused by the use of the :: glyph, finally figuring out that it was more like = or -> in other languages, rather than the usual namespace qualification or typing judgement. Finally went to the website and browsed through the documentation, but still couldn't find a quick description of what :: meant. I'd suggest putting in a directory of small examples where each unique language feature is described, perhaps in contrast to another well-known language.

5

u/Fine_Seaworthiness19 1d ago

That’s a great idea! I need to spruce up the README and clarify that more. Thanks for taking a look! It is essentially the => in js.

2

u/AustinVelonaut Admiran 1d ago

That's what I figured. Also, maybe add some more info on the organization of the src/ directory to specify the intent of the gab cgab and mod directories/files.

2

u/Fine_Seaworthiness19 1d ago

That actually *is* something I put in the sparse readme 😆

https://github.com/gab-language/cgab/blob/main/README.md#project-structure

3

u/AustinVelonaut Admiran 1d ago

Sure enough! I missed that on the first read-through (I dove into the source code too early ;-)

7

u/firiana_Control 1d ago

Your example:

ch 
:=
 Channels
.make

Fibers
.make
 () 
::

do
    ch 
<!
 "Hello"
    ch 
<!
 "world"
end

msg 
:=
 Strings
.make
(ch 
>!
, " ", ch 
>!
)

msg
.println
ch := Channels.make

Fibers.make () :: do
    ch <! "Hello"
    ch <! "world"
end

msg := Strings.make(ch >!, " ", ch >!)

msg.println

The ch >! items are sequential? what do I do if i want non-sequential access?

And you use cui
canwe see a few examples of GUI done in gab?

Thank you

2

u/Fine_Seaworthiness19 1d ago

There is a good example of GUI app here. I built a little demo wordle clone that can run as a native desktop application, or in the terminal.

If by sequential you mean "How to I put a value on a channel without blocking until someone has taken it" then the best thing to do would be to spawn a new fiber which blocks putting a value on the channel. That might look like:

Fibers.make () :: do
  ch <! value
end

You could do a similar thing when taking off a channel if you wanted.

5

u/cmontella 🤖 mech-lang 1d ago

Very cool, I like the name and the design goals of the language. I see a bit of a contradiction though, so I'm wondering if you can speak to it: you said the performance is a feature, but also the language is dynamic. How are you going to make sure it's performant, and what kind of performance targets are you aiming for? i.e is. LuaJIT level of performance good enough or are you aiming higher?

4

u/Fine_Seaworthiness19 1d ago edited 1d ago

Great point! I mostly meant that for a long time in Python and Ruby, performance was *not* a goal of the language maintainers. Recently these languages have introduced teams/projects to improve performance (YJIT, ZJIT, cpython performance team at Microsoft, etc) on *top* of the existing dynamic language. Ruby and python have dynamic features that make JIT compiling and performant interpretation difficult. I made compromises in gab's design such that performance features like a JIT, multi-threading, etc are easier.

Edit to answer your question:

If I got luajit levels of performance I would have exceeded my goals 😂

3

u/cmontella 🤖 mech-lang 1d ago

>  I made compromises in gab's design such that performance features like a JIT, multi-threading, etc are easier.

That's the interesting part to me, what kind of compromises did you make in your design?

3

u/Fine_Seaworthiness19 1d ago

The big three are:

  1. no global variables
  2. No mutable values
  3. Message sends are the only form of control flow

A specific example of how this helps:

Because all values are immutable, cyclic references among gab values are impossible. This means the garbage collector can be a very simple reference counter! I implemented a more involved one, that is parallel and buffered, but I don’t have to worry about collecting dead cycles because they can’t exist!

2

u/AustinVelonaut Admiran 1d ago

Message sends are the only form of control flow

This is also theoretically true for Smalltalk, but most (all?) implementations choose to have the compiler in-line the common versions ifTrue: ifFalse: whileTrue:, etc. for practical performance reasons. Do you intend to do any optimizations of this type?

1

u/Fine_Seaworthiness19 1d ago

I don’t have any inlining on the main branch yet. For lots of the built in types though I do have what I call primitives, which are message specializations that boil down to an instruction in the interpreter. Arithmetic operators, constructing values, channel operations, etc fall into this category.

On the jit2 branch I have an experimental JIT compiler which can do a pretty aggressive amount of inlining for that above situation. I’m still working out the kinks there however. And I may just implement a two-tier interpreter for now instead

3

u/FortuneLower7766 1d ago

I have yet to play with it, but it seems delightful.

2

u/EggplantExtra4946 1d ago

https://github.com/gab-language/cgab/blob/main/src/cgab/cgab.c

It's really curious to have a single file with 15 thousands LOCs containing the lexer, parser, data structures, bytecode compiler, interpreter and GC all in one files. Usually you would split it into as many files at minimum. It makes me think that this entire language is AI slop.

3

u/CertNZone 1d ago

AI normally follows standard practice since it's just rule of averages. If they've done something odd (I haven't looked at their code) I would sooner assume hand written

3

u/EggplantExtra4946 1d ago edited 1d ago

AI normally follows standard practice since it's just rule of averages.

That's a weak counter evidence. The size of this file is one of several reasons that makes me think it's AI generated. I think it's way too spotless, regular and tidy for a code of that size and complexity. Also it looks to me like way too much energy was spent on the optimization of the utilities rather than on the design and implementation of the language itself.

I'm looking at the jit branch and it's even more evident, looking at jit.c. The code is developped in such a breadth depth manner it's ridiculous. Almost 2000 LOCs of utility code that currently do nothing and a not single function dealing with instruction encoding. That's not how humans work, especially for complex code like that. For this kind of code you would make a basic program that can jit simple expressions and then add more stuff and utilities, depth first development.

If they've done something odd (I haven't looked at their code) I would sooner assume hand written

How convenient. And for the record that's not odd, it's inhuman. Who the fuck write 15 thousands LOCs and don't even bother to extract type definitions into a separate header file?

1

u/CertNZone 1d ago

Yeah, super fair. Obviously I should have looked at what they'd written before commenting

I personally prefer to write fewer, longer files than a series of small ones so was ready to give them the benefit of the doubt but 15,000 does sound insane for a single file. Especially given how new to making programming languages they sounded

1

u/Fine_Seaworthiness19 23h ago

Ah I think the confusion with instruction makes sense to me now. I’m working on a copy-and-patch jit compiler in that branch, so there is actually almost zero instruction encoding for me to do. I actually just have to perform some relocations, and that’s all I have to touch in the machine code. That’s where there isn’t any instruction encoding involved

3

u/Fine_Seaworthiness19 23h ago

I originally did have it broken out into multiple c source and header files. It doesn’t actually make things easier in c unfortunately, because there’s not a good module/package system. And it makes it harder to include your code in other projects.

Since I want gab to easily embed in other people’s c projects, I’ve tried to keep it to a single c file. This way people can just include the source file and not have to worry about linking at all!

This is a common approach in c. Although I do agree that cgab.c is quite big, it might make more sense to generate this file with another program, like SQLite does or something.

I’m curious as to what you think the 2000 lines of utility code that do nothing in the JIT branch are.

Also, just look at the git history! The progress of this repository has been incremental over the last several years

2

u/Fine_Seaworthiness19 1d ago

Per AutoModerator's request I hereby confirm that this project did not use an LLM as part of the development process.

1

u/david-1-1 1d ago

Big learning hurdle due to lack of familiar syntax.

1

u/manageablecactus 22h ago

This looks sick! Looking forward to reading

1

u/New-Deal7021 2h ago

i am interested but i have a question, can i join the contributors? I have some experience at creating a programming language, could help you.

1

u/Fine_Seaworthiness19 19m ago

I’ll always take some help! Testing is where I need the most help right now. I should also make a CONTRIBUTING.md, and include some good-first-issues.

0

u/Relative-Rooster-945 1d ago

it's a little bit confusing in how it seemingly tries to reinvent the wheel on many things, but overall cool project

3

u/Fine_Seaworthiness19 1d ago

I see how the syntax does that in a couple ways, especially with the unusual use of `::`. What else was confusing to you?

3

u/Relative-Rooster-945 1d ago

It's mainly the syntax, yes.

The choice of "message" to describe what I think are essentially symbols?

Messages are used as record keys, as sentinel/enum values

I'm guessing this is in the vein of Smalltalk? I'm not that familiar.

In the docs for defcase it's unclear to me whether the identifiers following message values are arguments to the blocks or part of the messages themselves.

Imports and printing as messages on strings are a bit weird.

That's probably it :)

3

u/Fine_Seaworthiness19 1d ago

This is really good feedback! The term "message" is definitely a bit overloaded and confusing. You're right in that they are used like symbols, but they are *also* used when you call methods (or as gab refers to it, send a message). Since they are the same values in the runtime, I used the same name. But it is definitely confusing. I need a more clear way to communicate this idea, and I don't have that yet

0

u/BenjiSponge 21h ago

You may be, um, interested to know that there is a far-right Christian nationalist social media platform called Gab. It's probably not absolutely critical to avoid the naming conflict, but I thought you should know.

3

u/Fine_Seaworthiness19 21h ago

Unfortunately I did the google search after I named it and did a bunch of work. It’s not too late to change the name though, I just need to think of something better

3

u/BenjiSponge 21h ago

After commenting, I've actually been reading the site. Very, very cool, and reminds me a lot of a project I've been bouncing around in my head for a long time. The name in my head is "map" because one of the biggest pieces of inspiration was the postfix .map chaining you can do in Ruby and JS, but also because maps typically have an emphasis on readability.

1

u/Fine_Seaworthiness19 21h ago

I like it! Maps are also a pure function, and gab is a functional language!

1

u/BenjiSponge 21h ago

Yes, exactly the idea although I didn't know it when I came up with the name circa 2016. I might have called it something like "bind" now, or maybe something like "forward" (I'm really into the idea of reading from left to right, which I think gab does very nicely, whereas most programming languages kind of make you jump around). I feel like there's also a message passing element that could be included here, although that's very well reflected in "gab".

Feel free to take "map" if you want it, by the way.

3

u/Inconstant_Moo 🧿 Pipefish 19h ago

It made me think of "gift of the gab". I don't think the Nazis own the word yet.

3

u/AustinVelonaut Admiran 18h ago

I thought of it as "gab" being a synonym for "smalltalk", which was cited as an inspiration for the language.

1

u/Fine_Seaworthiness19 19h ago

Appreciate it! That makes me feel better 😅

2

u/BenjiSponge 20h ago edited 20h ago

Probably last suggestion and then I'll stop spamming you: Dish. "Dish" also means to gossip, just like gab, but it also means to pass a basketball. It can also mean to "dish out" work, for example. Satellite dishes pass and receive messages. I don't see any real conflicts and it's fairly google-able. Maybe you could even call the `<!` operator the "dish" operator, and then make a satellite dish the logo (might be a small legal concern)