Skip to content

Instantly share code, notes, and snippets.

@mflatt
Last active September 28, 2019 16:40
Show Gist options
  • Save mflatt/aa09fd2ac9e445bbddd99f6243a21458 to your computer and use it in GitHub Desktop.
Save mflatt/aa09fd2ac9e445bbddd99f6243a21458 to your computer and use it in GitHub Desktop.
let | x : 1
| y : 2
in :
(x + y)
define pi : 3.14
define fib(n) :
log_error("fib called")
cond | (n = 0) : 0
| (n = 1) : 1
| else : (fib(n - 1) + fib(n - 2))
define :
| fib(0) : 0
| fib(1) : 1
| fib(n) : (fib(n - 1) + fib(n - 2))
define fib :
lambda(n) :
cond | n = 0 : 0
| n = 1 : 1
| else : (fib(n - 1) + fib(n - 2))
define fib(n) :
match n :
| 0 : 0
| 1 : 1
| n : (fib(n - 1) + fib(n - 2))
define fib(n) :
match n : | 0 : 0
| 1 : 1
| n : (fib(n - 1) + fib(n - 2))
define fib(n) :
match n :
| 0 :
0
| 1 :
1
| n :
(fib(n - 1) + fib(n - 2))
;; Currently, no way to break the above "+" across two lines
define make_adder(n) :
lambda(m) :
printf("adding to ~a\n", m)
(m + n)
;; This doesn't parse as possibly intended, because `printf...`
;; continues the `else :` line:
define analyze(n) :
if (n == 0) :
printf("zero\n")
else :
printf("other\n")
printf("done\n")
;; Here's one way to get the parse that was possibly intended:
define make_adder(n) :
if (n == 0) :
printf("zero\n")
else :
printf("other\n")
;
printf("done\n")
;; Here's another way, not as good:
define make_adder(n) :
[if (n == 0) :
printf("zero\n")
else :
printf("other\n")]
printf("done\n")
struct posn :
x
y
struct color_posn :
col
where :
extends posn
mutable
struct posn :
x mutable
y default(7)
where :
methods equality :
define equal(a, b) :
(is_posn(b) => (a.x == b.x && a.y == b.y))
;
define hash(a) :
17
;
define secondary_hash(a) :
19
struct posn :
x
y
where :
property prop_equal_and_hash :
let | hc = [lambda(a : posn, hc) :
(hc(a.x) + hc(a.y))]
| eql = [lambda(a : posn, b : posn, eql) :
(eql(a.x, b.x) && eql(a.y, b.y))]
in :
values(eql, hc, hc)
;; To avoid binding `eql` above, we'd need a multi-line function call
;; form to support a multi-line `lambda` argument
;; Allow using `=` instead of `:` for non-function
;; definitions to make this work?
define fourth(n : integer) :
define m = (n * n)
define v = (m * m)
printf("~a^4 = ~a\n", n, v)
v
define exp(n: integer, base :: base = 2.718281828459045) :
if (n = 1) :
base
else :
(base * exp(n - 1, base :: base))
;; No way to put `if` all on one line
define positive_p(n) : if (n > 0) : true
else : false
define go() :
[define helper(n) :
list(n, n)]
[define more(m) :
if (m = 0) : "done"
else : more(m - 1)]
helper(more(9))
define go() :
define helper(n) :
list(n, n)
;
define more(m) :
if (m = 0) : "done"
else : more(m - 1)
;
helper(more(9))
define approx(x) :
match x :
| something(v) :
printf("got it\n")
v
| nothing : 0
;; One level of indentation for `v` means that it continues the first `:`,
;; so the `lambda` body is empty:
define approx_thunk(x) :
match x :
| something(v) : lambda() :
v
| nothing : lambda() : 0
;; Two levels of indentation for `v` means that it continues the second `:`,
;; so the `lambda` body has `v`:
define approx_thunk(x) :
match x :
| something(v) : lambda() :
v
| nothing : lambda() : 0
define approx_thunk(x) :
match x :
| something(v) : [lambda :
| _() : v
| _(n) : (v + n)]
| nothing : [lambda :
| _() : 0
| _(n) : n]
define curried :
lambda(x) :
lambda(y) :
lambda(z) :
list(x, y, z)
define curried : [lambda(x) :
lambda(y) :
lambda (z) :
list(x, y, z)]
define dictionary : dict :
foo : 17
bar : string
baz : true
;; Not yet a way to break the argument list over multiple lines
define f(x_something, y_something_else, z_also_long_name) :
5
define show_all(l) :
for | x = in_list(l)
in :
print(x)
newline()
define show_zip(l, l2) :
for | x : in_list(l)
| x2 : in_list(l2)
in :
print(x)
print_string(\" \")
print(x2)
newline()
define show_combos_not_same(l, l2) :
for | x = in_list(l)
then :
| x2 = in_list(l2)
then :
| when !is_equal(x, x2)
in :
print(x)
print_string(" ")
print(x2)
newline()
define map(f, l) :
for list | x = in_list(l)
in :
f(x)
define partition(l, pred) :
for fold(yes = empty, no = empty, result values(reverse(yes), reverse(no))) \
| x = in_list(l)
in :
if pred(x) :
tuple(cons(x, yes), no)
else :
tuple(yes, cons(x, no))
define sum(l) :
let loop(l = l) :
if is_null(l) :
0
else :
(first(l) + loop(rest(l)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment