Hacker News new | ask | show | jobs
by KronisLV 1749 days ago
> You want, on top of everything else, the computer to refuse to run your program at all, unless you explicitly handle every possible edge case?

Precisely!

Even better - let the IDE suggest to you all of the possible exceptions and when you're feeling lazy or are hacking away at a prototype, either let it add a "throws SomeException" to the method signature and make it someone else's problem up the call chain, or just add a catch all after you've handled the ones that you did want to handle!

After all, none of us can recall the hundreds of ways network calls can get screwed up, but we're pretty sure what to do at least in a subset of those, but we'd also forget about those without these reminders. Not only that, but when you're writing financial code or running your own SaaS, you'll at the very least will want your error handling code to be as bulletproof as the guarantees offered to you by your language's rigid type systems.

Then, when you've finished hacking together your logic, your instance of SonarQube or another tool could just tell you: "Hey, there are 43 places in your code where you have used logic to catch multiple exceptions" and then you could review those to decide whether further work is necessary, or whether you can add a linter ignore comment to the code explaining why you don't want to handle the edge cases, or just do so in the static code analysis tool, so all of your team members know what's up.

Alternatively, if you're just writing something for yourself, just leave it as it is, knowing that if you'll ever need to publish your code for thousands of others to use, then you probably should go back to those now very visible places and review it.

So essentially:

  /** 
    * Attempts to load a Sprite from a file. You can then use the instance to display it on screen.
    * @param file This is the file that we want to load the image from. Use relative path to "res" directory.
    * Our engine loads PNG files and technically can also load GIF files because someone hacked that functionality together in an evening. 
    * That's kind of slow though, so we should use PNGs whenever possible. See ENGINE-33452 for more details.
    * @return A Sprite instance that you can pass to the rendering logic to put it on the screen, or alternatively process the loaded image in memory.
    */
  public Sprite loadSprite(@NotNull File file) throws SpriteGenericException, FileSystemGenericException {
    try {
      return FileSystemSpriteLoader.loadPNG(file);
    } catch (ImageWrongFormatException e) {
      wrongImageFormatLogger.warn("We found a " + e.getActualFormat() + " format file: " + file.getPath(), e); // the art team should have a look at this
      if (e.getActualFormat().equals(ImageFormats.GIF)) {
        return FileSystemSpriteLoader.loadGIF(file); // TODO unoptimized call because we needed GIFs for ENGINE-33452, remove later
      } else {
        throw SpriteGenericException("We failed to load sprite from file: " + file.getPath() + " because of wrong format: " + e.getActualFormat(), e);
      }
    } catch (SpriteCorruptedException e) {
      brokenImageLogger.warn("We found a corrupted sprite in file: " + file.getPath(), e); // maybe the pipeline is broken again?
      throw SpriteGenericException("We failed to load sprite from file: " + file.getPath() + " because of image corruption", e);
    } catch (Exception e) { // TODO ENGINE-44551 handle the file system access cases later once the API is stable and we know how it'll work on Android
      throw FileSystemGenericException("We failed to load sprite from file: " + file.getPath(), e);
    }
  }
I prefer software blowing up in predictable ways as opposed to doing so unexpectedly. Even Java is vaguely close to being what i'm looking for, however unchecked exceptions simply isn't acceptable from where i stand.
1 comments

If I had to write that kind of boilerplate every time I had an artistic inspiration, I'd never ship anything!

We are on far apart sides of a wide industry. I couldn't work productively in your dream language but hey, I'm happy we can have our different tools for our different needs. More power to us! :)

> let the IDE suggest to you all of the possible exceptions

So, programming without an IDE becomes untenable. I use a text editor. It feels like you're shifting language features into the IDE. What's the difference between the compiler doing it automatically vs the IDE doing it automatically?

I definitely agree that we're on the complete opposite ends of a wide spectrum of concerns and goals!

> So, programming without an IDE becomes untenable. I use a text editor. It feels like you're shifting language features into the IDE. What's the difference between the compiler doing it automatically vs the IDE doing it automatically?

I very much agree with this observation, but from the opposite side - for many development stacks and frameworks, working without an IDE feels like being a fish out of the water, since there are numerous plugins, snippets and integrations that provide intelligent suggestions, auto-completions and warnings about things that are legal within the language but are viewed as an anti-pattern.

I'd say that the difference between the two is pretty simple, just a matter of abstraction layers. Something along the lines of:

  - the business people have certain abstract goals, which they can hopefully synthesize into change requests
  - the developer has to implement these features, by thinking about everything from the high level design, to the actual code
  - the IDE takes some of the load off from the developer's shoulders, by letting them think about the problem and offering them suggestions, hints and assistance of other sorts to help in translating the requirements into code; of course, it's also useful in refactoring and maintenance as well, letting them navigate the codebase freely
  - the language server, linter, code analysis tools, plugins, AI autocomplete and anything else that the developer should want hopefully integrate within the IDE and allow using them seamlessly, to make the whole experience more streamlined
  - the compiler mostly exists as a tool to get to executable artifacts, while at the same time serving as the last line of defense against nonsensical code or illegal constructs
In essence, the IDE gives you choices and help, whereas the compiler works at a lower level and makes sure that any code (regardless of whether written by the developer with an IDE, one with a text editor or an AI plugin) is valid. In practice, however, the parts that the IDE handles are always more pleasant because of the plethora of ways to interact with it, whereas the output of a compiler oftentimes must be enhanced with additional functionality to make it more useful (for example, clicking on output to navigate to the offending code).

In my eyes, the interesting bits are where static code analysis tools and linters fit into all of this, because i think that those should be similarly closely integrated within the ecosystem of a language, instead of being seeked out separately, much like how RuboCop integrates with both Rails and JetBrains RubyMine. Our views may differ here once again, but i think that some sort of a convergence of tooling and its concerns is inevitable and as someone who uses many of the JetBrains tools (really pleasant commercial IDEs), i welcome it with open arms.

Ohh, you could have dependency management built into the IDE (probably already do, I don't know). An integrated profiler could tell you how fast a function is as soon as you write it. I'm getting funny ideas.

What if the IDE worked with a distributed function database, rather than flat text files? Where you could browse (shop?) all the code written by others, by licence, performance, etc.?

Wonder if there are any programming streams/channels I could uh, spy IDE-based development from.