The Odin Programming Language

I've finally gotten fed of up of creating external metaprogramming tools to fix C/C++ and thought why not just create a new language. So for past month I've been developing a new programming language.

The language is not currently done yet but it is in heavy development.

The main goal of the language is to replace my need for C/C++ and improve my quality of life. I want the language to be:

  • Simple to read and write
  • Easy to comprehend and reason with
  • Fast
  • Low-level
  • Compiled, strongly-typed, static language
  • Metaprogramming:
    • - Ability to run any code at compile time
    • - Unified syntax between main language and metaprogramming language
    • - Built-in introspection for all types
  • Higher control of data layout and data access
  • No need for external tools such as Make/IDE

If you would like to inspect my current progress or even like to help out, here is the repository to the language so far:
Odin Git Repository

Demos

First Talk & Demo
Talk: https://youtu.be/TMCkT-uASaE?t=338
Demo: https://youtu.be/TMCkT-uASaE?t=1800
Q&A: https://youtu.be/TMCkT-uASaE?t=5749

Composition & Refactorability
https://www.youtube.com/watch?v=n1wemZfcbXM

Introspection, Modules, and Record Layout
https://www.youtube.com/watch?v=UFq8rhWhx4s

push_allocator & Minimal Dependency Building
https://www.youtube.com/watch?v=f_LGVOAMb78

Edited by Ginger Bill on
Interesting.

How does your language differ from Jai?
Interesting, I'd also be interested in your thoughts on Jai. The general notion of an 'improved C' has been occupying me a lot lately, and I hit many of the same check boxes you've mentioned with respect to features I'd like.
I like quite a lot of the ideas from Jai however there are two main problems with Jai:
  • It's not available to the public yet and there is not ETA[/
  • I'm not sure if it is what I want

Jai is starting to get quite complicated and this is worrying to me. One of the great things about C is that you can actually know everything about the language (compared to C++ which is a beast). I also like being explicit about things (which is one of the reasons I like C) and Jai is tending towards having a lot of implicit stuff (however, none of that is final and may be removed). I want to be able to read the source code and know exactly what is happening.

Jai's type system is still not very good. I would love it if it had tagged unions/variants/algebraic types/whatever as a first-class construct as this would solve some of my annoyances I have with C/C++. Also, something like slices would also solve a lot of problems.

If it turns out that Jai is actually the better option, then I will go with that option but at the moment, it isn't even an option. I want to explore for myself what I can create and to do that, I have to create my own language to do that.

Edited by Ginger Bill on
Fair points. Rust actually gets most of what I want. The only major concern I have is build times(once you've worked on a 10+mloc codebase, you worry haha), but that's being actively worked on.
What features are you currently working on, and will be working on in future, in what order?

Edited by Kyle Devir on
It looks like you are taking some of the better stuff from the Go language and ditching the rest. I like that!

From the comments, I assume you are going to use llvm to generate machine code? It looks like a good solution to wanting C without all the problems.

Are you thinking of having nested functions with return values, because that would be wonderful.

Valmar:
First I need get a base language with which I am happy with before I can then expand upon.

timothy.wright:
I think Go got a lot of thinks correct but a lot of things wrong for it to replace C/C++. Mainly garbage collection and ability to do "unsafe" things is restricted and limiting. Having written hundreds of thousands of lines of Go already, I can say for definite, I cannot replace C/C++ (in their domains).

I'm trying to use LLVM-IR and LLVM but it's a bit of a pain to get working well on Windows :P.

Nested procedures are already part of the language. They are not closures as their scope is the global scope and not the parent procedure's scope (which makes using them easier to manage). I'm thinking of adding anonymous procedures but I'm still not sure about closure and if they are actually needed.



Ginger Bill
Jai's type system is still not very good. I would love it if it had tagged unions/variants/algebraic types/whatever as a first-class construct as this would solve some of my annoyances I have with C/C++. Also, something like slices would also solve a lot of problems.


So you're saying the language is too complicated, but that the problem is it's not more complicated.

I don't think it's particularly complicated. It is *tremendously* simpler than C++, and in some dimensions is a lot simpler than C (though of course in others it is more complicated).

I think it's hard to judge how complicated some of the new stuff is (like everything since polymorphism) without actually using the language. In isolated one-hour presentations, of course things are going to go by really fast and viewers won't get all the details. But I think if one is designing a language that people may use for 10+ years of their lives, you actually want to put lots and lots of work into making things powerful enough for experts. And that often means complications -- because things that are simpler don't do as good of a job at helping you get things done as they could in as many situations as they could, and over years that costs the expert programmer a lot of time.

Of course exactly which complications to add is something that is tuned to personal taste.

I think these trade-offs don't become too clear until you have a language that is very simple and you see that it doesn't do enough for you (which is where I was, say, 1.5 years ago).


Also ... I am not sure what implicit stuff you are talking about? There is almost no implicit stuff in the language currently.

Edited by Jonathan Blow on
Let me explain this more ... by analogy with CPUs.

Clearly you want CPUs to be simple because they are a bedrock computing component. All things being equal, you want your CPU to be as simple as possible.

But it would be a bad idea to say "we should not add SIMD instructions to our CPU, because that makes the CPU more complicated!" Because you get a lot of use out of SIMD and there isn't really a way to get those same performance characteristics otherwise. There's a clear trade-off between complexity and capability.

This is why almost nobody in the real world uses Scheme to build complex software. Yes, ideologically it is very nice that you can have a super-simple language with minimal syntax. But in the real world, there are trade-offs for that, and it turns out that the value of minimal syntax is low compared to the value given by a more-complex syntax (more readability, ability to get better compiler errors just because the grammar provides more context, etc).

So ... ideally, I think it would be great if the language I am building could be as simple as C. At the same time, though, I feel that the complexity vs capability tradeoff is asking for something more complex than C. BUT, you can also optimize this tradeoff. You can get back a little bit of the complexity budget by eliminating some of the complexities that C introduces (for example, 'int' being an unknown size, or always being forced to only refer to things that were being defined earlier in the file, or the whole structure of header files versus .c files, or types being in their own weird namespace, or the weird syntax of declaring and using pointers to procedures, or all the crazy stuff you have to do if you want to be compilable on C89 or earlier, like only declaring at the start of blocks, or the weird way of declaring structs and then typedeffing them, ... or all the baggage introduced by the fact that K&R-style C, of prototyping procedures with empty argument lists, is still valid and required to work). Once you've eliminated these complexities, you have room in the budget, and can spend that complexity on features.

This is why I am also saying that the language is probably less complex than you think it is -- because you are very familiar with a lot of the complexities of C, so you don't feel them as complexities ... but those have been dumped, and replaced by other things, which you *do* feel as complexities solely because you aren't used to them.

That said, I do agree it's more complicated than C, I am just saying there's also an optical illusion involved here.


Edited by Jonathan Blow on
jon:
Thank you for your reply. I think what you have done with your language, Jai, is absolutely brilliant! I completely agree that it's "tremedously" simpler than C++ and in many aspects, simpler than C. C++ is a language which needs pruning not additions but the C++ committee (as a whole) have no idea what they are doing. I have soothed some of my pains with C/C++ with metaprogramming tools but I can only go far without having to create a new language.

If I spent a long time with Jai, I could get a better judge of its "complexity" but I've only seen your demos and demo source code which form all of my basis for my opinions on Jai (which are few).

As I develop my language further and program more within this language, I may find that I do need more complex concepts to solve the problems that I have.

One example that I can think of for implicit stuff is iterators. I personally do not use "iterators" at all in C++ as I usually only iterate across arrays and linked lists. I understand your reasoning for adding them as it suits your personal style. For my personal style, I do not like them. It may just because I'm not used to them either nor like how many languages do them.

However to contradict myself, I do personally love the implicit context for procedures. This would solve most of my problems I have with custom allocations and external library allocation (e.g. no need for my custom allocators to be passed and stored in every structure nor #define LIB_MALLOC(sz) ... (if the library's sane)).

My years with C/C++ have heavily influenced the way I the think and their complexities may have distorted my views tremendously. A little more complex than C would not be a problem but how do I quantify complexity?

---

One of the reasons I noted tagged unions is that this is how I prefer to represent hierarchical types (rather than "inheritance"). With tagged unions, each subtype is exactly the same size in memory which is easier to control memory allocation and memory layout. In C/C++ it's a pain as it requires a lot of bookkeeping and extra stuff to get it working and is still not type safe. However, C++'s inheritance model is easier to use but does not have the memory layout benefits. (Note: these are C/C++ problems not other languages' problems.)

Even in this compiler, I use tagged unions extensively (ASTNodes, Types, Entities, et al.) as I can just preallocate the space I need and then allocate from the memory arena as I know the size of the allocations. With something like "inheritance" I wouldn't know the size as easily.

And the last thing I noted was slices. I handle arrays a lot and I commonly have to store the information around everywhere (mainly because of C/C++). A slice is just an extension to an array which is an extension to a pointer. pointer; array=pointer+length; slice=pointer+length+capacity. Having something like this would solve a lot of problems for me having it as a main data type.

These may be complex concepts but I find them simpler than the C/C++ alternatives.

---

- Bill

Edited by Ginger Bill on
Not to be a party pooper, but there is already a programming language named Oden: https://oden-lang.org/
The name was never final and just a placeholder. Also, Odin is a different spelling than Oden :P
Last night, I did a talk and demo of the programming language that I've been developing. Here is the recording for that stream: https://www.youtube.com/watch?v=TMCkT-uASaE

Talk: https://youtu.be/TMCkT-uASaE?t=338
Demo: https://youtu.be/TMCkT-uASaE?t=1800
Q&A: https://youtu.be/TMCkT-uASaE?t=5749
Hmmm, another language with these goals but I'm still wondering if a language is really needed?

The meta-programming and "No need for external tools such as Make/IDE" sound like the only divergence from standard C - But why not just use something like Cling? doesn't it achieve all 3 of those main goals? (just remember to use C not C++ if you want it to be "Simple to read and write" and "Easy to comprehend and reason with")

That said A language that has caught my attention is dale, it basically hits all these same points but does so with a much simpler more regular, uniform, minimalist, lisp-like syntax. (which is the only other complaint I'd make about C)

Edit: Another thing that's been on my mind: What's wrong with just fixing a few things with C and just ignoring ISO C?
eg. don't like having to write struct before struct variables? just fix it! C++ did? Don't like having to write a meta-type generator? just add some new pragmas or macros or whatever like #pragma meta-type-table(name) or #rtti-ptr or whatever or even start using $ and @ since they're totally free for use thanks to obsolete reasons. Why chuck out so much of what already works?

Edited by Michael Cameron on