Hi all,

Thanks to all replies, at the moment I would tend to agree that generalised
`set!` might not be such a great idea after all:

   - The notion of 'place' is essentially a pointer to a memory location,
   but it is not the first-class citizen: the following expressions are not
   equivalent: (let ((x (aref v 5))) (set! x 100)) and (set! (aref v 5) 100),
   and it might be the place for confusion.
   - The syntax part of it, `(set! (what-ever ...) new-value)`, however, I
   don't mind: `set!` is a special form/macro after all, not a procedure. No
   one would demand the procedural clarity from `let` or `define`. The
   question is rather if it worth having yet another special form.

Summarising the points above, what if instead of `set!` there is a more
general abstraction 'location': it can hold the value, the value might be
re-set, but on its own it is just a memory location. Basically, it's
Racket's `box`. But the interesting twists would be getting the locations
from mutable objects (like vectors and arrays). Something like this:

(define v (vector 0 1 2 3 4 5))

(vector-ref v 2) ;; -> 2 this gets you the value
;; Hypothetical procedure vector-loc
(vector-loc v 2) ;; -> "(boxed 2)"
(location-set! (vector-loc v 2) 200)
v ;; -> (0 1 200 3 4 5)
(let ((x (vector-loc v 3)))
   (location-set! x 300))
v ;; -> (0 1 200 300 4 5)

A quick implementation for vectors might look as follows:

#lang racket
(require racket/generic)

(define-generics location
  (location-ref location)
  (location-set! location new-value))

(struct vecloc (v ind)
  #:methods gen:location
  ((define (location-ref location) (vector-ref (vecloc-v location)
                                               (vecloc-ind location)))
   (define (location-set! location new-value)
     (vector-set! (vecloc-v location) (vecloc-ind location) new-value))))

(define (vector-loc v ind)
  (vecloc v ind))

(define v (vector 0 1 2 3 4 5))

(location-set! (vector-loc v 2) 200)

(let ((x (vector-loc v 3)))
  (location-set! x 300))

Wouldn't it resolve all the mentioned concerns? Now we can have named
locations and we don't introduce any new syntax. What I don't know is how
efficient this implementation is.


Best regards,
Alexey

On 1 July 2015 at 03:29, Matthias Felleisen <matth...@ccs.neu.edu> wrote:

>
> On Jun 30, 2015, at 6:43 PM, George Neuner wrote:
>
> > On 6/30/2015 5:34 PM, 'John Clements' via Racket Users wrote:
> >> > On Jun 30, 2015, at 8:10 AM, Alexey Cherkaev <
> alexey.cherk...@gmail.com> wrote:
> >> >
> >> > ... wouldn't it be beneficial to have such a generalised 'set!'
> system-wide? I understand that Racket focusses more on immutable
> structures, but there are still vectors and hash-tables which are
> inherently mutable and still have their niche.
> >>
> >> This style of set! seems like a bad idea to me.
> >>
> >> Specifically, one of the basic ideas of algebraic languages is that
> programs are compositional. Specifically, if I write (a (b x) c), then the
> meaning of this term depends on the meanings of a, (b x), and c. That is, I
> can combine these three values to get the result. Generalized set! breaks
> this intuition. Specifically, (set! (aref x 0 1) 13) does not depend on the
> value of (aref x 0 1). Rather, it pulls apart this term and uses its
> subterm’s meanings. Put differently, this is lvalues.
> >>
> >> I know, I know, I sound like a pure-functional snooty-poo.
> >
> > Don't confuse source syntax with what goes on under the hood - compilers
> for imperative languages often go to great lengths to transform programs
> into more "functional" forms.  Search for "value numbering" and "static
> single assignment" for more information. [Those aren't the only
> functionalizing transformations, but they are the most commonly used.]
> >
> > Moreover, assignment per se is not incompatible with composition -
> that's just semantics.  On real hardware, assignment is all you have:
> "binding" is implemented as assignment to a (possibly) new location.  Tail
> recursion is an important case of invisibly "binding" new values to the
> same locations (i.e. assigning to the control variables of an imperative
> loop).
>
>
>
> John knows these things. His advisor co-invented SSA and preached the
> imperative-compilers-are-functional while he was in grad school. I know, I
> was there and watched, and I know the guy. I am sure it all sank in.
>
> What you fail to see is that "it's just semantics" is a way of saying "why
> bother programming in languages such as Racket or ML or Coq. It's all
> assignment statements on the machine anyway." As we know from many years of
> experience of course is that this statement makes no sense to a good
> programmer. There are huge differences. And what John is getting at is that
> the language (as is) carries its meaning and its pragmatics on its sleeves.
> The very moment you introduce the kind of generalized assignment statement
> you lose this kind of clarity that comes with the language.
>
> So let's all be happy now and program in ASM. It's assignments anyway and
> LHS values are lovely for the heart-ware purist  :-)
>
> -- Matthias
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Racket Users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/racket-users/TWE4Yemx28Y/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to