Earlier quoted context omitted.
Haskell enforces purity, but you can still write pretty imperative looking code by using monads (e.g. some state monad). I don't think there is any philosophical difference between say int x = foo(); bar(); char y = baz(x); and do x I'd say the true difference is more related to how you describe state change. Imperative is about having a sequential list of instructions that all can mutate global state in some way, wh…
I'd say there is quite an important conceptual difference in that the state monad example exactly desugars to pure functional code. Monads give us a good syntax for sequential computation, but this sequentiality is built out of purely functional components.
Admitting That Functional Programming Can Be Awkward (2007)
121–130 of 148 posts
Re: Admitting That Functional Programming Can Be Awkward (2007)
#122Earlier quoted context omitted.
I'm all for the 'right tool for the job' mindset, but why would it be bad in principle to write an application in JS? Leaving aside the fact that modern JS is ~3x slower than C++, i.e. slightly slower than C# and Go but in the same league as Java/Haskell, not in the same league as Ruby and Python, programs like VSCode are written in JS and they have no performance issues. It's true that performance is often ignored f…
> VSCode are written in JS and they have no performance issues VSCode is not performant, especially on startup and especially when compared to editors like vim or sublime text. I agree that the reason likely isn't language choice though it's the use of electron. I don't agree with you about software not needing to be performant either, I believe developers should strive to make their software run as efficiently as th…
But that's a difference between developers and engineers
Re: Admitting That Functional Programming Can Be Awkward (2007)
#123Earlier quoted context omitted.
Haskell enforces purity, but you can still write pretty imperative looking code by using monads (e.g. some state monad). I don't think there is any philosophical difference between say int x = foo(); bar(); char y = baz(x); and do x I'd say the true difference is more related to how you describe state change. Imperative is about having a sequential list of instructions that all can mutate global state in some way, wh…
How would you handle state other than passing it around? The fundamental thing that Haskell and Elm do is that they don't have mutable values. They create a new value from the old one. You never mutate a record the way you mutate a JS object or a Python dict.
By only passing and updating the relevant bits of state.
>The fundamental thing that Haskell and Elm do is that they don't have mutable values. They create a new value from the old one.
If we're talking about the context of a game, you'll be very likely using monads where this isn't the case (IO, ST). Not to mention, even if you do just use a normal state monad, if you don't keep the old value around, there's no functional difference between mutating the entire program state and creating a new program state while forgetting the old.
Re: Admitting That Functional Programming Can Be Awkward (2007)
#124I would much rather write the logic the author describes in Haskell than C. The C code will have to be carefully managed during development and maintenance to make sure the side effects are happening in the expected order and that no changes ever introduce unexpected interleaving of mutation. The Haskell version will prevent that trivially. You can't even express doing it the wrong way, because you can't mutate anyth…
Re: Admitting That Functional Programming Can Be Awkward (2007)
#125Honestly I think this conclusion comes more from lack of familiarity with how people solve similar problems with FP than anything. For example, in the author’s followup post: All you have to do is pass the world state to each function and return a new state. True, yes, but...yuck. It can be clunky in a language with single-assignment. And what is this really gaining you over C? I mean, if you stop there, sure that’s…
I dont understand this. This has the same disadvantages as global variables: every function (that has the state) can change it.
It’s in Javascript, so not all of it is functionally pure, but the core game logic follows that pattern. The code is heavily commented, and hopefully somewhat readable. I think the main benefit I found was that it was trivial to snapshot states and replay as needed. That made debugging easier, and might have simplified something like a save/reload feature. Although I didn’t go there for this toy project, I’d argue that testability might be another consideration.
More generally, I’ve seen over the years that global state tends to be painful in unforseen ways. At one point, I was considering a fork of putty to add support for tabs. It has a lot of global state, so I had to abandon that idea. If the same state had been wrapped up in a state struct and passed around, it’d have been easy.
Re: Admitting That Functional Programming Can Be Awkward (2007)
#126>Sure, there have been games written in Lisp and some games written by language dilettantes fond of Objective Caml, but they never turn out to be programmed in a functional style. You can write imperative code in those languages easily enough. I would like to know more about this. I've written several games in Elm, a js counterpart to Haskell, and I guess foolishly assumed that meant I was writing them in the functio…
Re: Admitting That Functional Programming Can Be Awkward (2007)
#127Earlier quoted context omitted.
Lisp runtime implicitly runs each top-level expression as statement. When you run (def x y) it's not only true that this expression returns 'x, it's also true that it alters the static state of the program by adding 'x to the scope. To make a purely statementless language, I think you need to make everything happen in a single monadic computation. E.g. in pseudo-Haskell-ish: main : Scope -> StaticIO Scope main scope0…
At least in all of the discussions I have seen, the difference between statements and expressions is whether they return a value, not whether they have side-effects. So (def x b) is an expression, because it returns a value. {} in C is a statement, even though it has no side effects. Now, there are some statements in CL as far as I remember - I believe (declaim x integer) is a kind of statement, at least in the sense…
CL-USER(1): (defparameter *foo* (declaim (special x)))
*FOO*
CL-USER(2): *foo*
(X)
CL-USER(3): (defparameter *bar* (declaim (type integer x)))
*BAR*
CL-USER(4): *bar*
(X)
In other cases, e.g. `(values)` which is an expression that returns no values, the value is nilRe: Admitting That Functional Programming Can Be Awkward (2007)
#128https://youtu.be/1PhArSujR_A?t=125
https://www.gamasutra.com/view/news/169296/Indepth_Functiona...
Re: Admitting That Functional Programming Can Be Awkward (2007)
#129I think anyone who has coded long enough would recognize that OOP, functional, imperative, etc all have their strengths and weaknesses, and all have problem domains they are better suited for. Unfortunately, this sometimes gets lost in the language fan wars - it’s easy to lose nuance when discussing something you are passionate about, I have made this mistake myself.
Yeah but the question is which one of these types are more "program-y" Functional programming while a valid form, is inherently better expressed by constraining the possible use cases. It's closer to electrical engineering or mechanics then "programming." "Programming" inherently rewards extendability, interoperability and readability, therefore it rewards OOP. Now obviously computers have Both mechanical and extenda…