On 11/04/14 16:34, Gordon Sim wrote:
In a modified version of your original code snippet:

  message.body = ['Rod', 10000001, {cat: true, donkey: 8}];

how would you indicate that this is a management related message and that therefore the numbers should always be encoded as a double? (and what about the boolean?)

That's actually a really interesting question and one that has caused me a lot of navel gazing as to how to best encode from JavaScript into the AMQP type system (going the other way is relatively easy - well longs have some interesting edge cases).

I was as bit torn, for being *explicit* about types I started off thinking about creating a raft of wrapper/boxing classes such as say proton.Data.Float, proton.Data.UnsignedInteger etc. etc. ad infinitum :-) though I'm not thinking that I'll use strings with a "literal" form instead e.g. {"Rod": "4.0f"} {"Jack": "5ul"} and so on and if I want the string 4.0f to quote it {"Rod": "'4.0f'"} that seems a reasonable approach for typed numbers in a loosely typed language and feels perhaps more natural and idiomatic than say {"Rod": new proton.Data.Float(4.0)} though clearly the latter is as explicit as it gets, but is looking closer to Java than JavaScript at that point.

I'd be interested in the thoughts of the group on this - I'm open to offers.


It's possibly more "exciting" when considering what to do by default for numbers. The "easy and obvious" thing to do would be to take JavaScript numbers and encode them as double, what I'm currently doing looks like this (still work in progress) because "easy and obvious" didn't necessarily translate in my mind to "most useful"

    } else if (Data.isNumber(obj)) {
        /**
* Encoding JavaScript numbers is surprisingly complex and has several * gotchas. The code here tries to do what the author believes is the * most intuitive encoding of the native JavaScript Number. It first * tries to identify if the number is an integer or floating point type * by checking if the number modulo 1 is zero (i.e. if it has a remainder * then it's a floating point type, which is encoded here as a double). * If the number is an integer type a test is made to check if it is a
         * 32 bit Int value. N.B. JavaScript automagically coerces floating
* point numbers with a zero Fractional Part into an exact integer so * numbers like 1.0, 100.0 etc. will be encoded as int or long here, * which is unlikely to be what is wanted. There's no easy way around this * the two main options are to add a very small fractional number or to * represent the number in a String literal e.g. "1.0f", "1.0d", "1l"
         */
        if (obj % 1 === 0) {
console.log(obj + " is Integer Type " + (obj|0));
            if (obj === (obj|0)) { // the |0 coerces to a 32 bit value.
                // 32 bit integer - encode as an Integer.
console.log(obj + " is Int ");
                this['putInteger'](obj);
            } else { // Longer than 32 bit - encode as a Long.
console.log(obj + " is Long");
                this['putLong'](obj);
            }
        } else { // Floating point type - encode as a Double
console.log(obj + " is Float Type");
            this['putDouble'](obj);
        }
    }

In other words I check if the number is an "integer like number" by checking its remainder, if it is integer like I coerce it into a 32 bit value and if that is the same as the original then it is a real integer otherwise I encode as a long. Floating point types I encode as doubles.

I think that's mostly what would be "natural" in most peoples minds, however JavaScript screws with that a bit, so to take your example

message.body = ['Rod', 10000001, {cat: true, donkey: 8}];

Those would be encoded as Integers, but unfortunately

message.body = ['Rod', 10000001.0, {cat: true, donkey: 8.0}];

Would also be encoded as Integers because JavaScript implicitly converts things that can be exactly represented as integers into integers internally. So something like this

message.body = ['Rod', "10000001.0", {cat: true, donkey: "8.0"}];

Would be needed to specify integer numbers as doubles if you see what I mean.


I'm quite torn on all of this, which is why I definitely agreed with your comment that type systems can complicate things rather :-)


Again I'd be interested in what the community thinks would be the most useful approach. The JavaScript bindings are coming on quite well in the branch (currently working on Binary data support). I've still got some tidying, adding tests and sorting out some wrinkles like the stuff above, but it's starting to look pretty decent.

Frase



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to