The purpose of any computer program is to produce side effects. A program which has no side effects has no observable behavior and is therefore useless. In that sense, side effects are good, so embrace them.
That implies that the purpose of a functional program is also to produce side effects.
The only problem with side effects is managing them properly. Side effects can become tangled and conceptually incoherent. Functional programs can help manage side effects.
For example, if I call (draw_line P1 P2), I expect a line to appear on the screen joining points P1 and P2. That is a side effect.
As a simpler example, if I call (say "Hello"), I expect the line "Hello" to be output to my terminal. That too is a side effect.
Those are good side effects.
The way I like to encapsulate side effects in a functional language (such as Fexl, a language which I wrote), is to use closures. Take your mutable data, and bury it inside a closure.
If you object to closures (pun intended), then think again. If you're a C programmer and you write printf("Hello\n"), you are in effect using a closure. How? Because stdout is effectively buried inside printf -- i.e. you don't have to pass it as a parameter.
If I saw (draw_line P1 P2), I am using a closure. How? Because most likely some X window gadget is buried somewhere down inside draw_line.
Fexl does provide a "var" construct which is a mutable variable. Pure functionalists might object to that. But why? The X window gadget is a variable. Your screen memory is a variable. All the memory in your computer is a variable. The buffer for stdout is a variable. The whole world is a variable. Stop fighting it.
I would prefer to avoid using "var" in Fexl, and aim toward pure functions, but sometimes that's ridiculous. For example, what if I wanted to simulate the behavior of draw_line, so instead of it going into an X windows gadget, the effects get stored in memory so I can use them differently, maybe for testing.
In that case I might use a var which simply collects all the draw_line and other graphic commands into a big list.
So let's stop fighting side effects and learn to embrace them, and recognize the value of functional languages in managing those side effects rationally.
That implies that the purpose of a functional program is also to produce side effects.
The only problem with side effects is managing them properly. Side effects can become tangled and conceptually incoherent. Functional programs can help manage side effects.
For example, if I call (draw_line P1 P2), I expect a line to appear on the screen joining points P1 and P2. That is a side effect.
As a simpler example, if I call (say "Hello"), I expect the line "Hello" to be output to my terminal. That too is a side effect.
Those are good side effects.
The way I like to encapsulate side effects in a functional language (such as Fexl, a language which I wrote), is to use closures. Take your mutable data, and bury it inside a closure.
If you object to closures (pun intended), then think again. If you're a C programmer and you write printf("Hello\n"), you are in effect using a closure. How? Because stdout is effectively buried inside printf -- i.e. you don't have to pass it as a parameter.
If I saw (draw_line P1 P2), I am using a closure. How? Because most likely some X window gadget is buried somewhere down inside draw_line.
Fexl does provide a "var" construct which is a mutable variable. Pure functionalists might object to that. But why? The X window gadget is a variable. Your screen memory is a variable. All the memory in your computer is a variable. The buffer for stdout is a variable. The whole world is a variable. Stop fighting it.
I would prefer to avoid using "var" in Fexl, and aim toward pure functions, but sometimes that's ridiculous. For example, what if I wanted to simulate the behavior of draw_line, so instead of it going into an X windows gadget, the effects get stored in memory so I can use them differently, maybe for testing.
In that case I might use a var which simply collects all the draw_line and other graphic commands into a big list.
So let's stop fighting side effects and learn to embrace them, and recognize the value of functional languages in managing those side effects rationally.