Arc Forumnew | comments | leaders | submitlogin
2 points by akkartik 5118 days ago | link | parent

If someone redefines 'car and 'cdr to work with strings, 'first and 'rest won't reflect the change.. They're not hackable.

It's interesting; there seems to be a tension between future hackability and <strike>verbosity</strike> brevity. Perhaps the best way to get the best of both worlds is to go for an even more dynamic interpreter. Like forth or factor, just have all name lookups happen at runtime.



1 point by rocketnia 5118 days ago | link

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

-----

1 point by akkartik 5118 days ago | link

> (= setter (table)) ; oops ^_^

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

-----

2 points by akkartik 5118 days ago | link

Assuming the only case we care about is function name aliases, I've pushed out the following simpler version to my repo (https://github.com/akkartik/arc/commit/fe21a3456fc7e69fc6ec1...)

  (mac alias(f g)
    `(= ,f (fn args
             (apply ,g args))))
For example, compare using =:

  > (= be iso)
  > (be 3 3)
  t
  > (= iso +)
  > (be 3 3)
  t ; didn't get new iso
..with alias:

  > (alias be iso)
  > (be 3 3)
  t
  > (= iso +)
  > (be 3 3)
  6 ; got new iso
So now I have two questions:

a) Do we need to handle rhs being anything more complex than just a symbol?

b) Neither your late nor my simplified version seem to work with macros. Is it possible to get alias work with macros?

-----

2 points by rocketnia 5118 days ago | link

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.

-----

1 point by rocketnia 5118 days ago | link

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. :)

-----

1 point by akkartik 5118 days ago | link

Link or it didn't happen :)

-----

1 point by rocketnia 5118 days ago | link

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

-----