In sketching I iterated various designs, my notepad is below. It began trying to think about how to express scopes visually, or using tags/lables -- then moved into how that integrates with other langauge features etc.
By doing this I understand much more about what really a language feature is trying to do -- I understand the tradeoffs, etc.
program a:
let x:a = 10
if 10 < 5 b:
let x:b = x
print(x)
program UseyTypes:
x : once = new Resource() # at most once -- rust's default
y : never = ...
z : once! = ... # only once
q : many = ...
program MoveSemantics:
a = new 10
x = 10
y = move x
z = copy y
i0 = new(auto) 10
i1 = new(memo.alloc.heap) 10 # default
g1 = new(heap) Graph.init({...})
g2 = copy(Graph) g1 # uses Graph's (deep)copy method
g2 = copy(Graph.copy) g1 # eqv to above
program :
global heap = Allocator.tmp(...)
if True:
local xs = Vec.new(heap) { 1, 2, 3, 4 }
memo.lifetimeOf(x) # eg., local scope a = lineno 10 - 20
memo.lifetimeOf(x.data) # eg., global via heap allocator
repeat x <= xs:
x = 10 # error
print(x)
repeat i <= int.range(10):
x[i] += 1
repeat:
const answer = input("What's 2 + 2?").to(int)
print(compiler.scope)
print(compiler.lineno)
const int z = 10
const ref(int) y = ref(z)
print(y, deref(y))
const x : global = 10
if 10 < 5:
int x : local = 10
int y : parent = 10
# polymorphic .to
fn str.to(int):
parseInt(.)
program EffectSystem:
fn[IO] println(const ...data: ...any):
repeat d <- data:
IO.writeline(d.to(str))
pure fn calc(): # pure = no effects
return 10 + 20
# by default, all fns are impure, ie., have IO auto-passed ?
println("Hello", "World")
with IO = open("output.txt", "w"):
println("Into some file!")
println[open("output.txt")]("hello world")