Live data from Hacker News

Functional Language Features: Iterators and Closures

doc.rust-lang.org

31–40 of 40 posts

Re: Functional Language Features: Iterators and Closures

#31
post #6
post #2

> Programming in a functional style often includes using functions as values by passing them in arguments, returning them from other functions, assigning them to variables for later execution, and so forth. > ... > Other Rust features, such as pattern matching and enums, which we’ve covered in other chapters, are influenced by the functional style as well. What is it about pattern matching and enums that associates t…

> first popularized by certain functional languages Basically that. People associate all kinds of different thinks with the term functional programming. The only think in common is that it's focused on functions, including first class functions. For other thinks including things like (strict) immutability, lazy evaluation, syntax, algebraic data types, linear typing, etc. it is different from person to person weather…

It's not only 'first' but also immutable as a way of life.

You walk structures to extract information and derive a new structure. With immutable types and automated constructors this becomes regular enough to be baked in the language. Other languages like memory mutation so the main action is setting a variable to modify it.

Re: Functional Language Features: Iterators and Closures

#32
post #10

Earlier quoted context omitted.

I'm sure it makes sense to someone well-versed in Rust syntax, but to an outsider like me that code looks like the kind of "line noise" that made me switch from perl to python. The procedural 'if x.len == 3 and x[0] == x[1]' seems a lot clearer as to what is actually being tested.

That code in the comment above isn't actually rust. It's a lisp, I believe. In Rust, you'd write something more like: fn f(x: &[i32]) -> bool { match x { [x, y, _] if x == y => true, _ => false, } }

... and you could write

  fn f(x: &[i32]) -> bool {
      x.len() == 3 && x[0] == x[1]
  }
if you wanted. Honestly, I probably would.

Re: Functional Language Features: Iterators and Closures

#33
post #7
post #2

> Programming in a functional style often includes using functions as values by passing them in arguments, returning them from other functions, assigning them to variables for later execution, and so forth. > ... > Other Rust features, such as pattern matching and enums, which we’ve covered in other chapters, are influenced by the functional style as well. What is it about pattern matching and enums that associates t…

Yes -- sum types have historically not been present in imperative languages, whereas products types have essentially always been present. Imperative languages have correspondingly good support for various uses of product types, but even if sum types can be encoded, you generally can't abstract well over them due to the nonexistent language support for their use. C does have unions, but you can't distinguish which fie…

Historically imperative languages did have tagged unions (Algol, Pascal, Ada, Modula). Their disappearance is mostly because of OOP's takeover I think. It was thought that a tagged union should be replaced by a base class with one derived class per variant.

What they lacked was usually a nice way to operate on tagged unions, ie. pattern matching.

Re: Functional Language Features: Iterators and Closures

#36

Why do people post chapters from manuals to HN?

To start a discussion about that topic while bringing users who are unfamiliar up to speed quickly?

Maybe. Of course, everyone can submit whatever they want. To me it looks strange people upvote such links.

Re: Functional Language Features: Iterators and Closures

#37

Earlier quoted context omitted.

This works out really nicely when combined with variadic template tricks. (Taken from CPP Reference) // Helper for creating anonymous visitor functions template struct overloaded : Ts... { using Ts::operator()...; }; template overloaded(Ts...) -> overloaded ; using var_t = std::variant ; std::vector vec = {10, 15l, 1.5, "hello"}; // Type matching visitor for (auto& v: vec) { std::visit(overloaded { [](auto arg) { std…

That does not give you destructuring though, so to distinguish different variants of the same type you are left with a classic `if` inside the lambda. Also this has "language support" in the sense that it is (again) implemented via template meta programming, i.e. the compile time is impacted quite heavily. See "std::visit is everything wrong with modern C++": https://bitbashing.io/std-visit.html This standards propos…

Yes, I'm definitely not saying that std::visit is perfect by any stretch of the imagination

Re: Functional Language Features: Iterators and Closures

#38
post #18

Earlier quoted context omitted.

C++17 does - it's called std::variant. std::variant options; options = true; bool value = std::get (options); bool has_bool = std::holds_alternative (options); // or test which alternative is held if (auto i = std::get_if (&options)) { // do something with int } else if (auto b = std::get_if (&options)) { // do something with bool } else { // do something with double }

That's not a language feature though, right? It's just a struct containing a union and a discriminant. That means: - No pattern matching means your stuck with the awkward if-elseif-else - It doesn't check that you've accounted for every possible variant. - You can only hold one variant of each type: you can't have two variants that both contain a string. - The specific instance isn't it's own type, so you can't imple…

You can use std::visit() for the time being, and pattern matching is being discussed.

Re: Functional Language Features: Iterators and Closures

#39

How are iterators functional language features? They're not unique to functional languages and they don't require function composition to implement. They're present in most popular imperative languages.

Even if it's not the only way to implement iterators, using closures which maintain state and yield values one after another seems to be a very popular way to do it.

In that case you're passing around a function, which matches how this chapter characterizes "functional programming".

Re: Functional Language Features: Iterators and Closures

#40
post #7

Earlier quoted context omitted.

Yes -- sum types have historically not been present in imperative languages, whereas products types have essentially always been present. Imperative languages have correspondingly good support for various uses of product types, but even if sum types can be encoded, you generally can't abstract well over them due to the nonexistent language support for their use. C does have unions, but you can't distinguish which fie…

Historically imperative languages did have tagged unions (Algol, Pascal, Ada, Modula). Their disappearance is mostly because of OOP's takeover I think. It was thought that a tagged union should be replaced by a base class with one derived class per variant. What they lacked was usually a nice way to operate on tagged unions, ie. pattern matching.

Thanks! Always interested in learning more about the historical PL landscape ^_^
Post reply on HN