Hacker News new | ask | show | jobs
by cm3 3519 days ago
This wasn't one of the question of the survey, but while having the right crowd around, I have to ask.

When will Rust get

1. function head patterns like other languages in the ML family, although Rust isn't really part of the family, but rather a distant cousin from another continent, which once played with ML and family during a summer vacation

2. support for naturally writing recursive functions

3 comments

> Rust isn't really part of the family, but rather a distant cousin from another continent, which once played with ML and family during a summer vacation

It's actually more of a sibling in the family who ran away from home at the age of 6 and fell in with the crowd on the wrong side of the tracks.

Initially Rust was very much like ocaml. It isn't anymore :) Many of the normally-in-functional-languages features in Rust come from these days. Others were lost and re-added later. It's a very complex history.

> function head patterns like other languages in the ML family

could you elaborate? I'm not familiar with this feature (only have dabbled in sml).

> support for naturally writing recursive functions

yeah, I wish we had TCO.

> It's actually more of a sibling in the family who ran away from home at the age of 6 and fell in with the crowd on the wrong side of the tracks.

> Initially Rust was very much like ocaml. It isn't anymore :) Many of the normally-in-functional-languages features in Rust come from these days. Others were lost and re-added later. It's a very complex history.

Yeah, having tried Rust in those days, I kinda stopped when it broke every week, and was then surprised with the surface of 1.0. It seemed like a different person to talk to.

I've made my peace with the C'ification of Rust as the price to pay for attracting a large crowd of developers who grew up with C, C++, C#, Java, JavaScript, Ruby, Python, the list goes on. It's a reasonable sacrifice to make, but the two mentioned basic features aren't complex things to wish for.

> could you elaborate? I'm not familiar with this feature (only have dabbled in sml).

Imagine being able to hoist your match clauses into function head (signature?).

  oldEnoughToDrink :: Int -> Boolean
  oldEnoughToDrink 21 -> True
  oldEnoughToDrink _  -> False
Not all languages with support for that force you to repeat the function name, and there are good arguments for/against. For example in Erlang, when you define an anonymous function, you do not repeat it:

  OldEnough = fun(21) -> true;
                 (_)  -> false
              end,
Now, this may seem like a stupid little feature, but trust me when I say it's a natural feature to use like recursive functions after you're used to it.
Oh, yeah, I see what you mean by function head patterns. I'm aware of the coding pattern from Haskell, just didn't know the name :)

I don't think Rust will get support for that. You can simulate it with macros (and, later, syntax extensions). Of course, that isn't as clean as pure language support. I know why it makes recursion (esp tail recursion) easier to use though. You could always bring it up on the forums and try though.

1 and 2 go hand in hand in recursive functions, but 1 is useful without.

Say you have a function that should will tell you a file extension is likely to be that of a text file:

  isTxt("txt") -> true;
  isTxt("org") -> true;
  isTxt(_)     -> false.
With a more comfortable syntax, this can be expressed more concisely, but I just wanted to show that this isn't only useful for recursive functions.

If Rust is planned to get HKT, then I don't see why I cannot get pattern matching in function heads when there's also guards as found in ML languages.

> I just wanted to show that this isn't only useful for recursive functions.

Oh, I know that it's useful; I've used it in Haskell often. And the `fn foo (x) { match x {}}` pattern isn't uncommon in Rust.

> If Rust is planned to get HKT then I don't see why I cannot get pattern matching in function heads when there's also guards as found in ML languages.

The HKT proposal logically extends existing associated types syntax so that you effectively have HKT. It's particularly elegant in that it's something folks (who are unaware of what HKT is) on learning about associated types expect associated types to support. I've had folks ask countless times as to why you can't `type Foo<T>` in an associated type.

It also opens up access to patterns that weren't possible in the past.

OTOH function heads would just be sugar for fn + match. It doesn't open up new possibilities, it just makes some patterns easier to type. And frankly, with blocks being expressions, it's not much easier to type. You have to provide the function signature somehow, and it's there. The match arms are also there in both the Rust and haskell versions. The only thing exclusive to the Rust version is that you need to explicitly say `match`. Meh.

Languages have a "complexity budget" -- spend too much of it and folks won't learn your language because it's too complex. Rust has spent a lot of it on the borrow checker. Adding random bits of syntax spends this budget, and you need a compelling reason to do so. This is why I'm quite fond of the current HKT proposal -- I'd always thought HKT in Rust was pie-in-the-sky, but the current proposal ends up with a very unsurprising and natural-looking syntax (and doesn't feel "new"), which makes me think that it has a good chance of succeeding.

If you can come up with a good proposal for function heads, who knows, it might happen! But it will have to be good; I don't think just proposing function heads without tons of justification and/or a syntax that fits in naturally will work.

I should add 3, Erlang's bit syntax, which would be a perfect and natural fit for the target of Rust code. It's a very natural DSL to parse or build (complex) bit streams. You don't necessarily have to add bit syntax comprehensions.
Can you elaborate on what #2 means to you?
We are discouraged from writing recursive functions, which comes naturally when expressing many algorithms. Missing TCO is one cited reason to avoid it, so I gather we're not supposed to, generally speaking.
Support for guaranteeing TCE is possible and has been proposed, but there remain a few open questions, e.g. what to do about local variables with destructors (personally I'd statically forbid them from being in scope at the end of tail-call recursive functions).
I know, that's why I wrote "when", knowing it's been considered, but it doesn't appear to be missed by enough developers. I'm just spoiled having used those two features, and anytime someone cites the ML family as part of Rust's influence, it reminds me of these two basic, missing features.

Regarding semantics, without having thought about the Rust semantics too much, I'd suggest to check out the most prominent uses for recursive functions in OCaml, SML or Haskell, then try to consider that as the sweet spot to support in Rust.

I don't think it's discouraged (a least, not in the sense of it being considered bad); I think they're just being explicit about what guarantees you have (or rather, don't have) for recursive functions