4 ms·
You should really take a look at Haskell. What you describe in your 3rd paragraph is precisely the ST monad. It's true we're still pretty limited in how effect
by jberryman 14y ago
You should really take a look at Haskell. What you describe in your 3rd paragraph is precisely the ST monad.
It's true we're still pretty limited in how effects are typed (most effectful stuff still ends up in the "IO sin-bin"), but this is an area of active research and experimentation. This is the way haskell's going, and no one else is even close (afaict).
- deleted 14y ago[deleted]
- Chris_Newton 14y agoWhat you describe in your 3rd paragraph is precisely the ST monad. Not exactly. The ST monad supports local mutable state, essentially turning a computation that uses state internally into something that looks pure from the outside. I’m looking for something more general where, for example, a function could modify state outside its own scope, but only if it advertised explicitly which stateful resources it would read and/or write, so the language could enforce constraints or issue warnings if various kinds of undesirable and/or non-deterministic behaviour would result. And really, I want to generalise the concepts of resources and effects on them much more widely. A stateful resource might be a mutable variable, but it could just as well be a file, a database, a single record within a whole database, or anything else I care to model in that way. An effect might be reading or writing part of the state, but it might also be opening or closing a file, or beginning, committing or rolling back a DB transaction. I want a language that can understand the concept that a file must not be read or written before it is opened, or that a database transaction must always be committed or rolled back once it has begun, and warn me if any code paths could permit an invalid order of effects. I don’t just want to throw half my code into the IO monad and hope for the best. I want a language where I can pass a reference to a large data structure into a parallel map function and get a compile-time error because, somewhere in the function I was applying using the map, there was an attempt to perform a mutating operation on that shared data without sufficient safeguards. But I want to write almost identical code and have the effects automatically co-ordinated because the language understands that concurrent access is possible so synchronisation is necessary, but the spec for the parallel map says that non-determinism is permitted. And crucially, I want a language where even simple code that should look like this: def fib(n): if n < 2: return n x, y = 0, 1 for i in range(n - 1): x, y = y, x + y return y does not wind up looking like this (from [1]): fibST :: Integer -> Integer fibST n = if n < 2 then n else runST $ do x <- newSTRef 0 y <- newSTRef 1 fibST' n x y where fibST' 0 x _ = readSTRef x fibST' n x y = do x' <- readSTRef x y' <- readSTRef y writeSTRef x y' writeSTRef y $! x'+y' fibST' (n-1) x y [1] http://www.haskell.org/haskellwiki/Monad/ST http://www.haskell.org/haskellwiki/Monad/ST
- eru 14y agoFor something as simple as fibonacci, you wouldn't use the state monad machinery, but go directly: fib' :: Integer -> Integer fib' n = iterate (\(x,y) -> (y,x+y)) (0,1) !! n The state monad helps you keep more complicated code composable. But it does have some syntactic overhead, that makes it lose out in simple examples. (Though with a bit of golfing, you could get syntactically closer to the Python example. For example putting the tuple (x,y) into an STRef instead of having two of them, employing Applicative Functor style in some places, and using a loop-combinator from the monad-loops package.)
- tikhonj 14y agoYour last complaint is not fundamental to the language: it's just a matter of library design. I guess Haskellers don't like state very much in any guise, so having awkward syntax for it is only natural. Both programs are fundamentally ugly, so having it be superficially ugly as well is no big loss. However, if you really wanted to, you could have almost C-like syntax[1]. The demo in that particular blog post has its own issues, but there is no fundamental reason why you couldn't apply some of those ideas to the normal ST API. I suspect that people simply don't care enough. [1]: http://augustss.blogspot.co.il/2007/08/programming-in-c-ummm-haskell-heres.html http://augustss.blogspot.co.il/2007/08/programming-in-c-ummm...
- Chris_Newton 14y agoBoth programs are fundamentally ugly, so having it be superficially ugly as well is no big loss. Perhaps we’ll just have to amicably disagree on that point. I think making code superficially ugly is a huge barrier to adoption that has held back otherwise good ideas throughout the history of programming. Many an innovative programming style or technique has languished in obscurity until some new language came along and made the idea special and provided dedicated tools to support it. Then it becomes accessible enough for new programmers to experiment with the idea, and the code becomes readable enough to use the idea in production, and over time it starts to change how we think about programming. We push the envelope, probably developing some ingenious and useful but horrible abuses of the idea along the way, until we figure out how to make those new ideas available in a cleaner and more widely accessible way and the cycle begins again. I suspect that people simply don't care enough. Most people are programming in languages that don’t have the problem in the first place, so they don’t need to care.