Live data from Hacker News

Use Your Type System

dzombak.com

231–240 of 357 posts

Re: Use Your Type System

#232
post #15

Hard not to agree with the general idea. But also hard to ignore all of the terrible experiences I've had with systems where everything was a unique type. In general, I think this largely falls when you have code that wants to just move bytes around intermixed with code that wants to do some fairly domain specific calculations. I don't have a better way of phrasing that, at the moment. :(

"Phantom types" are useful for what you describe: that's where we add a parameter to a type (i.e. making it generic), but we don't actually use that parameter anywhere. I used this when dealing with cryptography in Scala, where everything is just an array of bytes, but phantom types prevented me getting them mixed up. https://news.ycombinator.com/item?id=28059019

Re: Use Your Type System

#233

Earlier quoted context omitted.

> I know what a UUID (or a String) is. I don't know what an AccountID, UserID, etc. is. Now I need to know what those are (and how to make them, etc. as well) to use your software. Yes, that’s exactly the point. If you don’t know how to acquire an AccountID you shouldn’t just be passing a random string or UUID into a function that accepts an AccountID hoping it’ll work, you should have acquired it from a source that…

And that's my point: I'm usually getting AccountIDs from strings (passed in via HTTP requests) so the whole thing becomes a pointless exercise.

If your system is full of stringly typed network interfaces then yes there is no point in trying to make it good. You can make things a bit better by using a structured RPC protocol like gRPC, but the only real solution is to not do that.

Re: Use Your Type System

#234
post #37

An adjacent point is to use checked exceptions and to handle them appropriate to their type. I don't get why Java checked exceptions were so maligned. They saved me so many headaches on a project where I forced their use as I was the tech lead for it. Everyone hated me for a while because it forced them to deal with more than just the happy path but they loved it once they got in the rhythm of thinking about all the…

Setting aside the objections some have to exceptions generally: Checked exceptions, in contrast to unchecked, means that if a function/method deep in your call stack is changed to throw an exception, you may have to change many function (to at least denote that they will throw that exception or some exception) between the handler and the thrower. It's an objection to the ergonomics around modifying systems. Think of…

> Checked exceptions, in contrast to unchecked, means that if a function/method deep in your call stack is changed to throw an exception, you may have to change many function (to at least denote that they will throw that exception or some exception) between the handler and the thrower.

That's the point! The whole reason for checked exceptions is to gain the benefit of knowing if a function starts throwing an exception that it didn't before, so you can decide how to handle it. It's a good thing, not a bad thing! It's no different from having a type system which can tell you if the arguments to a function change, or if its return type does.

Re: Use Your Type System

#235
post #93

Earlier quoted context omitted.

> This is where the concept of “Correct by construction” comes in. This is one of the basic features of object-oriented programming that a lot of people tend to overlook these days in their repetitive rants about how horrible OOP is. One of the key things OO gives you is constructors . You can't get an instance of a class without having gone through a constructor that the class itself defines. That gives you a way to…

I find regular OOP language constructor are too restrictive. You can't return something like Result to handle the error gracefully or return a specific subtype; you need a static factory method to do something more than guaranteed successful construction w/o exception. Does this count as a missing language feature by requiring a "factory pattern" to achieve that?

> You can't return something like Result to handle the error gracefully

Throwing an error is doing exactly that though, its exactly the same thing in theory.

What you are asking for is just more syntactic sugar around error handling, otherwise all of that already exists in most languages. If you are talking about performance that can easily be optimized at compile time for those short throw catch syntactic sugar blocks.

Java even forces you to handle those errors in code, so don't say that these are silent there is no reason they need to be.

Re: Use Your Type System

#236

Earlier quoted context omitted.

I think checked exceptions were maligned because they were overused. I like that Java supports both checked and unchecked exceptions. But IMO checked exceptions should only be used for what Eric Lippert calls "exogenous" exceptions [1]; and even then most of them should probably be converted to an unchecked exception once they leave the library code that throws them. For example, it's always possible that your DB cou…

Put another way: errors tend to either be handled "close by" or "far away", but rarely "in the middle". So Java's checked exceptions force you to write verbose and pointless code in all the wrong places (the "in the middle" code that can't handle and doesn't care about the exception).

> So Java's checked exceptions force you to write verbose and pointless code in all the wrong places (the "in the middle" code that can't handle and doesn't care about the exception).

It doesn't, you can just declare that the function throws these as well, you don't have to handle it directly.

Re: Use Your Type System

#237

Earlier quoted context omitted.

Ok please help me understand, what is the difference between - R method() throws L, and - Either method() To me they seem completely isomorphic?

There is a major difference at the call site. try/catch has significantly more complex call sites because it affects control flow.

That is just a syntactic sugar difference, you could have exactly the same call site structure if you wanted in a language.

Re: Use Your Type System

#238

I've seen experienced programmers do this a lot. It's the kind of thing that someone thinks is annoying, without realizing that it was preventing them from doing something incorrect.

It can be annoying though. I think Rich Hickey has a point that bugs like this almost certain get caught by running the program. If they make it into production it usually results in an obscure edge case. I’m sure there are exceptions but unless you’re designing for the worst case (safety critical etc) rather than average case (web app), types come with a lot of trade offs. I’ve been on the fence about types for a lo…

> I think Rich Hickey has a point that bugs like this almost certain get caught by running the program.

That is certainly correct... but that doesn't make it a good thing. One wants to catch bugs before the program is running, not after.

Re: Use Your Type System

#239
post #37

An adjacent point is to use checked exceptions and to handle them appropriate to their type. I don't get why Java checked exceptions were so maligned. They saved me so many headaches on a project where I forced their use as I was the tech lead for it. Everyone hated me for a while because it forced them to deal with more than just the happy path but they loved it once they got in the rhythm of thinking about all the…

There are lots of reasons.

But for one, Java checked exceptions don't work with generics.

Re: Use Your Type System

#240
post #196

Earlier quoted context omitted.

But then you are representing two distinct types as the same underlying type, String. MyType extends String; void foo(String s); foo(new MyType()); // is valid Leading to the original problem. I don't want to represent MyType as a String because it's not.

It has to work that way or else you can't use the standard library. What you want to block is not: StringUtils.trim(String foo); but myApp.doSomething(AnotherMyType amt); The latter is saying "I need not any string but a specific kind of string".

No I want to block both. I don't want to give devs the option of creating a function doSomething(String) that happens to accept MyType. If I need to call trim then I'll do

  StringUtils.trim(MyType.toString());
Post reply on HN