10/29/2012

Simplest:
  • No constraints
  • Cannot do any lookups on T, cannot assign anything other than any to T, cannot assign T to anything other than any and T ("T is a branded {}")
  • Function expressions cannot declare generic parameters
  • Class methods, function declarations
    • Later: What about object literals?

What's left:
  • Inference
    • Would like: Infer class type parameters from constructor calls
  • Type compatibility
    • Maybe: any's can fill in for T?
  • Try this out for 5 libraries

11/9/2012

/////////  PROMISE /////////////
// As discussed in design meeting
//  (1) we don't yet know of any cases where this fails
//  (2) seems we need the four overloads of then to deal with success or failure being T 
or Promise<T>
//  (3) progress should be added
interface Promise<T> {
  then<U>(success?: (x: T) => U, failure?: (x: any) => U): Promise<U>;
  then<U>(success?: (x: T) => U, failure?: (x: any) => Promise<U>): Promise<U>;
  then<U>(success?: (x: T) => Promise<U>, failure?: (x: any) => U): Promise<U>;
  then<U>(success?: (x: T) => Promise<U>, failure?: (x: any) => Promise<U>): Promise<U>;
  done(success?: (x: T) => any, failure? (x: any) => any): void;
}


var p = {
  then(success?: (x: string) => any): any;
  //done
}
 
 
/////////  WINRT /////////////
// Basic:  
//  (1) just a handful of generic types
//  (2) no generic methods
interface Windows.Foundation.Collections.IIterable<T> {
    first(): Windows.Foundation.Collections.IIterator<T>
}
interface Windows.Foundation.Collections.IIterator<T> {
    current: T;
    hasCurrent: bool;
    moveNext(): bool;
    getMany(): T[];
}
interface Windows.Foundation.Collections.IVector<T> extends T[] {
    size: number;
    getAt(index: number): T;
    indexOf(value: T): { index: number; returnValue: bool; };
    getMany(startIndex: number): T[];
    setAt(index: number, value: T): void;
    insertAt(index: number, value: T): void;
    removeAt(index: number): void;
    removeAtEnd(): void;
    clear(): void;
    replaceAll(items: T[]): void;
}
 
interface Windows.Foundation.Collections.IMapView<K,V> {
    size: number;
    lookup(key: K): V;
    hasKey(key: K): bool;
}
interface Windows.Foundation.Collections.IMap<K,V> {
    size: number;
    lookup(key: K): V;
    hasKey(key: K): bool;
    getView(): Windows.Foundation.Collections.IMapView<K,V>;
    insert(key: K, value: V): bool;
    remove(key: K): void;
    clear(): void;
}
 
/////////  ES6 Iterators /////////////
interface Iterator<T> {
  next(): T;
}
interface Iterable<T> {
  iterator(): Iterator<T>;
}
// This guy is hard
interface Generator<T> extends Iterator<any> {
    send(x: any): any;
}
var f: () => Generator<string> = function *() {
    var data = yield $.ajax(url);
    $('#result').html(data);
    var status = $('#status').html('Download complete.');
    yield status.fadeIn().promise();
    yield sleep(2000);
    status.fadeOut();
    return "hello";
}
var p: Promise<string> = spawn(f);
 
/////////  KNOCKOUT /////////////
// (1) Generic "Observable" interface the central object of KnockOut
// (2) Nice interaction of generics and interface call signatures
// (3) Interesting need for 'generic this' for chaining of sets
declare module ko {
    export interface Observable<T> {
        (): T;
        (value: T): void; 
        <O>(this: O, value: T): O; // Is this legit?
        subscribe((newValue: T) => void ): {
        dispose(): void
    };
    }
    export function observable<T>(value: T): Observable<T>;
    export function applyBindings(viewModel: any): void;
    export function computed<T>(() => T, owner: any): Observable<T>;
    export function computed<T>({ read: () => T; write?: (value: T) => void; owner?: any}): Observable<T>;
    export function isComputed(o: any): bool;
    export function isObservable(o: any): bool;
    export function observable(o: any): bool;
 
}

var o = {
   x: ko.observable("hello"),
   y: ko.observable(5),
   z: ko.computed(function() {
      return this.x + this.y; 
   })
}

o.x("goodbye").y(6);
 
 
/////////  UNDERSCORE /////////////
// Looks to be fairly standard LINQ-like library from the generics standpoint
// (1) Iteration over both arrays and objects (ordered string keyd dictionaries)
// (2) Not yet modelled below - API allows chained mode _([1,2,3]).map(f).filter(g)

_.each({a: 1, b: 4}, function(n) { return n + 1; });
// Note: 

interface Underscore {
 
    each<T>(
          list: T[],
          iterator: (element: T, index: number, list: T[]) => any,
          context?: any): void;
     each<T>(
          obj: {[x: string]: T},
          iterator: (value: T, key: string, object: {[x: string]: T}) => any,
          context?: any): void;
     map<T, U>(
          list: T[],
          iterator: (element: T, index?: number, list?: T[]) => U,
          context?: any): U[];
     map<T, U>(
          obj: {[x: string]: T},
          iterator: (value: T, key?: string, object?: {[x: string]: T}) => U,
          context?: any): U[];
    //?
    invoke(list: any[], methodName: string, ...arguments: any[]): void;
    pluck<T,U>(list: T[], propertyName: string): U[];
    max(list: number[]): number;
    max<T>(
          list: T[],
          iterator: (element: T, index: number, list: T[]) => number,
          context?: any): number;
    groupBy<T>(
          list: T[],
          iterator: (element: T, index: number, list: T[]) => string,
          context?: any): { [key: string]: T[]; };
    }

_.groupBy([1,2,3, 19], function(x) { return x.toString()[0]; })

{"1": [1,19], "2": [2], "3": [3] }


(<number[]>_.pluck(["a","b","c"], "length")) => [1,1,1]
_.pluck<string, number>(["a","b","c"], "length") => [1,1,1]

12/14/2012

Generics and constraints.

Today: foo(x: Comparable): Comparable {}
Generics: foo<TComparable>(x: TComparable): TComparable {}

Without constraints, the generic version is less expressive than the non-generic version (and as such, less useful in .d.ts to check against interface contracts). To regain this expressivity, we need to allow for constraints. Constraints can be based on a type variable extending an interface.

interface Bar {}  //or class Bar {}
class Foo<T extends Bar, U /* extends {} */, V extends Bar> {
  f() {
    var x: T;
    var y: Bar;
    y = x;
    x = y; // error

   var z: V; 
    x = z; // error
  }
}  


function foo<T extends Comparable>(x: T): T {
  x.compareTo();
}

var myComparable: MyComparable;
var z /* : MyComparable */ = foo(myComparable);


var foo: <T extends Comparable>(x: T) => T;

Interface Collection<T> {
  map: <U>(f: T=>U): Collection<U>;
}

var myColl: Collection<Foo> = {
  map: function(f) {
    
  }
}

Last edited Jan 4, 2013 at 6:09 PM by jonturner, version 5

Comments

No comments yet.