Curries and locks in Scala
I am preparing a presentation about Scala and functional programming and I am not sure about two concepts.
I am using the function I introduced earlier during the presentation:
def safe_division(x: Int, y: Int) : Option[Double] = {
if(y != 0)
Some(x / y.toDouble)
else
None
}
I created a curry version (please correct me if I am wrong!):
val curried_safe_division: (Int) => (Int) => Option[Double] = {
(x) =>
(y) =>
if(y != 0)
Some(x / y.toDouble)
else
None
}
So the first part where I'm not sure is curried_safe_division called curry? "
I then entered some code to show how currying functions enable the programmer to use functionality efficiently:
val divideSix = curried_safe_division(6)
divideSix(3)
// prints: Some(2.0)
divideSix(6)
// prints: Some(1.0)
Am I correct in saying what divideSix
is a closure? Is it curried_safe_division
closing? I am using this definition:
https://softwareengineering.stackexchange.com/a/40708 a function that can be stored as a variable (called a "first class function") that has the special ability to access other variables local to the scope in which it was created.
I read several resources on the internet, wikipedia pages and this stack question: What is "Closure"? but it's still not super clear
source to share
Value curried_safe_division
is a function. This is different from safe_division
which is the method.
It curried_safe_division
is also a function map . When you take it safe_division
and turn it into a function, then you usually get (Int, Int) => Option[Double]
. By changing it to Int => Int => Option[Double]
, you have applied this feature.
The function is divideSix
not a closure. This is a simple function that takes an integer and returns an integer. However, closure is an internal function in curried_safe_division
:
val curried_safe_division: (Int) => (Int) => Option[Double] =
(x) =>
// function below is a closure
(y) =>
if(y != 0)
Some(x / y.toDouble)
else
None
// end of closure
}
You can clearly see that it depends on x
, but does not take it as its own parameter; instead he used x
from the outside area. It "closes over x". When you say val divideSix = curried_safe_division(6)
, you take this closure by supplying it with six values ββfor the x parameter and assigning that value divideSix
. But divideSix
it is not itself a closure. It doesn't cover anything. It just takes one integer parameter and divides it by six.
I've seen some people tend to refer to the resulting value of a function ( divideSix
in our example) as "closure" because it is a function called in part by applying some function ( curried_safe_division
in our example) and resulted in a function (noted between the comments in our example) which was the actual closure. I'm fine with that. Since you understand the mechanics, it's easy to find your way around the terminology.
source to share
Currying is actually much simpler than your example. You don't need to introduce the method / function difference at the same time.
// a curried safe_division method
def safe_division(x: Int)(y: Int) : Option[Double] =
if (y != 0) Some(x / y.toDouble)
else None
From there you can enter the extension eta , safe_division(2)_
, which creates a function type Int => Option[Double]
.
source to share