I rather like the idea of having this syntax for string formatting: "name: {name:first} {name.last}".format(name)
It allows for more complex operations "name: {person.firstName} \nstart: {myEvent.startTime}".format(myEvent, person) Also, it doesn't require mundane fixes later on and keeps things simple for the developer. (No needed knowledge or maintenance of things based on position.) On Wed, Mar 9, 2011 at 15:36, Shanjian Li <shanj...@google.com> wrote: > I like this idea. I thought a lot about how to support those locale > specific stuff like plural and gender. Your suggestion provide an elegant > way to transfer the responsibility to a more appropriate party. > > shanjian > > On Wed, Mar 9, 2011 at 1:18 PM, Bob Nystrom <rnyst...@google.com> wrote: >>>> >>>> It doesn't specify how to print objects, except for %s, which says that >>>> if the argument is not >>>> a string, convert it to string using .toString(). >>> >>> If the format specifier does not apply to the argument given, it should >>> raise exceptions. Except string conversion, no other conversion will be >>> done. >> >> I like your first six points, but the formatting string stuff feels odd to >> me: neither dynamic nor object-oriented. C needs format specifiers because >> it doesn't otherwise know now to interpret the bits you give. ES doesn't >> have that problem. >> At the same time, baking a rigid set of formatting instructions into >> string.format() feels like a poor separation of concerns. string.format()'s >> just is to compose a string out of smaller pieces. Why should it need to >> know anything about numbers or dates? >> Could we just say that this: >> "hi, {0:blah}.".format(someObj); >> Is (conceptually) desugared to: >> ("hi, " + someObj.toFormat("blah") + ".") >> So anything after the ":" in an argument (the format string) gets passed >> to the object itself by way of a call to toFormat() (or some other method >> name) on it. Then each object can decide what format strings are appropriate >> for it. >> This keeps the responsibilities separate: string.format() does >> composition, and the composed object own their own formatting. It's also >> extensible: you can define your own formatting capabilities for your types >> and use them with string.format() by defining toFormat(). (By default, I >> would assume that Object.prototype.toFormat() just calls toString()). >> This, I think, helps with locale issues too. Types like Date that care >> about locale will be able to handle it themselves in their call to >> toFormat() without string.format() needing to deal with it. >> - bob >> >>> >>> >>>> >>>> The string conversion should probably use the internal ToString function >>>> instead (which works for null >>>> and undefined too). >>> >>> Agree. >>> >>>> >>>> For formats expecting numbers, it should convert the argument to a >>>> number using ToNumber. >>> >>> Probably not. As string is the thing being constructed, it make sense to >>> offer "hidden" string conversion. In my experience using this feature in >>> Python, it is within expectation and offer some convenience. Any further >>> "hidden" conversion should really be avoided. >>> >>>> >>>> Rounding is specified as "math.round(n - 0.5)" (capital M in Math?). >>> >>> Right, thanks. >>> >>>> >>>> This leaves it open whether overwriting Math.round should change the >>>> behavior of format. It probably >>>> shouldn't (i.e., again it would be better to specify in terms of >>>> internal, non-use-modifiable functions). >>> >>> Agree. >>> >>>> >>>> The rounding is equivalent to Math.floor(n) (aka round towards >>>> -Infinity), if I'm not mistaken, so why >>>> not just use that? >>> >>> In this example, 8 / (3 - 8 / 3) , the display will be 23.99999999999999. >>> So the internal representation could be a little bit more or a little bit >>> less than the theoretical value due to float precision. Math.round might >>> generate less surprise results than Math.floor. Of cause, the internal >>> implementation shouldn't rely on either of these two. >>> >>>> >>>> (Personally I would prefer truncation (round towards zero), if >>>> conversion to integer is necessary). >>>> >>>> Why can octal, binary and hexidecimal forms only be used on integers? >>>> Number.prototype.toString with >>>> an argument works on fractions too (try Math.PI.toString(13) for laughs >>>> :). >>> >>> >>>> >>>> Why only fixed bases (2,8,10,16)? How about adding an optional base >>>> parameter to number display (with >>>> x, d, o, b as shorthands for the more standard bases)? Again, >>>> Number.prototype.toString means that it's >>>> already in the language. (I know that step 7 says copy the format of >>>> other languages, but that seems >>>> shortsighted since ECMAScript is not those languages, and only copying >>>> functionality from C verbatim >>>> seems like tying your shoelaces together before the race). >>>> >>> The question for both questions is how useful is that. If it is only >>> needed in one or few rare occasions, it is probably not a good idea to >>> complicate the language. >>> >>>> >>>> "Placeholder used in format specifier part can not have format >>>> specifier. This prevent the replacement >>>> from embedding more than one level." >>>> Should that be "... can not have a placeholder."? >>> >>> No. The former prevent any format specifier (including embedded >>> placeholder). Refer to the Python specification, it does make sense. >>> >>>> >>>> If the placeholder value is not a string, it should be converted to a >>>> string. >>>> If it is not a valid format, what happens then? >>> >>> Raise exception? >>> >>>> >>>> Is the following valid: >>>> "{x} and {1[y]}".format({x:42},{y:37}) >>>> I.e., can object property shorthands ({x} instead of {0[x]}) be used if >>>> there are more than one argument? >>> >>> Good points. Possible choices: >>> 1. {x} always refer to the first object given. >>> 2. {x} only works when there is one and only one object argument. >>> 3. {x} will be replaced by the first object that has property x, ie. the >>> following should work too. >>> "{x}, {z} and {1[y]}".format({x:42}, {z:43, y:37}) >>> >>> I prefer 1. >>> >>>> >>>> And some arbitrary ideas for extension: >>>> >>>> How about a boolean test that checks for falsy-ness of the argument and >>>> acts as one of two other >>>> formats or literals? >>>> E.g. >>>> "{0:s} drew {1:?his|her} gun.".format(person.name, person.isMale) >>>> "Please press return{0:?.|{1}}".format(notCritical, " and run!") >>> >>> Interesting. In example 1, the issue is literal get into the placeholder, >>> that could make things messy. >>> >>>> >>>> Or allow computed indices? >>>> "{0[{1}][he]} drew {0[{1}][his]} >>>> gun.".format({male:{he:"He",his:"his"}, female:{he:"She",his:"her"}}, >>>> "female"); >>> >>> Allow embedded placeholder inside the field part (not the format >>> specifier part) of a placeholder is something that I will be very cautious >>> about. >>> shanjian >>> >>>> >>>> /L >>>> -- >>>> Lasse Reichstein - reichsteinatw...@gmail.com >>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss@mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> > > > _______________________________________________ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -- Adam Shannon UNI Freshman Web Developer ashannon.us _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss