proj-oot-ootTypeNotes5

"2. Generics (both types and immutable constraints), I think C++1z has the right approach to this (and constexpr and constant arrays are nice and are able to provide more hints to the compiler)."

---

think about the code examples in these subsections:

http://cglab.ca/~abeinges/blah/rust-reuse-and-recycle/#generics

http://cglab.ca/~abeinges/blah/rust-reuse-and-recycle/#aside-generic-inference-and-the-turbofish ---

also, in http://cglab.ca/~abeinges/blah/rust-reuse-and-recycle/#generics , i don't quite understand why need need two <T>s in the following declaration:

// Implementing functionality for all choices of T.
// Note that the "impl" is also Generic here.
// Hopefully this in conjunction with the previous
// example demonstrates why the extra <T> is necessary.
impl<T> Generic<T> {
    fn new(data: T) -> Generic<T> {
        Generic { data: data }
    }

    fn get(&self) -> &T {
        &self.data
    }
}

My guess based on other examples with <> after 'impl' later on that same webpage is that the first <T>, impl<T>, is just saying that the following declaration will have a type variable in it ('T'). Which i don't see why we really need, because we can infer it from the presence of capital T inside Generic<T>, right? But i guess this is like how we want to have 'lambda x: x + 2' not just 'x + 2' and let the compiler find out that 'x' hasn't been previously defined; also, in some examples further down that webpage, there is stuff like:

impl<T: Clone> Clone for Generic<T> { fn clone(&self) -> Self { Generic { data: self.data.clone() } } }

where there is a 'trait bound' on 'T' (why don't they call it a 'type bound'?) that says that T must implement trait 'Clone'.

i wonder if this stuff could be simplified by using ordinary function notation here, something like:

Clone for Generic<T> := fn(T :: Clone) {...}

(obviously this isn't quite right, but you see where i'm going; you are explicitly representing that T is a parameter using ordinary function notation)

---

if we have 'type attribute', need a syntax to say, within a type annotation "x has type attribute A, AND x also has type attribute B". Eg if you want to say that type "T" implements interface 'Box', and also "T" implements interface 'Clone', would you say:

T <: Box && T <: Clone

?

also, should we reserve '<:' for subtypes and have some other syntax for 'implements'?

also, interestingly, these are logical assertions, not imperative computations.

is this sort of notation what you'd find in the arguments of a function-style syntax for type bounds in genericity, as in the previous section? eg

... := fn(T :: T <: Box && T <: Clone)

that doesn't look quite right, because you expect to see stuff like

x :: int16

meaning "x ISA instance of type int16", but "T :: T <: Box && T <: Clone" up there means "T SUCH-THAT T is a subtype of Box and T is a subtype of Clone"

why not just have

T :: Box && Clone

to mean '(T s.t. T IS Box) AND (T s.t. T IS Clone)' where IS combines ISA and isSubtype as noted previously? That seems a little ambiguous, though.

hmm.

---

in Haskell, one reason for the "monomorphism restriction", according to [1], is to prevent surprising repetition of computation; eg without the monomorphism restriction, in

   genericLength :: Num a => [b] -> a 
   let { len = genericLength xs } in (len, len) 

each 'len' in '(len, len)' will be computed separately, so 'genericLength xs' will be evaluated twice. In [2], CaleGibbard? explains "The trouble is that typeclasses essentially introduce additional function parameters -- specifically, the dictionary of code implementing the instances in question. In the case of typeclass polymorphic pattern bindings, you end up turning something that looked like a pattern binding -- a constant that would only ever be evaluated once, into what is really a function binding, something which will not be memoised.".

So i guess CaleGibbard?