Hacker Timesnew | past | comments | ask | show | jobs | submitlogin

[flagged]


Realistically, other than cool factor I'm having a real hard justifying the use of rust. It either devolves into using reference counting (fine but we have lots of languages that do that without borrow checking), or dynamics (i.e refcell).

The type system is nice with the algebraic data types, but lacking the higher orderedness of languages like Haskell, it just seems sad.

So basically, to me it seems like you're getting the worst of both worlds. You don't get the freedom of c/c++ and you don't get the actual type safety of a language like Haskell (refcell kills the notion of compile time checking).

Realistically what needs to happen is some system for circular references like Haskell has (let bindings).


There's so much you can do in rust without messing with any of that, and the only time you have to get deep in the weeds arguing with the compiler is _exactly_ the sort of code that you _should_ be spending a lot of time carefully thinking about. That C allows you to write that code without thinking about it much is _not_ a benefit to using C.


Coming from a mostly Haskell background, I assure you I think about my code a lot.


Data structures with circular references are so incredibly rare in practice. I've occasionally needed to use a graph (sometimes even a cyclic one), and petgraph with integer indexes works fine for that. Other than that, I've been writing Rust full-time for over 7 years and really not needed them.

The benefit is that for almost all code you get mutability xor aliasing, which I think is incredibly important to achieving correctness at scale.


> Data structures with circular references are so incredibly rare in practice

A doubly-linked list enters the chat...


Doubly-linked lists are incredibly rare, few people should ever use one and even fewer people should ever write one. In almost all cases vectors are better [1].

Rust's stdlib comes with one: https://doc.rust-lang.org/std/collections/struct.LinkedList....

[1] There are some cases where they're useful, e.g. when amortized O(1) append is not enough and you want actual O(1) append. But this matters to almost no one.


> Doubly-linked lists are incredibly rare, few people should ever use one

Umm... how do you propose implementing a queue or a stack cpu-efficiently and memory-efficiently using vectors?


In almost all cases, it is better to use a vector for both those data structures. Cache locality is king, memcpy is blazing fast, and pointer chasing is generally pretty bad for performance.

For a stack, just use a regular vector. Pushes are amortized O(1), and pops are O(1).

For a queue, a ring buffer backed by a vector. (This is how VecDeque in Rust's stdlib works.) Again, enqueue is amortized O(1) and dequeue is O(1).

Even if you do need to use a linked list, it's generally better to depend on someone else's implementation than write your own.


> it's generally better to depend on someone else

I am the someone else who writes that, often enough…

All y'all forget that behind your cute libraries and abstractions stands someone who wrote them in C or assembly…


In that case, you'll find that Rust is an excellent language for writing doubly-linked lists.

A lot of the point of Rust is to make a few people do the hard work of writing some complex data structure in unsafe code, and let everyone else reap the benefits.


Where do I send the thank you card?


> incredibly rare

> doubly-linked lists

Synonyms for application developers.


> It either devolves into using reference counting (fine but we have lots of languages that do that without borrow checking), or dynamics (i.e refcell).

The point is that you don't have to do that for all of your data objects, unlike other languages that use refcounts and dynamic checks under the hood. Most alloc/dealloc in Rust can be dealt with via simple RAII.


I don't see what let bindings have to do with solving the circular reference problem, those are just local bindings. A Haskell doubly-linked list would use IORef, but no one would ever actually do that.


Haskell doubly linked list:

    data DLList a = DLList a (DLList a) (DLList a) | End

    make_dllist :: [a] -> DLList a
    make_dllist = go (\_ -> End)
      where go mkPrev [] = mkPrev End
            go mkPrev (x:xs) = go (\next -> let me = DLList x (mkPrev me) next in me) xs
No need for IORef. Too many people misunderstand the meaning of 'let' in Haskell. It doesn't mean what you think it does. It defines, not assigns. In rust, let 'declares' and assigns in one go. It does not define.


C is not a good language for people who are short on time.


But you have enough time to mess around with Valgrind?


If you have a job to do, use standard data structures implemented in a high quality library.


Which high quality libraries do you suggest for an environment with no OS, heap, stack, globals, or initialized data?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: