
JavaScript Is C - pcr910303
https://v4.chriskrycho.com/2018/javascript-is-c.html
======
roenxi
C was famously well designed. The problems it was well designed for have
disappeared and its good ideas are so well understood that, like many great
early works, they are cliches that can no longer be recognised for their
brilliance because everyone is doing that.

C's flaws are real, but they exist in the context of that design. For example,
C has bad memory management because it was built when programmers had kilo- to
mega- bytes to play with and needed perfect control.

I'm not sure anyone could ever accuse anything related to the internet of
being 'designed'. Even being standardised is a stretch. Javascript isn't C,
because C is an extremely focused attempt to solve specific problems.
Javascript simply does not attempt to tackle the same problems as C and it
doesn't attempt to tackle them in the same way.

It may be that they are both fail to solve the big problems in web
development, but that is not really a thing worth comparing languages on.

~~~
skohan
> The problems it was well designed for have disappeared

I think C is still an incredibly relevant language. There are still plenty of
cases where it's useful to have a very simple, un-opinionated language for
working close to the metal. I think C as "portable assembly" is still
incredibly useful, and no other language has really filled that slot
perfectly.

> C has bad memory management because it was built when programmers had kilo-
> to mega- bytes to play with and needed perfect control.

I don't think C's memory management is bad. It's not right for heaps of
problems where it's not needed; for example for things like front-end work, or
server software where the main concern is stability, manual memory management
is unnecessary. But for domains like computer graphics, or for optimizing
compute-bound workloads, manual memory management is still completely
relevant.

To me, the parts of C which seem a bit dated are the lack of some basic
"quality of life" features we take for granted in most languages. For
instance, I would be happy with a language almost exactly like C, but with a
slightly more powerful type system first-class optionals, and some syntactic
sugar for dealing with arrays (i.e. counts, map/reduce/filter functions etc.)

~~~
zucker42
I don't think C is un-opinioniated. It's opinions are just quite popular, so
people don't think they are opinions.

~~~
skohan
I mean, there are always matters of degree. Sure C imposes _some_ structure by
nature of it's syntactic choices, but it's extremely wide-open when compared
to other programming languages.

Lisp, for example, is very opinionated when it comes to things like side-
effects. Go is opinionated when it comes to how memory should be managed. Rust
is opinionated about when data should be readable and writable, and passed
between threads.

C doesn't impose any of these restrictions, largely by virtue of being low-
level, and moreover, it should be possible to implement whatever data
transforms are implemented in any of those other languages in C as well. The
inverse is not the case, so I would argue that C is more permissive than any
of those languages.

~~~
earenndil
> Lisp, for example, is very opinionated when it comes to things like side-
> effects

Ermm...no, it's not. Functional programming languages do tend to do that, but
most lisps aren't functional--certainly, it's not a defining characteristic of
the language family.

> C doesn't impose any of these restrictions, largely by virtue of being low-
> level, and moreover, it should be possible to implement whatever data
> transforms are implemented in any of those other languages in C as well. The
> inverse is not the case, so I would argue that C is more permissive than any
> of those languages.

1\. Turing equivalence.

2\. _Because_ it's so close to the hardware, c inherits the opinions of all
the major ISA designers.

~~~
skohan
> Ermm...no, it's not. Functional programming languages do tend to do that,
> but most lisps aren't functional--certainly, it's not a defining
> characteristic of the language family.

Fair enough. I haven't worked with Lisp since university days, but I think the
point stands with any strict functional language.

> 1\. Turing equivalence.

Ok technically it's possible to write programs which perform the same
computation any two turing-complete languages, but what I mean is that, for
example, it's easier to emulate _how_ an arbitrary Go program performs that
computation from C than in the other direction.

edit:

> 2\. Because it's so close to the hardware, c inherits the opinions of all
> the major ISA designers.

That's one way to look at it. Another way is that C just gives you an
interface to the hardware as it is, and doesn't make many judgements about
which abstractions should be built on top of it by default.

------
shakna
I would happily argue that JavaScript is _worse_ than C.

For example, this [0] is quite obviously outputting a string to the console,
isn't it? (Hint: some of those seemingly random characters pull a double quote
out of JS' leaky guts.)

And whilst TypeScript can help by identifying some types... The syntactic
difference between one type and another type can easily be hidden from the
programmer.

One mistake, one service sending one type when you expect another (we promise
we will always send a fully-formed object or plain text, oops we sent a list),
and you end up only hitting the error ten levels deep and not knowing how
things got so badly mangled.

Type safety is hard. Type safety in a language that desperately wants to be a
string is nearly impossible. If you look at anything the wrong way, it will
become something else.

At least with C, if I try and treat something as a size_t it will try and
behave like a size_t. It might not actually be the right type and cause
problems that way - but the behaviour is within the expected bounds.

[0] [https://gist.github.com/shakna-
israel/b0c1a5ef0171b265ce7f6e...](https://gist.github.com/shakna-
israel/b0c1a5ef0171b265ce7f6ef479be7497)

~~~
tiborsaas
Does this make C++ a horrible language?

[https://gist.github.com/aras-p/6224951](https://gist.github.com/aras-p/6224951)

Just because you can write horrible things in a language it doesn't mean it's
bad. Just like you can drive your car to a wall doesn't mean your car sucks.

~~~
pjc50
> Does this make C++ a horrible language?

As a C++ programmer from before it was standardised, I would happily say
"yes". Unfortunately it has some properties which make it too useful not to
use in some situations, and the default shared library linkage on most
platforms only works for C or C++ style languages.

Edit: no, it's worse than that, there's no truly reliable C++ ABI! See
[http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2014/n402...](http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2014/n4028.pdf)

Inter-linkage of C++ programs tends to be done over "extern C" ABIs, or
"object broker" systems (COM, CORBA etc).

Possibly the next closest system is C#'s MSIL, which is almost a first-class
platform citizen on Windows, and allows you to interlink assemblies produced
in different languages (F#, "managed" C++, VB). Even then it's capable of
alarming confusion depending on whether you've used a "framework" or "core"
version.

~~~
matheusmoreira
Using anything other than C makes one's code unusable as a general purpose
library due to the complexity of the binary interfaces. Writing C++ ensures
the code won't be touched by anything but more C++ code. A Python script can
load a C library shared object, resolve a symbol to a function pointer and
call it. I don't think I'll ever see Python load a C++ library shared object,
obtain a pointer to a C++ object and call methods on it using the C++ ABI and
handle the C++ exceptions it may throw.

The only way to interoperate is to sacrifice all the benefits of C++ and adopt
a C interface. Rust has this feature as well. I like how the creator of Zig
put it: if it doesn't speak the C ABI, someone's gonna rewrite it in C.

[https://youtu.be/Gv2I7qTux7g?t=2m](https://youtu.be/Gv2I7qTux7g?t=2m)

~~~
bluGill
In practice the C++ ABI issues are only on Microsoft Windows from what I can
tell. Everything else seems to have long ago standardized on the itaniam C++
ABI, with one c++ standard library for everything in the system. Upgrades do
happen, but they are major system updates where you are required to rebuild
everything (generally by installing packages) so it all works. It is possible
to violate those, either with a different ABI, or a different incompatible
library of course, but in practice nobody does.

Microsoft has their own ABI (which is annoying, but otherwise there is nothing
wrong with it), but they made the "mistake" of tieing it and the standard
library to the compiler not the system thus ensuring you will generally have
more than one ABI to worry about unless you are careful. They do this because
they have a rule that if it ever ran on a Microsoft OS it will still run (I
think they have dropped some DOS and Windows 16 support, but otherwise they
are famously bug compatible when bugs are exploited). I understand why
Microsoft made these decisions, but for developers they are a problem.

~~~
matheusmoreira
Even if it is stable, it's still far too complex. The compilers generate so
much machinery it's not realistic to expect interoperability with foreign
code.

~~~
bluGill
It works pretty well on unixish systems. It is complex of course, but that is
on the compiler writers not the developers.

------
mirekrusin
Next week - "Haskell is C" \- because you can write program that compiles and
doesn't do what you want.

Nobody ever claimed that flow/typescript magically makes your code bug free.

It will help with stupid mistakes. It will help with invariants at the type
level, but it won't guarantee anything because there are ways to supress it.
It will not help with value/runtime invariants because it doesn't have any
dependat-type constructs (you can use things like flow-runtime to get some
extra help if needed during runtime, but it will be likely slow if you use it
everywhere, maybe cherry picked places is good compromise, depends on what
you're trying to solve).

Things like immutable collections and/or better architecture should help.

~~~
ylyn
The author isn't claiming that someone claimed that either.

S/he's just saying that s/he likes Rust/Elm because they check more invariants
than C/TypeScript.

In other words, "no one said it does" isn't really a useful response to "I
don't like X as much as Y because X doesn't do A but Y does."

~~~
yoz-y
They might not claim that but the article’s title and gist still is
“JavaScript is C because of this one reason”. This kind of comparison is just
not useful.

~~~
bovermyer
I disagree. It changed how I think about JavaScript a little. As such, it was
useful for me.

Be mindful that you do not mistake _what_ we think for _how_ we think.

~~~
yoz-y
I think the point the article makes is good, I just don't like how the
comparison was made. I don't think the article would be of less value if the
author dropped the "JavaScript _is_ C" peppered all around it.

~~~
CathedralBorrow
Is there a difference between "I don't like this" and "This is not useful"?

~~~
yoz-y
There is. But in this particular case I stand by my point, a cursory glance
will show that JavaScript is nothing like C. Starting an article with such a
premise and re-stating it repeatedly smells like clickbait to me. Also it
devaluates the point made by the article which is actually good.

------
truth_seeker
> Earlier this week, I was working on a problem in the Ember app where I spend
> most of my day job, and realized: JavaScript is the same as C.

No sir, you have realized that Ember is promoting JS as C.

Throughout the whole article the author is trying to shift responsibilities to
compiler or he is seeking a solution which is closer to DSL.

If compiler or typechecker disciplines are more important, why not explore
eslint plugins and typescript advance types and use them appropriately before
jumping directly to new programming language and relatively limited community
?

~~~
jdance
I would guess whatever you do on top of typescript, its still a superset of
javascript, which will always have holes in it. Its that 100% guarantee that
the author is looking for, and that Elm provides.

The difference between 99% and 100% is enormous in my experience. A part of
your brain that constantly evaluated the situation can now be totally at rest,
spending that energy at other things.

Note that I have not used Elm myself, but looking at it I get the point. I
have the 99/100% experience in other things

~~~
Fellshard
This is especially true when it comes to working with JS libraries. Since no
two libraries or JS developers have the same set of ideas for how the
language's components work and fit together - how objects are intended to be
used, standard ordering of arguments, whether to use a functional or an OO
style, etc. - your application will be torn between the dozens of wildly
different libraries you end up selecting, or worse, by those you have no
choice but to select. Every crack in JS will be pulled wide open by that
tension, and even TS' attempt at some normalization will not fully erase that.

~~~
hombre_fatal
Sounds like every language I've used, from Python to Java to Rust.

JS actually has an improvement to offer here with its async-everything
concurrency model taking away one degree of ecosystem fragmentation.

~~~
Fellshard
No.

In general, there is a sense among Python coders of at least concrete schools
of thought for these kinds of abstractions. Java certainly is looser, since it
never clung tightly enough to 'pure OO' principles. Rust is young, and - I
expect - is still developing its standard idioms and common abstractions,
though it has certainly settled on a broad swathe of it already, and holds
strong opinions on what good Rust code looks like.

If I asked something similar of Javascript, you would see very little
commonality between people. It's designed as a Self-y language with functional
leanings, and gives far too unopinionated and broad a leeway to nudge its
developers in any one direction. Furthermore, early browser APIs for
JavaScript - especially when it came to features like window and cookie
interaction - pulled the rug out from under every reasonable abstraction the
language could have been geared towards, choosing unreasonable over reasonable
abstractions.

This leaves the language where it is now - incohesive, incoherent, unsound
when it comes to stitching multiple parts together, because each developer
behind each of those components has a wildly different perception of how the
JavaScript world 'ought to work'.

------
btschaegg
I'm in the camp that sadly does not have easy options to choose a different
language at work (I mainly work in C#), but I'm still very interested in
learning new programming paradigms and techniques.

From this view, and regularly having similar experience with code I have to
dig up for whatever reason, I've come to wonder whether the argumentation on
languages here doesn't ignore a very important aspect: The blogpost (as many
before it) presents the process of understanding your code as a tooling
problem. I slowly come to think that the real problem here is _educating
people to write understandable code_ that those tools really solve.

I've wrestled with some horrible in house Java application multiple coworkers
produced for quite some time now. It has mutable state everywhere and is full
of hacks, bugs and race conditions, although the actual problem really isn't
that complex. (It is so bad that it looks like management even might get past
the sunk cost fallacy regarding a rewrite directly after it has been
"finished"! I've never experienced that one so far.)

After thinking it through for quite some time, I'm convinced that there's a
very simple (and rather elegant) solution to this, but if you want to tackle
such a project, you should at least _know_ about immutable datastructures,
record types, algebraic datatypes and the basic concepts of idempotency and
CSP. But everytime I try to nudge someone in the dev team in the "right"
direction, I feel considerable friction in this regard.

So, more and more, I come to think of the biggest worth of languages like
Rust, Elm, Clojure, Erlang and so on being that they _force_ programmers to
think in different ways (and grow in the process) -- something that gets
handwaved away in other circumstances with "well, it has worked for me so
far…".

~~~
z3t4
I think most people learn those things by experience. Let them maintain their
code for a while, and they will eventually discover why things like "mutable
state everywhere" and "race conditions" are bad. It's only after they have
felt the pain they are willing to buy the solution.

~~~
btschaegg
I would have followed the same reasoning a couple of years ago, but have since
had the "pleasure" of working with people that have been producing this kind
of code for multiple decades. At this point, I've grown more amazed at how
good humans can ignore self-inflicted pain and more cynical when it comes to
believing in their adapability.

Though that obviously does not apply to everyone.

------
z3t4
I like to use something often called "regression tests", that whenever I find
a bug, before fixing it, I write a test that would detect that bug. Confirms
that the test catches the bug, then write the fix, and re-run the test to
confirm that it's fixed. _All_ tests are then run automatically before
deployment. Also if you already know those 2% of the code that can go wrong,
also write tests for those! The only disadvantage with tests are that writing
the tests can be more difficult that writing the actual code. Another strategy
I use is defensive programming; "throw an error if the invariant wasn’t
properly maintained" used together with code coverage and testing. So when the
tests run the code, (or during manual testing) those defenses would trigger. I
leave the defense on even in production, and log all errors (if on server) or
generates a bug report, that users can submit with the click of a button, if
in a user interface. The problem with defensive programming is that even if
you have a call stack and state, it can still be hard to figure out the steps
that lead up to the bad state. So you need some levels of logging.

I do not consider testing (TDD) or defensive programming a band-aid for bad
language design, they catch many sorts of issues, not only type errors. Even
if your code is very beautiful, you still want to verify that it works.
Although demoing the app, or putting the app in-front of thousands of users,
is probably the most effective way of finding issues.

~~~
josephg
I used to make this argument, but I think I was wrong. I sort of hate working
in javascript projects I’ve written with a million tests, because if I want to
refactor something, it takes 3x as much work because of all the tests I need
to rewrite.

Lately I’ve been really enjoying typescript and rust. The ability to write
code and if it compiles run it and have it be correct is like a cool breeze on
a summer day. In typescript I need to write fewer tests (because the compiler
catches bugs that I would need a unit test for in JS). But also, when I
refactor something the compiler gives me a list of all the places in my code
which I need to update. In JS I have learned to worry about lingering bugs
that I just forgot to write unit tests for or something. With a typed
language, that fear is (mostly) gone. It’s a lovely quality of life
improvement, and it noticeably improves my velocity.

~~~
z3t4
I do not like traditional unit testing as the tests are glued to the code,
then I would rather write assertions in-line together with the function!
Instead I take a black-box approach, for example a HTTP server is tested by
making actual HTTP requests to it. That way you do not have to rewrite the
tests when you change the code - just add additional tests.

~~~
bluGill
That is another useful way of testing. The problem with it is eventually you
write some low level code and realize that sometime in the future someone is
likely to use your new code in a way that will expose a bug - but right now
something higher level prevents that bug, and you have no idea how to prevent
it with assertions inline and the outside black box tests can't cover this
case yet.

For large complex systems all levels of testing are needed to get the best
quality.

~~~
z3t4
I use defensive programming, as in throwing errors when something is used the
wrong way. Assuming that the developer always run the code at least once
before shipping. But I try to avoid thinking into the future. I'm already too
good at finding edge cases, that if I would also think about possible issues
that might arise in the future, I would get nothing done. I instead wait for
it, and then fix it only when it has become an issue. Especially in
optimization, I often fall into though traps like "what about when this table
has millions of rows, this query would take a long time", I have to remind
myself of the problem and what the priority is _right now_. While there is
code debt, there is also opportunity cost.

------
marijn
Rust is also C, if the fact that you can't encode all possible invariants into
the type system makes a language C. But this is a spectrum, not a dichotomy,
and TypeScript falls somewhere way beyond C, but below Rust, in what you can
statically encode. And Idris lies beyond Rust.

------
atilaneves
> In Rust, I can be 100% confident that I will not have memory-unsafe code.
> Not 98%-and-I’d-better-check-those-last-2%-really-closely. One hundred
> percent. That’s a game-changer.

Also achievable, and far more easily, with a tracing GC. Do you know all those
people worrying about memory safety in Lisp decades ago? Me neither.

~~~
dgb23
I agree. Memory safety is a problem solved 60 years ago and adopted by most
mainstream languages, or rather most languages period. Rust doesn't solve
memory safety, it just lets you do it in a more performant way.

But the compiler does quite a bit more than just allow for performant memory
safety. It enforces rules around mutability and handling errors which are
usually only seen in functional languages.

None of these things are special about Rust. The special thing is that Rust
can do these things with less computer resources while asking more of the
programmer.

And this is a general truth. Type systems add friction and force programmers
to deal with details from the very beginning. In the long term this might
often be a good thing, but it certainly isn't ergonomic.

~~~
carlmr
>Type systems add friction and force programmers to deal with details from the
very beginning. In the long term this might often be a good thing, but it
certainly isn't ergonomic.

In Rust, I agree, but I find coding in C#/F# which are decently typed, but
with GC, is much faster for me than using e.g. Python. Typescript is much
easier than Javascript.

Lack of types usually leads to worse auto completion, errors maybe only found
on some edge cases which I didn't try and a huge slow down if I need to add a
feature when I've forgotten about the code, since they provide a lot of
documentation where you know that it's not stale.

I wouldn't use python at all if it didn't have pandas.

~~~
dgb23
Auto-completion for some dynamic languages has gotten much better with the
right tools/editors/plugins.

I get where you are coming from but I would argue that there is a bit of a
perception issue here. You can surely write fast in typed languages but you
also have to write more and think more.

But I fully agree with the benefits. Errors, changing/refactoring and
documentation.

I wonder if we can have the best of both worlds some day. Prototype
dynamically and then add types and abstraction progressively in the same
language and code base. In theory this is doable with Lisps, but only in a
self-imposed, possibly unstructured way.

------
flohofwoe
Oh, he's just trying to sell Rust ;)

IMHO, Javascript is the _C++_ of dynamic languages. It suffers from similar
early bad design decisions, which now a "committee" tries to fix by piling
layer upon layer of complexity upon the broken base without ever being able to
undo those early bad decisions.

Actual C is a clean and simple language both compared to Javascript and C++.

~~~
mac01021
I don't think thw committee's options are really so limited. They could
totally have defined a JavaScript 2 not backward compatible with JavaScript 1.
Browsers, of course would have then had to support both, but who cares?
Especially if there were a good FFI between the two, noone would have been
inconvenienced (except browser developers)

~~~
fermuch
Wasn't that what Dart tried to do?

------
olingern
Everyone loves a good Javascript punching bag but I would argue that the
language/ecosystem has the most inertia and positive change within it. It's
not perfect and it's exhausting at times, but I'm confident that the language
will continue to move towards something more robust and ergonomic.

One more thing to note. From the post:

> In a C application, try as hard as I may, at the end of the day I am always
> on my own, making sure the invariants I need for memory safety hold. In
> Rust, I can be 100% confident that I will not have memory-unsafe code. Not
> 98%-and-I’d-better-check-those-last-2%-really-closely. One hundred percent.
> That’s a game-changer.

I think if you're always leaning on a compiler for correctness, maybe your
problem doesn't reside in the static vs dynamic debate.

~~~
gerbilly
In the computer world, the worst thing often ends up winning.

The reason? Market forces are more powerful than technical features.

This means that if you rush a bad implementation out the door and it gets
adopted by the masses, the network effects will ensure your bad solution wins.

Meanwhile, competitors that are working on a high quality competing language
or product will be later to market and miss the train.

See:
[https://en.wikipedia.org/wiki/Worse_is_better](https://en.wikipedia.org/wiki/Worse_is_better)

~~~
t0astbread
It should be noted that because of market adoption, an ecosystem can grow to
have more value for the end user than a more complete but new competitor.

------
chriskrycho
It's pretty obvious that people are reacting to the headline without having
actually internalized the content of the post. Fair, I suppose: it was a bit
wild of a title, and the post was pretty off the cuff. This is the bit I
really wish people would take away from it, though:

> Neither of those is a guarantee I won’t have bugs. (A compiler that could
> guarantee that would have to be sentient and far smarter than any human!)
> Neither of them means I can’t intentionally do stupid things that violate
> invariants in ways that get the program into broken states from the user’s
> point of view. But both of them give me the tools and the confidence that I
> can absolutely guarantee that certain, very important kinds of invariants
> hold. We’re not looking for an absence of all bugs or a system which can
> prevent us from making any kind of mistake. We’re looking to be able to
> spend our times on the things that matter, not on minutiae the computer can
> check for us.

~~~
carapace
> We’re not looking for an absence of all bugs or a system which can prevent
> us from making any kind of mistake.

( _Some_ of us are looking for that.)

~~~
chriskrycho
Indeed! Thus the Assumed Audience header at the top of the post! It's
unreasonable to expect anyone to qualify everything they say in every blog
post they right, I think. ;) See also:
[https://v4.chriskrycho.com/2018/assumed-
audiences.html](https://v4.chriskrycho.com/2018/assumed-audiences.html)

------
rob74
Even though the first paragraphs are about JavaScript and C, I already had a
hunch that it would turn out to be about Rust in the end :D

~~~
enriquto
It's the all-encompassing Rust Evangelist Strike Force!

~~~
mxcrossb
You could tell as soon as you read the top of the page and saw it was a blog
about theology :)

~~~
xenocratus
Do you have a moment to talk about our Lord and Saviour, Rust?

------
tybit
I thought this was going to compare C and JavaScript as being imperfect
languages that are ubiquitous as the Lingua Franca of their respective
platforms, Unix and the web. I’d be interested in seeing that explored.

~~~
chriskrycho
Oooh, that _does_ sound like an interesting post.

I also have some unpublished notes on the value of taking the “make JS/C
better via tools etc.” path even when the other is available and why. It’ll
likely generate less interest than this one—less provocative by a lot!—but
it’s actually what I’m doing in my day job right now!

------
larusso
I would love to have an example of what exactly he is writing about. I spend
most my time at the moment to rewrite some code from JS to Rust and still
fight with invariants. I would like to know how to achieve the 100% safety. I
know that I get most of the null pointer exception etc handled with Option and
Result structs. But if you need to deal with string values etc the compiler
can’t really help out when the value is not the one you’re expecting. And I
also moved most of these to enums.

~~~
shpongled
That is how I would handle that - you lex or parse your strings into an
Option<Token> (or Result, etc), so that then all logic operating on the Token
enum doesnt need to worry about whether it's a correct value - it's statically
enforced.

I personally find the most value out of sum types (enums with data) and the
ability to use Option/Result with the try operator '?' for this kind of stuff,
where you can float errors up the call chain

~~~
larusso
Ok I kind of doing that already. The main issue I have is that some data comes
from configuration and I can’t create static values for those (URLs for
example). Thanks

------
sundarurfriend
The author means the title in a specific way that they explain in the article,
so it's somewhat disappointing to see the comments taking it as either just
C-bashing or saying "JS is good for _some_ things" as if the article said it
isn't.

Some people here might remember the mental shift from programming in old
school BASIC to doing it in C or another procedural language; having functions
as a tool gives you certain guarantees and allows you to program on a
different mental landscape. The author is talking about a similar mental shift
here, and saying that JS and C are similar to him in that they require him to
program in the older landscape. This kind of thing is something we as
programmers experience often in many levels, and something we should be able
to empathise with - whether we agree or vehemently disagree with it, we can at
least start by understand the sense in which the author is writing the
article.

------
brlewis
This could really use an example of an invariant that couldn't be elegantly
enforced with property descriptors[0] and decorators[1]. Without such an
example it's just flamebait.

[0] [https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) [1]
[https://www.typescriptlang.org/docs/handbook/decorators.html](https://www.typescriptlang.org/docs/handbook/decorators.html)

------
zoomablemind
This reminds me of my early C days dilemma: "Check for a disallowed NULL
pointer argument on function entry or just trust that it will have a valid
value?" And a mixed feeling that would settle after putting an assert there.

Eventually, one develops a "pragmatic trust", appropriate to the level of
interactions in the code.

After all a state change is a kind of input resulting from an interaction.
Some interactions are more trusted than others.

Asserting reality after every handshake is not going to make one feeling
safer. Operating in a trusted environment and understanding and upholding its
premises does add one more member to enforce that "safety in [sane] numbers".

------
carapace
" If you have only ever programmed in C/C++/Java and Lisp and scripting
languages, you have been sitting in a corner your whole life. Perl, Python,
Ruby, PHP, Tcl and Lisp are all the same language."

~ Frank Atanassow, "Some words of advice on language design"

[http://lambda-the-ultimate.org/node/687#comment-18074](http://lambda-the-
ultimate.org/node/687#comment-18074)

Fuller quote: > Go study Scheme and Prolog and ML and Haskell and Charity and
Lucid Synchrone and OBJ and Erlang and Smalltalk. Look at Epigram or Coq or
HOL or LEGO or Nuprl. Aside from Java, these are the important ones. If you
are familiar with all of these, then you are in a decent position. If you have
only ever programmed in C/C++/Java and Lisp and scripting languages, you have
been sitting in a corner your whole life. Perl, Python, Ruby, PHP, Tcl and
Lisp are all the same language. (Scheme itself is only interesting for
hygienic macros and continuations.)

~~~
kazinator
If you think Perl, Python, Ruby, PHP, Tcl and Lisp are all the same language,
you've been sitting in another corner all your life, one possibly not as well
illuminated as the C/C++/Java corner.

~~~
carapace
Well, I don't think he's being literal. He's saying (I think) that _all_ of
{C, C++, Java, Perl, Python, Ruby, PHP, Tcl, Lisp, Go, etc...} are of an ilk
when considered against the wider realms of programming languages. In other
words, they are each more similar to each other than any of them are to, say,
Prolog.

------
jonny383
Enough with the click-bait titles already!

------
7777fps
I think it's fair to say that, "Javascript's packaging is as bad as in C".

While ES6 modules make minor improvements in syntax, the entire npm ecosystem
relies on commonjs resolutions which aren't that far under the hood to
including header files wholesale.

Then you have the build system which you have to know your way around babel,
webpack, and a whole suite of arcane tools each of which with very fragile
equivalents to make files with similar nonsense errors when builds fail.

Javascript isn't C, but the ecosystem is a nightmare compared to modern
languages with modern language features such as first class package
management.

------
FpUser
1) JavaScript is NOT C.

2) There is nothing wrong with C. It was DESIGNED to service specific needs
and does that just fine

3) I think this obsession with "safe languages" is being taken too far. Safety
does not come free, we pay for it. Mostly in performance which is a valuable
"feature" for many types of software. Not gobbling all computer memory running
"Hello world" helps too. Besides automatic memory management and "everything
is immutable" does not really make software safe either.

~~~
timw4mail
3) It's not "safe languages", it's "memory safe languages". The whole point is
to make very common security vulnerabilities due to unsafe memory usage much
less common.

Rust and garbage-collected languages have memory safety. C/C++ do not. That's
the whole point.

~~~
FpUser
C/C++ have enough tools to detect and get rid of memory leaks. Quite frankly
memory safety ceased being a practical problem to me years ago.

~~~
timw4mail
That assertion would carry much more weight if not for the constant barrage of
security vulnerabilities due to memory issues.

------
lidHanteyk
The analogy doesn't make sense; they analogize C to Rust, as ECMAScript is to
Elm. I am forced to conclude that these are the only four Turing-complete
languages that they know.

~~~
Lapsa
Yeah. Analogy seems more harmful than useful. "Stuff changes, getting errors -
must be C".

------
tempodox
That's an interesting fact about Elm I wasn't especially aware of. Maybe I
should have a closer look at it, even though web front-end stuff is not my cup
of tea.

------
pier25
The problem with Elm is that you end up writing a lot of code.

Check this comparison of real world complete projects (not to-do MVC
examples):

[https://www.freecodecamp.org/news/a-realworld-comparison-
of-...](https://www.freecodecamp.org/news/a-realworld-comparison-of-front-end-
frameworks-with-benchmarks-2019-update-4be0d3c78075/)

Almost 3 times more loc than Svelte.

I know that loc is not the ultimate measure of verbosity, but still.

------
m00dy
_INSERT_YOUR_FAVOURITE_JAVASCRIPT_TYPE_COERCION_HERE

------
tetron
And TypeScript is C++ for the JavaScript ecosystem, with all the good and bad
things that implies.

~~~
chriskrycho
I think this is exactly right! I didn't go back and add it to the article when
it later occurred to me, because this was just a "thinking out loud" kind of
post, but the _exact_ same analogy occurred to me.

------
seemssilly
So the author can't solve a problem, goes ahead to say that javascript is c
because of one situation, then promotes rust by the end. All with a clickbait
title to boot.

I'd be more angry but this type of formula for an article is used so often now
that it should be expected.

I can't wait until people figure out that the individuals that aren't
competent enough to handle C's issues, aren't going to be competent enough to
handle Rust's either.

Hopefully the Rust hype train dies soon. There is simply too much
bandwaggoning involved in this language to keep bias out of the equation when
considering using it to solve a problem.

~~~
shpongled
Have you given Rust an honest try yet? I thought it was a hype train too at
one point, but I started using it, realized that the hype is well founded and
never looked back.

~~~
seemssilly
I haven't but that wasn't my point at all when saying that. It is on a hype
train, whether that hype is justified or not is not what I was trying to get
at. What I was saying was that this hype and massive surge in use and
publicity causes an inevitable bias which clouds judgement when deciding
whether or not to use it. That crowd of programmers that seem to hop on every
computer fad, the ones that have been adding hashtag reactjs to their twitter
posts for the past year, they're probably going to choose rust regardless of
whether or not it should actually be used. The bitter contrarian is probably
deciding not to use it because he's sick of seeing it mentioned in every other
tech blog post in the past year. As soon as this hype dies off, both of these
groups can move on and hopefully decide whether rust is actually worth using
for whatever they need done.

I would use it if it's the right tool for the job. I just want to stop seeing
it mentioned 20+ times a day and snuck into blog posts that started off as
critiques/comparisons of two other languages.

~~~
chriskrycho
I don't think you understood the blog post (which is presumably my failure as
an author; it was just an off the cuff post and I didn't edit it especially
carefully). The point is not to compare JS and C (interesting though that
would be) but to note ways in which _both_ of them may be slowly superseded by
languages which target the same environments they do but allow much more
developer confidence along certain axes—and, in my experience, therefore also
a better developer _experience_ and higher _productivity_ along those axes.
The whole _point_ was that Rust, Elm, etc. can and do prevent whole classes of
problems that are difficult (at best) to eliminate when writing C or JS
respectively—Rust and Elm (and F and OCaml and Haskell and Idris and…) were
_essential_ to the point I was getting at.

One of the challenges for dealing with hype is that things which are
legitimately really good tend to get hype, but things which get hype aren't
necessarily good. In my experience, Rust is actually really good (so much so
that I ran a podcast about it for a couple years). So are lots of other
things. It's not perfect, by a long shot. But while there's some of the
_people hyping it because it 's cool_ phenomenon—that's real!—people also get
excited by finding a tool they really enjoy, that solves real problems they
experienced previously.

------
butterisgood
A love letter to Elm in disguise with rationale. I like it!

------
keithnz
Tl;DR; some pattern in language X seems similar to language Y therefore X ~= Y
. Argue why said pattern makes it hard to program in language X or Y, posit
language A and B as saviors.

I find it hard to be charitable to these kind of articles. Not that I disagree
with the problems expressed, or the advantages of certain languages making
certain guarantees. Everything is a tradeoff, and I think you have to be very
aware, contextually, what exactly are you leveraging in order to get a certain
result. That extends beyond the product itself to things like lifetime, and
human factors. I'd like to see these kind of articles more of the "Consider A
|| B given these kinds of conditions, beware, this may not be suitable for
reasons H I J...".

~~~
chriskrycho
I actually strongly agree with this. Notably the post doesn’t say anything
about what you should choose in a given context. I’m in a context right now
where I support a pure JS (not even TS yet!) app, and while a colleague and I
occasionally joke about rewriting it in Elm, that’s literally a non-starter in
reality (and all I’d never suggest it in reality!).

Most of the comments here seem not to have grasped that the basic point of the
post is that advances in programming language design—here, specifically around
types—can make for _real_ differences in your confidence when shipping. And
that’s valuable! It’s also not the _only_ value… but then, I never said it
was, either.

------
volument
This is nice. I have always wanted to be a C programmer. Now I can just stick
to JavaScript and take all the same credit.

------
Aeolun
I just wish there was a decent way around Javascript, but even With
TypeScript, React, Redux and Redux-Saga, basically using everything we can to
give some structure to the application, it is still a clusterfuck.

I really, really enjoy the paradigm of the basic HTML application because so
many problems just magically go away.

------
wruza
tl;dr: No code was presented, but it feels like Ember was pushing unexpected
arguments to a typescript function, messing it up. Author then goes all rust,
hoping that it would catch broken invariant automagically, because it leaks no
memory. Thus JS is C.

------
known
[https://en.wikipedia.org/wiki/Apples_and_oranges](https://en.wikipedia.org/wiki/Apples_and_oranges)

------
0xdead
The author should have shown some code, because it certainly feels like
they're talking out of their ass. "Javascript is C" wtf does that even mean?

------
stjohnswarts
Meh it's 80% coder and 20% language

------
mhd
JavaScript is Fortran. Used to be Fortran66, now Fortran77, Ratfor is a thing
again.

~~~
vaxman
Let's not forget Fortran IV (RIP Mariner-1) --and Fortran 5 (ok lets
[https://youtu.be/cL_Ilhd7Odo](https://youtu.be/cL_Ilhd7Odo))

------
n0mad01
JavaScript = JavaScript

C = C

JavaScript Is C = clickbait

------
hootbootscoot
war is peace. freedom is slavery. javascript is c

luckily the rust evangelism strike force saved us from errors. once we rewrite
everything in rust and webasm, the world will shine with perfection.

posts like this kinda obviate n-gates raison-de-etre...

but at least we all agree that js stinks/long live js

~~~
hootbootscoot
I guess I just accept es5 for the necessary evil it is.

i'm not sold on the orm approaches.

typescript, reason, svelte, etc, all bring interesting ideas to the table.

end of the day, you can probably eliminate a lot of cruft from your ui before
actually being required to resort to these things. I still include tag
mithril.min.js and stuff like that plenty, and the world didn't stop nor did I
die writing hyperscript. or js. or html. or sql. or whatever...

~~~
hootbootscoot
of course, the ultimate loop is simply to use some barely-functioning type-
inferred js to c++ driver to emscripten to webasm. that should satisfy the
minimalist simple-life cravings of node devs.

------
eej2ya1K
C feels good, JavaScript doesn't. Rust is extremist propaganda disguised as an
admittedly pretty good programming language.

------
sn0n
Isn't the real point something like: this is a paid advertisement for elm,
check it out.

~~~
jamil7
Did you read the article? It isn't an advertisment for anything.

