4 ms·
The example of match usage is really poor. From the looks of it there is no "pattern matching" going on at all here. I don't know the syntax, but even something
by klibertp 13y ago
The example of match usage is really poor. From the looks of it there is no "pattern matching" going on at all here. I don't know the syntax, but even something like this would be a better demonstration:
let computed_key = match (key.len() > self.block_size, key.len() < self.block_size) {
(true, false) => self.zero_pad(self.hash(key).digest),
(false, true) => self.zero_pad(key),
(false, false) => key
}
At least there is some matching here, unlike in the original example. But in real world this should be if..else if..else statement, not match - the latter being used makes no sense if there is no matching going on. In Erlang there is an if statement, which is a 'case' (equivalent of match here) but with matches taken out and only guards allowed - that's what would fit here, but I doubt Rust has something like this.
Also, does the compiler complain about my example above being not exhaustive? I think in OCaml it would, which is sometimes nice.
- masklinn 13y ago> Also, does the compiler complain about my example above being not exhaustive? Yes, although the error message isn't very good: crypto.rs:55:23: 59:5 error: non-exhaustive patterns: true not covered crypto.rs:55 let computed_key = match (key.len() > self.block_size, key.len() < self.block_size) { crypto.rs:56 (true, false) => self.zero_pad(self.hash(key).digest), crypto.rs:57 (false, true) => self.zero_pad(key), crypto.rs:58 (false, false) => key crypto.rs:59 }; error: aborting due to previous error And technically that's not a good thing, since (true, true) is not possible considering the input.
- catnaroek 13y agoAs noted by masklinn, the compiler will complain about the non-exhaustive match. Stuff like this makes me want a dependently typed language for practical programming, in which I can express the concept of "this case ought to be impossible", and convince the compiler by supplying a proof. Also, this would eliminate the false dichotomy between "fast, unchecked, unsafe array indexing" and "slow, checked, safe array indexing", which would be a huge win for safe systems programming.
- Locke1689 13y agoI assume you're familiar with ATS? What don't you like about it?
- catnaroek 13y agoNo tactics.
- rdtsc 13y agoI am not the original poster but I'll respond to this one: I am familiar with ATS and I don't like that I am only familiar with it from the Language Shootout contest website. I haven't heard of it used in production, no blogs, no news on HN. It is a bad excuse and rather sad but my main charge against it is that it is not popular enough.
- doublec 13y agoI agree not much is heard about it. I blog about it a fair amount on [1]. There's also /r/ats [2]. I use it in production. The backend of my bitcoin mining pool [3] is written in ATS and has about 1% of the total bitcoin mining capacity and has been operating for a couple of years. The front end of the pool is written in Ur/Web. [1] http://bluishcoder.co.nz/tags/ats/ http://bluishcoder.co.nz/tags/ats/ [2] http://www.reddit.com/r/ATS/ http://www.reddit.com/r/ATS/ [3] http://mmpool.bitparking.com http://mmpool.bitparking.com
- doublec 13y agoThere are some languages heading towards this. ATS [1] provides a restricted form of dependent types [2] that allows you to do what you want and is designed for systems programming. You can do safe pointer arithmetic for example. Idris [3] is another language with dependent types (and is more Rust-like) designed for systems programming. I don't think Idris has type level presberger arithmetic though making some things a bit verbose. [1] http://www.ats-lang.org/ http://www.ats-lang.org/ [2] http://bluishcoder.co.nz/2010/09/01/dependent-types-in-ats.html http://bluishcoder.co.nz/2010/09/01/dependent-types-in-ats.h... [3] http://www.idris-lang.org/ http://www.idris-lang.org/
- pitterpatter 13y ago>but I doubt Rust has something like this. Oh, but it does! There's the cond! macro: let computed_key = cond!( (key.len() > self.block_size) { self.zero_pad(self.hash(key).digest) } (key.len() < self.block_size) { self.zero_pad(key) } _ { key } );
- relistan 13y agoYou're right that it's not an ideal example. I think I said that in the post. The context of the article was the week I spent with Rust and the project I actually did with it. There was not a better example in my code to show. I could have contrived something, but it wasn't really in spirit of what I was writing about.
- klibertp 13y agoYou probably should fix this in your code too. As noted in this thread, that's not a proper way to use pattern matching. Anyone reading your code will be confused by this usage and that's not a good thing. It probably would be best to use this: match key.cmp(self.block_size) { Equal => .. Greater => .. Less => ... } Which is much prettier (and more succinct) than both your original code and my example. You could also use a `cond!()` macro here, but that would mean you don't have an example for a blog post, so I think the above code is the best option. Thanks to kzrdude for posting.