Show HN: Beef, a new performance-oriented programming language
github.com
github.com
Before Beef, I was developing game code in C# and engine code in C++ and I felt C# was just much more pleasant to work with - faster compile times, better IDE tooling, better errors, etc. Then it struck me that none of the things I liked about C# really had anything to do with the JIT or the GC, and it may be possible to create a "best of" merging between C# and C++.
I know there are other "C replacement" contenders out there - the differences are probably best explained through Beef's specific design goals listed at https://www.beeflang.org/docs/foreward/
EDIT: i think you need to add some information about which systems exactly are supported, especially for Windows where not everyone is running the latest version.
Also what about backwards compatibility? It might be too soon considering a 0.x release but how often does the language break existing code and what are the plans for after 1.0? No break at all no matter the cost, breaks every major version, total breakage regardless of version, ?
This makes the maintainers' job a bit harder, but not by a lot, and as a user I find it a nice medium of stability and progress.
1: No users: infinite flexibility
2: "Small" userbase: changes produce grumbling, community adjusts over time, old code is successfully forgotten (deleted + no nostalgia)
3: Very Large™ userbase: even TNT won't change the language
Each of these is relative: (3) has happened with Python (famously explosively), Rust, Go... and also Lua, awk, FORTH. Language size ("volume") seems to have no impact; once a language becomes known for a certain way of doing things beyond a certain scale, trying to go against that (even as the language creator) will land you in a strange, undefined uncanney valley that's not precisely un-idiomatic, but... everyone will still try and steer/corral/etc you back to the "established way".
Obviously (2) represents the perfect ideal here. (Well it wins by default, since (1) is socially depressing :) )
So, one approach could be to try lots of ideas (at a pace that keeps up the creative energy to enjoy the effort) early on.
The key in this case seems to be figuring out the magic threshold point where the community is
- large enough to provide constructive feedback and help the project substantively grow
- small enough to stomach fundamental, relearn-everything-you-learned, changes
- cohesive enough not to be disbanded by the impact of said changes
and carefully ratelimiting publicity and knowledge spread to control ecosystem growth, in a way that does not rein it in.
The dynamics of what defines this balance seem to be specific to each project.
Currently the examples are buried multiple pages into the documentation, making it harder to evaluate the project at a glance
They have a nice little dropdown in the top corner, right there on the front page, that lets you see little code snippets. I really like that.
Should slightly more accessible code snippets have any influence on my choice of language? Probably not. But I like it nonetheless.
Is love to see a presentation on it.
I'm really enjoying this renaissance of "C replacement" languages like Beef, Jai, Zig, Rust, etc. It would be cool to have a table comparing them all, hyperpolyglot-style.
Also you reminded me that the Insaniquarium Screensaver was the original cookie clicker.
Some questions and feedback:
1. Did you start this project at PopCap and if so, are any of their games developed using a version of Beef? Do you know of any other games developed with Beef? I looked around the site but couldn't find any such information.
2. How would you use Beef with popular game engines like Unity or Unreal? Or is this language mainly intended for engine development as opposed to game logic?
3. Given the focus on developer "ergonomics" if you will, while retaining high performance execution characteristics – are there any representative benchmarking examples where you can showcase both great performance and "nicer" code?
Regarding that last question, a representative example in my mind might be something like a small raytracing engine. Something sufficiently complex that performance matters, but stils simple enough that someone familiar with the domain (and, presumably, a counterexample language like C++) could grok the Beef code and see the benefits in a show-me-don't-tell-me kind of manner. What do you think?
2) This is intended for both engine development and game logic. Using alternate languages with Unreal or Unity is nearly impossible at the moment- likely Rust will make inroads there before BeefLang.
3) Good idea.
- since you're using LLVM behind the scene, how do you manage to have low compile time ?
For a clean release build, however, LLVM will dominate the compile time as expected. Compared to C/C++, however, there is less duplication of ODR'd code (ie- methods defined in headers such as template methods) and less debug information duplication so backend time is lower.
Since you are working on debug-specific backend, have you considered Cranelift [1]? In case you never heard of it, it was especially intended for fast codegen (because it's being used to compile WASM in Firefox), and Rust wants to be able to use it for their own debug build. If you were aware of it and decided not to use it, I'd love to know what are your rationals.
just wanted to give a shout out to you & JV. you guys had a lot of influence over a generation of ARCers, some of which still play games together. so, thanks, and cool to see this from you. I will check it out and show my engineers
JV just texted me the other day to pitch ARC VR actually. He went the VR route, founding Pluto VR after PopCap.
Anyway- let me know what you think of BeefLang!
Would that have been one of you too? Those were gaming glory days for me, with limited forums for discussion and everyone gravitating to what there was. You got to rub shoulders with some pretty cool people, digitally speaking.
Also, how weird is it that the public net has been around long enough to ask things like if we met on the internet 25 years ago? My mind still reels.
She also may or may not have had a serious addiction to Bejeweled.
I had forgotten about that for so long, thanks for the childhood memories.
Kind of curious about performance benchmarks vs C# and C++. Did you post that somewhere?
A hint from a "professional": It would help a lot if you'd give a single-paragraph positioning in the field of PLs. In your case at first glance it looks like "first-order (?), monomorphic(?) nominally typed, strictly evaluated, object-oriented (?), ahead-of-time compiled, with a context-free syntax and no (?) macros." As you can see, there are a lot of question marks you could answer ;).
I'd be interested in more information about the IDE crash.
Better yet, turn it into something that others can use easily by configuring things like the server to which send the reports.
I did this for SumatraPDF (https://github.com/sumatrapdfreader/sumatrapdf/blob/master/s...) and now I think it's a must for writing desktop software that runs on other people's machines.
A shockingly low number of people report crash reports.
I know because I show a message box telling them to submit a bug report for a crash. I get plenty of crashes but no bug reports.
The IDE is maybe one of the nice/important aspects of this project, but then this really should not be Windows-only. Or maybe that are your priorities, but then I would not expect that it gets much adoption outside of the Windows world, but maybe this is ok for you.
I would suggest adding LSP support as a future todo.
Ps. If you're still looking for worthy features, might I suggest f#'s units of measure [1]? They are enforced by the compiler and stripped at runtime, so they are fairly simple to implement.
[0] https://www.beeflang.org/docs/language-guide/datatypes/
[1] https://fsharpforfunandprofit.com/posts/units-of-measure/
Compile times were a big issue, and the little edges of the language and libraries were problematic since they were built around a JIT. Then it struck me that I don't really care about the JIT, and the reason I liked C# had nothing to do with the GC, and it would be much better to just make a slight variation of C# that was statically compiled and without a GC.
I just followed along all the obvious next steps from there, and here we are 5 years later.
Please don't call inline functions mixins; that word has an established meaning in OOP.
Even if Beef supported class mixins, I would say "there's class mixins and method mixins". D does something similar with template mixins vs a mixin statement that compiles strings as code.
Golang provided:
* a tour of go + go playground to allow easy testing of the language + immutable sharing links
* effective go to explain how to use the language beyond the syntax/grammar
* strong opinionated choices on things that dont matter (go fmt)
* a strong opinion about non-breaking changes in the language + stdlib
and a number of other things. IMO a language is only as good as it's community.
- the immense success of docker based on it which made everyone build their devops tools in go (kubernetes helped too later)
- a very solid and stable http library included in stdlib (plus other networking goodies to easily run your own ssh endpoint in a few lines of code)
tl;dr to get your language some traction, make it solve at least one problem much better than the competition and have someone build a super popular open source project on it.
So a decent package manager would do wonders. Rust has Cargo which does builds and packages. D has dub as well.
Definitely recommend making code sharing / reuse a breeze.
Is there any possibility that you'll include some efforts towards doing back-end networking with this language as well? I could see multiplayer games needing servers after all.
PS: There's a typo in the Design Goals list - "Compliled (no JIT delays)"
This also seems pretty damn polished for it being the first time anyone publicly has gotten a look at it. I mean, a full IDE on day one is nuts.
I know Beef seems sharply tuned for game dev (another hobby of mine), but do you see Beef as being usable for general purpose systems/application development? Is there anything about it that would discourage its use for a standard desktop GUI app? And because I'm curious and haven't seen this answered elsewhere, is the Beef IDE also written in Beef, for some tasty beefy dogfood?
edit: Nevermind on that last question, I found it answered in the guide (in the affirmative). Nice!
Complete lack of accessibility support, particularly for blind users via screen readers, in the included GUI toolkit. Please don't use this for any application that people will be required to use in their job or education.
This is mentioned on https://www.beeflang.org/docs/corlib/ but should perhaps be more predominantly stated.
Still, I wonder why you chose to write your own GUI just for the Beef IDE (and installer) rather than use an existing general-purpose GUI. Were you aware of the accessibility issue?
How do you solve the IDE features ("fast and trustworthy refactorability (ie: renaming symbols)") in the presence of conditional compilation?
btw your name is an anagram of "beefitrian"
It's true that symbols in 'false' preprocessor blocks will not be caught. Maybe it's best said "if the compiler will find the symbol when you compile, then the symbol renamer will find it when you rename". Which is definitely not true for most symbol renames I dare to attempt in C++ IDEs.
I think starting with an IDE from the very beginning was a smart move.
For what it's worth, here is my current vaporware plan to solve this problem: https://github.com/ziglang/zig/issues/3028
I would be curious to see your thoughts on this, especially if you end up trying to tackle this problem in Beef.
They probably want newcomers to try a release, and if intrigued, clone the repo and stay current.
A shorter release cycle wil mean that folks will get new stuff/bugfixes faster and that Zig will get more mindshare in return.
Asking the tough questions here.
Keeping with the animal theme here
There's future plans to add more high-perf sugars like automating some SoA and AoSoA layouts, but you can do all that manually right now.
Also it would be awesome for you to make a few code samples / tutorials on how to get started with game development with Beef. I'm sure it would attract a lot of people to your language if you show some "proof" it is a nice language for gamedev!
It's tempting to give this a go, but there are so many languages out there... Maybe I'll try a Ludum Dare in it.
Also identical to Swift or C# (the latter being an explicit inspiration according to TFAA comments upthread).
I am sorry to see semicolons though. I have never missed semicolons after moving to languages where they're not required, and it's always a bummer going in the opposite direction.
I wish you luck!
For someone looking for a C replacement where memory safety is absolutely critical (ie- open server applications) then Rust may be a better fit.
Is there any evidence this is a tradeoff? What of linear types?
Bound checking often is the reason rust performs worse on some benchmarks. Though I wouldn't consider this a problem at all since it can be disabled.
The more important part of memory safety is preventing out-of-bounds accesses. Rust, Ada, and (it seems) Beef sacrifice performance for memory safety here by having runtime bounds checking. (Though there is not much performance cost to this and all of those have options to turn off runtime bounds checking anyway.)
The only performance-oriented language I'm aware of that is fully memory-safe at compile time is ATS‚ via a combination of linear types and dependent types, and using ATS is… cumbersome.
Its not all black and white though. Using iterators, bounds checks can often be elided by the Rust compiler.
https://www.beeflang.org/docs/language-guide/safety/
> Leaks can be detected in realtime with the debug memory manager. Reachable memory will be continuously traced at runtime and memory which is no longer reachable but has not been properly freed will be immediately reported as a leak...
Sounds like it doesn't have a Garbage Collector, but a "Garbage Detector" that's only active for debug builds?
Also, testing helps detect bugs, but cannot guarantee security.
One may say "then why not just make the GC optional like D", but when you design a library you really need to either design it for a GC or for manual memory management. Even for the basic string type - if Beef was a GC'd language then String would be immutable, but it's not so String is mutable. Totally different designs.
He's probably got enough runway for a couple centuries..
At a glance I don't have any other major remarks. It looks very much like it's on the same general trajectory as Zig, which is probably a good sign that that design space is in the right ballpark for low-level real-time systems. There is some attraction in having automatic memory available for application-level tasks with more indefinite boundaries(editing tools tend to develop compiler-like qualities which in turn creates a need for more introspective style), though it's probably outside the scope of this language and might be suitable for a scripting-layer approach instead.
The concurrency model is, like C++ or even C#: sequential consistency for data-race-free programs (SC-DRF). No green threads or anything crazy, no 'message passing', just normal system threads, normal locks, you control how you access memory yourself. You do synchronization just like you'd do in C/C++.
I would appreciate it if more languages had something like ucontext_t or byuu/co, because I don't enjoy tagging every call site with "await" whenever I change a method to do something that might consume some time (and every call site of those functions containing call sites too, and so on), and because I do enjoy being able to write code that uses speculative execution (like for time-travel netcode for a 2d fighting game) without manually converting all my imperative code to a state machine like a compiler should do.
I am a bit of a snob, maybe, but I've come to think one of the bare minimum features for any language is copyable coroutines.
C++ makes a lot more sense: the type declaration is not coupled to specific allocation patterns by default, which to me is a lot better choice than structs and classes ala D.
The real question is how fast an idiomatic expression of an identical complex program is in both language. Well, that might not even be the question- it may be more like "if presented with a problem that requires writing a program, what are the characteristics of the solution to that problem if the language chosen is X vs Y". Maybe?
Anyway, I don't think anyone has figured out how to properly compare programming languages yet in that way other than "try it and see if it works better for you than other things you've tried before".
More examples:
https://benchmarksgame-team.pages.debian.net/benchmarksgame/
The ideal case is for an engine such to embrace Beef and work through those issues.
Chucklefish was an early(ish) adopter of Rust and tried to maintain an XBox/PS4/Switch toolchain but eventually abandoned it. Rust is probably a good example of a popular "alternative language" that may pave the way for BeefLang and others to work their way into those spaces.
> The issue of how to interact with the hardware itself and how to participate in the toolchain provided by the console vendor is much more difficult and is outside the scope of the language/compiler.
I've been looking for a language that would allow gradual transition from C++ for example. If you have a C++ SDK, you could still write your whole engine or just some modules in Beef.
If you do have more control then you're in a much better situation, but crossing language boundaries can still be tricky.
Generally you end up having to write "wrapper" code to make those language boundaries palatable. There are code generators like SWIG to handle those things, and some languages like Zig handle importing of c headers, but if the C++ library your trying to use is returning a std::shared_ptr then that's not going to be a very pleasant construct for you to attempt to work with in any language besides C++.
If you can split your code sections into simple and clean C-like interfaces then the job becomes much, much easier.
Best of luck, looking forward to following it's progress!
Like he had complaints about other languages, and instead of moaning about them on the internet, he went out and made his own language.
Even a few code examples of some language features right there in the README would go a long way
[0] https://store.steampowered.com/app/1009960/Project_Hedra/
For us to pick up a new language and potentially use it for work, I need the confidence that this language is going to stick around and have a user base.
Go and Rust benefitted from being backed by Google / Mozilla.
Whereas, Beef doesn’t even have a corresponding game engine. Have you thought about you will grow the language usebase?
Questions:
1) Why your own IDE and not VSCode or something?
2) Can you tell us how this varies from Rust in terms of practical applications?
3) C++ integration support?
4) MacOS?
I really like your pragmatic ethos on this, it looks like it was designed to be used not talked about.
2) Like C, BeefLang idiomatically allows certain types of safe data patterns that the Rust checker would disallow since they cannot be reasonably statically proven to be safe. If you want to conform to Rust patterns then use Rust. If you don't, then BeefLang is another choice for you.
3) Do you mean if the IDE supports C++? It used to support Clang autocompletion and such, but it just wasn't anywhere near the quality of VS Intellisense so I just took it out and I still use VS for C++ editing.
4) Command-line compiler only.
This is really a great project, very pragmatically oriented, I wish you well. It's hard for any new language to gain momentum without underlying platform buy-in (i.e. Kotlin became 'a thing' when Google adopted it for Android). But I hope you can find an angle.
There are quite a lot of other complicated factors such as "what thread does this run on?" and "when?". When you are debugging and hit a breakpoint then you basically have a REPL in the Immediate window...
A small suggestion to rename the language to "dogmeat" instead to align even better with your meat logo. Filename extension could be ".dm".
Also love the example game. It's written so cleanly that I learned a thing or two about 2d gamedev just from scrolling through the code.
I love the little pragmatisms in the language, eg:
for (let entity in gGameApp.mEntities)
{
if (let enemy = entity as Enemy)
{
// .. do something with each enemy
}
}
That if/let/as combo there is something I'd have loved to have in many languages.Also hats off for switch/case without break. Finally! I also love how you're mixing C/C++ "global enum value names" convenience with namespaced safety:
public static Result<(char32, int32)> TryDecode(char8* buf, int bufSize)
{
...
return .Err;
// not Result.Err, because the return type is given in the signature
}
I know that these little syntactical things are not the key challenges of language design, but obviously they're the first things I see, and I like the amount of attention you've given them. You really only have the opportunity to get them right at the very beginning.I think the docs are a little sparse still (but that can be expected, of course). Eg:
- I found it hard to parse this:
public Random mRand = new Random() ~ delete _;
There's docs about it here https://www.beeflang.org/docs/language-guide/datatypes/initi..., but the "delete _" part isn't really explained. What's that underscore? I can infer that it probably means "this value", but I can't find it back.I love that you made it easy to destruct fields like that, right there in the initializer expression, btw. Will probably kill the need for 90% of destructor methods out there.
- Apparently this converts floats to ints:
(.)(mX - entity.mX)
Or at least it does in HeroBullet.bf:15. I'm thinking maybe this does something similar as `.Err`, in that the dot makes it cast to whatever the expected type is in the function being called? I'm not sure though, it looks like a super powerful feature, maybe :-)Finally, I believe .bf is also used for that other super convenient and performant language, Brainfuck. I doubt that causes any practical problems, but then again, why not just .beef?
With "delete _", you are correct, the "_" refers to "the value in question", which is mRand in that case. When you have a switch statement, the "_" refers to the value being switched over.
The "." type is a special type meaning "the expected type here". So that's explicitly casting to the expected type, since an implicit cast from float to int is not allowed.
And yes, my apologies to Urban Müller for overloading his file extension, but it seemed the chances of that actually being a problem for someone were acceptably low and I really really preferred ".bf".
Come to think of it, this is an excellent opportunity for even broader interop! Just make the compiler parse any series of, say, 5+ consecutive !?,.+-[] characters not as a parse error but a Brainfuck expression! What could possibly go wrong?
Wrt the "_" and the ".", if those are documented at all, maybe make the other sections in the docs (eg the one on destructors) link back to there. I didn't read the docs from top to bottom, instead preferring to refer to them when I saw code I didn't understand. I bet I'm not the only one that likes to learn like that. Note that everything I write here is intended as a friendly suggestion and feel free to ignore all of it. I'm just a random guy from the internet.
Finally, wrt casting: I've always found that C-style "(type)" casts are weird and messy and don't fit the rest of the feel of the code. I wonder why you took them over? You also have "as" for dynamic-casting, and personally I think those are a lot more readable. Did you consider stealing some ideas from Kotlin and TypeScript wrt this to unify the two? Let me know if I'm stepping over a creative boundary here, but I'm personally quite mesmerized by Kotlin's !! operator[0], which simply forces a value to be not-null and throws otherwise. That's essentially what "(int)foo" does in Beef when foo can't be casted to an int, correct?
Then, if Beef had such an operator, then prefix casts would be semantically equivalent to "(foo as int)!!", right? Or maybe even the super-nice-on-the-eyes "foo as int!!" if precedence rules allow. Obviously a naive compilation of that would be slower (a dynamic cast followed by an if-null), but it seems like a pretty simple optimization to add.
Maybe "foo as .!!" could even be shortened to "foo!".
Given that you have int? and ?? and ?. already, I could imagine you considered something like this already and decided against it? Sorry for the rambling :)
Again, great job! Really looking forward to playing around with it more. Still totally blown away by the completeness of all this. I can't understand how a single person can pull all of this off on their own time.
I was a bit puzzled by the SDL2 wrapper by the way (SDL2.bf) - I can't find any place where it refers to a .lib or even a .dll file. How does this work? I tried to find a Visual Studio-esque "project settings" screen with deeply hidden list of .lib files but to no avail. How does Beef know where SDL is?
[0] https://kotlinlang.org/docs/reference/null-safety.html#the--...
Generally that would mean: - More static, less dynamic - No GC - Lighter abstractions - More directly conforms to hardware (even when it create a 'less clean' interface)
- no exceptions
- mutable strings with optional pointer access
- no GC
BeefLang had an IDE on day one, and I think it'll show. One of my goals was to show how good a good IDE experience can actually be to someone who is used to working in C/C++.
I wonder what you find lacking in the current C++ experience. e.g. with the IDE I use (QtCreator), I can quickly refactor things across million-lines codebases, perform a decent set of more advanced refactors (https://doc.qt.io/qtcreator/creator-editor-refactoring.html), auto-generate boilerplate code, I get in-line hints, lints and warnings while I type all with clang-based auto-completion...
- It still can't handle most of the CMake projects.
- Refactoring/autocompletion/go-to-definition doesn't work on a heavy-templated code.
- Clang must be patched to work correctly (at least code analyzer doesn't work out of the box).
- Code generation sometimes produces malformed code.
- No ANSI escape codes support in terminal/output.
- Random crashes.
IDEA with Rust plugin is years ahead.
I think Rust has the _potential_ to be better, but it's years off and requires the rust community to change how they think.
I'm interested in the IDE due to the authors claims, but I don't really see him making this IDE better than VS + C#. If he can, that would be amazing though.
The said change already happened and Rust devs are currently refactoring in depth their compiler to make it IDE-friendly (taking a lot of inspiration from Roslyn). This is tons of work though and even if it's currently going well, it won't be there before next year.
See this talk if you're interested in this kind of things: https://m.youtube.com/watch?v=7_7ckOKZCJE&list=PLgC1L0fKd7Uk...
* pun obviously intended
I think when rust tooling gets "there", it's going to be able to do some really cool things that no one else can do.
What I want is a Lisp with Python-level libraries.
Clasp implementation of CL would be another choice, it leverages LLVM for compilation.
The problem is with the library and tooling ecosystem.
Now, you may say that "performance-oriented" doesn't have to go as far as SIMD or caching tweaks. And that's true. But if you want a performance-oriented language that can reach all the way up the performance curve, I don't see it being Lisp.
As someone desiring a performance-oriented Lisp, this is something I'd like. At runtime, I can handle memory myself ($deity knows I often do that when writing performant code). What I want to have is the friendly, homoiconic Lispy syntax, the ability (and the ease) to write code that writes code, and perhaps to have these facilities available at runtime.
All I can think is "beef begins to smell after a couple of weeks" and it's hard to overlook that mental imagery when evaluating the vast array of good options in the programming language space.
It may also be considered culturally insensitive to a noticeable percentage of software engineers, which could hurt the adoption rate.
Everyone has their opinion; If the author does not consider it culturally insensitive, then there is no problem.
I think there may be a hidden benefit in pre-filtering the community for "developers who flip their shit over naming"..
The author can do what he wants, but if he wants adoption, then it would behoove him to consider cultural sensitivity, especially if it is offensive to enough people to stifle adoption.
Arguing over meat-related naming is exactly the kind of "alternative viewpoint" I have no time for, i.e I would say it's completely wrong.
Many can play at this game.
If so, I belong to the culture that considers it insensitive to shit on things for light-hearted naming themes as if they are of any relevance next to a million other adoption metrics that are more objective, assuming the author even cares to weigh adoption vs creative license in the first place.
That's totally unfair, but it's how people work.
If no, it has no effect,
If yes, then either you didn't care much in the first place, or you are indeed, flipping your shit.
And no one said it was a bad name, but that it could be considered culturally insensitive - two ambiguities away from actually being the thing it might considered to be.
Would "veal" be an acceptable name?
When I think of eating beef in 2020, I think of a person whose freedom to eat whatever pleases them is more important than human health, suffering of intelligent animals and the environment.
Allow me a bad analogy. If I interviewed someone for a senior engineering role but they went out of their way to mention that they had named one of their children "Stalin" -- that would be kind of a red flag for me.
So to me, naming your pet project "Beef" is kind-of tone deaf at best.
And at worst, it's thumbing your nose at political correctness: "Haha I named my project Beef because beef is great and fine and if you disagree you're thin-skinned and blindly following the crowd."
I think the issue is a lot more complicated than that.
Just my admittedly-biased two cents.
I'm Vegan and the name doesn't bother me at all to be honest. I do not agree with the downvoting of parent though, as his reasoning is er.. reasonable.
Is it? Was the question about how acceptable would "veal" be as a name implying that it would not be acceptable at all? What about “lamb”? Or “pork”? (PORK is the long-awaited Well-Done BEEF, according to https://www.cs.cmu.edu/afs/cs/project/ozone/www/object-syste...)
By the way, there is also https://beefproject.com/
This complaint makes the top 3 comments on every post about a new programming language. It's tiresome.
But I also have to say that the name logo are... offputting. I don't know why exactly; I'm not a vegetarian or religious or anything like that, and the name doesn't bring anything negative in particular to mind (hell, I love eating beef!), but it just feels... wrong somehow.
I really don't think that many people would make that connection.
Is C# culturally insensitive to deaf programmers?
Four, now that it's a programming language.
> which has been built hand-in-hand with its IDE environment
This is a red flag for me. What this implies is that the design of the language is likely heavily based on the expectatio that it will be used with the given IDE.
Basing a language on C and C# in 2020 seems like a very uninformed choice to me. Sure, C is a great language, and C# is very successful, so they must be good right? But I suspect that line of thinking is also what made the languages as successful as they ultimately became.
In a world where even javascript treats 0 as false, because it's what C did, whenever I see a programming language doing things "the C way", I just assume it's cargo cult language design, because most often that's what it is. That's not to say that there can't be good reasons for doing things the way C did them; after all, C did most of them for a good reason.
As for the C# part; other than it also falling into the cargo cult language category that copies C without understanding C, I don't really like it's idea of object orientation (which is really just javas idea of OO with a fresh coat of paint). What syntax it copied from C is acceptable, but tell me a modern language that doesn't have somewhat acceptable syntax. Even functional languages don't look like lisp anymore (except lisp itself, of course, which makes up for its inconvenient syntax with other advantages).
Anyone who makes a language that is not like a popular language (ex C or C#) should have to do a lot of justification for it, not the other way around. Change for change's sake is bad.
In other words, if you can make a language that does something new, without having to have new syntax or paradigms, that is much better.
Of course; but that's expected. My point is that this always applies, but sometimes "C does it, so I'm doing it as well" is treated as a good reason for things when it really isn't.
Javascript, for example, treats 0 as false in if conditions. This made sense in C, which had no dedicated Nil-value and used the Nullpointer for that purpose, so 0 meant both the numerical zero and nil.
Javascript, however, has a dedicated nil-value, so 0 really only stands for the number zero, which isn't any less a value than any other number, and thus has way less reason to be treated as falsey.
So, in this example, while C had a good reason to do a thing, that reason just doesn't apply to JS. Maybe there are other good reasons that do apply to JS, maybe they just did what C did without thinking, maybe a bit of both.
But it does underline a opint: There should be a reasoning behind every language decision; one that specifically applies to the language in question. And I do believe this isn't the case with many C features.