pierce@CS.UCLA.EDU (05/07/88)
In reply to David Chin about "set in Scheme". I'd have to agree with Pavel that it's better to recode without passing around different symbols. However, there's a lot of code out there, UCILISP for natural language processing for example, which uses "set" all over the place. If you just want to get some simple examples from a text or article running, you may not consider it worth your time to recode everything; fortunately the problems described by Pavel may not be that critical either for this type of code. If so, why not just forget about elegance for a little while and save yourself some trouble. Just hack out a horrible little ugly macro like the following: (macro set (lambda (e) `(eval ,`(set! ,(eval (cadr e)) ,(caddr e))))) But I don't think I'd be "sticking my neck out" by saying that THIS doesn't adhere to the "Scheme philosophy", so I would use it only in emergencies. -- Brad Pierce <pierce@cs.ucla.edu>
pierce@CS.UCLA.EDU (05/08/88)
Sorry about the last message, I wrote the set macro down a little too fast and it clearly won't work as intended. I meant to say something like this: (macro set (lambda (e) (list 'eval (list 'list ''set! (list 'eval (list 'quote (cadr e))) (list 'quote (caddr e)))))) Then if you (define a 's) (define s 'any) (define b 'r) the effect of (set a b) should be to assign the value r to s. So far so good. But what about this function? (define foo (lambda (x y) (set x y))) If we (define s 'any) then the effect of (foo a b) is the same as above. Judging by my last posting, this may not be perfect either, but at least it's a lot closer. I'd be interested in seeing a shorter or better solution. Thanks for your patience. -- Brad Pierce <pierce@cs.ucla.edu>
crabb@phoenix.Princeton.EDU (David W Crabb) (05/10/88)
Dybvig's extend-syntax is a natural for your problem: (extend-syntax (set) ( (set x y) (set! x y) )) -- David
manis@faculty.cs.ubc.ca (Vincent Manis) (05/10/88)
Well, putting my radical hat on, not only is set evil, but also set!. Only non-destructive programming practices are safe, and everything else inevitably leads to disaster. But back here in the real world, one occasionally wants global variables. Those you can have via set! and define. I guess the frequency with which I use set in Lisp can be best judged by the fact that I hadn't realised it was absent in Scheme until reading the original posting on this subject. There are good reasons for omitting it. First of all, set makes programs opaque in that one has no idea which variable is getting modified. More to the point, Scheme dispenses with value cells, so implementing set would be non-trivial in most Schemes (though Chez Scheme's "boxes" might make it easier). My eyes glaze over when I see two levels of backquote in a macro definition, so I don't know how effective the posted solution is. However, my choice is the humble property list. Still not terribly structured, but efficiently implemented and a bit more modular (different bits of code can use plists without interfering, so long as they use different pnames). Of course, the *right* way to do this is probably a hash table or tree... Vincent Manis | manis@cs.ubc.ca The Invisible City of Kitezh | manis@cs.ubc.cdn Department of Computer Science | manis@ubc.csnet University of British Columbia | {ihnp4!alberta,uw-beaver,uunet}! <<NOTE NEW ADDRESS>> | ubc-cs!manis
dorai@titan.rice.edu (Dorai Sitaram) (05/10/88)
Here's my invaluable ;-) comment about _set_ in Scheme. As it is fairly easy to build up a case for loss of program readability with the addition of _set_ (as opposed to _set!_), we should perhaps be pleased that it is probably impossible (with macros, extend-syntax, what-not) to define _set_ in Scheme. The most "correct" version of _set_ in terms of _set!_ given on the net, (herein transliterated to extend-syntax) is probably (extend-syntax (set) [(set x y) (eval (list 'set! x (quote y)))]). However, Scheme does not offer 'eval' to the user. The most it does is offer a *global* eval, which ain't the same thing. So, (define x 0) ==> x (define y 'x) ==> y (let ([x 1]) (let ([y 'x]) (set y 2) x)) ==> 1 {instead of 2} x ==> 2 {instead of 0} Continuing { with global x = 2, y = x } (define z 3) ==> z (let ([z 4]) (set y z) x) ==> 3 {instead of 4} The second problem can be appeased by evaluating the settend (to coin a word) beforehand as in, (extend-syntax (set) [(set x y) (begin (set! |weird-identifier| y) (eval (list 'set! x (quote |weird-identifier|))))]) {|weird-identifier| HAS to be a global variable, because of the globalness of eval.} But the first problem remains. A modified version of the second problem can occur if there are _set_'s inside the settee (to coin a not-so-new word), as in (set (set <blah> <foo>) <hukares>) Any amount of tweaking the extend-syntax for set, seems destined to lead nowhere. That, as they (and Magnum) say, is "the hell of it". --dorai