Live data from Hacker News

Why your first Rust FizzBuzz implementation may not work

chrismorgan.info

31–40 of 139 posts

Re: Why your first Rust FizzBuzz implementation may not work

#31
post #20

Putting the String issue aside, I just wanted to show the beauty of pattern matching. for i in range(1i, 101) { match (i % 3, i % 5) { (0, 0) => println!("Fizzbuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } } -- edited: removed `.to_string()`, thanks chrismorgan

Weird to see this mix of a very imperative for-range iterative loop with a very functional pattern match, which makes it look similar to an SML or OCaml solution to FizzBuzz. I guess this is the definition of multi-paradigm right here.

Will Rust's type checker warn you of a non-exhaustive pattern match?

Re: Why your first Rust FizzBuzz implementation may not work

#32
post #23

The feature list in rust really does have my eye. The biggest one in particular was type inference . The reason type inference was such a big one was because if you use it right, annoying situations like "Two types of strings? What is this?" go the hell away. You have three types, static built in and binary strings, and a third that only makes the gaurentee that the datatype can do all the things a string aught to be…

Rust has type inference similar to Haskell: type information can flow "backwards". It is very different to Go and C++ where types of locals are 'inferred' from their initialiser, and nothing else. E.g. fn main() { let mut v; if true { v = vec![]; v.push("foo"); } } is a valid Rust program: the compiler can infer that `v` must have type `Vec ` based on how it is used. I don't think it's possible to syntactically write…

The C++ analogous, although not exactly the same, is to use a `make_vector` wrapper, like

  template
  inline auto make_vector(Args&&...args) {
    using T = typename std::common_type::type;
    return std::vector{{std::forward(args)...}};
  }
  ...
  auto v = make_vector("asd", "dsa", std::string("asdsa"));
It will obviously not deduce types after the vector is declared, but it's as close as one gets to type deduction based on the vector's content.

There is one instance in C++ where information does flow backwards in a sense: disambiguating template overloads. For example,

  using fn_type = std::vector(&)(int&&,int&&,int&&);
  auto v = static_cast(make_vector)(1, 2, 3);
In this case, the static_cast information flows "back" to the type deduction of `make_vector` to deduce what Args&& is. This is not very useful, just a curiosity.

Re: Why your first Rust FizzBuzz implementation may not work

#33
post #31
post #20

Putting the String issue aside, I just wanted to show the beauty of pattern matching. for i in range(1i, 101) { match (i % 3, i % 5) { (0, 0) => println!("Fizzbuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } } -- edited: removed `.to_string()`, thanks chrismorgan

Weird to see this mix of a very imperative for-range iterative loop with a very functional pattern match, which makes it look similar to an SML or OCaml solution to FizzBuzz. I guess this is the definition of multi-paradigm right here. Will Rust's type checker warn you of a non-exhaustive pattern match?

Non-exhaustive pattern matching is a compilation error.

Re: Why your first Rust FizzBuzz implementation may not work

#34
post #31
post #20

Putting the String issue aside, I just wanted to show the beauty of pattern matching. for i in range(1i, 101) { match (i % 3, i % 5) { (0, 0) => println!("Fizzbuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } } -- edited: removed `.to_string()`, thanks chrismorgan

Weird to see this mix of a very imperative for-range iterative loop with a very functional pattern match, which makes it look similar to an SML or OCaml solution to FizzBuzz. I guess this is the definition of multi-paradigm right here. Will Rust's type checker warn you of a non-exhaustive pattern match?

Here's the same approach in F# without the different types of String; therefore, easier to get more functional.

    let fizzbuzz num =     
       match num % 3, num % 5 with      
          | 0,0 -> "FizzBuzz"
          | 0,_ -> "Fizz"
          | _,0 -> "Buzz"
          | _,_ -> num.ToString()

    [1..100]
      |> List.map fizzbuzz
      |> List.iter (fun (s:string) -> printfn "%s" s)

Re: Why your first Rust FizzBuzz implementation may not work

#35
post #31
post #20

Putting the String issue aside, I just wanted to show the beauty of pattern matching. for i in range(1i, 101) { match (i % 3, i % 5) { (0, 0) => println!("Fizzbuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } } -- edited: removed `.to_string()`, thanks chrismorgan

Weird to see this mix of a very imperative for-range iterative loop with a very functional pattern match, which makes it look similar to an SML or OCaml solution to FizzBuzz. I guess this is the definition of multi-paradigm right here. Will Rust's type checker warn you of a non-exhaustive pattern match?

[deleted]

Re: Why your first Rust FizzBuzz implementation may not work

#36
post #31
post #20

Putting the String issue aside, I just wanted to show the beauty of pattern matching. for i in range(1i, 101) { match (i % 3, i % 5) { (0, 0) => println!("Fizzbuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } } -- edited: removed `.to_string()`, thanks chrismorgan

Weird to see this mix of a very imperative for-range iterative loop with a very functional pattern match, which makes it look similar to an SML or OCaml solution to FizzBuzz. I guess this is the definition of multi-paradigm right here. Will Rust's type checker warn you of a non-exhaustive pattern match?

[deleted]

Re: Why your first Rust FizzBuzz implementation may not work

#37
post #24

The feature list in rust really does have my eye. The biggest one in particular was type inference . The reason type inference was such a big one was because if you use it right, annoying situations like "Two types of strings? What is this?" go the hell away. You have three types, static built in and binary strings, and a third that only makes the gaurentee that the datatype can do all the things a string aught to be…

Type inference doesn't exactly paper over the differences between types automatically. It just infers types, and doesn't complain as long as all the types line up. Consider doing something similar in Haskell, setting a variable to either be a string or Text: GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Prelude> import qualified Data.Text as T Prelude T> let x = (if True then "foo" else T.empty) :3:32:…

that's a good point I suppose.

Re: Why your first Rust FizzBuzz implementation may not work

#38
post #31
post #20

Putting the String issue aside, I just wanted to show the beauty of pattern matching. for i in range(1i, 101) { match (i % 3, i % 5) { (0, 0) => println!("Fizzbuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } } -- edited: removed `.to_string()`, thanks chrismorgan

Weird to see this mix of a very imperative for-range iterative loop with a very functional pattern match, which makes it look similar to an SML or OCaml solution to FizzBuzz. I guess this is the definition of multi-paradigm right here. Will Rust's type checker warn you of a non-exhaustive pattern match?

[deleted]

Re: Why your first Rust FizzBuzz implementation may not work

#39

Earlier quoted context omitted.

It’s whether (i % 3, i % 5) is equal to (0, 0) et al., where _ means “any value”.

That's a very useful feature. Maybe I'll go ahead and learn Rust now. If it has a features like pattern matching, which seems about ten times more useful than the classic switch statement, then it probably has a lot of other insights worth learning. If you were to start a hypothetical project written in Rust, what would it be? I'm looking for something to cut my teeth on.

I would suggest you port over a project that you are already familiar with. It's easier to learn a new syntax when you don't have to grapple with implementation as well. And you get to have an objective comparison of the same project implemented 2 different ways.

Re: Why your first Rust FizzBuzz implementation may not work

#40
post #20

Putting the String issue aside, I just wanted to show the beauty of pattern matching. for i in range(1i, 101) { match (i % 3, i % 5) { (0, 0) => println!("Fizzbuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } } -- edited: removed `.to_string()`, thanks chrismorgan

I haven't looked too deeply into Rust yet, but was able to understand this coming from Elixir. Pattern matching makes for a beautiful solution. This is a similar solution in Elixir:

  fizzbuzz = fn(x) ->
    case {rem(x, 3) == 0, rem(x, 5) == 0} do
      {true, false} -> IO.puts "fizz"
      {false, true} -> IO.puts "buzz"
      {true, true}  -> IO.puts "fizzbuzz"
      _             -> IO.puts x
    end
  end

  Enum.each Range.new(1, num), fizzbuzz
Since functions are also pattern matched in Elixir (and Erlang!) it could also be done without using case and handled purely as functions.
Post reply on HN