Live data from Hacker News

The compiler is your best friend

blog.daniel-beskin.com

131–140 of 149 posts

Re: The compiler is your best friend

#131
post #66

> I'm personally not aware of languages that completely remove exceptions from the language. Zig is one. For that matter standard C has no exceptions

I'm sure undefined behavior counts as an exception in the meaning intended in TFA. Example:

  int inv(int x) {
    return 1/x;
  }

Re: The compiler is your best friend

#132

> A common pattern would be to separate pure business logic from data fetching/writing. So instead of intertwining database calls with computation, you split into three separate phases: fetch, compute, store (a tiny ETL). First fetch all the data you need from a database, then you pass it to a (pure) function that produces some output, then pass the output of the pure function to a store procedure. Does anyone have a…

Maybe check out Scott Wlaschin's videos on YouTube. There is one talk for his book "Domain Modeling Made Functional" which, if I remember, was very clear and easy to follow.

Re: The compiler is your best friend

#133
post #40

Earlier quoted context omitted.

I think you’re conflating 'conciseness' with 'correctness.' The 'clutter' you're describing in Swift like, having to explicitly define an Enum instead of using a vertical bar |, is exactly what makes it more robust than TS for large-scale systems. In TypeScript a union like string | number is structural and convenient, but it lacks semantic meaning. In Swift, by defining an Enum, you give those states a name and a pu…

I mean there should be _some_ sugar in a language like swift, no? It has sugar in many parts of the language, being able to define a simple type union should not require custom declaration of every forwarding accessor, a protocol, an enum, bridging back and forth between them, etc. It would be one thing to say that the vertical bar is a shortcut for these more exhaustive constructs (setting aside whether these constr…

I think we are talking past each other because we are optimizing for different domains.

You seem to want the ergonomics of a structural type system like TypeScript where data shapes are fluid but explicitly unsound [1]. In that paradigm requiring a named Enum feels like clutter because it forces you to pause and define a relationship that you just want to infer.

But Swift is a nominal static language designed for long lived binary compiled applications [2]. In this context that clutter is actually architectural definition. The friction is a feature not a bug because it discourages passing around anonymous bags of data and forces you to model what that data represents.

Swift actually has plenty of sugar but it puts it in places that don't compromise static analysis. It is designed to be expressive without being loose.

Complaining that Swift doesn't handle anonymous unions as easily as TS is like complaining that a tank handles worse than an F1 car. It is true but the tank is built to survive a direct hit whereas the F1 car trades that safety for raw speed.

[1] https://www.typescriptlang.org/docs/handbook/type-compatibil... [2] https://www.swift.org/about/

Re: The compiler is your best friend

#134

> How many times did you leave a comment on some branch of code stating "this CANNOT happen" and thrown an exception? Did you ever find yourself surprised when eventually it did happen? I know I did, since then I at least add some logs even if I think I'm sure that it really cannot happen. I'm not sure what the author expects the program to do when there's an internal logic error that has no known cause and no defini…

Ideally, if you can convince yourself something cannot happen, you can also convince the compiler, and get rid of the branch entirely by expressing the predicate as part of the type (or a function on the type, etc.) Language support for that varies. Rust is great, but not perfect. Typescript is surprisingly good in many cases. Enums and algebraic type systems are your friend. It'll never be 100% but it sure helps fil…

There is no inherent benefit in going and expressing that fact in a type. There are two potential concerns:

1) You think this state is impossible but you've made a mistake. In this case you want to make the problem as simple to reason about as possible. Sometimes types can help but other times it adds complexity when you need to force it to fit with the type system.

People get too enamored with the fact that immutable objects or certain kinds of types are easier to reason about other things being equal and miss the fact that the same logic can be expressed in any Turing complete language so these tools only result in a net reduction in complexity if they are a good conceptual match to the problem domain.

2) You are genuinely worried about the compiler or CPU not honoring it's theoretical guarantees -- in this case rewriting it only helps if you trust the code compiling those cases more for some reason.

Re: The compiler is your best friend

#135
post #66

> I'm personally not aware of languages that completely remove exceptions from the language. Zig is one. For that matter standard C has no exceptions

I'm sure undefined behavior counts as an exception in the meaning intended in TFA. Example: int inv(int x) { return 1/x; }

No, it certainly doesn't.

Re: The compiler is your best friend

#136
post #66

> I'm personally not aware of languages that completely remove exceptions from the language. Zig is one. For that matter standard C has no exceptions

Well, no, you're mistaken about Zig. There are custom panic handlers which are some kind of exceptions. I think Rust has something similar.

Re: The compiler is your best friend

#137
post #66

> I'm personally not aware of languages that completely remove exceptions from the language. Zig is one. For that matter standard C has no exceptions

Well, no, you're mistaken about Zig. There are custom panic handlers which are some kind of exceptions. I think Rust has something similar.

I'm not mistaken. Panic handlers are not any kind of exception.

Re: The compiler is your best friend

#138
post #107

Earlier quoted context omitted.

> Correct. But how are you testing that you successfully crash In a language like rust, failed assertions panic. And panics generally aren't "caught". > instead of corrupting on-disk data stores If your code interacts with the filesystem or the network, you never know when a network cable will be cut or power will go out anyway. You're always going to need testing for inconvenient crashes. IMO, the best way to do thi…

> In a language like rust, failed assertions panic. And panics generally aren't "caught". This thread was discussing debug_assert, where the assertions are compiled out in release code.

Ah I see what you're saying.

I think the idea is that those asserts should never be hit in the first place, because the code is correct.

In reality, its a mistake to add too many asserts to your code. Certainly not so many that performance tanks. There's always a point where, after doing what you can to make your code correct, at runtime you gotta trust that you've done a good enough job and let the program run.

Re: The compiler is your best friend

#139

Earlier quoted context omitted.

I mean there should be _some_ sugar in a language like swift, no? It has sugar in many parts of the language, being able to define a simple type union should not require custom declaration of every forwarding accessor, a protocol, an enum, bridging back and forth between them, etc. It would be one thing to say that the vertical bar is a shortcut for these more exhaustive constructs (setting aside whether these constr…

I think we are talking past each other because we are optimizing for different domains. You seem to want the ergonomics of a structural type system like TypeScript where data shapes are fluid but explicitly unsound [1]. In that paradigm requiring a named Enum feels like clutter because it forces you to pause and define a relationship that you just want to infer. But Swift is a nominal static language designed for lon…

I agree that you should evaluate languages in their domains. At the end of the day, Swift is mainly used for systems and iOS apps. In this, it is inadequate, as you can tell by, again, most apps not using the type system to enumerate valid views but instead (because enums and union types more broadly are so clunky to use!) masses of uncoupled types in their views, allowing for many, many implicitly invalid states.

Re: The compiler is your best friend

#140
post #94

Earlier quoted context omitted.

> Do you not make such a tacit assumption every time you index into an array (which in almost all languages throws an exception on bounds failure)? Yes, which is one reason why decent code generally avoids doing that.

Are you saying decent code avoids indexing into arrays? Or are you saying it avoids doing so without certainty the bounds checks will succeed?

Decent code generally avoids indexing into arrays at all; if it does so then it does so in ways where the bound checks are so certain to succeed that you can usually explain it to the compiler (e.g. split an array into slices and access those slices).
Post reply on HN