Your skill will accomplish
what the force of many cannot
Re^2: Is it worth using Monads in Perl ? and what the Monads are ?by BrowserUk (Patriarch)
|on Jun 12, 2007 at 12:36 UTC
++for the link. I've seen similar descriptions of monads as wrappers elsewhere but the nice thing about that article is that it gives an example of a purpose for wanting to wrap things. And it gives a nice analogy with a familiar concept--tainting--that bring that purpose home in a nice familiar way.
In turn, that has crystallised, for me, various feelings and intuitions about the process that I couldn't quite get a handle on before. And that leads to another analogy that allows me to express those intuitions, and relate them to Perl in a nice way.
It all stems from one sentence in the linked article:
But we've already said that we don't want to allow people to unwrap these things.
Perl already has a taint-mode. When enabled, it will taint 'at risk data' and ensure that whilst you can pass it around, you cannot use it in any way that would constitute a risk. And if you copy that tainted data, or amalgamate it with some other non-tainted data, the results are also tainted to ensure you cannot use those for at risk operations. And it does all this without requiring monads. It could probably be successfully argued that implementing tainting for Perl would have been much easier had it's source code (C) had a monad-like concept. But that's history, and perl exists and has tainting.
But there is one (huge) difference between the way it is implemented in perl, and the way it could be implemented using monads. Perl allows you/me/the programmer, to unwrap tainted data. It doesn't impose the language designers will upon me that tainted data must always and forever remain tainted--which in Haskell's terms is anything and everything that isn't hard-coded in the source file. And that is huge in it's implications for the ease of programming every further manipulation the program will perform upon that data.
In certain high security buildings--airports, courts, government buildings, even private firms--visitors, including potential employees, customers and the like, are 'tagged' (a visitor badge), and 'wrapped' (a security guard, secretary or other escort) when they come on site. And they (should) remain so tagged and wrapped throughout the duration of their visit.
But, when a visitor makes the transition to becoming an employee, they loose the tagging and wrapping. Okay, they may trade one tag for another, but they cease to be escorted. And the process that facilitates that unwrapping is a (more or less thorough depending) vetting procedure. It is simply impractical to have every employee be escorted (by whom?) throughout their working day. So after vetting--to what ever level is commensurate with their position--they are trusted.
And that's what Perl does also. It allows me--as the user of the language, the writer of the application and the best arbiter of what constitutes 'safe data' for my application and what risk I will accept; to 'vet' the data and declare it to no longer be tainted. From that point on, I can treat that data in exactly the same way as I do any values that I embedded in my application, using all of the standard language constructs the language provides.
I don't need to have a duplicate set of control structures--fmap as well as map, forM as well as for, and so on. And I certainly don't need to have to have a mechanism for re-using those extraordinary (and duplicated) control structure for every type of data.
In effect, Haskell's need for all external data to remain wrapped for the rest of its working existence, is like requiring all your employees to continue to be escorted throughout their working days.
Haskell's need for these extraordinary control structures arises solely from the language designers decision that Haskell users (programmers) cannot be trusted to decide for themselves, when their data is safe to be manipulated using the standard language facilities.
They could have taken a different route(*). Then could have taken the decision to provided primitives that would validate in-bound data (bytes--all external data coming into a program is at the base level bytes strings), to be of some intrinsic type, or some compound type(*). From that point on, that validated data would be manipulable using the standard language facilities. The manipulations may still have had to be performed within sections of the code marked as being effectful and/or sequenced (the IO monad), but the need for many of the other facilities 'provided' by other monads would disappear.
*This is exactly what several other functional languages (eg.ML) have done...but then the language is no longer 'pure'.
There is probably some deeply meaningful reason embedded within the Hindley-Miller type system why it is impossible to trust a programmer to decide when external data is safe(ly typed), but that only makes me question the need for HM typing--not the efficacy of trusting the programmer to make his own decisions regarding the (type) safety of his data.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.