I'm using the same semantics as I would do with, for example, Haskell. I don't think there would be any question about the Haskell implementation as that's simply the way that you deal with lists. For a long list (I would be operating on a list with a few thousand nodes), Haskell wouldn't blink (I imagine though; I've never tried).

But from what I understand with Scala, the match statement would call the unapply extractor method to split the list around the cons and, to extend the example to a function that does nothing to the list:

it would call apply extractor method to cons it back together. For a long list I imagine this would be very expensive.

To illustrate, in my specific case I want to recurse over a list of characters and accumulate various things, where the input string is anything up to a few tens of kilobytes.

Will I really be calling constructors and extractors for each step of the recursion if I want to recurse over a long list? Or are there optimisations? Or better ways to do it? In this case I would need several accumulator variables and obviously I wouldn't just be recursing over a list doing nothing...

1 Answer
1

First, Haskell is non-strict, so these function calls on the tail might never be evaluated at all. Scala, on the other hand, will compute all of the list before returning. A closer implementation to what happens in Haskell would be this:

I just realized you intend to go for tail recursion. What you wrote is not tail-recursive, because you prepend x to the result of the recursion. When handling lists, you'll get tail recursion if you compute the results backwards and then invert:

Decoding, it first calls the method equals on the passed parameter and the object Nil. Returns the latter if true. Otherwise, it calls instanceOf[::] on the object. If true, it casts the object to that, and invokes the method tl on it. Failing all that, loads the cosntant null and returns it.

So, you see, x :: xs is not calling any extractor.

As for accumulating, there's another pattern you might want to consider:

Thank you! Yes, what I am writing will be tail-recursive, the second snippet was a bad example! What I'm really aiming to do is partitioning the input string into various chunks based on some non-trivial function: the result is the accumulators not any map or fold style output. Perhaps I was trying to make the question too general in the search for a general pattern that I can use in this specific case.
–
JoeSep 3 '09 at 14:37

Well, take a look at the last example I added.
–
Daniel C. SobralSep 3 '09 at 15:06

Perfect, that answers both facets. Thank you very much!
–
JoeSep 3 '09 at 16:11