Thoughts of a C/C++ programmer after years in JavaScript

If you haven’t read the 4 stages of a C/C++ programmer using JavaScript this is a follow up on that so you might want to read that first.

Not that anyone reads this website I only update 3 times a year now but before you get your stockings in a bunch I’m not saying JavaScript rocks. I’m only saying that after using it for many years there’s things I’ve come to love that I now can’t stand when I’m not in it. Example include

(*) no setup

Every device has a browser.

(*) useful apis that just work across platforms

including canvas, webgl, audio api, camera access, gps, etc

Think about what I’ve have to do in C++ to get a cross platform canvas2d like API. I’d probably have to build Skia which is like a gazillion lines of code. I’d have to figure out what bazillion options to pass it etc, watch it compile for 10-15-20 mins and hope no obscure errors pop out. Or let’s take WebGL, sure you’ve got OpenGL on desktops. But, if you actually do any OpenGL programming you’ll find that all the drivers are fucked up in some way you’re not aware of. Then you have to deal with issues of ES (mobile) vs non-ES (desktop). You also have Windows where if your users are not nerds/gamers it’s unlikely they have OpenGL drivers installed. The browsers have solved all of this for you. For the most part WebGL just works, they’ve worked around the bugs for you. Same with audio, and the rest.

Sure you can point to something like SDL but does it run on Android, iOS? I’m sure you’ve got a camera library in libcinder or openframeworks but again does it run on some mobile or only OSX/Windows/Linux?

(*) no build generally so no platform specific IDEs or build systems

If I’ve got a Visual Studio project it doesn’t work on Linux or OSX. If I’ve got a makefile it’s unlikely to work on Windows. Sure if you get a super complicated program you might setup some pre-compilation step. This is pretty much cross platform at this point through node/grunt/gulp etc..

(*) Sharing is so easy

No downloading, no worrying about viruses or having to scan something, no corp firewall issues likely, no needing one of each target platform to build on.

(*) JavaScript’s loose typing makes making shit often ridiculously simple once you stop trying to bring C++/Java/C# ideas to it.

It’s hard to give examples without writing pages and pages of example code. Some simple ones

There’s no need to create interface classes in JavaScript because JavaScript doesn’t care. As long as the function names match that’s all it cares about. So it’s super easy to write mocks or make more than one implementation of something.

  logger = {
    log: function(msg) { console.log(msg) },
    error: function(msg) { console.error(msg) },
  };

  dummy = {
    log: function() {},
    error: function() {},
  };

Need some data, just start typing

   var orge = {
     hitpoints: 27,
     shield: 34,
   };

   var dragon = {
     hitpoints: 653,
     shield: 57,
     immuneToFire: true,
   };

I didn’t have to go define some class or struct first. I didn’t have to know every minor variation I might need. Just write code

   function giveDamage(enemy, type, damage) {
     if (type === 'fire' and enemy.immuneToFire) return;  
     enemy.hitPoints -= damage;
   }

It’s so gawd damn simple. In C/C++/C#/Java land I’d have to create a class, then start adding fields. If I added a field in the middle I’d have to go hand fix each and every static declaration. If I end up with too many fields that were only used by a few types of enemies each I’d have to start designing some specialized “extra” field that points to these specialty fields just so the main class isn’t cluttered. .

I’d probably have to make it some specialized generic container and then get accessors like this

   void giveDamange(Enemy ememy, DamageType type, int damage) {
     if (type == DamageType.Fire) {
        BooleanField* b = emeny.GetExtraField<BooleanField>("immuneToFire");
        if (b && b->value() == true) {
          return;
        }
     }
     enemy.hitPoints -= damage;
   }

Now imagine all the code I needed to write to make GetExtraField. I’d need some base class “Field” which would probably be 10-20 lines of code. I’d need a collection class to hold them, more lines of code. I’d need some private untyped version of GetExtraField that returned a the base Field class. Then I’d need some templated type of GetExtraField I could pass in a concrete type, it would get the untyped field by name, check some “is” function if it’s the correct type, if so downcast it to BooleanField and finally return a type safe concrete accessor. I’d probably have written 100-200 lines of code to do that. And worse, now I could no longer add them statically by typing a few lines of code Each one would have to be hand added at runtime in some init function. In JavaScript I don’t care. All that disappears. Yea I know JavaScript is doing runtime initialization but it’s mostly hidden in terms of what I actually have to type.

Now of course JavaScript sucks for those very same reasons. Every time I track down a bug and it’s one that would have been caught at compile time in a strictly typed language it’s kind of annoying. But, I wonder if there’s some middle ground. Could we design a language that had all or most of the flexibility of JavaScript AND the some/most/all of type safety of C/C++/C#/Java and the speed of C or at least optionally.

For example C# has struct vs class. An array of structs in inline whereas an array of classes is actually an array of references to instances of the class. That seems like an interesting idea. Maybe we could have class, struct and bag or something where bag is like JavaScript’s objects and class and struct are like C#?

Or maybe the compiler of this new language could do more global stuff so for example maybe without declaring types it could just guess them and then check at link or compile time they are all consistent.

   someFunc(a, b) {
     return a + b;
   }

Later I do

   c = someFunc(1, 2);

Oh, a, b, and c are ints so generate that function. If it sees

   d = someFunc(1.2, 3.4)

Then generate that. Maybe I could mark it as “must be consistent”

   someFunc!(a, b) {
     return a + b;
   }

Now if it’s used inconsistently the compiler complains?

Note I’m speaking out of my ass. I have no idea if these ideas will work, if they already exist in other language, or what.

How about this

   f = {
     name: "orge",
     hitpoints: 120,
   }

Should that be enough to know that F is a

struct AnonStruct {
  string name;
  int hitpoints;
}

What about this?

   monsters = [
    { name: "orge", hitpoints: 120, },
    { name: "orc",  hitpoints: 20, },
    { name: "rat", hitpoints: 1, },
    { name: "dragon", hitpoints: 700, canFly: true, },
   ]

Can the compiler figure out that monsters should be defined as

struct AnonStruct {
  string name;
  int hitpoints;
  bool canFly
} monsters[] = ...

Another idea is what if the compiler could look at all uses and decide if it can make something a struct like the example above or if it needs to remain a bag. JavaScript runtimes or at least V8 actually does this but I’d like it to do it at compile time. Decide if it’s a struct or a bag, pick one, then fail at runtime if it’s not used that way maybe? Then optionally give it a way to enforce it at compile time so you can track down stuff. If you say X is a struct then the compiler can check. If you say it’s bag then even if it thinks it could be a struct at compile time it leaves it a bag.

Anyway, I have no idea. I see Jonathan Blow is working on his language. I’ve talked to some language guys who say he’s basically repeating what research found 20, 30, 40 years ago and doing it poorly. I’d like to know more about what they’re talking about. I don’t agree with J.Blow that GC is evil. Sure, I used to think that but even Unreal engine uses GC and tons of AAA games have shipped with it. Similarly tons of Unity games are shipping just fine with GC. Knowing when it’s ok and when it’s not is fine but forcing you to do everything manually because you don’t understand GC is kind of stupid. It’s kind of like saying everything should be written in assembly language. No, a few down to the metal things should be, similarly a few down to the metal things should not GC, but overall GC works just fine just like scripting languages and blueprint systems work well for certain classes of problems. Don’t throw out the baby with the bathwater and all that.

Anyway, that was the long way of saying the point is going back to C/C++ is not fun for the reasons above. I feel like people who’ve never stopped C/C++ don’t understand that. I was certainly one of them at one point but I’ve had my mind expanded 😉

  • Justin Liew

    Interesting thoughts. I agree that the lack of friction in JS is great to get things up and running, but maintenance can obviously be a nightmare.

    I’ve seen JB’s compiler talks come through my Twitter feed but haven’t really kept up. While I commend his effort, and I tended to agree with a lot of his initial talk’s points, I do feel like it’s a bit of a pipe dream. Also, I want to play The Witness!

  • Liberty Prime

    If you are missing a compiler type checking, Typescript is an awesome option. And its still javascript.

  • fláráðr ljós

    I’d like to take this moment and point out that SDL2 indeed does run on Android and iOS!

  • Yea I knew that. Except I also know getting it setup will take 8+ hours of fighting with the Android SDK/NDK spaghetti nightmare. 🙁

  • harjay

    how much does a android game cost?
    what are the features?
    how long it takes to do it?
    is there any maintenance?

  • Mr Kad

    c++11 has an “auto” keyword now, javascript is great

  • Willy StarTec Nolan

    So my question, as someone who knows Javascript fairly well, should I focus on just mastering it or should I bother learning C++?

    At this point most of what I want to do (programming interactive experiences, making art and games) uses Javascript but I always hear “Skills in a C like language are good to have” and much of the tools I use, such as game engines and browsers, are themselves written in C++.

    All the things you write here make me think that I could either be more of a master of one language or more of a Jack of Two Trades, and while I would like to program micro-controllers and get “close to the metal”, it seems like all of the things I would use C++ for (Native apps, awesome performance) I could come pretty close to because of all the advances in JS (asm.js, Node-Webkit) etc.

    In other words, can you help me with the difficult task of figuring out if it is worth spending several years getting comfortable with C++ because I want to make bitching graphic and interactive experiences and it seems like I can already do a lot of that with just the web?

  • That is not an easy question. I think the pragmatic answer is learn whatever you need to learn to do the things you want to do when you want to do them. 20 years ago if you didn’t know C++ and assembly language you couldn’t do much at all in 3D. Now there’s Unity and Unreal and Dreams and many other things that are making it easier than ever to do amazing things building on top of what others have built.

    On the other hand leaning C can possibly open a few doors in places like arduino land and things like libcinder and/or open frameworks might be another good place to find a reason to learn

  • dheeraj suthar

    Hi,

    Had similar queries as Willy. I had learnt C/C++ during college and used it for few low level projects (micro kernel, networking programs, data structures etc.). However, since the start of my career (~3 years now), my world has been revolving around scripting languages(mainly JS). I some how don’t feel much passionate for it and crave for the core development in C++. However, your article made me re-evaluate my options. The thing which bothered me much is the confusing and crowded eco-system of JS for e.g. 100s of supporting tools (npm, bower, libraries like jquery, react etc.), dependencies on awkwardness of DOM, very different OOPs(Prototype) concepts as compared to other OOP languages like Java/C++. It gets so confusing. Not like C++, where knowing the language itself is sufficient most of the time. I do agree with you on the capabilities of JS. No other language has so many possibilities. However, what would be right path to master it (language, tools, frameworks etc.) especially from point of view of programmer coming from traditional programming background like C/C++/Java?

  • It’s only confusing because you don’t know it yet 😀 Right? I *mostly* don’t find it confusing anymore. 😀

    You might like ES6 as it adds a “class” keyword. The “class” keyword is just syntactic sugar mostly but it means you don’t have to learn the older ways. It also means there’s syntax for inheritance now built in. There’s also “let” now instead of var for bracket scope level variables instead of JavaScript’s traditional var function scoped variables. There’s also arrow functions => Which encompass “this” so that part gets less confusing for people not familiar with JS.

    Everyone says webpack is the *thing* right now so find a webpack tutorial would be my first suggestion.

    It also depends on what you want to do. React is a UI related library. What’s your go to library in C++? If you’re not writing a webapp maybe you don’t care about React? Similarly to you just want to make 1 page stuff or do you want to make full on client/server web app. That will also inform your decision. For that I mostly enjoyed Meteor so far but for 1 page stuff I just pretty much code by hand, no libraries needed depending on what I’m trying to do.

  • Nemo

    You know what’s funny n sad tho, I’ve been coding in C++ for *years* so this sounds way simpler than you make it seem, but at the same time, Javascript is just really weird and confusing for me. I feel like there’s no real structure to it, so I can’t formulate big projects in my head. Not saying it’s bad, it’s mostly just due to me never having really messed with it much before.

  • Nemo

    Unity is C#, silly. :p

  • Not sure what your snarky point is. My point is you don’t need to learn C++ and assembly to do 3d anymore because you have things like Unity. Unity uses C# which is not C nor C++. C# is arguably easier than C++ as you don’t have to learn about pointers and references and RAII and smart pointers and for the most part you can ignore templates etc.

    On top of which you can use tools like Unity and Unreal without using any programming. Both have enough features that creative people can make things just by plugging stuff together, using blueprints or the equivalent in Unity (there are plugins that do the same thing) or just being creative with trigger boxes etc..

    And on top of even that if you’re into visual effects there’s stuff like touchdesigner and all it’s competitors that also require no programmer to do amazing things (though they are extensible through programming)

    Learning C++ can open even more possibilities but with so many amazing options today it’s easier than ever to get by without.

  • Nemo

    I mean it wasn’t really snarky, but whatever.

  • Dud3

    I would agree with you, but still it can’t go worst than C++, I think no other language can go more complex than C++ unless the only purpose of a language was to see how complicated can a language be.

  • Nemo

    How is it difficult?