[plt-scheme] %, @, ^, etc.
From: "Michael Sperber" <sperber at informatik.uni-tuebingen.de>
>
> >>>>> "Eli" == Eli Barzilay <eli at barzilay.org> writes:
>
> Eli> For list-related administrative tasks:
> Eli> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
> Eli> On Sep 8, Anton van Straaten wrote:
> >>
> >> Do combined prefix-suffix cases count?
> >>
> >> *name* => global name
>
> Eli> I think it makes more sense for global parameters.
>
> I believe this convention comes from Common Lisp, where DEFVAR has
> consequences on local uses of the same name. In Scheme, it doesn't
> really make that much sense.
I disagree. The reason `globals' are `global' is that they are visible
to large amounts of code, and modifications to them can have far-reaching
effects. In Common Lisp, you tend to dynamically-bind globals more
than you do in Scheme (aka fluid-let), but still the asterisks are a
good indication of `don't SET! this unless you realize that it might
affect a lot of things'.
vis-a-vis prefixes and suffixes:
I use a leading % sign to indicate an `unsafe' routine --- one that
doesn't check arguments, manipulates raw memory, calls out to C,
or does something squirrely. I usually have a non-% version that
checks the arguments and then calls the %-version. This is useful
when you are writing low-level, high-performance code:
;;; moves bytes from src to dest where src and dest
;;; are fixnums that represent machine addresses
(define (%move-bytes src src-start src-end dest dest-start)
.....)
(define (move-bytes src-string src-start src-end dest dest-start)
(check-type src-string string)
(check-range src-start 0 (length src-string))
....
(gc-interlock (%move-bytes (address-of src-string) src-start ....)))
So the %move-bytes function would presumably compile into a
couple of machine instructions, but it should only be called by something
that checks the safety. I'll usually have some sort of low-level
abstraction layer that hides this.
I'll put two percent signs for truly insane code:
;;; Mutate a byte-vector to a string by bashing the type code.
(define (byte-vector->string! bv)
(%%write-memory-offset bv 0 immediate-string-tag))
Two percents means `just because I did this, don't think you can get
away with it'. Or maybe `close your eyes, nothing to see here....'
Lately, I have become fond of `type/selector' notation:
(define (queue/pop! queue)
(if (queue/empty? queue)
(error "Queue is empty")
(let ((head (queue/head queue)))
(queue/set-head! queue (cdr head))
(car head))))
This turns out to be rather handy notation in a large system, but
you have to watch out and *not* do this for polymorphic operators.