Key point being, similar to some random languages. JS and Python Syntax don’t fit a typed and compiled language at all.
Pretty syntax would probably be something like C, where not every single character already widely reserved for specific keywords (like !, ', =) is reused in completely random ways.
Ah yes I also found macro syntax like vec![ and println!( to be a bit jarring at first. However I don’t know if I would say that C’s approach to macros is any nicer, with it’s #define magic
fnmain() {
letfoo = 10;
// Suddenly, types are implicit now. A safe language should never have implicit types (now it's the (IDEs) implementations judgement which type that is. Combined with the variable shadowing "feature", this seems like a major clusterfuck. Now the IDE is the sole thing to tell you that you totally fucked up the logic, and both declarations/definitions (well which one is it? Would be nice to always have a direct KEYWORD telling you which type this fucking variable has. But no, the lazy piece of shit Rust 'programmer' left that as an exercise to the dear reader. Because in they just need to leave that part out instead of explicitly stating "I'm a lazy piece of shit" by *instead* typing 'auto'.) This is just Python-level BS. Yes, I also hate C++ for its auto keyword - but at least it explicit.println!("The value of foo is {foo}");
letfoo = 20;
println!("The value of foo is {foo}");
}
fnadd_two(x: i32) ->i32 {
// That is, again, the syntax of Python. Why? Because Python is explicitly untyped. So having types be a *literal* afterthought is Ok. They're fully optional anywhere there. Now we're in Rust. They're sometimes optional, sometimes not, but they're always preferred. Yet, they're also an afterthought, seemingly.
x + 2// Implicit statements are bad. Very bad. They so much invite to glossing over stuff, especially when your brain expects to see something else. Also, having every statement ended with ;, except context blocks, but suddenly *not* having statements ending with ;, is fucking ugly (which is the entire point of this rant). It's completly inconsistent. Which in itself is a huge magnet for errors.
}
if x > 5 {
// Now why would you leave the parantheses, which are a major contributor to readability, away. Or even allow this. Rust is just memory safe, like dozens of other mainstream languages, but continues by allowing, promoting and requiring hazardous practices.println!("value is greater than five");
}
Now I’m slowly getting annoyed from typing on phone (at least in nvim), and my throat gets clogged with mucus again.
Remember, some of that are subjective preferences and opinions. And the core idea of Rust - fast but safe programs - is good, yet very obvious and not innovative at all, while the syntax and implementation (of cargo (yes I like to wait an hour for a simple webapp to compile because there aren’t binary crates and cargo just doesn’t multicore 99% of the time)) is subpar to something that’s hailed as the savior for everyone and everything by such a large cult.
Types are not implicit, they’re inferred by the compiler when there is no ambiguity about what the type needs to be. This is a huge benefit for refactoring code and reducing maintenance. I acknowledge that sometimes you might care to know the exact type of the variable, and sometimes that’s not as easy for a human to infer as it is for the compiler, but every decent IDE will provide inline type hints for you. Interpreting code by reading it in plaintext is an exercise in masochism.
Python is actually the opposite on this, and it’s one of Python’s worst characteristics. The type is unknown until runtime unless you annotate it, and then the annotation isn’t really enforced. It’s the worst of every dimension.
C++11 introduced auto, and now the community is split between “almost always auto” and “never auto”.
JavaScript needed a whole new compiled language (Typescript) to fix its type system problems, and Typescript is only an incremental improvement at best.
Rust has the best type system of any modern language by far. If you’re tripped up by not always seeing the type declarations then you’re either focusing on the wrong details in the code or you just need a little more practice. The key thing that needs to sink in for new Rust users is that the compiler is always providing safety rails. That means it’s no longer your job to verify that every aspect of the code is correct. You can relax a little and actually have something akin to duck typing without all the pitfalls that usually come with it.
In practice, type inference in Rust is not a problem since the language is so strongly typed. In fact, it is more strongly typed than both C and C++, and will force you to cast values explicitly in cases where C and C++ will happily mess up your variables without warning. The absence of type inference would also be a major pain, since nested types such as iterators can get quite complex and very verbose. If you’ve programmed using older C++ standards, then you know this pain
It’s incredibly disingenuous to call this average Rust code and further erodes your credibility. I may as well point to hundreds of lines of preprocessor macros in a C++ header and call it average C++ code.
This is not what an average Rust developer is writing 99% of the time. If someone on my team submitted a PR with an implementation of sum that uses macro_rules! I would almost certainly reject it.
Haskell has the choice of both indentation based and brackets for things like do blocks, but most people use indentation based cause it’s the norm and looks cleaner
Whatever your place defines as a standard. I’ve seen ugly code in C, JavaScript, Java, etc., that uses them all over the place because they’re not mandatory.
If you don’t have consistent indenting, your code looks like copy/paste from several sources; but if you do have consistent indenting, then the indenting of Python is a non-issue.
Tabs are 8 characters, and thus indentations are also 8 characters. There are heretic movements that try to make indentations 4 (or even 2!) characters deep, and that is akin to trying to define the value of PI to be 3.
List comprehensions are much stranger than tabs vs spaces. There are very very very few languages that use them, and python’s is by far the worst out of the popular ones.
I’m not saying I don’t understand them. I’m saying the syntax is terrible. Compare it to Ruby (or any other modern language) and it’s abundantly clear.
python (uses syntax not available in any other top 25 language)
print([j**2 for j in [2, 3, 4, 5]]) # => [4, 9, 16, 25]
ruby (normal chain syntax with map)
puts [2, 3, 4, 5].map{|j| j**2}
even kotlin is more readable, even though you have to convert to a double and back
kotlin
val list = listOf(1,2,3,4)
println(list.map{it.toDouble().pow(2.0).toInt()})
For nested cases it’s even more apparent:
python
digits = [1, 2, 3]
chars = ['a', 'b', 'c']
print([str(d)+ch for d in digits for ch in chars if d >= 2if ch == 'a'])
# => ['2a', '3a']
val digits = listOf(1, 2, 3)
val chars = listOf('a', 'b', 'c')
println(digits.flatMap { d ->
chars.filter { ch -> d >= 2 && ch == 'a' }.map { ch -> "${d}${ch}" }})
just from a base level, you have to read the middle of the comprehension first, then the end, then the beginning. It’s a completely backwards way to write and read code. unlike other languages that use a ‘functional’ approach, where it’s chained methods or pipes, etc. Even Elixir, which does have list comprehensions, reads and writes in the proper order:
I can actually see where this is coming from, as I found Rust hard to read when I started out. I do really like Rust for reference, but I do agree Rust is hard to read for someone that has not learned it.
For example:
return statements that are implicit just because the semicolon isn’t there. Even better if they occur inside a if block or something like that. Very hard to understanding when you don’t know the syntax rules.
Lambda functions, especially when using move semantics too. They are quite simple, but if you don’t know the meaning, it’s more arcane characters. Especially when this is used inside lots of chained methods, and maybe a multi-line function in the lambda.
A lot for the if let x =… type of stataments are tough the first time around. Same for match statements.
Defining types for use with function::<Type>() and such.
Lifetimes, especially when they are all named a, b, c etc. It quickly gets messy, especially when combined with generics or explicitly defined types.
Macros, though not entry level rust to begin with, they are really cumbersome to decode.
None of these are sins of Rust, but for new people they are a hill to climb, and often hard to just “get” based on previous programming experience and reading the code. Rust can be really hard to approach because of these things. This happens in other languages too, but I do feel Rust has a particularly large amount of new concepts or ways to do something. And this is on top of learning lifetimes and borrow semantics.
This is the most sober take in this thread. I was bothered by all these things you mentioned for the first two weeks of using the language. I begrudgingly accepted them for the following two months because I felt the benefits of the language were worth it. Now all of these things feel natural and I don’t give them a second thought.
They might not be strictly language issues, but if they are symptomatic of idiomatic rust then they are “sins of rust”. Something about the language promotes writing it using these kinds of idioms.
Just like French speakers don’t pronounce 80% of the written syllables because it’s impractical to speak fast with all of them…language features (or lack of them) drive how the language is used.
(BTW the implicit return behaviour on a missing semicolon sounds like Chekhov’s footgun)
Something about the language promotes writing it using these kinds of idioms.
As someone who has used Rust professionally for 3 years, the idioms are good. I wouldn’t want the idioms to go away, and I don’t particularly want the style/aesthetics of the language to change unless it can be done without negatively affecting the idioms.
It’s not a situation where the aesthetics are actually bad, it’s just different than what most programmers are used to, but almost all of the differences are for pretty good reasons. With enough familiarity and practice you’ll start to recognize those differences as benefits of the language rather than detriments.
But I think a lot of people have so much inertia about tweaking their way of thinking that they don’t feel motivated to try long enough to make it over that hump, especially when their expectations get set by rabid Rust promoters like myself who insist that Rust is vastly superior to any other languages in almost all situations. The stark contrast between how good they’re told the language is and how they feel when first exposed to it might be too much whiplash for some people.
I recognise that different languages have different styles, strengths and idioms. One of my pain points is when people write every language as if it’s naughties java. Enough with the enterprise OoP crap.
I’ve also learnt languages like Haskell to expand and challenge the way I think about software problems. I learnt a lot doing it. That doesn’t stop a lot of Haskell code looking like line noise to me because it over-uses symbols and it being close to impenetrable in a lot of cases when you read somebody else’s code.
I think the aesthetics of Rust are the wrong side of the line. Not as bad as something like Haskell (or Perl), but still objectionable. Some things seem to be different even though there’s pre-existing notation. Things seem to be dense, magical, and for the compilers benefit over the readers (as an outsider).
I’ve been learning Zig recently and the only notational aspect I struggled with was the pointer/slice notation as there’s 5 or 6 similar forms that mean fairly different things. It has other new concepts and idioms to learn, but on the whole it’s notation is fairly traditional. That has made reading code a lot more approachable (…which is a good thing because the documentation for some aspects sucks).
I’m not sure, what you mean by “Chekhov’s footgun”, but well, it isn’t a footgun, so you won’t accidentally return a wrong value from the function, if that’s what you’re thinking.
It’s not a Rust invention, most functional programming languages have implicit returns, but basically think less of them as a function return and more just as the value that a scope evaluates to.
So, here’s a simple example:
letsum = {
letx = 5 + 9;
3 * x
};
Obviously, this is an extremely contrived example, but yeah, as you can see, it does not even have to involve a function. The implicit return makes it so that sum is set to the result from 3 * x.
And the scope-braces are nice here, because you can do intermediate steps without having x in scope for the rest of your function.
In practice, if you see scope-braces and the line at the end does not have a semicolon, then that’s the value that the whole scope evaluates to. Those scope-braces can also be the braces of a function, but then you need to annotate what the function is going to return, too, so it’s practically impossible to return a wrong value.
Well, and I would actually argue that explicit returns are a footgun in comparison.
Because someone might introduce clean-up code at the end of the function and not realize that an explicit return skips that clean-up code, somewhere further up in the function.
The implicit return always has to be at the end of the scope, so it’s not possible to accidentally skip code.
The implicit return is perhaps the most dubious of them. I don’t mind it for simple functions, but they are not so good in anything large and with multiple return sites. Even more so when developers choose to implicitly return 4 chained method calls inside a closure with else cases.
But the rest aren’t really sins, they are mostly new or different concepts or ways to do something. And if there is a sin, it’s largely because the language itself has a complexity larger than others.
Taking my own examples here, lambdas are just fine, but the move semantics are cumbersome to deal with. But we need to do it some way, to indicate that a value is actually being moved into the closure. Maybe there are better ways and they make into the language in the future.
Conditional values and let statements and such is a good consequence of Rusts design choice with returning Results or Option types. Just because it’s different doesn’t make it a sin. Just takes time to learn the right way. I think most come from an exception based language, and that has a differnet code flow than what Rust has.
Lifetimes are hard though, and I feel a lot of the introduction is made excessively hard with the simple naming. It’s as of every programming tutorial used single letter variable names. Lifetimes isn’t something I’m that good with either, mostly because I haven’t had to use that complexity yet.
Almost any language is OK, but Rust is just so, so fucking ugly
Almost any language is ok but some ecosystems make me want to turn into a murder hobo (looking at you, JavaScript).
Also looking at Rust. Yeah, I totally like recompiling thousands of crates for a single webapp single-threaded.
Try using luarocks with luajit.
what? what part of rust is ugly?
Literally every single bit of the syntax.
The majority of its syntax is very similar to many other languages. Can you give an example of a language with pretty syntax?
Key point being, similar to some random languages. JS and Python Syntax don’t fit a typed and compiled language at all.
Pretty syntax would probably be something like C, where not every single character already widely reserved for specific keywords (like !, ', =) is reused in completely random ways.
Ah yes I also found macro syntax like
vec![andprintln!(to be a bit jarring at first. However I don’t know if I would say that C’s approach to macros is any nicer, with it’s#definemagicBeing unable to give an actual example proves you’re just a foaming-mouth hater with nothing to contribute.
From the first syntax examples on Wikipedia:
fn main() { let foo = 10; // Suddenly, types are implicit now. A safe language should never have implicit types (now it's the (IDEs) implementations judgement which type that is. Combined with the variable shadowing "feature", this seems like a major clusterfuck. Now the IDE is the sole thing to tell you that you totally fucked up the logic, and both declarations/definitions (well which one is it? Would be nice to always have a direct KEYWORD telling you which type this fucking variable has. But no, the lazy piece of shit Rust 'programmer' left that as an exercise to the dear reader. Because in they just need to leave that part out instead of explicitly stating "I'm a lazy piece of shit" by *instead* typing 'auto'.) This is just Python-level BS. Yes, I also hate C++ for its auto keyword - but at least it explicit. println!("The value of foo is {foo}"); let foo = 20; println!("The value of foo is {foo}"); }fn add_two(x: i32) -> i32 { // That is, again, the syntax of Python. Why? Because Python is explicitly untyped. So having types be a *literal* afterthought is Ok. They're fully optional anywhere there. Now we're in Rust. They're sometimes optional, sometimes not, but they're always preferred. Yet, they're also an afterthought, seemingly. x + 2 // Implicit statements are bad. Very bad. They so much invite to glossing over stuff, especially when your brain expects to see something else. Also, having every statement ended with ;, except context blocks, but suddenly *not* having statements ending with ;, is fucking ugly (which is the entire point of this rant). It's completly inconsistent. Which in itself is a huge magnet for errors. }if x > 5 { // Now why would you leave the parantheses, which are a major contributor to readability, away. Or even allow this. Rust is just memory safe, like dozens of other mainstream languages, but continues by allowing, promoting and requiring hazardous practices. println!("value is greater than five"); }Now I’m slowly getting annoyed from typing on phone (at least in nvim), and my throat gets clogged with mucus again.
Remember, some of that are subjective preferences and opinions. And the core idea of Rust - fast but safe programs - is good, yet very obvious and not innovative at all, while the syntax and implementation (of cargo (yes I like to wait an hour for a simple webapp to compile because there aren’t binary crates and cargo just doesn’t multicore 99% of the time)) is subpar to something that’s hailed as the savior for everyone and everything by such a large cult.
Types are not implicit, they’re inferred by the compiler when there is no ambiguity about what the type needs to be. This is a huge benefit for refactoring code and reducing maintenance. I acknowledge that sometimes you might care to know the exact type of the variable, and sometimes that’s not as easy for a human to infer as it is for the compiler, but every decent IDE will provide inline type hints for you. Interpreting code by reading it in plaintext is an exercise in masochism.
Python is actually the opposite on this, and it’s one of Python’s worst characteristics. The type is unknown until runtime unless you annotate it, and then the annotation isn’t really enforced. It’s the worst of every dimension.
C++11 introduced auto, and now the community is split between “almost always auto” and “never auto”.
JavaScript needed a whole new compiled language (Typescript) to fix its type system problems, and Typescript is only an incremental improvement at best.
Rust has the best type system of any modern language by far. If you’re tripped up by not always seeing the type declarations then you’re either focusing on the wrong details in the code or you just need a little more practice. The key thing that needs to sink in for new Rust users is that the compiler is always providing safety rails. That means it’s no longer your job to verify that every aspect of the code is correct. You can relax a little and actually have something akin to duck typing without all the pitfalls that usually come with it.
In practice, type inference in Rust is not a problem since the language is so strongly typed. In fact, it is more strongly typed than both C and C++, and will force you to cast values explicitly in cases where C and C++ will happily mess up your variables without warning. The absence of type inference would also be a major pain, since nested types such as iterators can get quite complex and very verbose. If you’ve programmed using older C++ standards, then you know this pain
Average Rust code:
macro_rules! sum { ( $initial:expr $(, $expr:expr )* $(,)? ) => { $initial $(+ $expr)* } } fn remove_prefix<'a>(mut original: &'a str, prefix: &str) -> &'a str let mut up = 1; 'outer: loop {This is on the level of the esolang I made at 8 y/o, with random characters denoting random actions everywhere, at random positions.
It’s incredibly disingenuous to call this average Rust code and further erodes your credibility. I may as well point to hundreds of lines of preprocessor macros in a C++ header and call it average C++ code.
This is not what an average Rust developer is writing 99% of the time. If someone on my team submitted a PR with an implementation of
sumthat usesmacro_rules!I would almost certainly reject it.Removed by mod
You can use spaces in Python.
Indentation-driven control flow is one of the most cursed things ever invented, excluding things explicitly designed to inflict pain or death.
White space sensitive languages are evil.
Haskell has the choice of both indentation based and brackets for things like
doblocks, but most people use indentation based cause it’s the norm and looks cleanerTwo, three or four spaces? If you answer wrong I’ll never forgive you
Whatever your place defines as a standard. I’ve seen ugly code in C, JavaScript, Java, etc., that uses them all over the place because they’re not mandatory.
If you don’t have consistent indenting, your code looks like copy/paste from several sources; but if you do have consistent indenting, then the indenting of Python is a non-issue.
Per the Linux kernel coding style:
Depends on the mood.
List comprehensions are much stranger than tabs vs spaces. There are very very very few languages that use them, and python’s is by far the worst out of the popular ones.
Skill issue. Once you learn them they are quite fun.
The concept of a list comprehenshion is sinple but syntax is awful, as if Yoda was writing a for loop. “x for x in y it is, hmm yes”.
I’m not saying I don’t understand them. I’m saying the syntax is terrible. Compare it to Ruby (or any other modern language) and it’s abundantly clear.
python (uses syntax not available in any other top 25 language)
print([j**2 for j in [2, 3, 4, 5]]) # => [4, 9, 16, 25]ruby (normal chain syntax with
map)puts [2, 3, 4, 5].map{|j| j**2}even kotlin is more readable, even though you have to convert to a double and back kotlin
val list = listOf(1,2,3,4) println(list.map{it.toDouble().pow(2.0).toInt()})For nested cases it’s even more apparent:
python
digits = [1, 2, 3] chars = ['a', 'b', 'c'] print([str(d)+ch for d in digits for ch in chars if d >= 2 if ch == 'a']) # => ['2a', '3a']ruby
digits = [1, 2, 3] chars = ['a', 'b', 'c'] digits.product(chars).select{ |d, ch| d >= 2 && ch == 'a' }.map(&:join)kotlin
val digits = listOf(1, 2, 3) val chars = listOf('a', 'b', 'c') println(digits.flatMap { d -> chars.filter { ch -> d >= 2 && ch == 'a' }.map { ch -> "${d}${ch}" }})just from a base level, you have to read the middle of the comprehension first, then the end, then the beginning. It’s a completely backwards way to write and read code. unlike other languages that use a ‘functional’ approach, where it’s chained methods or pipes, etc. Even Elixir, which does have list comprehensions, reads and writes in the proper order:
elixir
for x <- 0..100, x * x > 3, do: x * 2Wasn’t the python convention to use spaces (4 iirc)? Which is just plain wrong imho.
I can actually see where this is coming from, as I found Rust hard to read when I started out. I do really like Rust for reference, but I do agree Rust is hard to read for someone that has not learned it.
For example:
return statements that are implicit just because the semicolon isn’t there. Even better if they occur inside a if block or something like that. Very hard to understanding when you don’t know the syntax rules.
Lambda functions, especially when using move semantics too. They are quite simple, but if you don’t know the meaning, it’s more arcane characters. Especially when this is used inside lots of chained methods, and maybe a multi-line function in the lambda.
A lot for the if let x =… type of stataments are tough the first time around. Same for match statements.
Defining types for use with function::<Type>() and such.
Lifetimes, especially when they are all named a, b, c etc. It quickly gets messy, especially when combined with generics or explicitly defined types.
Macros, though not entry level rust to begin with, they are really cumbersome to decode.
None of these are sins of Rust, but for new people they are a hill to climb, and often hard to just “get” based on previous programming experience and reading the code. Rust can be really hard to approach because of these things. This happens in other languages too, but I do feel Rust has a particularly large amount of new concepts or ways to do something. And this is on top of learning lifetimes and borrow semantics.
This is the most sober take in this thread. I was bothered by all these things you mentioned for the first two weeks of using the language. I begrudgingly accepted them for the following two months because I felt the benefits of the language were worth it. Now all of these things feel natural and I don’t give them a second thought.
I think that’s a great set of criticisms.
They might not be strictly language issues, but if they are symptomatic of idiomatic rust then they are “sins of rust”. Something about the language promotes writing it using these kinds of idioms.
Just like French speakers don’t pronounce 80% of the written syllables because it’s impractical to speak fast with all of them…language features (or lack of them) drive how the language is used.
(BTW the implicit return behaviour on a missing semicolon sounds like Chekhov’s footgun)
As someone who has used Rust professionally for 3 years, the idioms are good. I wouldn’t want the idioms to go away, and I don’t particularly want the style/aesthetics of the language to change unless it can be done without negatively affecting the idioms.
It’s not a situation where the aesthetics are actually bad, it’s just different than what most programmers are used to, but almost all of the differences are for pretty good reasons. With enough familiarity and practice you’ll start to recognize those differences as benefits of the language rather than detriments.
But I think a lot of people have so much inertia about tweaking their way of thinking that they don’t feel motivated to try long enough to make it over that hump, especially when their expectations get set by rabid Rust promoters like myself who insist that Rust is vastly superior to any other languages in almost all situations. The stark contrast between how good they’re told the language is and how they feel when first exposed to it might be too much whiplash for some people.
I recognise that different languages have different styles, strengths and idioms. One of my pain points is when people write every language as if it’s naughties java. Enough with the enterprise OoP crap.
I’ve also learnt languages like Haskell to expand and challenge the way I think about software problems. I learnt a lot doing it. That doesn’t stop a lot of Haskell code looking like line noise to me because it over-uses symbols and it being close to impenetrable in a lot of cases when you read somebody else’s code.
I think the aesthetics of Rust are the wrong side of the line. Not as bad as something like Haskell (or Perl), but still objectionable. Some things seem to be different even though there’s pre-existing notation. Things seem to be dense, magical, and for the compilers benefit over the readers (as an outsider).
I’ve been learning Zig recently and the only notational aspect I struggled with was the pointer/slice notation as there’s 5 or 6 similar forms that mean fairly different things. It has other new concepts and idioms to learn, but on the whole it’s notation is fairly traditional. That has made reading code a lot more approachable (…which is a good thing because the documentation for some aspects sucks).
I’m not sure, what you mean by “Chekhov’s footgun”, but well, it isn’t a footgun, so you won’t accidentally return a wrong value from the function, if that’s what you’re thinking.
It’s not a Rust invention, most functional programming languages have implicit returns, but basically think less of them as a function return and more just as the value that a scope evaluates to.
So, here’s a simple example:
let sum = { let x = 5 + 9; 3 * x };Obviously, this is an extremely contrived example, but yeah, as you can see, it does not even have to involve a function. The implicit return makes it so that
sumis set to the result from3 * x.And the scope-braces are nice here, because you can do intermediate steps without having
xin scope for the rest of your function.In practice, if you see scope-braces and the line at the end does not have a semicolon, then that’s the value that the whole scope evaluates to. Those scope-braces can also be the braces of a function, but then you need to annotate what the function is going to return, too, so it’s practically impossible to return a wrong value.
Well, and I would actually argue that explicit returns are a footgun in comparison.
Because someone might introduce clean-up code at the end of the function and not realize that an explicit return skips that clean-up code, somewhere further up in the function.
The implicit return always has to be at the end of the scope, so it’s not possible to accidentally skip code.
The implicit return is perhaps the most dubious of them. I don’t mind it for simple functions, but they are not so good in anything large and with multiple return sites. Even more so when developers choose to implicitly return 4 chained method calls inside a closure with else cases.
But the rest aren’t really sins, they are mostly new or different concepts or ways to do something. And if there is a sin, it’s largely because the language itself has a complexity larger than others.
Taking my own examples here, lambdas are just fine, but the move semantics are cumbersome to deal with. But we need to do it some way, to indicate that a value is actually being moved into the closure. Maybe there are better ways and they make into the language in the future.
Conditional values and let statements and such is a good consequence of Rusts design choice with returning Results or Option types. Just because it’s different doesn’t make it a sin. Just takes time to learn the right way. I think most come from an exception based language, and that has a differnet code flow than what Rust has.
Lifetimes are hard though, and I feel a lot of the introduction is made excessively hard with the simple naming. It’s as of every programming tutorial used single letter variable names. Lifetimes isn’t something I’m that good with either, mostly because I haven’t had to use that complexity yet.
Go look at that Lisp kojumbo then tell me Rust is ugly.
(defmethod wake ((object magic-packet) address port) (let* ((payload (encode-payload object)) (size (length payload)) (socket (usocket:socket-connect nil nil :protocol :datagram :element-type '(unsigned-byte 8)))) (setf (usocket:socket-option socket :broadcast) t) (usocket:socket-send socket payload size :host address :port port) (usocket:socket-close socket)))Actually unreadable.
Not to stereotype too much but I think this is the first Blåhaj I’ve seen (in a programming context) that wasn’t team Rust.
What your programming language of choice (if you don’t mind sharing)?
Compared to untyped languages? Sure. Compared to C or C++? Then maybe it’s a skill issue 😋