Skip to content

Instantly share code, notes, and snippets.

@milesrout
Last active November 23, 2017 00:09
Show Gist options
  • Save milesrout/3e1a947fa4ab1f07bdbe to your computer and use it in GitHub Desktop.
Save milesrout/3e1a947fa4ab1f07bdbe to your computer and use it in GitHub Desktop.
The ? language.
-- ? doesn't have statements, it has sentences.
-- sentences end with a full stop, as everyone knows.
-- every expression can be a sentence.
let a = 1.
-- let expressions look like this:
-- `'let' VARIABLE '=' EXPRESSION (',' VARIABLE '=' EXPRESSION)* ('and' VARIABLE '=' EXPRESSION)?`
let b = 2 and c = 3.
let d = 4, e = 5 and f = 6.
let g = 7, h = 8.
-- let expressions can have child blocks, like so:
let i = 9
in println i.
-- in addition to let expression, we have where expressions.
println.fmt "Hello, {name}\n"
where name = "Miles".
-- let expressions and where expressions can be combined.
let k = l
in println k
where l = 11.
let k = l
where l = 11
in println k.
-- calling functions should be very easy and have simple syntax.
-- many layers of parentheses can end up being ugly.
print (map (x ↦ x + 1) [1..100)).
-- some languages have a 'loose call' operator that does a
-- function call but is very loosely bound.
print $ map (x ↦ x + 1) [1..100)
-- in ? this can be done with |
[1..100) | map (x ↦ x + 1) | print
-- ? also has a 'tight call' operator that binds even more
-- tightly than normal function calls.
print map:(x ↦ x + 1):[1..100)
-- that isn't a very idiomatic use: it's normally reserved for
-- other situations like this:
let (sum product) = (reduce:+:0 reduce:*:1)
-- A nice feature of ? is its ranges, which are very
-- similar to the ranges of other languages like Python.
[1..100] | sum | println. --> 5050
-- a [a..b] denotes a closed range
-- a [a..b) denotes a half-open range
println sum:[1..3]. --> 6
println sum:[1..3). --> 3
-- ranges are printed out in mathematical notation
println [1..9]. --> [1..9]
println [0..10). --> [0..10)
-- when you want an array of objects, you use a vector.
-- this is the equivalent of Python's `print(list(range(10)))`
println vec:[1..10]. --> [0 1 2 3 4 5 6 7 8 9]
-- you can use map and for loops to iterate
map print [1..10]. --> 0123456789
for i in [1..10]
print i. --> 0123456789
-- generally, `map` is more useful than `for`.
-- it's difficult to do this with a for loop cleanly
print map:(x ↦ x * x):[1..5]. --> [1 4 9 16 25]
-- but sometimes for loops can be cleaner
map (x ↦ print x * x) [1..5]. --> 1491625
for x in [1..5]
print x * x.
-- you can obviously write out lists manually.
println [1 2 3 4 5].
-- functions are very easy in ?.
let add = (x y) ↦ x + y.
-- you can of course use them in let/where-expressions.
print mul 1 2
where mul = (x y) ↦ x * y.
let div = (x y) ↦ x ÷ y
in print (div 4 2).
-- that's right, ? uses ÷ for division. / is far too important
-- to be wasted on division, a relatively uncommon task with a
-- dedicated symbol already.
print 5 ÷ 4. --> 1.25
-- inefficient vector-based cache
let add-to-cache = (cache item) ↦
if item not in cache
then append cache item.
let c = [].
map (x ↦ add-to-cache c x) [1..10].
let i = [1..10] in
println all i in c. --> true
----
let cart-to-polar = (x y) ↦
let r = sqrt x^2 + y^2,
θ = atan2 x y
in r θ.
-- is turned into
let cart-to-polar = (x y) ↦
let r = sqrt x^2 + y^2
in (let θ = atan2 x y
in r θ). -- return the pair r and θ.
-- macros are an important feature of ?.
-- for example, macros make formatted strings easy.
mlet let = (bindings forms) e ~↦
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment