I had the same complaint with Rails: There&#x27;s too many libraries injecting things into various places, and it&#x27;s hard glancing at the documentation for any library to see what the rules of the game are.<p>To give one example, the documentation for just about every function seems to say that it returns &#x27;Object&#x27;. What kind of object? You have to dig through the source to find out.<p>I typed &#x27;image&#x27; into rubygems.org and here&#x27;s the first example:
<a href="http:&#x2F;&#x2F;www.rubydoc.info&#x2F;gems&#x2F;fastimage&#x2F;2.0.0&#x2F;FastImage" rel="nofollow">http:&#x2F;&#x2F;www.rubydoc.info&#x2F;gems&#x2F;fastimage&#x2F;2.0.0&#x2F;FastImage</a><p>It doesn&#x27;t seem hard to use, but notice that all the attributes are listed as returning &#x27;Object&#x27;. If I look at the &#x27;type&#x27; method, I wonder a few things:<p>* What is a uri exactly? Is it any old string? Is it an object returned by parsing a string using some standard Ruby library?<p>* What can be returned? They give some examples of symbols that can be returned. What is the full list?<p>Contrast that with the types listed in this image library I just looked up on Hackage:<p><a href="https:&#x2F;&#x2F;hackage.haskell.org&#x2F;package&#x2F;JuicyPixels-3.2.7&#x2F;docs&#x2F;Codec-Picture.html" rel="nofollow">https:&#x2F;&#x2F;hackage.haskell.org&#x2F;package&#x2F;JuicyPixels-3.2.7&#x2F;docs&#x2F;C...</a><p>I&#x27;ve never used this library before, and I can see roughly how I would use it just looking at the types:<p>readImageWithMetadata :: FilePath -&gt; IO (Either String (DynamicImage, Metadatas))<p>&quot;readImageWithMetadata takes a filename, and reads the file returning either an error message or an image together with its metadata&quot;<p>What exactly is an image? You can click through and see it&#x27;s one of 13 things:<p><a href="https:&#x2F;&#x2F;hackage.haskell.org&#x2F;package&#x2F;JuicyPixels-3.2.7&#x2F;docs&#x2F;Codec-Picture.html#t:DynamicImage" rel="nofollow">https:&#x2F;&#x2F;hackage.haskell.org&#x2F;package&#x2F;JuicyPixels-3.2.7&#x2F;docs&#x2F;C...</a><p>What exactly is an image&#x27;s metadata? You can click through and see it&#x27;s an abstract type that can be manipulated using operations like you&#x27;d find on a map(a dictionary). In particular, see the &#x27;lookup&#x27; function to see how to access things.<p>Here&#x27;s a more complex example:<p>encodeGifImages :: GifLooping -&gt; [(Palette, GifDelay, Image Pixel8)] -&gt; Either String ByteString<p>&quot;encodeGifImages takes a number of times to loop and a list of palettes, delays, and images of 8-bit pixels, and returns either an error message or a sequence of bytes representing the .gif&quot;<p>I feel like it would be less clear what needs to be done to call this function with the Ruby equivalent. I&#x27;d probably end up looking through the source.<p>Just as important with the signatures is what the functions are <i>not</i> doing: encodeGifImages isn&#x27;t rewriting any symbol tables, monkey-patching new methods into existence, changing global variables, writing to a database, opening a file, or printing a log message. I can say all of this because its type doesn&#x27;t allow it to. I could run encodeGifImages in an interpreter or test without needing any setup.<p>The Ruby library here wouldn&#x27;t give anyone trouble either. The examples are probably sufficient to use it. I think with Ruby as long as you can find examples close enough to your specific case you can usually make it work.<p>But if you&#x27;re debugging something that doesn&#x27;t have an example readily handy, the static type system makes it much easier to see what something is doing.<p>I used Haskell here, but C# or C++ would probably work just as fine for this purpose. Well, unless you&#x27;re the type who likes to cast everything to void* so he doesn&#x27;t have to worry about the types.