Skip to content

Instantly share code, notes, and snippets.

@chenglou
Forked from bsansouci/template-function-syntax.re
Last active September 18, 2017 05:02
Show Gist options
  • Save chenglou/77e1e5cb559127018121a0df4042e8b3 to your computer and use it in GitHub Desktop.
Save chenglou/77e1e5cb559127018121a0df4042e8b3 to your computer and use it in GitHub Desktop.
/* Template for proposals to update the syntax. Base template: https://gist.github.com/jordwalke/6935739b74eb9b8496670cc7860f5acf */
let a = 10;
let b = 20;
/* A */
let nonNamed = (a, b) => a + b;
type nonNamed = (int, int) => int;
/* B */
let nonNamedAnnotated = (a: int, b: int): int => a + b;
type nonNamedAnnotated = (int, int) => int;
/* C */
let named = (~a, ~b) => a + b;
type named = (~a: int, ~b: int) => int;
/* D */
let namedAlias = (~a as aa, ~b as bb) => aa + bb;
type namedAlias = (~a: int, ~b: int) => int;
/* E */
let namedAnnot = (~a: int, ~b: int) => 20;
/* F */
let namedAliasAnnot = (~a as aa: int, ~b as bb: int) => 20;
/* G: three args mixed */
let mixedNamedAndNot = (~a, ~b, c) => a + b + c;
type mixedNamedAndNot = (~a: int, :b: int, int) => int;
/* G2: three args mixed and annotated */
let mixedNamedAndNotAnnot = (~a: int, ~b: int, c: int): int => a + b + c;
type mixedNamedAndNotAnnot = (~a: int, ~b: int, int) => int;
/* G3: four args mixed */
let mixedNamedAndNot = (~a, ~b, c, d) => a + b + c + d;
type mixedNamedAndNot = (~a: int, ~b: int, int, int) => int;
/* G4: four args mixed and annotated */
let mixedNamedAndNotAnnot = (~a: int, ~b: int, c: int, d: int): int => a + b + c + d;
type mixedNamedAndNotAnnot = (~a: int, ~b: int, int, int) => int;
/* G5: named args and unit */
let namedAndUnit = (~a, ~b, ()) => a + b;
type namedAndUnit = (~a: int, ~b: int, unit) => int;
/* G6: named args and tuple */
let namedAndTuples = (~a, ~b, (x, y), z) => a + b + x + y + z;
type namedAndTuples = (~a: int, ~b: int, (int, int), int) => int;
/* G7: named args and tuple annotated */
let namedAndTuples = (~a: int, ~b: int, (x: int, y: int): (int, int), z: int): int => a + b + x + y + z;
type namedAndTuples = (~a: int, ~b: int, (int, int), int) => int;
/* G8: named args and tuple */
let namedAndTuples = (~a, ~b, z, (x, y)) => a + b + x + y + z;
type namedAndTuples = (~a: int, ~b: int, int, (int, int)) => int;
/* G9: named args and tuple */
let namedAndTuples = ((x, y), ~a, ~b) => x + y + a + b;
type namedAndTuples = ((int, int), ~a: int, ~b: int) => int;
/* G10: named args with first unnamed */
let func = (x, ~a, ~b) => x + a + b;
type func = (int, ~a: int, ~b: int) => int;
/* G11: named args with first unnamed */
let func = (x, y, ~a, ~b) => x + y + a + b;
type func = (int, int, ~a: int, ~b: int) => int;
/* H optional named args (optional args are always named) */
let myOptional = (~a=?, ~b=?, ()) => 10;
type named = (~a: ?int, ~b: ?int, unit) => int;
/* I */
let optionalAlias = (~a as aa=?, ~b as bb=?, ()) => 10;
/* J */
let optionalAnnot = (~a: option(int)=?, ~b: option(int)=?, ()) => 10;
type optionalAnnot = (~a: int=?, ~b: int=?, unit) => int;
/* K */
let optionalAliasAnnot = (~a as aa: option(int)=?, ~b as bb: option(int)=?, ()) => 10;
type optionalAliasAnnot = (~a: int=?, ~b int=?, unit) => int;
/* L */
let defOptional = (~a=10, ~b=10, ()) => 10;
type defOptional = (~a: int=?, ~b: int=?, unit) => int;
/* M */
let defOptionalAlias = (~a as aa=10, ~b as bb=10) => 10;
/* N */
let defOptionalAnnot = (~a: int=10, ~b: int=10, ()) => 10;
/* O */
let defOptionalAliasAnnot = (~a as aa: int=10, ~b as bb: int=10, ()) => 10;
/* P: Invoking them - Punned */
let resNotAnnotated = named(~a, ~b);
/* Q */
let resAnnotated: int = named(~a, ~b);
/* R */
let aa = 1;
let bb = 2;
let resNotAnnotated = named(~a=aa, ~b=bb);
/* S */
let resAnnotated: int = named(~a=aa, ~b=bb);
/* T */
let resAnnotated = named(~a, ~b);
/* U: Proof that there are no ambiguities with return values being annotated */
let resAnnotated: ty = named(~a, ~b=b);
/* V: Explicitly passed optionals are a nice way to say "use the default value"*/
let explictlyPassed = myOptional(~a=?None, ~b=?None);
/* W: Explicitly passing optional with identifier expression */
let a = None;
let explictlyPassed = myOptional(~a=?a, ~b=?None);
/* punned */
let explictlyPassed = myOptional(~a?, ~b=?None);
let explictlyPassedAnnotated: int = myOptional(~a?, ~b=?None, ());
/* X: tuples */
let receiveTuples = ((x, y, z)) => x + y + z;
type receiveTuples = ((int, int, int)) => int;
/* X2: calling syntax */
let d = receiveTuples((1, 2, 3));
let d : int = receiveTuples((1, 2, 3));
/* Y */
let receiveTuplesDestructure = (~vec as (x, y, z)) => x + y + z;
type receiveTuples = (~vec: (int, int, int)) => int;
/* Y2: calling syntax */
let vec = (1, 2, 3);
let d = receiveTuplesDestructure(~vec);
let d: int = receiveTuplesDestructure(~vec=(1, 2, 3));
/* Z */
let takesUnit1 = () => 4;
let takesUnit2 = (~a, ()) => a;
/* Z2 */
let randomNumber = takesUnit1();
let randomNumber = takesUnit2(~a, ());
/* ------------------------------------------------------- */
/* anonymous function syntax */
/* ------------------------------------------------------- */
/* A */
let func = (a, b, c) => a + b + c;
type func = (int, int, int) => int;
/* A2: compared to normal function */
let func = (a, b, c) => a + b + c;
type func = (int, int, int) => int;
let func = (a) => (b) => (c) => a + b + c;
type func = (int, int, int) => int;
/* B */
let func = (~a, ~b, ~c) => a + b + c;
type func = (~a: int, ~b: int, ~c: int) => int;
/* C */
let func: (~a: int, ~b: int, int) => int = (~a: int, ~b as bb: int, c: int): int => a + bb + c;
/* D */
let func: (~vec: (int, int, int), ~num: int) => (int, int, int) =
(~vec as (x, y, z), ~num) => (x + num, y + num, z + num);
/* D2: same calling syntax */
let vew = (1, 2, 3);
let newVec = func(~vec, 10);
let newVec = func(~vec=(2, 3, 4), 10);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment