8 ms·
I appreciate the comment, but what I have in mind looks very different to the way monads are used in Haskell today. For example, I don’t necessarily want pure
by Chris_Newton 14y ago
I appreciate the comment, but what I have in mind looks very different to the way monads are used in Haskell today.
For example, I don’t necessarily want pure functions by default in my idealised programming model. To me, a pure function is just a special case of a function whose effects are controlled and where the resources the function might interact with are readily identifiable, for which the sets of possible effects and interacting resources happen to be empty.
Put another way, I don’t see anything wrong, or even inferior or undesirable, with performing a quicksort of an array or some fast matrix computations destructively. However, I’d like my language to make sure I couldn’t accidentally try to use the old data again afterwards (including, for example, in other threads running in parallel). I’d like to be sure that just because my algorithm updates one set of data in-place, it doesn’t also draw a window, block to wait for user input, or kick off a background thread that will reformat my hard drive in half an hour. And in the calling code, I’d like to find out very quickly that just because I created and populated an array over here, and then ran a quicksort that changed it over there, and then printed it out down there, nothing else had any chance to modify it in between.
And I’d like to do all of that using syntax that is at least as clean and readable as today’s best languages, please, not the horrors that often seem to result when functional programming languages try to implement equivalent behaviour with realistic heavily structured/monadic values instead of the neat one-integer counter or append-only log that always seems to be used in the tutorial code samples.
I suspect that to do that will require a language that provides dedicated, specialised tools to support the new programming model. Sure, you could probably do this sort of thing using monads in Haskell, just as you could do OOP in C, text processing in C++, or write in a functional style in Python, but the results are clumsy compared to using the right tool for the job. I’m not sure that tool exists yet for the kind of programming models I’d like to use, but that’s where I’m hoping the lessons of today’s functional languages and academic research will bear fruit over time.
- jberryman 14y agoYou 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
- ridiculous_fish 14y agoWhat you describe reminds me of Rust's typestate, which they removed. But the "branded types" replacement, combined with the unique pointers, sound promising - see http://pcwalton.github.com/blog/2012/12/26/typestate-is-dead/ http://pcwalton.github.com/blog/2012/12/26/typestate-is-dead... I am new to Haskell, but I also have objections to Haskell's notions of purity. For example, accessing your pid or your argv do not have side effects, and certainly do not perform IO, yet these are grouped in the IO monad next to file deletion.
- tel 14y agoRuntime constant values as IO is a long-standing concern. The existence of withArgs cements the issue (definitely allows for non referentially transparent code to be written with getArgs) but there's more to be said about why withArgs exist and why getArgs is in the IO monad. http://www.haskell.org/pipermail/haskell/2005-October/016574.html http://www.haskell.org/pipermail/haskell/2005-October/016574... The argument usually seems to play out as "their denotation is uncertain" and therefore they get unceremoniously thrown into the IO monad. I tend to agree with that in that I feel a major point of purity is that it gives you a world sufficiently far from the reality of the RTS to play in. IO's general status as the "Unsafe Pandora's Box" is a wart in Haskell. I'd much prefer it be called the RTS monad and have something like IOSpec's Teletype type performing the classic IO. It's fixed by convention now though.
- Chris_Newton 14y agoIO's general status as the "Unsafe Pandora's Box" is a wart in Haskell. Isn’t that rather like saying mutable variables are a wart in C? :-)
- deleted 14y ago[deleted]
- tel 14y agoSure. Haskell's wart is automatically verified to be context constrained by the type system, though. There are also lots of tools to mitigate that wart that are also verified.
- tel 14y agoThat's very attainable in Haskell and is often well-modeled off the ST monad. You also have a number of "Data types a la carte"-like methods which allows you to build very specific effect contexts in order to precisely guarantee things like the fact that mutable array code never produces events in the UI. These can be achieved by products and compositions of applicative types, free monads, monad transformers, or the "sum of effects" "a la carte" method. Another big deal that comes out of these more specific effects is that you can have the compiler produce stream fusion to automatically optimize some inner loops, though I don't know how often that actually happens as of today. (Oh: if you want to play with "Data types a la carte" they're in the IOSpec package, http://hackage.haskell.org/package/IOSpec http://hackage.haskell.org/package/IOSpec and are described---somewhat densely---in http://www.staff.science.uu.nl/~swier004/Publications/DataTypesALaCarte.pdf http://www.staff.science.uu.nl/~swier004/Publications/DataTy...)