Is it possible to develop at a low level without assembler, C, or C++?
For example, develop a graphical controller using the Red/System programming language.
It is possible, it will depend on the technical skills and knowledge of the language, there are several languages ​​for low level, but few have a good balance between low level and ease.
Is Red/System on Haiku yet? One challenge with an operating system being written in C++ is the name mangling scheme. The parts of the OS that aren’t POSIX syscalls need wrappers if they don’t use the same mangling system as C++.
If you’re calling C++ API functions, yes. I don’t know what “graphical controller” means, and no idea what the idea is here. If you just need to make a few specific calls into the API, the wrappers shouldn’t be real hard to make, but it quickly turns into a big project when a more significant part of the API is to be exposed - virtual hook functions, function overloading, concurrency (BWindow threads) etc. I’ve been there because I like to program in Ocaml, and where it’s about the API itself - for example a program that’s real heavy on interface kit - even for an Ocaml enthusiast it would be a whole lot less fol-de-rol to just write it in C++.
It’s not a big deal if the operating system is written in C++ (nearly all modern OSes are partially or fully written in C++), but it becomes challenging when the primary API exposed by the operating system is itself in C++. There is a good reason why no other big OSes followed the BeOS path on that one. And IMHO the language-agnostic API was the idea behind the Binder component that BeOS engineers started to develop for the BeOS 6.x version, and which later landed in Android (where it’s language interop feature is not that important for the app developers as JVM itself allows to interact with the API from many JVM-based or native languages), and then was added to Linux (where nobody really needs it).
So, either you hide the C++ code behind some sort of system interface that allows a seamless interop between the C++ and other languages (like COM in Windows, or Binder in Android), or you expose the C++ API and require app developers to use it exclusively. In the latter case, if the developers want to use a different language, they would have to create and maintain bindings themselves, and currently this is not a viable solution in long term. But… that might change soon, as I’ve just checked and the latest SWIG version released a few days ago has added an experimental support for C as a target language:
https://www.swig.org/Doc4.3/C.html
I don’t think Swig is going to deal with the hard problems here.
- parameter semantics - in
BPoint BMessage::DropPoint(BPoint *)
, is the parameter to be allocated by the caller and written to, i.e. a return parameter? Or is it a value supplied to the function by pointer reference? If you think that’s easily guessed, I think I can look a little harder and scare up a few that are harder, but when Swig is guessing, you have to review all the guesses anyway. When you supply aBMessage
value to aBInvoker
subclass constructor, is it copied or not? If the calling language is reference counting here, you have to know. The include files say nothing about these things. - Virtual hook functions. You can’t use the API interface kit at all, without virtual function callbacks, so there has to be some mechanism to pack a sort of vtable in there.
- Concurrency. if the language has no runtime manager, maybe no problem.
- Function overloads. Which one is
BMessenger::SendMessage
? What do you call the other two?
These aren’t giant problems, they just aren’t going to be solved by a third party like Swig.
Some of them belong to the API. Somewhere the full, rigorous semantics of the API have to be made available in machine readable form. In/out parameters, who’s holding pointers, etc.
The rest is your problem, if you’re making an API interface wrapper. If it’s Rust, you could use some macro stuff to simulate C++ virtual functions, in Ocaml it’s simpler to go with a vtable. Generate interface modules, deal with overloaded names.
So I don’t think it would be worthwhile to try to make some common interface, that would inevitable fail to account for some language’s issues. Just document the API, and let each language bind according to its natural semantics.
I don’t see how some of your questions are relevant to the C++ → C bindings I mentioned in the context of SWIG. Obviously, it’s not a silver bullet and it won’t automagically translate the C++ API into a perfect C17 API. As one has to use an interface definition .i
file to specify what exactly they want to expose, there’s still a work to be done to prepare the input for SWIG and tune up its output, either manually or with a help of a script. But then you have a stable C ABI which you can use from other languages like Swift. That what SWIG does for you: eliminates the need to write or generate all the bindings yourself. You still have to help it, just the amount of work will be magnitude less.
So I don’t think it would be worthwhile to try to make some common interface, that would inevitable fail to account for some language’s issues.
No one suggested that. If you took it from the part where I wrote about COM or Binder, you misunderstood what I meant. It’s obvious that C++ is not a perfect choice for the operating system API as it limits the usage of other languages, it’s also obvious that it’s too late to change the Haiku API from C++ to something else, or add the Binder to it. PulkoMandy once wrote we might be able to add it in R2. Well, it warms my heart a bit, but I don’t think it will change anything, as at the moment all the API is built around the direct C++ calls, and no one is going to change that. Not before R1, and not even for R2 because that would mean a tremendous amount of work. That ship has sailed.
That’s what I’m saying, I don’t see a Haiku C API. My examples Rust and Ocaml – they’ll take significantly different approaches. Swift may have its own C++ interface, Python already seems to have C++ interface packages, as does Rust, etc.; to the extent any of these solutions manage to deal with C++ features in terms of the calling language, than they’ll have a big leg up on a C API.
The best yet strenuous way would be to recreate the API from scratch in the target language leveraging its peculiarities, patterns and types.
@nielx started this with Rust, for example.
Another example could be C#. The bindings created by @trungnt2910 have severe limitations due to the garbage collector. It requires a lot of hacks and it’s not Trung’s fault, of course. Moreover, it would make more sense to use IList<> over BList, delegates over MessageReceived() and other hook functions, DLR and/or reflection plus dictionaries for BMessage, just to mention a few.
Chances are that even if you get a working binding to C++ API, the target language characteristics make it a non viable approach.
By the way … I kind of lost interest in Rust myself, but it’s an example of a language that some things are being implemented in, so bindings could be of real interest at some point, and I did mess around with that. Here’s a piece of my demo application that puts up a window with some views.
#[be_dispatch(BWindow)]
impl BHandler_dispatch for AW
{
fn MessageReceived(&self, msg: &BMessage) {
// print_thread("window MessageReceived");
if msg.what == 20 {
msg.PrintToStream();
let a = BApplication::be();
let _v = a.PostMessage(&BMessage::from(9));
let (p, b) = self.top.me.GetMouse(None);
println!("mouse at {}, {}", p.x, p.y);
println!("box {:?}", self.top.me.Frame());
...
The key point being that macro at the top, that essentially makes MessageReceived
here an instantiation of BWindow::MessageReceived
. I did this almost exactly 4 years ago and frankly don’t remember much about it; nielx seemed to have some objection to the idea as I vaguely recall, but I mention it here in case anyone ever gets serious about this to look at some possibilities.
What I mean about things being implemented in Rust – I basically do the same project in whatever language, an IMAP client. I’m sure not going to do that in Rust, but it’s quite likely that someone will, and then there might be a big enough investment for that application to deal with the pain of a foreign interface to the application and interface kits.
I consider C more like “high-level Assembly” rather than a high-level programming language. As such, it is “ideal” for low-level programming. C++ is a “mix” I would say. The vast majority of low-level libraries are written in C, and this is the unavoidable reality anyone who prefers not to use C/C++ has to face, myself included. What I do for years now is what @VoloDroid mentions above. Whenever I do need functionality available via low-level C/C++ APIs, and when it makes sense, I just create and maintain my own bindings.
Granted, creating bindings means more work, but there is a reason people take that route. In my case, I want to use low-level Multimedia APIs but I want to write my applications in modern Fortran using its high-level module- and/or object-oriented features. The most pronounced reason for this preference is Fortran’s native matrix support and Math capabilities, which are far superior than what C++ has to offer in comparison (C itself has no such features, and third-party libraries made to fill the gap are not really a solution). Others may have other reasoning. For example, I have seen people taking the “bindings route” because they want to use Haskell for its “purely” functional programming nature.
Don’t get me wrong here, I’m not saying C/C++ is bad. For example, I am learning the Haiku API and I’m not planning to make bindings for it… That would take ages even with a determined team. It just doesn’t make sense, I’d rather use C++ instead. But there are other cases where writing bindings does make sense. There is a reason you will find bindings available for many low-level C/C++ libraries.
As for bindings not being a viable solution in the long term, I beg to disagree. I use bindings for many libraries and for years now. I have written several bindings, and the only C/C++ code I wrote was just in the testing phase. Once bindings are done, you won’t find a single line of C/C++ code in applications that use them. Binding just works - and without any loss of performance. Going that route includes applications that run on Haiku as well.
On the other hand, it’s not all “sunshine and roses”. The real problem is when the low-level API you are binding is changing too much too often, because maintaining such bindings can indeed be annoying (looking at you, OpenGL).
I came across Basic for Qt recently. How useful is this on Haiku?
It will be useful for Haiku users who also like Basic and Qt. I’m not in that list, but Basic is still used. Basic is not necessarily interpreted, I am aware of at least two modern Basic compilers maintained regularly. And even if it was strictly interpreted, so it it Python and yet it is constantly at number one in TIOBE index (crazy but true). There is a Basic audience, however small it might be.
Haiku is not just used out of curiosity, or just to play Doom / using LibreOffice in a “niche” operating system. If I were to guess, I’d say most people using Haiku regularly are developers, one way or another. I’m sure some of them might like Basic as well, at least for side projects. We already have Yab, after all.
Yow! I did not expect that -
I’m going to hit the web to see what shows up on that! I started with FORTRAN back in the late '70s, but by the time I had a real job I was pushing C on my colleagues because FORTRAN was way too clunky. I’m sure it still has retained a little of that clunk,but it would be hilarious if it turns out to be like, why worry about Swift, when we can step up to FORTRAN!
What is unique about yab is that it is a straightforward imperative language that hooks into the object-oriented abilities of Haiku. From what I can see here, that is not true of this dialect. You’ll have to bend your mind around the usual OO jargon. That might actually make it useful as a transitional step from yab to C++
But if the website is to be believed, the source code dates from 2012. Will it scale to newer versions of QT?
If @Akakor is looking for an ambitious porting project, maybe Gambas would be better. It lets you make QT, GTK and, at a pinch, ncurses applications from the same codebase. And it is still in active development.
You will be surprised.
Many people think the language was somehow “magically” stalled in the 70s, but the truth is Fortran has been evolved over time, like most other programming languages (even the name was de-capitalized in the early 90s, reserving the capital form for legacy versions).
Gambas and FreeBASIC are the ones I know for a fact they are in active development. I’m sure there are others too, not to mention Yabasic. And I have also seen modern dialects of Basic for vintage 8-bit computers of the early 80s (some are even sold as commercial software for 50-years old computers).
If I recall correctly someone asked for a FreeBASIC Haiku port in this discourse some time ago. But we already have Yab, and it is pretty much Haiku-native (even though it comes from Yabasic). So I doubt people would be interested much on other dialects.
It has been a long time, but most of this is unrecognizable. In the present context, though, the foreign function interface … what I’m reading sounds kind of grim, when it comes to the character string data type. Haskell has a problem with strings, too, in this case because a Haskell string is a linked list of characters, but there’s an alternative packed string type that’s reasonably easy to use instead.
Red/System not yet.
But I found a version of REBOL in the 32 bit repository.
Then once Gambas is ported, it might be an interesting follow-up project to make it capable of building for the BeAPI too. If this is possible, then it could become a great way to create cross-platform apps that have multiple native interfaces with relative ease.
My comment was not about bindings per se, but specifically about a non-automated creation and maintenance of the Haiku API bindings. As you wrote it would require a lot of efforts to build and follow the changes in the Haiku API.