Open ghost opened 9 years ago
Thoughts, @chochos?
It's true, those are valid keys in js. But they're only accessible with k[v] syntax. We'd need syntax not only to create objects with those keys, but also to read and assign them (can't remember right now what we do with k[v] when k is native, but that's easu; the problem is there's no o[k]=v syntax in ceylon)
Hrm. Tricky one.
@chochos So I think the simplest solution would be to just add putAttribute()
and getAttribute()
methods to Object.prototype
, so that the above code could be written as:
dynamic header = dynamic [ date = 123; ];
header.putAttribute("Content-Type", "text/plain");
We could even support the following, in addition to putAttribute()
and getAttribute()
:
dynamic header = dynamic [ date = 123; attributes = { "Content-Type"->"text/plain" }; ];
Or instead of putAttribute()
and getAttribute()
, we could add an attributeMap
attribute to Object.prototype
, letting you transform any JS object to a Ceylon Map<Object,Anything>
.
dynamic header = dynamic [ date = 123; ];
header.attributeMap.put("Content-Type", "text/plain");
Of course, I guess the natural syntax for this would be:
dynamic header = dynamic { date = 123; "Content-Type" -> "text/plain", "Content-Length" -> 348 ];
String contentType = header["Content-Type"];
That would require a language change, but it's doable. We would have dynamic { ... }
and dynamic [ ... ]
with slightly different semantics.
The attributeMap
wouldn't work because put
is not a method of native JS objects. We'd have to transform the put
call into o[k]=v
since that's the only way to add properties to a native JS object, but that would make it a nuisance to call a real put
method in JS objects (have to call it as o.\iput(...
).
I don't see why we need to add a different syntax with entries to the dynamic
objects; why not just allow quoted keys? dynamic[date=123; "Content-Type"="bla", "foo-bar"="baz"]
why not just allow quoted keys?
Grumble. because it looks like you're assigning to a string.
well, you are assigning to a string, in a way; keys in JS objects are strings...
This actually begs for a question if we need syntax in Ceylon for addressing weird identifiers.
Some languages (Groovy for example), allow defining your method names in double quotes, allowing all kinds of weird and groovy names that can contain whitespace, special characters and unicode symbols not otherwise allowed for identifiers.
This is sometimes quite neat; for example when writing test cases, you can write very descriptive method names, that read well later in the test reports...
In any case, this issue is just one of these cases that shows how we need this for interop with other languages that are more liberal with identifier names than Java or Ceylon.
So I have two potential ideas of how this would work:
1) Have special quoting around the identifier, that allows use of non-identifier characters:
dynamic header = dynamic [date = 123, \i'Content-Type' = "text/plain"; ];
2) Just add a way to escape characters in the identifier with a backslash. Uglier, but I think that if the goal is to allow referencing identifiers from another language, then making those identifiers look nice is a non-goal any way...
dynamic header = dynamic [date = 123, \iContent\-Type = "text/plain"; ];
@luolong This is a good point. The issue is, as always, whether we can think of any non-disgusting syntax for this, now that we've already used all the reasonable quote characters for other things.
What do you think of the proposals in my previous post?
What do you think of the proposals in my previous post?
I'm not sure I do think anything yet. I guess the second one might be on the right track.
What would be wrong with simply Content\-Type
?
I don't see anything wrong with Content\-Type
but does this mean \ will be a general escape character? Because in JS you can have any char as a property name: a.b
, a,b
, a-b
, a;b
, a!b
, a$b
, a?b
etc are all valid property names (although most are only accesible via o[k]
syntax).
I don't see anything wrong with
Content\-Type
but does this mean \ will be a general escape character?
Wellyeah, I suppose, is there some reason why it wouldn't work?
Another option that might work could be to deprecate \ifoo
and \Ifoo
and use:
i\Content-Type\
or
i'Content-Type'
or even
i`Content-Type`
Though we already use backticks for too many things.
I think it would be better to use \ as a general escape char. these i'x'
are just... eww...
What would be wrong with simply
Content\-Type
?
Nothing, except that if Content-Type
is a name for a field/method of an object, then \i
prefix is mandated by Ceylon language rules.
I actually quite like the backslash escape syntax. This way I can write a method name like this
shared object windowsFolders {
shared String \iProgram\ Files = "Program Files";
}
And it would actually look rather clean...
Another question is -- what it would be escaping? Same rules as within String
literal?
I personally think we should deprecate \i
and friends, especially if we use them for non-interop, and go away from single letters and use something like type::foo
or value::'Content-Type'
or something similar. Using backslash is confusing and repetitive for names like Content-Type-Negociation-Timeout
where we'd have to use many. Quoting is clearer to read, and full names makes it way less cryptic. But all this is a discussion that belongs in spec.
in javascript there are two ways to define property names in object literals one is using with quotes and other is without like this
in ceylon i can't create this object because of this second property.There is heavy usage of this type of property in nodejs app since most of http header names have "-" in between them like "content-length" i tried this but not working
dynamic header = dynamic [date = 123, "Content-Type" = "text/plain"; ];
is there any way??