Earlier quoted context omitted.
The nice thing about ADTs is that you can couple the state variables with the enum, so that the representable state is better tied to the enum value. (Yes, you can kind of do this in C with a discriminated union of a struct holding an enum and a union, but the type system doesn't stop you form grabbing a union member that doesn't match up with the current enum value.)
I use Swift. Swift enums are really nice[0]. [0] https://littlegreenviper.com/miscellany/swiftwater/enums-wit...
John Carmack on Functional Programming in C++ (2018)
111–120 of 179 posts
Re: John Carmack on Functional Programming in C++ (2018)
#112Earlier quoted context omitted.
>He said he spent some time there, IIRC, and found it somewhat intriguing, perhaps interesting, but needed to get shit done eventually and so […] I think this resonates with many. My take is: don’t be dogmatic. Regardless of the language, one should write as beautiful, composable and pure as possible - but no more than that. Where only performance matters, oop wins. When clarity is the only priority, Haskell wins. Bu…
No modern language seems to have oop tho (golang, rust)
Re: John Carmack on Functional Programming in C++ (2018)
#113Earlier quoted context omitted.
A classic way to do this, is enumerations.
ADTs is a concept I've had a tough time understanding; the approximate definition that made the most impact with is considering them as a specific type of enumerations: Ones where each variant holds a value. Is this correct?
In algebraic data types we have a sum (union) of a labeled cartesian products, and each product may have arbitrary number of values:
data MaybeInt = NoInt | AnInt Int
data MaybeItsPair = NoIntsPair | AnIntPair Int Int
The first constructor in both data types is a labeled (No...) product with empty number of value to apply cartesian product to.
The second constructor in both data types is a cartesian product: in first case an Int and in case a pair of Ints.
Of course you can have more involved data type:
data Expr = Void | Const Int | Var String | Bin BinOp Expr Expr | Un UnOp Expr
A label, two single value constructors and much more involved operations as well.
Re: John Carmack on Functional Programming in C++ (2018)
#114Earlier quoted context omitted.
It took me awhile to realize but this is one of the big things that algebraic data types (ADTs) help you to do...design your data types so they have exactly the number of valid states that your domain has. To use another common FP way of saying it...make invalid states unrepresentable.
And state machines
Re: John Carmack on Functional Programming in C++ (2018)
#115Earlier quoted context omitted.
> The pure functional way to append something to a list is to return a completely new copy of the list with the new element at the end, leaving the original list unchanged. Actual functional languages are implemented in ways that make this not as disastrous as it sounds, I'm curious : how do they manage to not make it (performance) disastrous ? Anyone could please forward me some functional-newbie-level examples ?
The short answer is that with a singly-linked list, you can easily add items to one end (conceptually, typically the front end.) Then if other code has references to the older parts of the list, they’re still valid. A great explanation of this is in “Practical Common Lisp”: https://gigamonkeys.com/book/they-called-it-lisp-for-a-reaso...
Case in point: for small cardinality data in practice it’s often (or at least occasionally) faster to use a linear time search algorithm on a fixed length array than to put it, say, in a tree, map, etc. that is big-O “better”.
Re: John Carmack on Functional Programming in C++ (2018)
#116Earlier quoted context omitted.
3d engine is very structured, it isn't the creative part of game development. Lets say you want to test your bullets having HP and can be shot down. So you add that in an hour, now bullets have HP, you test it, it doesn't work, so you remove it. Things like that needs to be seamless, because you need to iterate on ideas and test if things are fun. Big upfront design as you suggest where you very carefully constrain e…
> 3d engine is very structured, it isn't the creative part of game development. I also did lots of the creative bit ;). I just assumed this was going to go down a performance route question, sorry! > Big upfront design as you suggest No, I am not suggesting that at all - I'm saying the opposite of that. You're the third person to think that's what I am saying now, so I assume I didn't explain myself very well. Rather…
So, you say it works for you, but basically every example of the things I talked about are done in a very different way than you describe, so unless you have programmed some very impressive games I would say that the data strongly supports another style of programming than you suggest here. For compilers or parsers or stuff like medical systems? Sure, go ahead, it seems to work for those domains, but it doesn't seem to be a panacea. If games were so much easier to write that way we would see tons of them, especially among the better games, but we don't.
Re: John Carmack on Functional Programming in C++ (2018)
#117Earlier quoted context omitted.
A member function must have at least one parameter. Here it's "parameter0": parameter0.membfun() It doesn't really matter whether the parameter name is separated from the function name by a dot, or a bracket. In a different syntax, it might have been written as "membfun(parameter0)" without any practical difference. This means that Foo::length() can be pure no problem, because Foo is its parameter, and, as such, in i…
I see your point, but you are still passing the entire state of the entire object to your function if you want to follow that line of thought. This is also discussed in the article, and it’s not really what functional programming is about. What other state is in there that the function has access to? Maybe on a case-by-case basis you can say that particular object only has one piece of data, but in the general case t…
Re: John Carmack on Functional Programming in C++ (2018)
#118Earlier quoted context omitted.
The argument isn’t that state is bad or doesn’t need to be managed. It’s more that spreading that state over a large number of areas leads to a lot of complexity and cognitive overhead in terms of expected behaviour at any given point of execution. Functional programming gives you ways to be much more explicit about the transformation being performed and the before/after states (except arguably when you start getting…
Isn't encapsulating state - and functions that act on states - within the smallest-possible class ancestor a pretty reasonable way of handling that? I'm not suggesting spaghetti or`GOTO 10400` or `GlobalCatBehaviorFactory.StartMeowing(cat)` or something. I mean we have a paradigm, and it's basically OOP with a dash of functional programming at the functional level. Maybe what I'm trying to say is that a lot of functi…
Well, but who really follows that idea? What usually happens is, that the state is stored in the object (of a class) and the result of subsequent method calls depends on previous calls and arguments, since it changed the state of the object. Maybe there are even calls to other objects in the system changing their state, and in turn changing return values of their methods.
Also: If we have actual functions (in a mathematical sense), then they depend only on their inputs / arguments. Why then have them in a class, and not in say for example, a module?
Re: John Carmack on Functional Programming in C++ (2018)
#119Earlier quoted context omitted.
I was impressed by his concise daily planfiles. https://github.com/ESWAT/john-carmack-plan-archive/tree/mast...
thanks for sharing, do you know what those three sections (*, + and empty) mean?
(Tasks may appear in multiple days, and there's no guarantee of tasks being retrospectively marked as complete.)
Re: John Carmack on Functional Programming in C++ (2018)
#120Why aren't more universities teaching functional programming first to form good mental models for the students and then show them when to use state and when to not. Why is everyone teaching Python?