Skip to content

Instantly share code, notes, and snippets.

@bsansouci
Last active August 29, 2017 10:36
Show Gist options
  • Save bsansouci/93fb294b1d37b174ef15974e8bb28bbd to your computer and use it in GitHub Desktop.
Save bsansouci/93fb294b1d37b174ef15974e8bb28bbd to your computer and use it in GitHub Desktop.
/* Template for proposals to update the syntax.
This lists all cases of function definition, function type definition and function application.
Full credit to Jordan Walke, I copied the list from https://gist.github.com/jordwalke/6935739b74eb9b8496670cc7860f5acf and
only minorly tweaked it. */
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::aa b::bb => aa + bb;
type namedAlias = a::int => b::int => int;
/* E */
let namedAnnot a::(a:int) ::b :int => 20;
/* F */
let namedAliasAnnot a::(aa:int) b::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::(a:int) b::(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::(a:int) b::(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::(a : int) b::(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::aa=? b::bb=? () => 10;
/* J */
let optionalAnnot a::(a:option int)=? b::(b:option int)=? () => 10;
/* K */
let optionalAliasAnnot a::(aa:option int)=? b::(bb:option int)=? () => 10;
/* L */
let defOptional ::a=10 ::b=10 () => 10;
type named = a::int? => b::int? => unit => int;
/* M */
let defOptionalAlias a::aa=10 b::bb=10 => 10;
/* N */
let defOptionalAnnot a::(aa : int)=10 b::(bb : int)=10 :int => 10;
/* O: both forms are valid but get refmt to the first */
let defOptionalAliasAnnot a::(aa : int)=10 b::(bb : int)=10 : int => 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::b;
/* U: Proof that there are no ambiguities with return values being annotated */
let resAnnotated: ty = named ::a ::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;
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::(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 = fun 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 = fun a => fun b => fun c => a + b + c;
type func = int => int => int => int;
/* B */
let func = fun ::a ::b ::c => a + b + c;
type func = a::int => b::int => c::int => int;
/* C */
let func : a::int => b::int => int => int = fun a::(a:int) b::(bb:int) (c:int) :int => a + bb + c;
/* D */
let func : vec::(int, int, int) => (num:int) => (int, int, int) =
fun vec::(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