You can try and describe Rust syntax but I don’t think you’re going to beat “like trying to read the output of a UART with line noise.”


<< while we were coding Xous, a thing called `const generic` was introduced. Before this, Rust had no native ability to deal with arrays bigger than 32 elements! >>


That's... that's gotta be a mistake, right.......? I'm reading that sentence wrong....?

@natecull This is a very misleading description!

Only some _methods_ weren't available for #Rust arrays with len >32:

"For a long time, even the standard library _methods_ for arrays were limited to arrays of length at most 32 due to this problem."

If you have an array bigger than 32 elements, you could always convert it into an unsized slice:

So it is not that big of a deal as the author makes it seem to be.🙄


@janriemer @aral

But uh that doesn't sound better.

Methods randomly "not being available" for some instances of an object class would be a rather large problem, in most object-oriented languages.

@natecull @aral In the case of #Rust it is actually not a problem, but a feature, because Rust is not object-oriented, but strongly typed.

You can implement _different methods_ on type Foo<Bar> and Foo<Quux>, which makes total sense.

And an array of a certain length actually has it's own type.

It's all checked at compile-time.

There is no "MethodNotImplementedException" in Rust.

@aral It makes me really sad that people get caught up about such superficial things as syntax.
Concepts of a PL are far more important. Let's see - which one is more readable and expresses the intend of the algorithm?

let result;
if (foo != null && != null) {
result =
} else {
result = Result::new();


let result = foo
.and_then(|b| b.baz())


@aral Oh, turns out the last snippet is not only more readable, but also more correct!

Because in the first example one has forgotten to init `result` properly (it can be null down the line!).

#Rust #StronglyTyped


@janriemer icoUldntagReeMoreimeaNalltHatmaLarkeyaBoutreadAbiltyaNdaLlthatishUgelyoVerratEdifyOuaSkmEiFpeOplearEntwilLingtOdOtHewoRktolEarnsoMetHingdOtHeyeVendeseRvetouSeiTriTesoFpaSsaGeftWamiRiteaFteraLltHegUyoNlywRoteaNopeRatinGsyStemiNiTwHatanEwbwHatdOeshEknOw


@aral Could you please express your intend more clearly. I don't understand what you want to tell me.

@janriemer I think @aral used a very bad syntax to convey something using beautiful concepts.

Though I must admit that I also could not find the beautiful concepts because I did not understand the syntax.

Which I think is his point.

Syntax matters.

@ArneBab @janriemer What’s saddest is I actually pecked that out on my phone :)

@janriemer You are giving two examples, but you missed the elefant in the room:

const result = foo?.bar?.baz() || {};


@ArneBab @janriemer Optional chaining is fun but you can have it _and legible syntax_ – e.g., see Swift (I have no problem with the use of question marks for optionals, it’s rather elegant imho) ;)

@aral @janriemer I would not go and claim that Javascript is really *good*. It is what you get when you mix horrible concepts with enough syntactic sugar to paper over it that it appears nice until you dig a finger deep.

Therefore it is the perfect example that syntax matters, because the concepts of JS are deeply unsettling :-) (since they were never really designed, but tacked on with the requirement “every page must keep working with all its workarounds”).

@ArneBab @janriemer Ah, that was JS, sorry (of course we have optional chaining now; I really need to start using it). Thought you were giving me a good example of Rust for a moment there. Need to not comment on three different threads at the same time :)

@aral @ArneBab Agree, Swift syntax looks pretty elegant on first look.🙂

> thought you were giving me a good example of Rust for a moment there

Here you go - Rust has optional chaining, too:

It works a bit different as in other languages, though, in that it _returns early from the function_. Therefore, the function in which `?` is used needs to return something fallible as well (e.g. Some<T> or Result<T, E>).

You can see it in the example above.

@janriemer I see optional chaining there, and that’s an argument *for* syntax being relevant, because optional chaining makes it easier to understand intent both in a language with powerful compile-time guarantees and one with concepts that are about as brittle as you can make them.


@janriemer @aral I have no idea if this is your point, but I have no idea what's really going on in your second example.

@roadriverrail Of course you must be familiar with the Rust stdlib to understand this.

.and_then is a method on `Option<T>`

From the docs:
"Returns `None` if the option is `None`, otherwise calls f with the wrapped value and returns the result.

Some languages call this operation flatmap."

.unwrap_or_default() returns the value that is within the `Option<T>`. If no value exists, it returns the default value of `T`.


@janriemer @aral Sure, but this does make the point that syntax has a lot of relativity to it. I need relatively less context to read and understand the first example. Not only is it a syntax reflecting a family of languages, but I also don't have to know how the Option template works and all the nuances that came with it.

I get that you like one better. I feel it's okay for someone else to have a different sense of what's readable.

> I need relatively less context to read and understand the first example.

Yes, because you are _familiar_ with it.

And to be clear: I didn't want to show syntax with these examples (in fact, both examples actually have the _same_ syntax).

What I want to show is _concepts_.

It's not only about readability, but correctness:
Did you notice that the first example has a bug in it?

(keeping aral out, because he is not responding anymore)

@janriemer Okay, then I guess your point was lost on me, because I don't know what concepts you're even talking about. Your initial question was about readability and intent. With that framing and obvious psuedocode, I don't go hunting for bugs and trust the author is making a good faith A/B comparison, especially on a lightweight medium like a social network.

@roadriverrail Sorry, for not being clear enough here.

I was showing the concept of _handling the absence of values_.

In the first example `null` indicates the absence of a value.

In the second example absence of values is actually encoded within the type system and therefore less error-prone.

I hope this makes things more clear?

@janriemer Sure, and I understand the reasons why people champion this sort of thing, and I'm also aware of the pitfalls of having a null that's not integrated into the type system. My former thesis adviser and I go back and forth on this a lot.

The thing is, though, and this is nothing to do with you, these kinds of motivating examples don't really reflect my daily needs or even how I would want to police a rogue null in my code, so they don't really sell their ideas well to me.

@janriemer (addendum) the other side of it is that your "and_then" stuff keeps on running even after a None gets injected, and maybe I don't want that. The more explicit control flow in the first example is equivalent, I agree, but I often want to bail out early. When we talk about "intent", the explicit flow control says more than the "just let None percolate" system does. For me, anyway.

And regardless, great concepts are unreadable in bad syntax, which is why syntax matters.

@roadriverrail Yes, I completely agree.

> [...]but I often want to bail out early.

That's reasonable. For this, Rust has the ? operator, like other languages (see also the example I've given in earlier posts of this thread with a link to the playground).

> And regardless, great concepts are unreadable in bad syntax, which is why syntax matters.

Totally agree! I don't want to have syntax like APL.



What bothers me is that some people complain, but don't give examples on what they don't like about the syntax - or even suggest improvements!

It also seems some confuse syntax with... idk nature (stdlib, features) of the language?

And just to end on a positive note here: have you seen Rust's postfix .await syntax? It's pretty neat. In an async function you write something like:


where foo() and bar() are things to await (return a Future).



@janriemer Let's be clear-- I like you and I feel positive towards our interaction. That said, maybe it's just me, but with rare exceptions, when I meet someone who does a lot of functional coding, they tend to be exceedingly condescending to the way things were done before their favorite language came along, as it one is benighted for writing loops when some map-and-closure thing exists now. 1/n

@janriemer I actually watched a "tech lead" waste a month of project time trying to make Scala work for an Android application, despite my prior explanation that Scala's magic works through ballooning the method count in the final bytecode, and Android's limit on methods would mean we'd run out before we got started. But, for him, it was all just because Java was too gross to write in. He spent weeks making "poor man's Scala" so that he didn't have to slum it. 2/n

@janriemer And as a systems software engineer of decades, to the point that "systems software" to me means a different class of software entirely from what people seem to reserve it for today, this attitude is just really alienating, even when it's probably not meant to be.

For example, I have no idea why I would want to "await" a "Future". I spent part of last year reading the machine language for a disk controller driver. These concepts don't exist there. 3/n

@janriemer As a result, I still prize a linguistic experience that leaves me capable of having intuitions about how the hardware executes it. I understand why so many of these features you bring up are The Hotness for lots of people, but for a lot of systems software people, these features might as well be on the moon.

Back to the original syntax's definitely from an old-school humor tradition (it could have easily been a C++ joke) 4/n

@janriemer And yes, you can make that about most languages. I love C, but I have definitely seen some C-isms, even common ones, that I'd ban if I ran the circus.

But to make a positive remark back, maybe "boilerplate code" isn't always a dirty word? Maybe a little bit of boilerplate to keep the symbols less dense and more related to intuitive notions isn't always bad? Maybe "if...else...return" communicates better than "and_then?" or whatever? Maybe it's okay to take more than one line? 5/5

@roadriverrail Yes, I feel positive about our interaction, too, thank you.🙂
I really appreciate you for writing all this, which shows that you care. I've really enjoyed reading it and it was very eye-opening for me.💚

Have a nice weekend! 😉

@janriemer The fact that you intrinsically perceive "?" as natural and reasonable for "please bail out here", and say "like other languages", shows the gulf here, and it shows where these complaints start and why "this looks like line noise" complaints happen. Things like operators and their symbolic representation are still strongly bound to the semiotics one expects from both their natural use and from prior experiences with languages. 1/2

@janriemer I strongly suspect you come from one world and I and the author of that blog post come from another. And that's fine, but it's important to understand that, much as your world is natural to you, our world is natural to us. To invoke my former adviser again, back in 2014, we discussed Rust. His interest was "Scala, but faster" and mine was "C with better pointer safety." These reflect radically different psychologies and needs. 2/2

@aral For the "not finished" part, there is a great article from the perspective of Python:

I still have some essential projects that I have not yet finished converting to Python 3. Because when you have three layers of string-byte-mangling, that actually is hard.

Sign in to participate in the conversation
Aral’s Mastodon

This is my personal Mastodon.