Last active
August 29, 2015 14:03
-
-
Save kongtomorrow/ee9d14208659555ea578 to your computer and use it in GitHub Desktop.
Y combinator in ObjC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* This is an exercise, basically. See http://www.ece.uc.edu/~franco/C511/html/Scheme/ycomb.html | |
for why you might care, or https://gist.github.com/kongtomorrow/e95bea13162ca0e29d4b for the | |
same in Swift. | |
*/ | |
#define Y(Domain,Range) ({ \ | |
typedef Range(^DtoR)(Domain); \ | |
\ | |
^(DtoR (^almost)(DtoR)){ \ | |
typedef id (^IdToId)(id); \ | |
return (DtoR) (^(IdToId next){ /* the real type of next is DtoR(^)(typeof(next)). It's a recursive definition, so we just make it IdToId to keep the compiler happy.*/ \ | |
return (id)^(Domain args){ \ | |
return (Range) almost(next(next))(args); \ | |
}; \ | |
}(^(IdToId next){ \ | |
return (id)^(Domain args){ \ | |
return (Range) almost(next(next))(args); \ | |
}; \ | |
})); \ | |
}; \ | |
}) | |
typedef int (^IntToInt)(int); | |
IntToInt factorial = Y(int,int)(^(IntToInt recur){ | |
return ^(int n){ | |
switch (n) { | |
case 0: return 1; | |
default: return n*recur(n-1); | |
} | |
}; | |
}); | |
printf("%d\n", factorial(5)); | |
typedef int (^CharsToInt)(char *str); | |
CharsToInt maxIntInString = Y(char*,int)(^(CharsToInt recur){ | |
return ^(char *str) { | |
if (*str == '\0') { | |
return 0; | |
} else { | |
return MAX(*str - '0', recur(str+1)); | |
} | |
}; | |
}); | |
printf("%d\n", maxIntInString("0523562")); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment