Author here, sorry about that, I just deployed a fix, should be readable now. If it's not, here's the first few points
- Once you get good at Rust all of these problems will go away
- Rust being great at big refactorings solves a largely self-inflicted issues with the borrow checker
- Indirection only solves some problems, and always at the cost of dev ergonomics
- ECS solves the wrong kind problem
- Generalized systems don't lead to fun gameplay
- Making a fun & interesting games is about rapid prototyping and iteration, Rust's values are everything but that
- Procedural macros are not even "we have reflection at home"
- ...
the list corresponds to the titles of sections in the article.
build.rs is a source file that you can audit. A binary that has no reproducible build is not auditable even if anyone wanted to.
A single person does not audit all of their dependency tree, but many people do read the source code of some if not many of their dependencies, and as a community we can figure out when something is fishy, like in this case.
But when there are binaries involved, nobody can do anything.
This isn't the same as installing a signed binary from a linux package manager that has a checksum and a verified build system. It's a random binary blob someone made in a way that nobody else can check, and it's just "trust me bro there's nothing bad in it".
Stan gives you the ability to do probabilistic reasoning. There is actually Tensorflow Probability (https://www.tensorflow.org/probability) which has a lot of overlapping algorithms, but isn't as mature and approaches some things differently.
The main difference is that with Stan you think in terms of random variables and distributions (and their transformations), while with Tensorflow/DL you think in terms of predicting directly from data. Stan lets model a problem with probabilities and do arbitrary inference, generally asking any question you want about your model.
There are many other interesting alternatives, e.g. http://pyro.ai/ which takes a yet another approach merging DL and probabilistic programming with variational inference. (Stan and TFP can do variational inference too, but I guess it's like Python vs JavaScript vs Ruby vs Java - all of them can be used for programming, but not the same way).
VIM, and overall just being fast. It is extremely perceptible, especially if you ever use something like Arch Linux + st (or one of the faster terminals). iTerm is slow as shit compared to that.
I'm glad I found someone who shares my point of view. You're right about IDEs and debuggers.
> Instead, I believe in thinking carefully about the problem. Close your eyes and visualise the program and its data and control flow in your mind, then write the code. Use a whiteboard or even pencil and paper to collect your thoughts and get a good mental model of what you're trying to accomplish. Block out all other distractions and focus on the problem.
It's funny how many problems I've solved by writing code on paper/whiteboard when I got stuck doing actual programming. It's so much easier to focus on the problem when there's no code to run.
Another thing I found useful is just reading the code outside of an editor. Either by printing it out and scribbling over it with a pencil, or just reading it on a phone/tablet that can't run the code.
> Many others I've talked to are in disbelief when I tell them I can spend an hour writing several hundred lines of code that compiles and works flawlessly the first time, but this is what careful thought will allow.
I've been having the same experience. Recently at a uni we were given an assignment to write an interpreter for a rather simple imperative language (conditionals, loops, simple recursive functions and stack depth checking). We were given 3 hours to write a program that could interpret a sample program.
Most people struggled to get anything working at all during that time, since each and every one of them I talked to didn't have a clear picture of they were trying to build.
It took me a little over an hour to write the whole thing in almost a single pass, in a modular fashion with separate tokenizer, parser and evaluator with the necessary checks. There was no need to run the code, most of it was rather trivial, implementing simple state machines. It was quite a bit of code (over 1000 lines), but there was almost no thinking required if you knew how the parse tree should look.
In situations like this I'd even say it's hard to make the program not work if you're methodical, working step by step and checking if you've covered all the cases.
> This is why interview code tests are... badly misguided. Most "fizzbuzz" screening is grossly artificial, denying one the feedback loops which are a critical element of productivity, and without which one is relegated to spending time manual checking what automation does almost instantly.
Do you really need to compile/run something like fizzbuzz? What if you're writing code that can't be run, such as when modifying a larger piece of code that won't run until all modifications are made?
Isn't there some value in being able to verify correctness of code just by looking at it for a few seconds? Surely you can overlook some things, but with practice probably a lot less than people think.
> High latency feedback forces you to be more methodical in your development and think about the changes you're making.
This! People rely on their fancy REPLs and super fast feedback loops and 1000 unit tests too much these days. What do you actually do when you can't run the code? What if you have to debug it just by reading it?
There's a lot to be said about being efficient with trivial changes vs being methodical and able to solve much complicated problems when they arise.
I understand, I do like the idea of Phoenix, and it is definitely great to be able to keep 2M connections open at all.
I'm just wondering where is the per-connection overhead going into. Is there some inherent limitation of the WebSocket protocol that forces the server to keep large buffers or something? Not trying to bash on Phoenix, I'm just genuinely interested in what is the lowest possible overhead one could achieve while keeping an open WS connection.
> which is going to be peanuts for a company requiring this kind of scale
That depends. Two million connections from people in an e-commerce site is a lot, but two million connections for a side-thingy like some analytics/ads/background-job-whatever doesn't have to be that much, especially if you consider 3rd party code.
That's only about twice as much as in your case (I'm not saying it's not a lot, just pointing it out).
Still, I wonder how low could one get when implementing this at a much lower level. 41kB per connection seems like a lot of bookkeeping for something that's essentially a handle to a socket? Yes there's a process overhead in BEAM, but based on the Erlang docs, this should be only 309 memory words.
This is interesting, when I opened the link I thoguht to myself "this might be a nice and faster way to browse HN" ... but wow, this thing I slow. Not just slow, but the back button isn't working as well. Or maybe it is, but it loads the whole content again when you click back?
- Once you get good at Rust all of these problems will go away - Rust being great at big refactorings solves a largely self-inflicted issues with the borrow checker - Indirection only solves some problems, and always at the cost of dev ergonomics - ECS solves the wrong kind problem - Generalized systems don't lead to fun gameplay - Making a fun & interesting games is about rapid prototyping and iteration, Rust's values are everything but that - Procedural macros are not even "we have reflection at home" - ...
the list corresponds to the titles of sections in the article.