3

I'm totally new with Scala, I have to maintain an old code, so I have to understand what it does.
Now I am stuck on this piece of code, it is about defining and calling a method.

This is the definition of the method:

private def myMethod[I, O](price: Long, id: Int)(i: I)(f: (I, String) => O): O = {
      ..some code..
}

this is the method call

myMethod(price, id)(b) {
      ..some code.. //single line of code, just calling an other function 
}

I understood the part of having type parameter also of having multiple parameter (currying).
But what I didn't understand, is :

  • first of all this part: (f: (I, String) => O) , this is completely strange for me
  • second, why in the method call, it contains code after the { symbol, is it overriding the original method? even it's the case, it make no sense to override it when making the call
  • also, myMethod is supposed to return a value of type O , but in my code it's never affected to any variable. (EDIT: this point is clear now, I just misunderstood the code, nvm mind about it)

Please can any one clarify this points (especially the first and second one which are making me so confused)


EDIT

private var x : classX

myMethod(price, id)(b) {
      x.listX //calling method without parameters
}

def listX (param1: ListFaFBI, param2: String): ListX ={
  //returning an Object of type ListX, not a function
}

as you can see that myMethod is calling listX. if I understood well, myMethod is returning the method listX itself which has two parameters ListFaFBI (or I) and String and returning ListX (or O) as defined in (f: (I, String) => O)

Bashir
  • 2,057
  • 5
  • 19
  • 44
  • 2
    `(I, String) => O)` this asks for a function. `{ ... some code ... }` passes the function, in Scala we can omit the parenthesis when calling a method with a single argument. Maybe in your case, the `O` is inferred to **Unit** thus no need to assign the result, or maybe the function is just called by their side-effects. Anyways, this is just basic syntax any tutorial should have covered, if you are going to maintain some code, it would be good to study a little bit more. – Luis Miguel Mejía Suárez May 29 '20 at 16:52
  • @Bashir that single line of code you say is inside the curly braces - what function does it call and what is the return type of that function? I think it might be a higher order function – user May 29 '20 at 17:12

2 Answers2

3
  1. f is a function that takes in an I and a String and returns an O. f: (I, String) => O is syntactic sugar for f: Function2[I, String, O].

  2. The braces act essentially the same as parentheses would, although there are some differences, as they can be treated as blocks (See this question). The code inside the braces is actually a function literal, and it will be passed as f. Also see this question. Here,

myMethod(price, id)(b) { (i, s) =>
      ..some code.. 
}

would be syntactic sugar for

myMethod(price, id)(b)({ (i, s) =>
      ..some code.. 
})
  1. I'm not sure what you mean by "in my code it's never affected to any variable", but I assume that what is returned is either irrelevant or that there is an implied return (in case the call to myMethod is at the end of a block.
user
  • 7,435
  • 3
  • 14
  • 44
  • hmm nice, I understand now, but if the method f takes an `I` and a `String` as parameter, why I have directly braces and the code of the method, where are this parameters, I mean the `I` and the `String`? – Bashir May 29 '20 at 17:01
  • @Bashir Can you show me what "...some code..." really is? Is it just an expression or does it have something like `(i, s) => `? – user May 29 '20 at 17:02
  • 1
    @Bashir after the braces there should be something like `{ foo =>` or `{ case (i, str) =>` or `{ _.foo` if not, then it seems like a syntax error, but maybe there is an implicit conversion happening, without seeing actual code is hard to help. – Luis Miguel Mejía Suárez May 29 '20 at 17:03
  • @Bashir It's possible that the function looks like an expression because it uses underscores, like `{ _ + _}` – user May 29 '20 at 17:03
  • @user please reject my edit for your answer, it was a mistake from me – Bashir May 29 '20 at 17:15
  • I edited my answer to mention that in the some code, it is just calling an other function in a single line of code – Bashir May 29 '20 at 17:16
  • @Bashir maybe that method also returns a function? – Luis Miguel Mejía Suárez May 29 '20 at 17:18
  • 1
    @LuisMiguelMejíaSuárez Yeah, that's what I thought too. Might be another curried function – user May 29 '20 at 17:19
  • 1
    no it returns an object, I'm sorry guys now it's the weekend, I'm at home and I don't have the code right now, but I assure you that it returns an object – Bashir May 29 '20 at 20:30
  • @Bashir Is it at all possible the object has an `apply` method that takes 2 arguments? If not, that code probably shouldn't work – user May 29 '20 at 20:41
  • I edited the question, I added what is being called inside myMethod , as you see it is calling an other function which returning an Object, not a function that takes 2 arguments. the code is working in prod years ago, so it works, but is's confusing me more and more .. – Bashir Jun 01 '20 at 08:50
3

first of all this part: (f: (I, String) => O) , this is completely strange for me

It is a function, taking a tuple of two elements of type I and String, and returns an O

why in the method call, it contains code after the { symbol, is it overriding the original method?

Your method is using multiple parameter list, and the syntax of the last parameter group is a block definition that allows to define the function value ((I, String) => O)

For example, if we had a method which takes a function in the same parameter list:

def foo(s: String, f: String => String)

Our implementation would look like this:

foo("hello", {
    s => s + "world"
  }
)

However, if we used a separate parameter group:

def foo(s: String)(f: String => String)

Our implementation look like this:

foo("hello") {
   s => s + "world"
}

Which is more eye pleasing and reads nicer.

myMethod is supposed to return a value of type O , but in my code it's never affected to any variable

If you add the implemention of the method we can better help show you where it is returning a value of type O

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321