Speaking of Lisp...

classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

Speaking of Lisp...

P T Withington
One of our developers wondered why no scripting language has adopted  
symbols.  I replied:

> Objects have most of the features of symbols:  they are unique, you  
> can compare them for identity, you can store properties on them.  
> An object by itself is like an uninterned symbol -- you have to  
> keep a handle on it.  If you want to intern an object, you can just  
> assign it to a global variable.  So, I think what you are mostly  
> missing is the shorthand where in lisp you can write
> 
>   'foo
>
> and if the symbol already exists, you get the symbol, and if it  
> doesn't it will be created for you.
>
> It wouldn't take much to mimic that in Javascript.  Something like:
>
> class Symbol {
>   static var allSymbols = {};
>
>   function Symbol(name) {
>     if (name in Symbol.allSymbols) return Symbol.allSymbols[name];
>     this._name = name;
>     return Symbol.allSymbols[name] = this;
>   }
>
>   function toString() {
>     return this._name;
>   }
> }
>
> var _ = Symbol;
>
> Then you can write a symbol as:
>
>   _('mySymbol')
>
> Clearly, IWBNI there were a shorter hand for writing symbol  
> literals, 1 character rather than 5, but this isn't too bad is it?

Were symbols ever discussed as a possible addition?  Is there a handy  
non-symbol punctuation mark that could be co-opted?

   @mySymbol

Dylan uses:

   #"mySymbol"

(3 characters rather than 5).  Yet another use for `#`.




Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Bob Ippolito
On 1/5/07, P T Withington <[hidden email]> wrote:

> One of our developers wondered why no scripting language has adopted
> symbols.  I replied:
>
> > Objects have most of the features of symbols:  they are unique, you
> > can compare them for identity, you can store properties on them.
> > An object by itself is like an uninterned symbol -- you have to
> > keep a handle on it.  If you want to intern an object, you can just
> > assign it to a global variable.  So, I think what you are mostly
> > missing is the shorthand where in lisp you can write
> > 
> >   'foo
> >
> > and if the symbol already exists, you get the symbol, and if it
> > doesn't it will be created for you.
> >
> > It wouldn't take much to mimic that in Javascript.  Something like:
> >
> > class Symbol {
> >   static var allSymbols = {};
> >
> >   function Symbol(name) {
> >     if (name in Symbol.allSymbols) return Symbol.allSymbols[name];
> >     this._name = name;
> >     return Symbol.allSymbols[name] = this;
> >   }
> >
> >   function toString() {
> >     return this._name;
> >   }
> > }
> >
> > var _ = Symbol;
> >
> > Then you can write a symbol as:
> >
> >   _('mySymbol')
> >
> > Clearly, IWBNI there were a shorter hand for writing symbol
> > literals, 1 character rather than 5, but this isn't too bad is it?
>
> Were symbols ever discussed as a possible addition?  Is there a handy
> non-symbol punctuation mark that could be co-opted?
>
>    @mySymbol
>
> Dylan uses:
>
>    #"mySymbol"
>
> (3 characters rather than 5).  Yet another use for `#`.

Do you think that encouraging global variables would be a good thing?
I thought ES4 was trying to make them less popular.

-bob


Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

John Cowan
In reply to this post by P T Withington
P T Withington scripsit:

> One of our developers wondered why no scripting language has adopted  
> symbols.  I replied:

In Java, symbols are there under the covers, in the form of interned strings.
The trouble is that there is no way to examine a string to see if it is
interned, so people engage in a lot of String.equals where == would suffice.

--
Is a chair finely made tragic or comic? Is the          John Cowan
portrait of Mona Lisa good if I desire to see           [hidden email]
it? Is the bust of Sir Philip Crampton lyrical,         http://ccil.org/~cowan
epical or dramatic?  If a man hacking in fury
at a block of wood make there an image of a cow,
is that image a work of art? If not, why not?               --Stephen Dedalus

Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Jeff Thompson-5
In reply to this post by P T Withington
P T Withington wrote:
>   If you want to intern an object, you can just assign it
>> to a global variable.  So, I think what you are mostly missing is the
>> shorthand where in lisp you can write
>> 
>>   'foo
>>
>> and if the symbol already exists, you get the symbol, and if it
>> doesn't it will be created for you.

For Yield Prolog, I wrote my own internalize function.  (In Prolog, they call it an "atom".):

var _internalizedStrings = new Object();
// Return the unique string object that equals name.  If you always internalize the strings you use,
// then when you compare two strings, they will be the same string object and compare instantly.
function internalize(name) {
     var atomName = _internalizedStrings[name];
     if (atomName == undefined) {
         _internalizedStrings[name] = name;
         return name;
     }
     else
         return atomName;
}

This way, a string object itself is like a Lisp symbol, if you call internalize on it first.
Since Firefox 2.0, they fixed the following bug, so that == on two strings instantly checks
for two identical string objects.
https://bugzilla.mozilla.org/show_bug.cgi?id=314890

- Jeff


Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Brendan Eich-2
On Jan 5, 2007, at 5:01 PM, Jeff Thompson wrote:

> Since Firefox 2.0, they fixed the following bug, so that == on two  
> strings instantly checks
> for two identical string objects.
> https://bugzilla.mozilla.org/show_bug.cgi?id=314890

That's just an optimization, since == is defined to compute true for  
any two strings with the same ordered list of characters.

ECMA TG1 has not considered symbols.  Macros and property quotation  
facilities have been mentioned for post-ES4 work, so who knows?

Another item falling out of the ES4 spec: hashes mapping string to  
value where the mapping is not polluted by Object.prototype.  A late  
"save" may be possible, if anyone can suggest syntax.  E.g., var hash  
= #{'foo':1, 'bar':2, 'baz':3}; alert('toString' in hash) => false.  
Eek, yet another attempt to use #.

(Should these map value to value, rather than string to value?  E4X  
(ECMA 357) already introduced QName objects as identifiers, so one  
can't pretend all properties are named by strings, if one believes in  
E4X.)

/be

Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Peter Hall-2
While identifiers can be QNames, does that automatically mean that
it's useful to use QNames for hash keys? Probably not.

But, even so, I don't see a big barrier if qualified keys were
required. For QNames with non-empty namespace URI, there would be no
pollution problem and for unqualified keys you could add a prefix to
prevent collision with Object.prototype.

Something like AS3's Proxy object would mean you could encanpsulate
that implementation quite cleanly too. I'd prefer to see AS3's Proxy
and Dictionary classes added to ES4 before more strange syntax - ES4
is already filling up with a lot of new notations and concepts, that
would be unfamiliar and difficult to many existing JS/AS developers.

Peter

On 1/6/07, Brendan Eich <[hidden email]> wrote:

> On Jan 5, 2007, at 5:01 PM, Jeff Thompson wrote:
>
> > Since Firefox 2.0, they fixed the following bug, so that == on two
> > strings instantly checks
> > for two identical string objects.
> > https://bugzilla.mozilla.org/show_bug.cgi?id=314890
>
> That's just an optimization, since == is defined to compute true for
> any two strings with the same ordered list of characters.
>
> ECMA TG1 has not considered symbols.  Macros and property quotation
> facilities have been mentioned for post-ES4 work, so who knows?
>
> Another item falling out of the ES4 spec: hashes mapping string to
> value where the mapping is not polluted by Object.prototype.  A late
> "save" may be possible, if anyone can suggest syntax.  E.g., var hash
> = #{'foo':1, 'bar':2, 'baz':3}; alert('toString' in hash) => false.
> Eek, yet another attempt to use #.
>
> (Should these map value to value, rather than string to value?  E4X
> (ECMA 357) already introduced QName objects as identifiers, so one
> can't pretend all properties are named by strings, if one believes in
> E4X.)
>
> /be
> _______________________________________________
> Es4-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es4-discuss
>

Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Brendan Eich-2
On Jan 5, 2007, at 6:33 PM, Peter Hall wrote:

> While identifiers can be QNames, does that automatically mean that
> it's useful to use QNames for hash keys? Probably not.

It's not clear to me whether E4X *requires* QNames as hash keys.  One  
way of reading it (when I implemented it) says "yes".

> But, even so, I don't see a big barrier if qualified keys were
> required. For QNames with non-empty namespace URI, there would be no
> pollution problem and for unqualified keys you could add a prefix to
> prevent collision with Object.prototype.

One often wants a hash from string to value, no QNames or namespaces  
involved.

> Something like AS3's Proxy object would mean you could encanpsulate
> that implementation quite cleanly too. I'd prefer to see AS3's Proxy
> and Dictionary classes added to ES4 before more strange syntax - ES4
> is already filling up with a lot of new notations and concepts, that
> would be unfamiliar and difficult to many existing JS/AS developers.

Let's not get stuck on syntax -- I made up #{...} because I know of  
use-cases for an object initialiser where Object.prototype does not  
pollute the hash.  Whether you have to use B&D-language class-ical  
OOP, or lighter-weight JS object "literal" syntax, we can wave off  
(ok, I'm baiting/teasing a little in this sentence ;-).

Sounds like one vote for a Dictionary class.  Could you cite some  
URLs documenting Proxy and Dictionary from the Flex SDK (I'm assuming  
these are not "AS3" but "host" types).

/be


Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Peter Hall-2
Yes, they are native to the Flash Player, not AS3 in general - though
there is of course currently no practical separation...

http://livedocs.macromedia.com/flex/2/langref/flash/utils/Dictionary.html
http://livedocs.macromedia.com/flex/2/langref/flash/utils/Proxy.html

But Dictionary does not solve the pollution problem by itself, as it
still inherits from Object. You'd need to extend Proxy and
specifically handle identifiers that conflicted with members of
Object.prototype.

Peter

On 1/6/07, Brendan Eich <[hidden email]> wrote:

> On Jan 5, 2007, at 6:33 PM, Peter Hall wrote:
>
> > While identifiers can be QNames, does that automatically mean that
> > it's useful to use QNames for hash keys? Probably not.
>
> It's not clear to me whether E4X *requires* QNames as hash keys.  One
> way of reading it (when I implemented it) says "yes".
>
> > But, even so, I don't see a big barrier if qualified keys were
> > required. For QNames with non-empty namespace URI, there would be no
> > pollution problem and for unqualified keys you could add a prefix to
> > prevent collision with Object.prototype.
>
> One often wants a hash from string to value, no QNames or namespaces
> involved.
>
> > Something like AS3's Proxy object would mean you could encanpsulate
> > that implementation quite cleanly too. I'd prefer to see AS3's Proxy
> > and Dictionary classes added to ES4 before more strange syntax - ES4
> > is already filling up with a lot of new notations and concepts, that
> > would be unfamiliar and difficult to many existing JS/AS developers.
>
> Let's not get stuck on syntax -- I made up #{...} because I know of
> use-cases for an object initialiser where Object.prototype does not
> pollute the hash.  Whether you have to use B&D-language class-ical
> OOP, or lighter-weight JS object "literal" syntax, we can wave off
> (ok, I'm baiting/teasing a little in this sentence ;-).
>
> Sounds like one vote for a Dictionary class.  Could you cite some
> URLs documenting Proxy and Dictionary from the Flex SDK (I'm assuming
> these are not "AS3" but "host" types).
>
> /be
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Chris Double
In reply to this post by Brendan Eich-2
On 1/6/07, Brendan Eich <[hidden email]> wrote:
> Sounds like one vote for a Dictionary class.  Could you cite some
> URLs documenting Proxy and Dictionary from the Flex SDK (I'm assuming
> these are not "AS3" but "host" types).

A Dictionary class would be useful I think. Looking around the web for
'javascript associative arrays' will show quite a few hits where
people have hit the problem of objects in the prototype being picked
up without them realising this would happen.

Although 'hasOwnProperty' can be used to avoid this it doesn't work in
all cases. For example, in Firefox all objects return true for
hasOwnProperty('__proto__'). So using an object as a Dictionary has to
handle issues like this.

Chris.
--
http://www.bluishcoder.co.nz

Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Brendan Eich-2
On Jan 5, 2007, at 6:59 PM, Chris Double wrote:

> Although 'hasOwnProperty' can be used to avoid this it doesn't work in
> all cases. For example, in Firefox all objects return true for
> hasOwnProperty('__proto__').

Indeed, __proto__ appears to be a property of every object in  
SpiderMonkey.  It's "DontEnum" in ECMA terms, so it does not pollute  
for-in loops, but it's still a hazard reduced in risk only by the __  
bracketing.

> So using an object as a Dictionary has to
> handle issues like this.

Suppose ES4 adds a Hash or Dict class.  Would there be demand for  
initialiser syntax, because a common use-case is a constant or pre-
filled (whether mutated later or not) mapping?

Any thoughts on value vs. string key?  Surveying real pages, even if  
skimmed by a search such as 'javascript associative arrays', is a  
good idea.  More detail?

/be


Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

P T Withington
In reply to this post by Brendan Eich-2
On 2007-01-05, at 20:14 EST, Brendan Eich wrote:

> ECMA TG1 has not considered symbols.  Macros and property quotation  
> facilities have been mentioned for post-ES4 work, so who knows?

That would suffice.

> Another item falling out of the ES4 spec: hashes mapping string to  
> value where the mapping is not polluted by Object.prototype.  A  
> late "save" may be possible, if anyone can suggest syntax.  E.g.,  
> var hash = #{'foo':1, 'bar':2, 'baz':3}; alert('toString' in hash)  
> => false.  Eek, yet another attempt to use #.

Since you can't build a pure hash in Javascript, this would be a  
_highly_ desirable addition.  Naive use of Object for hash has been  
the source of a number of subtle bugs in our code.  One might even be  
so bold as to make Hash the primitive and Object inherit from it?

We would have many uses for Hash in our code base.  I have defined a  
dictionary class that I use for some cases, but often have had to  
trade correctness for performance.

A literal syntax would not be that important if you could have a  
constructor with named arguments.  (Because the constructor's  
`arguments` property would be a Hash?)  It would also be useful to  
have a constructor that constructed a new hash from an existing one.

> (Should these map value to value, rather than string to value?  E4X  
> (ECMA 357) already introduced QName objects as identifiers, so one  
> can't pretend all properties are named by strings, if one believes  
> in E4X.)

value -> value would be a bonus that I would greatly appreciate, but  
then won't you need to define a protocol for extending hash-code  
computation and `===`?

Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

John Cowan
In reply to this post by Brendan Eich-2
Brendan Eich scripsit:

> Suppose ES4 adds a Hash or Dict class.  Would there be demand for  
> initialiser syntax, because a common use-case is a constant or pre-
> filled (whether mutated later or not) mapping?

That could be avoided by having Dictionaries which wrap Objects (literal
or otherwise) and provide get, put, delete methods on the wrappee.

--
John Cowan  [hidden email]  http://ccil.org/~cowan
The competent programmer is fully aware of the strictly limited size of his own
skull; therefore he approaches the programming task in full humility, and among
other things he avoids clever tricks like the plague.  --Edsger Dijkstra

Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Jeff Thompson-5
In reply to this post by Brendan Eich-2

Brendan Eich wrote:
 > Suppose ES4 adds a Hash or Dict class.  Would there be demand for
 > initialiser syntax, because a common use-case is a constant or
 > pre-filled (whether mutated later or not) mapping?
 >
 > Any thoughts on value vs. string key?

I'm not sure if this is what you're asking, but Python, Java, etc. let
you override the hash function that is used for hash maps.
And this of course lets you create hash keys other than a string.
Does/will ES4 let you override the hash function and would that address the problem?


Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Chris Hansen-5
In reply to this post by Chris Double
(thinking out loud)

One way to circumvent the syntax issue could be to allow maps as part
of function calls -- like a combination of varargs and keyword
arguments:

function foo(x, y, arg_map) { return x + y + arg_map.a + arg_map.b }
foo(1, 2, a: 1, b: 2)

The compiler can recognize the map arguments and turn the method call
into this at compile time:

foo(1, 2, #{'a': 1, 'b': 2})

Then you could make a Hash or Dict using a built-in method call or a
constructor: "new Hash(foo: 1, bar: 2)" or "hash(foo: 1, bar: 2)".
It's a bit heavy syntactically but one advantage of this over a
dedicated syntax is that  people can add their own map types: "new
PrefixTree(wip: 1, wap: 2)".

Just a thought.


-- Chris

On 1/6/07, Chris Double <[hidden email]> wrote:

> On 1/6/07, Brendan Eich <[hidden email]> wrote:
> > Sounds like one vote for a Dictionary class.  Could you cite some
> > URLs documenting Proxy and Dictionary from the Flex SDK (I'm assuming
> > these are not "AS3" but "host" types).
>
> A Dictionary class would be useful I think. Looking around the web for
> 'javascript associative arrays' will show quite a few hits where
> people have hit the problem of objects in the prototype being picked
> up without them realising this would happen.
>
> Although 'hasOwnProperty' can be used to avoid this it doesn't work in
> all cases. For example, in Firefox all objects return true for
> hasOwnProperty('__proto__'). So using an object as a Dictionary has to
> handle issues like this.
>
> Chris.
> --
> http://www.bluishcoder.co.nz
> _______________________________________________
> Es4-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es4-discuss
>

Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Peter Hall-2
In reply to this post by Brendan Eich-2
On 1/6/07, Brendan Eich <[hidden email]> wrote:

> On Jan 5, 2007, at 6:59 PM, Chris Double wrote:
>
> > Although 'hasOwnProperty' can be used to avoid this it doesn't work in
> > all cases. For example, in Firefox all objects return true for
> > hasOwnProperty('__proto__').
>
> Indeed, __proto__ appears to be a property of every object in
> SpiderMonkey.  It's "DontEnum" in ECMA terms, so it does not pollute
> for-in loops, but it's still a hazard reduced in risk only by the __
> bracketing.
>

It's also "DontDelete". It's not ReadOnly though, but setting it to
null probably isn't enough.

Irrelevent, but I think interesting, in ActionScript 1 and 2 there is
a bug which means you can create an object without a __proto__ by
using o=Object() instead of o=new Object(). But AS1+2 let you toggle
the DontDelete flag anyway, with undocumented functions.

Peter

Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

zwetan-3
In reply to this post by Brendan Eich-2
On 1/6/07, Brendan Eich <[hidden email]> wrote:
...
>
> Sounds like one vote for a Dictionary class.  Could you cite some
> URLs documenting Proxy and Dictionary from the Flex SDK (I'm assuming
> these are not "AS3" but "host" types).
>

and another vote here :)

most wanted AS3 class I would want to see native in ES4 are:
flash.utils.ByteArray
flash.utils.Dictionary
flash.utils.Proxy

and btw Tamarin already have these (in the shell, not the core language)

ByteArray
\mozilla\js\tamarin\shell\ByteArray.as
\mozilla\js\tamarin\shell\ByteArrayGlue.cpp
\mozilla\js\tamarin\shell\ByteArrayGlue.h

and Dictionnary
..\mozilla\js\tamarin\extensions\Dictionary.as
..\mozilla\js\tamarin\extensions\DictionaryGlue.cpp
..\mozilla\js\tamarin\extensions\DictionaryGlue.h


Concerning flash.utils.Proxy
its features should be combined imho with the intrinsic namespace
http://developer.mozilla.org/es4/spec/chapter_5_names.html#intrinsic_namespace
and the catchalls
http://developer.mozilla.org/es4/proposals/catchalls.html


so concerning the hash and overriding of hash
I would like to be able to do something like that in ES4

  class Foobar {
    . . .
    public function hash():uint {
      var seed:uint ^= propA.hash();
           seed       ^= propB.hash();
      return intrinsic::hash( seed );
    }
  }


with that logic
function intrinsic::hash( seedvalue ):uint, the non-overridable
universal hash method call.
function hash( seedvalue ):uint, the hash method call

hope that make sens ?

zwetan

Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Rob Sayre-2
In reply to this post by Chris Double
On 1/5/07, Chris Double <[hidden email]> wrote:
>
> A Dictionary class would be useful I think. Looking around the web for
> 'javascript associative arrays' will show quite a few hits where
> people have hit the problem of objects in the prototype being picked
> up without them realising this would happen.

I also think a Dictionary or Record type would be useful, and a
convenient literal initializer would be nice. Round-tripping creates
further problems:

http://people.mozilla.com/~sayrer/2007/02/02/hasOwnProperty.html

Any application that uses untrusted input is at risk here.

- Rob

Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Yuh-Ruey Chen
>
> Another item falling out of the ES4 spec: hashes mapping string to  
> value where the mapping is not polluted by Object.prototype.  A late  
> "save" may be possible, if anyone can suggest syntax.  E.g., var hash  
> = #{'foo':1, 'bar':2, 'baz':3}; alert('toString' in hash) => false.  
> Eek, yet another attempt to use #.

Would this new hashtable class derive from Object? If not, then in
strict mode, would the following work (using #{} as the hashtable syntax)?

var x: Object = #{'foo':1};

Reply | Threaded
Open this post in threaded view
|

Re: Speaking of Lisp...

Lars T Hansen-2
On Feb 4, 2007, at 3:00 PM, Yuh-Ruey Chen wrote:

>>
>> Another item falling out of the ES4 spec: hashes mapping string to
>> value where the mapping is not polluted by Object.prototype.  A late
>> "save" may be possible, if anyone can suggest syntax.  E.g., var hash
>> = #{'foo':1, 'bar':2, 'baz':3}; alert('toString' in hash) => false.
>> Eek, yet another attempt to use #.
>
> Would this new hashtable class derive from Object?

I think it could in principle, though it would violate the Object  
protocol the way we currently understand it (no toString / valueOf  
properties on the prototype object).  So we would have to finesse the  
use of those methods in the spec.

--lars

> If not, then in
> strict mode, would the following work (using #{} as the hashtable  
> syntax)?
>
> var x: Object = #{'foo':1};
> _______________________________________________
> Es4-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es4-discuss