Do you mean that if you say (= foo (a b c)), then (a b c) shouldn't be evaluated until you look up foo? Well, I know I wouldn't want that all the time:
(= setter (table)) ; oops ^_^
It's interesting; there seems to be a tension between future hackability and [brevity].
I think that's only a tension between being brief and being specific. It can't be avoided; if I specifically want things to be a certain way (e.g. hackable), I'm willing to leave the beaten path to get there. The real issue for me is how far off the beaten path I can get while still being brief enough not to get fed up and make a more hospitable language. :-p
There's another kind of brevity tension. I think a language that tries to maximize brevity doesn't need to worry about having a small implementation too. After all, it's probably built in a more verbose language. ...But now that's really off-topic. XD
Yeah I'm not sure I understand all the implications. It probably wouldn't be an entirely new evaluation model. Perhaps you just have def store pre-evaluated names.
I went back to your examples, and I think first:rev is already resistant to changes to first or rev (Update: confirmed [1]). What's hard is:
(= first car)
Perhaps we should give def a specialcase so that
(def first car)
creates a synonym without hardcoding the implementation. How about this?
(mac alias(a b) `(= ,a (late ,b)))
[1] Observe:
> (= first car)
> (= last first:rev)
> (last '(a b c d))
d
> (= first cadr)
> (last '(a b c d))
c
I was going to call that '=late. ^_^ There are still other cases where a global function can end up stored somewhere it doesn't stay up-to-date with the variable binding, like storing it as a behavior in a data sructure or using (compare ...). But I don't expect to need anything more brief than 'late, actually.
It's funny, I hadn't settled on the name 'late until I posted it here, and before that point I was thinking of it as 'alias. ^_^ I wanted to avoid confusion with Racket's aliases, so I changed it at the last second.
macros?
Macros generally aren't hackable anyway, right? I don't have any ideas to change that.... Well, except these I guess. :-p
a) Change the whole language over to fexprs. This is probably the most elegant way to make things hackable, but it'll probably be inefficient without a convoluted partial evaluation infrastructure (ensuring things are free of side effects, and headaches like that ^_^ ).
b) Record which macros are expanded every time a command is evaluated, and re-run commands whenever their macros change. Running commands out of order and multiple times would be pretty confusing. (I bet there'd be ways to manage it, but I for one would forget to use them at the REPL.) It would also be easy to fall into an infinite loop by trying to redefine a macro using a command that actually uses that macro.
first:rev is already resistant to changes in first or rev
Oh, good to know. ^_^ For Penknife, I tried to make [= foo a:b] produce a custom syntax if a or b was a custom syntax, but I got stuck. I ended up with [foo ...] using the local values of a and b, I think. In the process I got a bit confused about how a:b was supposed to work in the edge cases, from a design point of view.
This experiment was reflected in two commits in the Git repo: One introducing it, and one removing it 'cause of the poorly thought-out complexity it introduced. :)
Here it is. https://github.com/rocketnia/penknife/commit/3ca7a6c216cc022... Penknife's significantly more complicated than what I've been able to talk about so far, with its own ad hoc vocabulary throughout, so good luck. ^^; Then again, that's a pretty old commit, so it's actually a simpler codebase in ways. XD