Arc Forumnew | comments | leaders | submitlogin
2 points by zunz 6175 days ago | link | parent

Thanks - manually generating unique variables where needed solves the arguably biggest part of the hygiene problem.

It's then part of macro writer discipline to remember to guard your introduced names. Fair enough. If you're writing macros, you arguably should know what you're doing.

It does still leave the problem of the macro using bindings from it's expansion point rather than it's definitition point i.e. you redefine if() and the macro uses that rather than the original definition and thus behaves badly.

Admittedly, redefining core parts of the language and using macros can be a 'don't do that then' sort of thing but considering arc's focus on language exploration, I would have thought having automatic guard-rails to be 'a good thing' (TM) (which is what hygiene really is IMO i.e. avoiding suprises from idea X interacting strangely with idea Y).

I've always felt the biggest benefit of hygiene is that it makes macro writing a bit more approachable for mere mortals. But considering the audience and arc's author(s), maybe that's not worth worrying about :-)



1 point by tjr 6175 days ago | link

Yeah, it seems like, "let the programmer do whatever the want, no matter how silly it seems, because they might actually have a valid reason" drove a non-trivial amount of Arc design.

This sort of "programmer power" is similar to what you get in C. You can't redefine the language with C, but you can do some pretty nasty things if you want to. Or even if you make a subtle, honest mistake. Or even if you use C at all. ;-)

-----

1 point by kennytilton 6174 days ago | link

Mortals need not fear. Avoiding variable capture is easy albeit mildy tedious, and deliberate variable capture can be quite useful. I have seen good Schemers explaining why Scheme's macros were just as good as CL's and they convinced me they were not. :)

-----

1 point by petermichaux 6175 days ago | link

;;;;;;;;;;; the following doesn't work reliably ;;;;;;;;;;

;;; in Arc + is defined

;;; macro writers code depends on Arc's + ;;; but doesn't insure it always uses Arc's +

(mac foo () (list '+ 1 2))

;;; app writers code

(* 2 (foo)) ;;; 6

;;; app writer doesn't know foo depends on Arc's + ;;; and decides to redefine +

(= + (fn ((o x) (o y)) (prn "gotcha")))

(* 2 (foo)) ;;; error

;;;;;;;;;;;;;;;;;; the following works ;;;;;;;;;;;;;;;;;;;;

;;; in Arc + is defined

;;; macro writers code is tricky and ugly ;;; but will always use Arc's +

(= g (uniq))

(eval (list '= g '+))

(eval (list 'mac 'foo `() `(list (quote ,g) 1 2)))

;;; app writers code

(* 2 (foo)) ;;; 6

;;; redefining + doesn't affect the addtion function ;;; used in the foo macro

(= + (fn ((o x) (o y)) (prn "gotcha")))

(* 2 (foo)) ;;; 6

;;;;;;;;;;;; if foo is a function then it is easy ;;;;;;;;;;

;;; in Arc + is defined

;;; library writers code is easy because ;;; the original + can be in a closure

(= foo ((fn () (let plus + (fn () (plus 1 2))))))

;;; app writers code

(* 2 (foo)) ;;; 6

;;; redefining + doesn't affect the addtion function ;;; used in the foo function

(= + (fn ((o x) (o y)) (prn "gotcha")))

(* 2 (foo)) ;;; 6

-----