Could you expand on why this is so powerful for you?
Not doubting it’s power, but I’m having a hard time understanding _why_ it’s so powerful for some people.
Could you expand on why this is so powerful for you?
Not doubting it’s power, but I’m having a hard time understanding _why_ it’s so powerful for some people.
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")Out of curiosity, have you ever tried developing DSLs in Racket? One of its explicit reasons for existence is to enable fast development of custom DSLs.
C was "intuitively mind-expanding" to assembly developers and PDP-machine programmers -- and so on.
My aim is always to express a semantic concept in syntax so that it is so obvious that it's originating language developers will be shocked.
You can do that both with, eg.,
map fn over collection
and xs/fn
and repeat x from xs: fn(x)
and { fn(x) st. x <- xs & st. x > 0 }
etc.In that each syntax resonates with a certain programming culture.
For novices, I suppose the following might be "consciousness raising",
set result :=
repeat:
set x := next xs:
save fn(x)