Post A4eI5ro0EbOTsft6Aa by teek_eh@aus.social
(DIR) More posts by teek_eh@aus.social
(DIR) Post #A4daETTVfUdx2nb2P2 by wizzwizz4@fosstodon.org
2021-02-25T16:11:41Z
0 likes, 0 repeats
Lately, #Rust just fills me with a profound sense of disappointment. It's the best programming language I've ever used, but there are so many things that you *should* be able to do but you just can't.enum Example { Hi(u64), Question(bool)}impl From<u64> for Example { from = Example::Hi;}That *should* work. In plenty of other places, Example::Hi is treated as a function with the correct prototype. But Rust's syntax doesn't let you express *this*, so you need boilerplate.
(DIR) Post #A4e0scc5i0P5mIPlXk by janriemer@mastodon.technology
2021-02-25T21:10:15Z
0 likes, 0 repeats
@wizzwizz4 Hm...interesting.🙂 But imagine adding another variant to the enum that takes `u64`. Now your `From` impl doesn't work anymore, because it doesn't know which variant to produce.But what's probably even more relevant: When you `impl From<U> for T` `T` automatically implements `Into<U>`. With enums this can't work, because what value do you expect when calling `into()`?Enums are a little bit like "one-way-functions" in that regard if that makes sense.😉
(DIR) Post #A4e1e2VhF6BXhq2Aka by wizzwizz4@fosstodon.org
2021-02-25T21:18:40Z
0 likes, 0 repeats
@janriemer That's not what I mean; I know about that ambiguity (though being able to have derive macro-like attributes on enum variants would also be good). I mean I should be able to do exactly what I wrote: from = Example::Hi;instead of the boilerplate: fn from(x: u64) -> Example { Example::Hi(x) }because Example::Hi is treated as a function with prototype fn(u64) -> Example elsewhere, but Rust doesn't provide a syntax to let you use existing functions in trait impls.
(DIR) Post #A4e3V6nQ8dGEIhC3pA by janriemer@mastodon.technology
2021-02-25T21:39:38Z
0 likes, 0 repeats
@wizzwizz4 Ah, ok, I see, thanks for clarifying.Hm... I don't know, whether this is any more or less boilerplate. The usecase seems pretty niche to me.Also, when it doubt, Rust always decides to be *explicit* about things, so ¯\_(ツ)_/¯But you are right, your solution definitely seems more consistent.
(DIR) Post #A4e5M4ytiTm3yRNsKO by wizzwizz4@fosstodon.org
2021-02-25T22:00:25Z
0 likes, 0 repeats
@janriemer The thing is, there isn't a keyword for it. So unless fn lets you have =, like trait does (with a nightly feature), my solution is *inexpressible* in Rust.That makes me feel sad – especially since there are probably a load of things like this that I *haven't* thought of yet. Special-casing each one as somebody finds it feels like the wrong way to do it, but I don't see another path forward for Rust, as it is.
(DIR) Post #A4eI5ro0EbOTsft6Aa by teek_eh@aus.social
2021-02-26T00:23:07Z
0 likes, 0 repeats
@wizzwizz4 @janriemer It's misleading to think of Example::Hi(x) as some sort of constructor. The way your enum is defined, () represents a tuple. e.g. for contrast you could have written:enum Example { Hi { index: u64 }, Question(bool)}I broadly agree there might be syntax shortcuts to make your use-case easier but I'm not convinced it would work in the way you suggest.
(DIR) Post #A4f3wbl1KLkVIn8xW4 by wizzwizz4@fosstodon.org
2021-02-26T09:19:16Z
0 likes, 0 repeats
@teek_eh @janriemer Rust seems to treat it as a constructor in other places. https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c511988f892a2f02accb3470fa76eea5.#[derive(Debug)]enum Example { Hi(u64), Question(bool)}fn hello<T>(f: impl Fn(u64) -> T) -> T { f(42)}fn main() { println!("{:?}", hello(Example::Hi));}
(DIR) Post #A4f4K84xK40uCpgT0i by teek_eh@aus.social
2021-02-26T09:23:32Z
0 likes, 0 repeats
@wizzwizz4 @janriemer Not gonna lie, I had no idea. That’s trippy.
(DIR) Post #A4fbCrKKVMZci813Ka by dnaka91@mastodon.technology
2021-02-26T15:32:01Z
0 likes, 0 repeats
@wizzwizz4 maybe the derive_more crate can help you reduce some boilerplate on your enums:https://jeltef.github.io/derive_more/derive_more/from.html#enums
(DIR) Post #A4m3G2y5dtRfLigJXc by moonbolt@mst3k.interlinked.me
2021-03-01T18:14:16Z
0 likes, 1 repeats
@wizzwizz4 @janriemer> so unless fn lets you have =, like trait does (with a nightly feature).m …but why not though?We've totally run into wanting to do exactly the thing in the root post. And `fn quux = foo;` seems almost like just a natural extension of `trait Quux = Foo + Bar;`.Somecreature should make an RFC.
(DIR) Post #A4mDNgYjqDBThw6Xdw by wizzwizz4@fosstodon.org
2021-03-01T20:08:06Z
0 likes, 0 repeats
@moonbolt @janriemer Trouble is, there's a lot of inference going on with the implicit cast-to-function.Inside function and trait bodies would be the only places you could do this, if it is to be consistent with the rest of the language in terms of inference semantics, which then means you're violating “syntax must work everywhere” semantics… which Rust doesn't have in the first place (see: let), so it's probably fine.I keep coming up with counter-arguments, but they're actually not valid. 😖
(DIR) Post #A4mEbpw1sZwynIJIsy by moonbolt@mst3k.interlinked.me
2021-03-01T20:21:36Z
0 likes, 0 repeats
@wizzwizz4 @janriemer .m `type` and `trait` aliases already work inside and outside function bodies, so I think it would make sense for `fn` aliases to as well.