Working on an exercise from "CoffeeScript - Accelerated JavaScript Development," I'm trying to write this function without duplication:
doAndRepeatUntil = (f, pred) ->
f()
f() until pred()
How can I write this function without calling f() twice?
In my opinion, the way you wrote it is the preferred one. To avoid two calls to f one could write:
doAndRepeatUntil = (f, pred) ->
loop
f()
break if pred()
But I would argue that it is less readable and elegant (equivalent to using while (true)).
Related
I've seen around the following F# definition of a continuation-passing-style fibonacci function, that I always assumed to be tail recursive:
let fib k =
let rec fib' k cont =
match k with
| 0 | 1 -> cont 1
| k -> fib' (k-1) (fun a -> fib' (k-2) (fun b -> cont (a+b)))
fib' k id
When trying out the equivalent code in Scala, I've made use of the existent #tailrec and was caught off-guard when the Scala compiler informed me the recursive calls are NOT in tail position:
def fib(k: Int): Int = {
#tailrec def go(k: Int, cont: Int => Int): Int = {
if (k == 0 || k == 1) cont(1)
else go(k-1, { a => go(k-2, { b => cont(a+b) })})
}
go(k, { x => x })
}
I believe my Scala implementation is equivalent to the F# one, so I'm left wondering why the function is not tail recursive?
The second call to go on line 4 is not in tail position, it is wrapped inside an anonymous function. (It is in tail position for that function, but not for go itself.)
For continuation passing style you need Proper Tail Calls, which Scala unfortunately doesn't have. (In order to provide PTCs on the JVM, you need to manage your own stack and not use the JVM call stack which breaks interoperability with other languages, however, interoperability is a major design goal of Scala.)
The JVMs support for tail call elimination is limited.
I can't speak of the F# implementation, but in the scala you've got nested calls to go, so it's not in tail position. The simplest way to think about it is from the stacks point of view: is there any other information the stack needs to 'remember', when doing a recursive call?
In the case of the nested go calls there obviously is, because the inner call has to be completed before the computation 'goes back' and completes the outer call.
Fib can recursively be defined like so:
def fib(k:Int) = {
#tailrec
def go(k:Int, p:Int, c:Int) : Int = {
if(k == 0) p
else { go(k-1, c p+c) }
}
go(k,0 1)
}
Unfortunately, the JVM does not support tail-call optimisation yet (?) (to be fair, it can sometimes optimize some calls). Scala implements tail-recursion optimisation via program transformation (every tail-recursive function is equivalent to a loop). This is generally enough for simple recursive functions but mutual recursion or continuation-passing style require the full optimisation.
This is indeed problematic when using advanced functional patterns like CPS or monadic style. To avoid blowing the stack up you need using Trampolines. It works but this is neither as convenient nor efficient as proper tail-call optimisation. Edward Kmett's comments on the subject is a good reading.
Is there a concise, idiomatic way how to express function iteration? That is, given a number n and a function f :: a -> a, I'd like to express \x -> f(...(f(x))...) where f is applied n-times.
Of course, I could make my own, recursive function for that, but I'd be interested if there is a way to express it shortly using existing tools or libraries.
So far, I have these ideas:
\n f x -> foldr (const f) x [1..n]
\n -> appEndo . mconcat . replicate n . Endo
but they all use intermediate lists, and aren't very concise.
The shortest one I found so far uses semigroups:
\n f -> appEndo . times1p (n - 1) . Endo,
but it works only for positive numbers (not for 0).
Primarily I'm focused on solutions in Haskell, but I'd be also interested in Scala solutions or even other functional languages.
Because Haskell is influenced by mathematics so much, the definition from the Wikipedia page you've linked to almost directly translates to the language.
Just check this out:
Now in Haskell:
iterateF 0 _ = id
iterateF n f = f . iterateF (n - 1) f
Pretty neat, huh?
So what is this? It's a typical recursion pattern. And how do Haskellers usually treat that? We treat that with folds! So after refactoring we end up with the following translation:
iterateF :: Int -> (a -> a) -> (a -> a)
iterateF n f = foldr (.) id (replicate n f)
or point-free, if you prefer:
iterateF :: Int -> (a -> a) -> (a -> a)
iterateF n = foldr (.) id . replicate n
As you see, there is no notion of the subject function's arguments both in the Wikipedia definition and in the solutions presented here. It is a function on another function, i.e. the subject function is being treated as a value. This is a higher level approach to a problem than implementation involving arguments of the subject function.
Now, concerning your worries about the intermediate lists. From the source code perspective this solution turns out to be very similar to a Scala solution posted by #jmcejuela, but there's a key difference that GHC optimizer throws away the intermediate list entirely, turning the function into a simple recursive loop over the subject function. I don't think it could be optimized any better.
To comfortably inspect the intermediate compiler results for yourself, I recommend to use ghc-core.
In Scala:
Function chain Seq.fill(n)(f)
See scaladoc for Function. Lazy version: Function chain Stream.fill(n)(f)
Although this is not as concise as jmcejuela's answer (which I prefer), there is another way in scala to express such a function without the Function module. It also works when n = 0.
def iterate[T](f: T=>T, n: Int) = (x: T) => (1 to n).foldLeft(x)((res, n) => f(res))
To overcome the creation of a list, one can use explicit recursion, which in reverse requires more static typing.
def iterate[T](f: T=>T, n: Int): T=>T = (x: T) => (if(n == 0) x else iterate(f, n-1)(f(x)))
There is an equivalent solution using pattern matching like the solution in Haskell:
def iterate[T](f: T=>T, n: Int): T=>T = (x: T) => n match {
case 0 => x
case _ => iterate(f, n-1)(f(x))
}
Finally, I prefer the short way of writing it in Caml, where there is no need to define the types of the variables at all.
let iterate f n x = match n with 0->x | n->iterate f (n-1) x;;
let f5 = iterate f 5 in ...
I like pigworker's/tauli's ideas the best, but since they only gave it as a comments, I'm making a CW answer out of it.
\n f x -> iterate f x !! n
or
\n f -> (!! n) . iterate f
perhaps even:
\n -> ((!! n) .) . iterate
I want to evaluate arguments to any function in parallel transparently (without any source level changes).
For example -
c = f(a, b) should result in:
a and b being evaluated in parallel and then invoking of f.
One way to do this is to convert the above expression to:
a' = future { a }
b' = future { b }
f' = lift f
(so that f: a -> b -> c becomes f: Future<a> -> Future<b> -> Future<c>)
so that c' = f'(a', b')
Is this possible to do in scala?
Assuming that you're OK using Scala 2.10 (not yet released, but up to Release Candidate 2) and are happy to use an experimental feature, this should be pretty easy to achieve with Scala's macro system.
e.g.
val f1 = (a:Int) => a+1
def f2 = (a:Int) => a+1
Seems they are quite inter-changeable, are there any specific use case which I should use a particular one?
Typically one would write the def version as:
def f2(a:Int) = a+1
If you write it they way you did, it's actually creating a method f2 that, when called, constructs a new function closure. So in both of your cases, you still have a function. But in the first case, the function gets constructed only once and stored (as f1) for later use. But in the second case, the function gets constructed every time f2 is referenced, which is kind of a waste.
So when to prefer a function over a method? Well, you can work with a function a bit more easily in certain situations. Consider this case:
(1 to 3).map(f1 andThen f1) // totally fine
(1 to 3).map(f2 andThen f1) // "missing arguments" error
(1 to 3).map(f2 _ andThen f1) // fixed by adding "_" after the method name
So f1 is always a function and so you can call a method like andThen on it. The variable f2 represents a method, so it doesn't expect to be used like this; it always expects to be followed by arguments. You can always turn a method into a function by following it with an underscore, but this can look a little ugly if it's not necessary.
Expressions like
ls map (_ + 1) sum
are lovely because they are left-to-right and not nested. But if the functions in question are defined outside the class, it is less pretty.
Following an example I tried
final class DoublePlus(val self: Double) {
def hypot(x: Double) = sqrt(self*self + x*x)
}
implicit def doubleToDoublePlus(x: Double) =
new DoublePlus(x)
which works fine as far as I can tell, other than
A lot of typing for one method
You need to know in advance that you want to use it this way
Is there a trick that will solve those two problems?
You can call andThen on a function object:
(h andThen g andThen f)(x)
You can't call it on methods directly though, so maybe your h needs to become (h _) to transform the method into a partially applied function. The compiler will translate subsequent method names to functions automatically because the andThen method accepts a Function parameter.
You could also use the pipe operator |> to write something like this:
x |> h |> g |> f
Enriching an existing class/interface with an implicit conversion (which is what you did with doubleToDoublePlus) is all about API design when some classes aren't under your control. I don't recommend to do that lightly just to save a few keystrokes or having a few less parenthesis. So if it's important to be able to type val h = d hypot x, then the extra keystrokes should not be a concern. (there may be object allocations concerns but that's different).
The title and your example also don't match:
f(g(h(x))) can be rewritten asf _ compose g _ compose h _ apply x if your concern is about parenthesis or f compose g compose h apply x if f, g, h are function objects rather than def.
But ls map (_ + 1) sum aren't nested calls as you say, so I'm not sure how that relates to the title. And although it's lovely to use, the library/language designers went through a lot of efforts to make it easy to use and under the hood is not simple (much more complex than your hypot example).
def fgh (n: N) = f(g(h(n)))
val m = fgh (n)
Maybe this, observe how a is provided:
def compose[A, B, C](f: B => C, g: A => B): A => C = (a: A) => f(g(a))
basically like the answer above combine the desired functions to a intermediate one which you then can use easily with map.
Starting Scala 2.13, the standard library provides the chaining operation pipe which can be used to convert/pipe a value with a function of interest.
Using multiple pipes we can thus build a pipeline which as mentioned in the title of your question, minimizes the number of parentheses:
import scala.util.chaining._
x pipe h pipe g pipe f