For the following question: http://pastie.org/4825115, here is my code: http://pastie.org/private/n22zohyshn2ymqrbrb3g
def randList(len: Int, n: Int): List[Int] = len match {
case 0 => List()
case len => scala.util.Random.nextInt(n) :: randList(len-1, n)
}
but I don't know why randList is called a closure.
According to my understanding randList is definitely not a closure (Wikipedia seems to agree) , since - in the snippet of code you provided - it only depends on local variables (parameters are also considered local variables). Considering the body of randList, there is no so-called free variable, i.e., a variable that does not get its value from the current lexical scope, where the latter is the method body itself. len and n are both variables of the current lexical scope since they are both parameters of the enclosing definition of randList.
Consider this example:
var n = 10
val f = (x: Int) => x + n
println(f(1)) // 11
n = 20
println(f(1)) // 21
The function f is a closure because it does not only depend on its parameters, but also on a variable that is declared outside of its own lexical scope (namely n).
The Wikipedia article mentions that a closure is defined by a function together with a lexical scope that declares the free arguments. The next example illustrates this:
// n == 20
// f as above
def foo(g: Int => Int) = {
val n = 100
g(1)
}
println(foo(f)) // 21
The result of foo(f) is still 21 although foo defines its own local variable n, and one might assume that f now uses this n. However, the closure f is coupled to the lexical scope that surrounds its declarations, which is where the value of n is take from when f is evaluated.
I agree with #Malte as randList is not dependent on any variable declared outside the function. So this function is not a closure.
To my understanding, a closure is a function that can reference state in another function. Look this thread for more details: What is a 'Closure'?.
In this problem, as randList doesn't reference any outer variables, it's not a closure...
Related
Folding list in scala using /: and :\ operator
I tried to to look at different sites and they only talk about foldRight and foldLeft functions.
def sum(xs: List[Int]): Int = (0 /: xs) (_ + _)
sum(List(1,2,3))
res0: 6
The code segment works as described. But I am not able to completely understand the method definition. What I understand is that the one inside the first parenthesis -> 0 /: xs where /: is a right associate operator. The object is xs and the parameter is 0. I am not sure about the return type of the operation (most probably it would be another list?). The second part is a functional piece which sums its two parameters. But I don't understand what object invokes it ? and the name of function. Can someone please help me to understand.
The signature of :/ is
/:[B](z: B)(op: (B, A) ⇒ B): B
It is a method with multiple argument lists, so when it is just invoked with on argument (i.e. 0 /: xs in your case) the return type is (op: (B, A) ⇒ B): B. So you have to pass it a method with 2 parameters ( _ + _ ) that is used to combine the elements of the list starting from z.
This method is usually called foldLeft:
(0 /: xs)(_ + _) is the same as xs.foldLeft(0)(_ + _)
You can find more details here: https://www.scala-lang.org/api/2.12.3/scala/collection/immutable/List.html
Thanks #HaraldGliebe & #LuisMiguelMejíaSuárez for your great responses. I am enlightened now!. I am just summarisig the answer here which may benefit others who read this thread.
"/:" is actually the name of the function which is defined inside the List class. The signature of the function is: /:[B](z: B)(op: (B, A) ⇒ B): B --> where B is the type parameter, z is the first parameter; op is the second parameter which is of functional type.
The function follows curried version --> which means we can pass less number of parameters than that of the actual number. If we do that,
the partially applied function is stored in a temporary variable; we can then use the temporary variable to pass the remaining parameters.
If supplied with all parameters, "/:" can be called as: x./:(0)(_+_) where x is val/var of List type. OR "/:" can be called in two steps which are given as:
step:1 val temp = x./:(0)(_) where we pass only the first parameter. This results in a partially applied function which is stored in the temp variable.
step:2 temp(_+_) here using the partially applied function temp is passed with the second (final) parameter.
If we decide to follow the first style ( x./:(0)(_+_) ), calling the first parameter can be written in operator notion which is: x /: 0
Since the method name ends with a colon, the object will be pulled from right side. So x /: 0 is invalid and it has to be written as 0 /: x which is correct.
This one is equivalent to the temp variable. On following 0 /: x, second parameter also needs to be passed. So the whole construct becomes: (0/:x)(_+_)
This is how the definition of the function sum in the question, is interpreted.
We have to note that when we use curried version of the function in operator notion, we have to supply all the parameters in a single go.
That is: (0 /: x) (_) OR (0 /: x) _ seems throwing syntax errors.
This question already has an answer here:
Can anyone explain how the symbol "=>" is used in Scala
(1 answer)
Closed 4 years ago.
I am new to scala and I confused little bit with = and =>, I don't know in which scenario exactly = used and => used.
#RamanMishra's comment is correct, however I would like to expand it a bit hopping it becomes more clear to you.
a = b means a is now equals to b (in the imperative meaning of the word, which is better understood as assignment).
It is used in many places, including when defining a function\method, for example
def sum(a: Int, b: Int): Int = a + b
The above statement can be readed as:
"We defined a function with name sum which takes two parameters (a & b) both of type Int and returns an Int. And its body\implementation is 'equals' to a + b".
a => b means, there is a function which takes a parameters list a and has a body b, it is used a couple of places, including anonymous functions and higher-order functions.
val anonymous: Int => Int = x => x + 1
The above statement can be readed as:
"We defined a value called anonymous, whose type is a function with one parameter of type Int and a return type Int, which is 'equals' to the 'anonymous' function which takes one parameter x (its type is inferred in by the context, in this type the explicit type signature before) and its body is x + 1"
def higherOrder(x: Int, f: Int => Int): Int = f(x)
The above statement can be readed as:
"There is a function (sum), which takes another function as a parameter (f), the later is a function of type Int to Int".
Edit
As #Aki suggested, the => is also used in pattern matching to separate the cases and the block of code to execute for each one.
def fact(n: Long): Long = n match {
case 0L => 1L
case n => n * fact(n - 1)
}
"This is somewhat similar to a parameter list => function body, as the above examples".
PS: This is a 101 Scala question, SO is not the best place for such questions, because there is probably enough resources on the internet - like this cheatsheet, or better places to ask - like the scala gitter channel.
I want to do define a function in scala that takes arguments in prefix notation:
sum i1 i2 i3 ... in
and returns and Int with the sum of all the provided args. Note that I don't want to use parentheses when I call the function.
My goal is to do something like sum i1 plus i2 but I want to start with something simpler first.
NOTE: You might say there is not purpose for doing this if you can use the + operator, but my goal is not to add numbers. I am just using this as a generic learning tool.
Before answering the question, I'd like to point out that scala is first and foremost an object oriented language, so most of the functions you'll want to define will actually be methods on specific objects. I will give answers in more generality for any class T (not necessarily for Int). I also assume that what you want to do on your list of values can be done iteratively, so sum 1 2 3 is actually the same as sum (sum 1 2) 3, so I assume you have some reducer function f: (T, T) => T.
To define an infix operator, so that you can do something like
i1 and i2 and i3 ...
you just have to define a method
and(that: T): T = f(this, that)
on your class T. If you are not able to add methods to your type (eg, if you're using a class from a lib, or Ints), you can use an implicit wrapper for your type:
implicit class ReducibleT(i: T) {
def and(j: T): f(i, j)
}
To define a prefix operator, with infix repeater, such as
sum i1 and i2 and i3 ...
it appears that you cannot do it! That's because an expression like ident1 ident2 ident3 is always (as far as I know) parsed as ident1.ident2(ident3), (unless ident2 ends with a colon, in which case it is reversed). But you cannot define a method for all possible identifiers for your type T (eg, for Ints, you cannot define a method 1 on an object, so sum 1 2 has no meaning whatsoever), so it won't be possible.
However, you can do almost as good:
sum (i1) and i2 and i3 ...
In that case, the parens indicates a function call, so it actually calls the method and on the object sum(i1) (which actually is sum.apply(i1), since all functions are objects with the special method apply). Here is an example:
def sum(i: T) = i
implicit class ReducibleT(i: T) {
def and(j: T): f(i, j)
}
Now, if you understood this second case, it will come to no surprise that you cannot do
sum i1 i2 i3 ...
either. We have to limit ourselves to
sum (i1) (i2) (i3)
using the following:
def sum(i: T) = i
implicit class ReducibleT(i: T) {
def apply(j: T) = f(i, j)
}
Or, to mix things up a bit, you can use implicit conversion to a function:
implicit def tAsReducer(i: T): T => T = f(i, _)
scala> def sum(a:Int)={a} //I have defined the function with a single parameter
sum: (a: Int)Int
sum{val b=10+20} //passing the parameter as expression block
Getting error
scala> sum{val b=10+20}
<console>:9: error: type mismatch;
found : Unit
required: Int
sum{val b=10+20}
Why is it expecting Unit here?
The error is that {val b = 10 + 20} is of type Unit while sum is expecting an Int.
You can either call sum directly without assigning the variable:
sum(10 + 20)
> 30
Or make the block return an Int, like:
sum{
val b = 10 + 20
b // return b, which is an Int
}
> 30
You do not pass an expression but a block with one declaration. Try:
sum(10+20)
You are experiencing a weird combination of syntax error and type-system convention.
The curly braces mark a block (see e.g. the body of your sum function declaration). Function arguments can be passed in juxtaposition or using parenthesis. That is your syntax error.
The type system convention allows languages with side-effects to gently insert these effects into basically any expression. This happens by treating the composition of statements (i.e. the semicolon) as "evaluate these expression but do nothing with the result, then evaluate the next expression". The nothing as result part is combined with the unit type for statements that do not compute anything.
def sum(a:Int)={a}
What this statement does is create a method that takes one Int-typed parameter and returns it.
sum{val b=10+20}
Here you pass a value to your defined method sum. What you're passing is an expression. Scala will, effectively, 'rewrite' that expression before applying it to sum. If we write the expression being passed (val b=10+20) in the REPL we will see what it gets rewritten to:
scala> val b=10+20
b: Int = 30
But this is only part of the story, because the assignment of a value to a name returns nothing. We can see this by putting brackets around the assignment:
scala> { val b=10+20 }
Note that the REPL displays nothing when this happens.
Because the re-written expression includes this evaluation, you're actually passing a scope to the function, in which b is defined. However, that scope doesn't 'return' an Int to be bound to a. To return the result of the b assignment, you have to do one of two things. Either you have to have a call to the variable be the last call in the expression, or have the last call be the calculation itself, and don't assign that to a variable:
sum{ val b=10+20; b } // Explicitly call the bound variable
sum{ 10 + 20 } // Don't assign the variable
I'm basically new to functional programming and scala, and the following question might possibly look stupid.
val f = (a:Int) => a+1
In the above snippet, should I consider f to be a function or a variable? Coming from a C/C++ background, the first thought that occurs is that f is a variable that stores the return value of the anonymous function, but I think that's not the correct way to interpret it Any explanation would be really helpful.
(Some of the terminologies I used above might be wrong with respect to scala/functional programming, kindly bear with it)
Here, f is a variable that stores a function. It's really no different from saying any of the following:
val a = 4 // `a` is a variable storing an Int
val b = "hi" // `b` is a variable storing a String
val f = (a:Int) => a+1 // `f` is a variable storing a function
You can also confirm this with the REPL:
scala> val f = (a:Int) => a+1
f: Int => Int = <function1>
So this is telling you that f has the type Int => Int. Or in other words, f is a function that takes one argument, an Int, and returns an Int.
Since f is a variable, you can call methods on it or pass it as an argument to functions that expect its type:
a + 3 // here I'm calling the `+` method on `a`, which is an Int
f(3) // here I'm calling the `apply` method on `f`, which is a function `Int => Int`
f(a) // the function `f` expects an `Int`, which `a` is
(1 to 3).map(f) // the `map` method expects a function from Int to Int, like `f`
Yes, like dhg said, f is a variable (that can't be changed) that stores a function.
However, there's a subtlety here:
... the first thought that occurs is that f is a variable that stores the
return value of the anonymous function
f actually stores the function, not the result. So you can give it different inputs, and get different outputs. So, you can use it like f(7) and then f(5). Functions in Scala are objects, so can be assigned to variables, passed as parameters, etc.
I recently posted about function literals, which may be helpful to you.
f is a value denoting a function literal.
In the statement, the right-hand-side is a function literal. The left-hand-side binds it to a name which is then called value (the val keyword is similar to let in LISP). Now the function is associated with the symbol f, so you can refer to that function by using this symbol f.
I disagree with the other answers which suggest that f should be called a variable. f is a value, because it is fixed to the right-hand-side term which is determined only once and cannot change. On the contrary a variable, introduced with var, allows you to re-assign values to a symbol:
var f = (i: Int) => i + 1
Where var begins a variable definition, f is the name or symbol of the variable, there could be an optional : ... defining type of the variable (if you leave that out, the type is automatically inferred from the assignment), and = ... defines the value initially assigned to the variable.
So when one says value, don't confuse this with a numeric constant, it is simply an entity that doesn't change. A function can be a value too, because f then always denotes this same identical function, even if you can feed that function with different arguments which yield different results.
Now with the var you can re-assign its right-hand-side:
f(2) // --> 3
f = (i: Int) => i * 2 // assign a new function to the variable f.
f(2) // --> 4
Functional programming is all about avoiding variables (re-assignments).
It is also possible to define a function without assigning it at all (to a value or a variable). The following defines such a function and immediately calls it with argument 4:
{ i: Int => i + 1 } apply 4 // --> 5
although that is seldom useful as a statement per se, but you will see 'plain' functions often when calling a method that expects a function argument. For instance
val s = List(1, 2, 3)
s.map { (i: Int) => i + 1 } // --> List(2, 3, 4)
s.map { _ + 1 } // equivalent
s.map( _ + 1 ) // equivalent