3 ms·
>For-loops do exist, they just need to not have side effects, No they don't. For loops and loops in general are procedural actions. You are jumping from direct
by ninetyninenine 2y ago
>For-loops do exist, they just need to not have side effects,
No they don't. For loops and loops in general are procedural actions. You are jumping from directive to directive, command to command. Loops are NOT functional at all. loops are an artifact of the computational machine, jumping to different instructions.
Functional programs like functions in mathematics DO not contain for loops.
> which in practice means the likes of map/filter/reduce (ideally promoted to a first class language feature like sequence comprehensions).
>You could argue that those are still desugared to recursion, but I think at that point it's kinda moot - the construct is still readily recognizable as a loop,
All programs are desugared into assembly instructions. Assembly instructions are procedural by nature... they are not functional so your point is moot as everything is desugared into loop based jumps.
map/filter/reduce Are not loops. They are fundamentally different. It doesn't matter if it's "recognizeable" as a loop, it is NOT a loop. There is an isomorphism between imperative and functional programming, So the definition of Loop vs. no loops refers to the superficial differences between the two EVEN when the underlying things are the same.
>In general, so long as mutation can be encapsulated in modules that only expose pure functional interfaces, I think it should still count as FP for practical purposes.
It actually can't... for loops rely on mutation to work.
a for loop looks like this:
<OUTER SCOPE>
for i in range(10):
<INNER SCOPE>
By nature the for loop needs to influence outer scope otherwise your for loop is utterly useless. So how would you influence outer scope from inner scope?
<VARIABLE FROM OUTER SCOPE>
for i in range(10):
<MUTATE VARIABLE FROM OUTER SCOPE WITHIN INNER SCOPE>
That's the only way man.
This is the fundamental nature of for loops. They are imperative constructs. Sure it can look very similar to map or reduce or even filter, but THEY are not the same.
- tmtvl 2y agoI dunno, I imagine that there's no appreciable difference between: (loop :for i :below 10 :collect i) and: (let loop ((i 0)) (if (= i 10) nil (cons i (loop (1+ i)))))
- ninetyninenine 2y agoFirst off I can’t read that. Please use more common pseudo code for your example if you want me to understand. Second it looks like there’s a function called for here that does something similar to reduce? That’s a functional thing. The topic at hand is for loops as in loops that are procedural statements which is what most people recognize as loops. For, while, do while and those things you see in popular languages. Not some obscure construct in lisp. If your talking about the isomorphism between functional and imperative programming, I already covered that.
- gpderetta 2y agoPython: def range_mul(n, mul): for i in range(n): yield i*mul x = list(range_mul(10, 20)) range_mul is a pure function, yet it is implemented with a for loop. Once you have first class continuations or the equivalent, the differences between imperative and pure blur (cf. Haskell do-notation, is it imperative?). In any case I think you are missing int_19h point, the it doesn't matter if a function is implemented using imperative constructs, if you can't tell from the outside it is still pure. And an FP compiler will convert pure code to imperative anyway.
- ninetyninenine 2y agorange_mul is not pure. Don’t believe me? Ask ChatGPT: “”” No, a Python function that contains the yield keyword is not a pure function. A pure function is defined as a function where the output is solely determined by its input values, with no observable side effects. This means it should: • Always return the same result when given the same input. • Have no side effects (like modifying global state, reading from or writing to files, etc.). Functions containing yield are generators, which maintain internal state between successive calls, making their behavior dependent on the sequence of calls (because they return values incrementally and remember the point where they left off). This internal state makes them impure because they don’t always return the same result when called with the same input—they return successive values upon subsequent calls. In summary, a function with yield is not pure due to its stateful behavior and non-deterministic output across multiple calls. “”” >In any case I think you are missing int_19h point, the it doesn't matter if a function is implemented using imperative constructs, if you can't tell from the outside it is still pure. And an FP compiler will convert pure code to imperative anyway. You’re making a side point here that’s irrelevant to the main point. Sure you can do this, these are techniques you can do to segregate your impure code away from your pure code. But is this the topic of conversation? No. Additionally your code actually is like a virus. Not only is the example wrong but The impurity can infect other functions that use it such that those functions lose determinism and purity as well. Which brings me to my main point. Circling back to my parent comment. Most people don’t understand fp and don’t get carmacks insight… and you are an example of such a person for now.
- 2y ago