<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>ByteLabs: Tag Types</title>
    <link>http://blog.solaris.bytelabs.org/articles/tag/types</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>additions to a vast pool of entropy by Igor and Ines</description>
    <item>
      <title>Playing with Rank-N Types</title>
      <description>The following shows some dummy Haskell example code that demonstrates the usage of rank-n types:
&lt;pre&gt;&lt;code&gt;{-# LANGUAGE RankNTypes #-}
module Main (main) where
-- g1: identity function
-- GHC implicitely quantifies it to: forall a. a -&amp;gt; a
g1 :: a -&amp;gt; a
g1 x = x
-- g2: Rank2Type
g2 :: (forall a. a -&amp;gt; a) -&amp;gt; (Bool, Char)
g2 f = (f True, f 'a')
-- g3: Rank3Type
g3 :: ((forall a. a -&amp;gt; a) -&amp;gt; (Bool, Char)) -&amp;gt; (Char, Bool)
g3 f = (\x -&amp;gt; (snd x, fst x)) (f g1)
-- g4: Rank4Type
g4 :: (((forall a. a -&amp;gt; a) -&amp;gt; (Bool, Char)) -&amp;gt; (Char, Bool)) -&amp;gt;
         (Bool, Char)
g4 f = (\x -&amp;gt; (snd x, fst x)) (f g2)

main :: IO ()
main = do
  putStrLn "Rank-2 Example:" 
  putStrLn . show . fst . g2 $ g1
  putStrLn . show . snd . g2 $ g1
  putStrLn "Rank-3 Example:" 
  putStrLn . show . fst . g3 $ g2
  putStrLn . show . snd . g3 $ g2
  putStrLn "Rank-4 Example:" 
  putStrLn . show . fst . g4 $ g3
  putStrLn . show . snd . g4 $ g3
&lt;/code&gt;&lt;/pre&gt;

 If you want to see more &amp;#8216;useful&amp;#8217; examples have a look at the paper &lt;a href="http://research.microsoft.com/~simonpj/papers/higher-rank/putting.pdf"&gt;Practical Type Inference for Arbitrary-Rank Types&lt;/a&gt;.</description>
      <pubDate>Sun, 10 Aug 2008 12:51:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:488c2a29-77c7-4c9f-8e1e-e7a1843f8766</guid>
      <author>igor</author>
      <link>http://blog.solaris.bytelabs.org/articles/2008/08/10/playing-with-rank-n-types</link>
      <category>Hacking and Computers</category>
      <category>Haskell</category>
      <category>Types</category>
    </item>
    <item>
      <title>Predicative vs. Impredicative Polymorphism and Type Reconstruction</title>
      <description>&lt;p&gt;The polymorphism of &lt;a href="http://en.wikipedia.org/wiki/System_F"&gt;System F&lt;/a&gt; is often called &lt;strong&gt;impredicative&lt;/strong&gt;. A definition is called &lt;strong&gt;impredicative&lt;/strong&gt; if it involves a quantifier whose domain includes the very thing being defined. For example in &lt;a href="http://en.wikipedia.org/wiki/System_F"&gt;System F&lt;/a&gt;, the type variable X in the type T = &amp;forall;X. X &amp;rarr; X ranges over all types, including T itself (so that, for example, we can instantiate a term of type T at type T, yielding a function from T to T).[6]&lt;/p&gt;


	&lt;p&gt;The polymorphism found in ML is called &lt;strong&gt;predicative&lt;/strong&gt;, because the range of type variables is restricted to monotypes (i.e. quantifier-free types), which do not contain quantifiers.&lt;/p&gt;


	&lt;p&gt;When talking about type reconstruction the previous definitions are important. There is a growing &amp;#8220;[...] need for ever more expressive type system features, 
most of which threaten the decidability and practicality of Damas-Milner type inference.  One such feature is the ability to write functions with higher-rank types&#8212;that is, functions  that take polymorphic functions as their arguments.&amp;#8221;[1]&lt;/p&gt;


	&lt;p&gt;Complete type inference is known to be undecidable for higher-rank (impredicative) 
type systems. This post serves as a reference for type reconstruction in the presence of polymorphism in higher-rank type systems.&lt;/p&gt;


	&lt;p&gt;[1] &lt;a href="http://research.microsoft.com/~simonpj/papers/higher-rank/putting.pdf"&gt;Practical type inference for arbitrary-rank types&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;[2] &lt;a href="http://en.wikibooks.org/wiki/Haskell/Polymorphism"&gt;Haskell/Polymorphism&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;[3] &lt;a href="http://docforge.com/wiki/Type_polymorphism#Rank_Restrictions"&gt;Type Polymorphism &amp;#8211; DocForge&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;[4] &lt;a href="http://en.wikipedia.org/wiki/Polymorphism_(computer_science"&gt;Type Polymorphism -Wikipedia&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;[5] &lt;a href="http://en.wikipedia.org/wiki/System_F"&gt;System F &amp;#8211; Polymorphic/Second-Order Lambda Calculus&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;[6] &lt;a href="http://www.cis.upenn.edu/~bcpierce/tapl/index.html"&gt;Types and Programming Languages&lt;/a&gt; [p.360]&lt;/p&gt;</description>
      <pubDate>Sun, 10 Aug 2008 11:29:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:f5ccb877-e3c8-4aa9-9c13-50fb50320f5a</guid>
      <author>igor</author>
      <link>http://blog.solaris.bytelabs.org/articles/2008/08/10/predicative-vs-impredicative-polymorphism-and-type-reconstruction</link>
      <category>Hacking and Computers</category>
      <category>Types</category>
    </item>
    <item>
      <title>Hindley-Milner type inference</title>
      <description>The term &lt;strong&gt;&amp;#8220;Hindley-Milner type system&amp;#8221;&lt;/strong&gt; is one I have read quite often only having had an intuitive understanding of what it means. Since every paper about Type Systems or some Functional Programming papers often use the term in such a way that one might get the impression that it is universally understood by everyone, I was firstly reluctant to ask the simple question:
	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;What is a Hindley-Milner type system?&lt;/strong&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;But the simple questions are usually the interesting ones! When you write a program in an imperative programming language like Java, C, etc.  the compiler depends on &lt;strong&gt;explicit&lt;/strong&gt; type annotations in order to do its type checking. This may not sound particularily disturbing since a good programmer should always know the types of function arguments, return types, etc. Type ascriptions also serve as documentation. So what&amp;#8217;s wrong with explicit type annotation?&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;It is tedious!&lt;/li&gt;
		&lt;li&gt;You do not always get it right!&lt;/li&gt;
		&lt;li&gt;It is tedious!&lt;/li&gt;
		&lt;li&gt;You do not always get it right!&lt;/li&gt;
		&lt;li&gt;...&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;But what about languages like Ruby, Perl, &lt;span class="caps"&gt;PHP&lt;/span&gt; etc. where there is no need &amp;#8211; or almost no need &amp;#8211; for explicit type annotations? How do those languages infer the types of expressions, function parameters, variables etc. (e.g. Perl example &amp;#8216;&lt;code&gt;sub foo($) { my $arg = shift;  }&lt;/code&gt;&amp;#8216;) In order to answer this question it necessary to distinguish between the following type checking strategies:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Type_system#Static_typing"&gt;Statically checked&lt;/a&gt;: 
Static type checking happens during compile time. It can be seen as a &lt;strong&gt;static&lt;/strong&gt; approximation to the run-time behaviors of terms in a program.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Type_system#Dynamic_typing"&gt;Dynamically checked&lt;/a&gt;: 
Dynamic or latent type checking occurs during run-time, where run-time type tags are used to distinguish different kinds of structures in the heap.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Type_system#Static_and_dynamic_type_checking_in_practice"&gt;Hybrid &amp;#8211; statically &amp;#38; dynamically checked&lt;/a&gt;: 
Many languages like Java do extensive static type checking as well as some dynamic type checking during run-time (e.g. to support &lt;a href="http://en.wikipedia.org/wiki/Type_conversion"&gt;down casts&lt;/a&gt; (a.k.a. widening))&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Thus &amp;#8216;type inference&amp;#8217; and &amp;#8216;type checking&amp;#8217; in languages such as Ruby, Perl, &lt;span class="caps"&gt;PHP&lt;/span&gt; etc. happens at run-time when all the expressions are evaluated. Even some language constructs in Java require run-time &amp;#8216;type checking&amp;#8217;. A language like &lt;a href="http://www.haskell.org"&gt;Haskell&lt;/a&gt; infers and checks types statically &amp;#8211; so you do not have to run a program to find out about possible type errors.&lt;/p&gt;


	&lt;p&gt;There is a lot of debate on what strategy is &amp;#8216;better&amp;#8217; or &amp;#8216;worse&amp;#8217;, but hey, what about &lt;strong&gt;Hindley-Milner&lt;/strong&gt;? So let others do the debating about the merits of language &lt;span class="caps"&gt;XYZ&lt;/span&gt; and its type checking strategy and let&amp;#8217;s concentrate on the original problem.&lt;/p&gt;


	&lt;h3&gt;Type Inference&lt;/h3&gt;


	&lt;p&gt;Type inference is the ability to deduce the type of a value derived from the &lt;em&gt;eventual&lt;/em&gt; evaluation of an expression. So we do not actually evaluate an expression to &amp;#8216;infer&amp;#8217; its type (dynamic typing), but rather infer the type of a value &lt;strong&gt;before&lt;/strong&gt; the expression which produces it is evaluated (static typing). How can this work? Well, if the compiler is able to recognize the eventual reduction of an expression to &lt;strong&gt;implicitly&lt;/strong&gt; typed atomic values (e.g. 1, &amp;#8220;string&amp;#8221;, 1.3, False), it is able to type check and compile a program completely without type annotations. Now there are limits to this, but delving into those would be a bit too much for now.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;So what does Hindley-Milner stand for ?!&lt;/strong&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Finally we can answer this question! The common algorithm used to perform &lt;strong&gt;type inference&lt;/strong&gt; is referred to as &lt;a href="http://en.wikipedia.org/wiki/Type_inference#Hindley.E2.80.93Milner_type_inference_algorithm"&gt;Hindley-Milner&lt;/a&gt; or Damas-Milner algorithm. So if you have a language with a Hindley-Milner type system, it basically means that the language can infer almost all types and you do not have to explicitly write type ascriptions. Of course you can still make type annotations where it makes sense for better readabilty. Hindley-Milner type inference will check if your ascriptions are correct and ensure that there are no type errors before you execute the program. In case of type errors it is even able to tell you what type it would have expected at the erroneous position. That&amp;#8217;s pretty cool and very powerful indeed!&lt;/p&gt;


Sources:
	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Type_inference"&gt;http://en.wikipedia.org/wiki/Type_inference&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Benjamin_C._Pierce"&gt;Pierce, Benjamin C.&lt;/a&gt;. &lt;em&gt;Types and Programming Languages (Chapters 1, 23)&lt;/em&gt;&lt;/li&gt;
	&lt;/ul&gt;</description>
      <pubDate>Mon, 11 Jun 2007 21:23:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:f7391f49-a01b-4d9a-ba3e-50d358db6b2d</guid>
      <author>igor</author>
      <link>http://blog.solaris.bytelabs.org/articles/2007/06/11/hindley-milner-type-inference</link>
      <category>Hacking and Computers</category>
      <category>Types</category>
      <category>Inference</category>
    </item>
  </channel>
</rss>
