For Angry Java Developers: Scala Functional Programming


#1

For Angry Java Developers That Are Pissed Off At The Way Scala Professors present their material. ( this example was taken from Chapter 3, Functional Programming In Scala, Paul Chiusano and Runar Bjarnason.)

Write a function flatMap that works like map except that the function given will return a list instead of a single result, and that list should be inserted into the final resulting list. Here is its signature and definition as presented by the author:

def flatMap[A,B](l: List[A])(f: A => List[B]): List[B] =
concat(map(l)(f))

Now just looking at that definition will cause the typical Java Developer to throw his/her hands up proclaiming something to the effect: WTF is this jerk talking about!!!

But, me, being a little stubborn decided to decompose the definition:

The declaration seems to be saying: Given a list , take each element and convert that element into a List finally converting all the individual lists to one list of
elements.

def flatMap[A,B](l: List[A])(f: A => List[B]): List[B] =
concat(map(l)(f))

So what does: concat(map(l)(f)) actually do? Well, map(l)(f) will do the following:

apply the function , f , to every element in l. Lets observe that behavior:

def map[A,B](l: List[A])(f: A => List[B]): List[B] =
l match {
case Nil => Nil
case Cons(h,t) => Cons(f(h) ,map(t))
}

Now this will seemingly convert the List of elements into a List of List of elements. This in turn is passed to the concat method.

Again, lets analyze concat to see what it does:

According to the author’s definition of concat we have:

def concat[A](l: List[List[A]]): List[A] =
foldRight(l, Nil:List[A])(append)

Now the definition of concat is a function that takes a List[List[A]] and returns a List[A] which is what we actually want to happen. But how does it do this?

foldRight(l,Nil:ListA !!!

Holy Cow!

foldRight’s purpose is to take a list, apply a function to the elements of the list moving from right to left until all the elements are exhausted and then return a terminating element which is in this case: Nil:List[A]. So it boils down to what the append function is doing to pairs of elements of the input list.

In steps the definition of append:

def append[A](a1: List[A], a2: List[A]): List[A] =
a1 match {
case Nil => a2
case Cons(h,t) => Cons(h, append(t, a2))
}

QED


#2

I thought the title meant, Java programmers angry at Java. I have to use Java in my day job, and it makes me angry every day. I have no doubt that Java makes my life expectancy shorter. It costs me not only the time to program, but years snipped from the end of my life, such as it is.


#3

Not to mention the days or weeks just lost because you spent them being angry about the stupid things that are stupid, rather than just doing the stupid thing, which usually takes far less time than I spent being angry about it.


#4

@sidhartha11 as an angry markdown user could I ask you to edit your post and put your code blocks inside triple back ticks,


#5

No. It was meant as a humorous title describing the frustrations of a java developer, like me, attempting to read a functional programming book using scala


#6

Triple back ticks? Explain?


#7

Surround blocks of code with three “`” - which some call a “backtick”. That way your code will look like this:

def flatMap[A,B](l: List[A])(f: A => List[B]): List[B] =
  concat(map(l)(f))

Instead of:

def flatMap[A,B](l: List[A])(f: A => List[B]): List[B] =
concat(map(l)(f))

Also, how would you express this in Java that would be so much easier to read?


#8

Hi Sidharta,
What is your doubt exactly?
By the way, it is natural be a bit perplexed when dealing for the first time with functional programming if one has learned programming just through imperative languages like Java, C, etc. Even more so functional programming with Scala.
What steps have you taken so far in your effort to learn Scala?
Functional Programming in Scala is considered an advanced book.
Maybe you could have a more gentle aproach in your efforts to learn Scala.
As you already know Java maybe you could read “Scala for the Impatient”, 2nd edition (https://horstmann.com/scala/). An then
Functional Programming, Simplified (https://alvinalexander.com/scala/functional-programming-simplified-book).
There is many people here willing to help, you just have to be polite. Don’t be angry.
Cheers.


#9

Granted, but again – you’re trying to run before you can walk. I mean, I didn’t start playing with that stuff until I’d been working full-time in Scala for 3+ years. I find that most people need to ease gradually into FP…


#10

Understand exactly what you meen. The book, functional programming in scala, is somewhat of a challenge


#11

Im as nice as a Labrador


#12

I’d like to address what I see as a common misunderstanding about what it means to do functional programming in Scala, particularly among Java developers who are new to Scala.

There seems to be a notion that you start off using Scala as an alternative syntax to Java until you have completely mastered FP (and understand the book mentioned here), at which point you switch from procedural to FP.

That’s not the right way to look at it. You can get most of the benefits of FP for most application programming by following a few simple rules, such as:

Of the classes that you define yourself and instantiate, nearly all of them should be immutable case classes. That means no var fields in the class definition.

Variables are OK inside of methods and functions unless you are doing parallel processing in the method. Of course, vals should be preferred to vars inside of methods, but they are not essential. Don’t bend over backwards trying to avoid a var inside a method (or function) just for the sake of avoiding a var.

To create a modified version of an immutable case class instance, use the copy method to change one or more fields while leaving everything else unchanged. The copy method is your friend! Get to know it.

Use expressions instead of statements.

Do not mix IO and algorithms in the same method.

Use Vector instead of Array. Use basic functional methods such as map and yield to transform Vectors when necessary.

Did I miss anything obvious?

If you follow these simple rules, I contend that you can get at least 90% of the benefits of FP for 20% of the cost of learning it. At least for the kind of application programming that I do.


#13

I have walked ( or hobbled ) a little reading the book, programming in scala, 2nd edition. Decided to take a break and opened the functional programming in scala book. It is a bit tough, but since i am approaching it as a part time summer hobby only it is ok.just requires careful analysis, er, slow careful analysis


#14

I don’t know about 90%, but certainly a lot. Indeed, I’d gone a fair ways down the FP road simply by following the capabilities that were built into C# a dozen or more years ago. Simply learning to favor immutability and higher-order functions makes an enormous difference in one’s programming style…


#15

Focusing on the exercise 3.20, the answer
concat(map(l)(f))
I saw that you considered the answers in the booklet Funcional Programming in Scala Companion.
concat is the function defined in exercise 3.15
def concat[A](l: List[List[A]]): List[A]
In exercise 3.18
map has the following signature
def map[A,B](as: List[A])(f: A => B): List[B]
and not
def map[A,B](as: List[A])(f: A => List[B]): List[B]
But the parameter function f of flatMap has the signature
f: A => List[B]
So, when applying map, type B of map context result in a type List[C] in the context of flatMap and
List[B] of map context would result in LIst[List[C]] in the context of flatMap.
The result of map(l)(f) has type List[List[C]]

So, concat(map(l)(f)) makes sense. Can you see?


#16

Refrasing the last part:
So, when applying map, type B of map context result in a type List[B] in the context of flatMap and
List[B] of map context would result in LIst[List[B] in the context of flatMap.
The result of map(l)(f) has type List[List[B]]


#17

My area of expertise in java was/is multithreading. That being the case, imutability is my default mode of implementation. So, al the hoopla about mutability versus immutabity , er , mutable versus immutable is amusing, somewhat. I completely understand that design paradigm. But not sure about how it helps in learning fp otherthan having the ideal of immutable not being a new concept


#18

What “hoopla” are you referring to? As far as I know, immutable collections are not the norm in Java. If you are using them, you must be doing FP to some extent at least.


#19

What I mean by hoopla is this: In the java eco system/development environment, there are many different types of developers that do different types of work , you might say.
For developers that are interested in utilizing multiple cores and now multiple separate machines in the development work they do, immutable objects are the default , for the most part. The limited number of collection classes in java are, as you say, mutable by default. However, in multi-threaded and/or distributed processing, the objects stored in those collections are immutable. The collections themselves can be wrapped in various ways, forcing them to behave as immutable collections. This is just , actually, the correct way , in my opinion, that Java developers should approach their development. When you design your classes, those classes should be immutable. There are various design idioms that allow you to accomplish this in Java. In a pure form of development, free of frameworks, and in an environment in which speed and efficiency is of utmost importance … then … you program in a way that is very foreign to many, even some seasoned java developers. All your instance variables are made private and final so that they can never be changed … Objects are created via Constructor instantiation only … no internal state is ever allowed to escape …
---- BUT ----
Big deal … Java has its strong points. Currently, I have yet to consider Scala as an efficient programming language. I am not interested in scala for reasons of efficiency or speed at the moment. I am only curious about the interesting constructs presented in the language and also of the approach Scala appears to take for Functional Programming.
Thus far, I can only view Scala as a powerful scripting language due to its rich collections and functional programming techniques. It also makes a lot of things easy and concise to do.
I have a lot to learn about Scala . I am just a newbie at the moment. And right now Scala is a BIG complicated thing for me to understand … haha


#20

In Scala you can do the same kind of programming you did in Java, only a lot easier, cleaner, more fun, less ugly, … And you can take it a couple steps further also if you want. But you don’t have to (but you can if you want!) go to the limit of pure functional programming and interpret your entire program in an IO monad. Functional programming can also just mean that you program with referentially transparent functions and immutable data as much as possible, try to keep mutation as local as possible if necessary, try to push I/O to the boundaries of your application, …