I think that's a bad example, because your TryParse function can be thought of as returning a value wrapped in a monad. A Maybe monad, to be specific. In Haskell:
case (tryParse s) of
Just n -> putStrLn "Parsed " ++ (show n)
Nothing -> putStrLn (s ++ " was not an integer")
Nothing is a very convenient little concept: It's a value which isn't a 'legitimate' value in any context. It's always a flag value. In C, for example, there's no way to have a flag value of type int in this context, because tryParse could conceivably return any value of type int as its legitimate result. It's also wonderfully conceptually clean: The function either just returns a legitimate value or it returns nothing legitimate at all, and you always know which it did. The point is, however, it only returns one value, and doesn't rely on any out-of-band communications through errno or similar.If you want to get fancy, you can use the Either monad. This can allow you to say why a parse failed, for example:
case (tryParse s) of
Left n -> putStrLn "Parsed " ++ (show n)
Right m -> putStrLn "Parse of " ++ s ++ " failed because " ++ m
In this case, tryParse would have the type: tryParse :: String -> Either Int String
The point here is, you still only return one value, but they can be either of two different kinds of value, as distinguished by being tagged either Left or Right, and can even be different types. Again, one value, no out-of-band signalling.And, of course, Haskell has tuples. You can do interesting things without them, however.