[ create a new paste ] login | about

Link: http://codepad.org/eLr7lLJd    [ raw code | fork ]

OCaml, pasted on Jan 4:
staload _ = "prelude/DATS/array.dats"

fun getitem{n,m:nat}(arr : array(int, n) , length : int(n), index : int m) : int =
    (*  This is an ML-style comment, which is similar to C-style comments
        except that they can be nested arbitrarily (* like this *)
       
        The first thing we do is declare compile-time variables that the
        dependent types refer to, the natural numbers n and m.
        These refer to the size of the list, and the index, respectively.
        {n,m:nat} is the same as {n,m:int | n >= 0 && m >= 0}
        Arguably we should be saying this as
        {n,m:nat | n > m >= 0}, but perhaps that's getting ahead of ourselves.
        Besides, the array type already does that.
       
        a value is of type array(X, Y) if its contents are of type X, and it is 
        of length Y
       
        array(int, nat(n)) says:
            the array has some non-negative length, and only contains integers

        length: nat(n) says:
            length is a natural number value n, which is the same as the length
            of the array
    
        Because the types have been declared this way, the code will fail to
        typecheck (at compile time) if these relations are not true. The
        compiler's job is to verify, everywhere this function is called,
        that the value passed for the length parameter is the same as the
        allocated size of the list.
        
        If the compiler can't prove this, then the program fails to typecheck.
    

        in short, we know at _compile time_ a value "n" which is the length of
        the array and we know, at _run time_, a value "length", which is also
        the length of the array. The compiler guarantees to us that length == n, and moreover it is aware of this fact itself, so that if we check things against length, it knows that it can do the same checks against n.

        This means that we can inspect the value "index" to make sure it will
        not go out of bounds, and when we do that, we also satisfy the compiler
        that we have done so.
    *)
    
    (* The compiler would complain if there was ever a value for which this
       was not true, and we forgot to check it *)
    if index < length then
        arr[index]
    else
        ~1 (* -1, error *)


(* erm ...*)
implement main () = let (* def main(): *)
    val A = array $arrsz{int}(2, 1, ~20, 900, 123, 2, 12) (* A = [2, 1, -20, 900, 123, 2, 12] *)
in (
    printf("%d\n", @(getitem(A, 7, 0))) (* print "%d\n" % (getitem(A, 7, 0),) *)
)
end


Create a new paste based on this one


Comments: