Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #21148 > unrolled thread
| Started by | kj <no.email@please.post> |
|---|---|
| First post | 2013-09-02 20:23 +0000 |
| Last post | 2013-09-02 23:10 +0200 |
| Articles | 7 — 4 participants |
Back to article view | Back to comp.lang.javascript
(golf-ish) Conditional object property access kj <no.email@please.post> - 2013-09-02 20:23 +0000
Re: (golf-ish) Conditional object property access Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-09-02 21:52 +0100
Re: (golf-ish) Conditional object property access Stefan Weiss <krewecherl@gmail.com> - 2013-09-02 23:11 +0200
Re: (golf-ish) Conditional object property access Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-09-03 00:03 +0200
Re: (golf-ish) Conditional object property access Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-09-02 23:19 +0100
Re: (golf-ish) Conditional object property access Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-09-03 01:59 +0200
Re: (golf-ish) Conditional object property access Stefan Weiss <krewecherl@gmail.com> - 2013-09-02 23:10 +0200
| From | kj <no.email@please.post> |
|---|---|
| Date | 2013-09-02 20:23 +0000 |
| Subject | (golf-ish) Conditional object property access |
| Message-ID | <l02s3s$fdt$1@reader1.panix.com> |
(WARNING: This is a "JavaScript golf"-type query, of little practical
import; just for those who get into this sort of thing...)
Quick version
=============
How to shorten the generic JavaScript expression
o.hasOwnProperty('p') ? o.p : <EXPR>
...while still preserving the *conditional* evaluation of the <EXPR>
clause? (Here <EXPR> stands for an arbitrary JavaScript
expression.)
----------------------------------------------------------------------
Leisurely version
=================
I'm dealing with JavaScript code where expressions having the form
above appear *all over*.
Given the frequency of this pattern, it would be nice if JS had
some special, and more succinct, syntax for it, e.g., something
like:
o['p':<EXPR>]
...where the <EXPR> "clause" would be evaluated (and returned as the
value of the whole expression) *only if* o.hasOwnProperty('p') is
false[1].
Absent such syntactic help, how can one shorten the pattern given
above?
The best that my noob-level JS can come up with is to define a helper
function `HAS` (in a suitably restricted scope) to replace the verbose
built-in hasOwnProperty, so that one can at least write:
HAS(o, 'p') ? o.p : <EXPR>
At the end of this post I give other alternatives I could think of,
but they are all either *more* verbose than what they try to replace,
or have some other weakness (e.g. failure to delay the evaluation of
the <EXPR> clause).
For the more expert JS coders out there: can one do better?
----------------------------------------------------------------------
Below are my various attempts:
o.hasOwnProperty('p')?o.p:<EXPR> // the one to beat
o['p':<EXPR>] // hypothetical/theo-
// retical minimum?
HAS(o,'p')?o.p:<EXPR> // my disappointing best
GET(o,'p',<EXPR>) // <EXPR> evaluated
// unconditionally
GET2(o,'p',function(){return <EXPR>}) // ambiguous when the
// value of o.p may be
// a function
GET3(o,'p',T(function(){return <EXPR>})) // T for Thunk
function HAS(obj, prop) {
return obj.hasOwnProperty(prop);
}
function GET(obj, prop, alt) {
return HAS(obj, prop) ? obj[prop] : alt;
}
function GET2(obj, prop, alt) {
return HAS(obj, prop) ? obj[prop] : alt();
}
function Thunk (fn) { this.fn = fn }
function T(fn) { return new Thunk(fn) }
function GET3(obj, prop, alt) {
return HAS(obj, prop) ? obj[prop] :
alt instanceof Thunk ? alt.fn() : alt;
}
----------------------------------------------------------------------
[1] The "delayed", or, more precisely, *conditional*, evaluation of
the <EXPR> clause is an important aspect of the original
expression's semantics, and is therefore one that any alternative
formulation should retain. I point this out because the first
alternative formulation that I came up with, the one using the
helper function `GET`, turns out to fall short in this respect.
[toc] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2013-09-02 21:52 +0100 |
| Message-ID | <0.c54068976de565cd12fc.20130902215206BST.877gezuetl.fsf@bsb.me.uk> |
| In reply to | #21148 |
kj <no.email@please.post> writes:
> (WARNING: This is a "JavaScript golf"-type query, of little practical
> import; just for those who get into this sort of thing...)
>
>
> Quick version
> =============
>
> How to shorten the generic JavaScript expression
>
> o.hasOwnProperty('p') ? o.p : <EXPR>
>
> ...while still preserving the *conditional* evaluation of the <EXPR>
> clause? (Here <EXPR> stands for an arbitrary JavaScript
> expression.)
<snip>
> The best that my noob-level JS can come up with is to define a helper
> function `HAS` (in a suitably restricted scope) to replace the verbose
> built-in hasOwnProperty, so that one can at least write:
>
> HAS(o, 'p') ? o.p : <EXPR>
If HAS returns o.p when o.hasOwnProperty('p'), then you can avoid the
conditional
HAS(o, 'p') || <EXPR>
Anything that uses functions to wrap EXPR for delayed execution suffers
from the fact the ECMAScript uses such a long keyword, and that the
syntax requires empty parentheses. (I take it that one of the rules of
this golf game is that the expression should be short.)
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Stefan Weiss <krewecherl@gmail.com> |
|---|---|
| Date | 2013-09-02 23:11 +0200 |
| Message-ID | <l02uu2$42f$2@news.albasani.net> |
| In reply to | #21149 |
On 2013-09-02 22:52, Ben Bacarisse wrote: > HAS(o, 'p') || <EXPR> Beat me to it :) - stefan
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2013-09-03 00:03 +0200 |
| Message-ID | <1513771.HS4XPLjgls@PointedEars.de> |
| In reply to | #21149 |
Ben Bacarisse wrote:
> kj <no.email@please.post> writes:
Such anti-social address munging leads to at least one killfile entry.
>> (WARNING: This is a "JavaScript golf"-type query, of little practical
>> import; just for those who get into this sort of thing...)
>>
>>
>> Quick version
>> =============
>>
>> How to shorten the generic JavaScript expression
>>
>> o.hasOwnProperty('p') ? o.p : <EXPR>
>>
>> ...while still preserving the *conditional* evaluation of the <EXPR>
>> clause? (Here <EXPR> stands for an arbitrary JavaScript
>> expression.)
> <snip>
>> The best that my noob-level JS can come up with is to define a helper
>> function `HAS` (in a suitably restricted scope) to replace the verbose
>> built-in hasOwnProperty, so that one can at least write:
>>
>> HAS(o, 'p') ? o.p : <EXPR>
>
> If HAS returns o.p when o.hasOwnProperty('p'), then you can avoid the
> conditional
>
> HAS(o, 'p') || <EXPR>
Incorrect. There is a difference between an object having a property and
converting the result of a property access to Boolean. Assuming you meant
function HAS (o, p)
{
if (o.hasOwnProperty(p)) return o[p];
}
(where “HAS” is a very unwise identifier), if the value of o[p] was a false-
value, the result of
HAS(o, 'p') || <EXPR>
would be
<EXPR>
> Anything that uses functions to wrap EXPR for delayed execution suffers
> from the fact the ECMAScript uses such a long keyword, and that the
> syntax requires empty parentheses. (I take it that one of the rules of
> this golf game is that the expression should be short.)
Harmony (ECMAScript Edition 6) is going to fix that with foo(bar => baz):
<http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax>
That aside, the rules would also have to include that at “o” and “o.p” do
not hold references to host objects because those objects do not need to
implement [[HasProperty]] and [[Get]] the standard way (they may even throw
exceptions, as long-time subscribers should know).
I do not think this expression can be shortened (if you count the called
function as well), while being value-equivalent, as long as it must be
*generic*.
The “in” operator could be used if it did not consider inherited properties,
whereas hasOwnProperty() does not. So the shorter
"p" in o?o.p:<EXPR>
must be excluded. The proprietary, considerably safe
"p" in o&&!("p" in o.__proto__)?o.p:<EXPR>
would not be shorter than
o.hasOwnProperty('p')?o.p:<EXPR>
And the “in” operator should be forbidden with host objects because it uses
[[HasProperty]].
Much depends on what is meant by “JavaScript”:
<http://PointedEars.de/es-matrix>
--
PointedEars
Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2013-09-02 23:19 +0100 |
| Message-ID | <0.cf0106c707f704dac5bd.20130902231902BST.87zjruuasp.fsf@bsb.me.uk> |
| In reply to | #21155 |
Thomas 'PointedEars' Lahn <PointedEars@web.de> writes:
> Ben Bacarisse wrote:
>
>> kj <no.email@please.post> writes:
>
> Such anti-social address munging leads to at least one killfile entry.
>
>>> (WARNING: This is a "JavaScript golf"-type query, of little practical
>>> import; just for those who get into this sort of thing...)
>>>
>>>
>>> Quick version
>>> =============
>>>
>>> How to shorten the generic JavaScript expression
>>>
>>> o.hasOwnProperty('p') ? o.p : <EXPR>
>>>
>>> ...while still preserving the *conditional* evaluation of the <EXPR>
>>> clause? (Here <EXPR> stands for an arbitrary JavaScript
>>> expression.)
>> <snip>
>>> The best that my noob-level JS can come up with is to define a helper
>>> function `HAS` (in a suitably restricted scope) to replace the verbose
>>> built-in hasOwnProperty, so that one can at least write:
>>>
>>> HAS(o, 'p') ? o.p : <EXPR>
>>
>> If HAS returns o.p when o.hasOwnProperty('p'), then you can avoid the
>> conditional
>>
>> HAS(o, 'p') || <EXPR>
>
> Incorrect. There is a difference between an object having a property and
> converting the result of a property access to Boolean. Assuming you meant
>
> function HAS (o, p)
> {
> if (o.hasOwnProperty(p)) return o[p];
> }
>
> (where “HAS” is a very unwise identifier), if the value of o[p] was a false-
> value, the result of
>
> HAS(o, 'p') || <EXPR>
>
> would be
>
> <EXPR>
Yes, good point. I've used something similar, but in situations where
this problem would be unlikely. I was too hasty, though I suppose it's
possible that || works in all the OP's use cases.
>> Anything that uses functions to wrap EXPR for delayed execution suffers
>> from the fact the ECMAScript uses such a long keyword, and that the
>> syntax requires empty parentheses. (I take it that one of the rules of
>> this golf game is that the expression should be short.)
>
> Harmony (ECMAScript Edition 6) is going to fix that with foo(bar => baz):
>
> <http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax>
Nice. The return is no longer needed in simple cases too. It's always
seemed to me that the early designers never expected the wide use that
function expressions would get.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2013-09-03 01:59 +0200 |
| Message-ID | <7836422.gBDQCprLM3@PointedEars.de> |
| In reply to | #21156 |
Ben Bacarisse wrote:
> Thomas 'PointedEars' Lahn <PointedEars@web.de> writes:
>> Ben Bacarisse wrote:
>>> If HAS returns o.p when o.hasOwnProperty('p'), then you can avoid the
>>> conditional
>>>
>>> HAS(o, 'p') || <EXPR>
>>
>> Incorrect. There is a difference between an object having a property and
>> converting the result of a property access to Boolean. Assuming you
>> meant
>>
>> function HAS (o, p)
>> {
>> if (o.hasOwnProperty(p)) return o[p];
>> }
>>
>> (where “HAS” is a very unwise identifier), if the value of o[p] was a
>> false- value, the result of
>>
>> HAS(o, 'p') || <EXPR>
>>
>> would be
>>
>> <EXPR>
>
> Yes, good point. I've used something similar, but in situations where
> this problem would be unlikely. I was too hasty, though I suppose it's
> possible that || works in all the OP's use cases.
I do not think there is a use-case here. That is the very nature of code-
golfing, because it is more play than work: trying to find the shortest
equivalent expression, however unreadable, to solve a *theoretical* problem.
You would never used golfed code in production: it is probably inefficient,
likely error-prone, and definitely hard to maintain.
>>> Anything that uses functions to wrap EXPR for delayed execution suffers
>>> from the fact the ECMAScript uses such a long keyword, and that the
>>> syntax requires empty parentheses. (I take it that one of the rules of
>>> this golf game is that the expression should be short.)
>>
>> Harmony (ECMAScript Edition 6) is going to fix that with foo(bar => baz):
>>
>> <http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax>
>
> Nice. The return is no longer needed in simple cases too. It's always
> seemed to me that the early designers never expected the wide use that
> function expressions would get.
ISTM that this particular syntax for lambda expressions was borrowed from
C#, which in turn might have shortened that of Python. I learned it when I
first used LINQ extension methods about a year ago.
--
PointedEars
Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Stefan Weiss <krewecherl@gmail.com> |
|---|---|
| Date | 2013-09-02 23:10 +0200 |
| Message-ID | <l02us6$42f$1@news.albasani.net> |
| In reply to | #21148 |
On 2013-09-02 22:23, kj wrote:
> How to shorten the generic JavaScript expression
>
> o.hasOwnProperty('p') ? o.p : <EXPR>
>
> ...while still preserving the *conditional* evaluation of the <EXPR>
> clause? (Here <EXPR> stands for an arbitrary JavaScript
> expression.)
[...]
> The best that my noob-level JS can come up with is to define a helper
> function `HAS` (in a suitably restricted scope) to replace the verbose
> built-in hasOwnProperty, so that one can at least write:
>
> HAS(o, 'p') ? o.p : <EXPR>
>
> At the end of this post I give other alternatives I could think of,
> but they are all either *more* verbose than what they try to replace,
> or have some other weakness (e.g. failure to delay the evaluation of
> the <EXPR> clause).
I think that's about as close as you can get without special syntactic
sugar. If only the value of truthy properties is of interest, this form
could make a shorter alternative:
HAS(o, 'p') || <EXPR>
function HAS (obj, prop)
{
if (obj.hasOwnProperty(prop)) {
return obj[prop];
}
}
Golf entertainment aspect aside, is the verbosity of hasOwnProperty()
actually bothering you? This method tends to be used more in libraries
than ad-hoc scripts, so the ugliness should stay well hidden most of the
time.
In a misguided attempt to reduce the download size by increasing the
efficiency of minimizers, I once used something like this (not just for
hasOwnProperty):
// large library with many occurrences of hasOwnProperty etc:
(function () {
var _hasOwnProperty = "hasOwnProperty";
...
if (obj[_hasOwnProperty](prop)) {
...
})();
"_hasOwnProperty" can then be minified/obfuscated to something like "a",
which I thought was a good thing at the time. Honestly, the main effect
was to make the code less readable for the dubious benefit of saving a
few bytes. Not recommended.
I suspect that any highly golfed solution you may discover will suffer
from similar readability problems.
- stefan
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web