How can we increase adoption of c/c++ alternatives?
-
How much faster would those parts of the runtime be if they were written in c?
-
Probably not faster at all, but much harder to maintain.
http://benchmarksgame.alioth.debian.org/u64q/performance.php?test=fasta#about
-
Thats the same bench a second time. I noticed that go used more cycles but achieved shorter execution time by better utilizing all four cores. Are there many programs or algorithms for which that would be doable?
-
JIT
Is JIT still relevant in the world of JOP, where there's no further compile step than Java bytecode?The original statement was "A good language provides enough tools so that that runtime can be a library written in the language itself."
which I simplified to "A good language is Turing-complete."
Wrong. The point is that a good language is such that can have runtime written exclusively in itself - which is equivalent to being able to run with no runtime at all (because runtime can't require runtime). Can Go do that? With channels and GC and all that fuzz?Also, fucking nested quotes how do they work?
-
... Can a C runtime be written exclusively in C? I'm pretty sure glibc has some inline ASM, or at least some ASM source files.
-
Have you just proved that C isn't a good language?
-
... Can a C runtime be written exclusively in C? I'm pretty sure glibc has some inline ASM, or at least some ASM source files.
I'm pretty sure these are just hardcore optimizations written by early 70's hackers that didn't trust gcc to produce code good enough, and could be easily rewritten in C.
-
hardcore optimizations
easily rewritten in C
I don't know of any valid, portable, plain C source code that compiles to the x86_64
SYSCALL
instruction.
-
... Can a C runtime be written exclusively in C? I'm pretty sure glibc has some inline ASM, or at least some ASM source files.
With exception of platform-specific bits (that any other language needs assembly, or existing standard C library, for too) it can. The only assembly needed in standard C library is the system call mechanism and the only assembly needed in kernel is syscall and interrupt entry trampolines, bus I/O, before C11 thread synchronization and on platforms with segmented memory segment register manipulation. There are some other bits written in assembly as hand-optimization, but they are not needed.
-
Any questions?
[-]>[-]< >++++++++[<++++++++>-]<++. >+++++++[<+++++++>-]<-. >++++[<---->-]<-. >+++[<+++>-]<-. >++[<++>-]<+. >++++++[<------>-]<----. >+++++++[<+++++++>-]<--. >++++[<---->-]<--. >+++[<+++>-]<-. >+++++++++[<--------->-]<++++++. >+++++++++[<+++++++++>-]<--------. >+++[<+++>-]<+. >+++++++++[<--------->-]<--. >+++++++[<+++++++>-]<+++. >++++++[<++++++>-]<---. ---. >+++[<--->-]<. >++[<++>-]<+. >+++[<--->-]<++. >++++++++[<-------->-]<-------. >++++++++[<++++++++>-]<+++. >+++[<+++>-]<+++. --. +++. ----. >+++[<--->-]<++. >++++[<++++>-]<-. >++++[<---->-]<+. >+++++++[<------->-]<------. >++++[<---->-]<++. >+++++++[<+++++++>-]<++++++. >+++++[<+++++>-]<-. >++[<++>-]<++. >+++[<--->-]<. >+++[<--->-]<+. >++++++++[<-------->-]<----. >+++++++++[<+++++++++>-]<++++++++. >+++[<--->-]<-. >++[<++>-]<++. >+++++++++[<--------->-]<----. >++++++++[<++++++++>-]<+++. --. >+++[<+++>-]<++. . >+++++++++[<--------->-]<+++++. >+++++++++[<+++++++++>-]<--------. >+++[<+++>-]<++. >+++++++++[<--------->-]<---. >++++++++[<++++++++>-]<+. >++++++++[<-------->-]<-. >++++++++[<++++++++>-]<+++++++. >+++[<+++>-]<-. . >+++[<--->-]<--. >++++++++[<-------->-]<----. >+++++++++[<+++++++++>-]<-----. >+++[<--->-]<--. >++++[<++++>-]<---. >+++[<--->-]<++. >++++[<++++>-]<--. >++++[<---->-]<----. >++[<++>-]<++. --. >++++++[<------>-]<--.
-
<Riking> ?web>bf http://pastebin.com/raw.php?i=SBmqHkpR <Shocky> BrainFuck is Turing complete. Would you call it a good language?
No less than 5 fully-featured computers were involved in bringing you this message, running software in at least
45 different programming languages. (It depends on what the IRCd(s) is(are) written in.)Bumped from 4 to 5 because I forgot to count Brainfuck. Also, PHP got ran
twicethree times.
-
No less than 5 fully-featured computers were involved in bringing you this message, running software in at least 4 different programming languages.
Efficient.
Also, while your public service is appreciated, you just robbed me of some joy involved in making others translate it by themselves.
Filed under: @ben_lubar would probably write his own interpreter in Go
-
- Machine D runs Ruby to show the webpage
- Machine R runs C++ to have a browser
- Machine R runs Javascript to display Discourse
- Machine P runs PHP to display pastebin.com to me, involving L the load balancer
- Machine R runs C to have an IRC client
- Machine I runs ? to act as an IRC daemon
- Machine I2 runs ? to act as a peering IRC daemon
- Machine S runs Java to serve an IRC bot
- Machine C runs PHP to download the pastebin and report its contents to S
- Machine P2 runs PHP to display the pastebin raw to C (Episode VI: L the load balancer strikes back)
- Machine S runs Brainfuck to interpret the BF code
- The result bounces back from S → I2 → I → R, where I submit it as a new post to D.
Key:
Discourse at what.thedailywtf.com, Riking's computer, Pastebin.com php server, pastebin.com Load balancer, Irc server, Shocky the irc bot, Clone1018's php server which shocky uses as a php runner.
What a wonderful world.
-
-
Is JIT still relevant in the world of JOP, where there's no further compile step than Java bytecode?
No but an optimizing compiler could do many of the things yall were talking about.@ben_lubar said:
The original statement was "A good language provides enough tools so that that runtime can be a library written in the language itself."
which I simplified to "A good language is Turing-complete."
Wrong. The point is that a good language is such that can have runtime written exclusively in itself - which is equivalent to being able to run with no runtime at all (because runtime can't require runtime). Can Go do that? With channels and GC and all that fuzz?
Just because the language semantics allow gc doesn't mean that every single allocation will have to go through the garbage collector. Future Ben's gonna be able to say that the c parts of the go runtime were just hardcore optimizations by early hackers who didn't trust the go compiler.Also, fucking nested quotes how do they work?
Use email-style >s.
-
No but an optimizing compiler could do many of the things yall were talking about.
To date, no non-JIT Java optimizing compiler exists.Just because the language semantics allow gc doesn't mean that every single allocation will have to go through the garbage collector.
But can I use GC in runtime-less app? Because I totally can use shared_ptr in runtime-less C++ (assuming I have an implementation that doesn't depend on runtime itself - which I can wind up myself because shared_ptr is just a library). Same question for channels - because while GC is optional(?) and you can live without it, channels are the killer feature which make it better than plain C and working without them would be very unidiomatic Go.Use email-style >s.
I tried
and
I failed
-
I don't think it's doable with Java
If I was making a super-snazzy JIT for Java, I'd be very interested in looking at whether I can prove I can inline POJOs in what contains them. Proving it is tricky, but might be possible. (It depends on being able to prove that the POJO isn't ever handled as an independent entity except by things that we're planning to inline.)
I suspect that most code won't ever be able to establish that proof, not unless there's a mechanism for undoing the data-inlining optimisation too, which I think would be necessary if anything obtains a
Field
instance for the POJO. (That in turn is rather common, at least in the frameworks that my code uses. Ho hum…)
-
To date, no non-JIT Java optimizing compiler exists.
gcj
was a thing, and might still be. Nobody sane uses it.
-
To date, no non-JIT Java optimizing compiler exists.
I know. It's disappointing. But the nice thing about jop is that code could be optimized for a specific version of the architecture but still be compatible with any jvm.
But *can* I use GC in runtime-less app? Because I totally can use shared_ptr in runtime-less C++ (assuming I have an implementation that doesn't depend on runtime itself - which I can wind up myself because shared_ptr is just a library). Same question for channels - because while GC is optional(?) and you can live without it, channels are the killer feature which make it better than plain C and working without them would be very unidiomatic Go.
Which is why it makes sense to bake those things into the language. Because for what go is trying to accomplish, it is much better to be able to use multiple cores well than to conserve cycles, and it is much more useful to have guaranteed memory safety than to allow low level access to allocation and deallocation. And the gap between fully optimized go and c is just going to shrink as each compiler matures, but programmer productivity will only increase.@Buddy said:
Use email-style >s. >I tried
and
I failed
That's messed up, I don't know what to tell you :<frowning>(
-
Discourse and empty lines have a love/hate relationship
-
Which is why it makes sense to bake those things into the language.
No, it means the exact opposite - it's BAD DESIGN DECISION for systems language. If your language has hard-coded feature that heavily depends on runtime implementation, you can't do runtimeless build anymore no matter what. It becomes impossible. Your language becomes useless everywhere where you can't run your runtime. For example, barebone PC without an operating system in place.Because for what go is trying to accomplish, it is much better to be able to use multiple cores well than to conserve cycles, and it is much more useful to have guaranteed memory safety than to allow low level access to allocation and deallocation.
When did I say anything about performance? But answering to your non sequitur, Rust has both memory safety and low-level access. And doesn't depend on its runtime.
-
-
http://proguard.sourceforge.net/
I don't see "removing excess variables" or "inlining" in feature list...
-
-
Ok, point taken. Now, what is the performance of optimized bytecode running on JOP vs. JIT-ed bytecode running on x86/ARM of comparable power?
-
If your language has hard-coded feature that heavily depends on runtime implementation, you can't do runtimeless build anymore no matter what. It becomes impossible. Your language becomes useless everywhere where you can't run your runtime. For example, barebone PC without an operating system in place.
There's no fundamental reason that you couldn't GC inside an OS.There are small (and I emphasize small) portions where you couldn't, but there are small portions of OSs now where you can't dynamically/deallocate memory at all, and that covers most of the not-GC-able parts.
I'm not necessarily saying it's a good idea, because of performance, but it would work. (I generally think that virtually everything should be in a GC'd language for memory-safety reasons, but the OS is one of the few exceptions I'm willing to grant.)
-
There's no fundamental reason that you couldn't GC inside an OS.
There is - garbage collecting must be done by runtime, and you don't have runtime if you write OS.I generally think that virtually everything should be in a GC'd language for memory-safety reasons
There are other ways to achieve memory safety.but the OS is one of the few exceptions I'm willing to grant
Which is, ironically, the single thing that absolutely must be perfectly stable.
-
There is - garbage collecting must be done by runtime, and you don't have runtime if you write OS.
Operating systems contain their own runtime (if they need it). The GC engine itself is one of the parts that can't be garbage collected.
-
The GC engine itself is one of the parts that can't be garbage collected.
As well as anything that GC uses to do its work, which is, frankly, many of the basic OS functions.
-
There is - garbage collecting must be done by runtime, and you don't have runtime if you write OS.
Bull. Shit. A runtime is just a library, usually with the implication that it's doing something fancy. But plain C has a runtime; it provides things likemalloc
/free
. Does that mean thatmalloc
/free
can't exist in the kernel? No, of course not, as evidenced by every OS kernel ever. (Statement may be an exaggeration.)There's nothing magical about runtimes or what runtimes do. The only thing that a GC needs to be able to do is interrupt other parts of the same "process" to do GC, to muck about with memory, and to find the root set to use. The latter two things don't change when running in the kernel; as for the first, almost all of the kernel is interruptable already, and the exceptions are what I said before where you can't do memory alloc/dealloc anyway. (I could be wrong about that last part, but I don't think so.)
If you want concrete evidence that you can write an OS kernel in a GC'd language, you need look no further than Singularity, which is written in C#:
The Singularity kernel is a privileged system component that controls access to hardware resources, allocates and reclaims memory, creates and schedules threads, provides intraprocess thread synchronization, and manages I/O. It is written in a mixture of safe and unsafe C# code and runs in its own garbage collected object space.
(As another example of this reasoning, consider exceptions. You often see people asserting you can't use (software) exceptions in a kernel because it requires a runtime. But this too is patently false, as evidenced by, oh, Windows.)
There are other ways to achieve memory safety.
That's true, but I don't know of another way that still looks like "common" programming today.Which is, ironically, the single thing that absolutely must be perfectly stable.
It's also the thing that must be performant, and the stability issues are countered somewhat by the fact that it's always running under everything (and is thus unusually well-tested), gets an unusual amount of attention to correctness, etc.
-
Bull. Shit. A runtime is just a library, usually with the implication that it's doing something fancy.
It's pretty low-level, that's all. More low-level than anything else except kernel, and probably few other things.But plain C has a runtime; it provides things like malloc/free.
I'm pretty sure you could compile C program without providing malloc/free anywhere.If you want concrete evidence that you can write an OS kernel in a GC'd language, you need look no further than Singularity, which is written in C#:
Oh, cool. I'll look into it later. Thanks alot!As another example of this reasoning, consider exceptions. You often see people asserting you can't use (software) exceptions in a kernel because it requires a runtime. But this too is patently false, as evidenced by, oh, Windows.
AFAIK runtime is only needed to catch uncaught exceptions. I see no reason why it would be impossible to throw in kernel code.That's true, but I don't know of another way that still looks like "common" programming today.
An intuitive definition of word "common" excludes all non-GC languages.
-
AFAIK runtime is only needed to catch uncaught exceptions.
That's also something that both Java and C# make pretty easy. ;)
-
That's also something that both Java and C# make pretty easy.
C++ makes it easy too - justint main() { try { return real_main(); } catch(...){} }
.
-
An intuitive definition of word "common" excludes all non-GC languages.
I'm also including C, C++, etc. in here, as well as refcounted languages if you count that as not GC.I'm pretty sure you could compile C program without providing malloc/free anywhere.
You could write a C program without a runtime, yes, I will agree with that. But that's not my point: my point is that kernels have a support library that could be reasonably called a runtime.
-
C++ makes it easy too - just
int main() { try { return real_main(); } catch(...){} }
.Small note: there's no need for the extra function, e.g.:
int main() try { /* whatever */ return 0; } catch( ... ) { /* whatever */ return 1; }
-
I'm also including C, C++, etc. in here, as well as refcounted languages if you count that as not GC.
If you put it that way, then the alternative is RAII.You could write a C program without a runtime, yes, I will agree with that. But that's not my point: my point is that kernels have a support library that could be reasonably called a runtime.
And you must write that runtime without using runtime.
-
You could write a C program without a runtime, yes, I will agree with that. But that's not my point: my point is that kernels have a support library that could be reasonably called a runtime.
Yes, they certainly do. And yes, they could have garbage collector in it. After all it's just a bunch of functions that the compiler inserts calls to at appropriate places. And kernels have to handle interrupts anyway, so there's nothing simpler than hook up the collector into
schedule()
.The thing with non-hosted (= without the usual runtime) implementations is more like this: in languages like C, C++ or Rust you only have to do features you want to use and only those features cost you memory, code size and CPU cycles, so you can choose whether in your particular situation it is easier to implement the support, do without the feature or implement lighter-weight version of the feature or version tuned to the purpose (Linux kernel has very sophisticated allocator, but it's interface is quite different from
malloc
andfree
). On the other hand languages that have runtime-dependent features built into the language usually force you to implement the feature and don't let you implement modified version.The later ability is probably useful in more circumstances. It can be demonstrated on Go like this: Consider some functionality that uses associative container. Fine, Go has it built in. So you go with that. But then you find you would need the container to be sorted, or to maintain order of insertion or something. You are suddenly left with polymorphic solution using empty interface and the associated allocation overhead and casts all over the place. On the other hand in C++ or Rust you just replace the standard unordered map with ordered map or multi-index container from suitable library and it is almost direct replacement and you get to keep the same efficiency and features.
-
... Can a C runtime be written exclusively in C? I'm pretty sure glibc has some inline ASM, or at least some ASM source files.
In an OS environment: the likely hangups would be the system call stub(s) and perhaps some of the pre-startup initialization code, although the latter probably can be written in C.
Ironically enough, it's easier to do this on some microcontrollers (the ARM Cortex-Ms were designed for an assembler-free bootstrap) -- the NVIC in the Cortex-M family is smart enough to invoke a C function directly (no more trampolines!).
The only assembly needed in standard C library is the system call mechanism and the only assembly needed in kernel is syscall and interrupt entry trampolines, bus I/O, before C11 thread synchronization and on platforms with segmented memory segment register manipulation. There are some other bits written in assembly as hand-optimization, but they are not needed.
I'd say that you could write a kernel completely in C given a suitably smart interrupt controller in your hardware and a platform that uses memory-mapped I/O. (Why more interrupt controllers lack the ARM NVIC's brains beats me...)gcj was a thing, and might still be. Nobody sane uses it.
GCJ is still a thing, but yes, it is insane.No, it means the exact opposite - it's BAD DESIGN DECISION for systems language. If your language has hard-coded feature that heavily depends on runtime implementation, you can't do runtimeless build anymore no matter what. It becomes impossible. Your language becomes useless everywhere where you can't run your runtime. For example, barebone PC without an operating system in place.
Exactly -- the Cortex-M family can run compiled C code from the very first instruction after reset!Operating systems contain their own runtime (if they need it). The GC engine itself is one of the parts that can't be garbage collected.
Pretty much this -- klibc is a thing.The thing with non-hosted (= without the usual runtime) implementations is more like this: in languages like C, C++ or Rust you only have to do features you want to use and only those features cost you memory, code size and CPU cycles, so you can choose whether in your particular situation it is easier to implement the support, do without the feature or implement lighter-weight version of the feature or version tuned to the purpose (Linux kernel has very sophisticated allocator, but it's interface is quite different from malloc and free). On the other hand languages that have runtime-dependent features built into the language usually force you to implement the feature and don't let you implement modified version.
This, even more so when you're writing embedded code -- embedded hardware often demands a drastically different and lower-level interface than what a "normal" set of syscalls provide; in some cases, you may not even be able to use "normal" calls to talk to a device due to needing to use a different mode of the hardware or somesuch.
-
If you put it that way, then the alternative is RAII.
I count reference counting as (poor1) GC. RAII also doesn't give you memory safety; you'd need a language that enforced it (as well as removing the other things that makes C++ memory-unsafe).1Overall. There are some advantages compared to a tracing GC like usually more amortized & predictable performance.
And you must write that runtime without using runtime.
And? How do you think a user-space GC is written? Does it use OS capabilities to do GC? (No.) Is it GCs all the way down?Just like a user-land GC can be written without an underlying GC, so could a kernel-land one.
in languages like C, C++ or Rust you only have to do features you want to use and only those features cost you memory, code size and CPU cycles, so you can choose whether in your particular situation it is easier to implement the support, do without the feature or implement lighter-weight version of the feature or version tuned to the purpose
I agree with out this, with a couple caveats. First, the problem with that applied to GC is that while using GC costs you memory and CPU cycles, not using it can cost you security, and that's sort of my focus. (That being said, I think that GC is less important than other memory-safety guarantees that come with languages that are, somewhat orthogonality, attached to GCs, like bounds checking.) Second, you can say "oh I'll just write a GC for C", and while technically true2... that's really really difficult. The only one I know of is Boehm, and you wouldn't want to use that in the kernel.2 Technically technically false except I think C++11.
On the other hand languages that have runtime-dependent features built into the language usually force you to implement the feature and don't let you implement modified version.
So I'm not saying a kernel would want to use sort of an off-the-shelf GC; they could customize it. The kernel is probably a good candidate for a more real-time one.
-
This, even more so when you're writing embedded code -- embedded hardware often demands a drastically different and lower-level interface than what a "normal" set of syscalls provide
Yeah. I mentioned above that I'm begrudgingly willing to budge on my GC ideology for the kernel; I definitely (and not-begrudgingly) wouldn't apply to most embedded stuff.
-
If your language has hard-coded feature that heavily depends on runtime implementation, you can't do runtimeless build anymore no matter what
Maybe I'm old fashioned, but what happened to the idea that languages are designed to do different things, and in theory, you'd want a different language for something like embedded systems or barebones no-OS PCs than you'd want for, say, a typical desktop environment with memory to spare? I mean, otherwise.... why have many languages at all? If all hammers are meant to be multi-tools capable of handling every possible home construction project start to finish, why would you ever want more than one? And how can it be as good at everything all at once?
-
And? How do you think a user-space GC is written? Does it use OS capabilities to do GC?
Yes. malloc() for instance. And many other memory-related syscalls.Maybe I'm old fashioned, but what happened to the idea that languages are designed to do different things, and in theory, you'd want a different language for something like embedded systems or barebones no-OS PCs than you'd want for, say, a typical desktop environment with memory to spare?
Marketing happened. Go is presented as a language that can fully replace C and C++ in every field.And how can it [language] be as good at everything all at once?
By keeping the core functionality as small as possible and stuffing everything into libraries, making these libraries feel like the core language but still making them more or less optional :)
-
Maybe I'm old fashioned, but what happened to the idea that languages are designed to do different things, and in theory, you'd want a different language for something like embedded systems or barebones no-OS PCs than you'd want for, say, a typical desktop environment with memory to spare? I mean, otherwise.... why have many languages at all? If all hammers are meant to be multi-tools capable of handling every possible home construction project start to finish, why would you ever want more than one? And how can it be as good at everything all at once?
Once you get high enough up on the language power web -- you start seeing programming languages that are good metalanguages -- i.e. they not only provide you with tools to write code for a given task, but allow you to build and customize those tools to make the language better at a given task.
-
And then you are doomed to never again STFU about Lisp
-
Someone post this xkcd about the universe and God, please.
-
If only for blakeyrat's benefit
-
-
Maybe I'm old fashioned, but what happened to the idea that languages are designed to do different things…
Oh, that's totally a thing. C/C++ mostly was already replaced in areas where the other languages provide benefits and don't show any significant disadvantages. Even the C zealots from GNOME have switched to Python or C# for most of their applications. But we are talking about what features that would be needed to replace it in places where it stubbornly sticks (not possible completel; backward compatibility is a thing too; but at least for new stuff).
By keeping the core functionality as small as possible and stuffing everything into libraries, making these libraries feel like the core language but still making them more or less optional
QFT
-
. But we are talking about
Nah, I was just replying to the increasing amount of "Your language doesn't do X so it is terrible" stuff going on as this thread develops, the original topic was fine.
-
It's more “your language doesn't do X so it is not adequate replacement of C++”. Which, well, it usually isn't, if C++ does X and the language does not and does not have any adequate replacement for it.