1,392 karma · joined January 20, 2013
It's not a one-size-fits-all type of game here. So having one choice will essentially lock you into what you can do with it.
I also wouldn't say a Future, which is a Monad, a leaky abstraction. You don't really need to understand monads to use them, in fact, a lot of people use what are monads all the time, without knowing it.
Imagine if your Browser crashed every time it hit an error, like a network connection issue, writing to a file, etc...! That just wouldn't be tolerated by consumers of the software.
Because the truth is that people generally don't care enough to do anything worth while ("signing" a petition is pretty minimal in terms of effort). There will always be the activists that are local to the cause who will do everything they can to fight, but everyone else, living their own lives, working, being parents, having hobbies or what have you have their own personal problems to take care of.
It's just routine. With the added regular news from the regular sources, who knows how manipulated they are, they're just so removed from what's actually going on. Not to mention, many people won't ask "What can the people do?" but "What can I do?" and their answer will be: "Nothing!"
We live in a world where people are told to live their lives, handle their business and the rest will be taken care of.
Maybe that's just common in Canada.
I don't like this situation, but this is what I'm seeing.
That's absolutely still loosing type safety. Reflections don't substitute type safety.
Uhmm, what? That seems entirely ignorant for ignoring an expressive concept and rather "do it the hard way". And, "remembering the generic syntax" is no different from remembering any other features' syntax, and I don't imagine you have issues remembering those, do you?
For example, in Rust, who's `enum`s are effectively sum types, we can take advantage of the type system while using channels that are well-typed.
https://github.com/servo/servo/blob/master/components/msg/co...
pub enum Msg {
ExitMsg,
FailureMsg(Failure),
InitLoadUrlMsg(Url),
LoadCompleteMsg,
FrameRectMsg(PipelineId, SubpageId, Rect<f32>),
LoadUrlMsg(PipelineId, LoadData),
ScriptLoadedURLInIFrameMsg(Url, PipelineId, SubpageId, IFrameSandboxState),
NavigateMsg(NavigationDirection),
PainterReadyMsg(PipelineId),
ResizedWindowMsg(WindowSizeData),
KeyEvent(Key, KeyState, KeyModifiers),
/// Requests that the constellation inform the compositor of the title of the pipeline
/// immediately.
GetPipelineTitleMsg(PipelineId),
/// Requests that the constellation inform the compositor of the a cursor change.
SetCursorMsg(Cursor),
}
Here we can define a sum type called `Msg` that has various variants. These are the only thing a channel constraint to that type can consume. Each destructing or pattern matching has to cover all possible cases, otherwise it's a compiler error.This makes it effortless to have complex communication where the data is composed of multiple things, multiple types.
[1] Here's another example of a sum type being used as a messaging type in Servo. [2] Shows pattern matching on all variants and variants of variants, which produces well-typed code.
[1]: https://github.com/servo/servo/blob/master/components/net/re...
[2]: https://github.com/servo/servo/blob/master/components/net/re...
I probably use `enum`s pretty frequently, especially when working with channels. I don't use primitive types-based channels too often come to think of it.
The point of the Node ecosystem is to be library-based. It's quite rare to have full-fledge frameworks dictate an environment like Rails does (and a method I personally hate). Go has the same principle afaik with it's web libraries.
I'd personally rather use a dynamic language rather than a statically-typed one with a weak type system. While the former can produce more errors at times, the later is often times just too inflexible and painful to use properly.
Then if you take into account the fact that Go's language features do not promote highly-performant code (GC, heap allocation, dynamic dispatching) that a few people in this thread has touched on.
While better looking code is highly subjective, Rust has indeed traded off some aesthetics for safety, performance, etc... However, that's not to say Rust code is ugly, you can certainly write very nice looking code in Rust.
For any embedded work or kernels, you wouldn't be pulling in the standard library via a `#![no_std]` attribute.
But you're right that bugs in the compiler could produce safety issues.
The next issue, if we're talking about high-performance http is asynchronous I/O which Rust doesn't currently bundle with (now that Rust has dismantled it's green threading runtime and is now sticking with native threading). However, mio [2], a lower-level Rust library in providing proper I/O abstractions that support async apis and the like is progressing pretty well.
The awesome part about Rust is that you have full control over the system. This allows one to build something like mio even though Rust doesn't support async I/O or a more efficient threading model, etc...
[0]: https://github.com/hyperium/hyper [1]: https://github.com/servo/servo/pull/4198 [2]: https://github.com/carllerche/mio
[1]: https://groups.google.com/forum/#!topic/v8-users/VgL3Fn4ijqE
Rust doesn't do that. Rust expands the macros at compile-time. Integrating the whole compiler into the runtime wouldn't make much sense considering what area Rust is targeting.
It's also recommended to not link a crate that is used during runtime with the compiler or parser because they're fairly big and would bloat your final build by a large amount.
"It’s important to be clear about what we mean by stable. We don’t mean that Rust will stop evolving. We will release new versions of Rust on a regular, frequent basis, and we hope that people will upgrade just as regularly. But for that to happen, those upgrades need to be painless." [0]