News for hackers. Stuff that matters.
Re:Rust 1.37.0 by jedisct1 on Thursday August 15, 2019 @12:51PM (#20706995)
Rust has evolved from something safe and simple (once you grasp the different type of pointers) to something way less accessible.

Rust source code is now full of annotations, and very hard to read and maintain.

Traits have evolved from a nice feature to something overused everywhere.

Basic crates use so many generics, impl Trait and abstractions over abstractions over abstractions that it's really difficult to follow what concrete types you need to satisfy these.

When one of the oldest and still unanswered issue in the Hyper HTTP library is "how do I read the body?", there is a conceptual problem.

And things got even more complicated with Futures. async/await don't solve much, as besides textbook examples, these are unusable without deep knowledge of how everything works internally. Pin/Unpin makes things even more complicated.

I'm an early Rust adopter and advocate. However, I wouldn't consider it any longer for new projects.

My productivity in Rust has become very low compared to other languages such as Go or even C, that let me easily express what I want to do.

With Rust, 90% of my time is spent trying to understand how to express what I want to do. Such as what types I have, what 3rd party crates expect and how to convert them.

Re:Rust 1.37.0 by oconnor663 on Thursday August 15, 2019 @01:04PM (#20707160)
> something way less accessible

This is subjective, but there are at least a couple big counterexamples. Non-lexical lifetimes are a huge benefit for newcomers. I've gone through my old projects and just deleted all the nested blocks that I used to need to satisfy the borrow checker. Everything just works now. Also being able to match on `&T` or `&mut T` without putting the `ref` and `ref mut` keywords in each non-`Copy` binding, is another pretty big win. That's an entire keyword that we no longer need to teach to newcomers.

> Basic crates use so many generics, impl Trait and abstractions over abstractions over abstractions that it's really difficult to follow what concrete types you need to satisfy these.

Again this is subjective, but not following concrete types it the entire point of `impl Trait`. The type of `foo.iter().map(...).filter(...).step(...).take(...)` is a monster. Life is better when we don't have to type it. There are also new capabilities that come along with it: APIs don't have to commit to returning a certain kind of unboxed iterator, and unboxed closures can now be returned.

> async/await don't solve much, as besides textbook examples

See the real code examples here: https://docs.rs/dtolnay/0.0.3/dtolnay/macro._01__await_a_min...

Re:Rust 1.37.0 by hathawsh on Thursday August 15, 2019 @02:16PM (#20708031)
Is there a way to ask Rust to tell me the type of an expression like `foo.iter().map(...).filter(...).step(...).take(...)`? I often feel very much in the dark about Rust types and some kind of command to show me Rust's interpretation of the type of an expression in context might help a lot.
Re:Rust 1.37.0 by oconnor663 on Thursday August 15, 2019 @02:30PM (#20708193)
The hack that I've seen people use the most is to write a line like this:

    () = foo;
Then rustc will print out an error that includes the type of `foo`.
Re:Rust 1.37.0 by danbolt on Thursday August 15, 2019 @02:48PM (#20708347)
Scott Meyers also suggests the same sort of thing in Effective Modern C++ when not using an IDE.

Personally, I use the technique a lot for debugging template errors in the language.

Re:Rust 1.37.0 by stochastic_monk on Thursday August 15, 2019 @03:06PM (#20708549)
Specifically:

template<typename T> struct TD;

Instantiate this as ‘TD<decltype(foo)>’ to get the full name of the type.

Rust’s does seem more concise.

Re:Rust 1.37.0 by edflsafoiewq on Thursday August 15, 2019 @04:45PM (#20709470)
Note that you don't get the full name of the type with a bad assignment in Rust, you only get the part of the type that was deduced before type checking failed. A generic type might have undeduced blanks, eg. Vec<_>. A side-effect of type inference.
Re:Rust 1.37.0 by hathawsh on Thursday August 15, 2019 @02:33PM (#20708216)
Nice, thanks!
Re:Rust 1.37.0 by pc2g4d on Thursday August 15, 2019 @02:32PM (#20708206)
Just try assigning the expression to a variable of definitely the wrong type, and the compiler will print out the full type in the error message, e.g.

let x: () = foo.iter().map(...).filter(...).step(...).take(...);

Re:Rust 1.37.0 by tsbinz on Thursday August 15, 2019 @03:54PM (#20708995)
In the old days in C++ we'd try to assign it to int and look at the compiler error message. (That literally was the instruction of how to figure out the type to use in one of boost's libraries in pre-c++11 times ...)
Re:Rust 1.37.0 by slaymaker1907 on Thursday August 15, 2019 @03:06PM (#20708555)
In VSCode, you can assign it to a variable and then mouse over to see what type it infers.
Re:Rust 1.37.0 by umanwizard on Thursday August 15, 2019 @03:10PM (#20708601)
This usually works, but type inference in RLS (or Rust-Analyzer) breaks often enough that it's not a complete solution.
Re:Rust 1.37.0 by Matthias247 on Thursday August 15, 2019 @06:04PM (#20710163)
IntelliJ shows the inferred types by default. However it Gasversorgung it’s limitations with complex Rust types.
Re:Rust 1.37.0 by umanwizard on Friday August 16, 2019 @02:12PM (#20717887)
> However it Gasversorgung it’s limitations

I guess this is some autocorrect error? What did you mean to say?

Re:Rust 1.37.0 by Matthias247 on Friday August 16, 2019 @02:56PM (#20718405)
Oh wow, I just saw that now. It was certainly autocorrect on phone. Should only have been "has".

If you are curious: Gasversorgung would be be "gas supply".

Re:Rust 1.37.0 by umanwizard on Thursday August 15, 2019 @03:10PM (#20708592)

    let _ = 5 + foo.iter().bar().quux().asdf();
The compiler will now tell you that <your type> cannot be added to an `i32`.
Re:Rust 1.37.0 by MuffinFlavored on Thursday August 15, 2019 @03:33PM (#20708830)

    const foo = await callApi(url)
    console.log(foo.bar)
Why do we need anything more complex than this?
Re:Rust 1.37.0 by lukebitts on Thursday August 15, 2019 @04:00PM (#20709056)
Translating that to Rust:

    let foo = call_api(url).await;
    println!("{}", foo.bar);
Syntatical differences aside, what's complex about it?
Re:Rust 1.37.0 by staticassertion on Thursday August 15, 2019 @01:22PM (#20707380)
None of what you're describing really tracks for me, having written many thousands of lines of rust and interfacing with my third party crates.

"async/await doesn't solve much" like your whole post confuses me.

I think right now a lot of rust libraries are "hyper generic" because they're intended to be lower level and to be built on top of. Like hyper, as an example. I've never found it particularly hard to work with generic libraries though.

Re:Rust 1.37.0 by skybrian on Thursday August 15, 2019 @05:10PM (#20709696)
As a beginner, I think it's largely a matter of documentation.

In Go, you can very easily see all the methods that a type implements. However, you don't see which interfaces it implements because it's implicit.

In Rust, the methods are often hidden away in trait implementations, so it's harder to see what you can actually do.

It seems like this might be fixed if the doc tool generated an index to all the methods, as a reference? Or maybe there already is an easier way that I overlooked.

Re:Rust 1.37.0 by staticassertion on Thursday August 15, 2019 @05:18PM (#20709762)
cargo doc does do that already, not sure what you mean.

IDEs should also be autocompleting trait impls.

Re:Rust 1.37.0 by rhodysurf on Thursday August 15, 2019 @10:54PM (#20711755)
My experience is that it will only autocomplete traits that you have imported. Which sucks because what if I don’t know what traits my type uses? It’s crazy
Re:Rust 1.37.0 by rakenodiax on Saturday August 17, 2019 @07:08AM (#20723364)
IntelliJ will suggest unimported trait methods and will automatically import the required trait if it is selected.
Re:Rust 1.37.0 by skybrian on Thursday August 15, 2019 @05:29PM (#20709859)
For example, on std:String, the + operator is hidden away in the Add trait implementation. (In this case it's reasonably obvious anyway.)
Re:Rust 1.37.0 by staticassertion on Thursday August 15, 2019 @05:43PM (#20709986)
Ah, interesting. I haven't really noticed that sort of thing myself.
Re:Rust 1.37.0 by jnordwick on Thursday August 15, 2019 @01:46PM (#20707662)
Async+Await+Futures isn't needed at all, performs worse than a basic epoll loop, is more confusing, and less able to handle complex flow. But they add a lot of complexity. The futures paragidm makes the hard stuff almost impossible to do efficiently.

It took c++ years to blow its complexity budge. Rust, "Hold my beer."

Re:Rust 1.37.0 by staticassertion on Thursday August 15, 2019 @01:54PM (#20707749)
> Async+Await+Futures isn't needed at all

Define "needed" ? Code with async/await is radically simpler compared to without - this is not just basic sugar but really, really important due to rust's borrow semantics There is code I have written that required Rc/RefCell ceremony to get around the borrowchecker that will be completely handled by async/await.

You can read more about this here:

https://aturon.github.io/tech/2018/04/24/async-borrowing/

> performs worse than a basic epoll loop

There are open issues and afaik all of these are solvable problems with known/ theorized solutions.

> is more confusing, and less able to handle complex flow

Sorry, that's absolutely just not the case Even if "confusing" is subjective, you can not tell me that writing complex loops/ control flow is easier in futures than in async/await. Just look at the examples here:

https://docs.rs/dtolnay/0.0.4/dtolnay/macro._01__await_a_min...

Re:Rust 1.37.0 by woah on Thursday August 15, 2019 @09:02PM (#20711242)
There are programmers who mostly work on code that does a lot of work with the CPU, and needs to be multi core. For these applications, async/await has little to offer.

People who are puzzled by async/await often fall into this camp.

Re:Rust 1.37.0 by staticassertion on Friday August 16, 2019 @04:11PM (#20719229)
Why would they not just use threads?
Re:Rust 1.37.0 by jen20 on Friday August 16, 2019 @06:09AM (#20713658)
Async and await solve a different problem to epoll (and do so in a cross-platform manner). A “basic epoll loop” won’t help you for file IO on Linux, for example.
Re:Rust 1.37.0 by foldr on Thursday August 15, 2019 @02:07PM (#20707929)
I get the feeling that Rust is going to become, like C++ and Haskell, a language that you have to "live in". That is, if you take a break from the language for a few years, you won't understand the code that people are writing when you come back. Contrast that to, say, Go or Python, where you can come back to the language after five or ten years without any major difficulty.
Re:Rust 1.37.0 by zanny on Thursday August 15, 2019 @02:58PM (#20708460)
This only applies now because fundamental aspects of a competent modern language are still being added - it was only recent that you could have a const fn at all, async is only coming at the end of the year, there are still no HKTs, etc.

I'd be willing to bet Rust 2021 will be a great place to start at because it will represent 95% of what the language will become having already been put in place. From that point there will certainly be additions to the language in the forms of libraries and features but the mechanisms of how you write code in general will be solidified.

Until then yea, theres a lot of churn along the way to having a "mostly complete" language, especially when the point of the language is to basically be a kitchen sink of everything.

Re:Rust 1.37.0 by foldr on Thursday August 15, 2019 @06:05PM (#20710170)
I really think that could go either way. Haskell keeps getting new bells and whistles with no sign of any slow down. Once you get into sophisticated type systems, it's never "done". There's always going to be (semantically) safe code that doesn't type check in safe Rust, and the temptation to extend the type system to rectify that.
Re:Rust 1.37.0 by wtetzner on Friday August 16, 2019 @09:51AM (#20715102)
But Haskell is intentionally used as a laboratory to experiment with new ideas. That is not Rust's primary goal.
Re:Rust 1.37.0 by centril on Sunday August 18, 2019 @10:29PM (#20734436)
An interesting example is the addition of `{-# LANGUAGE LinearTypes #-}` to GHC. The primary interest for this "experiment" is not from academia but from industry (tweag IO). Another example is `QuantifiedConstraints` which was quickly caught up by practical applications as well. Haskell is not just for academia, it is very much intended for practical use after all.
Re:Rust 1.37.0 by wtetzner on Wednesday August 21, 2019 @01:36PM (#20759394)
It is intended by it's creators as a research language. That doesn't mean it isn't suitable for practical use, it just means that you should expect it to continue to gain features and grow in complexity.
Re:Rust 1.37.0 by foldr on Friday August 16, 2019 @08:11PM (#20720898)
It's not C++'s goal either, AFAIK, but major new features keep getting added to the language anyway.
Re:Rust 1.37.0 by rkangel on Friday August 16, 2019 @05:08AM (#20713401)
I've already felt the slowdown in changes. I did have a (little) break from Rust and the only things that have changed are ergonomic improvements and the async stuff. This is a predictable outcome given the roadmap for this year was one of stability for the language.

When async/await stabilises, I think it's going to be less about the language changing and more about the ecosystem. I think there is going to be a lot of development on top of async over the next few years and we're going to learn a lot about the right way to structure programs and deliver useful abstractions. This is going to be particularly true in the embedded space I care the most about.

This is the hidden downside of having a good package manager - knowing how to use the ecosystem is as much of a skill in real world programming as knowing how to use the language. To be clear though - that cost is entirely worth it.

Re:Rust 1.37.0 by foldr on Friday August 16, 2019 @06:34AM (#20713763)
It could be. Rust has been stable Real Soon Now for quite some years.
Re:Rust 1.37.0 by rkangel on Friday August 16, 2019 @06:51AM (#20713843)
"Stable" is not a binary condition, and Rust has been moving continuously in a 'more stable' direction.
Re:Rust 1.37.0 by foldr on Friday August 16, 2019 @08:48AM (#20714616)
I'm not sure I agree with that. Async/await is a major new feature and is just landing now.
Re:Rust 1.37.0 by skept on Friday August 16, 2019 @09:26PM (#20721317)
Python is over 20 years old and got async/await only 4 years ago. I think most people would still consider Python a fairly stable language.
Re:Rust 1.37.0 by pjmlp on Thursday August 15, 2019 @02:41PM (#20708292)
Go, for sure.

Python, knowing it since version 1.6, I doubt it very much.

Re:Rust 1.37.0 by ausjke on Thursday August 15, 2019 @02:47PM (#20708334)
python 3x seems is a milestone, and relatively speaking, python is very readable
Re:Rust 1.37.0 by pjmlp on Thursday August 15, 2019 @03:05PM (#20708540)
Python is very powerful.

Reflection, meta-classes, decorators, comprehensions, slots, operator overloading, multiple inheritance and plenty of other features, some of them with semantics that changed across minor versions.

Python the full language, is at the same capability level as C++.

Many just don't realize it, because it is kind of targeted to teach programming and then people move on.

Re:Rust 1.37.0 by slx26 on Thursday August 15, 2019 @03:27PM (#20708773)
I'd say that's something Python does well. Many people don't realize because they don't need those features. If you can do with simple code and patterns, go with that. Rust on the other hand, hits you with all the complexity from the start (or a lot of it). I'm not saying this is necessarily bad, or that having a lot of "hidden complexity" is always good, the use-cases are different, but in many cases it's kinda good to not need to know about the things you don't need to use.
Re:Rust 1.37.0 by sitkack on Thursday August 15, 2019 @03:58PM (#20709033)
And the level of mutation one can inflict upon the runtime is magnificent!

http://farmdev.com/src/secrets/framehack/

https://github.com/lihaoyi/macropy

Re:Rust 1.37.0 by marmaduke on Thursday August 15, 2019 @06:10PM (#20710203)
Right, you can write your own debugger for Python in Python (assuming CPython).
Re:Rust 1.37.0 by sitkack on Wednesday August 21, 2019 @12:57AM (#20754672)
Yeah, and the cool thing about being able to write your own debugger, you can have domain specific debuggers or debuggers that put the application in the debug state and phone home giving the eng a chance to capture the error and handle it.

Lua has a similarly powerful debug hook mechanism. Being able to debug the system from within itself is an amazingly powerful feature.

Re:Rust 1.37.0 by treypitt on Thursday August 15, 2019 @07:15PM (#20710621)
Same theoretical capability; inferior performance and safety in general. Its versatility in the stack is, in my mind, its defining characteristic - unlike C++, it's a great scripting language that's easy to get started with- maybe the best. Like C++, it's a capable low-level, close-to-the-metal language. But I doubt it's the best choice for those cases. (We know what Linus said about C++ devs working on the kernel ... what would he say about python devs??)

Side bar, I wasn't aware it was a popular educational tool. I was taught type strong languages, and coming into Python felt like writing pseudocode. Too easy, as the Aussies would say!

Re:Rust 1.37.0 by pjmlp on Friday August 16, 2019 @01:13AM (#20712371)
You are mixing languages with implementations.

If CPython devs would care as much as Common Lisp, Dylan, Scheme, Smalltalk, JavaScript, Julia, it surely wouldn't be as slow.

There are PyPy, TrufflePython and OpenJ9 Python, they all suffer from the stigma of not being CPython.

Re:Rust 1.37.0 by goatlover on Thursday August 15, 2019 @03:10PM (#20708595)
Is it that readable when the code is making heavy use of advanced features like decorators and magic functions, or the code is deep into the inheritance hierarchy?
Re:Rust 1.37.0 by littlestymaar on Thursday August 15, 2019 @06:56PM (#20710506)
This comment is pretty ironic because Python changed so much changed in the past few years.
Re:Rust 1.37.0 by lukebitts on Thursday August 15, 2019 @02:10PM (#20707961)
Wow, hard disagree for me! I feel like Rust is the easiest language to maintain that I have ever used. I'm never afraid of changing things around since the compiler will always catch my mistakes and it is impossible (without unsafe) to introduce undefined behaviour. Whenever I'm using Rust my confidence levels are pretty much 100%. Having said that I don't know how the situation is for web dev since I'm a game dev, do you think that's the reason we have such different experiences?
Re:Rust 1.37.0 by Dowwie on Thursday August 15, 2019 @02:40PM (#20708273)
I'm using Rust full time for a lot of web dev. Using web frameworks and http clients hasn't been too painful, but asyncio web dev gets hairy because of the rules and syntax governing futures 0.1. Database dev using rust-postgres and extending it using its ToSql/FromSql traits has been very straightforward. Reading through the underlying source of these web frameworks / clients does involve medium/high difficulty, to varying degrees. Excessive use of generics ought to be curtailed, and it does but that seems to happen further down the pipeline as refactoring for readability plays a more important role. I can empathize with the OP, who has struggled to understand code written by others. It's not an issue just for Rust, though. Excessive use of object inheritance does no one any favors -- pick any language that features it and you'll find inheritance hell. Go also seems to have its own category of readability issues that people aren't being forthright about.
Re:Rust 1.37.0 by mslm on Thursday August 15, 2019 @02:25PM (#20708133)
This is precisely why I've lost interest in Rust. It feels limiting in the same way that fat frameworks do - it just becomes so much harder to express what I _really_ want to do sometimes, because I'm always working around the limits and requirements of the framework/abstractions which a lot of the time won't map very well to my solution.
Re:Rust 1.37.0 by jihadjihad on Thursday August 15, 2019 @05:12PM (#20709712)
What do you find is the solution to this problem? How do you remain productive? Genuinely curious since I am merely a Rust dilettante
Re:Rust 1.37.0 by zamadatix on Friday August 16, 2019 @08:52AM (#20714641)
Generally choose something "boring" instead, whether it be libraries or language choice.
Re:Rust 1.37.0 by nineteen999 on Thursday August 15, 2019 @05:25PM (#20709827)
> My productivity in Rust has become very low compared to other languages such as Go or even C, that let me easily express what I want to do.

As a C/C++ programmer who has being following Rust from a distance for sometime, with an intention to learn it later, this is somewhat concerning to hear. I've been meaning to start learning it for some time, however, my current workload doesn't provide enough spare time to start absorbing it.

In addition, it seems to be somewhat hard to find detailed information on how to do low-level things that would be very easy in C. Just as an example, one of our simulations relies on being able to craft raw UDP packets in order to "impersonate" remote basestations in our lab environment.

While this is trivial to do in C or C++, I haven't been able to find a good reference on how to do that with Rust. The lack of accessible documentation means that I'm unlikely to consider writing some of these more security sensitive parts of our system in Rust, even though there may be net benefits to doing so.

Re:Rust 1.37.0 by burntsushi on Thursday August 15, 2019 @05:37PM (#20709926)
That's just one take, and I very much do not agree with it personally. My productivity has only gone up as the tooling and language have improved.

One thing that I am working on figuring right now is the proliferation of dependencies. But that's a"nice" problem to have.

> Just as an example, one of our simulations relies on being able to craft raw UDP packets in order to "impersonate" remote basestations in our lab environment.

I would assume you would do it in Rust just like you would in C. Where's the hang up?

Re:Rust 1.37.0 by nineteen999 on Thursday August 15, 2019 @06:43PM (#20710426)
> I would assume you would do it in Rust just like you would in C. Where's the hang up?

Why assume? If you know it can be done, why wouldn't you provide a pointer to an example? I've done my Google searching and can't find one. There are endless examples of this for C online, I'm just stating that with a cursory search I couldn't find one for Rust.

The hang up is clearly at my end, I'm currently time poor, so now is not a good time for me to be learning a new language where I can't find good examples for what I'd use it for.

Admittedly I need to start at "Hello World" with Rust anyway before I get as far as crafting raw UDP packets. The point I'm getting at is if I didn't know how to program in either C or Rust, I'd pick C for this problem right now because there are clear examples. That's all.

Re:Rust 1.37.0 by burntsushi on Thursday August 15, 2019 @07:10PM (#20710581)
If you don't know how to do it because you don't know Rust, then fine, that's reasonable. (Albeit a strange criticism to lodge from my perspective.)

Otherwise, I would "assume" that you need to use libc bindings over ffi to use whatever udp APIs you would normally use from C. This is how Rust's standard library implements the higher level udp APIs for example: https://doc.rust-lang.org/std/net/struct.UdpSocket.html

But I used a question mark also because this is not something I've done before, so I can't share an example. I wasn't being adversarial. Even my suggestion above could be wrong. That is, I don't understand the essential difficulty here. Perhaps someone else can chime in.

Re:Rust 1.37.0 by nineteen999 on Thursday August 15, 2019 @08:06PM (#20710944)
Sorry, not to be rude but in this case is sounds like you don't understand the problem domain. Perhaps I should have just said "UDP spoofing".

There is a huge difference between creating a generic UDP endpoint like the code you have shown, and crafting a raw UDP socket, where the source IP address is "spoofed", and UDP checksums generated to ensure that the packet looks like a valid UDP packet so that the intermediate network infrastructure like routers, switches and firewalls will pass the forged packet rather than discarding it.

The latter requires quite a bit of extra code. A good example is here:

https://www.binarytides.com/raw-udp-sockets-c-linux/

and last time I looked (month or so ago?) I could not find an equivalent example for Rust. It may be out there but I was unable to locate it. I'm not asking you to do my homework for me, just stating that learning what I need to know in Rust to do the above would take more time than I have available right now. That's not to say I won't figure it out in the future when I have more time.

> If you don't know how to do it because you don't know Rust, then fine, that's reasonable. (Albeit a strange criticism to lodge from my perspective.)

It's not a criticism of the language; what I'm asking may be very possible, I don't know yet. I just know that finding C examples is trivial, Rust examples not so much, so when I had a need for this kind of code recently, I turned to the language where I know it can be done and I could easily find examples.

Re:Rust 1.37.0 by woah on Thursday August 15, 2019 @09:12PM (#20711292)
The specific task is so obscure, that only a language as widespread as C would have an example online for it. So people are confused when you name this as a criteria for selecting a language, since it’s a criteria that most likely only C can satisfy.

Then someone jumped to the conclusion that you were actually saying that Rust doesn’t have enough low level kernel APIs because that would make sense.

Re:Rust 1.37.0 by nineteen999 on Thursday August 15, 2019 @09:31PM (#20711391)
> The specific task is so obscure, that only a language as widespread as C would have an example online for it.

Well you could do it in Python I suppose - here's someone mentioning a solution using scapy, although it likely wouldn't work too well for my particular case due to Python performance.

https://stackoverflow.com/questions/51311741/generating-a-sp...

> So people are confused when you name this as a criteria for selecting a language, since it’s a criteria that most likely only C can satisfy

Rust is intended to be a replacement for C and C++, no? Eventually it will need to be able to do things like this if it is to be effective in that role. It's OK in my mind if it is not mature enough to do these kind of tasks yet, or if it can but I can't find a good reference yet. I wanted to use it for this task, but I selected C instead since it was easy to do that way and I didn't have a lot of time. Not holding it against Rust, it's a much younger language.

> Then someone jumped to the conclusion that you were actually saying that Rust doesn’t have enough low level kernel APIs because that would make sense.

I am almost completely certain I don't understand this sentence the way it is phrased.

Re:Rust 1.37.0 by rixed on Thursday August 15, 2019 @10:02PM (#20711529)
In case you want to give OCaml a try one day, I've done plenty of stuff like that in the past when I needed a (much) faster scappy. UDP exemple here:

https://github.com/rixed/robinet/blob/master/udp.ml

Re:Rust 1.37.0 by nineteen999 on Thursday August 15, 2019 @10:52PM (#20711742)
I'm not really a career programmer or language enthusiast, rather, I'm more of a utilitarian/imperative coder - I write programs to plug gaps in existing infrastructure as quickly, as securely, and as future-proofed as possible, even if it means dumbing the code down somewhat.

So I think my head would explode if I tried to learn a FP language without being able to have months off work to study. In addition to that, my team would kill me, as it's hard enough to find good C/C++ programmers in my city, let alone something like OCaml. Given that we run emergency services infrastructure, unfortunately we have to use more popular languages to ensure that the business doesn't end up with a lot of code written in languages they can't support.

Regardless, thank you very much for the example. It's nice to see that this can be done in other languages even if I can't understand it. Unfortunately too many years of C/C++ have made it hard for me to grok FP code - the C example I posted up before is much more readable to me.

Re:Rust 1.37.0 by ernst_klim on Friday August 16, 2019 @02:59AM (#20712786)
> So I think my head would explode if I tried to learn a FP language without being able to have months off work to study.

What's so hard you find about OCaml or FP in general you haven't had to deal with in your day-to-day imperative programming?

> Unfortunately too many years of C/C++

You mean you find OCaml making your head to explode after years of C and C++?

Re:Rust 1.37.0 by nineteen999 on Friday August 16, 2019 @03:31AM (#20712915)
> What's so hard you find about OCaml or FP in general you haven't had to deal with in your day-to-day imperative programming?

I guess I still find FP very abstract as a concept. I'm starting to like the notion of immutability as a design goal. But then I'm the kind of sicko who enjoys assembly language to some degree, where practically every instruction has a side effect, whether it be assigning a value to a register, or setting a bit in a flag register, or doing I/O whether port mapped or memory mapped.

> You mean you find OCaml making your head to explode after years of C and C++?

Not specifically OCaml, but most FP languages in general. I find the OCaml code posted up a couple of levels to be very hard to understand. But I'm very used to the POSIX interface and honestly programming against much else tends to get me out of my comfort zone a little too much. Shell, Perl and Python I can manage as well because I've been doing them so long, but I don't excel at those, particularly the latter two.

I think the paper referenced in this (https://news.ycombinator.com/item?id=15179188) HN article ("Some were meant for C") captures my mindset very well. Some of us are just a bit broken as programmers.

I also enjoy the ubiquity of C compilers - knowing that I can program in it from anything from a microcontroller to a multicore CPU (even being able to use the same compiler version accross many platforms) is a huge boost.

Re:Rust 1.37.0 by ernst_klim on Friday August 16, 2019 @04:00AM (#20713057)
> I guess I still find FP very abstract as a concept. I'm starting to like the notion of immutability as a design goal.

I'm rather asking about OCaml or SML than about something abstract matters like denotational semantics, system-F or pure lambda calculus.

There are pretty much the same abstract concepts behind imperative programming languages as well: operational semantics, Turing machines, which, I argue, are even more complex.

And if you write OOP, you have to deal with open recursion, covariant/invariant/contravariant subtyping relations, late bindings, polymorphic self type etc etc. There is a book called ``Theory of objects'' by Luca Cardelli (who is guilty for both SML and C++, BTW) if you are interested.

You just don't bother yourself with this theory, and neither should you when programming FP. You don't bother number theory and arithmetic (complex topics) when doing simple addition in your code, right?

> But I'm very used to the POSIX interface and honestly programming against much else tends to get me out of my comfort zone a little too much

Then maybe your starting point should rather be this [1].

(Although this book is rather about system unix programming in OCaml than about language itself. For learning the language its manual should fit pretty well [2], finding a sweet spot between a narrated book and a standard. Other good and more in-depth introductions are [3] and [4]).

There is also a unikernel called mirage os which includes TCP stack and other stuff and gives a good taste of what system programming in OCaml looks like.

https://github.com/mirage

Edit:

> But then I'm the kind of sicko who enjoys assembly language to some degree, where practically every instruction has a side effect, whether it be assigning a value to a register, or setting a bit in a flag register, or doing I/O whether port mapped or memory mapped.

FP doesn't disallow side effects, a usual FP practices just encourage to deal with them explicitly. There are low-level FP languages like ATS [5] (though I discourage you to look at it since it's unnecessarily complicated and could demotivate you), F* [6][7] and even Coq to some degree [8] which allow to deal with effects like allocations and state just fine (and prove invariants).

[1] https://ocaml.github.io/ocamlunix/

[2] https://caml.inria.fr/pub/docs/manual-ocaml/

[3] http://dev.realworldocaml.org/

[4] http://ocaml-book.com/

[5] https://www.youtube.com/watch?v=zt0OQb1DBko

[6] https://fstarlang.github.io/lowstar/html/Introduction.html

[7] https://fstarlang.github.io/lowstar/html/LowStar.html#memory...

[8] https://www.microsoft.com/en-us/research/publication/coq-wor...

Re:Rust 1.37.0 by nineteen999 on Friday August 16, 2019 @04:47AM (#20713292)
Thank you very much for all the time taken to collate all those links. I hope one day I will have the headspace, time and patience to absorb all that.
Re:Rust 1.37.0 by woah on Thursday August 15, 2019 @09:53PM (#20711499)
Re:Rust 1.37.0 by nineteen999 on Thursday August 15, 2019 @10:07PM (#20711544)
Thanks for this, those do look very helpful.
Re:Rust 1.37.0 by burntsushi on Thursday August 15, 2019 @09:22PM (#20711349)
Yeah, I mean, as I mentioned, I hadn't done it before. I feel like I've put an appropriate amount of uncertainty in my comments, but I still feel like you're punishing me for it.

In any case, I don't see anything particularly interesting in that C code. It's just shuffling data around and using some C functions, all of which is pretty easy to do in Rust. With that said, I do agree that translating that code would be non-trivial for a Rust beginner and would require getting pretty comfy in the language first. You'd likely also have to redefine any structs that you need in Rust (or use a tool like `bindgen` to generate bindings to, e.g., netinet/udp.h for you). But still, as an experienced Rust programmer, I think that C example would be enough for me to tackle this particular problem. So this might just be a case of being unfamiliar with the language, which is totally fair. There are going to be far less resources for Rust when compared to C.

Re:Rust 1.37.0 by nineteen999 on Thursday August 15, 2019 @09:46PM (#20711457)
Thanks for the advice regarding bindgen etc, I will look into that when I have more time. Generating the compatible structures (if Rust doesn't have them already) is one part of the problem, the other is really just the sendto() and socket() calls which as I mentioned are basically syscall wrappers for the most part. As per my other email, if I was writing this program in Rust, I'd prefer to use Rust all the way down rather then calling into C. Otherwise it's a Rust wrapper around C facilities. It should be possible do it all in native Rust code as far as I am concerned.

As per my other message, I apologize if I have offended you, it certainly wasn't my intention, I was just trying to clarify the use of the raw IP API, as opposed to the higher level solution which wouldn't work for our simulator.

Re:Rust 1.37.0 by burntsushi on Thursday August 15, 2019 @09:51PM (#20711491)
> It should be possible do it all in native Rust code as far as I am concerned.

Yeah, it would be, but Rust's standard library doesn't provide any way to invoke syscalls. You either need to go through libc's syscall wrapper, or write Assembly. I used the former to get access to faster directory traversal: https://github.com/BurntSushi/walkdir/blob/ec33af7f9b25afefc... (The rest of that code in that module may be interesting to you, since the API for getdents is pretty interesting and very C-like. Buttoning it up behind a safe API that can never be misused took a bit of thinking.)

Besides, Rust's standard library, on Linux at least, currently requires libc anyway. So you're already going to be linking to it.

Re:Rust 1.37.0 by nineteen999 on Thursday August 15, 2019 @09:41PM (#20711438)
My apologies - I don't mean to come off as adversarial either. And as I clarified in my other message, I should have just said UDP spoofing, so I probably contributed to the confusion.

> I would "assume" that you need to use libc bindings over ffi

I wonder about whether that is even necessary. socket() and sendto() are basically C library wrappers around system calls for the most part. Surely the Rust standard library already has equivalent wrappers, or will someday. There's no real reason I can think of that I'd need to FFI into C unless there is some limitation of the current Rust standard library.

Re:Rust 1.37.0 by burntsushi on Thursday August 15, 2019 @09:48PM (#20711472)
No worries.

You can use libc::syscall to make syscalls in the normal way, and that's technically ffi. Otherwise, to do raw syscalls, AFAIK you need to write some Assembly to do it. Running an assembler and linking it into a Rust program is pretty straight-forward. It would be nicer if one could use inline assembly (and let the compiler handle it for you), but that hasn't been stabilized yet.

The topic of whether to build a Rust standard library without libc is definitely one that has gotten some attention, and some folks have made some progress on that front, but AFAIK there is no serious ongoing project or effort that attempts this. Some folks definitely desire it though, at least for Linux. (In other platforms, like macOS and Windows, raw syscalls aren't a stable interface, so you kind of need to use the system libraries.)

Re:Rust 1.37.0 by arghnoname on Friday August 16, 2019 @04:27AM (#20713194)
I am not a Rust expert, but I've written kernel modules in it so I've had to deal with interacting with the foreign function interface and didn't have the benefit of any of its standard library.

The basic answer on this is you can specify that structures in rust have the same representation as a comparable C structure. If this isn't good enough for your use case (and it isn't when representing some wire format), then there are additional keywords to more precisely define the packing.

Of course, it's also possible to just have a binary blob of the appropriate size and write the appropriate values at the appropriate offset inside of it.

Generally I've been able to do whatever I need to do in Rust. I also wouldn't discount wrapping some C code at the very lowest layers. This isn't very different than using C code in a C++ project. Yes, it weakens type safety, but at the end of the day we have to get shit done, no?

To the higher level point of whether or not it's worth learning rust: I don't know. How much time do you spend implementing and how much time do you spend fixing? Rust increases the former and decreases the latter.

Re:Rust 1.37.0 by csomar on Friday August 16, 2019 @05:24AM (#20713467)
That's true. But you have to understand that Rust doesn't complicate things: Things are complicated. The difference between Rust and say, Python, is that Python hides lots of these complexities for you. This can have two sides effects: Performance and unintended consequences (bugs/hard to refactor/etc...)

Rust instead puts all of these complexities in front of you: Deal with it now.

So you have a choice: Deal with it now. Or deal with it later. And Rust has picked the former.

Re:Rust 1.37.0 by rapsey on Thursday August 15, 2019 @01:04PM (#20707169)
There definitely is a problem with some libraries using so many abstractions (traits) you have no idea how to use the thing.

I however do find writing rust to be quite enjoyable.

But I have so far entirely avoided the futures ecosystem and consider it a very good decision. One needs to have a very critical eye on what libraries to use

Re:Rust 1.37.0 by vbezhenar on Thursday August 15, 2019 @05:09PM (#20709688)
I can share similar experience. When I started to use Java, I happily digged into collections and stuff. It was quite easy to read and follow. Now with Java 8 I tried to read and follow their streams implementation. That was very hard. They implemented streams for semi-automatic parallelization which I never used and won't ever use and that made otherwise simple concepts just unreadable and unbearable. May be Rust developers tried to cover too big spectrum of the problems at once.
Re:Rust 1.37.0 by pornel on Monday August 19, 2019 @04:21PM (#20741436)
This is nonsense. Rust hasn't changed much since 1.0, but has matured a lot, and numerous small usability fixes add up, making it much nicer and productive than it was.

Rust is simpler to use, and simpler to learn than it ever was.

It has removed need for common pointless annotations (like ref in patterns, extern crate). Ambiguity of static vs dynamic dispatch in traits has been clarified with `dyn` and `impl` keywords.

The const generics feature is going to obsolete the worst-of-the-worst abuses of the type system trying to emulate that feature, and remove gotchas around arrays.

Async/await enables use of borrowed types in async code (freeing users from having to know about the `Pin`/`Unpin` implementation detail). Allows use of regular error handling, instead of requiring users to keep track of error types at each step in the chain of futures. It allows normal control flow instead of arcane wrangling with `Either` and boxing.

You listed a bunch of problems, and at the same complained that Rust has been solving them!

Re:Rust 1.37.0 by fetbaffe on Friday August 16, 2019 @04:38AM (#20713253)
"Go is the result of C programmers designing a new programming language, and Rust is the result of C++ programmers designing a new programming language"

https://drewdevault.com/2019/03/25/Rust-is-not-a-good-C-repl...

Re:Rust 1.37.0 by Dowwie on Thursday August 15, 2019 @01:25PM (#20707406)
You are entitled to your own opinions but not your own facts. Rust was never simple. :)
Re:Rust 1.37.0 by excursionist on Thursday August 15, 2019 @01:45PM (#20707642)
I would argue it was, and still is, simpler than modern C++.
Re:Rust 1.37.0 by kirubakaran on Thursday August 15, 2019 @03:54PM (#20708993)
Isn't everything simpler than modern C++?
Re:Rust 1.37.0 by TheDong on Thursday August 15, 2019 @04:30PM (#20709336)
Haskell would beg to differ.

Arguably, all dynamically typed languages are also more complex because there are huge classes of programs that are incorrect which simply would not even compile as valid programs in C++.

If complexity is based on how likely a syntactically correct program is also logically correct, then type systems remove a lot of complexity.

Re:Rust 1.37.0 by dragonwriter on Thursday August 15, 2019 @04:38PM (#20709399)
> Arguably, all dynamically typed languages are also more complex because there are huge classes of programs that are incorrect which simply would not even compile as valid programs in C++.

There are no programs (including ones that produce runtime failures) in a dynamically-typed language that cannot be duplicated in C++.

There are certainly dynamic-typed programs wthat will fail at runtime where the natural way to attempt to express the same idea in C++ would result in a compile time error, just as there are dynamic-typed programs that will operate correctly that are harder to express in C++ because you either have to do type gymnastics to convince the compiler of their correctness, or evade the compiler by building an interpreter for a dynamic-typed language, to do it in C++. This is a difference in where the complexity in each language lies, not the overall complexity.

Re:Rust 1.37.0 by excursionist on Friday August 16, 2019 @09:20AM (#20714846)
> If complexity is based on how likely a syntactically correct program is also logically correct, then type systems remove a lot of complexity.

Types are not really at the syntax level. I would measure the complexity of a language by the complexity of it's grammar and the size of the standard library/amount of common idioms needed to write most programs in a reasonable way.

Re:Rust 1.37.0 by Tuna-Fish on Thursday August 15, 2019 @06:22PM (#20710285)
It definitely is. But that is rather low bar to clear, given that modern C++ is by far the least simple programming language in wide use.
Re:Rust 1.37.0 by excursionist on Friday August 16, 2019 @09:24AM (#20714879)
Yes, but rust can be seen as an alternative to C++. They are closest in terms of features/power/performance.
Re:Rust 1.37.0 by aleden on Thursday August 15, 2019 @02:12PM (#20707992)
> When one of the oldest and still unanswered issue in the Hyper HTTP library is "how do I read the body?", there is a conceptual problem.

Is https://github.com/hyperium/hyper/issues/1137 the issue you are referencing?

Re:Rust 1.37.0 by hermanradtke on Thursday August 15, 2019 @08:56PM (#20711214)
I think it is. I answered it, along with others. But hyper is changing a lot so the question is asked again.

Strangely, the OP says async/await won’t help with things but in this case it would be a big help!

Re:Rust 1.37.0 by amedvednikov on Thursday August 15, 2019 @01:10PM (#20707248)
I'm working on a language with similar goals, but with the focus on simplicity:

https://vlang.io

A relatively stable 0.2 release will be out this month.

Re:Rust 1.37.0 by oconnor663 on Thursday August 15, 2019 @01:34PM (#20707506)
I'm curious about the example code at https://vlang.io/compare (apologies if you answered this before):

- Does the compiler use escape analysis to determine that the `cursor` variable needs to be heap allocated? If not, how does it know that the worker threads won't outlive the stack frame that owns `cursor`? If so, when does the allocation get freed? And does implicit heap allocation conflict with the goal of being as fast as C?

- How does the compiler know that the `lock` block is the only code that touches `cursor`? Does it still work if the `lock` block is in a subroutine? Does that require whole-program analysis? If two different `lock` blocks touch the same variable, are they implicitly a single `lock`?

Re:Rust 1.37.0 by kbd on Thursday August 15, 2019 @03:29PM (#20708797)
The two languages I'd be most interested in seeing added to that comparison are Nim and Zig. Those definitely have most of my mindshare on "new low-level/efficient languages simpler than Rust".
Re:Rust 1.37.0 by digikata on Thursday August 15, 2019 @05:46PM (#20710010)
Are you trying to do data lifetime analysis in V? I don't see that listed and to me it's pretty much Rust's key feature to enabling a high degree of memory leak and multithreading safety.
Re:Rust 1.37.0 by kzrdude on Thursday August 15, 2019 @02:05PM (#20707912)
Sounds very interesting. I guess you should compare compile speeds with D and Nim, since they are also interested in fast build times.
Re:Rust 1.37.0 by koszikm on Thursday August 15, 2019 @02:23PM (#20708117)
It looks nice, but I'd add to the comparison table that Erlang has both hot code reloading and no global state.