Splicing exercise

O

optimistx

Johannes said:
Csaba Gabor :


And I appreciated that, it is exactly the kind of things I would like
to see more of on this newsgroup. I am not particularly interested in
incompatibility issues in various browser's implementation of the
DOM, and even less in ego-related flames.

Yes, that expresses my opinion too. Ego-related flames :).

The example is interesting, I like postings like that.

I can afford to read and write here about only the things which
I feel fun to have. I need not spoil my day by reading insults.

If some people try to have only 'expert level advanced'
QUESTIONS here, where the OP (original poster?) has first
tried to solve some years/months/weeks before posting,
I think that goal is going to fail.

So let us have fun instead. Let us have friendly and fun DISCUSSION.
Ideas. Experiences. Exercises. Right or wrong, not so important. We
learn by making mistakes.

Is c.l.j a help desk? Perhaps a help desk for some people to get their daily
ego boost and increase of their self esteem. If they need to insult
others to feel better and expertlike, we cannot prevent them doing
that, as little as we cannot prevent spam coming. Anyhow, we can ignore
spam, ignore ego boosting wars.
 
T

Thomas 'PointedEars' Lahn

VK said:
OP named it "Splicing exercise', that enough of a hint IMHO.

It is evidently ambiguous. An exercise *for whom*? Also, one should not
assume the Subject header is read, and therefore should not use it alone
to convey the meaning of the posting. If that is not already mentioned
in the FAQ under #posting, it should be.


PointedEars
 
A

Asen Bozhilov

Johannes Baagoe wrote:
š function insertArray(a1, a2, pos) {
š š return a1.splice.apply(a1, [pos, 0].concat(a2)), a1;
š }

By which criterion is that better? šIt requires Function.prototype.apply()
(compatibility issue), a nested call (performance issue), and is less clear
(code reuse issue).

ECMA 262 - 3
15 Native ECMAScript Objects:
Every built-in function and every built-in constructor has the
Function prototype object, which is the initial value of
the expression Function.prototype (section 15.3.2.1), as the value of
its internal [[Prototype]] property.
(performance issue)

It's wrong. If you compare:

function insertArray(a1, a2, pos) {
return a1.splice(0, a1.length,
a1.slice(0, pos).concat(a2, a1.slice(pos))), a1;
}

function insertArray1(a1, b1, pos)
{
Array.prototype.splice.apply(a1, [pos, 0].concat(b1));
return a1;
}

For 100000 times with:
var a = [1, 2, 3],
b = ['a', 'b', 'c'];

insertArray : 447ms
insertArray1 : 386ms

In Fx 3.5
 
T

Thomas 'PointedEars' Lahn

Asen said:
Thomas said:
Johannes said:
function insertArray(a1, a2, pos) {
return a1.splice.apply(a1, [pos, 0].concat(a2)), a1;
}

By which criterion is that better? It requires
Function.prototype.apply() (compatibility issue), a nested call
(performance issue), and is less clear (code reuse issue).

ECMA 262 - 3
15 Native ECMAScript Objects:
Every built-in function and every built-in constructor has the
Function prototype object, which is the initial value of
the expression Function.prototype (section 15.3.2.1), as the value of
its internal [[Prototype]] property.

Entirely irrelevant to what I said.
It's wrong.

Hear, hear.
If you compare:

function insertArray(a1, a2, pos) {
return a1.splice(0, a1.length,
a1.slice(0, pos).concat(a2, a1.slice(pos))), a1;
}

function insertArray1(a1, b1, pos)
{
Array.prototype.splice.apply(a1, [pos, 0].concat(b1));
return a1;
}

For 100000 times with:
var a = [1, 2, 3],
b = ['a', 'b', 'c'];

insertArray : 447ms
insertArray1 : 386ms

In Fx 3.5

That doesn't prove anything.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Johannes said:
Johannes Baagoe :

It is not Pan's default, obviously. It takes some work, and alas one
that cannot be entirely automatised even if it is not that difficult
to write helper scripts.

IOW: You are going to great lengths to modify your news client so that it
posts differently than any other news client by default, and different to
all Usenet recommendations. Some would consider that to be rather trollish
behavior, and your stating that you care for your readers to be a
hypocritical statement.
[TLDR]
if you really believe that there is a consensus that, e.g.,


is better, I suggest a RFD in order to change the charter :)

Of course, if others feel like you, we could also discuss it here,
or on another more suitable newsgroup. If a consensus is reached,
I shall comply with it.

So far, the recommendations in the FAQ of this newsgroup displays what could
reasonably be called the consensus. The current FAQ maintainer has imposed
some of his views on it, but most of the FAQ appears acceptable to all whom
it may concern. To name one, Richard Cornford recently stated what he finds
acceptable when he replied to one of VK's postings, and with regard to the
position of the attribution that is precisely what is described in the FAQ.
Otherwise, I shall continue quoting in the way I find the best, without
going to the extreme of reprimanding others for not doing like me.

ISTM you overestimate your importance here.


F'up2 poster

PointedEars
 
C

Csaba Gabor

Johannes Baagoe :
The shortest (except for whitespace) solution for the problem
as stated seems to be

  function insertArray(a1, a2, pos) {
    return a1.splice.apply(a1, [pos, 0].concat(a2)), a1;
  }

If one changes the problem to that of returning an array without changing
the value of the first argument as a side-effect, the following is
slightly shorter, clearer and possibly better :

  function splicedArray((a1, a2, pos) {
    return a1.slice(0, pos).concat(a2, a1.slice(pos));
  }

Johannes, thanks for cleaning up my example code.
I find this use of the comma very interesting. It's the
only time I've ever seen it used outside a var statement
or for loop, thanks.

As a variation on a theme, one could also use:
function insertArray(a1, a2, pos) { return (
a1.splice.apply(a1, [pos, 0].concat(a2)).length || a1); }

Asen, thanks for pointing out that one can also use
Array.prototype.splice.apply in place of
a1.splice.apply above. Do you know offhand which of
the two versions is more efficient?
 
A

Asen Bozhilov

Asen, thanks for pointing out that one can also use
Array.prototype.splice.apply in place of
a1.splice.apply above.

BTW, before my post with Array.prototype.splice.apply, i don't see
your code :)
Do you know offhand which of
the two versions is more efficient?

The only difference between two version is a way of prototype lookups.
In the two version lookups is 5. Your code make much more lookups
internal.

1: a1 is instance of Variable object in local execution context. a1
refer `object' who [[Prototype]] property referred to Array.prototype.
2: That `object' who referred from a1 doesn't have property with name
`splice'.
3: Look for `splice' in `object' who referred from a1.[[Prototype]].
4: `splice' property referred `object' who internal property
[[Prototype]] referred to Function.prototype. `Object' referred from
`splice' doesn't have property with the name `apply'. Going in
prototype chain.
5: Property `apply' will be in the `splice'.[[Prototype]]

In my code:

1: `Array' is instance from Variable object in global execution
context. `Array' referred `object' who internal [[Prototype]] referred
to Function.prototype. And `Array' internal [[Class]] value is
'Function'.
2: Object referred from `Array' have property with name `prototype',
because `prototype' property is instance property.
3: `splice' property will be in `object' referred from `prototype'
property.
4: Point 4 from before explained list.
5: Point 5 from before explained list.
 
A

abozhilov

The shortest (except for whitespace) exact solution I have found is

  function insertArray(a1, a2, pos) {
    return a1.splice(0, a1.length,
      a1.slice(0, pos).concat(a2, a1.slice(pos))), a1;
  }

You can use more shortest:

function insertArray2(a1, a2, pos)
{
var len = a1.length;
a1.splice(0, len, a1.concat(a2, a1.splice(pos, len)));
}

If you doesn't want to change a1 is much more short:

function insertArray2(a1, a2, pos)
{
return a1.concat(a2, a1.splice(pos, a1.length));
}
 
A

abozhilov

If you doesn't want to change a1 is much more short:

function insertArray2(a1, a2, pos)
{
        return a1.concat(a2, a1.splice(pos, a1.length));

}

Actually that example is wrong. a1.splice will be change a1 and that
is not good.
 
G

Garrett Smith

kangax said:
Richard said:
kangax said:
Richard Cornford wrote:
1.Examine the Variable object to see if it has a property named
"Array"; it does not.
2 Examine the Variable object to see if it has a [[Prototype]],
it does not, so move on to the next object on the scope
chain, which is the global object.

If we're talking about function code, where Variable Object is
an Activation Object, how do we know that it has no [[Prototype]]?

See below.
Possibly because of the absence of any assignment to [[Prototype]] in
association with the creation of the activation object, when every
other object creation (that I can think of right now) either specifies
a [[Prototype]] value/assignment or implies it (as in the use of "as
if by the expression new Object()").

Fair enough.
Isn't Activation Object just a specification mechanism, with
unspecified [[Prototype]]?

Yes, but the activation object becomes the function call's Variable
object and if it did have a [[Prototype]] then that would always be
involved in Identifier resolution from within a function.

Of course.

We can actually test if Activation Object has [[Prototype]] referencing
something like `Object.prototype` (or `Array.prototype`, etc.). However,
[[Prototype]] can also reference some "internal" entity, which we have
no way of checking for (and its existence probably doesn't really matter).

And if the activation object has no property, scope chain and identifier
resolution takes to global object, which is a split object, which may
have Object.prototype on the scope chain (that is implementation-
dependent).

| The values of the [[Prototype]] and [[Class]] properties of the global
| object are implementation-dependent.

Interesting example Leithead posted up on whatwg, calling -
hasOwnProperty - on global object, a WindowProxy, yet expecting the
result to be based off global object itself.

Extra interesting is Blackberry9000 bug of resolving an Object.prototype
property on the Variable object.

We can test this by setting something in containing scope and see if the
identifier is resolved off global object.

http://github.com/GarrettS/ape-javascript-library/blob/master/adhoctest/activationo.html
(can be run using gitHubSource bookmarklet)

Example source:
<!doctype html>
<html>
<head>
<title>test activation object</title>
</head>
<body style="white-space: pre">
<script type="text/javascript">
var hasOwnProperty = 12;
this.hasOwnProperty = 14;
this.gProp = "g";
(function(){
function hasOwnProperty(a){return 1;}
var constructor = 123;
function toString() { return "local"; }
function testThis(){
document.write([
hasOwnProperty("gProp"),
constructor,
toString(),
this.toString()]);
}

return testThis;
})()();
</script>
</body>
</html>

Expected output would be something* like:
1,123,local,[object Window]

* "[object Window]" is not an expectation; everything else is.

Blackberry9000/9500:
true, function Object() { [native code for Object.Object, arity=1] }
,[object Window],[object Window]

The result of first hasOwnProperty("gProp") could be explained by
the identifier being resolved on activation object's scope chain and
calling hasOwnProperty using |null| as the |this| value for the function
call, as in s10.1.6.

| When the call operation is applied to a Reference value whose base
| object is an activation object, null is used as the this value of the
| call.

The implication this has is that any identifier name that coincides with
with an Object.prototype property will not be found on the enclosing
scope. Don't name you function "hasOwnProperty", etc.

Function decompilation that expects "[native code]" will fail.
(Function decompilation is best avoided altogether, for various other
reasons).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,820
Latest member
GilbertoA5

Latest Threads

Top