Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> The most tragic aspect of this bug, howevere, is that it is intended behavior according to the YAML 2.0 specification.

This is one of those great ideas that sadly one needs experience to realize are really bad ideas. Every new generation of programmers has to relearn it.

Other bad ideas that resurface constantly:

1. implicit declaration of variables

2. don't really need a ; as a statement terminator

3. assert should not abort because one can recover from assert failures



I agree with the general observation, but the need for ";" ? Quite a few languages (over a few generations) have been doing fine without the semicolon. Just to mention two: python and haskell. (Yes, python has the semicolon but you'll only ever use it to put multiple statements on a single line.)


> Yes, python has the semicolon but you'll only ever use it to put multiple statements on a single line.

This is also true of Haskell btw.


Another inreresting example is Lua. It's a free form language without semicolons. It's not indentation sensitive.


Lua does have semicolons!

It even has semicolon insertion, but because the language is carefully designed, this doesn't cause problems, and most users can go a lifetime without knowing about it.

Our coding style requires semicolons for uninitialized variables, so you'll see

    local x;
    if flag then
       x = 12 
    else
       x = 24
    end

As a way of marking that the lack of initialization is deliberate. `local x = nil` is used only if x might remain nil.


I don't like saying that it's semicolon insertion because it might give people the idea that the semicolons work similarly to Javascript. In Lua, inserting a semicolon is always optional and it's an stylistic matter (like in your example). It even allows putting multiple statements on the same line without a semicolon.

    -- Two assignment statements
    x = 10 y = 20


> I agree with the general observation, but the need for ";" ? Quite a few languages (over a few generations) have been doing fine without the semicolon. Just to mention two: python and haskell. (Yes, python has the semicolon but you'll only ever use it to put multiple statements on a single line.)

But then it's inconsistent and has unnecessary complexity because now there's one (or more) exceptions to the rules to remember: when the ';' is needed. And of course if you get it wrong you'll only discover it at runtime.

"Consistent applications of a general rule" is preferable to "An easier general rule but with exceptions to the rule".


Have you ever used Python? If you did you really wouldn't be saying this. There isn't an exception. The semicolon is used to put multiple statements on a single line. That's it's only use, and that's the only time it's 'needed' - no exceptions.


But python has instead the "insert \ sometimes" rule, which isn't better.


> Have you ever used Python? If you did you really wouldn't be saying this. There isn't an exception.

For the ';', perhaps not. For the token that is used to terminate (or separate) statements? Yes, the ';' is an exception to the general rule of how to terminate statements.

The semicolon also works on some sort of statements and not others, throwing errors only at runtime.

It's easier to remember one rule than many.


Honestly, the rule is "don't use semicolons in Python". I don't think there's a single one in the large codebase I work with, and there's really no reason at all to use it other than maybe playing code golf.

It's not a language in which you ever need be saving bytes on the source code. Just use a new line and indent. It's more readable and easier.


There are no exceptions. You only need it if/when you want to put multiple statements on a single line. That's its sole purpose.

And I'd also add that it's something that you almost never do. One practical use is writing single line scripts that you pass to the interpreter on the command line. E.g. `python -c 'print("first command"); print("second command")'`

If you don't know about the `;` at all in python then you are 100% fine.


When you use ; and possibly {, }, code statements / blocks are specified redundantly (indentation + separators), which can cause inconsistent interpretation of code by compiler / readers.

I find it much, much easier to look at code and parse blocks via indentation, than the many ways and exceptions of writing ; and {, }, while an extra or missing ';' or {} easily remains unspotted and leads to silly CVEs.


Haskell has the semicolon for the same reason!


> implicit declaration of variables

This is so true. I really like Julia and I know that explicitly declaring variables would be detrimental to adoption but I prefer it to the alternative, which is this: https://docs.julialang.org/en/v1/manual/variables-and-scopin...


What do think of implicit member access (C++, Java, C#) vs explicit (python, javascript)? Is there a concrete argument one way or the other?

I feel like I prefer explicit

    self.member = value
    this.member = value
vs implicit

    member = value
But clearly C++/Java/C# people are happy with implicit ... though many of them try to make it explicit by using a naming convention.


That was my single biggest pet-peeve of C++. A variable appears in the middle of a member function? Good luck figuring out what owns it. Is it local? Owned by the class? The super-class? (And in that case - which one?)

The added mental load of tracking variables' sources builds up.


FWIF, most C++ style guards recommend writing member variables like mVariableName or variable_name_ so they're easy to distinguish from local variables, and modern C++ doesn't generally make much use of inheritance so there's usually only one class it could belong to.


The fact that people introduce naming conventions to keep track of member variables is probably the biggest condemnation of implicit member access. People clearly need to know this, so you'd better make it explicit.

It's actually a bit surprising that this is one thing that javascript does better than Java. In most other areas, it's Java that's (sometimes overly) explicit.


I can tell for certain that as a JS/Python man, every time I look through Java code I have to spend a bit of time when stumbling upon such access, until I remember that it's a thing in Java. Pity that Kotlin apparently inherited it.

But at least, to my knowledge, in Java these things can't turn out to be global vars. Having this ‘feature’ in JS or Python would be quite a pain in the butt.


F#, Kotlin, Python, Nim and many others all seem to get by fine without semicolons as statement terminators.


In Python, a newline is a token and serves as a statement terminator.

What I'm referring to is the notion that:

    a = b c = d;
can be successfully parsed with no ; between b and c. This is true, it can be. But then it makes errors difficult to detect, such as:

    a = b
    *p;
Is that one statement or two?


This is one of those great ideas that sadly one needs experience to realize are really bad ideas. Every new generation of programmers has to relearn it.

It's a bad idea because ASCII already includes dedicated characters for field separator, record separator and so on. These could easily be made displayable in a text editor if you wanted just as you can display newlines as ↲. Anyone who invents a format that involves using normal printable characters as delimiters and escaping them when you need them, is, I feel very confident in saying, grotesquely and malevolently incompetent and should be barred from writing software for life. CSV, JSON, XML, YAML, all guilty.


The obvious first step toward the brighter future is to refrain from using any and all software that utilizes the malevolent formats you mentioned. Doing otherwise would mean simply being untrue to one's own conscience and word.


> It's a bad idea because ASCII already includes dedicated characters for field separator, record separator and so on.

ASCII is over 60 years old and separators haven't caught on yet; what's different now?

> These could easily be made displayable in a text editor if you wanted just as you can display newlines as ↲.

Can you name a common text editor with support for ASCII separators? It's a lot easier to use delimiters and escaping then change every text editor in the world.

> Anyone who invents a format that involves using normal printable characters as delimiters and escaping them when you need them, is, I feel very confident in saying, grotesquely and malevolently incompetent and should be barred from writing software for life. CSV, JSON, XML, YAML, all guilty.

All of the formats you rant about are widely used, well supported, and easy to edit with a text editor - none of these are true of ASCII separators. People chose formats they can edit today instead of formats they might be able to edit in the future. All of these formats have some issues but none of the designers were incompetent.


US-ASCII only has four information separators, and I believe they can only be used in a four-layer schema with no recursion, sort of like CSV (if your keyboard didn’t have a comma or quote or return key). When you need to pass an object with records of fields inside a field you’re out of luck, and everyone has to agree on quoting or encoding or escaping again.

I think SGML (roll your own delimiters and nesting) was pretty close to the Right Thing,™ but ISO has the specs locked down so everyone had a second-hand understanding of it.


how do you write them though


Ctrl-\, Ctrl-], Ctrl-^ and Ctrl-_ for file, group, record and unit separator, respectively.

However, your tty driver, terminal or program are all likely to eat them or munge them. Also, virtually nothing actually uses these characters for these purposes.


virtually nothing actually uses these characters for these purposes.

Right. Which is why we have all these hilarious escaping and interpolation problems. Any why programmers will never be taken seriously by real engineers. It's like we have cement mixed and ready to go but we decide to go and forage for mud instead and think that makes us cleverer than the cement guys.


> your tty driver, terminal or program are all likely to eat them or munge them

Maybe that has something to do with this?


I’m surprised that with your experience you come to such unbalanced conclusions. Everything in engineering is about trade-offs and while your conclusions may be indisputable for the design goals of D they may wrong in other contexts.

1. If I scribble some one time code etc. the probability of having an error coming from implicit declarations is in the same order of magnitude as missing out edge cases or not getting the algorithm right for most people. The extra convenience may well be worth it.

2. I would relax this it should be clear to the programmer where a statement ends.

3. Go on with a warning is a sane strategy in some situations. I happily ruin my car engine to drive out of the dessert. The assert might have been to strict and i know something about the data so the program can ignore the assert failure.


> 1. If I scribble some one time code

.... and here is another entry for Walter's list of bad ideas:

4. "It's okay. I will use this code only once"


My favorite Red Green quote is “now, this is only temporary … unless it works.”


Your rationale in this and your followups are exactly what I'm talking about.

1. You're actually right if the entire program is less than about 20 lines. But bad programs always grow, and implicit declaration will inevitably lead you to have a bug which is really hard to find.

2. The trouble comes from programmer typos that turn out to be real syntax, so the compiler doesn't complain, and people tend to be blind to such mistakes so don't see it. My favorite actual real life C example:

    for (i = 0; i < 10; ++i);
    {
        do_something();
    }
My friend who coded this is an excellent, experienced programmer. He lost a day trying to debug this, and came to me sure it was a compiler bug. I pointed to the spurious ; and he just laughed.

(I incorporated this lesson into D's design, spurious ; produce a compiler error.)

3. I used to work for Boeing on flight critical systems, so I speak about how these things are really designed. Critical systems always have a backup. An assert fail means the system is in an unknown, unanticipated state, and cannot be relied on. It is shut down and the backup is engaged. The proof of this working is how incredibly safe air travel is.


> 3. I used to work for Boeing on flight critical systems, so I speak about how these things are really designed. Critical systems always have a backup. An assert fail means the system is in an unknown, unanticipated state, and cannot be relied on. It is shut down and the backup is engaged.

I ask you to reconsider your assumptions. How did this play out in the 737 MAX crashes? Was there a backup AoA sensor? Did MCAS properly shut down and backup engaged? Was manual overriding the system not vital knowledge to the crew?

You don’t have to answer. I probably wouldn’t get it anyway.

But rest assured that I won’t try to program flight control and I strongly appreciate your strive for better software.


> How did this play out in the 737 MAX crashes?

They didn't follow the rule in the MCAS design that a single point of failure cannot lead to a crash.

> Was manual overriding the system not vital knowledge to the crew?

It was, and if the crew followed the procedure they wouldn't have crashed.


I disagree with most of what you said but I want to specifically call out:

> 3. Go on with a warning is a sane strategy in some situations.

No, if its sometimes ok, to continue, than you should not assert it.

Assert means "I assert this will always be true, and if it's not our runtime is in unknown/bad state."

If you think you can recover, or partially recover, throw/return appropriate error, and go into emergency/recovery mode.


Your reactor is boiling. Your control software shut down with assertion failed: temperature too high, cannot display more than 3 digits.

Downvote me if you want to open a bug ticket with the vendor and wait a week for the fix.

Upvote me if you’d give it a try to restart with a switch to ignore assertions.

You may abstain if you never shipped a bug.

Edit: not to forget that this website runs on lisp which violates all three. Was it really a bad choice for the website?


> Your reactor is boiling. Your control software shut down with assertion failed: temperature too high, cannot display more than 3 digits.

Several points:

1. Most of such critical components have several different and independent implementations, with analog backup (if possible).

2. You are arguing one specific safety critical case, that 99.999% or even more programmers will never face, should somehow inform decision about general purpose programming language.

3. Even if you are working in such safety critical situation, you should not really on assertion bypass, but have separate emergency procedure, which bypasses all the checks and try's to force the issue. (ever saw a --force flag ?)

Because what happens in reality, is developer encounters a bug (maybe while its still in development), notice you can bypass it by disabling assertions (or they are disabled by default), log it as a low priority bug, that never gets fixed.

Then a decade later me or someone like me is cursing you because you enterprise app just shit the bed, and is generating tons of assertion warnings, even when it running normally, so I have to figure out, which of them are "just normal" program flow, and which one just caused an outage.

I never experienced situation like you described, but I have experienced behavior like I wrote above, too many times.

Botom line is:

- don't assert if you don't mean it

- if you need bypass for various runtime checks, code one in explicitly.

Edit: Hacker News is written in ARC which is schema dialect. ARC doesn't have assertions as far as i can tell.

ARC doesn't have its own runtime and is run on racket language, that has optional assertion, that exit the runtime if they fail https://docs.racket-lang.org/ts-reference/Utilities.html


I agree with this. Nuclear reactors are a special case of systems where removing energy from the system makes it more unsafe, because it generates its own energy and without a control system it will generate so much energy that it destroys itself (and due to the nature of radiation, destroys the surrounding suburbs too).

With most systems, the safest state is off. CNC machine making a weird noise? Smash that e-stop. Computer overheating? Unplug it. With this in mind, "assert" transitions the system from an undefined state to an inoperative state, which is safer.

That isn't to say that that you want bugs in your code, and that energizing some system is free of consequences. Your emergency stop of your mill just scrapped a $10,000 part. Unplugging your server made your website go down and you lost a million dollars in revenue. But, it didn't kill someone or burn the building down, so that's nice.


Modern nuclear reactors are designed and built with the expectation that when they melt down, the results aren't catastrophic (at least for the outside world).


See my previous reply. Your reactor design is susceptible to a single point of failure, and, how do I say it strongly enough, is an utterly incompetent design. Bypassing assertions is not the answer.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: