

Writing Code for Humans - ilyoTheHorrid
https://medium.com/@ilyothehorrid/writing-code-for-humans-5b80a89f439c

======
falcolas
> Use Javascript everywhere

And here I thought the author was trying to simplify their life. Using
Javascript on the server is not simplifying your life.

By writing Javascript on the server, they have made it all but impossible to
reason about code's execution order and performance - it's going to depend
entirely on epoll and the underlying threaded IO implementations. They are
also relying on the developer's ability to understand and use continuations
properly.

There are some developers who can do this (just as there are some developers
who can write threading code without any race conditions), but most others
will rely on so many layers of abstraction (which they don't fully understand)
that they are hardly writing Javascript anymore.

"In the past year I think I have finally come to understand the ideals of
Unix: file descriptors and processes orchestrated with C. It’s a beautiful
idea. This is not however what we interact with. The complexity was not
contained. Instead I deal with DBus and /usr/lib and Boost and ioctls and SMF
and signals and volatile variables and prototypal inheritance and C99FEATURES_
and dpkg and autoconf.

Those of us who build on top of these systems are adding to the complexity.
Not only do you have to understand $LD_LIBRARY_PATH to make your system work
but now you have to understand $NODE_PATH too - there’s my little addition to
the complexity you must now know!"

~~~
Touche
Your distaste for JavaScript aside, writing your app in a language that can
run the same exact code on the server and client is a giant win for companies
that have been doing redundant work for years.

~~~
stephenr
I always hear this but I don't buy it.

The client and the server have different jobs to do, how much code re-use is
really happening in real world apps?

~~~
secoif
The real benefit of one language everywhere is reduced penalty for context
switching and flexibility with your architecture.

The promise of "code reuse" is very alluring but reusing _application code_
rarely happens in reality. However, reuse of patterns and libraries is very
common – solve a generic problem once and you don't have to research how to
achieve the equivalent in another ecosystem. Just grab the exact same library,
browserify the thing and you're done (ideally).

"One language everywhere" grants you lots of flexibility – where your code
executes is no longer locked in stone – you can shift responsibilities from
the server to client & vice-versa without significant overhead. No need to
port to a different language which perhaps lacks similar paradigms or tooling.
Doors are opened to optimisations and architectural changes that would not
have even been a consideration otherwise.

To get the benefits of "one language everywhere" doesn't necessarily mean "use
JavaScript" but it's a safe decision to choose the lowest common denominator;
JavaScript is not going out of fashion any time soon, it runs on nearly every
platform and has an ecosystem that's competitive in a wide gamut of problems.
An investment in vanilla JS will pay out in long term, while any investment in
Framework-X or compile-to-js Y or AltJS-Z is high risk and usually only pays
out for the 18 months or so while said tool is in vogue.

JS may not be the best choice, but it's a smart choice.

~~~
xamuel
>reuse of patterns and libraries

While this sounds alluring, in practice I think it would mostly be limited to
the kind of thing where you check something client-side (like whether a
username meets the requirements) and then re-check it server-side because
security 101.

Client-side code is about displaying things, turning JSON into buttons and
widgets, etc. There is no point having that on server-side. The server does
not have a human user clicking buttons and scrolling bars.

Server-side code is about performing calculations and facilitating
communication between different clients. If these can be done client-side,
then there's no reason to do them server-side in the first place.

>An investment in vanilla JS will pay out in long term

This is true, but a lot of JS investment is _not_ in vanilla, it's in whatever
framework is popular that week, and next week that framework will be dropped
like bellbottom pants.

~~~
falcolas
> Client-side code is about displaying things

Actually, JS developers are learning that this is frequently better done on
the server; there are more and more articles every week about the benefits of
pre-rendering the application page on the server side, then letting the client
JS take over and make the server generated code responsive.

I believe the term being used is "isomorphic" javascript.

However, since the Node.js server is inherently single threaded, the cost of
generating these templates server side impacts every connection being handled
by that particular instance.

~~~
xamuel
What JS developers call "pre-rendering" is what everyone else has been calling
"not a static webpage" since forever. It takes willful blindness to ride
around on a bike with square wheels, ignore the round-wheel bikes around you,
then eventually switch to round-wheel yourself and act like you invented it
and it's the next big thing.

~~~
username223
Well, some of these guys are also riding single-speed fixies over a century
after the invention of the derailleur and freewheel. I'm not hip enough to
know if (extraordinarily dangerous) penny-farthings are coming back yet.

------
pjc50
_Cut 80% of your product’s features_

lol

Yes, it's easy to be clear and readable when what you're trying to do is
simple. The hard case is keeping the complexity managed in the face of complex
demands. The real-world analogy for most software is not JK Rowling but the
60,000 page set of contracts running the privatised London Underground.

~~~
br3w5
The writer doesn't quite make the link I wanted between product and code.
Regardless of the number of features, the product should be understandable and
then the application design and tests should be able to be clearly mapped to
the product features, and is well documented.

------
frou_dh
> Macro film photo from my Macbook Air’s display

This is why people make fun of us.

~~~
microcolonel
I tuned out immediately after reading that caption.

Why does it matter that it's macro film? Why does it matter that it's a
Macbook Air? Because the author is all too happy with how tasteful and cool he
thinks he is. It shows through in the rest of the article.

I write full stack js, and this guy is making me look bad.

------
TylerH
Please proofread your articles. Even running it through spell check in
Microsoft Word would have caught many of the errors I've found.

------
hellbanner
April fools is early, huh. Who actually writes "Zen Javascript" in Production?
Examples, please.

~~~
ashark
The only time I feel "zen" writing Javascript is when I'm writing it as much
like C as possible, without touching the DOM, without using 3rd party
libraries (the API of which invariably ruins any "zen" I've got going on) and
certainly without using Node. I don't mind it as a kind of toy language for
playing with algorithms in JSFiddle.

Real-world Javascript, in my experience, is a constant struggle to cram a
dozen call styles for your various npm-fetched libraries in to something
resembling coherence, and god help you if you have to dig in to the code of
any of those libs, because there are so many different styles and commonly-
used libraries serving the same purpose as one another that it's likely to be
like reading a completely different language from what you've been writing.

A dozen competing approaches each for making the language suck less at doing
useful things, code organization, call chaining, _et c._ , and every goddamn
one of them is present somewhere in your stack.

The language is kind of OK. Zen enough in small, controlled doses, once you
know about the usual unintuitive (backwards, broken) stuff like variable
scoping. The ecosystem, every place the language touches the browser (not
Javascript's fault, really), and Node are ripping-your-hair-out un-Zen, IMO.

------
z3t4
An article about writing good code without any code examples.

------
whiskeySix
> Cut 80% of your product’s features

... _closes tab_

------
taco_emoji
This is either bad satire or bad advice.

------
vezzy-fnord
_In each, it took me between few weeks to few months to fully understand their
code-base, and I have about 6 years of experience with JavaScript. This does
not seem reasonable to me at all._

Correct me if I'm wrong, but for entire large codebases, isn't this normal?

The problem is that we still don't have enough developed tools to truly
analyze internal/white-box code relationships (or perhaps we do, but they're
buried in research circles). Expressive programming languages seem to only go
so far. Most IDEs have symbol tables, tree visualization, but those are hardly
enough. UML was a failure.

In contrast, our black-box analysis tools, like the various system tracers
(DTrace, SystemTap, s/l/ftrace, etc.), debuggers, disassemblers, decompilers
and fuzzers, are relatively well advanced.

I don't know if moving to image-based environments would help with this,
though that'd be too profound a leap.

~~~
falcolas
Hmm. This is an interesting topic to think about.

Why aren't the tools for analyzing White Boxes as good as those we have for
Black Boxes? I would say it's due to the differences in boundaries.

For example, Black Box tools have it simple. Capture anything that crosses in
the direction of Black to White. Capturing what goes from White to Black is
much harder, though, since there are less visible boundaries on what can be
accessed. For example - if I write a black box which utilizes a environment
variable, you have to be tracking what memory a program accesses to see this
from outside the program.

White boxes, on the other hand, have very few boundaries, and those which
exist are fuzzy at best. Sure, there are technically functions and modules and
scopes, but these boundaries are soft; frequently and easily pierced. Global
variables, shared memory, inlined functions, tail call optimization,
continuation passing... all of these make it incredibly difficult to reason
about and trace program flow, because the program flow depends so heavily on
the global context.

Functionally pure programming paradigms might be our best bet in the long run:
when a "function" produces deterministic output for given input, we suddenly
create a network of predictable black boxes within our white box, giving us
the edges we need in order to implement our tracing and automated reasoning
tools.

