5 ms·
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
by shakna 7y ago
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/b0c1a5ef0171b265ce7f6ef479be7497 https://gist.github.com/shakna-israel/b0c1a5ef0171b265ce7f6e...
- tiborsaas 7y agoDoes 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.
- deleted 7y ago[deleted]
- ekianjo 7y agoI think the parent was concerned about accidental unsafe behavior, not by design.
- pjc50 7y ago> 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/n4028.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n402... 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.
- rocqua 7y agoIt makes the C++ preprocessor a horrible language. Whether C++ templates are an improvement is very much up for debate.
- pjc50 7y agoC++ templates allow you to do some brilliant metaprogramming. They can also be computationally expensive to compile, produce incomprehensible error messages, and are a great way of teleporting surprising behavior into your program. Especially when combined with operator overloading.
- pjmlp 7y agoAt least with C++20 modules and concepts that should improve.
- matheusmoreira 7y agoUsing 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 7y agoIn 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.
- bcoates 7y agoMost or all of these are ill-formed and required to be diagnosed by a conforming compiler.
- lmm 7y ago> 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. Usually the C behaviour is undefined, at which point it can do absolutely anything. If it just gives you an arbitrary value and chugs along (as many C implementations will do), that's harder to understand and diagnose. If you run a big calculation in Javascript and it comes out as "true5", it's pretty clear what's gone wrong (and pretty easy to bisect the calculation to find where the mistake is). If you make the same code error in C you'll get an answer like 823491 and might not even realise that it's incorrect.
- saagarjha 7y ago> If you make the same code error in C you'll get an answer like 823491 and might not even realise that it's incorrect. Or, worse, your code will give you "true5", but only on Tuesdays at 2 AM when your server load is low, and you'll look at the code and wonder how it's possible something like this could ever happen…
- madmax96 7y agoThe C behavior in this case isn't undefined, unless you go out of your way to violate aliasing rules or something -- but that's a far reach from what parent was saying.
- mirekrusin 7y agoYou can pick this kind of nonsense code for pretty much any language, are you writing this kind of code? Not really. You have several options when validating input, from handrolled asserts, flow-runtime, json schema, several helper libraries to writing your own dsl with help of nearley or something similar if needed.
- Supermancho 7y ago> are you writing this kind of code? Not really JS that doesnt check the type of every argument down to the prototype and dependent function level (not knowing what fns are going to be required further), is written by JS devs all day everyday. The situation isnt nonsense, it is state of the art JS development.
- saagarjha 7y ago> 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. Yeah, until the compiler figures out it's really not a size_t and that it's free to do whatever it likes to your operation.
- diegoperini 7y agoFrom now on, compilers are criminal masterminds in my fantasy world!
- madmax96 7y ago> Yeah, until the compiler figures out it's really not a size_t and that it's free to do whatever it likes to your operation. That's not true. Being gracious, parent was saying that if you treat another scalar type as a size_t (or vice versa) something sane happens. The standard guarantees that size_t is an unsigned integer type. If you use any other scalar type where a size_t is expected, it will be converted to a size_t correctly, even if it has less precision than a size_t. If you use a size_t where a less precise scalar type is expected, the behavior is perfectly defined as long as the value stored by the size_t can be stored in the less precise type. The result is implementation defined, or an implementation defined signal is raised, if it cannot be represented in the less precise type. Either way, the compiler is never free to do whatever it likes in this case. In most cases, doing this is perfectly safe. Compilers are free to warn (and they do!) users when this happens. For instance, GCC and Clang both will warn on this behavior if you supply `-Wconversion`. But you never will see totally unreasonable code generated by compilers when this happens.
- jiofih 7y ago> 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) How exactly would this happen if both the output and input are typed? Are you talking about shared (or not) typedefs across services?
- thegeomaster 7y agoI don't get your argument. You receive some JSON over the wire, it's not the right format, and everything blows up in your face. Likewise, you receive some bytes over the network, interpret it as one struct but it's really a bit different struct, and you have your problem all over again. Arguably worse. This is going to happen with any technology unless you validate your data at the boundary. Good C code does that. You can do it in TypeScript as well, a good part of it automated (see e. g. https://github.com/woutervh-/typescript-is https://github.com/woutervh-/typescript-is). What's the difference?
- the_gipsy 7y agoYou are right. I guess that, often, people just JSON.parse and think that's enough 'cause they already typed their stuff. But that's not really a problem of TS or JS.
- nebulous1 7y agoI don't agree with his overall thought process, but JavaScript is not without issues. I believe what he's referring to here is that JS will (usually) determine its actions based on its runtime type whereas C will (usually) determine its action based on the compile time type. So if I am expecting a number but get passed a string, in JS I am now executing string operations (with all operators) whereas in C I'm going to be doing arithmetic as expected but on incorrect data (probably the address of the string). Both of these are likely not be what we want, but the JS can end up with extremely unexpected outcomes, especially if we end up with object mismatches, where as the C is restricted to outcomes for different numeric inputs.
- shakna 7y ago> You receive some JSON over the wire, it's not the right format, and everything blows up in your face. If I was using a staticly typed JSON parser, like say Rust's or Crystal's, then it would blow up, right there. It'd throw an exception, or pass back a failure value that I have to handle. JS doesn't do that. It just keeps going, and due to the way it implicitly handles types, getting a list instead of an object can mean you end up with a string later on.
- mettamage 7y agoI'd say for learning programming (the basics: variables, functions, if-statements and loops) JavaScript is better. Why? 1. You can visualize your code easier.. 2. You do get to be introduced to types, but don't have to worry too much about them (I got really upset when I learned that in Java you could only make arrays of one type as I didn't see the point, now I do, then I didn't). 3. Error handling is easier. 4. No memory management is not something you want to deal with as a beginner (as someone who starts learning programming, memory management is nonsense, later on it's a a necessity for performance). 5. A nicer debugging experience with Chrome dev tools. So yea, for learning programming JS > C or C++ for that matter. Disclaimer: my first programming language was Java. In light of that, I'd rather choose for C (that hello world example tripped me up for 8 weeks! After 8 weeks, I still didn't know what command-line arguments were as they taught us to use Eclispe... sigh). Though, for learning how to hack: <3 C, <3 assemby, <3 opcodes. For learning how to hack, I love C. They made everything easy, there are leaks everywhere! I wonder how that will go about a 100 years from now when things are presumably a lot more tight and secure. Entry level hacking seems to become rarer everyday (aka a simple stack smash and voila! You're in!), so I wonder what difficult antics you'd need to do in a 100 years from now. But for now, we still have C. Disclaimer: I really enjoyed C when learning how to hack, I might sound sarcastic, I'm not.
- the_gipsy 7y ago1. it's extremely hard for beginners to visualize the event loop and how it orders function execution and scope 2. really only primitives, not useful 3. it's not. again the event loop makes try/catch useless, there are too many different ways to handle errors for each situation. 4. and 5. ok, but you can have that, or better, with other languages.
- mettamage 7y agoOh boy, I'm arguing over the Internet. Sorry for that. You do bring good points and I agree upfront that they are indeed JS features that either suck or are not very pedagogical. 1. You don't need to learn about the event loop straight away (or asynchronous programming) by the time you get to that concept, you might as well go to another language that's easier for that. But I do concede that once you get to async programming: JS is not the best language to learn from. With that said for people who got past the basics, here's an intuitive video about the event loop [1] (note: if you're past the basics, don't watch it while you're still doing the basics xD). 2. Basic objects are easily learnable with JS since you can type them in a literal sense, whereas otherwise you need to instantiate it with a constructor (e.g. Java) or you don't really learn about objects (e.g. C, though I've heared that it does have objects right? Despite it being an obscure feature, anyways, I'm not sure if you should be happy to learn about objects, learning about dictionaries or hashing is cool though). More importantly, when you start out learning programming, primitives + some HTML + simple objects are all you need to know. 3. Yes, try/catch is useless. I wouldn't call that basic though, but I'm already noticing we're differing on definitions (note: my definition was relatively clear, variables, if-statements, for loops and functions). And in coding bootcamps, the concept came long after I taught the basics of programming (e.g. it came in week 5 because of NodeJS). I remember Python being better for this. Errors in try/catch are as infuriating as segfaults or other memory leaks / coredump issues, they simply seem to happen in C a lot more when you're just starting out with programming (sorry if I mangle terms, C has been a while for me, and I like C, just not as a starter language, just as I used to like Charizard but not as a starter pokémon :D). Later on, it's a different story and I have suffered enough pain from it. Note: I'm not saying JS is the best language to learn from in the world. I think Python is better suited for that, or in some cases Scratch, or in other cases C# + Unity3D. I'm simply saying it's better than C (in terms of learning programming basics). [1] https://www.youtube.com/watch?v=8aGhZQkoFbQ https://www.youtube.com/watch?v=8aGhZQkoFbQ
- lucideer 7y ago> Hint: some of those seemingly random characters pull a double quote out of JS' leaky guts. If one is going to critique a subject, the least one could do is learn the most simplistic basics of said subject. There are no "double-quotes" pulled from anywhere, and there is nothing "leaky" nor buggy about the behaviour. Sure, many people are not fans of type coercion but it's not in any way unique to javascript.
- __ryan__ 7y ago> (Hint: some of those seemingly random characters pull a double quote out of JS' leaky guts. Nope! It’s just JSFuck [0] 1. All objects have a `toString` method that returns a string. 2. Object properties can be accessed by subscript (`object.prop === object[“prop”]`) and numeric property keys are really strings (`object[0] === object[“0”]`). 3. String characters can be accessed by index (`”hello”[0] == “h”`). 4. JavaScript has string concatenation support. It occasionally will implicitly convert something to a string if it’s used like a primitive value. The script you posted just abused those facts to generate the string “Hello World”. It does not “pull a double quote out of JS’ leaky guts”. Is it weird? Sure. But using strict types prevents this type of stupid stuff from occurring. Do you really think TypeScript doesn’t try to prevent you from using an object as a string? Of course it does. If you use strict types internally and validate at the edges then you really shouldn’t have a problem. [0]: http://www.jsfuck.com/ http://www.jsfuck.com/
- shakna 7y agoThat process _is_ string leaking out from inside JavaScript. That all property keys are actually strings is a leak from JS' original implementation. You've accurately explained how it works, without understanding that what I've said explains why that how is allowed to occur.
- nebulous1 7y agoThere's no double quote involved, you saying that implied you didn't know how the statement worked (regardless of whether you actually understood it or not), so their reply was valid. I feel like this whole avenue doesn't fit your overall point. You can certainly create a string in C without using quotes, and you can also write heavily obfuscated code that would be difficult to understand and look very strange.
- Shorel 7y agoTo add insult to injury, compilation time is bigger in JavaScript compared to C, with all the things that Webpack (or one of the alternatives to it) has to do.
- timw4mail 7y agoC compilers are far more optimized, and have the advantages of a much longer development lifetime, and lower-level languages. A transpiler written in Javascript has a huge performance advantage to begin with.
- gatherhunterer 7y ago> I would happily argue that JavaScript is _worse_ than C. Hacker News with the hot take. You are responding to the title, not the article.
- shakna 7y agoI went into some detail about the type system of JS and why I believe that justifies that JS is worse than C, the very same type system that is discussed in the majority of the article. I did in fact, read and respond to the article.