[cap-talk] Abstractions that subsume capabilities
Richard Uhtenwoldt
notprivate2 at gmail.com
Wed Mar 12 00:04:11 EDT 2008
From: "Richard Underwood/Uhtenwoldt" <ru at sonic.net>
Kevin "performs surgery" on the following simple Haskell
program to give it "the capability nature":
main = do
s <- readFile "/etc/passwd"
hPrint stdout s
But the above code does not need to be changed to be good,
attack-resistant code. To see why, we will make some very simple
modifications to it: namely, we will use different, more-primitive
input/output facilities to achieve the exact same behavior:
import IO
main = do
handle <- openFile "/etc/passwd" ReadMode
contents <- hGetContents handle
flip mapM_ (lines contents)
(\ line -> hPutStrLn stdout line)
Here is untested E code which does the same thing. Observe that
it is almost identical except for syntax and the names of the
input/output operations.
def handle := <file:/etc/passwd>
def contents := handle.getText()
for line in contents.split("\n") {
println(line)
}
To be painfully explicit in case you do not get it yet,
hGetContents is Haskell's version of E's getText; flip map is
Haskell's version of E's for loop; lines is Haskell's version of
E's split("\n"); hPutStrLn stdout is Haskell's version of E's
println.
Since I found the E code in the E Idioms Quick Reference Card, I
assume you all regard it as good, attack-resistant code. But
obviously if it does not need surgery to make it more
attack-resistant, the Haskell code does not either.
It appears that there is a tendency on this mailing list to try
to make monads --and referential transparency?-- do things
they cannot do.
P.S. In case there are any beginning Haskell learners reading
this, here are the type signatures of all the identifiers in the
above Haskell code:
data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
openFile :: FilePath -> IOMode -> IO Handle
hGetContents :: Handle -> IO String
-- flip f takes its (first) two arguments in the reverse order of f.
flip :: (a -> b -> c) -> b -> a -> c
-- here is a definition of flip:
flip f x y = f y x
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
-- here is a definition of mapM:
mapM_ f as = sequence_ (map f as)
sequence_ :: Monad m => [m a] -> m ()
sequence_ = foldr (>>) (return ())
-- lines breaks a string up into a list of strings at newline characters.
-- The resulting strings do not contain newlines.
lines :: String -> [String]
hPutStrLn :: Handle -> String -> IO ()
--
Text by me above is hereby placed in the public domain
More information about the cap-talk
mailing list