Portability. A C library can be trivially linked with any other language. But one will be hard pressed using a python library form Ruby, for example.
It's fairly rare that you actually need to be in the same process. (The thing I wrote was a wrapper for unshare(), so it did strictly need to be in-process, but that's an unusual use case.) Even if you want to share large amounts of data between your process and the library, you can often use things like memory-mapped files.
And there are some benefits from splitting up the languages, including the ability to let each language's runtime handle parallelism (finding out that the C library you want to use isn't actually thread-safe is no fun!), letting each language do exception-handling on its own, increased testability, etc.
If you're a Ruby application, sure, you can use a Python library by forking off a subprocess.
Just make sure to document the installation requirements - in addition to having Ruby and the correct gems installed, you also need Python (which version?) and the correct pip libraries installed.
If you're a Ruby library, instead of an application, forking off a Python process is a nonstarter, unless you want to propagate those requirements out to every single application using your library.
I'm mostly thinking that if you already have a Python library you really like, chances are you already have a Python environment capable of running it. (The environment doesn't have to be related to your Ruby environment at all! If you want to get Ruby through your OS and Python through a Docker container, or whatever, that should work fine.)
I realized recently that Python could have saved a decade by having a means to "interlink" modules allowing the use of python 2 modules in python 3. Much easier in the C world; there have been incompatible syntax changes and incompatible link changes BUT not both at the same time.
Python has a very rich runtime, so there are some tricky problems to solve if you want this to be perfect. e.g., circular references between the GCs. However, there are simplifying assumptions that can dramatically reduce the difficulty, and these assumptions might not significantly hinder the language-upgrade use-case.
We've known about this approach to embedded interpreters for a couple of years, but we've not found a sufficiently compelling use-case for anyone to develop it beyond a simple proof-of-concept.
In general, it seems like there most compelling use-case for inter-language interfaces is writing core libraries in something fast, (mostly) runtime-free, and portable, especially for codes that no one wants to write twice.
Though I spend most of my time writing codes in slow, rich runtime languages, I've been on the lookout for a better technology to replace C. There are quite a few interesting options, and some have even less of a runtime than (dynamically-linked) C!
Where can I pip install this from?
Or is there a reason that none of the huge numbers of python users delaying their transition as much as possible until all their libraries were updated built it?
A couple of signatures have changed, but the general approach looks like: https://gist.github.com/dutc/eba9b2f7980f400f6287 or https://gist.github.com/dutc/2866d969d5e9209d501a
The above will launch ("embed") a Python 2 or Python 1.5 interpreter from within a Python 3 interpreter. If you use `dlmopen` and `LM_ID_NEWLM`, the guest interpreter will have its own linker namespace. In other words, the guest interpreter (and any DSOs it opens) will be totally isolated from the host interpreter.
The above shows the use of `PyRun_SimpleString`. Since `PyRun_String` accepts a `PyObject* globals` and `PyObject* locals`, you could build a very basic bridge in <30 lines of code by using serialisation to copy and convert. (For user-defined classes, you would need something better.)
I've given a many talks about this at various Python and PyData conferences. (I've mentioned it a number of times on HN, both in response to complaints about the Python 2→3 transition and in response to comments like yours suggesting this solution to that problem.)
Though presented as a joke, the approach could be made to work with some effort. I can't speculate on why no one has ever followed-up on it, and I can't speculate on why the Python 2→3 transition has been so difficult for some users. Perhaps in some places, financial or organisational arguments are more influential than technical arguments.
That's a bullshit argument very close to FUD.
You don't need to know the 1400 pages of the C++ standard to use safely a subset of it. Specially with proper tooling to help you.
Do you really think that every web frontend developer knows every W3C/ECMA standard every time they create a website ? Or that they have even an idea of feature the complexity of the Web browser they use. One tips: no they don't.
Most importantly, if someone does find a way, it's an error in either the spec or the browser implementation. It's not flagged as "undefined behavior" and we go on with the assumption some web pages just break your browser or the OS hosting it.
I can tolerate a thousand-page spec for a system that can't crash unsafely; it's a much bigger risk for one with unchecked pointer indirection as a feature.
This is a narrow view where you focus only on memory safety and buffer overflow. Undefined Behaviours goes way wilder than that.
Many problems coming by UBs do not goe into any crash, just wrong results and wrong behaviour which is something even worst.
And currently, JavaScript is full of that. Almost everything that JS can not handle (or do not know how to handle is undefined) or purely implementation specific.
There are circumstances where you want the features C++ brings to solve a problem. But solving a problem with dynamite is still solving a problem with dynamite; there's a lot more ways it can go wrong than solving the problem with a steam drill, to torture an analogy a bit.
Excepted that a language is not absolute, is not dynamite or not dynamite. It is what you do of it depending of the subset you use. C++ is not exception.
... which goes back to the topic of the HN post; that's only one way to look at the state of a running program, and it's a way that has strengths and weaknesses. The utility of it comes at the cost of the program failing in ways programs in other languages structurally cannot fail (unless you do something truly exotic, like implement a subset of a C++ compiler or interpreter in that language).
JS is ... well, JS
This is at least for me the first time I've seen them discussed in the same breath, which is revolutionary: C++ the language bringing a blue screen to a desktop near you; JS the language bringing your startup to its knees.
I guess I never realized that while they are polar opposites, there are probably some subtle cultural similarities that would make for some hilarious unearthing
To be fair, that contains both language documentation and library documentation. The language specification portion itself is only ~400 pages, which is smaller than the Java Language Specification and JS's specification (both about 700-800 pages, although JS does include its [meager] standard library in there).
I did that over 20 years ago and have never looked back.
I manage a c++ team btw. Our app has to be fast.
Still, have you guys looked at alternatives -- and seriously evaluate them? Rust, Zig, Nim, D, others?
If you tell me "we can't afford to, we have too much work" then that's also a valid answer (for a while at least).
C++ alternatives still need to grow up to this kind of mixed language development, where I can have .NET code with C++ libraries and easily debug across them on the same Visual Studio session.
Same applies to Java and C++ development experience.
F.ex. when coding in Erlang/Elixir I can use an excellent bridging library between their VM and Rust. There's also an excellent support for working with C libraries. Not sure what else can be expected.
Maybe I am not reading you correctly and I apologise if so. It just kind of sounded like "the newer languages must be compatible with 20+ different ABI standards if they want us the older programmers working in C/C++ to adopt them"?
Back on the original topic, I completely understand if a project has too much baggage and sunk cost so as to make even a partial migration (and hardening via using memory-safe languages and/or professional paid code analysis tools) unrealistic.
It is like telling someone to delivering games in Unity and Unreal that they should use Amethyst instead, without understanding what it means to actually having a team working in those ecosystems.
Naturally Rust will get there, however it took C++ 30 years to be where it is today, and that is what any replacement attempt should take into consideration.
That being said, I agree -- existing teams can't be expected to just run away to the new thing, that much is true.
CLI tooling is the best it ever was in history (from where I stand at least). But IDE tooling isn't a first class citizen for many languages these days, is what I was saying.
Just for reference, my first UNIX was Xenix.
Don't see the point why people buy expensive computers to just use them like we did at the university lab with IBM X terminals.
The main difference was that instead of Slack we had xterms dedicated to run talk sessions.
Good lord, if that's the kind of human capital that's involved in making next-generation languages, then I have no doubt what will still be used to write serious software in 2080.
(Hint: not Rust.)
For any particular combination of compiler, OS and computer architecture there are no 'undefined behaviors'; you only care about the concept if you want portability to a different compiler/OS/architecture.
So the idea that C++ sucks because of 'undefined behavior', so let's use some random language without an ISO standard or any portability guarantees at all is completely and utterly insane.
Java's main issue is the barrier to entry is lower because it has good tooling, which means really bad, inexperienced programmers can write bad code, and have more tooling to bail them out, allowing them to continue down that path until they have a huge ball of mud.
There ought to be some kind of phrase for this "the tooling curse".
GDB isn't bad, IMHO, but the inability of IDEs to deterministically parse templates / index code without huge problems is problematic.
More like the inability of text editors to parse templates; most IDEs rely on a full compiler backend that can usually figure things out.
The ultimate result, given the slow compile times of c++, is that you cannot know in your editor if your code is correct.
My experience is frankly more that the usual IDEs I know of can't even handle syntax coloring 100% correct when it comes to C++…
It turns out if you use enough layers of templates, the compiler has to carry around an awful lot of state to figure out what program it should actually output.
This is another downside to a 1400 page language specification; whether the user can hold most of it in their head or use a reliable, safe subset to avoid sharp edges, the compiler and tools still have to be aware of all of the layers of complexity in both the code a developer is writing and often whatever tricks and quirks developers chose to usein the libraries the developers code is depending on.
I'm surprised you haven't seen this point made many times. It would be a full-time job on the internet asking people why they have code completion issues with C++ IDEs.
template<typename T>
void foo(T bar) { bar.buzz(); }
Other than that, finding foo<T> is usually easy, i've had good experience with qtcreator or clangd, you just have to be very very sure that your include paths are correct, qtcreator is good in that it uses CMakeLists as project-files so all this is done automaticaly. template<class _Tp, class ..._Args>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
!is_array<_Tp>::value,
shared_ptr<_Tp>
>::type
make_shared(_Args&& ...__args)
{
return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...);
}For that matter, most of the so-so devs resumes that come across my desk will list "HTML and CSS" as skills. Even among experienced devs, being legitimately good with HTML or CSS is extremely rare. I'd give my eye teeth to have a dev on staff who was an actual HTML expert (knows the w3c docs, can write clear, correct, semantic html using the right tags, organizes and expresses their intent, etc.), but since the barrier to entry is barely above basic literacy, so finding one is tough.
Why don't you use something else?
Because, most (all?) of those other languages fall into one of three traps, they also have a lot of undefined behaviors, they define the behaviors in ways that don't reduce actual programming bugs (javascript!), or they have so rigorously defined the language with underlying assumptions (say a really strong memory model, signaling NaN, overflow exceptions, etc) that the performance is sub-optimal on any platform that doesn't exactly fit the expected machine description.Really, C isn't hard if you burn your copy of K&R and stop trying to be so damn clever. It also turns out to be a lot more readable, if a bit more verbose, if one ignores a lot of its "features" and pretends its pascal with a single statement, without side effects per line. That includes using pointers in any kind of arithmetic (or type casting), instead using them only as though they were C++ references. (and a few other basic rules).
So, while I don't think rust is a particularly good language, I'm also starting to think that everyone should be forced to use it early in their career so they are forced to consider object ownership and lifetime in a rigorous way. Then when they move to C/C++/etc they wont be foot-gunning themselves at every turn.
... turns out to be an extremely tall order; the 2017-11-17 working draft of the C++ standard is 1,448 pages in PDF format.
At some point, I wonder when programmers who are required to care about correctness throw up their hands and say "This language isn't reasonably human-sized for a user to know they're using it correctly." At which point the immediate next question should be "Why don't you use something else?"
(In my experience, the only sane counter-answer to that last question is "I'm programming on an architecture where the {C/C++} compiler is the only one with any real expressive power that anyone has ported to this physical system." This is an answer I understand; most other answers will raise an eyebrow from me).