Using "new function() {...}" as a Singleton

D

David Mark

Stefan said:
Dmitry A. Soshnikov :
I think it is from another song. Ry Nohryb likes cute constructs that
minimise code lines. Most other contributors frown upon anything the
average programmer may fail to understand and maintain.

Count me in as an average programmer, then. In order to understand the
example, I had to rewrite it and rename the variables/arguments:

aQuery = (function () {
var list = [];

list.refresh= function () {
var set = document.body.getElementsByTagName('*'),
i = set.length;
list.length = 0;
while (i--) {
if (set.width === "100%") {
list[list.length] = set;
}
}
return list;
};

list.refresh();
return list;
})();

Unless I made a mistake during refactoring - which is entirely possible,
I didn't test it or spend a lot of time on it - aQuery is a sparse array
of all elements in the body with a "width" property of "100%". It also
has a refresh() method which will update the array and return the aQuery
object for method chaining.

The "width" property looks suspicious. Not necessarily a bug, and it
could be intentional, but I wonder how easy it is to find such problems
in a "compressed" piece of code?


Not very. :)
I enjoy playing around with terse and obfuscated code, too. For example,
this is a working Perl program, written entirely with keywords:

not exp log srand xor s qq qx xor
s x x length uc ord and print chr
ord for qw q join use sub tied qx
xor eval xor print qq q q xor int
eval lc q m cos and print chr ord
for qw y abs ne open tied hex exp
ref y m xor scalar srand print qq
q q xor int eval lc qq y sqrt cos
and print chr ord for qw x printf
each return local x y or print qq
s s and eval q s undef or oct xor
time xor ref print chr int ord lc
foreach qw y hex alarm chdir kill
exec return y s gt sin sort split

Dear God. PERL programmers drive me nuts.
 
R

Ry Nohryb

LOL. I declare you incomprehensible.

Well, s/usually/often
Yes, in CS such "cute" constructs are known as "job security".  In
business it is known as being a complete prat who should be shown the
door immediately.

Q: Objectively, what's wrong with a && b(); ?
A: Nothing.
Hasta la vista El Abuelo!

Ja, qué salao!
They are useless in that case.  But where do you come from?  :)

I might come from "un lugar de la Mancha de cuyo nombre no quiero
acordarme" :)
 
D

David Mark

Johannes said:
Stefan Weiss :


Exactly. I find Ry Nohryb's cute constructs both entertaining and to
some extent enlightening - in general, not this particular snippet.

No, that one stunk to high heaven.
I don't know whether they could or should make their way into production
code.

Not in JS, that's for sure.
What is considered too obscure seems to depend on the language.
Nobody would hire a Perl programmer who didn't understand

open(IN, $file) or die "Couldn't open $file - $!\n";

That's perfectly appropriate for that language.
but perhaps javascript is different, and for a good reason.

It is and here's the reason: most JS programmers are incompetent. As
we've been over, browse around the Web with the error console open.
Read the Dojo source (pick any of the hundreds of files). Supposedly,
those are experts working on that crap. Print out today's jQuery forum
posts (or a StackOverflow JS search) and throw darts at it. You'll hit
a maddeningly inept exchange virtually every time. Not most of the
time, but virtually /every/ time.

The trouble is that JS makes it easy for programming novices (or even
non-programmers) to cobble together something that appears to work in
their installed browsers. That creates overconfidence, which leads to
foolhardiness, which leads to all of those errors you see in the console.
 
D

David Mark

Ry said:
Well, s/usually/often

Groan. That was the one word (over two letters long) that made sense. :(
Q: Objectively, what's wrong with a && b(); ?
A: Nothing.


Ja, qué salao!

Klaatu barada nikto!
I might come from "un lugar de la Mancha de cuyo nombre no quiero
acordarme" :)

Why don't you go back there? :)
 
D

Dmitry A. Soshnikov

Dmitry A. Soshnikov :


Ry Nohryb likes cute constructs that
minimise code lines.


I like them too. And always (try to) write as effective by a /code
reuse/ and short code elegant constructions as possible. The only
reason, when I prefer other way is when it seems less convenient for me.
That's it.
Most other contributors frown upon anything the
average programmer may fail to understand and maintain.

This reason I always don't like as an logical argument in talks (it's
not about you, it's in general). The situation is simple: some
(authority) having a previous experience in /other/ language writes a
book, describing e.g. things like /a && b();/ as (let suppose) "bad
practice", arguing that for some programmers it is hard to understand
and isn't habitual.

Of course, the readability matters. And the clear readable code reason
is on the first place. But. We should talk about the concrete exact
language and its constructions which are specially was invented as
alternative for that long boding (invented /before/) constructions.

That logical chains such as /a && b();/ there are in many languages:
ECMAScript, Ruby, Python, Erlang, etc. and I use such constructions very
often (regardless that someone can tell me: "can you use /if/ instead?
Because it isn't habitual for me after <previous language>").

It also depends of the professional level of a programmer. It's like
e.g. math: there is a technical school math, there is an university
school math, there is an academical level math... etc.

So why the hack from this position I should use "beginners secondary
school math" constructions for the reason that my code can be understood
by any newbie after reading "JavaScript for dummies"?

So, personally I have the following priorities of a code:

1. Readability (by your own wish level, but not forced by some meaning
that "this will be non-habitual for C-programmers");

2. All other invented (specially invented to improve code reuse
stylistics) constructions which can decrease readability, but can
improve (a) code reuse and make such constructions more elegant/less to
write, (b) performance.

So, for any middle/professional level ES/Ruby/Python/Erlang/etc.
programmer the constructions such as:

a && b();
a = a || b;

etc.

should be /absolutely normal/.

Dmitry.
 
R

Ry Nohryb

Dmitry A. Soshnikov :
I think it is from another song. Ry Nohryb likes cute constructs that
minimise code lines. Most other contributors frown upon anything the
average programmer may fail to understand and maintain.

Count me in as an average programmer, then. In order to understand the
example, I had to rewrite it and rename the variables/arguments:

  aQuery = (function () {
      var list = [];

      list.refresh= function () {
          var set = document.body.getElementsByTagName('*'),
              i = set.length;
          list.length = 0;
          while (i--) {
              if (set.width === "100%") {
                  list[list.length] = set;
              }
          }
          return list;
      };

      list.refresh();
      return list;
  })();

Unless I made a mistake during refactoring - which is entirely possible,
I didn't test it or spend a lot of time on it - aQuery is a sparse array
of all elements in the body with a "width" property of "100%". It also
has a refresh() method which will update the array and return the aQuery
object for method chaining.
Perfect.

The "width" property looks suspicious. Not necessarily a bug, and it
could be intentional, but I wonder how easy it is to find such problems
in a "compressed" piece of code?


You've got it perfectly except that you've hardcoded document.body,
"width" and "100%", which in my mind were just regular parameters to a
generic "attribute query generator". (Before David Marks jumps in: I
know that not all html-elements' attributes are reflected in JS-land,
and that those that are, might be with a different name (e.g. class/
className))
I enjoy playing around with terse and obfuscated code, too. For example,
this is a working Perl program, written entirely with keywords:

    not exp log srand xor s qq qx xor
    s x x length uc ord and print chr
    ord for qw q join use sub tied qx
    xor eval xor print qq q q xor int
    eval lc q m cos and print chr ord
    for qw y abs ne open tied hex exp
    ref y m xor scalar srand print qq
    q q xor int eval lc qq y sqrt cos
    and print chr ord for qw x printf
    each return local x y or print qq
    s s and eval q s undef or oct xor
    time xor ref print chr int ord lc
    foreach qw y hex alarm chdir kill
    exec return y s gt sin sort split

(from <http://www.perlmonks.org/index.pl?node_id=290607>)

LOL. Perl is exceptional. I love this one:
http://99-bottles-of-beer.net/language-perl-737.html
Pretty impressive stuff, but perhaps not the most appropriate format for
production code. There's a time and a place for everything :)

I too write tricky code is an as clear as possible way, but a little
snippet as that query generator is not exactly "tricky", or is it ?

In any case, we ought to do an obfuscated JS contest ! It would be
funny!
 
R

Ry Nohryb

(...)
I enjoy playing around with terse and obfuscated code, too. For example,
this is a working Perl program, written entirely with keywords:

    not exp log srand xor s qq qx xor
    s x x length uc ord and print chr
    ord for qw q join use sub tied qx
    xor eval xor print qq q q xor int
    eval lc q m cos and print chr ord
    for qw y abs ne open tied hex exp
    ref y m xor scalar srand print qq
    q q xor int eval lc qq y sqrt cos
    and print chr ord for qw x printf
    each return local x y or print qq
    s s and eval q s undef or oct xor
    time xor ref print chr int ord lc
    foreach qw y hex alarm chdir kill
    exec return y s gt sin sort split

$ perl (that above)
--> "just another perl hacker"
 
D

Dmitry A. Soshnikov

On 22.05.2010 21:02, Johannes Baagoe wrote:

an indispensable
idiom - Cornford's Construct, `(function() {/*...*/}) ();`.

Why do you call it so? Did Richard Cornford suggested first to use
exactly /this style/ of a function expression (with grouping operator)
to provide a local initializing scope? Wasn't it used before? I don't
believe. What's the date?

(Richard, answer yourself please, and confirm it, if it is true).

Dmitry.
 
D

David Mark

Johannes said:
David Mark :


That seems, alas, to be the case.
Unfortunately.


Quite, but what can we do about it?

Not a thing. That's one point.
Is it better to simply acknowledge
the fact and say "Nothing fancy in production code", or do we attempt
to raise the general level of programming skills even in javascript?

How can we do that?
I'm not suggesting that each and every clever construct should be
endorsed and used, of course. But there is at least one that seemed
very odd when it first appeared, and which has become an indispensable
idiom - Cornford's Construct, `(function() {/*...*/}) ();`.

I don't find the one-off construct particularly odd. It fits the
language perfectly.
So, perhaps, there is a case to be made for some ingenuity.

I just didn't consider the example code to be ingenuity (more like
deliberate obscurity). It wasn't just the use of boolean operators for
flow control; the whole thing was a mess.
It could
be argued that so-called "programmers" who can't follow simply aren't
fit to write programs for a living, not even Web applications which
hardly require less skills than, say, business reports in COBOL.

Web applications (particularly cross-browser applications) require a lot
more discipline than COBOL reporting.
Perhaps that would be a better way to increase the general level of
quality of Web applications than insisting that only what morons can
understand should be used in production code.

It's not so much about understanding as clarity, which leads to ease of
maintenance. The fact that it makes it easier for less-disciplined
programmers is just a bonus.
 
D

Dmitry A. Soshnikov

Dmitry A. Soshnikov :


I believe that it should have a proper name. By coincidence, a catchy
alliteration is available, like Duff's Device and the Muenchian Method.


It would seem so.

Well, don't know. The concept of a function expression existed long time
before JavaScript (and exactly) in many functional languages.

For example, Erlang (which I'm currently diving in):

(fun (X) -> 2 * X end)(10). % results 20

The other talk (and purpose) is a private scope, but even from this
viewpoint I'm not sure about to whom should be "awarded" the "invention"
of the construct (and its exact view -- with a grouping operator) which
existed long time before that.

Dmitry.
 
D

David Mark

Ry said:
Dmitry A. Soshnikov :
Is it relevant or this is from other song?
I think it is from another song. Ry Nohryb likes cute constructs that
minimise code lines. Most other contributors frown upon anything the
average programmer may fail to understand and maintain.
Count me in as an average programmer, then. In order to understand the
example, I had to rewrite it and rename the variables/arguments:

aQuery = (function () {
var list = [];

list.refresh= function () {
var set = document.body.getElementsByTagName('*'),
i = set.length;
list.length = 0;
while (i--) {
if (set.width === "100%") {
list[list.length] = set;
}
}
return list;
};

list.refresh();
return list;
})();

Unless I made a mistake during refactoring - which is entirely possible,
I didn't test it or spend a lot of time on it - aQuery is a sparse array
of all elements in the body with a "width" property of "100%". It also
has a refresh() method which will update the array and return the aQuery
object for method chaining.
Perfect.

The "width" property looks suspicious. Not necessarily a bug, and it
could be intentional, but I wonder how easy it is to find such problems
in a "compressed" piece of code?


You've got it perfectly except that you've hardcoded document.body,
"width" and "100%", which in my mind were just regular parameters to a
generic "attribute query generator". (Before David Marks jumps in:


That's not my name, George.
I
know that not all html-elements' attributes are reflected in JS-land,
and that those that are, might be with a different name (e.g. class/
className))

You really don't know what you are talking about, do you? Bugs
notwithstanding, all standard attributes of "html-elements" are
reflected in "JS-land" in one way or another.

So, why wouldn't you want me to "jump in", considering that you seem to
be confused about the subject. It's not as if attributes and their
related properties are minor details. Misunderstanding their
relationship is tantamount to a mathematician misunderstanding basic
arithmetic.

And since you seem to be asking for it...

Why do you think the failings of jQuery (and YUI, Dojo, etc.) in this
area are so appalling? These "standard" scripts are supposed to make
things easier for beginners. One big selling point is that they have
been around for years and used by thousands of developers, who have
tirelessly logged bugs, submitted patches, written blogs, etc. This
would seem to indicate that they have the basics down pat at this point
(roughly five years later). But, as we know, they aren't even close and
their authors seem oblivious, even to basic (and often well-documented)
problems that date back to last century. If anything, they are making
things much harder than they should be.

For example, building a CSS selector query engine on top of botched
attribute methods is like trying to do calculus with a calculator that
can't be counted on to add and subtract correctly. In the same way,
creating widgets on top of code that can't measure the height/width of
elements consistently is like trying to build skyscrapers with a
slightly off tape measure.

But I digress. The point is that no other industry would put up with
such nonsense. Would you fly in an airplane that relied on Dojo for its
instrumentation? How about a space shuttle with rockets controlled by
jQuery? For many businesses, Websites are mission-critical. And seeing
as JS code is always available for review (unlike the code in Microsoft
Windows), there doesn't seem to be any sound reason for such follies to
persist. The apologists can wave their hands and point to the fact that
lots of people are doing these things, but that doesn't make them any
less ill-advised (or the objections to criticism any less ridiculous).
LOL. Perl is exceptional. I love this one:
http://99-bottles-of-beer.net/language-perl-737.html


I too write tricky code is an as clear as possible way,

That would seem a contradiction in terms. Why are you trying so hard to
be clever when it makes your code less clear? Of course, I know the
answer. That's why I fired you. :)
but a little
snippet as that query generator is not exactly "tricky", or is it ?

No, it's just less clear than it should be.
In any case, we ought to do an obfuscated JS contest ! It would be
funny!

Not really. I think you'd be happier as a PERL programmer. :)
 
R

Ry Nohryb

Ry Nohryb wrote:
(...)

That's not my name, George.

Sorry, a typo.
You really don't know what you are talking about, do you?  Bugs
notwithstanding, all standard attributes of "html-elements" are
reflected in "JS-land" in one way or another.

I didn't say *standard* attributes. I said just attributes. If you add
the attribute "DavidMark" to an element it won't be reflected in JS-
land.
So, why wouldn't you want me to "jump in", considering that you seem to
be confused about the subject.  It's not as if attributes and their
related properties are minor details.  Misunderstanding their
relationship is tantamount to a mathematician misunderstanding basic
arithmetic.

And since you seem to be asking for it...

I don't agree with you in that matter, you know, so thanks, but no,
thanks. With all due respect, not again, please... :)
(...)


That would seem a contradiction in terms.  Why are you trying so hard to
be clever when it makes your code less clear?  Of course, I know the
answer.  That's why I fired you.  :)

It's not so much about "trying so hard to be clever" as it's about
feeling the joy of using the language to its fullest. What's easy for
you you can optimize or write in a compact, pretty, "clever" form from
the start, but when you're finding it tricky, when you're still in the
struggling phase of solving the problem, still trying to get the
algorithm right, when it still doesn't work, you tend to write it as
if for dummies and only start thinking about prettifying afterwards,
if ever. And I say if ever because there are always some parts of a
project that you hate and find boring, and others that you like and
enjoy and prettify more.
No, it's just less clear than it should be.


Not really.  I think you'd be happier as a PERL programmer.  :)

I'd be happier as a Ruby programmer and it's where I'm heading towards
right now.
 
D

David Mark

Ry said:
Sorry, a typo.


I didn't say *standard* attributes. I said just attributes. If you add
the attribute "DavidMark" to an element it won't be reflected in JS-
land.

I know. That's why I said "standard" attributes. Who cares about
non-standard attributes?
I don't agree with you in that matter, you know, so thanks, but no,
thanks.

You can put on whatever public face you want, but try arguing with the
results I've posted over the years. Beware the black squares. :)

And a child could recognize the fallacies I described (and that you
snipped). Do you use YUI or jQuery or Dojo? If so, you are either
blind or insane. Well, as for the latter; that ship has sailed.
Eyesight problems too?
With all due respect, not again, please... :)

It's not for your benefit, George (sorry, typo). This is a public
newsgroup. Other people read it. And we know newcomers don't search
the archive (even when the GG search feature is working). Get it?
It's not so much about "trying so hard to be clever" as it's about
feeling the joy of using the language to its fullest.

Whatever. From a business standpoint, your joy couldn't be any less
relevant.
What's easy for
you you can optimize or write in a compact, pretty, "clever" form from
the start, but when you're finding it tricky, when you're still in the
struggling phase of solving the problem, still trying to get the
algorithm right, when it still doesn't work, you tend to write it as
if for dummies and only start thinking about prettifying afterwards,
if ever.

Are you talking about me?
And I say if ever because there are always some parts of a
project that you hate and find boring, and others that you like and
enjoy and prettify more.

I do not.
I'd be happier as a Ruby programmer and it's where I'm heading towards
right now.

Good. Why don't you go there. Bye. :)
 
A

Andrea Giammarchi

I don't understand the whole "arguments" flame, neither how you guys
ended up talking about ternary and other operators ... anyway ... all
I've provided in my first post was a description, with all common
matters (e.g. arguments, compressors and the usage of "this", the
shadowed constructor, etc)

Next, just my 2 cents for those "patience" enough to at least read a
post 'till the end before they start replying randomly bulling and
bullshitting around ...

@Dmitry, I agree about the "new function(argum, ents) { ... }" , but
in a 1 to 1 pattern "challenge" it was worth it to mention that:
if for semantic reasons we would like to "mark" outer scope variables
used internally, we can re-assign named arguments *or* as already
mentioned, we can pass directly arguments at the end.

The reason I did not mention is that a singleton is usually complex
enough to do not fit into few lines and I agree about the scroll down/
up problem (I still use this pattern to preserve an extra "var" when
it is possible, choosing semantic arguments names)

In any case, being the pattern a Singleton, the cost is absolutely
relative and surely less greedy than whatever framework library we use
to define a Singleton (those weird things used "somewhere" such ...)

var
o = new Class(function(){
return { ... proto .... };
}()),
o = new o
;

About bytes and re-assigned arguments, being the usage of "var" quite
inevitable if we need a closure to define a singleton rather than just
a literal "{...}", no bytes will be saved for compilers so, as
demonstration, it may works, but as provided functionality, it is not
convenient.

At the same time, if the matter is an undefined argument performance
impact, because it is assigned twice, I would explain properly the
difference between these 2 patterns you wrote after:

a && b();
a = a || b;

in the first case we have a shortcut for a classic

if (a) {
b();
}

fair enough, in the second case we have *double* assignment that is
completely useless

The right pattern in that case is this:

a || (a = b);

the difference is that "a" is not assigned to itself if it does not
point to a falsy value and the readability is not compromised (we have
an extra byte there tho)

On NewExpression, I still believe it's a valid option, somehow more
elegant and readable for the singleton pattern when a closure is
necessary while the module pattern requires a "return" plus extra
parenthesis VS just a "new"

// module way
var o = (function () {
return {};
}());

// NewExpression
var o = new function () {
};

// module way via compressors
var o=function(){return{}}();

// NewExpression via compressors
var o=new function(){};

now, where is exactly the confusion there? I can't see it at all

Best Regards,
Andrea Giammarchi
 
A

Andrea Giammarchi

(fun (X) -> 2 * X end)(10). % results 20

ah ah, the classic "lambda", I could not resist :D

function L(body){
var i = body.indexOf(":");
return ~i ?
Function(body.slice(0, i), "return " + body.slice(++i)) :
Function("return " + body)
;
}

L("x:2*x")(10);

Br,
Andrea Giammarchi
 
A

Andrea Giammarchi

just in case somebody would like to use it, 99 bytes version with
mandatory arguments (the only reason I would use a lambda, no
arguments does not make sense)

function L(b){var i=b.indexOf(":");return
Function.call(this,b.slice(0,i),"return "+b.slice(++i))};

L("x,y:x*y")(2,3); // 6

Br,
Andrea Giammarchi
 
A

Andrea Giammarchi

and then I realize the call is absolutely a non sense FFS! ... easy

function L(b){var i=b.indexOf(":");return
Function(b.slice(0,i),"return "+b.slice(++i))};

right, I am off with off topics here, have fun :D

Br,
Andrea Giammarchi
 
R

Ry Nohryb

(...) But there is at least one that seemed
very odd when it first appeared, and which has become an indispensable
idiom - Cornford's Construct, `(function() {/*...*/}) ();`.

Maybe, at the very best, the [name both of them] construct, because
there's no doubt that it's been Douglas Crockford who has contributed
more than anybody else to its divulgation. Not Cornford nor c.l.js
neither its FAQ.

I've witnessed for the last 3+ years the influence of this group and
it's ~= nil, what a waste, what a lost opportunity, not to mention the
fact that the few (JS newbies or not) that every now and then happen
to dare to post here asking for help or advice more often than not are
immediately repelled by the harsh + impertinent answers of no help nor
valuable advice by the usual bunch of bigoted regulars.

OTOH, I and tens of thousands like me have learned of and about that
construct -and much more- in Crockford's videos.

And let's not forget that this group's FAQ is outdated and will always
be forever so until its current guardian is swapped for an -unlike
him- efficient -unlike him- maintainer -rather than guardian-.

It's a pity, it's waste, but it's the truth, and it's been a lost
opportunity: c.l.js could have been the best resource for the JS
community but instead everybody laughs at it because of this bunch of
regulars that behave as rude little men.
 

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
474,077
Messages
2,570,569
Members
47,206
Latest member
MalorieSte

Latest Threads

Top