3 ms·
John Carmack wrote a nice article about experiences writing functional code in C++ here: http://www.altdevblogaday.com/2012/04/26/functional-programming-in-c/
by quux 14y ago
John Carmack wrote a nice article about experiences writing functional code in C++ here:
http://www.altdevblogaday.com/2012/04/26/functional-programming-in-c/ http://www.altdevblogaday.com/2012/04/26/functional-programm...
- mark-r 14y agoThat very link was at the bottom of his original response.
- quux 14y agoAh, didn't notice it. Thanks. If I missed it, I can't be the only one.
- worldsayshi 14y ago"a function can still be pure even if it calls impure functions, as long as the side effects don’t escape the outer function" This is a very good point that probably could be systematically exploited. Does anyone know examples of this?
- greiskul 14y agoI think caching/memoization is one of the most typical cases of this.
- ufo 14y agoIn Haskell there is the ST monad can be used to write stateful implementations for pure functions. The type system guarantees that side effects can't escape their scope. http://www.haskell.org/haskellwiki/Monad/ST http://www.haskell.org/haskellwiki/Monad/ST
- worldsayshi 14y agoAlthough this is great information I primarily had 'less pure' languages' in mind when I asked. Come to think of it, restricting mutable access to only the relevant objects as per function call using const seems to allow just this! A function having only const input and output "should be" free of side effects (if no global mutables); while still being allowed to run all manner of unpure processes local to its own calling context.
- mattdw 14y agoClojure has "transient" (mutable) forms of its immutable datastructures, which can be bashed in place, but they're not allowed beyond function boundaries in either direction (I think). So you convert (copy?) to transient, mutate it in-place, then convert back to "persistent" before returning it.
- crntaylor 14y agoHere's a pretty trivial example in Haskell - computing the factorial function using a mutable variable. import Control.Monad.ST import Data.STRef fact :: Int -> Int fact n = runST (fact' n) fact' :: Int -> ST s Int fact' n = do a <- newSTRef 1 mapM_ (\x -> modifySTRef a (*x)) [1..n] readSTRef a Here the function `fact'` uses mutable variables (encoded in the use of `ST` in its type -- `ST` stands for State Thread) but the function `fact` is pure -- the call to `runST` ensures that none of the side effects leak out of `fact'`. As with most Haskell code, the types are optional - I included them for clarity.
- DanWaterworth 14y ago> As with most Haskell code, the types are optional - I included them for clarity. I'd just like to make it clear to anyone else reading this. The types aren't optional, but because Haskell has type inference, specifying them is optional.