Is this best practice?

Hey,

I’ve just started this coursera course on Scala and I’m seeing super weird functions, and I was wondering if this was actually considered best practice in Scala?

Would love to hear thoughts from more experienced Scala devs :slight_smile:

Can you explain, what part of it you find weird? It looks pretty normal to me.

If you’re coming from an imperative language, it may take a bit getting used to lots of things being an expression (i.e. evaluating to a result), that would be statements (no result, run for a side effect) in other languages.

The body of a def in Scala is an expression, and the value it evaluates to is returned. if clauses are also expressions, an if returns the value from the branch it takes. This means you can write something like val x = if(cond) 1 else 0, and it will store either 1 or 0 in x.

Also the Coursera course is specifically about functional programming, which means you can’t have side effects. One kind of side effects is changing a variable, without which normal loops become pretty useless (or endless). Therefore looping in FP is usually done by recursion.

Btw., this is probably used as an example for recursion, but as you asked for best practice, that functionality is also in the standard library using ranges: (a to b).sum will have the same result.

2 Likes

Hi
In others language like Java, PHP, whatever, in an example like that it would be necessary using of Loop to resolve it but it would create a process that will finish only when you code loop would finish.
Using Function Langage, you have the same loop but each part of loop will spend a little part of computer memory.
But in short I will show a example using the code above

Image that a = 3 and b = 5
What will be the sum of integer between 3 and 5

Start program

3 > 5 no then 3 + sumInts((3+1),5) - open another thread
4 > 5 no then 4 + ((4+1),5) - open another thread
5 > 5 no then 5 + ((5+1),5) - open another thread
6 > 5 yes 0 finish process
Ok between 3 and 5 there are 3 number that are (3+4+5) = 12

2 Likes

Thanks for the explanations! That makes a lot of sense, I’ve been using Python mainly up to now and had not seen this function inside of a function thing but I like it a lot! It’s really efficient! Thanks!

Functions calling themselves, i.e. recursive functions, are actually possible in most languages, but in my experience teaching programming courses, learners often find it more difficult to understand than loops, so it’s used less often in imperative languages. There are problems that are simpler to express using recursion and others that are simpler using loops. You’ll probably also learn about for-comprehensions in the Coursera course, which are syntactically closer to loops.

As functional programming doesn’t allow normal loops, recursion is much more used there. But functional languages also usually make it easier to use. Scala also can optimize certain cases of recursion (called tail recursion), making them as fast and memory-efficient as loops (usually a loop is cheaper than a function call, and having deeply nested function calls can lead to a stack overflow). But I’d recommend to first get feeling for writing recursive functions in general, before learning how to write them tail-recursive.

1 Like

Let n = b - a. For large n, sumInts soon runs out of stack room and crashes. Moreover, sumInts takes theta(n) time, i.e., the maximum, minimum, and average running times are always proportional to n.

Here is a better way: The sum of i from i = 1 to n is n * (n+1) / .2. Hence the sum from a to b, is sum of i from 1 to b minus the sum of i from 1 to (a-1). Hence

def sumInts(a: Int, b: int): Int = b * (b + 1) / 2 - (((a - 1) * a) / 2 )

In real life one would check that a and b are positive. Also, division is a very expensive operation, so the divides by 2 should be replaced by right shift 1.