All good points. I should also mention that formlets do this automatically, which is why you don't name the fields when using formlets.
Jay On Sun, Jul 31, 2011 at 11:08 PM, Neil Van Dyke <n...@neilvandyke.org> wrote: > You are correct that it is effectively black magic, in that you probably > don't need to know about it right now. Only a small percentage of Racket > programmers will ever need to know about it. > > When you look at the "reference/symbols.html" page of Racket documentation, > pretend that you don't see anything other than "symbol?", "string->symbol", > and "symbol->string". You will probably use those three procedures a lot, > and you will probably never need to use anything else on that page. > > I suggest making your own somewhat "gensym"-like procedure, tailored to your > needs. If you're, say, generating symbols that must be unique only within a > single generated Web page, write your own procedure to support doing exactly > that. In this procedure, you will naturally use "string->symbol", and > consequently procedures like "eq?", "memq", and "assq" will simply work like > you'd expect (no black magic). As an example, here's one utility procedure > you might write, which itself produces a "gensym"-like procedure that you > can use in the context of, say, generating a single Web page: > > ;; Definition of your utility procedure: > (define (make-serially-numbered-symbol-maker prefix-string) > (let ((serial-number 0)) > (lambda () > (let ((last-serial-number serial-number)) > (set! serial-number (+ 1 serial-number)) > (string->symbol (string-append prefix-string > (number->string > last-serial-number))))))) > > ;; Example use of that utility procedure: > (let ((my-make-symbol (make-serially-numbered-symbol-maker "foo-"))) > (list (my-make-symbol) > (my-make-symbol) > (my-make-symbol))) > ;;==> '(foo-0 foo-1 foo-2) > > If a procedure that produces new procedures seems a little too fancy-pants > right now, you can do a similar thing in a block of your code that needs the > symbols made, without the part about producing a procedure. The nice thing > here about a procedure that produces a new procedure is that it's a good way > to put this code into a reusable library, rather merely having a code > pattern that you retype or copy&paste every time you need to do a similar > thing. > > Esoterica #1: If you wanted the produced symbol maker (in the example above, > a particular "my-make-symbol" value) to be callable from multiple threads > simultaneously, then the code should be modified to use a semaphore, so that > the setting of "last-serial-number" and the incrementing of "serial-number" > happens in a mutex block. (The "string->symbol" part could be left out of > the mutex block, to increase parallelism.) But you probably don't want to > be calling the same "my-make-symbol" from multiple threads simultaneously, > anyway, so I didn't complicate this illustration with a semaphore. > > Esoterica #2: You'll see functions like "gensym" and "gentemp" in some old > Lisp dialects, and they will be used mostly to get around problems of > non-hygienic macros in that particular dialect. I don't recall seeing them > used in real Racket or Scheme code, however, probably because those > languages have hygienic macros. > > Estoterica #3: In some Lisp dialects (not Racket), interned symbols are not > garbage-collected, so, if you tried to generate unique symbols infinite > numbers of times in a run of a program, *eventually* they might want to take > up more space than can be represented by your computer and then by the > universe. > > -- > http://www.neilvandyke.org/ > _________________________________________________ > For list-related administrative tasks: > http://lists.racket-lang.org/listinfo/users > -- Jay McCarthy <j...@cs.byu.edu> Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users