lyn@BASEL.AI.MIT.EDU (Franklyn Turbak) (05/04/88)
> Did anybody already think about adding ``generalized functions'' > (a la Common-Lisp's setf/defsetf feature) to Scheme? This would > eliminate the need for several primitive procedures, among them > set-car!, set-cdr!, vector-set!, and string-set!. Instead of writing > > (set-car! p 5) or (vector-set! v 10 'a) > > this would make it possible to write > > (set! (car p) 5) or (set! (vector-ref v 10) 'a) What's so great about SETF? It doesn't eliminate the *need* for the setting primitives (after all, they conceptually must still be there); it just makes it easier to remember their "names" by providing a convention for deriving the setter from the accessor. But it's easy to develop alternate naming conventions without altering Scheme. One simple convention can be carried out by simple renaming: (define set!car set-car!) (define set!cdr set-cdr!) (define set!vector-ref vector-set!) (define set!string-ref string-set!) Here the name of each setter is the name of the accessor prefixed by set! Now we can write (set!car p 5) or (set!vector-ref v 10 'a) which, except for the missing pair of parens, looks a lot like the SETF approach. And we didn't have to extend Scheme all! - Lyn -
Ram-Ashwin@cs.yale.edu (Ashwin Ram) (05/09/88)
In article <8805031911.AA04352@basel>, lyn@BASEL (Franklyn Turbak) writes: > > Did anybody already think about adding ``generalized functions'' > > (a la Common-Lisp's setf/defsetf feature) to Scheme? This would > > eliminate the need for several primitive procedures, among them > > set-car!, set-cdr!, vector-set!, and string-set!. Instead of writing > > > > (set-car! p 5) or (vector-set! v 10 'a) > > > > this would make it possible to write > > > > (set! (car p) 5) or (set! (vector-ref v 10) 'a) > > What's so great about SETF? [...] > it's easy to develop alternate naming conventions without > altering Scheme. One simple convention can be carried out > by simple renaming: > > (define set!car set-car!) [...] > > (set!car p 5) or (set!vector-ref v 10 'a) > > which, except for the missing pair of parens, looks a lot like > the SETF approach. And we didn't have to extend Scheme all! I don't know about Common Lisp's SETF, but in the T dialect of Scheme there is a difference between the two. When you write (SET (FOO ...) ...), the operation FOO can specify how it is to be set, i.e., it can handle the operation (SETTER FOO) and return a setter procedure, which then does the setting appropriately. This is not a matter of simple renaming; rather, it is a very useful programming construct which lets you define new operations and their setters within the existing syntax. For example, you could implement a two-dimensional array by defining an accessor operation (array-element A x y), where the definition of the operation would include a definition of its setter. Of course, you can do this without this feature too; it just turns out to be a nice way to program, that's all. -- Ashwin. ARPA: Ram-Ashwin@cs.yale.edu UUCP: {decvax,ucbvax,harvard,cmcl2,...}!yale!Ram-Ashwin BITNET: Ram@yalecs
gerald@umb.umb.edu (Gerald Ostheimer) (05/10/88)
Following the discussion on assignments in Scheme, and how to have them performed in subroutines, the following question strikes my mind: *** Why didn't the designers of Scheme include locations (~anonymous variables) as first-class values in the language? *** Wouldn't that fit the Scheme philosophy of orthogonality and 'first-class everything'? After all, locations are part of the denotational semantics of Scheme, so this wouldn't be much of an extension to Scheme from an abstract point of view. A variable would then be an identifier bound to a location, and we would have true constants as well, by binding identifiers to values that are not locations. All identifier bindings would then be irreversible, only locations could be updated (thus indirectly updating identifiers bound to them). If that sounds too abstract, consider the following hypothetical program fragment: (let ((x (var 1)) ; VAR creates a new location and (y 1)) ; initializes it to its argument (set! x 2) (set! x (+ val x) 2)) ; VAL looks up the current value of x (set! x (+ y 2))) ; y can't be set! and needn't be val'ed The cons function would have to create a pair of locations and initialize them to its arguments. (So that we could make sense of setcar!) We could now also write a 'swap' function as in (define (swap x y) ; actual arguments must be variables (let ((h (val x))) (set! x (val y)) (set! y h))) This would not violate the 'call by value' principle, since locations would _be_ values. First-class variables shouldn't give us any more headaches than side-effects per se. Separating constants from variables should even simplify some compiler optimizations (for the constants). For the very least, we would get rid of having to write macros or extend the syntax in order to abstract over assignments. Any takers? -- ------------------------------------------------------------------------------ Gerald "When I use a word, it means <gerald@grn.umb.edu> exactly what I want it to mean" (Humpty Dumpty, Through the Looking Glass)