
Advantages of Functional Programming in Java 8 - Kellanved
https://bulldogjob.pl/articles/156-the-advantages-of-functional-programming-in-java-8
======
bad_user
The article isn't about functional programming.

Functional programming is programming with pure (mathematical) functions. As a
consequence, functional programming is also programming with (immutable)
values (i.e. persistent data-structures, etc).

This isn't pedantry. The whole point of FP is being able to have your code be
"referentially transparent", a property that gives you "equational reasoning",
making your code more composable, more testable and easier to understand
because you can take any function, divorce it from its surrounding context and
still make some sense of it. Of course, there's no silver bullet, yada yada,
but take those traits away and the definition loses meaning and usefulness
almost completely.

And btw I shouldn't need to specify "pure" or "mathematical" if programming
wouldn't have overloaded the meaning of the word "function". We could have
stuck with "procedure" or "routine" or "sub-routine". As in jumps in code that
push and pop the call stack and that have side-effects. And if you want to
express the act of programming using side-effectful functions, there's also a
perfectly adequate term for it already: " _procedural programming_ ".

Yes, it's cool having closures and anonymous functions in your language. It's
sort of a prerequisite if you want your FP code to be comfortable. But that's
not FP. There's actually nothing resembling FP about the code samples in the
article. And the implementation of AccountConverterImpl would make any
programmer that likes FP to cringe.

On Java 8: yes, it's becoming possible to do FP, sort of anyway. But it's
still painful as hell, with the environment actively working against you.
First of all there aren't many libraries that do FP in Java, I only know of
functionaljava.org. So you're swimming against the tide, with the standard
library itself being actively hostile to FP. And you can start from the fact
that Java 8 was released in 2014 and even its new Option type is breaking the
Functor laws, because map(x).map(y) != map(x.andThen(y)) and lets not even
mention the word monad because it scares people.

But I guess that if you're forced to use Java, well, then you can find some
ways to cope with it (especially if you aren't scared of building your own
stuff).

~~~
jerven
So Lisp is not a functional language...

~~~
baldfat
So R isn't a functional language...

To be fair the vast majority of people would say that it isn't BUT hidden
inside is a very Scheme inspired system that can make pretty functional
programs.

[http://link.springer.com/chapter/10.1007%2F978-3-642-40447-4...](http://link.springer.com/chapter/10.1007%2F978-3-642-40447-4_12#page-1)

~~~
catnaroek
Scheme isn't a very good functional programming language either. Even cons
cells are mutable objects with identity: just use eq? everywhere instead of
equal?, and use set-car! and set-cdr! instead of creating new cons cells, and
you're back to JavaScript.

\---

Sorry, can't reply properly, I'm “submitting too fast”.

<ignore>I understand neither the form nor the content of your objection. Is
Scheme a programming language? Yes. What does this have to do with whether it
supports functional programming reasonably well?</ignore>

Scheme is a higher-order programming language: procedures are first-class
objects whose identities can be bound to variables just like any other value.
I'm not sure about calling it “functional”, though: the type of procedures
isn't fully abstract, because you can query the physical distinction between
two procedures that have the same behavior when called. In other words, in
Scheme, procedures are _objects_ , but they are not _values_.

~~~
baldfat
Scheme is a functional programming language yes?

Sorry but I am an old timer and seeing people blast the paths that led us to
where we are is very frustrating to me.

Edit added is a functional

------
edejong
I am really wondering why this is on HN front-page. It does not provide any
good, in-depth analysis of FP in Java 8. In the contrary, the writing seems to
be incoherent and assuming knowledge of a certain Java stack.

~~~
b15h0p
Agreed. A major red flag is the omission of generics usage on their methods.
Just using List or Collection without type parameters is just dangerous and
very bad advice for a novice programmer seeking enlightenment for Java 8
programming.

~~~
misja111
It looks like the generics used to be there but have been removed. Because
there is one generic type 'T' left in the implementation of
ClassUtils.setIfNotNull.

So about this setIfNotNull: I don't understand why this method is used in
updateEntity. To me it seems the accountType property in the dto can be set
with whatever is in the entity, null or not null. And of course, Java 8 has
introduced the Optional class as a better way of dealing with null values, so
why bother writing a workaround at all?

~~~
hepta
I see now, probably just something to do with formatting/escaping, the <> are
being swallowed.

Yes, it's strange. I'd prefer to map a null in a DTO to an empty optional. I'd
like even more to never have nulls in the dto in the first place.

------
islon
For me the biggest advantage of FP languages is exactly not have to deal with
`GenericConverter`s, `AbstractDTO`s, `BaseEntity`s and other overly-complex
constructs that many OO languages inflict upon the programmer, but to create a
small and simple sub-language that solves my problem without making it even
more complex.

~~~
kozikow
You can horribly engineer things, regardless if you use haskell or Java.

I've seen Java code like you described, but I've also seen big java projects
written in clear, no-nonsense style. For example, look at any open source Java
projects released by Google.

I've also seen FP projects that require all engineers to learn category
theory. Even when armed with programmers proficient in FP, project did not
seem significantly more productive or less buggy from the outside. The
approach-ability was lower - you couldn't just quickly glance how something
works, even if you knew FP.

The most successful approaches I have seen involved adapting good functional
concepts - referential transparency, immutability, compos-ability, minimising
local state, functions as objects. They rarely went dogmatically all-in on
pure-FP/category-theory/DSL-all-the-things. I strive to write code adhering to
those rules, even in non-FP languages, but ultimately favouring practicality
and I believe that I get the best of both sides.

------
pmontra
Every time I see a class like ClassUtils I remember that OO is only good for
half of the programs we have to write (1). Problem is, it's a half of each
source file. On the other side, OO is a very convenient abstraction for the
other half.

(1) I'm sure there are more gracious ways to do that, but maybe not in a
single line. That's why we keep seeing classes whose only purpose is to be
bags of random methods.

~~~
ajuc
Even C++ has the solution to that - separate namespaces and classes. Allow
standalone functions.

    
    
        namespace Utils {
             void setIfNotNull(const Supplier& getter, const Consumer& setter) {
                 ...
             }
        }
    
        ....
    
        using namespace Utils;
        setIfNotNull(...);

~~~
odabaxok
I believe you can achieve the same in Java by static import.

EDIT: Also, I think the parent comment was not complaining about the missing
possibility of creating standalone functions, but rather saying that not every
functionality can be forced into objects, i.e. there is still need of
standalone functions in OOP.

~~~
ajuc
You still have to put each method in some class in java, in C++ you can just
put it in namespace. It makes more sense, even if in practice the difference
is minimal.

> there is still need of standalone functions in OOP

Yes, and that's what I've shown?

~~~
ivan_gammel
It's a syntax issue. Final class with private constructor and all members
being static is effectively a namespace.

~~~
scott_s
I think it's more than just syntax - it's culture. In C++, free standing
functions has been a part of the culture of the language since the beginning.
The design of the language encourages them - there are even cases, such as
operator overloading, where it's preferable to implement it as a free standing
function rather than a class method. In Java, when I write a class that is a
collection of static methods, I feel like I'm fighting _against_ the language
and it's culture, even though they are sometimes used.

~~~
ivan_gammel
How much do you write code on Java?

Such functional namespaces were part of Java from the very beginning (Math is
a good example and with release of Java 8 now there are many more in standard
library). I have not seen an enterprise project yet, in which there's no
something ending with Utils or Helper, that is just a collection of functions.
Such naming is an anti-pattern, of course, but still, almost every developer
in Java world uses this and has it part of it's development culture.

~~~
ajuc
> Such naming is an anti-pattern, of course

This is exactly the cultural problem with too strict adherance to OOP :)

It's like people saying "nails are anti-pattern of course, but people still
use them, so we've added hammer-heads to our screwdrivers".

~~~
scott_s
Yes, that was the point I was getting at. It's obviously part of how real Java
code is written, but I feel like I'm going against how the language was
designed when I do it. (Clearly, everything is _not_ an object, and a class is
not always the most appropriate way to group code.)

------
cromwellian
There's something about these kinds of threads that seems somewhat snobbish
and tribalist. There was a similar rant a few weeks ago over whether your
'FRP' is really 'FRP' ([https://medium.com/@andrestaltz/why-i-cannot-say-frp-
but-i-j...](https://medium.com/@andrestaltz/why-i-cannot-say-frp-but-i-just-
did-d5ffaa23973b#.7ht5m8am1))

I think we can all agree that there's a certain beauty and elegance to
completely functionally pure programs. CycleJS for example, really pleases me
compared to the complexity of React.

However, like everything in life, the real world is messy and hard to squeeze
into binary categories. I can't forsee any large scale program that adheres to
such constraints without bending over backwards in weird contortions to meet
the limitations imposed, to the extent that such code may even be harder to
reason about than mutative code.

I think practical languages 'win' by being 'worse', by compromising and
allowing the developer to shoot themselves in the foot a little.

~~~
willtim
Haskell is absolutely capable of mutation, it's just controlled and tracked.
IMHO, immutability is simply a saner default for a high-level language. I
think languages "win" due to socio-economic reasons, not technical ones.

------
dschiptsov
> _Adding a new Converter for another entity-DTO pair (like User, Address,
> etc.) needs just creating a new UserConverterImpl class, implementing its
> own UserConverter, which in turn should implement GenericConverter._

This is exactly what is wrong.

Unnecessary complications resulting from not merely over-engineering but
piling up completely unintelligible crap, produced in order to... well, use
some Java 8 features.

Imagine that in math instead of doing algebraic simplification one would go
into the opposite direction.

Same kind of madness, BTW, is going on in the realm of Javascript frameworks.

------
myst
FP in Java. HA HA HA OH WOW

