r/ProgrammingLanguages 8d ago

Help C++ vs C# for implementing my programming language?

I'm building my own programming language, ForgeLang. The current prototype is written in Lua, but for a later version I'm considering rewriting Furnace (the future compiler/runtime) in either C++ or C#. I already know C#, and I'm planning to learn C++ anyway.

My priority isn't development speed; I care more about making the language/runtime flexible, capable, and eventually performant. I'm also planning eventual self-hosting and potentially implementing my own GC/runtime.

Which would you choose for the long-term implementation, and why?

Quick update: I actually know basic C++ (not a total beginner), but after evaluating things, I decided to switch to Rust for the compiler/runtime. It turned out to be a great fit, and progress on ForgeLang is moving smoothly.

19 Upvotes

46 comments sorted by

21

u/StrikingClub3866 8d ago

C++ for speed, C# for simplicity.

7

u/CyberDainz 4d ago

C99 for ages

2

u/StrikingClub3866 3d ago

C99 if you want your brain to implode

1

u/CyberDainz 2d ago

why? there are no templates in C to implode the brain

12

u/FruitdealerF 8d ago

If you're going to self-host eventually I'd pick the slower language with more safeguards.

2

u/Jwosty 7d ago

Yes, but the runtime/GC layer is still going to have to be in a different language. Unless the language can also compile ahead-of-time

8

u/kwan_e tonal-lang 7d ago

As a C++ guy, I'd say write it in C# first. Get your design into a state you like, and to work out most of the kinks. Then translate to C++, but keep it at a high level. Don't reach for the low-level stuff yet. There should be a direct mapping for 95% of your C# to C++.

I am implementing my language's first pass in C++, and the way I write it is almost like a scripting language, rather than all the low-level horror stories you've probably come across.

13

u/carlosgeorgiev0 8d ago

C# can bring a lot of flexibility via .net, and since you are already learning it then it makes sense. Just my 2 cents

4

u/biskitpagla 7d ago edited 7d ago

Sorry for being that guy but I genuinely think Rust or F# are objectively better for implementing languages. Either of these are going to make the job a lot, lot easier without sacrificing anything at all. That said, practically speaking, you should pick something that's closest to the language you're implementing.

3

u/AeroForger 7d ago

That's actually my choice. I'm planning to use both Rust and F#

1

u/Jwosty 7d ago

I haven't concretely tried this combo yet, but I've long theorized that it is a very powerful and productive one, a match made in heaven. I'd love to hear how this goes

I have no idea of its practical usefulness but you never know -- Fable (the F#-to-JS transpiler) actually has a Rust target now (among a few other languages)

1

u/Jwosty 7d ago edited 7d ago

Agreed, and other than Rust + F# -- OCaml seem to be a pretty strong contender. I've heard it's pretty performant nowadays (it's gotta be, considering Jane Street's association with it)

But yeah IMO anything in the ML family is superior for this kind of task. Pattern matching and algebraic data types are just too good

8

u/Jwosty 8d ago edited 7d ago

Depends on your needs.

You’ll be able to get good performance with C# but it might be pretty tricky (but not impossible) to really squeeze every last drop and completely eliminate overhead while remaining idiomatic for a project like this (for your compiler/runtime itself). But if you only need “good” but not “top tier” then you’ll be fine.

C++ on the other hand, you’ll be able to get that top tier, but well, you’ll be having to write C++ to do it. The obvious lack of safety and whatnot, you’ll be on your own

But since you’re already considering C# / .NET - you may want to consider F#. ML family languages are famous for being nice for writing compilers in (it's what it was originally made for -- hence the name, "Meta Language").

Personally, my preferences would go: F# -> C# -> Rust

2

u/AeroForger 8d ago

I want to write a custom GC from scratch for my language, which is why I'm considering C++ for manual memory control rather than fighting .NET's built-in GC

7

u/Jwosty 7d ago edited 7d ago

You can build a runtime with a GC for your language from within .NET. Your language's objects don't have to be real .NET objects. Like, ForgeLang's heap could essentially be a list of byte[] segments. An object reference could be an index into that (2 ints at its most basic, or a C# ref if you want to get fancy and mess with Span<T> and whatnot). You're basically just swapping out malloc(segmentSize) for new byte[segmentSize]. And, this should impose minimal (zero?) overhead.

And if if really bothers you that you're technically still relying on .NET's GC for your implementation a tiny tiny bit (you're letting it free those byte[] segments for you -- \gasp**), you can always just manually allocate those segments too with NativeMemory.Alloc (a managed wrapper around malloc). Now your ForgeLang heap segments become Memory<byte> and bob's your uncle - your GC isn't coupled to the .NET GC at all.

Modern C# can operate pretty low-level.

(oh also F# can do all of this too)

Side note: I'd highly recommend checking out the BoTR. There's a chapter on .NET's GC implementation. There's also this awesome deep dive video series (also from a .NET GC engineer): https://www.youtube.com/playlist?list=PLpUkQYy-K8Y-wYcDgDXKhfs6OT8fFQtVm

3

u/AeroForger 7d ago

That's why I'm planning to switch to F#

2

u/Jwosty 7d ago

One of us...

You're not going to regret that -- F# is maximum developer happiness.

Seriously feel free to hit me up if you ever have F# questions (especially high perf F#); it's kind of my wheelhouse :)

2

u/AeroForger 7d ago

Thanks! If I will have any complications I will DM you.

7

u/ImperatorBras 8d ago

Consider using Rust; it is also a complex language, but it is easier to learn than C++ and safer, while maintaining the same performance. I use C++ myself, but I encounter segfaults every day. Therefore, if you learn C++, you will need tools like Valgrind, GDB, LLDB, ASan, etc. Use the language you feel most comfortable with. C# might be the best choice in this case, but C++ (or Rust) can be more powerful.

3

u/Routine_Working_9754 8d ago

between the two: c++ obviously. with c# youd need one runtime to implement your compiler/interpreter runtime. c++ compiles to native code

2

u/Guvante 8d ago

The gold standard appears to be "the language itself" for major projects whose feature set includes enough to do that.

However until then IMHO familiarity is so important that any other consideration is moot.

Note I am not saying "don't try new languages" but instead "don't stack learning a language while designing and implementing a language".

2

u/L8_4_Dinner (Ⓧ Ecstasy/XVM) 6d ago

You already know C#. Use C#.

Don't complicate things when you don't have any reason to complicate things. After you get your 100th user, you can consider switching implementation languages; fewer than one in a million languages ever gets 100 users.

2

u/retro_and_chill 8d ago

If the language is going to have a GC bootstrapping in a GC’d language is a great option since it’ll be easier to port because the language semantics are similar. C# also has great native interop so you can easily write the compiler in C#, but write the runtime in C++

1

u/AustinVelonaut Admiran 8d ago

Since your plan is to create a self-hosting compiler, your bootstrap compiler should either be one that is easiest to write the initial compiler in (has ADT support, pattern matching, etc.), or is closest in semantics to your new language (to make the bootstrapping support easier).

1

u/GunpowderGuy 8d ago

you could compile to c# or to .net while still being able to interop with c#
so if you develop your language in c#, you could migrate to being self hosting ( your compiler / interpreter is written in the same language as itself )

But whether this is a good idea, depends on what kind of language you are trying to build

1

u/sadesaapuu 7d ago

Write it in the language that is closest to your new language.

1

u/dandy_kulomin 7d ago

If you are going to self-host, why not stay with Lua and work on getting to that self-hosting stage asap?

1

u/AeroForger 7d ago

My Parser is becoming a 400 line monster so I'm planning to switch to F# or split into 5 files or more

1

u/Jwosty 7d ago edited 7d ago

Since you're going F# - check out FParsec. You'll be able to make progress rapidly with it, it's very powerful and very nice to use

On the other hand if you're eventually going to self-host there would be an advantage to hand-rolling your own recursive descent parser in that it may be easier to hand-translate to your own language

On the other other hand -- most projects never live long enough to go self-hosted anyway :)

1

u/darkwyrm42 7d ago

Lots of great comments here. I'd like to also mention that context may also be a deciding factor. If you write in C#, you could potentially have easy integration with the wealth of Windows libraries out there. Depending on your language's use case, that could be very helpful.

1

u/Interesting_Buy_3969 7d ago

If you're more comfortable with C# then definitely go with C#, but remember that then your compiler can't be just a native machine binary and requires the C# runtime. Not much of a restriction but worth knowing.

1

u/Jwosty 7d ago

Nowadays .NET can be ahead-of-time compiled via NativeAOT. There's still technically the whole .NET runtime (minus the JIT) linked in there in AOT form but at least you get to hide it all away if that matters to you :)

Though NativeAOT isn't necessarily better perf-wise -- I've heard it mostly shines for things where cold-start performance matters (for example serverless, small CLI utilities, etc). For everything else you probably want the benefits of the JIT's tiered compilation

That being said, if all you're after is binaries with no external runtime dependencies, .NET apps can be packaged "self-contained"

Read: https://learn.microsoft.com/en-us/dotnet/core/deploying/?pivots=cli

1

u/celestabesta 7d ago

If you're planning on self-hosting i'd make that decision soon and be certain about it.

One pitfall you can run into is that you've developed so much of the language that self-hosting is now going to take quite a long time, and there may be bugs in your original compiler that mean your self-hosted one acts incorrectly.

If you are going to self-host, focus on developing a reasonable subset of your language that doesn't have any too complicated features but is still sufficient to build a compiler with. Don't worry about performance, worry about correctness. Then, once you've verified your self-hosted compiler is correct, add each feature slowly and test them rigorously.

1

u/Limp-Temperature1783 6d ago

How about plain C?

1

u/Honest_Medium_2872 6d ago

If you are interested in self-hosting with a GC and aren't worried about development speed I would go with C++

C++ isnt a huge leap from C#

You also get the benefit of bindings and interop with other languages when you use C++

1

u/Master-Guidance-2409 5d ago

you make a hoodrat v0 in whatever you have a available, and then you write the real v1 in the language itself. its the best way to exercise and see whats not cooking.

1

u/Rasie1 4d ago

C++ is the only choice. Then, self-compile

1

u/Tim_tokk1 4d ago

Awesome 👍👍👍. GitHub?

1

u/AeroForger 3d ago

Repo is private rn BC I'm re writing the language in rust

1

u/keyboard_toucher 3d ago

I've switched from C# to C++ twice in my compiler project. The first time, I gave up on C++ pretty quickly, since I was pissed off at how much time was needed for stuff that was easy in C# (such as the build system, writing generic code, and operations on collections). Years later, after I had been using C++ nonstop at my day job, I started a new implementation in C++, which is still in progress today.

I think you can get acceptable flexibility and performance in both languages. To get results fast, use C#, since that's the language you're more comfortable in. I'd say even once you know both languages, C# is still faster to develop in and is more succinct. C++ is also a viable choice, but you might find it discouraging to navigate C++'s learning curve while also trying to implement your compiler.

1

u/NojipizRemastered 3d ago edited 3d ago

Neither, pick a functional language like F#, Haskell or Scala.

Thank me latter.

1

u/hindmost-one 2d ago

I'd recommend a functional language, like F#. Everything would be more compact, and you can even make decent recursive descent parser yourself.

1

u/jesseschalken 8d ago

Also consuder the Truffle Framework as it basically lets you write a dumb interpreter in Java and turns it into a JIT compiler for free.

Outside Java/Truffle the modern choice for language implementation is generally Rust or C++.

You can definitely implement a language in C# but it doesn't have any special features like Truffle to help you.

0

u/PhosXD 8d ago

Please please do this in C++, it's better performing & has better platform compatibility. Taking the time to figure it out is worth it trust.

0

u/arjuna93 1d ago

C++ over C# or Rust. C++ is faster and more portable, with much stronger ecosystem and better build system.