News for hackers. Stuff that matters.
Re:Bastion of the Turbofish (2020) by scott_s on Wednesday February 03, 2021 @04:17PM (#26019230)
If you're wondering, "What is the turbofish?", it is the awkward syntax Rust requires when specifying generic arguments in an expression, such as:

  Vec::<u8>::new()
Re:Bastion of the Turbofish (2020) by ruph123 on Friday February 05, 2021 @12:58AM (#26033571)
Re:Bastion of the Turbofish (2020) by Subsentient on Friday February 05, 2021 @04:09AM (#26034446)
Am I the only one not really bothered by the turbofish? I just think 'declarations, no colons. expressions, colons.' and that rule generally works fine for me.
Re:Bastion of the Turbofish (2020) by adkadskhj on Friday February 05, 2021 @11:01AM (#26037704)
I love it. I'm not here to debate whether it should be there, but i like it nonetheless. Mostly because of the cute name.

And i came from being a Python "kill all syntax!" zealot back in the day, hah. Funny how in both Types and Syntax i have migrated from minimalist to explicitness over the years. I was such a zealot on both fronts in those Python days.

Re:Bastion of the Turbofish (2020) by scott_s on Friday February 05, 2021 @08:59AM (#26036361)
It's a straight-forward rule that (I think) I have mostly internalized. But coming from C++, I was initially mystified.
Re:Bastion of the Turbofish (2020) by vbarrielle on Friday February 05, 2021 @10:18AM (#26037207)
C++ has a rule similar to the turbofish though:

    #include <Eigen/Dense> // a library where I know it's required

    using namespace Eigen;

    int main() {
        VectorXd zeros = VectorXd::zeros(5);
        VectorXf zeros_float = zeros.template cast<float>();
        return 0;
    }
Re:Bastion of the Turbofish (2020) by nzmsv on Saturday February 06, 2021 @11:10AM (#26047452)
I'm sure you know better, but at first glance this seems wrong. Reason: `main` is not itself a template, so `cast` is not a dependent name.

C++ compilers used to be liberal about accepting unnecessary instances of the `typename` keyword so lots of people would just sprinkle them everywhere. Modern versions of both Clang and GCC call this out.

The actual rule: https://en.cppreference.com/w/cpp/language/dependent_name#Th...

Re:Bastion of the Turbofish (2020) by vbarrielle on Saturday February 06, 2021 @03:40PM (#26049729)
You're right, since I'm frequently using templated functions I encounter this issue quite often, but here when I wanted to give an example I forgot I needed to be in a dependent context. I guess I'd better test my example next time I want to give one...
Re:Bastion of the Turbofish (2020) by scott_s on Friday February 05, 2021 @10:18AM (#26037217)
And I have never internalized it! This is me, but for `typename` and `template` in expressions: https://xkcd.com/1168/
Re:Bastion of the Turbofish (2020) by tomjakubowski on Saturday February 06, 2021 @12:05AM (#26044273)
The syntax gives me a warm feeling, reminding me in the moment that I'm not writing C++.
Re:Bastion of the Turbofish (2020) by edflsafoiewq on Friday February 05, 2021 @12:50AM (#26033538)
Specifically it's the ::<u8> part. It's only used when writing type parameters in an expression.

    let x: Vec<u8> = vec![]; // spelled Vec<u8> in "type context"
    let x = Vec::<u8>::new(); // spelled Vec::<u8> in "expression context"
Re:Bastion of the Turbofish (2020) by scott_s on Friday February 05, 2021 @08:51AM (#26036272)
Yes, and googling around for this rule is what landed me on this epic poem and test.
Re:Bastion of the Turbofish (2020) by __henil on Friday February 05, 2021 @12:44AM (#26033509)
I find specifying type on the left side of assignment operator much easier to interpret.

> let x: Vec<u8> = Vec::new();

Re:Bastion of the Turbofish (2020) by adamnemecek on Friday February 05, 2021 @01:52AM (#26033807)
let x: Vec<u8> = vec![];
Re:Bastion of the Turbofish (2020) by baby on Friday February 05, 2021 @12:37AM (#26033469)
It’s also never clear where this appears, like a::<b>(c) or a::<b>::c()
Re:Bastion of the Turbofish (2020) by unrealhoang on Friday February 05, 2021 @01:08AM (#26033602)
in both case, `<b>` is a parameter of `a`, but in the former, `a` is a function with generic parameter and in the latter, `a` is a type with generic parameter.
Re:Bastion of the Turbofish (2020) by kzrdude on Friday February 05, 2021 @06:29PM (#26042523)
The generic paramer is directly after the thing that has the parameter (it could be on the type or the method). With an exception, for enum variants it's after the variant, like None::<i32>
Re:Bastion of the Turbofish (2020) by tooltower on Friday February 05, 2021 @12:29AM (#26033427)
It makes me wonder. If things went differently, and if Rusty always needed this syntax for generic parameters, would the consistency have made the syntax more palatable?
Re:Bastion of the Turbofish (2020) by kibwen on Friday February 05, 2021 @12:34AM (#26033450)
As in, if declaring generics looked like `fn foo::<T>()` rather than `fn foo<T>`? I dunno, at think at that point you just stop worrying about adhering to the principle of making declaration resemble use.
Re:Bastion of the Turbofish (2020) by tooltower on Friday February 05, 2021 @01:55AM (#26033826)
I guess I was only thinking of types, where turbofish comes up. E.g. for declaring generics, like `struct Point::<T>`.
Re:Bastion of the Turbofish (2020) by edflsafoiewq on Friday February 05, 2021 @01:53AM (#26033819)
IMO no. I find even :: by itself unpalatable.