idk if y’all remember my idea for a #Lisp where all expressions are actually #Lua -style tables, instead of linked lists like a normal Lisp. (I’m calling these expressions T-expressions btw, since they’re not quite the same thing as S-expressions, and they make Tables)
but lately I’ve been trying to figure out a way to add symmetry between defining a variable and adding a key to a table. like here’s a table literal:
'([key value]
[key2 value2])
and ideally I’d love to be able to reuse this concept as the way to define variables. because I want this language to have as little magic as possible and as few discrete concepts to learn as possible, and a special form like (define) would be a discrete concept that I want to get rid of. so I considered letting people do something like this:
[variable 666]
(print variable) ; -> 666
and it would work for any nested T-expressions too:
[variable "foo"]
(do
[variable 666]
(print variable)) ; -> 666)
(print variable) ; -> foo
(print
[variable "bar"]
variable) ; -> bar
but the main problem is that in order to resolve this, the reader would have to work in phases with the interpreter:
(do
[variable 666]
(print variable)
; ↑ the reader only goes this far,
; then this gets interpreted
[variable "foo"]
(print variable)
; ↑ now the reader stops here and
; lets the interpreter work again
)
which intuitively seems to me like it would probably be a terrible idea. alternatively, it would be a syntax error to redefine the same {variable / table key} in the same scope, which might work well enough
this would also mean that sending keyword arguments to a function would have to use less elegant semantics:
; if these are variables instead of
; kwargs:
(func ['kwarg0 value0]
['kwarg1 value1])
; then kwargs would have to just be
; this, like a normal Lisp. which
; isn't as elegant :/
(func :kwarg0 value0
:kwarg1 value1)
; alternatively, you could do
; something like this, which is IMO
; a bit better
(func [:kwarg0 value0]
[:kwarg1 value1])
but the biggest problem with this idea is that they would be absolutely terrible in any kind of deeply-nested data structure, since every single key-value declaration would also be clobbering a variable:
[id 666]
`([name "Earth Machine"]
[element ""]
[id 667]
[submachine
([name "Earth Submachine"]
[id ,id] ; <- oops! this is
; 667, but I wanted
; 666
))
I could fix this by saying that “by convention, all variables declared in a table should start with a $“ or, “by convention, all table keys that will be used as table keys (and not as variables) should be keywords”. and the latter does sound kind of reasonable
actually, yeah. I really really like that last option. because then you can create variables with any arbitrary scope that you want, inside of literally any T-expression that you want, without increasing the level of indentation, and you can define them pretty much anywhere, and they won’t interfere with deeply-nested data structures at all, and they won’t mess with the reader -> interpreter pipeline either! that’s actually an amazing solution, unless I’m missing some reason why it won’t work



