News for hackers. Stuff that matters.
Re:Why Go and Not Rust? by thelazydogsback on Monday September 16, 2019 @01:58PM (#20986800)
I can see moving from C/C++ to Rust for buffer-copying style codes, but for most code general-use programs the cognitive load required to deal with resource management seems way to high to move from from Java/C#/Node to Rust. (I just got called about a shop moving their Node code to Rust, and I can't imagine why any code that would make good Rust code was written in JS in the first place.) Go seems like a non-starter to me -- sure features can be abused (as implementation inheritance has been for years) but to omit generics at this point just seems silly.

As for moving from C# to Rust, you can learn to program with the Span<> APIs and get the non-GC perf. of Rust for the most part and still keep GC and other C# niceties (like the whole toolchain and ecosystem...) in much less time than a wholesale move to Rust. As as for message-passing/agent/channel programming, you can certainly do that in C# if you like, and though there is certainly a lot a foot-shooting that can be done with async and thread contexts, in general the Task<> system is a joy to use compare to almost anything else out there, not only for async code, but for concurrent code.

Don't get me wrong, I always thought that C++ was a "worst of all worlds" language and appreciate moving to Rust from there, but for most user-facing applications that tend to have complex object lifetimes, I just can't see why you'd want to deal with RIAA when modern GC's are so darn good.

Re:Why Go and Not Rust? by dochtman on Monday September 16, 2019 @02:16PM (#20986984)
Have you actually used Rust? I spend very little time (or code) on resource management when writing Rust code. And when I do, it's usually the compiler helping me understand an aspect of my design that doesn't work as I expected. Sure, other languages might allow me to gloss over that, but that will likely come down to finding the edge case in production.
Re:Why Go and Not Rust? by rubber_duck on Monday September 16, 2019 @03:22PM (#20987635)
Yes - rust type system is very restricted in what it can express because it needs to be verifiable at complie time - this means that some trivial things become a huge pain to describe to rust compiler and rust programmers seem to develop this Stockholm syndrome relationship with it and start singing it's praises on every turn. Memory management in dynamic graph structures with cycles is hard without GC, rust type system is not equipped to deal with this. Although you can still have leaks by holding on to unused references the problem becomes a higher level one and describing the structures/managing them becomes much simpler with a GC.

That guy saying that you can easily avoid GC in C# is also not realistic or doesn't know what he's talking about - even language expressions can lead to object allocation in C# - you really need to know what you are doing to avoid the landmines - it's very clear the language wasn't designed for this - if you need a lot of code like that.

Re:Why Go and Not Rust? by thelazydogsback on Monday September 16, 2019 @04:45PM (#20988411)
LOL, I'm "that guy" I think... Glad we agree about the complex/cyclic structures at least.

Regarding C#, I said for the most part. I stick by my assertion that (a) GC is quite efficient (esp.w/gen0 objects generated by your "expressions") and far from "lame" and (b) working with value types and Span<> (like Rust Slices) together can significantly reduce GC pressure to the point where it's acceptable, assuming there was actually an issue to begin with. Doing this in C# on hot-paths is certainly much less effort than moving to Rust wholesale, and you haven't thrown out the GC baby with the bath-water.

All the things that you do to make Rust efficient - allocate on the stack instead of the heap when you can, pre-allocate when size is known, use static/nested lifetimes, use slices to owned structures, etc., you can do in C#, but you don't have to worry about it until it actually becomes an issue.

If you're in the kernel or embedded system or the middle of a game rendering loop, then sure, Rust's compiler guarantees make this style programming easier if that's the way you want to go - and Rust has macros and other features that C# lacks. (Although the .Net JITTer is going to generate type-specialized methods and inline them, etc., w/a Rust macro you know up-front exactly what is being generated, which is nice.)

Re:Why Go and Not Rust? by rubber_duck on Monday September 16, 2019 @07:53PM (#20989717)
My experience in avoiding C# GC comes from XNA era when Microsoft had this shitty .NET runtime for XBox 360 allowing anyone to develop for it - the GC was so bad you had to be very very careful to avoid it and stuff like using foreach would allocate (AFAIK nowdays it can optimize it away in some cases but not in all and you still need to know when if you want to avoid allocation). People wrote code which avoided GC but it looked nothing like C# and in fact was more verbose than something like Rust or C++ and you were in uncharted territory since no allocation programming is not really C# thing and using high level features would just lead you into invisible traps. So you ended up using preallocated arrays, static functions, globals, etc. etc. in a language with poor generics (you can't even specify an operator as a generic constraint), no top level functions, etc. etc.

I've kept track of .NET progress since then and read about stuff like Span and ValueTask, ASP.NET Core team perf did a good job leveraging those for optimisations (eg. their optimised JSON parser) in such scenarios I agree C# with low level stuff sprinkled in is a good choice

But if your problem domain requires avoiding GC throughout and having better understanding on what the abstractions will compile to pick a language thats designed for that. It's like when I had to review some Java 6 code which tried to work around the fact that Java doesn't have value types with byte arrays - it was just soo bad compared to even C equivalent it was better to rewrite and go trough JNA.

Re:Why Go and Not Rust? by simonask on Monday September 16, 2019 @04:11PM (#20988095)
You are right that cyclic mutable graphs are very hard to model in Rust.

But very little code actually looks like that in reality. A lot of code looks like that by accident.

Re:Why Go and Not Rust? by brutt on Monday September 16, 2019 @04:28PM (#20988238)
Cyclic mutable graphs are very hard to model in _safe_ Rust (without arena). They can be implemented easily in unsafe Rust, using pointers instead of references, like in C.
Re:Why Go and Not Rust? by connicpu on Monday September 16, 2019 @05:27PM (#20988726)
They can also be implemented by not using pointer spaghetti ;)

Even in C++ I generally prefer to use handles over pointers for cases like that because graphs are just plain hard to get right, and if you use handles you can get a nice error message when something goes wrong instead of a segfault.

Re:Why Go and Not Rust? by banachtarski on Monday September 16, 2019 @02:37PM (#20987171)
To be fair, I spend the same amount of time on resource management in C++ too (compared to Rust). Unless I'm writing a data structure (happens occasionally) or some explicit resource management layer (texture pool, mesh LOD system, etc), I delegate management/ownership to the system designed to handle it.
Re:Why Go and Not Rust? by thegeomaster on Monday September 16, 2019 @03:40PM (#20987810)
I'm a hobby Rust user and I love the language, but I definitely feel the heavy hand of the borrow checker a lot of the times. It's the only language where coding can something seemingly simple can push me to the limit of my abilities and understanding.

However, I usually pick Rust for performance-critical code with quite a bit of concurrency, so the problems involved are inherently tricky. I'm gaining more and more intuition about ownership and rustc-friendly software design, and so I hope I'll be able to better understand if my struggle is due more to limitations of the compiler and Rust's semantics or the limitations of my skills.

For comparison, I've written ~6000 SLOC of Rust in my lifetime, so I do have some experience but I'm definitely not an expert.

Re:Why Go and Not Rust? by pjmlp on Tuesday September 17, 2019 @03:10AM (#20992481)
I use it occasionally and trying to port an old Gtkmm toy project to Gtk-rs was an eye opener regarding both build performance and the pain of dealing with callbacks in GUI code.

First having neither a build cache, or binary dependencies, means that C++ wins on the "make world" build, because naturally all my third party libraries are already compiled.

Then there is incremental compilation, incremental linking, pre-compiled headers and modules to help with the rest.

GUI code then becomes a fest of Rc<RefCell<>> in event handlers, or using arrays with vector clocks workaround as shown on Catherine's talk.

Re:Why Go and Not Rust? by cosarara on Tuesday September 17, 2019 @04:53AM (#20993047)
Could you link that talk?
Re:Why Go and Not Rust? by pjmlp on Tuesday September 17, 2019 @05:03AM (#20993092)
"RustConf 2018 - Closing Keynote - Using Rust For Game Development by Catherine West"

https://www.youtube.com/watch?v=aKLntZcp27M

Re:Why Go and Not Rust? by thelazydogsback on Monday September 16, 2019 @02:50PM (#20987294)
I have a bit -- but I don't have a project that makes sense to do in Rust at the moment. I'm mostly doing long-running symbolic AI code where I don't want to mess around with object lifetime because imposing the concept of "ownership" would be difficult. (F#/C# is the best fit at the moment.)
Re:Why Go and Not Rust? by arcticbull on Monday September 16, 2019 @03:08PM (#20987476)
It takes a little while to wrap your head around it -- I think it took me a solid 3 months before it clicked. Once it clicks though, the lifetime stuff is completely automatic. You really don't think about it. I think because Rust's syntax is so similar to what you might see in a C derived language it adds to the cognitive burden of learning lifetimes the first time around, but IMO, Rust should be the first thing people learn.
Re:Why Go and Not Rust? by marmaduke on Monday September 16, 2019 @03:08PM (#20987470)
> long-running symbolic AI code

That sounds cool. An obvious question is, why not a lisp? But generally do you find f# works well on dotnet mixed with c#?

Re:Why Go and Not Rust? by thelazydogsback on Monday September 16, 2019 @03:48PM (#20987877)
I love Lisp and Prolog the languages and I went there first -- the issue always turns out to be either (a) they make hard stuff really easy, but stuff that should be easy really hard, and (b) IMHO nothing even comes close to the .Net ecosystem when it comes to debugging tools, libs, etc. Clojure+Cursive comes closest, but the JVM world is a bit of a turn-off for me -- maybe I've been away from it too long, but it just seems a bit clunky. (And of course, reified generics, value types, etc., aren't available in the JVM.) The meta-programming story isn't as good as in Lisp/Prolog of course. JS (as others have said) an acceptable Lisp and has some advantages for the type of work I'm doing -- my problem with JS (and Typescript) isn't the language, but the run-time environment of Node, which makes things like true parallel programming a PITA and incurs serialization overhead between workers.
Re:Why Go and Not Rust? by marmaduke on Tuesday September 17, 2019 @01:23AM (#20991864)
Thanks fort he reply. I've been looking at f# or ocaml for a symbolic code generation project, but haven't been able to decide.
Re:Why Go and Not Rust? by munk-a on Monday September 16, 2019 @02:05PM (#20986868)
Ah the Generics, the fact that empty interfaces have been accepted as the way to get things done is absolutely terrifying to me. I understand that C++'s approach to generic type usage has slowly evolved into the most absurd collection of left angle brackets out there but Go seriously needs to shape up about generics, when people are regularly hacking your logic rules and advising others to do the same thing then... maybe there was an error in your rules.

Go is interesting and I really wonder how it'd be doing if someone went all in on the multi-return syntax sugar (pretty awesome stuff), the prohibition (mostly) on exceptions, channels and trivial threading and a bunch of other nicely packaged features while giving some ground on Generics. All languages have their warts, but I think this one is particularly easy to address - though it may take a major version bump and introduce some BC breaks I feel like those could be minimized, the biggest cost would be library incompatibility.

Re:Why Go and Not Rust? by erik_seaberg on Monday September 16, 2019 @03:07PM (#20987462)
Multiple return values are a lot less general and harder to use than tuple values; you can't store them in maps or pass them over channels or compose functions (while f(g()) works, f(g(), h()) is not allowed).
Re:Why Go and Not Rust? by masklinn on Tuesday September 17, 2019 @09:57AM (#20995116)
You could implement an entire corner of the language to work with special-cased / non-reified MRV, that's what Common Lisp does.

Go doesn't do that though. There is some magic for builtins (e.g. variable-arity MRV) but as usual mere mortals need not apply.

Re:Why Go and Not Rust? by otabdeveloper2 on Monday September 16, 2019 @03:18PM (#20987584)
> C++'s approach to generic type usage has slowly evolved into the most absurd collection of left angle brackets out there

C++ templates are a purely-functional Lisplike language. There's nothing strange or absurd about it; it's a very vanilla way to approach string rewriting systems.

(It's ugly to read, yes, but then all Lisplikes are too.)

Re:Why Go and Not Rust? by nwallin on Monday September 16, 2019 @07:05PM (#20989447)
> but for most user-facing applications that tend to have complex object lifetimes, I just can't see why you'd want to deal with RIAA when modern GC's are so darn good.

My day job is ~half c++ and ~half c#, and I couldn't possibly disagree more.

The first problem is IDisposable and event handlers. Because c# doesn't have anything like weak pointers, event handlers require that you manually dispose of half your objects. In c, there's a simple rule: you always dispose of your objects. In c++, there's a simple rule: the destructor of your data structure/smart pointer always disposes of your objects. In c#, the rule isn't simple. Half the time, you have nontrivial destructor doing nontrivial things, the other half the time you can leave it up to the GC. But it isn't necessarily immediately clear which is which.

The second is `using`. Again, you must necessarily mix the semantics of non-deterministic GC cleanup and deterministic RAII cleanup. Which is worse than having a simple rule that always works.

Re:Why Go and Not Rust? by Const-me on Tuesday September 17, 2019 @02:49AM (#20992368)
> c# doesn't have anything like weak pointers

https://docs.microsoft.com/en-us/dotnet/api/system.weakrefer...

https://docs.microsoft.com/en-us/dotnet/api/system.weakrefer...

https://docs.microsoft.com/en-us/dotnet/api/system.runtime.c...

> event handlers require that you manually dispose of half your objects.

You probably have software design issue on your day job. C# events can be great, but they're not a silver bullet.

For loosely coupled application wide events, event aggregator pattern works better, see IEventAggregator from Caliburn.Micro for an example.

If the two sides of the event handlers need strong coupling for a good reason, an interface or abstract class for the consumer works better, see ExpressionVisitor from System.Linq.Expressions for an example.

Re:Why Go and Not Rust? by pjmlp on Tuesday September 17, 2019 @03:13AM (#20992501)
You forgot to add safe handles as well.

https://docs.microsoft.com/en-us/dotnet/api/system.runtime.i...

This and the the thread of the other day regarding having to use C for what C# is capable of, apparently many don't look on their toolboxes.

Re:Why Go and Not Rust? by qaq on Monday September 16, 2019 @05:59PM (#20988988)
There is obviously a learning curve but it's hard to argue that:

#[get("/hello/<name>/<age>")]

fn hello(name: String, age: u8) -> String {

    format!("Hello, {} year old named {}!", age, name)
}

is more complex than express + Node. With added bonus that you get validation for free

Re:Why Go and Not Rust? by tinco on Monday September 16, 2019 @07:52PM (#20989711)
I'm a firm believer in that Rust is the greatest imperative programming language ever designed. But your example is a pathologically simple problem with a horrendously complex solution in Rust. In responding to a simple get request you have to lean on both function annotations and a macro. That code would be so much nicer in Ruby.
Re:Why Go and Not Rust? by qaq on Monday September 16, 2019 @11:43PM (#20991208)
Would you post an equivalent code in Ruby ? (that like above does validation of inputs)
Re:Why Go and Not Rust? by tinco on Tuesday September 17, 2019 @06:26AM (#20993444)
If you need input validation like that, which you normally wouldn't in Ruby because your models should do it for you, I'd probably use grape or something similar:

  require 'grape'

  params do
    requires :age, type: Integer
    requires :name, type: String
  end
  get "/hello/:name/:age" do
     "Hello, #{params[:age]} year old named #{params[:name]}!"
  end

In any case, my beef is more with the macro than with the function annotation, which is rather spiffy. The macro hides the fact that string manipulation in Rust definitely requires a little bit of manual reading. And I feel that as soon as your app becomes more complex Rust will just start getting more in the way. And to an experienced Rust dev that might not be a big deal, because an experienced dev knows how to work with strings or which memory management strategy so it won't bog them down. But if you're just working on something and you quickly want to whip out a service that tells people what age they are, I'd definitely go for a quick Ruby or Go service.
Re:Why Go and Not Rust? by steveklabnik on Tuesday September 17, 2019 @11:13AM (#20996118)
One of the things this API can do for you is not give you just strings, but fully typed instances of structs. And you don’t need to do the conversions yourself. So you’re not wrong, but it’s easier than you may imagine.
Re:Why Go and Not Rust? by johnlinvc on Tuesday September 17, 2019 @02:36AM (#20992289)
Not exactly the same, since there's no UInt8 in Ruby.

    require 'sinatra'
    get %r{/hello/([^/]+)/(\d+)} do |name, age|
      "Hello, #{age} year old named #{name}!"
    end
Re:Why Go and Not Rust? by qaq on Tuesday September 17, 2019 @02:49AM (#20992370)
I am guessing age would be a string though?
Re:Why Go and Not Rust? by johnlinvc on Tuesday September 17, 2019 @03:12AM (#20992495)
yes, the regex part handles the validation.
Re:Why Go and Not Rust? by otabdeveloper2 on Monday September 16, 2019 @03:04PM (#20987432)
> the cognitive load required

There's no cognitive load required to code in C++. You just don't know the language.

There's no easy tutorials or learning materials for it, but it's not hard.

Re:Why Go and Not Rust? by arcticbull on Monday September 16, 2019 @03:11PM (#20987507)
Im not sure if this is sarcasm, honestly. C++ is one of the hardest languages to use, full of edge cases, it blows my mind every time I pick it up.

> You just don't know the language.

Nobody knows the language haha. If anyone tells you they know C++, they're absolutely wrong. This has been, IME, the easiest way to know if a candidate is over-stating their resume -- if they say they "know" C++.

Re:Why Go and Not Rust? by otabdeveloper2 on Monday September 16, 2019 @03:21PM (#20987617)
> C++ is one of the hardest languages to use,

No.

> full of edge cases,

Definitely no.

> it blows my mind every time I pick it up.

I'm tempted to say "programming is not for you", but I'll be charitable and just point out that you've never learned the actual language to make statements like that.

> If anyone tells you they know C++, they're absolutely wrong.

That's a load of crapola. It's impossible to "know C++" in the sense of knowing the ISO standard for C++; but that is also true of any other language with a real standard.

Languages without standards, of course, are worse in every way.

Re:Why Go and Not Rust? by munk-a on Monday September 16, 2019 @04:03PM (#20988025)
C++ (as a result of it's C roots) has one of the most obscure and arcane library assumptions out there. Different platforms only need to roughly adhere to a standard and this can cause wildly different usages. Additionally it's the only language I've ever worked in that provides ample opportunities to blow off your own foot while copying a string. Lastly `const` what does it do where and why and should everyone ever use it... C++ is one of the simplest languages at a surface level, but the standard is incredibly dirty.
Re:Why Go and Not Rust? by otabdeveloper2 on Friday September 20, 2019 @03:08PM (#21030135)
> Additionally it's the only language I've ever worked in that provides ample opportunities to blow off your own foot while copying a string.

False.

    std::string x = y;
There's no way to mess this up.

Again, learn the language. There is no such thing as "C/C++". 99% of the problems stem from the fact that people don't understand that C and C++ are completely different languages, despite sharing one compiler.

Learn C++ as itself and your problems go away.

> Lastly `const` what does it do where and why and should everyone ever use it...

`const` is a contract that means "I will not modify this object here". Nothing confusing or complex about it, unless you're trying to shoehorn this concept into C semantics somehow.

Re:Why Go and Not Rust? by code_sloth on Monday September 16, 2019 @03:53PM (#20987922)
>> C++ is one of the hardest languages to use

> No.

Most defenses I've seen of C++ boils down to something along the lines of "you're using it wrong (tm)".

I've seen enough C++ to take the side of "the design is probably wonky if it's that easy to do the wrong thing."

Re:Why Go and Not Rust? by otabdeveloper2 on Friday September 20, 2019 @03:15PM (#21030202)
> Most defenses I've seen of C++ boils down to something along the lines of "you're using it wrong (tm)".

Maybe, but that wasn't what I said. The problem is that lots of people know C, but very, very few people know C++.

A big part of the problem is that both languages share one compiler, and people come from C thinking that C++ is just an upgrade with some features bolted on.

It's not. It's a completely different language, and if you approach it as "I'll learn a bit of C and then throw in some C++ features" you're setting yourself up for a world of hurt.

The hurt goes away if you forget C, start with a clean slate and learn C++ as a new language.

Re:Why Go and Not Rust? by kinjba11 on Monday September 16, 2019 @11:45PM (#20991229)
C++ has more historical baggage than any other mainstream language. Consider something as simple as initialization: https://www.youtube.com/watch?v=7DTlWPgX6zs
Re:Why Go and Not Rust? by marmaduke on Monday September 16, 2019 @03:33PM (#20987739)
That's not true, and an example of it would be scoping rules. If you see 'x' in the code for a method, there are strictly more places that could come from than in say, Python or Gp, than in C++.