HNHacker News
TopNewBestAskShowJobs

nercury

894 karma · joined October 9, 2013

submissionscomments
nercury··on Why you should, actually, rewrite some of it in Rust
While I am avid supporter of Rust, I can't help but feel this post is not right. If Rust is so much better, why not prove it by writing software in Rust, instead of words. After all, if Rust is so much better, the result will speak for itself.
nercury··on How Rust is tested
I don't get it, because you have just explained how to unit test everything else. Which is way better than nothing. Not sure how it is moot, also not sure how it is related to the article :)
nercury··on Europe mostly ends mobile roaming fees from today
It was costing less, now it is a bit more than you say. I think this law forced cheaper operators to make deals with all the other country operators, no one was going to decrease prices, so in the end we got the maxed out price.
nercury··on How to Report a Bug to Microsoft
I remember submitting an early preview F# bug directly to dev email which I got together with compiler crash message related to some obscure attribute handling situation. I remember being very surprised that I could do it, and more so when I got a response! That was the first time I realized there are people like me behind this faceless Microsoft machine.

Funny, wildly different times, I don't think github was even popular (existed?) back then.

nercury··on Two years of Rust
> I do not support HTTP!

You are, in fact, right. But I advise you to read about HTTPS here, so you can more clearly understand the points others are making: https://en.wikipedia.org/wiki/HTTPS.

nercury··on Two years of Rust
Please stop claiming to support HTTPS when your site breaks perfectly https-compliant browsers.
nercury··on Rust 1.17
It is fine, because you can't accidentally use modified string on the left.
nercury··on Rust on AVR: Safer microcontrollers almost here
While I also agree that Rust does no better in unsafe code, I think it allows for some sweet careless use of pointers (references) in _safe_ code.
nercury··on “My Code is Self-Documenting”
No, the reader must not need to read the function to understand how it works.

The idea would be that the function names are so good that one does not need to read the function contents, right?

But some things are complicated and may not be expressible with the function name alone.

That's why people write comments. To help readers understand the code.

Let's say I am implementing some algorithm. I may mention the performance characteristics in the comment. Or I may let the readers dig into the code to find out what they are. Seriously, please don't follow "no comments" rule dogmatically.

nercury··on The struggle with Rust
Well, you either uniquely mutate, or keep the value immutable.

Usually you construct the pipeline to switch between these as you need. If you need to share the result from one mutation to the other, you can do it by passing a simple immutable value that communicates the state change to other mutation, but don't try to do both at the same time. This is simply a good practice enforced at compile time. Of course, sometimes these rules prevent some valid cases, but overall it is worth it.

If we are talking about HashMaps, the Rust std lib has useful Entry api to for get-or-insert use cases. In rare cases where you need to share the value between different parts of the system, there are primitives you can wrap your value in and enable reference counting, as well as internal mutation (even if wrapper is immutable, it provides safe api for mutation). In cases where the concurrency is needed, there are mutexes, channels, and multiple libraries to parallelize the code (like rayon or crossbeam).

nercury··on The struggle with Rust
Yes, it is hard to use mutable shared values Rust. This is exactly the point.
nercury··on Short intro to C++ for Rust developers: Ownership and Borrowing
Thanks for your comment, looks like my knowledge is still lacking here. Although I hoped that it would be enough to give an overview, without going into much detail.

I have removed a bit where I say that rvalues are same as returned values, to avoid confusing other readers.

nercury··on Rust by Example
When I started out (before 1.0 release), the documentation was very poor, I was coming into Rust with 5+ years of dynamic language experience (PHP, JS), my C#/C++ knowledge was rusty.

It took me a month (of my free time) to start feeling like I can write code in Rust. It felt like I was learning programming all over again.

There were several reasons for that: first, I assumed that Rust can be used the same way as Javascript, with callbacks everywhere, and second, I was used to OO patterns that can not work in Rust. So, to overcome that, I had to realize that while Rust may have modern features, it is fundamentally a low-level language; and I had to really understand what the OO patterns actually give me to find the alternatives in Rust. I think that these things have made me a better programmer overall.

I remember these distinct stages.

Rust is low-level stage: It took a while to realize that Rust structs live on stack, and the pointer to such struct can not be freely passed around like an object, because the stack frame will be gone at the end of a function.

I found out how to do virtual dispatch: the fact that borrowed traits have virtual dispatch table was missing from docs at the time (they are called Trait Objects). This is what I was actually missing from OO: a way to use the interfaces without putting everything into enums, and have a way to invert dependencies.

There is a borrow checker, but you need to think in ownership: Again, I was trying to use references as if they were objects in OO language, while the primary model is ownership. I wrote a bog post at that time discussing this: http://nercury.github.io/rust/guide/2015/01/19/ownership.htm...

Rust is more functional than it seems: At that point I found that you can model anything in Rust if you can express it as a data-flow from the input to output. Turns out, anything can be expressed as the data flow. The data that flows can be uniquely mutable, processed in parallel. I had to ditch thinking in highly shared hierarchies of objects and focus on flows that transform one set of structures to other sets of structures.

nercury··on Rust by Example
I use Rust primarily because it has very precise mutability semantics: things are either immutable or uniquely mutable. It is much easier to understand what can or can not happen to structures when they are passed between functions, as opposed to, say, Java, where object's lifetime is undefined.

Destruction after last use (RAII) ensures that resources such as files, sockets, db connections are closed. Also unavailable in majority of languages.

Also the language is expressive (type inference, generics, pattern matching, traits).

These three things are the main reasons, although I wish other languages (old or new) would pick up the first idea too.

nercury··on The Rust module system is too confusing
Rust module system is similar to C#: mod is namespace, extern is assembly reference. The difference here is that there is no separate "project" file, so all references to inner module files need to be described in the parent file.
nercury··on The Piston image library is now pure Rust
This is fantastic news! This was the reason I kept using SDL2_image - I had too much trouble compiling Rust image crate on windows.
nercury··on The Original Postal Has Been Made Open Source
Reading the source code of this is sure sobering. All files and code lines are there for the single purpose - to ship the game.
nercury··on Rust is mostly safety
Few recent posts that I can see are about the compiler internals, design of a tracing GC and a crypto problem. These things might just be complicated anyway :)
nercury··on Rust is mostly safety
Rust safety is ultimately a productivity boost.

For example, if I have a big string, I may create a hashmap where both keys and values are references to some portions to that original string.

Then, I may pass this hashmap to another function that will transform this hashmap into structs that contain reused portions of those string references.

Rust compiler will make sure that the original string is not destroyed or moved in any way in memory while this is happening.

While it is certainly possible to do this in C and C++, the development cost there is way higher. In C++, one would be sensible to stick to a slower version that copies and allocates data, unless he/she is really sure that the need for performance justifies the code complication.

Meanwhile, juggling the references this way in Rust is common and almost sloppy: the hashmap contains references to strings because it was probably created from iterator that iterated over references. The developer might not even need to notice it unless the string reference in result might be kept around longer than original. The compiler will tell about the type mismatch, and the developer will then create a new string from the reference, and then he/she will move on.

There is a similar story when such code needs to be refactored. The word "sloppy" still works here, but in a good way: offloading "being very, very careful" stuff to compiler is deliciously fun.

nercury··on Rust is mostly safety
I am not sure it's really a split when you can build stable on nightly. Nightly is great for experimentation.
nercury··on TDD Doesn't Work
I was commenting on the methodology as I heard and watched it explained by the author (Robert C Martin), as well as the way it was presented in his videos.

TDD workflow is fine; it's not thinking about the pink elephant (the source code) idea that bugs me.

nercury··on TDD Doesn't Work
TDD presents a paradox that requires split-brain thinking: when writing a test, you pretend to forget what branch of code you are introducing, and when writing a branch, you pretend to forget you already knew the solution. It is annoying as hell.

You CAN indeed cover all your branches with tests afterwards. You can even give that a fancier name, like "Exploratory Testing". Of course it may be more boring or tedious, but is a perfectly valid way to ensure coverage when needed.

TDD was great for popularizing writing test first; However I much prefer the methodology called CABWT - Cover All Branches With Tests. Let the devs choose the way to do it, because not everyone likes these pretend games.

nercury··on Announcing Rust 1.13
Initial work on specialization has already landed on nightly and is backwards compatible. AFAIK, there are no plans to break that.
nercury··on Announcing Rust 1.13
Not sure what you are talking about - it is the first bigger syntax addition since 1.0, and I actually want more.
nercury··on Announcing Rust 1.13
But consider that the Rust does not have null, so every case where you need to step over the code and see if it does the right thing when value is null does not need debugging!
nercury··on Rust: Systems Programming for Everyone
I guess Rust may seem more complex, if you know C++ well, but from the side it may not seem like it.

For example, C++ Core Guidelines [0] is longer than Rust Book. Core Guidelines is itself a great example of things one needs to keep in the head while writing C++ code.

Look at implementation of something as basic as optional<T> [1]. The amount of things one needs to know is so high most C++ developers would never attempt it.

[0]: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppC...

[1]: https://github.com/akrzemi1/Optional/blob/master/optional.hp...

nercury··on Writing a JPEG Decoder in Rust – Part 2: Implementation I
> `collect()` doesn't know what type of collection to collect into.

Yes, unless there is some other mention of Vec, i.e. it is returned from the function.

> This is impossible without varargs, no?

Varargs would definitely help, and would allow Rust to borrow more ideas without workarounds. But one can do it manually for each tuple variant.

nercury··on Writing a JPEG Decoder in Rust – Part 2: Implementation I
Looking at the example, I can't find a thing in there that is not required (except the obvious `:Vec<_>` type that is not required). We need `.iter` to tell that iterator is imutable (there is mutable version), we need `.collect` to actually run the iteration. I also don't think objects should have default constructor functions.

It may be possible to implement `.zipped` on tuples though.

nercury··on PHP the Wrong Way
I worked with PHP for 5 years and I am well aware of the composer; I am being downvoted because I said that author is right on some point.
nercury··on PHP the Wrong Way
It is near impossible to write "Modern" PHP and achieve good performance.

On every request, PHP reads and parses every file that is referenced somehow. It is in direct contradiction to the language constructs the PHP itself provides - especially Exceptions, Interfaces and Inheritance.

People want to use these features, because they help design better systems, where the concerns are separated, and features are plugins instead of hardcoded all over the place.

Unfortunately, the required files for a request can pile up quite quickly, to the point where bytecode cache does not help, serving multiple requests per PHP load does not help, prewarming cache for frontend such as Varnish does not help, memory usage is over the roof because of trashed heap memory.

So, to sum up, the author here is right: this is insanity, until PHP provides a module system that can handle PHP abstractions.

← PreviousPage 3 of 6Next →