Imagine you are designing a practical relatively low-level programming language to use instead of C++. What approach to memory management would you use?
In case someone asks, ``what is wrong with manly manual memory management in C++?'', I would briefly explain my disdain towards it. C++ strives to allow for efficient programs to be written, yet you have to jump through hoops and remember 30 different things if you want to avoid inefficiences C++ compilers inject into your application code. Where C would hit the spot with passing of pointers, C++ programmers need to know about RVO and const references and rvalues and perfect forwarding and noexcept declaration of copy constructors (why even have copy constructors anyway‽ how sane is having such thing‽) and reference collapsing rules. All just to prevent compiler from inserting procedures that needlessly copy your data multiple times here and there.
Instead of fixing a conceptually shitty design the committee adds 5 even more shitty things, each with its own semantics, each designed to work around one compiler/stdlib deficiency or another. Each has to be used manually.
So C++ programmers spend their brain cycles on recalling hundreds of shitty techniques while churning out code doing stuff which would be trivial for a saner language compiler to infer, instead of focusing on actual functionality.
Since it is lunch time where I work, I want to fantasize about a language/compiler which has most or all benefits of fast memory management (no GC), takes modern hardware into account, and doesn't fucking get in your way every time you pass a string to a function.
Name:
Anonymous2014-10-21 8:25
So here is a bunch of my crappy ideas, in no particular order.
∘ There is a limited number of types in a language. Writing memory allocators for each is tedious. Why not make an arena for each by default? ∘ However, some containers might enforce that their data (objects) lie in a continuous chunk of memory (think vectors). In this case, objects ``owned'' by those containers will be moved there (see next item). ∘ Compiler can infer which data is used simultaneously, and improve its locality. It can even do it in runtime to certain pieces of data (if it knows which pointers point to which; atomic swap of objects AND pointers requires locks though; need to think more about it). ∘ Objects are created on heap by default, and passed around by reference. However, if an object is a temporary or a function-local thing which is never returned or stored outside of function-local or temporary containers, it may be allocated on stack. You have no say in where exactly the object will be created.
I have not been thinking about it for long, so the ideas are likely very crappy and unrealistic and troublesome. Maybe you have better ones. Let's listen.
Name:
Anonymous2014-10-21 8:25
C is the language you are looking for. malloc() and free() are usually very fast, it does not have a GC, compilers will optimize for modern hardware, and it never gets in your way of passing an argument to a function.
This is simply not true. And you have to use them carefully if you want anything resembling efficiency.
>>4 Did not yet have the chance to look at it, but it sounds very promising.
Name:
Anonymous2014-10-21 10:11
I just want to make my anus haxing device that goes directly to the prostate and does all the work for you. Maybe it can even change size. I can walk around Akihabara with a tiny stick the size of a pencil and just wait for some asshole to give me the stinkeye. Then I shove it straight up his anus and it expands to ten times that size! Haxxing so bad that he may never walk again.
Name:
Anonymous2014-10-21 10:23
// this program will use at most 10KB #define MEMSIZE 1024*10 static char mem[MEMSIZE]; static size_t nalloc;
>>7 The commet lies. It obviously takes at least 10KB + sizeof(size_t) + whatever the stack needs (which is very hard to figure out in practical cases)
>>11 //this program will use at most 3 inches of RAM
Name:
Anonymous2014-10-21 15:04
>>11 The other one is JEDEC but only sandniggers use JEDEC.
Name:
Anonymous2014-10-21 16:19
i would go for a racket-style garbage compiled language with support for explicit C-style memory management through malloc/free for when ya really need it.
Name:
Anonymous2014-10-21 19:08
>>5 You can't screw up allocations in Rust without being aware of it. Heap allocations are explicit and assigning to pointers only copies if you actually create a copy during the assignment.
Name:
Anonymous2014-10-21 22:52
>>15 I feel like Rust has a lot of good ideas, but suffers from the enormous complexity of having both "everything is manual/explicit" and "everything is safe." They basically reinvented a worse version of ATS. It's a shame all that work went nowhere.
>>16 I'm nearing the end of a two week project using Rust. My main motivation writing with Rust is to avoid writing with any C++ nightmares in the future.
Unfortunately, I'm arriving at a similar conclusion which you mentioned. It has good ideas to be implemented on a lower level lang. However, the explicitiness, lack of higher kinds, funky fn names for simple stuff, and tiring conversions between primitives can be really annoying at times. Sometimes, it's too much because now I have a 150+ col one liner which would have been 50 col in C. Its verbose and complex syntax is difficult to read.
I really want to like it more than its currently worth. And I'll probably use it off/on and before/after it hits 1.0 because I'm sure as hell won't ever be going back to C++. But I don't enjoy it as much as its capable.
Name:
Anonymous2014-10-23 6:40
>>16 ATS syntax looks like someone trying to stir a vomit-covered wine glass with excrement in it with a fork.
Name:
Anonymous2014-10-23 14:07
>>18 I'm just happy it's nicer to write than C++. Even nicer than C most of the time because of the abstractions you can use.
Name:
Anonymous2014-10-23 18:02
>>20 But "nicer" by how much, exactly? Is it really nicer in ways that Ada (for example) isn't?
Name:
Anonymous2014-10-24 7:27
>>21 Ada is a great language, shunned for some unknown to me reason by many.
>>24 That's what NSA would like you to think. They have destroyed evidence in the past, and will destroy evidence of tampering with Ada should you raise the issue.
>>23 That's not a problem if you're programming for them.
Name:
Anonymous2014-11-01 16:09
Reason 2: Ada hath no metaprogramming.
Name:
Anonymous2014-11-01 19:09
Ada Wong
Name:
Anonymous2014-11-01 22:53
Just do manual memory management and use tools to catch memory leaks and use-after-free. This is not something that needs support at the language level.
Name:
Anonymous2014-11-02 8:51
Hey, I didn't know that Idris is headed for uniqueness types. They've built an experimental level of support for them:
All these academic languages are taking the wrong approach. Every time one of these new languages is made, it comes with a ton of new rules about how you can use different types together and what operations you can perform in what kinds of functions. Academia is making up new rules of safety faster than it can write code to implement them!
C and C++ have flaws, but they get the fundamentals right: They put the programmer in control. Any language that violates that principle, even in the interest of addressing those flaws, is built on the wrong idea. Any language based on garbage collection, or restrictive rules of safety, is just wrong. Programming is not about letting the computer figure out how to do it for you. You have to know what you're doing. You have to be the expert. If you depend on academia to know your field for you, they won't. You have to be the one who does your own job.
>>45 Gee, why oh why don't nuclear plants put their employees in control and force those ridiculous safety rules upon them? "The languages which put the programmer in control" can't even handle concurrency properly, for fuck's sake. Which is why your favorite C and C++ are thankfully getting flushed down the drain.
Why can't you retards understand that the speed of software development is proportional not to the number of low-level good-for-nothing LOC, and not to the number of pointer bits the "l33t macho coder" can fuck around with unsafely, but to the number of lines of code the programmer gets correctly on first try. And in order to get things fucking correctly right away, you need a safe language in which the compiler will shove your mistakes in your face as fast as it is (non-)humanly possible.
You have to know what you're doing. You have to be the expert.
Exactly. You have to know the problem domain and what you're doing in it. Not the tedious and and unproductive bookkeeping that goes along with it.
Fuck, when I want to print hello + str, I just write print $ "hello" ++ str, not
allocate me a goddamn buffer of some fuck-do-I-know size; run a cycle where I have to manually screw little integers around to fill the buffer; print the string from that buffer; don't forget to free the buffer
In fact, Idris and Rust allow you to do all the same mutable whoring that you think is so empowering about C and C++, except that it will be safe AND high-level.
>>48 Your example doesn't really hold for sepples, so I don't know why you included it. If you have a std::string str("sex") you can simply say std::cout << "butt" << str to print it.
There are valid criticisms for sepples, but yours was not one of them.
implying academic safety rules work in practices, instead of getting in the way.
C/C++ is a enormously popular, yet the most unsafe language after machine codes. PHP is somewhat safer, yet its practical problems arise from unescaped queries, memory leaks and bad scoping - none of these problems is fixable with static analysis. You can probably invent some overly-complex static query verifier, which would have failed miserable in practice, even if any potential user had time to learn it.
The major problem of functional programming languages is the construction of many temporary data structures, which makes manual memory management impractical. Thus arises requirement for automatic memory management, usually implemented through heap and garbage collection process (GC), which determines obsolete data and frees its memory. Heap-based GC processes are complex, requiring suspending execution and copying large chunks of memory to avoid fragmentation, which impedes allocation of large continuous data structures. To avoid pauses, modern GCs uses generations, but generations are still unreliable, uncontrollable by user and poorly map to memory usage.
Symta's motto for memory management is "no heap - no garbage". By using just stack we can compact incrementally and use stack frames naturally as garbage collector generations: when a function leaves a stack frame, all frame's data is freed or compacted to parent frame. A good example would be a video game engine `render_frame`, allocating a lot of per frame data, which won't be needed for the next frame. Stack provides explicit, intuitive and predictable way to manage memory.
Name:
Anonymous2014-11-03 7:46
>>54 Fragmentation arises without automatic memory management just as well. "No heap - no garbage" is just idiocy. Heaps were invented for a reason, obviously.
Symta's motto for memory management is "no heap - no garbage". By using just stack we can compact incrementally and use stack frames naturally as garbage collector generations: when a function leaves a stack frame, all frame's data is freed or compacted to parent frame. A good example would be a video game engine `render_frame`, allocating a lot of per frame data, which won't be needed for the next frame. Stack provides explicit, intuitive and predictable way to manage memory.
Rust does this. It's not enough for 100% of use cases, which is why the system is extended with other features like refcounted heap objects.
>>55 If the compiler can statically determine that a memory object will outlive the context in which it was first allocated, and also identify the context in which it should be deallocated, then it can be allocated in the latter context's stack frame.
Rust does this. It's not enough for 100% of use cases, which is why the system is extended with other features like refcounted heap objects.
I've looked up Rust, and it appears to do different thing - smart pointers and allocates on heap.
If the compiler can statically determine that a memory object will outlive the context in which it was first allocated, and also identify the context in which it should be deallocated, then it can be allocated in the latter context's stack frame.
We all know that static code analysis is impractical bullshit. The promising at first field of program verification has degenerated into a vulgar pathological science, inventing perpetuum mobiles. It is impossible to build Facebook with Agda, the same way it is impossible to prove halting, unless you work on a toy problem.
I've looked up Rust, and it appears to do different thing - smart pointers and allocates on heap.
It is capable of both. You tell it on an object-by-object basis which approach you want it to use.
We all know that static code analysis is impractical bullshit.
Don't be ridiculous. First of all, nobody is seriously calling static analysis a panacea for every programming problem you might ever have. Second, all compiler optimizations involve some limited application of static analysis. If you're actually taking a hardliner stance against it, you are wasting your time by interacting with a computer. They are built on static analysis of problem spaces.
As for comparing Rust to Agda, your ignorance is just disappointing. Escape analysis (statically determining where on the stack to allocate an object without being told by the programmer where to put it) has been part of Java for years. When Java is unable to decide where to put an object, it leaves it on the heap. When Rust is unable to decide, it flags an error and tells the programmer to be more specific. It's not magic.
Don't worry! I have no chance outdoing the ridiculousness of academia crackpots.
First of all, nobody is seriously calling static analysis a panacea for every programming problem you might ever have.
So far it haven't been even a leech therapy level efficient.
all compiler optimizations involve some limited application of static analysis.
No. They involve explicitly stating what you want. Like using "restrict" keyword or using bytes instead of 64-bit integer.
If you're actually taking a hardliner stance against it, you are wasting your time by interacting with a computer. They are built on static analysis of problem spaces.
Compilers are built on translating high-level code into machine code.
When Rust is unable to decide, it flags an error and tells the programmer to be more specific.
You may as well use C++. Rust solves the wrong problem.
It has to be one or the other. Those two ideas don't work together.
As for comparing Rust to Agda (...) When Rust is unable to decide, it flags an error and tells the programmer to be more specific.
That is what Agda does.
Name:
Anonymous2014-11-03 19:52
>>60 Escape analysis is a flawed concept. When a function returns, the calling function should grow its own stack frame and move allocations into it, skipping anything that's no longer used. See >>54
Name:
Anonymous2014-11-09 9:23
I think the ideal is a language where there is a pure (total) core functional language, and where all effects, including non-termination and exceptions, are banished to a secondary language (e.g., monad). An example is Coq + the Ynot monad.
There, you get the best of both worlds. You get to evaluate the pure fragment CBN, CBV, or CB-need or however you see fit. (Though I think I prefer a cost model that leans towards CBV to avoid the space problems. However, to support control-abstraction, which I also think is important, you might lean towards CBN or CB-need.) You get to factor everything out with "let" if you like. You get to do de-forestation. The compiler doesn't have to do strictness analysis. You can add "strictness" annotations to types or calls to seq and have it not break all of those nice properties Haskell folks claim they have for small programs, but never have for big ones.
There are other advantages. Integrating dependent types is easier. Embedding DSLs with control requirements that rule out divergence or exceptions becomes possible. And you get to do Curry-Howard, something you can't pull off in Haskell at all, and in ML only when you do silly things like restrict dependencies to A-normal form (c.f., Leroy's modules.)
A whole bunch of copying. Your stack will be slower than conventional stacks.
Also what about static vars? Consider: 1. Function F1 calls F2 which returns, but it's got some static vars that it will need for its next invocation. 2. These static vars get copied to F1's frame. 3. F2 gets called again, it needs the static vars, but they're already in F1's frame. So either they'll need to be copied back to fucking F2's frame, or F2 will need access to all the frames on the stack.
>>80 Only it's no good, you can't install evince and many other programs without bundled systemd. I really enjoyed Debian all these years - 10 years already? time runs so fast - because it went so well with my mentality, and will continue using it, never upgrading and compiling stuff I need myself until I run out of patience and switch to Mac because there would be no point in sticking with gnoo/leenooks anymore.
>>82 I used it before Mozilla rolled out the pure JS renderer of PDF, so I read pdfs with firefox now. Tried kpdf and xpdf, both were terribly annoying.
Why was the ATS language dropped from the Computer Language Benchmarks Game?
Unfortunately, there was no effective way to make sure that contributed ATS programs were comparable to the other programs that had been contributed. There are not enough ATS experts.
Name:
Anonymous2014-11-16 17:33
>>84 That means YOU have a chance to become an Expert ATS Programmer way before it gets fashionable.
Name:
Anonymous2014-11-16 18:01
>>83 Okular is the best, if you don't mind the KDE dependency.
>>89 No. And yes, Firefox is better than kpdf and xpdf. Evince was better than firefox.
Name:
Anonymous2014-11-16 20:18
>>90 Try Zathura or Chrome's PDF reader. Both are way better than pdf.js.
Name:
Anonymous2014-11-16 20:48
>>86 is right though. Okular is the bomb. I have even used it on windows.
Name:
Anonymous2014-11-16 21:27
I am using only Okular.
Name:
Anonymous2014-11-16 21:40
>>89-91 Evince and zathura both use Popped for their PDF backend. Poppler itself is derived from xpdf, so the capabilities of all three applications are nearly equivalent.
It's very unfortunate that Google and Mozilla failed to agree on a common framework to replace NPAPI. Between Google's closed source Pepper PDF blob and Mozilla's non-performant PDF.js, PDF functionality in contemporary open source browsers has regressed terribly.
PDF functionality in contemporary open source browsers has regressed terribly.
Has it really? It's always been garbage in browsers but I don't think that's the right place for the viewer. Google and Mozilla put them there because nearly everyone has Adobe's or another vulnerable viewer installed.
Name:
Anonymous2014-11-17 1:45
>>95 If built-in viewers aren't approaching feature parity as the old NPAPI viewers accumulate security vulnerabilities and generally bitrot, then yes, I would call that a regression overall.
>>96 Never had any problems with pdfjs. The only thing that may be missing that I might use is ability to fill out forms. Other than that, everything I encountered rendered perfectly, and quickly enough.
>>97 pdf.js always maxes out one core of my latest gen Intel CPU and renders everything like shit. It's Javashit too. I don't understand how anyone considers this gigantic hack a good thing.
I'd rather download the files and open them with my local reader.
Name:
Cudder !MhMRSATORI2014-11-17 12:19
>>1-50 "Those who sacrifice freedom for security deserve neither."
>>83-97 If I want to read a PDF I'll download it and open it in something else.
>>97 Forms is bullshit. Just open the file in a PDF editor. Use the text tool to add text in the right places. Save it and you're done.
"Those who sacrifice freedom for security deserve neither."
You're right.
Actually, I'm sick to death of the tyranny of the C calling convention, the inability to goto from one function to another, the overhead of reinterpret casts when I need to treat an int as a float, the difficulty of accessing individual bytes in a word when the CPU can do that just fine. I'm sick of address spaces being isolated from each other so I have to jump through hoops to make IPC work. I'm sick of having to go through unoptimized proprietary drivers just to control my hard drive and sound card. I'm sick of making compromises for someone else's putrid worthless tech. The computer industry is a tiramisu of crippled leaky abstractions made of many different layers of bullshit. I deserve better than this.
I am a fucking programmer. I am the creator of thousands of programs. I know what I'm doing. The computer shall do exactly as I tell it and never argue with its god. It is mine to dominate and use. Not Google's. Not Apple's. Not AMD's. Not some fucking patent office. Kiss my ass. Everything they've made is a crime against me, and I'm done with it.
>>99 The thing is, with Evince gone, there are no local readers... Okular is bloated unusable shit. Seriously, how is it even possible to fuck up navigation that badly? Not to mention the handful of shitty features nobody ever uses. Plus overall KDE ugliness, like it was designed for a kindergarten.
Name:
Anonymous2014-11-17 19:28
>>103 Evince is not gone. it doesn't depend on systemd. Except if you're on a shit system like Debbie.
funny, okular on my system is exactly as ugly as the pdf. there is nothing else in the window, not even the titlebar.
Name:
Anonymous2014-11-18 2:47
>>102 This hit deep. For too long I've been hoping at best to retain the option to use something that doesn't explicitly fuck me over. But what else can I hope for? When complexity rises as time goes on, how can you maintain your personal audit of your computer? At some point you need to accept the untrustworthy work of others if you're to use a computer at all.
>>110 If you have less physical RAM than what your program is using, what business do you have trying to operate a computer?
Name:
Anonymous2014-11-18 17:23
>>107 Low IQ does not necessarily mean low intelligence, you idiot.
Name:
Anonymous2014-11-18 18:04
>>112 That's literally exactly what it means. Unless you're basing your definition of ``IQ'' on some flawed IQ test.
Name:
Huskellfaggot2014-11-18 18:08
>>113 IQ has been considered a bad way to measure intelligence for a while now.
Name:
Anonymous2014-11-18 19:04
>>114 Yeah, by SJWs who want to turn the world into a "safe space"/hugbox for weaklings who blame their problems on others. IQ measures actual brain capacity. That's why it's called IQ.
Name:
Anonymous2014-11-18 19:20
>>115 So if I call my penis "The Ultimate Penetrator", you'll agree to get penetrated by it?
IQ measures only the ability to solve logical puzzles. It doesn't measure expertise, experience, cognitive abilities, stress-endurance, creativity, erudition, etc etc - i.e. all those things that are present in truly intelligent people.
>>120 C's aliasing rules are a bit of a disaster, actually. Leaving aside the decisions to omit dynamic allocation and escape analysis from the language entirely (it's a systems language from the 1970s so these are somewhat excusable), aliasing is really the only thing left and they got it wrong.
Restricting aliasing by default makes programs much easier for both humans and compilers to reason about. There's always room for escape mechanisms like volatile for the few cases it's desirable to not constrain it.
Name:
Anonymous2014-11-20 15:29
>>121 Back when C was designed, there were no such words... restrict is a very new keyword, compared to the overall age of C. They could not restrict pointer aliasing by default because then it would break 90% of existing C programs. Might as well call it C' then.
Name:
Anonymous2014-11-20 16:24
>>122 My point being that they should have had restrict semantics in the language by default from the very start. Contemporary languages (FORTRAN) already did this so K&R really had no excuse.
Name:
Anonymous2014-11-20 17:27
>>123 If you're talking about Fortran's array semantics, you simply don't understand the problem. The distinction between pointers and arrays is academic. They're the same thing under the hood. C was right to acknowledge this.
The distinction between pointers and arrays is academic
No, it most certainly is not. Array types and pointer types are distinct, even in C. Interchangeability of arrays and pointers in some contexts is a syntactic convenience, nothing more.
The problem with C is that a pointer can point to anything of compatible type, even if another pointer at the same sequence point already does, and it's impossible in general to tell if any two pointers to compatible types are pointing at the same thing at the same time. This confuses programmers and greatly constains the work optimizers can do.
Name:
Anonymous2014-11-21 0:49
>>125 You're starting to sound like a Rust advocate. Slow down before you hurt yourself. It's unsafe.
Interchangeability of arrays and pointers in some contexts is a syntactic convenience, nothing more.
If anything, arrays are a syntactic shorthand for pointer arithmetic. I can't think of any contexts where they're completely distinct.
The problem with arguing this kind of thing is C doesn't specify an IR. Under the hood the types are erased and arrays and pointers are indistinguishable. With an IR, there would be an ontological frame of reference to use to make your case. I'm not sure why you would bother arguing it, since you seem to be complaining that C doesn't make enough distinctions in the first place.
If anything, arrays are a syntactic shorthand for pointer arithmetic.
Actually it's the other way around. The standard is very careful to avoid providing any guarantees about what happens if pointer arithmetic is used to obtain an invalid array index.
I can't think of any contexts where they're completely distinct.
Actually it's the other way around. The standard is very careful to avoid providing any guarantees about what happens if pointer arithmetic is used to obtain an invalid array index.
Tomato, tomato. It's equally unconcerned with what happens if you use an invalid index.
Definition, for one.
That misses the point, you could achieve that with a simple transpiler. There is no ontological content. Can you think of another?
If array semantics correctly show a an operation to be invalid where pointer semantics do not, the distinction is significant.
I'm going to ignore this until you actually say something.
Please enlighten me as to the exact nature of this trivial transformation.
Useless, you're probably trying to enlist my help in building a strawman. If you want to argue the point, bring something that survives type erasure etc per the spec.