News for hackers. Stuff that matters.
Re:Memory Safe Languages in Android 13 by optymizer on Thursday December 01, 2022 @02:45PM (#33821647)
As an Android user ever since the T-Mobile G1, I'm a fan of not having my phone remotely exploited via WebView, or with an SMS, or the other million ways there are to interact with a device, so I absolutely celebrate this progress.

As an Android developer though, I have to be the one bitter old man yelling at cloud. I was spoiled by Java and Kotlin to the point where I cannot look at Rust and think it's a nice modern language.

Yes, I will start a language war today. Rust is like a truck driver who tried to make a race car that doesn't blow up. It's safe but it does not look refined. I wish you knew how weird Rust looks to me. I tried to learn it 3 times and had to give up after all the WTFs. I said it in the past, and I'll say it again:

* What the hell kind of language choice is to force everyone to type "#[derive(Debug)]" for annotations? I'd rather write past the end of an array and have someone steal my Bitcoin wallet than press "shift 3 bracket shift 9 shift 0 bracket" at the top of my structs. What's wrong with @? Nothing. @derive(debug). 2java4u? Ok, [derive debug] then.

* What's with the ' everywhere? Not the quote, the piece of dirt on your display. Why are our displays so dirty?

* Going for super short keywords "let", "fn", "mod", but then, "let mut" could have been "var". When is typing speed the bottleneck in writing software where you can't take the time to type out "module" or even 'function'? Come on now.

* print! now! fast! it's! a! macro! why! are! we! yelling!

* Passing "self" as the first argument was bullshit in Python, and it's bullshit in Rust too. Don't look at me like that - the compiler can inject it as the first parameter without requiring you to type it in.

* What does "::" do that "." can't? That's right. Nothing. All hail D.

D got language design right. Syntax better than Rust. CTFE better than Rust. Templates better than Rust. Marketing worse than Rust, though.

I'll try to learn Rust a 4th time now to stay relevant in the Android world, because I have bills to pay, but I want you to know that I blame each and everyone of you weirdos for not holding language designers to a higher bar.

Edit: if you downvote, reply with a link to the last compiler you wrote.

Re:Memory Safe Languages in Android 13 by pcwalton on Thursday December 01, 2022 @03:11PM (#33822029)
> Edit: if you downvote, reply with a link to the last compiler you wrote.

https://github.com/rust-lang/rust/

Re:Memory Safe Languages in Android 13 by satvikpendem on Thursday December 01, 2022 @03:22PM (#33822168)
This has to be as good as the "Did you win a Putnam?" comment from 15 years ago [0].

[0] https://news.ycombinator.com/item?id=35079

Re:Memory Safe Languages in Android 13 by optymizer on Thursday December 01, 2022 @03:32PM (#33822306)
upvoted <3
Re:Memory Safe Languages in Android 13 by j-krieger on Thursday December 01, 2022 @02:58PM (#33821835)
> Passing "self" as the first argument was bullshit in Python, and it's bullshit in Rust too. Don't look at me like that - the compiler can inject it as the first parameter without requiring you to type it in.

Nope, that would be a static function on your struct. By using self you let the compiler know that you want to use an instance function.

Re:Memory Safe Languages in Android 13 by optymizer on Thursday December 01, 2022 @03:41PM (#33822410)
what if there's no static function with that name?
Re:Memory Safe Languages in Android 13 by masklinn on Thursday December 01, 2022 @04:18PM (#33822907)
There is since that's what you declared.

    impl Foo {
        // static
        fn foo() {}
    }

    impl Foo {
        // instance, owned
        fn foo(self) {}
    }

    impl Foo {
        // instance, borrowed
        fn foo(&self) {}
    }

    impl Foo {
        // instance, boxed
        fn foo(self: Box<Self>) {}
    }

    impl Foo {
        // instance, refcounted <strike>(currently nightly, arbitrary_self_types)</strike>
        // actually stable, alonside Arc, and Pin, it's other things which
        // Deref<Target=Self> which require arbitrary self types
        fn foo(self: Rc<Self>) {}
    }
Re:Memory Safe Languages in Android 13 by phaylon on Thursday December 01, 2022 @04:27PM (#33823040)
Small nitpick: Fortunately, `Rc` and `Arc` actually don't require the nightly feature.
Re:Memory Safe Languages in Android 13 by masklinn on Thursday December 01, 2022 @04:31PM (#33823100)
Oh yeah you're right that's been stabilised, now that I'm thinking about it, it was probably something like `self: std::sync::MutexGuard<'_, Self>` which told me to enable the feature
Re:Memory Safe Languages in Android 13 by optymizer on Sunday December 04, 2022 @05:02PM (#33858435)
Again, what if there is no static declaration?

    impl Foo {
        // static
        fn foo() {}
    }
Why would I need to use self to tell the compiler about an instance method? Surely the Rust compiler is smart enough to detect this case and complain if the call site is ambiguous.
Re:Memory Safe Languages in Android 13 by masklinn on Wednesday December 07, 2022 @02:13AM (#33891566)
> Again, what if there is no static declaration?

So your suggestion is to remove static methods from the language?

> Why would I need to use self to tell the compiler about an instance method? Surely the Rust compiler is smart enough to detect this case and complain if the call site is ambiguous.

Detect what case? There is a dozen and eventually an infinite number of potential instance call ABIs.

And the Rust compiler is generally very much on the “refuse to guess” side of the fence (hence no global type inference), so you have to tell it what it should expect, `self`, `&mut self`, and `&self` have rather different requirements, impacts, and capabilities to say nothing of the rest.

Re:Memory Safe Languages in Android 13 by nneonneo on Thursday December 01, 2022 @03:11PM (#33822026)
Also, there are several different ways to pass self: `self`, `mut self`, `&self`, `&mut self`, and they have very different semantics.

Rust could have taken the C++ route here: `fn static foo()`, `fn foo()`, `fn mut foo()`, `fn &mut foo()`, etc. but I feel like the explicit `self` is very clear and easy to understand.

Re:Memory Safe Languages in Android 13 by masklinn on Thursday December 01, 2022 @04:18PM (#33822913)
> Rust could have taken the C++ route here: `fn static foo()`, `fn foo()`, `fn mut foo()`, `fn &mut foo()`, etc.

`fn Box foo()`? `fn Arc foo()`? It also requires more parser lookahead.

The `mut` case is also very odd, as it's not part of the function API (it just configures the binding of the internal local). Plus if self was implicit it likely would need to be a keyword, so that wouldn't be a usecase at all anymore.

Re:Memory Safe Languages in Android 13 by pkolaczk on Friday December 02, 2022 @03:58AM (#33828312)
IMHO that would be a dead end. I prefer passing self explicitly and I still hope it will be possible to bind self partially in the future, e.g bind only one field. Currently if you call a function that e.g returns a reference to a field, the compiler borrows the whole self, not the field. So partial borrows are supported partially : they can't cross function boundaries.
Re:Memory Safe Languages in Android 13 by masklinn on Friday December 02, 2022 @04:07AM (#33828364)
Yeah partial borrows are not part of the file system, which makes a lot of sense as it would severely leak implementation details.

I regularly get frustrated but I don’t really see an easy alternative, it’s be a lot of work having it work let alone contextually (e.g. from pub functions for pub fields but not for private types / fields), and how would you even express the borrows / holes?

Re:Memory Safe Languages in Android 13 by nevi-me on Thursday December 01, 2022 @03:05PM (#33821951)
I prefer self. The changes in ES5 in JavaScript were painful because some people kept losing track of `this`'s scope. IIRC it changed with arrow functions, making it hard to know what `this` the code was using.

I prefer an explicit `this` or `self` being passed, so that I know where it's defined. Something close enough, Kotlin uses `it` in lambdas. If you're nesting your lambdas, it can be tricky to review the code when just staring at it (when the IDE isn't helping you with types).

Re:Memory Safe Languages in Android 13 by throwup on Thursday December 01, 2022 @03:12PM (#33822037)
So many complaints above surface-level syntax here.

> press "shift 3 bracket shift 9 shift 0 bracket" at the top of my structs

Just use an IDE and you can press alt+enter. Same thing you do in Java when writing getters and setters for your AbstractFactoryBeans.

> "let mut" could have been "var"

The "mut" does not belong to the "let", it belongs to the variable name.

  let (read_only, mut read_write) = (1, 2);
> Passing "self" as the first argument was bullshit

Explicit is better than implicit. I quite like the names in the argument list to match the set of names available in the function, rather than having an extra keyword (`static`) that you add to remove a function parameter.

Re:Memory Safe Languages in Android 13 by masklinn on Thursday December 01, 2022 @04:13PM (#33822843)
> Explicit is better than implicit.

Not only that, but in Rust it actually has a meaning. Self can be &self or &mut self, which impacts the calling conventions.

The alternative would be fully typing anything but owned method calls which would just not have a self parameter, which would be incredibly weird.

It also shows that as in Python (and really even more so) "methods" are little more than syntactic sugar for functions. It would also require a new and separate syntax to declare non-instance methods.

Re:Memory Safe Languages in Android 13 by afdbcreid on Thursday December 01, 2022 @06:13PM (#33824394)
It can also be `self: Box<Self>` or `mut self: Pin<&mut Self>` or `self: Box<Arc<Rc<Self>>>` if you feel brave.
Re:Memory Safe Languages in Android 13 by shpongled on Thursday December 01, 2022 @03:03PM (#33821926)
I find it interesting that your complaints are almost totally about the syntax - that is generally the last thing I care about in a language.

When I choose languages, I choose them based on semantics, tooling, community/ecosystem, UX, and then maybe syntax

Re:Memory Safe Languages in Android 13 by netr0ute on Thursday December 01, 2022 @03:07PM (#33821973)
For me, syntax is one of the top priorities because if I can't express what I want using something compatible with how I think, then it doesn't matter if the language has SuperLib 4000 available if I can't program with it.
Re:Memory Safe Languages in Android 13 by shpongled on Thursday December 01, 2022 @07:08PM (#33824961)
Personally, the opposite is true for me - case in point: python.

I really dislike both the semantics and syntax of python. However, the scientific computing libraries (pandas, numpy, scipy, scikit-learn, matplotlib, seaborn, etc) are just too productive to turn away from for quick data analysis tasks. If these libraries didn't exist, I wouldn't touch python with a 500-foot pole.

Re:Memory Safe Languages in Android 13 by gavinray on Thursday December 01, 2022 @03:00PM (#33821863)
I'm just commenting to agree with the "D got language design right, Marketing worse than Rust". I cry every time =(

Don't have anything against Rust though, except the syntax can be a bit obtuse.

Re:Memory Safe Languages in Android 13 by netr0ute on Thursday December 01, 2022 @02:56PM (#33821813)
I had the same experience with Rust too. After trying and failing for hours to trudge through syntax BS, I'm (probably) not touching it again until something big changes. I can't even get user input without making a huge ugly one-liner or importing some dependency.
Re:Memory Safe Languages in Android 13 by nneonneo on Thursday December 01, 2022 @03:19PM (#33822128)
Unclear what you mean by user input - for arguments, `std::env::args()` exists, and for stdin `std::io::stdin()` exists and provides various read functions.

    let mut line = String::new();
    stdin().read_line(&mut line)?;
    println!("input: {}", line);
I suspect that there _have_ been some changes since you last looked - for example, the ? operator lets you propagate errors in a more compact way.
Re:Memory Safe Languages in Android 13 by netr0ute on Thursday December 01, 2022 @04:04PM (#33822711)

    let mut line = String::new();
    stdin().read_line(&mut line)?;
This is what I'm talking about. This is so ugly and clunky and needlessly verbose like Java compared to C++ where you can do

    std::string input;
    std::cin >> input;
and have it Just Work. Why can't Rust do something similar?
Re:Memory Safe Languages in Android 13 by nneonneo on Thursday December 01, 2022 @04:20PM (#33822940)
Except, you've failed to check for an error, and you need another line to do that. Suppose the user ended their input or the input is a pipe that's been closed - what does your C++ program do?

Here's another example. C++ lets you do this:

    long input;
    std::cin >> input;
    process(input);
and this is very convenient! It's much shorter than the Rust code for doing the same. It's also wrong! If the input cannot be read, or it cannot be parsed as an integer, `input` now contains undefined content. You'd need to remember to check the contents, or end up processing undefined memory values. You cannot make this error in Rust without a lot of contortions (e.g. unsafe).

Some people will say, I just want to get stuff done and not worry about all this safety junk. As someone who works in security and have exploited bugs in C/C++ programs, this is pretty much why we wound up with so many CVEs.

Re:Memory Safe Languages in Android 13 by netr0ute on Thursday December 01, 2022 @06:02PM (#33824252)
> Some people will say, I just want to get stuff done and not worry about all this safety junk. As someone who works in security and have exploited bugs in C/C++ programs, this is pretty much why we wound up with so many CVEs.

Are constructions like these really the root cause of CVEs? As long as you do a correct check, then you're all good. If Rust can do the same thing in fewer lines, then that may or may not be a good thing because some people might want a lower degree of abstraction or a greater one.

Re:Memory Safe Languages in Android 13 by nneonneo on Thursday December 01, 2022 @08:33PM (#33825612)
Oh absolutely! Here’s an example from 2019: https://www.cve.org/CVERecord?id=CVE-2019-15900

“An issue was discovered in slicer69 doas before 6.2 on certain platforms other than OpenBSD. On platforms without strtonum(3), sscanf was used without checking for error cases. Instead, the uninitialized variable errstr was checked and in some cases returned success even if sscanf failed. The result was that, instead of reporting that the supplied username or group name did not exist, it would execute the command as root.”

Fail to check that your input parsed correctly, wind up with privilege escalation to root.

Re:Memory Safe Languages in Android 13 by netr0ute on Thursday December 01, 2022 @11:07PM (#33826651)
The problem here is that that implementation was written in plain old C and is super unsafe, and is NOT C++. I don't know why C keeps getting confused with C++ because the two are basically totally different now.
Re:Memory Safe Languages in Android 13 by nneonneo on Friday December 02, 2022 @01:17AM (#33827431)
Oh my bad! That must be why C++, a definitely not super unsafe language that is basically totally different from C, lets you do this:

    char buf[10];
    std::cin >> buf;
    std::cout << buf << std::endl;
g++ -Wall -std=c++2a (sorry, I’ve only got GCC 9), no warnings or errors, happily overruns the stack when fed more than 10 characters. This code is essentially equivalent to the C gets(buf) (splitting on whitespace instead of newline), but gets is deprecated and generates big warnings on most modern C compilers. Yet, operator>>(char *) does not.

Sure, you can write secure code in C++. You can write secure code in C too, even if that language is “super unsafe”. But neither language will stop you from writing insecure code either.

Re:Memory Safe Languages in Android 13 by dagmx on Thursday December 01, 2022 @11:23PM (#33826751)
I have to say I appreciate when folks like yourself explain the subtle flaws in very simple code.

It’s been really eye opening as I do security analysis of C++ projects how many foot guns are in a ton of codebases that now need so much scaffolding to handle properly, after they’ve done damage.

With Rust, my first pass is usually the right pass.

Re:Memory Safe Languages in Android 13 by masklinn on Thursday December 01, 2022 @04:25PM (#33823011)
Because Rust does not want to have implicit constructors, default constructors, constructors at all, random statics, ...

And `std::cin` does not read a line from the input, you need `getline` for that.

Re:Memory Safe Languages in Android 13 by oll3 on Thursday December 01, 2022 @05:05PM (#33823600)
Not that this kind of stdin reading operation is something I do often. But at least the Rust code says what it does. Bitshifting stdin by a string on the other hand... Does it read a line, or forever, or read at all? I wouldn't call it the ultimate syntax for a line reader anyway. :)
Re:Memory Safe Languages in Android 13 by aliceryhl on Thursday December 01, 2022 @03:09PM (#33821993)
> Rust is like a truck driver who tried to make a race car that doesn't blow up.

Lamborghini originally made tractors.

Re:Memory Safe Languages in Android 13 by masklinn on Friday December 02, 2022 @04:24AM (#33828463)
Still do. Isn’t Clarkson’s stupid big tractor on diddly squat farm a Lamborghini?
Re:Memory Safe Languages in Android 13 by going_ham on Thursday December 01, 2022 @04:03PM (#33822702)
* `@` is already used for pattern matching, so it can't be used for that; the brackets are necessary to allow more freedom in what kind of stuff you can put in those directives

* `fn` and `mod` are super common and mostly just to make the language LL(1), complaining that they're hard to understand is like complaining that the average person couldn't guess that `//` denotes comments; `let mut` is chosen over `var` to prevent people from just using `var` everywhere and opting out of const correctness

* makes parsing deterministic

* unlike in python, `self` can be passed in multiple ways, such as `&self` or `&mut self`, so you need to specify somehow and this is more elegant that the C++ east const

* `::` is for static dispatch, `.` for member access, there are cases where both are valid and distinct

Re:Memory Safe Languages in Android 13 by estebank on Thursday December 01, 2022 @04:47PM (#33823336)
https://github.com/rust-lang/rust/pulls?q=is%3Apr+author%3Ae...

The aesthetics of syntax is a personal matter, but when the critique of a language focuses exclusively on its syntax, it tells me that the critique is skin deep. Semantics are way more important to what code "feels" like to write.

Why not @derive? @ was a reserved token for something else before 1.0 and today is still used in patterns. Now it's too late to change.

The ' lifetime syntax was borrowed from another language. Some way of differentiating types and lifetimes is necessary, ' is not any worse than most others we could have chosen.

We try to make things that are common and safe terse, and things that are uncommon and potentially problematic more verbose. ? is common and safe, .unwrap() is less common and potentially problematic. Mutable bindings are not exactly unidiomatic, but mildly discouraged.

println! is a macro because it 1) is a compiler intrinsic to do compile time magic like the recent addition of capturing bindings directly in the formatting string and 2) it takes a variable number of arguments. Differentiating between macros and function calls is important if you want to get a sense for what the code you're reading can do. You can choose another way of differentiating them, but whatever you choose will be subjective and has to mesh well with the rest of the language.

Explicit self makes it easy syntax to differentiate between associated functions (part of the type) and methods (part of the instance), while also making very clear when you're accessing the current instance's data. And because Rust cares about mutability and ownership, you still need to communicate the differences between self, &self and &mut self. It also provides syntactic space for arbitrary self types: fn foo(self: Pin<&mut Self>)

Re:Memory Safe Languages in Android 13 by O_H_E on Friday December 02, 2022 @09:45AM (#33831064)
just fyi, you can still write all the Java/Kotlin you want to stay relevant.

this post have nothing to do with writing apps for android. They are talking about developing the android system itself. They are writing new system code in Rust instead of C++. Userspace code is still enoraged to be written in Kotlin.