On Fri 26 Jul 2013 12:29:10 PM PDT, Brendan Eich wrote:
> Steve Fink wrote:
>> (2) writing JS still feels clunky in comparison to writing
>> Python,
>
> What's missing in your experience?
That question deserves a proper response, but it's tough remembering
the issues when I'm not actively hacking out code. I've attempted to
make lists of stuff at various times that I can dig up, but for now
I'll just list out some that I've noticed recently. These are things
that are possible but seem a little indirect or unnatural:
* copying an array with copy = orig.slice(0). Compare with Python's
copy=list(orig) or copy=dict(orig), or Perl's @copy = @orig or %copy =
%orig.
* using an array for a tuple feels heavyweight. |return [a,b]|. Compare
with Python's tuples or Perl's multiple return values.
* |if (!(item in collection))|. I miss Python's |if (item not in
collection)|
* Related to the above, the whole sequence
if (!(key in collection))
collection[key] = []; // or {}
collection[key].push(value);
Compare with Python's somewhat clunky collection.setdefault(key,
[]).append(value) or Perl's autovivification push @{ $collection[$key]
}, $value
* |a + " " + b + ";" + c|. I think interpolation is coming with some
future ES version (whatever quasiliterals are called now?), but compare
with Python's rich string formatting or Perl's "$a $b;$c" string
interpolation.
* Extending an array via |combined = orig.concat(newstuff)| creates
garbage, can't be used when updating the original is what you want, and
concat behaves differently for arrays vs everything else. (I don't know
the spec well enough to understand what "array" means in this case.)
Compare with Python's orig.extend(newstuff) and Perl's push @orig,
@newstuff.
* Not a language issue, but I really like the cleaner control flow and
intermediate memory usage of generators. But I am avoiding them in hot
code because neither ionmonkey nor baseline currently gets along with
them. (As in, they don't compile them, so I've been advised to avoid
them when I don't want a performance cliff.)
* |in| vs |of|. Beyond the usual, the most recent way this bugged me
was when I found that |for (x in generator())| and |for (x of
generator())| seem to do the same thing. Given that I mostly consider
|in| to iterate over keys and |of| over values, having them do the same
thing seems odd. I'm not sure how I'd *want* them to behave, but it
would somehow feel cleaner to have one of them be an error or making
|in| return numbers counting up from zero or something. Then again,
|of| doesn't give me values, only elements, which suggests that I just
have the wrong mental model. It seems like |in| wants me to think of
Arrays as objects that happen to have numeric keys, and |of| and
|concat| don't.
* undefined testing. It bothers me that |undefined| can be defined, so
|x === undefined| isn't 100% guaranteed to mean what I want (and yet
redefining undefined doesn't do anything useful.) And actually, I don't
really like |x === undefined| in the first place, since I'm uneasy with
treating undefined as a valid value. I prefer Python's |x is None| and
Perl's |defined(x)|.
* |if (item in collection)| is fine for non-Arrays, but |if
(collection.indexOf(item) != -1)| feels clunky.
I'm probably just wrong about some of these. I reserve the right to
turn around and argue that it should have been more obvious to me that
I was wrong. :-)
On a separate note, please don't think that I am arguing against
dogfooding in general. I'm just not so sure I want it in the build
system. I think the rooting analysis has shown the power of dogfooding.
bhackett needed to spawn external commands, so he added system() to the
shell. I really wanted to load scripts relative to other scripts so I
could split them into multiple files, so I added loadRelativeToScript.
When developing in JS "for real", I wanted a debugger, so I tweaked
js/examples/jorendb.js to allow easy debugging of standalone scripts.
(My latest work on the analysis led me to discover that it had
bitrotted, and that I needed to add some more functionality.) Due to
some changes I needed to make in the data flow for the analysis, I
found I needed to write out multiple files from one script, so just
print() and shell redirection was no longer enough. I first fixed up
mfeeley's implementation for writing a string to a file, then
immediately discovered that it was useless for me because I didn't want
to materialize the whole string before writing anything. So I added the
ability to redirect stdout and/or stderr to a named file. (It would be
better to be able to specify a file object for each print, but I have
no interest in reintroducing a whole File object to the shell.)
These are all cases where the dogfooding led to improving the shell,
not improving JS itself, but I'd like to think of these sorts of things
as necessary prerequisites to "true" dogfooding, that which would lead
to improvements in the shipped JS engine. You need a decent development
environment before you can get people to do proper dogfooding.
_______________________________________________
dev-tech-js-engine-internals mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals