BeefLang will report leaks as they occur, not when the program shuts down. There's a tracing "GC" in debug mode for detecting unreachable memory in realtime. It's also used for reliably detecting use-after-free since memory is held when there are references and released when the last reference goes away -- again, a debug-only feature.
This is totally possible with custom allocators in Odin too. You'll be surprised by how much custom allocators can do, but so many people know little about them.
Thanks for the mention, Gene. Thanks for being an early adopter, and keep those bugs and feedback coming in!
As far as performance vs C - there's not a lot of features that incur dynamic dispatch: virtual method calls, dynamic casts (as/is keywords), and direct interface dispatch. When you use interfaces as generic constraints, those monomorph into static dispatches unless the implementing method itself is virtual.
For C-style code, however, the performance should be the same as the C equivalent in Clang. File a bug if it isn't!
Also, to be clear- the custom GUI library that the IDE uses is NOT a general-purpose GUI library; it is a support library for the IDE and other BeefLang tools. A true general-purpose GUI would be quite a lot more flexible and also much more complicated... which is not something that is intended for this particular GUI library.
I did eventually find that notice in the documentation, after I posted my comment (and sent you an email). I should have read more of the docs first.
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?
1) VSCode was not able to accomplish the development experience I wanted, but I would certainly support a BeefLang language server for VSCode (and other editors/IDEs).
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.
Thanks. By c++ integration support I meant able to use C++ headers and link to C++ binaries.
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.
Seems great - I'll copy as many good ideas as I can. The root goals are very similar, but some issues in preference have resulted in very different approaches to meeting those goals.
Thanks for the checking out the language thoroughly, that's appreciated.
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?
It's as fast as C, since anything you can express in C can be expressed in BeefLang.
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".
Hm- maybe your experiences are different, but for projects I've worked on, the game state is way too complicated to be usefully inspected and manipulated with a REPL. Especially if you are doing any sort of data-oriented design such as SoA or ECS.
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...
This is correct - P/Invoke is not required because all interop datatypes can be expressed in BeefLang, whereas C# does not allow certain types of datatypes in structs (IE: pointers to structs, statically sized arrays).