News for hackers. Stuff that matters.
Re:“Coding is basically just ifs and for loops.” by laurent92 on Saturday December 04, 2021 @05:40PM (#29444960)
That’s what disappoints me in modern Java. There is practically no ifs. It makes it inaccessible to beginners on the project, and the streams are about twice as slow… just because devs think they are more clever if they pile 7 “.map()” to transform a list.

list.stream().filter(Objects::nonNull).map(User::getUsername).filter(Objects::nonNull).filter(name -> name.contains(searchString)).map(name -> “We have found your user: “ + name).orElse(“We haven’t found”);

Basically unreadable.

for (User user : list) if (user != null && user.getName() != null && user.getName().contains(searchString)) return “Found it!”;

return “Not found”;

Re:“Coding is basically just ifs and for loops.” by filoeleven on Saturday December 04, 2021 @07:03PM (#29445483)
That’s a failure of Java’s language design, not a failure of the functional/declarative paradigm.

Your for loop can do all kinds of damage to the list, and you have to read it all to find out what it does. Saner languages make the functional version more expressive.p:

  return first(users.filter(u => contains(u.name, searchString))
I’m not saying JS is a sane language; it has an anemic standard library without a robust “first()” or “contains()”. But that code gets you the first user where the name matches, without resorting to indexes or null checks or worrying about how a for loop can mutate lists that it should not.

EDIT: I should have used filter(list fn) here, I was trying to write something plausible in JS instead of a purer functional language and misses that translation.

Re:“Coding is basically just ifs and for loops.” by nayuki on Saturday December 04, 2021 @07:45PM (#29445736)
Re:“Coding is basically just ifs and for loops.” by filoeleven on Saturday December 04, 2021 @08:40PM (#29446028)
Same caveat applies here as my other sibling comment. I shouldn’t have to do null checks before calling functions.
Re:“Coding is basically just ifs and for loops.” by salawat on Sunday December 05, 2021 @12:15AM (#29446918)
I shouldn't have to QA properly written code.

Alas, reality, she is a cruel mistress.

Re:“Coding is basically just ifs and for loops.” by FpUser on Saturday December 04, 2021 @08:42PM (#29446039)
>"Your for loop can do all kinds of damage ..."

So can programming in general

Re:“Coding is basically just ifs and for loops.” by usrbinbash on Saturday December 04, 2021 @07:25PM (#29445625)
>and you have to read it all to find out what it does.

Which isn't a problem, because as long as its all loops'n branches, the code is easy to understand.

Re:“Coding is basically just ifs and for loops.” by filoeleven on Saturday December 04, 2021 @08:46PM (#29446053)
Hard disagree. For loops do not have guarantees about in-place mutation; that’s why they require a full read. Anything that starts with a map/filter is guaranteed to only apply to the thing that it is assigned to. That’s more than worth its weight in grey hairs.

EDIT: “full read” includes “everywhere else this array is used, which can have far-reaching consequences if it was passed into the containing function by reference.”

Re:“Coding is basically just ifs and for loops.” by jstimpfle on Saturday December 04, 2021 @09:33PM (#29446256)
Most temporary variables are single assignment, and many newer procedural languages do have variable declaration syntax for single-assignment variables. Such as Javascript's `let`.

Another wide-spread syntax feature is for-loops over collections like `for item in list`, again being extremely easy to read and not requiring any assignments. So, accidental in-place mutation is not an issue in practice. But, in-place mutation can be very useful to express logic in an easy to understand way.

Coincidentally my main language does not have any of these features, and in-place mutation is like 0.1% of all my problems. (And notably, memory management is < 5% of my problems).

These are all just theoretic problems, what really matters is developer experience. You can write terrible bug-ridden convoluted code in any language, ESPECIALLY with many filters and lambdas and callbacks.

The issue with the functional style is that it becomes harder to see the control flow and run-time characteristics. I'm sure functional style is great to express set operations (like DB queries) but IME they tend to optimize for source code brevity and pessimize for runtime performance.

Re:“Coding is basically just ifs and for loops.” by filoeleven on Sunday December 05, 2021 @11:08PM (#29456019)
DB queries are a good analogy, especially if we qualify them as atomic operations. I’m hard-pressed to find a situation where procedural mutation-in-place makes more logical sense than an atomic update of the whole list, so why not make atomic updates the default?

It’s different if you’re working in lower-level code. I don’t intend to trivialize performance; the option to “go procedural” should be available. I just think it’s the wrong default. Operating systems and some kinds of Big Data need those perf boosts.

But for your run-of-the-mill CRUD app, map/filter is both clearer and safer than a for loop. Strong language support encourages this both algorithmically and syntactically—unlike what Java did, which is what I originally replied to.

Re:“Coding is basically just ifs and for loops.” by int_19h on Wednesday December 08, 2021 @07:59PM (#29492602)
JS "let" is not single-assignment; did you mean "const"?
Re:“Coding is basically just ifs and for loops.” by jstimpfle on Thursday December 09, 2021 @08:27AM (#29497059)
Oops, guess you're right. I haven't written any Javascript in years.
Re:“Coding is basically just ifs and for loops.” by usrbinbash on Sunday December 05, 2021 @04:53AM (#29448052)
>For loops do not have guarantees about in-place mutation;

Every modern language has a `for elem in range` construct, giving exactly that guarantee, as long as the element isn't a pointer.

Besides, I neither want nor need such a guarantee. There are many scenarios where in-place mutation is exactly what I want to do in a loop, and I don't want to fight the language, aka. my craftsmans tool, to do it, just because it imposes an arbitrary restriction on what I can or cannot do.

Is this a potential source of bugs? Of course it is. That's why I have tests, code reviews and debuggers.

And besides, nothing prevents me from doing the functional approach in languages like Golang, Python or Julia *if I want to*. I simply refuse to use languages that that force a paradigm on my code. This is true not only for "pure functional" languages, but also Java, which wants me to use OOP everywhere.

To me, paradigms are tools. They need to be there when I need them, and get not get in my way when I don't.

Re:“Coding is basically just ifs and for loops.” by valenterry on Sunday December 05, 2021 @01:08AM (#29447166)
The first, filter, map, etc. functions are also only loops&branches under the hood, no? :)
Re:“Coding is basically just ifs and for loops.” by gavinray on Saturday December 04, 2021 @07:20PM (#29445594)
JS has Array.some() for "contains"
Re:“Coding is basically just ifs and for loops.” by filoeleven on Saturday December 04, 2021 @08:55PM (#29446093)
The caveat there is that you cannot call it without a null check on “u.name” first. contains(null, “whatever”) would just return false instead of throwing a runtime exception. Hence my edit: users.filter() has the same problem.
Re:“Coding is basically just ifs and for loops.” by peoplefromibiza on Saturday December 04, 2021 @06:46PM (#29445393)
the two snippets you posted do different things

In a list

  John
  Jonhatan
  Joy
searching for "Jo" returns all three of them in the first example, it stops when the first has been found in the second.

Start including the tedious bits about adding found items to the list and the waste of intermediate variables and your "clear" code is wrapped around a lot of repetitions, that only add noise.

It just happens that you are more familiar with the second style, but pipelines are better in many other ways, clarity of intentions being one of them.

Re:“Coding is basically just ifs and for loops.” by RHSeeger on Saturday December 04, 2021 @10:48PM (#29446536)
The code he posted isn't actually valid because you can't "orElse" a list. That being said, I would presume it was meant to include a "findFirst". Something like

    list.stream().filter(Objects::nonNull)
        .map(User::getUsername).filter(Objects::nonNull)
        .findFirst(name -> name.contains(searchString))
        .map(name -> “We have found your user: “ + name)
        .orElse(“We haven’t found”);
Re:“Coding is basically just ifs and for loops.” by peoplefromibiza on Sunday December 05, 2021 @04:40AM (#29447997)
exactly, that was the catch.

the point I wanted to make is that the snippets presented seem carefully crafted to make pipelines look bad, but usually that's not the case.

Re:“Coding is basically just ifs and for loops.” by freidenker on Sunday December 05, 2021 @05:16AM (#29448149)
The snippets actually do the same thing, as long as you add a .findFirst() to the first example to make it valid Java code.

Intermediate stream operations like map or filter are always lazy. And .findFirst() is a short-circuiting terminal operation, that does not need to consume all stream elements.

https://docs.oracle.com/en/java/javase/11/docs/api/java.base...

Re:“Coding is basically just ifs and for loops.” by peoplefromibiza on Sunday December 05, 2021 @03:17PM (#29452733)
obviously that was the point, if you don't even care to write correct code, you can make every piece of code look bad.

Truth is java streams and, even more, reactive java are the only two things that make java bearable, god save who invented them.

If I had to program java with for loops and list.add or null checks everywhere, I would probably kill myself on the spot.

But the amount of programmers taught to program like it's still 1995 it's so damn high

And I am closer to my 50s than my 40s, I can't understand why people fresh from uni say they can't understand something like

  list.stream() 
  .map(this::maybeGetUser)
  .filter(maybeUser -> userIsPresentAndNameStartsWith(maybeUser, prefix))
  .findFirst()
  .orElseThrow(new UserNotFoundException());

with the benefit of being lazy and only inspecting list items up to the first one that matches (and if you don't mutate any data, easily parallelizable)
Re:“Coding is basically just ifs and for loops.” by the_gipsy on Saturday December 04, 2021 @06:36PM (#29445321)
You forgot to add null-check ifs for `list` and `searchString`. Oh and check-wrap for exceptions too!
Re:“Coding is basically just ifs and for loops.” by raxxorrax on Wednesday December 08, 2021 @08:49AM (#29484629)
Modern Java looks horrible to be honest. I create abominations like this in JS pretty often, but it isn't good code. Best if wrapped in a huge try/catch where the error case juwt prints "didn't work for some reason...".

https://esolangs.org/wiki/Pancake_Stack Pancake stack doesn't need this hipster crap like functional programming or ifs or fors.

Re:“Coding is basically just ifs and for loops.” by cmeacham98 on Saturday December 04, 2021 @08:17PM (#29445921)
I don't write java, but assuming it has a null coalescing operator you can likely do all that in a single map in a way that is (in my opinion) cleaner and easier to read than both of your examples.
Re:“Coding is basically just ifs and for loops.” by erik_seaberg on Saturday December 04, 2021 @11:05PM (#29446610)
Kotlin does but sadly Java’s Optional<T> has no syntactic sugar, so it ends up looking like

  Optional.ofNullable(user).map(User::getUsername).map(name -> name.contains(searchString))
Re:“Coding is basically just ifs and for loops.” by ineedasername on Saturday December 04, 2021 @05:53PM (#29445054)
Java has never really liked to do in 10 characters anything that could be done in 30 characters instead, especially if it obfuscated things a bit more at the same time.
Re:“Coding is basically just ifs and for loops.” by MattPalmer1086 on Sunday December 05, 2021 @05:38AM (#29448247)
I just started using Java's functional side a few weeks ago. Lambdas are really nice and often make the code clearer. I like writing more declaratively.

But the stream interface is just horrible. I had to read a lot before I understood how to just filter a list and collect the results. And even after that, it still somehow didn't scream out what it was doing to me. I guess you get used to it.

Re:“Coding is basically just ifs and for loops.” by angelzen on Saturday December 04, 2021 @11:45PM (#29446744)
Coding is values, arrays, dicts, ifs, loops and functions. An expressive set-like operations library over arrays (& dicts) gives superpowers.
Re:“Coding is basically just ifs and for loops.” by AtlasBarfed on Saturday December 04, 2021 @08:32PM (#29445995)
Groovy is still far better and more readable. And with @CompileStatic it is basically the same speed.
Re:“Coding is basically just ifs and for loops.” by benwaffle on Tuesday December 07, 2021 @02:40PM (#29477234)
Scala is super readable

   users.find(_.name.contains(str))