Hacker News new | ask | show | jobs
by justthistime_ 3889 days ago
> Rust itself isn't particularly influenced by Scala

Agree! Sadly, they didn't use all the lessons Scala could offer them when designing their own language. :-(

Painful to watch as they introduce stuff where Scala developers already know that it's completely broken.

2 comments

Rust and Scala operate in entirely separate contexts, are intended for entirely separate domains, have entirely separate goals, and are intended for entirely different sets of programmers. Lessons that apply to Scala do not necessarily apply to Rust.
There is still a huge chunk that does.
Your point would be bolstered if you would start speaking in specifics. :)
Would you mind expanding on what these things are?
The cascade of efforts at error handling, which I think at one point involved a macro and a magic method name, rather than getting on with higher-kinded types to allow them to do it right.

Allowing "return".

Mandating braces for functions and control flow constructs.

Rust iteration, which is both more limited and less safe (laziness) than the scala/ruby style of passing a closure.

  > The cascade of efforts at error handling
You must be referring to ancient Rust with its condition system and such. Modern Rust code just uses Result types.

  > rather than getting on with higher-kinded types to allow 
  > them to do it right
Er, no, you don't need HKTs to "do it right", you'd just need HKTs to do it generically. Rust's error handling works fine for specific types; you can even write macros to emulate do-notation (and people have).

  > Allowing "return"
Welcome to the realities of imperative programming. :) Unlike Scala, Rust does not aspire to functional godhood.

  > Mandating braces for functions and control flow constructs
Scope in Rust is very, very important for expressing when references go out of scope and when resources are freed. Leaving scope implicit would be massively frustrating.

  > the scala/ruby style of passing a closure
Rust had internal iterators for years, and the entire `for` construct was based around them. They were removed because they were found wanting.

As I've mentioned in a sibling comment, the lessons that Scala may have learned in its life do not necessarily apply to Rust. They are very, very different languages.

I am a Scala developer but I agree with your points. The only thing that just simply drives me mad in Rust is mandatory semicolons. Once you are used to be able to omit them then it gets really annoying to go back using them.
I actually agree with this one. :) The usual argument in their favor is that having to explicitly return `()` all the time would get tired in low-level C-alike functions that mostly operate via side effects, but I'm not particularly swayed that we should be optimizing for that use case (but then again I'm also of the opinion that bitwise operators don't deserve their own symbols, so I may already be an enemy of this crowd :P ).
Thank you! It's really hard to understand where criticism is from without specifics, even if you're not the OP.

I would love higher kinded types, but most of our users are asking for other type system features first. What we've done doesn't preclude a HKT style in the future, as the signatures are the same.

I'm not aware of an imperative language that doesn't allow early returns, maybe there are some, but I find 'guard clauses' to significantly combat rightward drift.

Braces are to appeal to our core audience, who have been using braces and semicolons for decades. Absolutely, 100% subjective though, I know people who prefer the whitespace-based syntax, but you really only get one or the other.

  > Rust iteration, which is both more limited and less safe (laziness) than the scala/ruby style of passing a closure. 
I'm not sure specifically what you mean here, around both safety and closures.

Here's Rust:

    let v = vec![1, 2, 3];
    let v1 = v.iter().map(|x| x + 1).collect()
Here's Ruby:

    v = [1, 2, 3]
    v1= v.map {|x| x + 1 }
Other than the laziness, both are "pass a closure." And I'm not sure how safety ties in here at all.

Most of these things seem like subjective preferences, rather than things that are "completely broken."

> I would love higher kinded types, but most of our users are asking for other type system features first. What we've done doesn't preclude a HKT style in the future, as the signatures are the same.

I think many users don't know that they want higher-kinded types, only that they want particular features.

> I'm not aware of an imperative language that doesn't allow early returns, maybe there are some, but I find 'guard clauses' to significantly combat rightward drift.

I don't know what you consider an "imperative language"; I'd consider Scala an example. I think a decent error mechanism (which Rust does have, even if the implementation is ad-hoc and reliant on a macro) provides a better way to express guard clauses. I think return is untenable in a language with lambdas, because any possible choice of semantics for return inside a lambda (including "compile error") will confuse a decent proportion of programmers.

> Braces are to appeal to our core audience, who have been using braces and semicolons for decades.

If by your core audience you mean C++ users then they're used to being able to omit braces on if/while/etc.

> Other than the laziness, both are "pass a closure."

I'm objecting to the .iter() part. Or perhaps more generally to the lack of something as extensible as do or for/yield. The for/yield construct turned out to be far more valuable to Scala than was realised initially.

> And I'm not sure how safety ties in here at all.

I meant unsafe in the colloquial sense. I think laziness makes programs very hard to reason about.

> Most of these things seem like subjective preferences, rather than things that are "completely broken."

I agree that they're not completely broken, but I think they're more than subjective; in many cases Scala has tried the various options over the years. We've tried exceptions and macros and found a better way of doing error handling. We've had return in the language and discovered it to be more trouble than it's worth. We've had a notoriously flexible syntax around function calls and seen a consensus on the best style develop over the years. We've seen some control-flow structures virtually wither away and others become indispensable.

> Or perhaps more generally to the lack of something as extensible as do or for/yield. The for/yield construct turned out to be far more valuable to Scala than was realised initially.

Yield doesn't make a whole lot of sense in a systems language with machine-level control over stacks and allocation. It doesn't make a whole lot of sense in a systems language where the idea of jumping out of a stack frame either means doing strange low-level stack jumping tricks (defeating standard CPU/compiler optimizations) or allocating behind your back (which is something that Rust never does). Very early Rust actually tried using yield for iteration and it didn't work.

> We've tried exceptions and macros and found a better way of doing error handling. We've had return in the language and discovered it to be more trouble than it's worth.

We've experimented with these too. And I use return all the time in Rust. It's really useful and I would hate to see it go away.

I think Rust and Scala are just different languages. One's an applications language built on the JVM and the other is a low-level systems language with manual memory management. That difference means that different decisions may be appropriate.