Live data from Hacker News

Mindset shifts for functional programming (with Clojure)

blog.janetacarr.com

21–30 of 100 posts

Re: Mindset shifts for functional programming (with Clojure)

#21

Earlier quoted context omitted.

Out of curiosity is there actually any chipset with the algorithmic ability to add more than 2 numbers altogether in one operation (without having to store intermediate results)? I'd also think looping is far closer than recursion to how we tend to manually calculate things (either entirely in our heads or using a pen & paper or even a basic calculator). (Edit: looks like a number of other posters have made the same…

Chips have ability to run vector operations that can add a bunch of numbers. The issue is that recursion in software development is relatively rarely about arithmetic operation. For example, you might want to traverse a tree of objects (like a filesystem folder) to run some operation on them, etc. In this case the intermediate information is pointers to where you are currently processing various folders in your tree…

Vector operations that perform the same fixed addition to each element, yes, but that's not really the same thing.

And yes I'm very much in agreement that the real power of recursive algorithms is when working with tree-like data structures.

Re: Mindset shifts for functional programming (with Clojure)

#22
If your team and you can read it later or when it goes wrong, then it's fine.

I don't want to need to think hard about what code does, it should be clear. Or jump through 100 files to find a simple algorithm that has been divided into 100 pieces.

I think people refactor to their own understanding or mental model or refactor-to-understand.

I think there are cases where imperative code is intuitive and others where functional code is intuitive.

I've worked on two professional projects in Clojure at a surface level but I still find Python easier to read, but that's my experience YMMV.

There's a point in my programming projects when my own understandability is weakened and I this week I've been trying to think of a mindset that simplifies the problem. I am experimenting with multithreaded code in Java that implements left-right concurrency control. The idea is readers don't block writers and writers don't block readers and writers don't block writers. Give each thread a shard and rely on commutative property of your tree data structure and have a coordinator thread handle merging. The benefit: each thread can operate at single core speeds without any synchronization for reading OR writing. Buffer flipping is handled by the coordinator thread.

Each thread has its own copy of state which is merged by the coordinating thread. So it's an eventually consistent system. The result: each thread can modify its own copy of the data as much as it wants and it can see its own snapshot of global state at the last snapshot point. Cross thread writes always happen on the inactive buffer.

How do you think about data transformation pipelines? If only there was an IDE for kafka or clojure transformation pipelines.

Re: Mindset shifts for functional programming (with Clojure)

#23
post #15

> Recursion over Looping Part of what makes Clojure a great programming language is that you don't have to believe this if you don't want to. Nobody has yet convinced me that recursion has any sustained advantage over looping. Using a loop is generally bad practice if a more specialised operation is available (don't loop if something is a simple map or reduce for example). But if the situation justifies a recursion t…

Maybe it's my background but recursion feels more natural, either you are at the base, or at a point with N-1 items below. This gives you two different invariants that you can use to simplify the code. Small example, though not exactly comparable to looping. I needed to create a human readable qualified path appended by a hash (to avoid conflicts). This qualified path was needed ahead of the construction of an object…

I don't understand your problem or your solution, but that seems like a lot of things going on to construct a string.

But it sounds like you could just bash the logicalIds together and append the hash of the bash of the mash. Might not need loops or recursion.

Re: Mindset shifts for functional programming (with Clojure)

#24
post #8
post #6

Earlier quoted context omitted.

> If the recursion would be too complex, usually iteration is going to be easier to represent the solution in manageable chunks without requiring the reader to take everything in in one go. Perhaps? But the reason I reach for recursion is so that I don't have to first produce the "wrong answer", and then modify it until it's the "right answer". The sum of 1..10 is always 55. It isn't first 0, then 1, then 3, then 6,…

I don't understand where you come from with your argument. Recursion is also producing results that are "wrong answers" although I prefer to call them partial results. Just like a loop that is producing partial results as long as it has not finished yet.

> Recursion is also producing results that are "wrong answers"

Not true. If you share your copy of:

    answer = sum [1..10]
One viewer might see:

    answer = 3 + sum [3..10]
and another viewer might see:

    answer = 6 + sum [4..10].
They may be "partial results", but they are correct and equal to each other. This is different from one viewer seeing 3 and another viewer seeing 6.

"But can't you just hide the partial result until it's ready?"

Sure. Get rid of class fields and getters(). I'm happy to. Are you?

Re: Mindset shifts for functional programming (with Clojure)

#25
post #8

Earlier quoted context omitted.

I don't understand where you come from with your argument. Recursion is also producing results that are "wrong answers" although I prefer to call them partial results. Just like a loop that is producing partial results as long as it has not finished yet.

Out of curiosity is there actually any chipset with the algorithmic ability to add more than 2 numbers altogether in one operation (without having to store intermediate results)? I'd also think looping is far closer than recursion to how we tend to manually calculate things (either entirely in our heads or using a pen & paper or even a basic calculator). (Edit: looks like a number of other posters have made the same…

> Out of curiosity is there actually any chipset with the algorithmic ability to add more than 2 numbers

Perhaps? But this would be like asking if there was a chipset that can work without branching because of someone mentioning "GOTO bad".

> I'd also think looping is far closer than recursion to how we tend to manually calculate things

It's not the looping I mind, it's the mutation.

Re: Mindset shifts for functional programming (with Clojure)

#26
post #23

Earlier quoted context omitted.

Maybe it's my background but recursion feels more natural, either you are at the base, or at a point with N-1 items below. This gives you two different invariants that you can use to simplify the code. Small example, though not exactly comparable to looping. I needed to create a human readable qualified path appended by a hash (to avoid conflicts). This qualified path was needed ahead of the construction of an object…

I don't understand your problem or your solution, but that seems like a lot of things going on to construct a string. But it sounds like you could just bash the logicalIds together and append the hash of the bash of the mash. Might not need loops or recursion.

To just bash them together I'd have to either use the private api which is not a good thing. Alternatively I can push a list of items N steps to each object and have each one of them both adding and removing the logical names.

Re: Mindset shifts for functional programming (with Clojure)

#27
post #15

> Recursion over Looping Part of what makes Clojure a great programming language is that you don't have to believe this if you don't want to. Nobody has yet convinced me that recursion has any sustained advantage over looping. Using a loop is generally bad practice if a more specialised operation is available (don't loop if something is a simple map or reduce for example). But if the situation justifies a recursion t…

I think the difference between recursion and looping is that the former requires you to be very explicit about the state you intend to modify and persist between iterations, while it's generally somewhat of a free-for-all in imperative loops.

The most common looping construct I see in clojure is the for statement

Which isn't quite the free for all it is in traditional languages

You have to be very conscious and coding against the grain to use it to bang on values in place

Re: Mindset shifts for functional programming (with Clojure)

#28
post #15

> Recursion over Looping Part of what makes Clojure a great programming language is that you don't have to believe this if you don't want to. Nobody has yet convinced me that recursion has any sustained advantage over looping. Using a loop is generally bad practice if a more specialised operation is available (don't loop if something is a simple map or reduce for example). But if the situation justifies a recursion t…

> Nobody has yet convinced me that recursion has any sustained advantage over looping.

Looping may require trampolining or defunctionalisation, whilst recursion can be written much more directly and simply. As a very simple example (in pseudocode):

  even(n: uint): boolean = n match {
    case 0: true
    case n: odd(n-1)
  }

  odd(n: uint): boolean = n match {
    case 0: false
    case n: even(n-1)
  }
Whilst these are pretty silly implementations of odd & even, I don't know of a direct analogue using loops. For more realistic examples, just look at any "main loop"; AKA "trampoline boilerplate to work-around our language's lack of tail-call elimination" ;)

Re: Mindset shifts for functional programming (with Clojure)

#29
post #15

> Recursion over Looping Part of what makes Clojure a great programming language is that you don't have to believe this if you don't want to. Nobody has yet convinced me that recursion has any sustained advantage over looping. Using a loop is generally bad practice if a more specialised operation is available (don't loop if something is a simple map or reduce for example). But if the situation justifies a recursion t…

> Nobody has yet convinced me that recursion has any sustained advantage over looping. Looping may require trampolining or defunctionalisation, whilst recursion can be written much more directly and simply. As a very simple example (in pseudocode): even(n: uint): boolean = n match { case 0: true case n: odd(n-1) } odd(n: uint): boolean = n match { case 0: false case n: even(n-1) } Whilst these are pretty silly implem…

    for(range(n)):
        is_true = !is_true
And adjust for all the off by 1 errors. You're managing the same amount of state both ways, but with the loop all the state mutation lives on one line instead of spread throughout a stack.

Re: Mindset shifts for functional programming (with Clojure)

#30

Earlier quoted context omitted.

Chips have ability to run vector operations that can add a bunch of numbers. The issue is that recursion in software development is relatively rarely about arithmetic operation. For example, you might want to traverse a tree of objects (like a filesystem folder) to run some operation on them, etc. In this case the intermediate information is pointers to where you are currently processing various folders in your tree…

Vector operations that perform the same fixed addition to each element, yes, but that's not really the same thing. And yes I'm very much in agreement that the real power of recursive algorithms is when working with tree-like data structures.

Your question was, and I quote:

> is there actually any chipset with the algorithmic ability to add more than 2 numbers altogether in one operation (without having to store intermediate results)

I was just answering your question. I am not responsible for quality of your questions.

What you do is you posted a question but had something else in mind. You got an answer but that answer does not match the question you had in your mind so now you think it is ok to berate somebody for not being able to read your mind.

Post reply on HN