Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhancement to dynamic object #474

Open
ghost opened this issue Dec 28, 2014 · 19 comments
Open

enhancement to dynamic object #474

ghost opened this issue Dec 28, 2014 · 19 comments
Assignees
Labels
Milestone

Comments

@ghost
Copy link

ghost commented Dec 28, 2014

in javascript there are two ways to define property names in object literals one is using with quotes and other is without like this

var header = {
  date: 123,
 "Content-Type" : "text/plain"
}

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??

@gavinking gavinking added this to the 1.2 milestone Dec 28, 2014
@gavinking
Copy link
Member

Thoughts, @chochos?

@chochos
Copy link
Member

chochos commented Dec 29, 2014

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)

@gavinking
Copy link
Member

Hrm. Tricky one.

@gavinking
Copy link
Member

@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" }; ];

@gavinking
Copy link
Member

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");

@gavinking
Copy link
Member

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.

@chochos
Copy link
Member

chochos commented Jan 2, 2015

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"]

@gavinking
Copy link
Member

why not just allow quoted keys?

Grumble. because it looks like you're assigning to a string.

@chochos
Copy link
Member

chochos commented Jan 3, 2015

well, you are assigning to a string, in a way; keys in JS objects are strings...

@luolong
Copy link
Member

luolong commented Jan 5, 2015

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"; ];
  1. 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"; ];

@gavinking
Copy link
Member

@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.

@luolong
Copy link
Member

luolong commented Jan 5, 2015

What do you think of the proposals in my previous post?

@gavinking
Copy link
Member

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?

@chochos
Copy link
Member

chochos commented Jan 5, 2015

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).

@gavinking
Copy link
Member

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?

@gavinking
Copy link
Member

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.

@chochos
Copy link
Member

chochos commented Jan 5, 2015

I think it would be better to use \ as a general escape char. these i'x' are just... eww...

@luolong
Copy link
Member

luolong commented Jan 7, 2015

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?

@FroMage
Copy link
Member

FroMage commented Jan 8, 2015

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants