Re: [MIT-Scheme-devel] Keywords

2010-03-19 Thread Joe Marshall
> On Tue, Mar 16, 2010 at 2:45 PM, Matt Birkholz
>  wrote:
>>
>>
>>    (make-sumpn :color: "red")
>>
>> Sorry.  Not the last one?  ?
>
> Ok, I'll fix that.

Fixed, sort of.  I have removed the `both' option because I
couldn't clearly describe what it was supposed to do.

I have fixed the escaping of keywords to be just like SRFI-88
describes:
  In other words, in such implementations, |foo|: and foo: are
  the same keyword, and |foo:| is a symbol, not a keyword,
  and ||: is a keyword.


1 ]=> (set! *keyword-style* 'suffix)
;Value: #f

1 ]=> |foo|:
;Value 12: foo:

1 ]=> (keyword? |foo|:)
;Value: #t

1 ]=> (eq? foo: |foo|:)
;Value: #t

1 ]=> |foo:|
;Unbound variable: foo:
;To continue, call RESTART with an option number:
; (RESTART 3) => Specify a value to use instead of foo:.
; (RESTART 2) => Define foo: to a given value.
; (RESTART 1) => Return to read-eval-print level 1.

2 error> (restart 1)
;Abort!

1 ]=> (symbol? '|foo:|)
;Value: #t

1 ]=> (symbol? ||:)
;Value: #f

1 ]=> (keyword? ||:)
;Value: #t

1 ]=> (keyword? :color:)
;Value: #t

1 ]=> (keyword->string :color:)
;Value 13: ":color"

1 ]=> (transcript-off)


I have also restricted the value of *keyword-style* to be either
'prefix, 'suffix, or #f.


BTW:  I'd like to keep this as an `internal' feature until I figure
out the best way to control it.  I don't mind if people want to
play with it, but they should expect the `keyword-style' switch
to change and some other details to change for a bit until I
iron this out.  No guarantees of stable behavior, but I'd love
feedback from users.


-- 
~jrm


___
MIT-Scheme-devel mailing list
MIT-Scheme-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/mit-scheme-devel


Re: [MIT-Scheme-devel] Keywords

2010-03-19 Thread Joe Marshall
>> From: Taylor R Campbell 
>> Date: Tue, 16 Mar 2010 02:23:51 -0400
>>
>> What advantage does a disjoint data type have over writing (foo
>> 'bar: baz 'quux: zot)?  [It] strikes me as needless complication to
>> the language.

I agreed with you for very many years, but a few years back I changed
my mind.  I'll try to show you why.

>> Using keyword objects rather than (non-keyword) symbols as the
>> arguments to keyword parameters makes sense in Common Lisp only
>> because of its package system.

It certainly arose that way.

The package system started out as a hack
to allow different unrelated Lisp applications to share the same image
without interfering with each other.  The problem is that symbols are
heavily overloaded in old lisp systems.  In the earliest lisp, a
symbol had an associated `property list' which stored everything you
needed to know about a symbol.  This even included the symbol's
`value' property and possibly its `subr' property (function cell).
In this model, a symbol is actually a named set of mappings.  The name
itself had no ontological significance (it was stored as the 'pname'
property), it was just a way of getting ahold of the mapping set.

Two different systems would likely make different uses of the
properties of a symbol, so trying to load two different systems into
the same image wouldn't work.  The root cause of this problem is very
tricky to understand, and I'll get to it in a moment, but the
`obvious' problem appears to be one of aliasing:  both System `A' and
System `B' refer to symbol `foo', but they aren't referring to the
*same thing*.  The obvious solution is to give each system a private
symbol.  Symbols were interned in the obarray, so a hack that
allowed you to use multiple obarrays and switch between them was
created.  The `multiple obarray hack' was the precursor to the
`package system'.

Although the value and function cells of symbols are firmly
entrenched, there has been a shift away from the practice of using
property lists.  When a symbol is used only as a key in a table, there
is less need for collision avoidance.  On the other hand, there is an
immediate problem that the symbol 'foo' in package A is *not* the
symbol 'foo' in package B, even though they look the same.  The
keyword package comes to the rescue.  Keywords are good as `symbolic
keys' because they *don't* have values, functions, or properties.  You
can use them freely without worrying about collisions.

So keywords arose as a solution to a problem that was an unintended
effect of a solution to an unrelated problem.

-

Earlier I mentioned that the root cause of the problem was tricky to
understand.  The cause isn't really one of aliasing unrelated symbols,
the cause is a misunderstanding of naming.  (Unfortunately, I haven't
found a good authority on the issues of naming, so I'm going to fly by
the seat of my pants here.)

Abstractly, we want to be able to refer to objects by names.  We do
this by establishing a `context' where names are associated with
values.  The minimal requirement is that the `name' can be an
arbitrary sort of thing (like the word "foo") and that the `context'
is what provides the mapping.  We also desire that the mapping is
relatively static unless told otherwise.

We do this *all the time* in computer science.

The root cause of `symbol collision' is that early lisps were
confused.  A `symbol' in these lisps is not a name at all, but a very
complex sort of beast.  At a very early phase in interpreting a
program, a symbolic token (like what a user types) is mapped to a
`symbol object' via the obarray.  Further interaction with the symbol
is mediated through the `property list'.  A picture of this would sort
of look like this:


  obarray   plist
symbolic token >   Symbol ---X> Value
 ^
 |
  Symbol

So a symbol *itself* is really a function from another symbol to a
value.  This part of the picture:


plist
-X> Value
 ^
 |
   Symbol

But that is a terrible idea.  What you *want* is the *other* half of
the picture:

obarray
  symbolic token >  Symbol >---


And the `symbolic token -> Symbol' mapping via the obarray can be
considered an implementation detail of the reader, we just want this
part:

   Symbol >

which, when we later supply a context becomes

context
   Symbol >-> Value

The keyword package in Common Lisp accomplishes this by essentially
erasing the components of a symbol that are causing the problems and
using the remaining shell as a stand-in for the conceptual symbol.
(This last step is beautiful kludge.  The original idea of a symbol
had all these bells and whistles, but if we plug these h