Moon patiently told the student the following story:
“One day a student came to Moon and said: ‘I understand how to make a better garbage collector...
A = [a | A]
This is less strict than pure functional programming, but still feels declarative and makes concurrent programming easy: no piece of code that looked previously at your variable will have its assumptions about it broken.
Lazy evaluation makes it possible to construct circular data structures without mutation.
CL-USER> (subseq '#1=(1 2 3 . #1#) 0 10)
(1 2 3 1 2 3 1 2 3 1)
Church-Turing thesis says lambda calculus is turing complete and it is purely functional with no pointers at all.
That being said, reference counting is a really bad fit for functional languages for several other reasons.
I wonder if C programmers only drive manual.
Drive it well and it's scary fast.
Make a mistake and you're upside down in a ditch.
And it takes 30s for a dedicated amateur to break in and steal it.
I guess that was a big mistake for F1 and other sport cars to have adopted semi-automatic gear boxes then.
> A semi-automatic transmission ... is an automobile transmission that does not change gears automatically, but rather facilitates manual gear changes by dispensing with the need to press a clutch pedal at the same time as changing gears.
I wasn't talking about clutch-and-stick vs. push-a-button. I was talking about controlling which gear is on vs. letting the car guess alone. I've never heard about race cars where the driver does not decide himself which gear is on at which moment; if you have, thanks for letting me learn something new.
That said, I see no reason why a (semi-)automatic couldn't engine brake.
The semi surely can. The full automatic, I don't know. How can the car understand that you want a lower gear before you touch the brake?
Better update yourself.
The Subaru Impreza WRC2004 gearbox does a gear change in 0.05s vs 1s taken by the best manual ones.
Do you know any WRC driver able to beat that?
FWIW, I mostly program in C and I drive automatic. C enables me to be a control freak with my code, but I don't really have a need or desire to be a control freak with other things in my life…
Except when your garbage is full of rotting fish and you want that garbage disposed right now. In other words, RAII.
I'd really like a language where you can choose GC or RAII for the types you define.
They used that 1:15 real:virtual ratio in their experiments and claim typical use used 1:30.
I think this system swapped quite a bit more than most modern systems. That must have had an impact on optimizing the garbage collector.
1 MW was not really enough for practical development use. After a few years 4 MW = 18MB was a useful RAM size. Disks might then be 300MB or even larger. Which made virtual memory of 200-400 MB possible. Mid 80s onwards.
> That must have had an impact on optimizing the garbage collector.
That is one of the topics of the linked paper... ;-) We are not only talking about 'the' garbage collector, but the whole memory management system, which provided static/manual memory management and various forms of GCs.
There are all kinds of bells & whistles you can add on top of the general approach, mostly time-space tradeoffs, such as with a copying collector. But the overall time-space complexity generally remains the same. Sometimes it can get worse, like when you add concepts like ephemerons.
And then you realize that they are more or less the same in the end:
"A Unified Theory of Garbage Collection" TL;DR: Refcount and tracing are a duality.
"Reference counting must perform extra graph iterations in
order to complete collection of cyclic data. This is
typically viewed as a major drawback of reference counting"
In practice when people refer to reference counting it's usually implied that there's no trace phase, and that the GC cannot reclaim cycles. Perl, Swift, etc, are the typical examples. Python is the counter example because it does reference counting and tracing.