Related
I want to know what exactly an asterisk does before a variable name in Kotlin.
I saw this (*args) in a Spring boot Kotlin example:
#SpringBootApplication
open class Application {
#Bean
open fun init(repository: CustomerRepository) = CommandLineRunner {
repository.save(Customer("Jack", "Bauer"))
repository.save(Customer("Chloe", "O'Brian"))
repository.save(Customer("Kim", "Bauer"))
repository.save(Customer("David", "Palmer"))
repository.save(Customer("Michelle", "Dessler"))
}
}
fun main(args: Array<String>) {
SpringApplication.run(Application::class.java, *args)
}
The * operator is known as the Spread Operator in Kotlin.
From the Kotlin Reference...
When we call a vararg-function, we can pass arguments one-by-one, e.g. asList(1, 2, 3), or, if we already have an array and want to pass its contents to the function, we use the spread operator (prefix the array with *):
It can be applied to an Array before passing it into a function that accepts varargs.
For Example...
If you have a function that accepts a varied number of arguments...
fun sumOfNumbers(vararg numbers: Int): Int {
return numbers.sum()
}
Use the spread operator to pass an array's elements as the arguments:
val numbers = intArrayOf(2, 3, 4)
val sum = sumOfNumbers(*numbers)
println(sum) // Prints '9'
Notes:
The * operator is also the multiplication operator (of course).
The operator can only be used when passing arguments to a function. The result of the operation cannot be stored since it yields no value (it is purely syntactic sugar).
The operator may confuse some C/C++ programmers at first because it looks like a pointer is being de-referenced. It isn't; Kotlin has no notion of pointers.
The operator can be used in-between other arguments when calling a vararg function. This is demonstrated in the example here.
The operator is similar to the apply function in various functional programming languages.
In addition to the answers that were directly towards "what is this thing!?!", you often have the case where you have a List and want to pass it to a function that is expecting a vararg. For this, the conversion is:
someFunc(x, y, *myList.toTypedArray())
Assuming that last parameter of someFunc is vararg of the same type as the elements in the list.
As described in the documentation this is a spread operator:
When we call a vararg-function, we can pass arguments one-by-one, e.g.
asList(1, 2, 3), or, if we already have an array and want to pass its
contents to the function, we use the spread operator (prefix the array
with *):
val a = arrayOf(1, 2, 3)
val list = asList(-1, 0, *a, 4)
In Java you can pass an array as is but an advantage of unpacking an array with spread operator * is that spread operator lets you combine the values from an array and some fixed values in a single call. Java doesn't support this.
If a function which accept a vararg(Variable number of arguments) parameter like:
fun sum(vararg data:Int)
{
// function body here
}
Now to call this method, we can do:
sum(1,2,3,4,5)
But what if we have these value in an array, like:
val array= intArrayOf(1,2,3,4,5)
then, to call this method we have to use spread operator, like:
sum(*array)
Here, *(spread operator) will pass all content of that array.
*array is equivalent to 1,2,3,4,5
But wait a minute, what if we call it like this: sum(array)
it will give us Type Mismatch compile time error:
Type mismatch.
Required:Int
Found:IntArray
The problem is sum function accept a vararg Int parameter(which accept value like: 1,2,3,4,5) and if we pass array, it will be passed as IntArray.
I'm trying to set a value to a variable inside a function in Enum.each, but at the end of loop, variable is empty and I don't know exactly why this behaviour.
Code:
base = "master"
candidates = ["stream", "pigeons", "maters"]
return = []
Enum.each(candidates, fn candidate ->
cond do
String.length(base) == String.length(candidate) ->
return = return ++ [candidate]
true ->
true
end
end)
IO.inspect return
At this example, return is expected to be ["stream", "maters"], but instead, it is only an empty list: []
My question is why this happens.
When dealing with languages like Elixir, it is better to think in terms of "values" and "names" instead of "variables".
The reason you cannot do what you want is that Elixir has "lexical scoping".
When you assign to a "variable", you create a new value in the inner scope. You never change the "value" of a "name" defined in the outer scope.
(you probably can get what you want with Enum.filter/2, but I'm guessing this is just an illustrative example)
EDIT:
As of today, Elixir will allow you to write something like this:
if condition_that_evals_to_false do
x = 1
else
x = 2
end
IO.inspect x # => 2
```
But this will be deprecated in Elixir 1.3
Any reason why you don't just filter?
Anyways it seems like you're trying to mutate the value of return which is not possible with Elixir.
base = "master"
candidates = ["stream", "pigeon", "maters"]
result = Enum.filter(candidates, fn(candidate) ->
length(candidate) == length(base)
end
IO.inspect result
Edit: I'd also like to add that based on your logic, all of the candidates would be returned
Not sure, since I've never worked with the language, but a couple things spring to mind:
String.length(base) == String.length(candidate) can be equivalent to true, which is already a pattern in your set.
It could also be a scope issue with the return variable. It could be that the local return is hiding the global return. You could check this by outputting return every iteration. Each iteration the return should contain a single entry.
This is a bug. From Elixir's documentation:
Note: due to a bug in the 0.12.x series, cond‘s conditions actually
leak bindings to the surrounding scope. This should be fixed in
0.13.1.
You should use filtering like #{Christopher Yammine} suggested.
I'm a beginner at groovy and I can't seem to understand this code. Can you please tell me how does this code operate?
def list = [ [1,0], [0,1,2] ]
list = list.sort { a,b -> a[0] <=> b[0] }
assert list == [ [0,1,2], [1,0] ]
what I know is the second line should return the value of 1 because of the spaceship operator but what is the use of that? and what type of sort is this? (there are 6 sort methods in the gdk api and i'm not really sure which is one is used here)
The code is using Collection#sort(Closure). Notice that this method has two variants:
If the closure is binary (i.e. it takes two parameters), sort uses it as the typical comparator interface: it should return an negative integer, zero or a positive integer when the first parameter is less than, equal, or grater than the second parameter respectively.
This is the variant that is being used in that piece of code. It is comparing the elements of the list, which are, in turn, lists, by their first element.
If the closure is unary (i.e. it takes only one parameter) it is used to generate the values that are then going to be used for comparison (in some languages this is called a "key" function).
Therefore, the snippet of code you posted can be rewritten as:
def list = [[1,0], [0,1,2]]
list = list.sort { it[0] } // or { it.first() }
assert list == [[0,1,2], [1,0]]
Notice that using this unary-closure variant is very convenient when you want to compare the elements by some value or some "weight" that is calculated the same way for every element.
The sort in your code snippet uses the comparator argument method call - see http://groovy.codehaus.org/groovy-jdk/java/util/Collection.html#sort(java.util.Comparator)
So, you are sorting the collection using your own comparator. Now the comparator simply uses the first element of the inner collection to decide the order of the outer collection.
I am new to Scala and am trying to get a list of random double values:
The thing is, when I try to run this, it takes way too long compared to its Java counterpart. Any ideas on why this is or a suggestion on a more efficient approach?
def random: Double = java.lang.Math.random()
var f = List(0.0)
for (i <- 1 to 200000)
( f = f ::: List(random*100))
f = f.tail
You can also achieve it like this:
List.fill(200000)(math.random)
the same goes for e.g. Array ...
Array.fill(200000)(math.random)
etc ...
You could construct an infinite stream of random doubles:
def randomList(): Stream[Double] = Stream.cons(math.random, randomList)
val f = randomList().take(200000)
This will leverage lazy evaluation so you won't calculate a value until you actually need it. Even evaluating all 200,000 will be fast though. As an added bonus, f no longer needs to be a var.
Another possibility is:
val it = Iterator.continually(math.random)
it.take(200000).toList
Stream also has a continually method if you prefer.
First of all, it is not taking longer than java because there is no java counterpart. Java does not have an immutable list. If it did, performance would be about the same.
Second, its taking a lot of time because appending lists have linear performance, so the whole thing has quadratic performance.
Instead of appending, prepend, which had constant performance.
if your using mutable state anyways you should use a mutable collection like buffer which you can add too with += (which then would be the real counterpart to java code).
but why dont u use list comprehension?
val f = for (_ <- 1 to 200000) yield (math.random * 100)
by the way: var f = List(0.0) ... f = f.tail can be replaced by var f: List[Double] = Nil in your example. (no more performance but more beauty ;)
Yet more options! Tail recursion:
def randlist(n: Int, part: List[Double] = Nil): List[Double] = {
if (n<=0) part
else randlist(n-1, 100*random :: part)
}
or mapped ranges:
(1 to 200000).map(_ => 100*random).toList
Looks like you want to use Vector instead of List. List has O(1) prepend, Vector has O(1) append. Since you are appending, but using concatenation, it'll be faster to use Vector:
def random: Double = java.lang.Math.random()
var f: Vector[Double] = Vector()
for (i <- 1 to 200000)
f = f :+ (random*100)
Got it?
Where can I find a list of Scala's "magic" functions, such as apply, unapply, update, +=, etc.?
By magic-functions I mean functions which are used by some syntactic sugar of the compiler, for example
o.update(x,y) <=> o(x) = y
I googled for some combination of scala magic and synonyms of functions, but I didn't find anything.
I'm not interested with the usage of magic functions in the standard library, but in which magic functions exists.
As far as I know:
Getters/setters related:
apply
update
identifier_=
Pattern matching:
unapply
unapplySeq
For-comprehensions:
map
flatMap
filter
withFilter
foreach
Prefixed operators:
unary_+
unary_-
unary_!
unary_~
Beyond that, any implicit from A to B. Scala will also convert A <op>= B into A = A <op> B, if the former operator isn't defined, "op" is not alphanumeric, and <op>= isn't !=, ==, <= or >=.
And I don't believe there's any single place where all of Scala's syntactic sugars are listed.
In addition to update and apply, there are also a number of unary operators which (I believe) qualify as magical:
unary_+
unary_-
unary_!
unary_~
Add to that the regular infix/suffix operators (which can be almost anything) and you've got yourself the complete package.
You really should take a look at the Scala Language Specification. It is the only authoritative source on this stuff. It's not that hard to read (as long as you're comfortable with context-free grammars), and very easily searchable. The only thing it doesn't specify well is the XML support.
Sorry if it's not exactly answering your question, but my favorite WTF moment so far is # as assignment operator inside pattern match. Thanks to soft copy of "Programming in Scala" I found out what it was pretty quickly.
Using # we can bind any part of a pattern to a variable, and if the pattern match succeeds, the variable will capture the value of the sub-pattern. Here's the example from Programming in Scala (Section 15.2 - Variable Binding):
expr match {
case UnOp("abs", e # UnOp("abs", _)) => e
case _ =>
}
If the entire pattern match succeeds,
then the portion that matched the
UnOp("abs", _) part is made available
as variable e.
And here's what Programming Scala says about it.
That link no longer works. Here is one that does.
I'll also add _* for pattern matching on an arbitrary number of parameters like
case x: A(_*)
And operator associativity rule, from Odersky-Spoon-Venners book:
The associativity of an operator in Scala is determined by its last
character. As mentioned on <...>, any method that ends
in a ‘:’ character is invoked on its right operand, passing in the
left operand. Methods that end in any other character are the other
way around. They are invoked on their left operand, passing in the
right operand. So a * b yields a.*(b), but a ::: b yields b.:::(a).
Maybe we should also mention syntactic desugaring of for expressions which can be found here
And (of course!), alternative syntax for pairs
a -> b //converted to (a, b), where a and b are instances
(as correctly pointed out, this one is just an implicit conversion done through a library, so it's probably not eligible, but I find it's a common puzzler for newcomers)
I'd like to add that there is also a "magic" trait - scala.Dynamic:
A marker trait that enables dynamic invocations. Instances x of this trait allow method invocations x.meth(args) for arbitrary method names meth and argument lists args as well as field accesses x.field for arbitrary field names field.
If a call is not natively supported by x (i.e. if type checking fails), it is rewritten according to the following rules:
foo.method("blah") ~~> foo.applyDynamic("method")("blah")
foo.method(x = "blah") ~~> foo.applyDynamicNamed("method")(("x", "blah"))
foo.method(x = 1, 2) ~~> foo.applyDynamicNamed("method")(("x", 1), ("", 2))
foo.field ~~> foo.selectDynamic("field")
foo.varia = 10 ~~> foo.updateDynamic("varia")(10)
foo.arr(10) = 13 ~~> foo.selectDynamic("arr").update(10, 13)
foo.arr(10) ~~> foo.applyDynamic("arr")(10)
As of Scala 2.10, defining direct or indirect subclasses of this trait is only possible if the language feature dynamics is enabled.
So you can do stuff like
import scala.language.dynamics
object Dyn extends Dynamic {
def applyDynamic(name: String)(a1: Int, a2: String) {
println("Invoked " + name + " on (" + a1 + "," + a2 + ")");
}
}
Dyn.foo(3, "x");
Dyn.bar(3, "y");
They are defined in the Scala Language Specification.
As far as I know, there are just three "magic" functions as you mentioned.
Scalas Getter and Setter may also relate to your "magic":
scala> class Magic {
| private var x :Int = _
| override def toString = "Magic(%d)".format(x)
| def member = x
| def member_=(m :Int){ x = m }
| }
defined class Magic
scala> val m = new Magic
m: Magic = Magic(0)
scala> m.member
res14: Int = 0
scala> m.member = 100
scala> m
res15: Magic = Magic(100)
scala> m.member += 99
scala> m
res17: Magic = Magic(199)