News for hackers. Stuff that matters.
Re:Two Weeks of Rust by danieldk on Tuesday January 12, 2016 @06:48AM (#10886842)
No, that does not solve the problem. Consider this Java fragment:

   String someLargeString = ...;
   //...
   String interesting = someLargeString.substring(10, 20);
   someLargeString = null;
Now assume that someLargeString is garbage-collected after the last statement. Is the backing character array of interesting 10 chars long or the size of the backing array of someLargeString?

You don't know, unless you know what the implementation of String#substring does. Suppose that someLargeString's array was a couple of megabytes, you could be using 20 bytes of memory or megabytes for interesting.

(Note that in the case of Java they switched from a O(1) index-based slicing to O(n) copying some time ago.)

Re:Two Weeks of Rust by fpoling on Tuesday January 12, 2016 @07:22AM (#10886957)
This is about quality of the GC and string implementation. A good one can detect that only a range of allocation is alive and release unused part of someLargeString. The GC could also flatten a deep nested tree of strings in implementations based on ropes.
Re:Two Weeks of Rust by danieldk on Tuesday January 12, 2016 @07:54AM (#10887080)
A good one can detect that only a range of allocation is alive and release unused part of someLargeString.

Can you give an example of a (somewhat widely-used) library/runtime that does this?

I think this is harder than it initially seems. How does the GC know that if you have some type with a backing array and two pointers (or indices) that I don't want to move one of the pointers to some other valid position later?

I am not arguing that it is not possible, but this seems difficult in the general case, unless you can explicitly provide hints to the garbage collector.

Re:Two Weeks of Rust by fpoling on Tuesday January 12, 2016 @09:30AM (#10887568)
There is nothing difficult with that as long as the GC knows everything about strings and their pointers so it can detect that a particular string is reachable only through single another string.

At some point this for considered for JS engine in Firefox, but that was before introduction of ropes, small strings that holds string chars inline and various other optimizations like recent switch from UTF16 to byte per char for strings with Latin1 characters. That and the fact that Firefox flattens all strings that name properties of objects, this optimization is unnecessary on the current web.

Re:Two Weeks of Rust by danieldk on Tuesday January 12, 2016 @09:38AM (#10887614)
There is nothing difficult with that as long as the GC knows everything about strings and their pointers so it can detect that a particular string is reachable only through single another string.

Right, but that is a specific case where a built-in data type is optimized. It's not difficult, because the GC knows the semantics of a specific data type. But this does not work in the general case of slicing of library/used-defined data types.

Re:Two Weeks of Rust by lmm on Tuesday January 12, 2016 @09:14AM (#10887476)
I have no idea about the popularity, but something like https://github.com/Chris00/ocaml-rope ?
Re:Two Weeks of Rust by danieldk on Tuesday January 12, 2016 @09:34AM (#10887597)
Sorry, I meant specifically:

A good one can detect that only a range of allocation is alive and release unused part of someLargeString.

I do agree that ropes are nice, though they may not be acceptable if you want O(1) indexing or slicing.

Re:Two Weeks of Rust by lmm on Tuesday January 12, 2016 @10:23AM (#10887884)
If you're using a rope representation in a GCed language then you get that for free, no?
Re:Two Weeks of Rust by alkonaut on Tuesday January 12, 2016 @08:03AM (#10887122)
> You don't know

Exactly. Which is the core of "not worrying about it". When it becomes a problem (Such as an out of memory exception) you worry about it. There is no illusion. The time you don't worry about it is when you write it. I'd write it exactly like you did above (except I probably wouldn't null it), and wouldn't think of it again until it became a concrete problem.

You are absolutely right that a GC didn't magically make all memory issues disappear. It just hides them.

Re:Two Weeks of Rust by Findeton on Tuesday January 12, 2016 @08:56AM (#10887380)
But then, the really good Java (or Scala, or whatever GC-based lang) programmers are the ones that actually know and actively take into consideration how the GC works memory-wise and speed-wise. The same kind of thing can be said about interpreted langs and speed. Of course, that kind of thing also happens in C++, good C++ devs know the order of any instruction speed and memory-wise, but it is much more evident in C++/Rust and it's actually documented in the standard libraries, and the lang itself tackles the problem.
Re:Two Weeks of Rust by alkonaut on Tuesday January 12, 2016 @10:06AM (#10887781)
Yes, with age and experience comes the ability to predict where things will need attention, but in the vast majority of cases memory management causes no issues -- which is why the language gets out of your way so you can focus on the business problem (which causes bugs and other issues millions of times more often).
Re:Two Weeks of Rust by markque on Tuesday January 12, 2016 @06:55AM (#10886869)
A somewhat contrived example which may require a quick look at the API docs but in the main you can focus on solving the problem, premature optimization and all that.
Re:Two Weeks of Rust by jasode on Tuesday January 12, 2016 @07:16AM (#10886938)
> may require a quick look at the API docs

But that tradeoff of memory footprint vs performance implemented by Oracle is not in the API documentation[1] for Java 7 nor Java 8.

One would have to stumble across other sources such as unofficial blogs[2] written by non-Oracle employees like Mikhail Vorontsov. That blog article then triggers an explanation from the actual coder that's buried in a reddit thread[3].

Hunting down why your business-domain java code is now suddenly slower because of hidden GC tuning is taking time away from "solving the problem."

Your rebuttal consists of:

-- repeating the "premature optimization" meme which is not relevant in this case.

-- recommending to look at the API docs, which doesn't even have the information!

[1]v7: https://docs.oracle.com/javase/7/docs/api/java/lang/String.h...

v8: https://docs.oracle.com/javase/8/docs/api/java/lang/String.h...

[2]http://java-performance.info/changes-to-string-java-1-7-0_06...

[3]https://www.reddit.com/comments/1qw73v

Re:Two Weeks of Rust by anon1385 on Tuesday January 12, 2016 @07:26AM (#10886977)
>A somewhat contrived example

It's not a contrived example. When Java changed this exact behaviour it caused a lot of pain for people. Code that previously ran in a reasonable amount of time suddenly became impractically slow:

https://news.ycombinator.com/item?id=9862556

>may require a quick look at the API docs

The behaviour isn't specified by the spec. That is why they were able to change it from one release to the next.

>premature optimization and all that.

The "premature optimization" meme you are parroting contains the implication that at some point optimisation will be necessary. When that happens you have to think about memory management, even in a GC language. The string example given by danieldk is just one of many ways in which that can happen.

Re:Two Weeks of Rust by rakoo on Tuesday January 12, 2016 @09:24AM (#10887532)
> The "premature optimization" meme you are parroting contains the implication that at some point optimisation will be necessary. When that happens you have to think about memory management, even in a GC language. The string example given by danieldk is just one of many ways in which that can happen.

That's exactly the point: caring about the actual memory used by interesting may not be as important as other parts of the application, or may not be important at all for now. You should only care about that when it does prevent pose a problem (performance, impossibility to evolve features, ...) (all while making the initial code flexible enough to be potentially changed in the future)

Re:Two Weeks of Rust by danieldk on Tuesday January 12, 2016 @09:51AM (#10887694)
You should only care about that when it does prevent pose a problem

Then you are setting up yourself for a lot of trouble.

Another part of memory management is thinking about ownership (to which the substring discussion is very much related) and it pains me to see how many bugs are caused by code like:

   Foo getFoo() {
     return myFoo;
   }
Where Foo is some mutable class and the invariants of the wrapping class suddenly don't hold anymore because some outside code is mutating the Foo instance through the pointer/reference.

Throw in some amount of concurrency and you get something that is not only hard to debug but also difficult to reproduce.

tl;dr: in a GCed language you need to think about memory management and ownership as well.

(Note: I am not arguing against garbage collection.)

Re:Two Weeks of Rust by wtetzner on Tuesday January 12, 2016 @12:53PM (#10888988)
> Where Foo is some mutable class

Ah, there's your problem :)

Re:Two Weeks of Rust by jerf on Tuesday January 12, 2016 @09:00AM (#10887403)
I'm firmly of the opinion that GC is the correct default [1] and that removing GC ought to be considered an optimization, not a default choice, but there's nothing contrived about that example. I've written apps where I had to know what was going on.

[1]: At least between GC and not-GC. Rust is a new third option IMHO.