Will Hare replace C? Or Rust? Or Zig? Or anything else?
harelang.org
harelang.org
I don't have to waste time evaluating web frameworks I can just start coding a website with net/http right away. Oh its production ready!? Amazing!
I do wish Go had more things built-in like email and other protocols.
If I were maintaining or creating a systems language, I'd invest in the standard library being powerful out of the box. I really secretly wish Rust / D had a web server baked in sometimes.
All things said, this is the first I've heard of Hare, and it looks nice to me from what little I've looked at.
I attribute Go's success purely by it being pushed by Google.
If we use Rust as an example, it's super easy to include high quality libraries (just add s line in Cargo.toml and you're good to go).
Another example is Ruby and how it was made popular thanks to Rails, or how Elixir is making a splash in web dev thanks to Phoenix.
Assuming a web server—Which library? Which version? How many commits does it have? When was the last one? How long will it be supported? Is it async? How many deps will it pull in? Will it be superseded by a fork? Does that fork have a different API? Will I have to bump the Rust version to match it in the future? Ok, I've gone to another team and their app uses a completely different library, what's the answer to all those questions again? Etc.
With Go, the answer is and always has been:
include "net/http"
I love Rust, but its DIY libraries can be quite a barrier to overcome when starting a project.In the future the answer may be go to <SITE-URL>, look up the HTTP server category and either read through a few one-line descriptions or just use the recommended package.
https://blog.cloudflare.com/the-complete-guide-to-golang-net...
You -CAN- go the route of using a well supported, well maintained library but I have seen some code rot on larger projects in the go code ecosystem for stuff that tried to include more batteries.
At the beginning Google's support really made a difference, but the continued traction of Go is really the result of it being a great tool to build network servers where you want a high level of performance.
This was the case from the Day 1. Google strongly shaped the language's direction and that has a continuing effect on Go's success. Put it differently, if somehow we end up with the future without servers Go will have a very hard time.
Golang isn't really faster then any other on the same playing field (compiled and with GC).
I would say that having Ken Thompson and Rob Pike's names attached was far more significant than Google. More than that, though, it was successful because it solved problems people had at the time. The solution space is much larger today, but at the time Go was quite unique in filling its niche.
For comparison see Dart which was pushed even more by Google (I still remember when we were being inundated by "dart is soon gonna replace javascript everywhere" posts/videos) and now has not even remotely the userbase of Go and it's just a niche language for its specific framework Flutter
It was only rescued by AdWords team , and then Flutter team picked it up.
The Android team is also not in love with it, and Jetpac Compose is surely an reaction to it.
Which add +100 dependencies, many of them 0.x and constantly changing. I remember updates where I clicked through the docs of three different crates to decipher cryptic compiler errors. And don't get me started on getting started with Rust - Go is much easier to learn.
Unlike Swift or Kotlin that are heavily entwined with the main mobile platforms, nobody needs to use Golang for any particular reason. As far as I can tell its developer experience is pretty good so people have opted for it because it fits their needs.
Is this a joke? How the hell would I know which out dozens of library is complete, safe, well documented without significant research?
I started trying to use something like tokio for async stuff, but found that Rust's standard lib threading primitives were already nice and numerous enough to get a lot of work done.
The rust programming language book has a nice little project of building a multithreaded HTTP web server from scratch. Of course you don't necessarily want to do this for everything, but the fact that a lot of the primitives are present and with good abstractions is commendable!
Go's stdlib stuff for web servers is obviously much easier to get rolling though.
https://doc.rust-lang.org/stable/book/ch20-00-final-project-...
The ability to have all the bells and whistles out of the box may be a lot of the appeal of Go, and is certainly a lot of the appeal of languages like Python. But it's not core to the ethos of C.
Though C++ and Java both probably have more container/algorithm libraries builtin than Go does.
people already complain constantly that the C and C++ standard libraries are bloated though
C's standard library is rather spartan and includes some security issues. What C does have is a) interoperability-friendliness, b) a vast ecosystem.
People should learn lessons from C++'s success and understand how important it is to be able to easily consume C libraries.
You can check out the stdlib here:
Let me know if you think this strikes the right balance.
Also, no data structures? I don't see maps, arrays, sets. No support for custom allocators (where's the `mem` module)?
The roadman mentions TLS, smtp, sql and http (no json?) but you're not too concerned with people wanting to use it for web development?
Arrays and slices are built into the language, sets and maps are not. Much like C, though slices are new to Hare.
I like the concise names. It's a matter of taste.
pwent and grent have been called that for 46 years, though usually only in the names of functions: https://www.freebsd.org/cgi/man.cgi?query=getgrent&sektion=3
Similarly, chown. Or is your complaint that there are two different chown calls?
Trying to rename these things would make the library a lot harder to understand. Can you imagine if someone decided to call the USA "Samland" because they thought the three-letter identifier was too short? Would that reduce confusion?
I kind of agree about vtable, though.
Arrays are part of the base language, not a module. Not sure about sets and maps.
(BTW, https://harelang.org/documentation/ is the link for more general documentation about the language.)
Standard library usually comes with strong backwards compatibility guarantees. So it becomes ossified over time. Leading to - standard lib is where libraries go to die.
Without stability guarantee, you risk introducing breaking changes between versions, which is worse. And inferior to just downloading a lib with most stars.
1. Include as much as possible. This has been Python's approach and is showing its limitation: you end up with lots of historical baggages you can't maintain. It took an eon to remove some dead batteries from the Python standard library [1].
2. Exclude as much as possible. This is the preferred approach for most newer languages, which can't readily determine at which direction the language would be heading. These languages tend to weigh more on third-party libraries with their pros and cons.
3. Pick use cases and design the standard library only for those use cases. It would mean that you have a near-total control over the language's evolution, so you can include whatever you want without thinking about its long-term consequence (because you know a new addition would be necessary for your use case). This can be often seen from some smaller languages, but Go is in my opinion the only mainstream language using this approach and that's only possible due to Google's involvement.
I don't think Drew wants to compete with any of these languages. That's the point of this article.
Let's give this one some time before ruling it out right at the gate.
I have yet to work at a Silicon Valley startup that used C# or F# though, despite it being a pretty solid choice in terms of "one language to rule them all" kind of thing like Kotlin / Java and (to maybe a lesser extent?) JavaScript.
I respect the tools and the language Microsoft has put out there, I'm not saying its objectively better or worse.
Especially F#, which is, to interject my opinion, an incredibly productive language on the same level as Go, and you get access to the rich .NET ecosystem out of the box.
As far as I'm aware Java and C# are still first/second by job listings in both the US and UK but in significantly less sexy enterprise settings. This might have changed since python became more widespread though.
I think C# and F# will get significantly more popular over the next 5 years.
And if this doesn't happen it will have been pure mismanagement of opportunity by MS.
Rust doesn't seem to have that rich of a standard library, bunch of the official documentation asks you to add crates for lots of things. I find myself reaching for external crates for tons of things I'd expect to be in the language as well.
I also don't think Go's success can be attributed to one single thing, but probably the biggest attribute would be that they are backed by one of the biggest tech company in the world, who have adopted it wholesale and would do so, no matter what, since they built and control it.
May, partly, sure...
I attribute Go's success due to the simplicity of the language. All successful languages tend to have one thing in common - they are extremely easy to read.
Forget about needing to decide on a web server library because there isn't one in the standard library. With C++ you have to decide which parts of the language itself you're going to use. Trying to learn is incredibly intimidating, because you look up how to do something simple and there's 17 unique answers with a million opinions on which is best, and which will lead you into a nightmare of unmaintainable code.
Go was built on the principle of being incredibly picky regarding what features are added to it. It's best assumed that any new feature that's proposed to be added will never be added, and until it goes through a heavy pitching process and gets hard-earned approval, it won't be there because the language has worked well enough without it up to now.
Having the formatting forced into the source code is genius too. Whether or not I agree with the prettiness of every formatting decision, I'm just happy it's there, because it's less decisions I have to make, and no matter whose code I'm reading, I know it'll be formatted in the same way as everyone else's.
This way you won't need to give up on any of your existing, working, debugged C code.
I would say SPARK2014 or straight up Ada for life-critical software given the maturity and target markets. Rust is heading there, and there is some communication between Adacore and Ferrous Systems (Rust group)[1] taking place that gets me excited, but I will stick with SPARK2014 for now.
[1] https://blog.adacore.com/adacore-and-ferrous-systems-joining...
Honest question, what are the compelling ideas? I really don't mean that with any snark. I haven't read through everything on the site, but so far I see:
- Uses the `let var: type = value` syntax
- Infers `type` from the value when it can
- Has arrays and slices of arrays
- Uses `defer` for cleanup
- Doesn't have a garbage collector
- Imports using `use` (vs `#include`)
- Module scoping with `::`
- Has `match` (not sure about patterns/destructuring)
- It looks like `yield` is a return from sub-expressions
edit: some more...
- tagged union types
- non-nullable types (opt in)
- utf-8 strings
I asked the #hare IRC channel to add their own thoughts, will edit this comment with any answers:
> Simplicity.
> I think a strength is the plan for long term stability.
> It's simple and the compiler is tiny.
> First thing that comes to mind is error handling.
> The syntax seems simple to me, like c and go and unlike c++ and rust.
> I think a major strength is you can transfer your C expertise.
> You don't have to worry about your post-1.0 code breaking or becoming obselete from new language idioms.
> Clear communication from the hare dev team about what the project goals are.
If you have a formatting operation that produces an in-memory string, you cannot use it if the amount of text being produced is too large, or if you do not know if it is too large. But if it is not too large, you can then output the string to a buffered output file, although this is less efficient because it involves an extra copy and potentially dirties a lot more memory.
So these two ways of handling formatting are easily interconvertible when memory permits, but in some circumstances only the first one is applicable, and it is always more efficient.
Therefore, when reliability or efficiency is important, generating a formatted string should be implemented as a layer on top of sending formatted output to a stream, not vice versa.
There are cases where reliability and efficiency are not important, because your code is being used by end users and not as part of a library, and an error message is also an acceptable result of trying to run your program, and in those cases you should probably write your program in a language like Lua, Python, or JS.
It is probably true that if you are used to languages like those, a lot of design decisions that are necessary for reliability and efficiency will be counterintuitive to you.
This seems like an extremely rare case, which is itself a subset of the very rare case that you are formatting something that can be arbitrarily large. Oh, and the programmer must somehow have overlook this and not written it formatted output to output in reasonably-sized chunks.
Meanwhile, having back-and-forth between the formatter and I/O means the formatter must correctly handles all the I/O problems and corner cases: disk full, disconnect, transient failures, ... not even going into that for some of them, you might want the caller to decide the outcome, which is easy when you split formatting and I/O, but hard when the formatting performs the I/O.
I think this is a case that it may sounds superior to mix both, but it is actually buying next to nothing but both complicates matters and probably hides or ignores real issues.
I suspect "simple enough" is a threshold/constraint, but not really the goal.
Is there something about Zig that rubs you the wrong way? Honestly, Hare almost seems like a Zig subset.
Edit: I respect your technical skills and sheer volume of output a lot so not trolling here, just trying to gain clarity after reading the language introduction.
Absolutely hilarious (and thanks for making this decision!)
That should be somewhere in summer of 2023, if we go by previous release dates.
Smart choice for packaging. Keep it simple should be a rule, not the exception.
C coders are defined by having seen a thousand languages go by and passed on all of them. C coders like C to the exclusion of all else, or they would have abandoned it long ago. Hare will not be picking up any substantial number of C coders.
Hare will not be picking up any C++ or Rust coders. It is a huge step down, offering literally none of what makes either language compelling for its users.
Likewise, Lisp and its offshoots. And Haskell, Erlang, MLs, APLs, Smalltalks, and Adas, all themselves niche.
Hare will not be picking up any Forth coders.
Zig is much more mature, and will maintain its lead. Nim is more mature, but will continue trailing Zig. Hare might chase after Zig alongside Nim.
The normal fate of any new language, absent The Miracle, is to fizzle. It is the certain fate of any language that brings nothing compelling to the table. Hare is exactly such a language.
A few people may continue using a fizzled language, indefinitely, like people maintaining their DVD collection. But there will be no reason for others to pay it any attention. The overwhelming bulk of the value in any language is network effects, and a fizzled language has none.
I doubt very much that there are many C coders who like the C language.
I had liked very much C around 1990, when I could use for the first time the Microsoft C compiler and the Borland Turbo C compiler.
Previously I did not have access to programming languages better than Cobol, Fortran, Basic or Pascal. In comparison with any of those, programming in C was much more enjoyable.
However, later, after better languages became available, I had no reason to continue to like C.
Despite that, I continue to program frequently in C, because there are still cases when it remains the best choice, for various reasons having nothing to do with the quality of the language, i.e. mainly for embedded computers or kernel drivers.
In any case, the C language will always remain on the list of languages important in the history of programming languages, independently of how many programmers happened to use C or to like it, because of a couple of valuable innovations: the "continue" statement and the distinct operators for the McCarthy "and" and "or" and for the bit string "and" and "or" (though it would have been better if single characters would have been used for McCarthy operators and double characters for the bit string operators).
(A few other innovations that are sometimes attributed to C had actually been introduced in the language B, the predecessor of C, or in the language BCPL, the predecessor of B, or in the language CPL, the predecessor of BCPL.)
(It probably is better on net, but) not as much as one might think, actually. It's a clear win in terms of Huffman coding, but there's also a general principle that small infix operators have higher precedence, and large ones lower precedence, like how multiplication in math notation uses "·", or more often nothing at all, while addition uses "+". (It also shows up in natural languages; consider "Tom and Dick and Harry as well as Alice and Bob".) It's (probably, usually) worth subverting for assignment, because "=" is used a lot, but I'm not sure if it's a good tradeoff for boolean operators, eg:
if(x == 3 & y == 5) foo(); // look's a bit too much like it's saying
if(x == (3&y) == 5) foo(); // ie (x==(3&y)) & ((3&y)==5), rather than
if((x==3) & (y==5)) foo();
Though, like "=", the initial misleading hueristic might wear off with sufficient exposure, and you can usually fudge it by adding spaces around the low-precedence operator.In my opinion this is one of the greatest mistakes of C, and which unfortunately has been inherited by too many other languages. Even Dennis Ritchie has admitted that this might have not been a good idea.
Mind you i don't know, i like Rust - but i'm not a C-like programmer and don't want to be. But, nevertheless my opinion of Zig seems quite high. It seems Zig is the benchmark in this space.
There's even old languages dug up for this purpose. Most pascal I have seen lately is malware samples.
Write any trivial program in vb6 and upload it to virus total. Red alert left and right. Even Windows Defender of all things goes off for anything a little more involved. Sometimes only a couple of days after you did the initial scan. Signing the binary helps, but is no silver bullet, and sometimes companies still can't be arsed. There's an endless thread in the last remaining forum about vb6 where people try to figure out what increases chances of detection, and it mostly reads like cargo culting.
That being said: automated malware analysis is of dubious efficacy and flexibility to begin with, so who knows.
I think they DON'T want to compete with any language nor attract C/C++/Rust/Zig/Nim/Forth/<name_your_language_here> coders.
From my point of view, all languages which don't add anything new and improved are a drag on our collective computing experience.
I'd be happy if humanity had like three or four programming languages: Idris or some other better-Haskell (for guarantees), Lisp (for simplicity), Rust (for performance), and probably one or two other languages which are unique enough, Prolog or something, K?
I couldn't disagree more. The more people writing languages and implementing standard libraries the better.
Are these minor languages going to be used in production? An even smaller minority of them, sure.
For the majority of them it's a chance for developers to relearn data structures and algorithms and compilers. Real, hands-on practice that is hard to beat with any other method. I only got decent at algorithms and data structures by implementing languages and standard libraries.
I'd rather every developer built their own language.
If people weren't experimenting with weird esoteric languages, how would we have gotten any of the languages you list here? If I'm recalling correctly, K is descended from APL, a language you needed a special keyboard even to use. Rust synthesizes ideas from lots of small academic languages no one will ever ship software on.
I understand the network effects and 'community' benefits of large/non-fizzled languages, but I want to believe that a language that makes an individual programmer happier, more productive, better able to meet engineering goals, or whatever metric they seek to increase through choosing one language over another, is the language they should be using.
I remain hopeful for a heterogeneous approach to language usage in the future, where multiple engineers working on those applications can utilize a language which they determine is best for them. I think this could results in multiple languages which all compile to a well defined target language, via well specified semantics for the source language transformation. I know this is almost the idea behind the JVM or CLR, and is similar to many languages transpiling to C. I would like to see an environment cultivated to support this from the ground up and grow from there.
Thus, there are very powerful organizational forces pushing for a single implementation language. A practical exception to this is that there are plenty of programs coded in a systems language providing a scripting language (e.g. gdb in C++ with Python scripting, Emacs in C with Elisp, Vim in C with Vimscript) made tolerable by the scripting language being extra-easy, very widely known, or known to all users of the program, so familiar to any contributor.
But the need to learn another language, or two or three, just to contribute to a project will turn away people not able to spare that much attention. Businesses would need to pay for the time all the developers need to learn all the languages. And, languages will be at multiple levels of maturity and stability. What do you do when 10% of your system is coded in a now unmaintained language? When you want to port to a new target execution environment, does each language not ported there get to hold you hostage?
This is why languages with a wide range are attractive. C++ and Rust aim for this wide range, providing for both bit-twiddling optimization and system architecture organization. Supporting a wide range is a big burden for a language maintainer, so there will never be very many like that.
It is based on a stable standard.
It is extremely portable and not in a target major platforms way - that is much better done in other languages - but in a being able to run on nearly every OS and hardware in existence. You can feasible port your C software to you weird hobby operating system.
It is simple enough that you could write your own compiler or at least something to bootstrap a proper one.
It is the Latin of programming languages. It is the common, cultural core we have. Nearly all bigger languages have some way to interact with C. If you want to write a library that can be easily used from any language, C is the way to go.
It is (relatively) fast too compile and creates binaries of minimal size that run at maximal performance. (Yes, you do make trade-offs in some of these aspects when using Rust or C++. Those trade-offs are worth it in many cases but let's don't pretend they don't exist. C serves as a performance gold standard for a reason.)
Yes, it is also a horrible language is many ways and should not be used for most projecs but the advantages can make all the difference for certain use cases. For projects like SQLite or Lua it was for sure the right choice to use C.
Just because you don't care about the downsides does not mean there are no there. First of all, which subset of C++ should be used? It is a huge language that only very few people can claim to master. So lot's of people wouldn't be able to understand or change the code anymore. That is quite the significant downside.
Not to mention all the other downsides mentioned in my other post, like being slower to compile, bigger binary and so on. Yes, those downsides might not matter to you and should not matter for many projects but they do exists.
C programmer often care more about building the best possible software not so much about having the best possible development experience while building.
That said, Rust has much better safety guarantees, so it DOES offer some significant upside that C can't.For more complex software it is is definitely a very good choice.
I agree. And for that matter, see a lot of the same for Zig too. Hardcore C coders have learned to live with it or have incurable Stockholm syndrome and stay despite of the situation.
I believe it's really a matter of programmers who are newer (younger), casual, or part-time at it (like various people in IT or security) that are looking for more convenient alternatives. In that case, things are more wide open. They could pick Go, Odin, Vlang, Hare... just as easily as they could pick up Zig. There are many "better C" alternatives vying for position. It could shift so easily.
As for Nim, I think they have a certain level of guaranteed "lock-in" for being so Python-like and seen as an alternative to it. How far that will take them, remains to be seen. Same for Rust, they have "safety" to play on, and the backing of Mozilla that added wind to their sails.
> The normal fate of any new language, absent The Miracle, is to fizzle. It is the certain fate of any language that brings nothing compelling to the table.
True.
With just that, I'd say it's a win in my book. Not mentioning actual, useful strings.
I just pointed a couple of it's good sides, that make it worthwhile for myself to eventually learn.
It seems like a lot of people choose languages due to ecosystem constraints?
Those irrational people seem to have code that doesn't require rewrites/refactoring every few years. Switching to an entirely new ecosystem as a primary field? I leave it to the beta-testers, perhaps in 10 years Zig/Rust/Nim will be standardized languages with multiple compilers and big ecosystems supporting them, just like C and polished enough to be as easy as C to write.
> Part of our work in developing Hare is laying the groundwork for a collaborative, productive, healthy community that people want to work in, ...
Maybe that's enough? It's okay to be a niche, even toy, language. The community is the "feature" that makes it compelling, eh? Like how Gemini doesn't compete with WWW, or indeed how Sr.ht is not exactly a competitor to GitHub, but still has its value.
In what sense? I mean, he's not entering contests with it? (Forgive me for being dense.)
> He just doesn't want people making fair comparisons.
I dunno, I feel like he's been pretty up front about where Hare is different (not to say inferior) to other languages. (I should mention that I'm generally pro-ddevault even though I don't agree with everything he's into. (E.g. I'm not on the Graph DB bandwagon (yet?).)
FWIW, I see Hare as a fun toy (a toy that can do real work through, to be sure.) As long as it and the ecosystem around it can attract people to work/play with it then it doesn't need to compete. (Except in the general sense of competing for time and attention with everything else.)
Except under proprietary operating systems. It's really not that difficult to compare Hare with C. C works everywhere, Hare doesn't. It's disingenuous to compare languages that aren't even close to the same portability level. C, Rust and Zig can be used to implement any imaginable piece of software, from desktop to server on almost any architecture and operating system. Hare is a niche language for Linux services, so I don't think anyone had any doubts Hare would not replace C.
Unlike LLVM, adding a new backend for Hare is a relatively straightforward effort: riscv64 was done by one person in a few months and is only 1,476 lines of code.
And again: the answer to the question posed by the blog post's title is "no".
That is likely just trolling, but is also specially obnoxious considering that Rust does prevent use-after-free bugs as much as Java does (i.e. a lot, but definitely not all).
However, I really do think for a new "systems language" nowadays, you do want to look at how major security holes occur in practice, and have a good story on how users should avoid them.
Also I was wrong before and you were out of line. Matthew wasn't trolling, he never said you should be held criminally liable. You just made that criminal part up for no reason. Anyone should be held socially liable and shamed if their project has bad security and they refuse to fix it after they knew about it. I think you would even agree with that.
Why does anyone need an excuse to build anything? He’s doing this in his free time. He doesn’t need the internet’s permission.
None of what you said is even true, all of those patterns are trivial, except "back-references" which are very slightly non-trivial.
And none of it is relevant. We don't need another memory unsafe language. It's fine if it's a toy, but this obviously isn't. It causes real harm.
> Part of our work in developing Hare is laying the groundwork for a collaborative, productive, healthy community that people want to work in
The goal to have a healthy community is laudable but it comes from the top and hitting out at others doesn't set a good foundation. I'd recommend rising above by responding to critique without emotion.
That's solely my point.
> Look if you can't understand that this is a thing that will happen in the real world and that people will potentially suffer as a result you shouldn't be writing a crypto library.
Which is still far from suggesting someone should be prosecuted.
But it confirms what I was thinking, going from "liable" to "criminally prosecuted" is a pretty big stretch imo.
So let's summarize:
1. Simplicity and readability - C, Go
2. Tiny language - C, Go
3. Modularity - Go, Rust
4. Defer statement - Go
5. Metaprogramming (generics, compile time, macros) - lots of inspiration and some really fresh ideas like Zig and Jai, Go interfaces, and Rust traits look nice
6. Strong type system - Go, Rust
7. Manual memory management, pointers - C
8. No OPP in terms of C++, Java
9. No references, just pointers
10. Syntax - Go, Rust
11. Zero cost abstraction and as much as possible minimal runtime - C, Rust
Mostly their look like Rust with "defer" but without borrow checker, move semantics, references, RAII, and lifetime annotation.
Mb this is what we really need? :)
Rust is inspired by ML family languages and heavily leans on it's type system, while Go is very simplistic in comparison. (This has improved somewhat with the recent addition of generics)
In Go the answer is that strings are just some bytes, and filenames are just some bytes and so this naturally just works.
In Rust the answer is that strings are AsRef<Path> and you can open a Path, so when you call open the compiler gives it a Path even though that isn't what you actually had (you can't mutate the Path via this reference, so we know open doesn't change it).
The difference becomes more stark if we go the other way, starting from a list of files in the current directory and writing a JSON file.
In Go if you get a list of all the filenames in the current directory, it's a list of strings, and the fact that those aren't actually text is your problem, you will need to explicitly take care of this or you can't emit valid JSON.
In Rust, you get Paths, and you're going to need to explicitly ask for the strings to make JSON, at which point you have to decide what you want to do if the Path isn't just text, you're obliged to decide, even if it's just panic (ie abort the program).
You'll still emit valid json. The encoding/json doc says:
> String values encode as JSON strings coerced to valid UTF-8, replacing invalid bytes with the Unicode replacement rune.
- Defer is nice for cleanup, but I think destructors are the gold standard there. They're even simpler to reason about, you can't forget to invoke them, and combined with move semantics they automate away a really wide range of cleanup scenarios. Another interesting difference is that adding destructor-based cleanup to an existing type that didn't previously have a destructor is often a backwards-compatible change. Lastly, GC'd languages like Go usually need to include some sort of finalizer mechanism in addition to the defer syntax, and finalizers are surprisingly complicated.
- I don't think C should get full points for zero cost abstractions. There's a lot of pressure to use void*'s or intrusive structures in place of true generic containers like std::vector/Vec, and that comes with runtime overhead in practice.
> Hare is a systems programming language designed to be simple, stable, and robust. Hare uses a static type system, manual memory management, and a minimal runtime. It is well-suited to writing operating systems, system tools, compilers, networking software, and other low-level, high performance tasks.
I would be happy to clarify further if you're still unsure of what kind of programs are well-served by being written in Hare.
https://sr.ht/~vladh/hare-project-library/
I hope that helps.
In the case of Hare, it doesn't seem to be good if you want to be able to have anything running on Windows/macOS, as one stated goal is "Hare does not, and will not, support any proprietary operating systems" according to https://harelang.org/platforms/, which makes it very unattractive for me at least, as I move across three platforms daily.
https://harelang.org/blog/2021-02-09-hare-advances-on-c/
And if you have any specific questions that you want to frame in the context of another language, I will do my best to answer them.
It seems to me that these crusaders (and I've seen a few) think that because you shouldn't build a big bridge out of wood, you shouldn't build anything out of wood. Is the thinking more sophisticated than that? Honest question (and I code in Rust).
However, there is definitely a subset of the community that is so bought into the idea that memory safety is an Absolute Good that any new developments, projects, or languages that don’t make it a priority are a priori bad.
I am a huge fan of rust, but we should let the language stand on its own merits and not assume that it is the only valid choice. Just because I and/or my company prioritize the features rust gives us doesn’t mean it’s the perfect solution for every problem.
That said, I do feel like this view that rust is the only valid language is a minority one in the community. It just is a bit loud at times.
(A "true believer" for my point here isn't someone for whom Rust is their favorite language or their generic first choice; it's someone who gets angry if someone else doesn't choose Rust for some task, and especially gets publicly angry.)
I bet for a lot of the True Believers, they learned some language that isn't very good, like C, or C++-as-taught-by-schools, (which is a very bad language, much worse than C++ as a whole!), or Javascript at its worst, and then encountered Rust. Hey, I get it, that would be a pretty big leap! But you've got a path dependency in your opinions there.
I'd encourage any such person to broaden their horizons a bit. It's OK. Rust really is a pretty good language and you probably won't change your opinion of it much. Plenty of people I know and respect who do know many languages still have Rust as their favorite and general default language. But it is not the only good language in the world, and other languages do offer things Rust does not. Consider trying out the Erlang environment (either via Erlang or Elixir), or Haskell, or Lisp.
Then (now you're about a year in), someone will tell you, you poor thing, you've been abused by being taught that way! Use modern C++ and the STL and never use a raw pointer again. Drop that OOP stuff, learn about lambdas and functional C++ instead. You then read flame war threads about the proper way to do things, which you finally learn to ignore as they're just people with inflated egos throwing things at each other online.
Finally you understand: people write firmware in C because it's about as low-level as you can get without going to assembly, and people write big projects and games in C++ because of all the libraries and the STL and good performance speed-wise, and then there are people who've abandoned C & C++ for Rust because of the memory leak issues and perhaps the convenient build system, and you never ever again write the kind of code you wrote for your assignments in your C++-as-taught-by-schools courses.
Finally, you take a few Python courses and marvel at how much easier it is to code in Python, but you feel a bit better off than those who learned to program in Python, because, you at least know what pointers are. Then someone tells you, hey, learn some Java too, it's easy to get a boring corporate job if you know Java. Anyway, that's what schools are teaching right now in their core intro CS curriculum, more or less.
Your description accurate but a little off because most students at least in America learn Java first as part of their AP Computer Science course, and a lot of colleges use Java as an intro language for this very reason.
Isn't the whole point that Rust is a replacement for C/C++, specifically the whole "close to hardware" and (basically) zero-cost abstractions? If you can afford things like a GC or a VM there are way better languages, that's for sure.
It should be criminal to build anything out of wood. Heard of forest fires huh? Guess what, they are made of wood!
---
Sorry, I couldn't resist.
Our wood workers have a track record at that.
It's one thing laughing at wooden bridges. The other thing is we already have charred landscape full of them.
I think the way it usually works is a less reasonable one would make outrageous statement, later on some one more reasonable sounding would put a context or nuance around it.
So a single crusader maybe called outright troll or whatever but if a few work together they can be much effective for evangelism.
Software engineering is more than writing a program, there are economic factors at play too.
That being said, I also wish my browser was written in Rust (and my OS too!).
Existing code and existing engineers are a massive barrier-to-entry.
One trap engineers fall into is we tend to view exaggerate the importance of certain problems. Verbosity in Java is a big one. IDEs fill it in for you. It doesn't slow you down. It's a complete non-issue.
Zig is interesting. I don't know a ton about it. My sense is that Zig is to C what TypeScript is to JavaScript. I mean Zig isn't transpiled into C but the point is that it seems to be very closely related so transition should be fairly easy.
Rust most closely competes with C++ (IMHO) but it does something really interesting that C++ just can't do: it tackles ownership and memory safety at compile-time. Yes, C++ has smart pointers but these incur a runtime cost. C++'s features, history and (dare I say it?) baggage mean C++ can't do the same thing.
I personally consider this to be an increasingly important issue so Rust has a definite niche. But will it displace C++? The odds aren't in its favor. But it will certainly be viable.
C is the funniest one though. Asking "Will X replace C?" is a bit like "Will [search startup] replace Google?" The startup landscape is littered with the ocrpses of Google-killers. Likewise the language landscape is littered with the corpses of C-killers. So my money is on "no".
I think a lot of C programmers dislike some parts of the language - something that's true of any language - but they like writing C code the way they have for the last X years. If they're willing to give up the preprocessor, they can keep using C. There's no need to replace C. D has support for all the platforms of GCC and LLVM. That's obviously not as many as C, but it's a lot.
It most definitely does! Perhaps not when writing code. But it does take longer to read/scan verbose code. I'd also argue many kinds of refactoring are made slower by verbosity.
This might be referring to comments elsewhere, but I thought there was a pretty thought-provoking debate about safety tradeoffs in the Hare intro thread.[1]
Which I'd summarize as: let's say we now know how to prevent, say, 70 out of 100 security bugs in C codebases, without performance compromise, by statically ruling out things like buffer overflows and use-after-free; and we also have good evidence that bugs your language ecosystem is bad at detecting are hard to backport detection for. Is it a good idea to make a language that prevents _most_ of those 70 mistakes, but not all that we know how to prevent, in exchange for being simpler, and therefore reducing the other 30 mistakes and getting more software done that helps people? Or would it be better to avoid investing in or relying on new languages with that tradeoff for infrastructure code, and focus on seeing how simple a language can be that prevent all 70?
Which isn't a logic question, but an engineering question: does the mostly-safe language prevent 65 out of 70 memory bugs, or 30 out of 70? Does it let you get twice as much done as the safer language, or 10% more done? Does it result in fewer logic bugs than the more complex language, or the same number?
I don't know, but I'm interested, because I want the next billion lines of code that affect me to do useful stuff and not break. "My goal is not to force anyone who doesn’t like Hare to use it" isn't really an option; I'll be impacted by all the code people write in every language. So: I'm happy to see people make new things that test a new point in the design space! But I'm _also_ happy to see other people say, wait, before I end up with a ton of this code tucked into the lower levels of my machine and the other hundred billion machines wired up to it, what mix of features would convince me that "less safe than we know how to make new languages" is still safe enough for a new language in this case?
I think I speak for a majority of the Rust community when I say that we're embarrassed by this sort of behavior and we desperately wish that folks would stop it.
My main motivation for using Zig is that it's rapidly becoming a better C toolchain that GCC or Clang. So I'm extremely motivated to compile all my C code with Zig when it becomes possible. After that it's only natural to write more of my code in Zig.
So, my hypothesis is, a language that could replace C has to have a better C compiler built-in than existing C compilers.
Another side of this, is that it has to be extremely easy to use C from the new language and vice-versa. Something I also think Zig does mostly right.
Perl has Inline::C that allows snippets of C code to be placed directly into Perl code like many C and Pascal compilers allow inline assembly. That's for interoperation and an occasional optimization of course, since Perl is in no way a C replacement for much of what's done in C. Do you foresee a replacement language having such inline sections, being a superset language like C++ or Objective C, or being able to just handle separate files/modules in separate languages?
Because the code written in HTML and Javascript isn't going to be rewritten in Rust another language, probably ever.
Open visual studio (or Qt) 'File' menu, 'New C/C++ project'. Press F7 to compile.
No command line, no cargo build, no cargo run, no cargo.toml. Just press the green "play" button and your full graphic application shows up.
Embedded with Arduino C++: 'file' menu, then 'new sketch', click the arrow to compile and download to the board.
0. Export/upload my source
1. Import/download my remote source
2. Compile my source for different targets
3. Cleanup my source and my compiled source
5. Do all the above for different versions/locations of my source
6. Do all the above for source not my own
7. Do all the above with a simple command and or a simple key->value in a config file
Then I need to do all the above with
8. using a terminal on my personal computer
9. on a remote server using ssh'ed terminal
10. in a script automation file like a docker file or maybe a vim script that setups my dev environment
11. Have 0 - 10 be so easy to do, basically a simple command or two, that I don't have to spend days figuring out tooling FOR EACH TASK and googling mystical error messages for solutions on obscure forums posted 2009.
I stayed with Rust because it has good tooling. Because it's the one thing that hasn't driven me insane at one point or another. I wanted to program in Haskell and c, but I am so sick of the terrible tooling and the terrible conventions of the communities (something Go at least gets right) that I instead program in Rust, a language I enjoy less for it's merit as a language.
Cargo is very opinionated, forcing upon you certain directory structures and even a default VCS. If you have a large project, cargo makes you jump through hoops. Building multiple binaries and libraries from one project is a pain, and has to be done exactly as cargo wants.
In terms of being able to "just get started", I think `gcc app.c` is way easier than using cargo. But that's not really important. You're not going to replace a million line C project with Rust just because "getting started" was a few seconds faster/slower.
No, it expects source code in `src` like most C/C++ projects anyway. Then it's `lib.rs` or `main.rs`. The opinionated directory structure (`pkg.rs` or `pkg/mod.rs`) is rustc not cargo.
> even a default VCS
Because it's the one used by most projects. Anyway, nothing prevents you from using mercurial, svn, ...
> Building multiple binaries and libraries from one project is a pain
Have you heard of Cargo workspaces? Because I've had no troubles with it.
> I think `gcc app.c` is way easier than using cargo
Agree to disagree. Because really soon, you'll want to manage dependencies.
C & Rust come from different eras of easy-getting-started, IMO:
C - I just want to get shit done, I'm not taking on any dependencies, I'll just write it myself and sure it won't be the best but it'll do what I need and keep it simple;
Rust - I just want to get shit done, surely there's a lib for this and that, I can just glue them together.
So with Rust that's no harder to do than doing anything at all; with C it's quite a bit harder but also a bit easier if you don't.
Agreed that's not going to hold any weight in deliberating switching a million line project, but I do think it matters what hobbyists/spare-timers are using, what people want to work with, etc. Slowly.
(E.g. my day job is mainly python; if we needed something highly performant or embedded or whatever I'd be way more comfortable in Rust than ropey university-C.)
https://doc.rust-lang.org/cargo/reference/cargo-targets.html...
Then add configuration options for conditional compilation, and a build system to define them properly.
Then use the configuration options of your dependencies in your build system.
Finally, repeat this process for every project and make sure you use the same syntax/api for your build system so you don't have to relearn everything everytime.
cc main.c is as easy as it gets when you rewrite everything from scratch.
cargo is as easy as it gets when you want an ecosystem.
Most software have dependencies that should be managed, linked in, figure the header file path of etc. Most software consists of several files which you don't want to re-build every time you change just 1 file (unless you change compiler flags etc.). It's a very tiny step from your example until the C or C++ toolchain becomes far from easy.
How do you mean? Where?
[1] just for reference, 0.1 was announced 2012, 10 years ago, 1.0 was announced 2015, 7 years ago.
In the case of Rust, at least they made safety a thing to hang their hat on. As an competitor, how do you "out safety" Rust?
Golang carved out a nice niche for itself, and the involvement of one of C's original creators and Google backing it up sure did help out. And Golang has ignited a group of its own alternatives like Odin and Vlang.
Not sure where Hare can find a niche that isn't already occupied or how it's going to make people want to jump ship to them.
Rust is still not totally safe. There's quite bit of code out there that needs to be panic safe, run within a statically-sized arena, be guaranteed to always terminate/progress and so on and so forth. None of these things are ensured by Rust at present (and common language features like arbitrary function calls get in the way of them), while Ada/SPARK and the like at least make some effort to guarantee those.
But I don't "get it." Why would I choose Hare over plain old C? What are the motivating features of the language that make it "worth it?"
Remember: It's a pretty big hurdle to write something in a lesser-known language. If I had to convince a team of developers to choose Hare over C/C++/Rust, what would be the argument in Hare's favor?
It wont run because the QBE compiler doesnt have bindings to those OSes. Only x64.
Hare doesnt support Windows, so it will never rise to the level of C, Rust or Zig.
It just confirmed my initial thougts about this language. "A better C", for the people who respect it's ideology.
It's true that C++ is almost a superset of C, but most C programming idioms would be discouraged in C++.
As for Java - it's a whole different kettle of fish. Intended to run on a virtual machine with opaque high-level abstractions usable by your program; nothing like C.
(I don't know ObjectiveC enough to comment.)
And does the job well at implementation-defined int size and a char = u8 (there is a rune type, so why bother?)
Clang tidy[0] contains 67032 LOC from my calculations. Rust, Zig, whatever comprise millions LOC. Imagine if 1/10 was contributed to static/dynamic analyzers for C/C++ instead.
[0] https://github.com/llvm/llvm-project/tree/5da7c040030c4af72d...
This path is not constructive. Maybe instead of trying to be original, we can learn from mathematics where theories remain valid for thousands of years.
That's a pretty harsh and ignorant statement.
Those repositories made developer experience much more enjoyable than the mess that is the C/C++ ecosystem.
All the package managers I've used have pros and cons, including using none at all.
Pypi is a mess. Python packaging is a mess. I would rather download and include Python source code by hand than learn all of those 3rd-party packaging "solutions".
The only saving grace Python has is it's vast standard library. So you don't have to reinvent wheels all the time.
EDIT:
Oh, and the C bindings, too.
I understand not wanting to deal with the hassle of running a repo, but what about tooling around decentralized git repos? I can’t imagine distributions picking up Hare packages in larger numbers.
So now instead of packaging a library once, you need to do it for every possible distribution?
https://drewdevault.com/2021/09/27/Let-distros-do-their-job....
This plays into Hare's philosophy on packaging.
Obviously, C++ set the precedent and people are familiar with it. But if you're starting a completely new compiler, why make the same old mistakes with syntax?
A lot of languages made a mistake of using the dot for both scopes. You get used to it.
Not if you've swapped : and ;, like I have!
I think any new language (including Rust, Go, Nim, etc) that wants to displace C should not be trying to fix C's biggest mistake, it should be trying to replicate C's biggest success: simplicity.
Hence the growing popularity of Go as a C replacement. I look at Zig and Nim, and they look like viable replacements too.
Time will tell.
Every new language should fix every older mistake that can be done "for free", without growing the language too much or complicating things. C certainly has plenty of those.
Fun fact: I've seen more Python projects being rewritten in Go than C projects being rewritten in Go.
Is Go a Python replacement?
What kind of magic is this?
https://harelang.org/specification.pdf
They are a very lightweight language feature which is mostly supplemented by the standard library, e.g. the strings module.
There is an example with freeing of strings in the introduction. Search for strings::freeall.
Inevitably, in the steady state? No
If some cataclysmic event occurs, perhaps with key industry influencers’ involvement? Maybe
https://en.wikipedia.org/wiki/Betteridge's_law_of_headlines
(And so does the article, FWIW.)
How is it that developers feel qualified to talk about subjects they understand so little of?
It's memory-unsafe, so you might as well use C++ instead, or if you want a "newer" language, then use Rust instead.
All(ish) code used to be written in C and shell. To what degree had eg JavaScript replaced C already? I think quite a bit.
I don't understand the "static typing vs type inference" argument, so I'll not comment on that :) (there are plenty of statically typed languages with type inference)
"Pointer" types could just be library-based and architecture-specific. It doesn't really need to be part of the base language. This would make it easier to support things like GPU-bound code where general memory addressing isn't really a thing, or other features like multiple address spaces, segmented memory or the CHERI memory tagging extension.
1. You don't need to engage with the community to use a programming language
2. The guys "ruining" conversations are a (loud) minority, most of the people I've talked with are light years away from proselytismlol "moral crusaders" who want software engineers to take a modicum of responsibility for their code