[rust-dev] Bikeshed proposal to simplify syntax
niko at alum.mit.edu
Sat Jul 14 18:32:33 PDT 2012
This is an interesting idea. I guess the key question is just *how*
negative heap allocations are. I think you are likely overstating the
case, or perhaps underestimating the extent to which the price of heap
allocations can be ameliorated by optimizing the allocator. But I don't
claim to have extensive data on this point.
But I have another concern as well. Regardless of how expensive heap
allocations are, they are likely to be frequently *necessary*. Much as
I love borrowed pointers, they are only suitable for things whose
lifetimes follow a stack discipline. Moreover, without a more complex
type system, there will be cases that do follow a stack discipline but
for which borrowed pointers are not complex enough to express. Given
that, forcing uses to write `ptr<Foo>` where in any other modern
language they would probably just write `Foo` doesn't seem like it's
going to win us any friends. `@Foo` seems a reasonable compromise to me.
I guess my fears boil down to this: I am already concerned about Rust
feeling too heavy-weight and ponderous. I like that Rust exposes things
like the program stack and gives a fair amount of room for
micro-optimization while still retaining type safety, but if that ends
up making the language feel less convenient than e.g. Java it may not be
worth it, given the speed/memory capabilities of today's computers (and
tomorrow's). So I'm hesitant to make changes that tax users of GC more
than we already do.
On 7/12/12 11:41 PM, Sebastian Sylvan wrote:
> Hi Rust team! First of all, congratulations on the 0.3 release!
> I have a bikeshed proposal to selectively simplify Rust's syntax in a
> way that has the side benefit of applying "negative syntactic
> pressure" on expensive constructs. It boils down to this: remove all
> special syntax for heap allocations and heap pointers. Keep special
> syntax for borrowed pointers, keep special syntax for fixed size
> vectors. E.g. a heap pointer might be ptr<T>. Allocating a block of
> uninitialized memory of type T might be heap_alloc<T>(), with the
> normal literals used to initialize it.
> Now, this sounds a bit crazy, and I'm pretty sure it won't be adopted,
> but I'd appreciate it if you gave it a moment's serious consideration
> and thought about what the impact would really be. I don't think it
> would cost as much as you might initially think (modern C++ does
> essentially this with all the shared_ptr etc., and many of the actual
> allocation calls are hidden behind constructor functions anyway) and
> there are strong wins.
> The two main benefits would be:
> 1. Reduce the complexity of the syntax. In particular, reduce the
> amount of "special symbols". You've all heard jokes about Perl looking
> like line-noise, I'm sure. Reducing the amount of special characters
> you need to know about before understanding code is a win. Getting rid
> of some of the symbols and treating those types in a more regular way
> would also kill a lot of design problems like "what does a heap
> allocated fixed-sized vector literal look like"? Even more
> importantly, it would make it easier to see what a complicated type
> means because it would follow simple nesting rules that you already
> understand, because it's the same rules that apply to user-defined
> types. It would also make library-pointer types look like the "real
> thing" (e.g. arc<T>).
> 2. Apply selective negative pressure to constructs which should be
> avoided if possible. IMO good syntax makes "preferable" constructs
> easy to write, and non-preferable constructs harder. Rust does a
> pretty good job here already (e.g. sharing mutable memory between
> tasks is suitably clunky). I personally think that heap allocations
> deserve to be in the "non-preferable" category, too. They add memory
> management overhead (GC/refcounting). They reduce locality. They add
> waste (header words, the pointer itself, maybe ref counts, etc.). They
> increase fragmentation. I believe controlling allocations will be
> essential to good performance in the future, as heap sizes grow
> massive (esp. for GC which is O(live_objects)). Heap allocations are
> absolutely essential sometimes, of course, but it's preferable by far
> to try to store the data on the stack or interior to the owning data
> structure, or in a big memory pool, and use borrowed pointers to
> access it indirectly - only resort to heap pointers if there is no
> other option. This is also why I think the *only* syntactically
> preferred pointer should be the borrowed pointer. IMO, Rust makes it
> far too easy to allocate memory on various heaps - just add a little
> sigil and you're done. C makes you appreciate the implications of what
> you're about to do when you type "malloc".
> Anyway, as I said, I don't think this will gain much traction, but
> it's one of those small niggles that I would do differently if I was
> designing the language, so I thought I'd float it for consideration.
> Thanks for your time!
More information about the Rust-dev