5 ms·
Why would you want to have a constructor of type T that returns you something that is not even an object of that type T? If you need the "return null on error"
by Joker_vD 2y ago
Why would you want to have a constructor of type T that returns you something that is not even an object of that type T? If you need the "return null on error" behaviour — so that you can never check that it's null (or forget to check) and let your execution stop with "TypeError: Cannot read properties of null" way down the line instead of right here, where you can fix it immediately before even shipping the code — then just write a tryParse() wrapper for that!
Now, to be fair, having a public constructor for URL with just a string as the argument, with the parsing semantics is arguably an anti-pattern, and a static factory function would serve much better indeed. A proper public URL constructor should instead take (scheme, authority, path, query, fragment) tuple and validate its constituents. The private URL constructor could be the one without validation, and that's what parse() and the public constructor would call internally.
- cageface 2y agoIt doesn't help that there's no way to specify in the contract of the function that it can throw. Blowing up your entire program because it can't parse a URL is something you should be made explicitly aware of.
- mkleczek 2y agoAhh... MalformedURLException is checked in Java and is a source of constant backlash from developers - for over 20 years :)
- nine_k 2y agoChecked exceptions have been tried in Java, and were universally hated, mostly for poor ergonomics. A very similar thing, the Result type in Rust, does pretty well. (Much like Maybe / Either do in Haskell.)
- tome 2y agoWhy? I never understood the objection to checked exceptions. It seems to me they would give me exactly what I want! (Granted, I'm a Haskell programmer, not a Java programmer.)
- demurgos 2y agoOne of the problems is that return types and exception types are not unified so it makes composition harder. `Result` brings exceptions into the regular type system
- nine_k 2y agoWithout parametric types, your methods grew longer and longer lists in the "throws" clause. It was easy to miss one of the dozen exceptions and only have the compiler point you at it after wasting several minutes on compilation (think 133MHz CPUs and slow HDDs). Type inference in modern Java makes you forget how long and repetitive type signatures used to be in it 20 years ago. BTW this makes Result<D, E> more ergonomic anyway: you still have only one E, at least one per invocation level. With checked exceptions, you had to haul a whole garland.
- michaelcampbell 2y ago> It was easy to miss one of the dozen exceptions and only have the compiler point you at it This sounds like (one of?) the killer feature of types, though. > after wasting several minutes on compilation (think 133MHz CPUs and slow HDDs). Sure, but everything we did was slow then.
- robertlagrant 2y agoI don't remember Java being that slow even on a 133MHz CPU. Maybe if it was a giant project, though.
- Joker_vD 2y agoThere is also no way to specify in the contract of the function that it can return null. Blowing up your entire program because it can't parse a URL and returns you a booby-trapped value that blows up your program when you try to use it as an URL is something you should be made explicitly aware of. Right? Although there are docs, of course, but who has time to read them? Or write them, for that matter? For some reason many client programmers are perfectly fine with calling random functions that has names sounding close enough and then expecting those functions to behave the way they expect them to behave, and many library programmers don't bother to document the actual behaviour of their functions because they for some reason believe that descriptive and self-evident (well, self-evident to them) names are enough of documentation. And you know, I think I can safely bet $5 the way TFA came to be was something like this: the author wrote a code that used URL() with no error recovery-path whatsoever, ran it, and it blew up on that line. The author then rolled its eyes, wrote an (admittedly) ugly try-catch around, and went to write the article complaining about exception. Now, I can bet another $5 that if URL() returned null what would happen instead would be that the author would write a code that used URL() with no error recovery-path whatsoever, would run it, and it would blow up somewhere down the line, on call to fetch() or something. The author would then ponder the code for several minutes, trying to figure out what exactly fetch() didn't like about the URL it was provided with, find that null came from the call to URL() and add the error recovery there. Crucially, they later would not go and write a article complaining about null returns because they regard it as a completely normal and acceptable behaviour.
- merrywhether 2y agoThis is one of the reasons for the broad popularity of TypeScript, where “[specifying] in the contract of the function that it can return null” is foundational to the experience. Meanwhile thrown errors are unmodelable COMEFROM statements in TS and many other languages.
- symlinkk 2y agoWhy is a public constructor with a string an anti pattern? 99% of the use case is parsing a string, and 99% of the users are going to try using the constructor first.
- deleted 2y ago[deleted]