Hacker Newsnew | past | comments | ask | show | jobs | submit | walterburns's commentslogin

I don't understand why the author bought an iPhone. That's the deal - you do things Apple's way in exchange for not having to figure out how you'll do them. For most people this is a massive convenience, and that's why they pay so much for Apple products (and why I don't).


On Writing Well, by William Zinsser. Hilarious, enlightening, affirming of everyone's need and ability to write well.


"But we'd like to give a type to this function. In most languages (Haskell, Typescript, C++, Rust, C#, etc.) there is no way to do that.[2] "

Can't you do this with a GADT? With a GADT, the type of the output can be specified by which branch of the GADT the input matches. Seems quite a similar idea.


GADTs let you do similar things in the simplest cases, they just don't work as well for complex constraints.

Like, append: Vector n t -> Vector m t -> Vector (n+m) t. With GADTs you need to manually lift (+) to work on the types, and then provide proofs that it's compatible with the value-level.

Then you often need singletons for the cases that are more complex- if I have a set of integers, and an int x, and I want to constrain that the item is in the set and is also even, the GADT approach looks like:

doThing :: Singleton Int x -> Singleton (Set Int) s -> IsInSet x s -> IsEven x -> SomeOutput

Which looks reasonable, until you remember that the Singleton type has to have a representation which is convenient to prove things about, not a representation that is convenient/efficient to operate on, which means your proofs will be annoying or your function itself will hardly resemble a "naive" untyped implementation.

Dependent types fix this because your values are "just" values, so it would be something like

doThing :: (x : int) -> (s : set int) -> so (is_in s x) -> so (even x) -> SomeOutput

Here, x and s are just plain values, not a weird wrapper, and is_in and event are ordinary (and arbitrary) library functions.


I mean, you can trivially do it with a (non-G) ADT, if you're content with wrapping the return value.

OTOH you can do this in TypeScript easily without wrapping; it could return a union type `number | string`.


Isn't that just saying you can do dependent types in TypeScript easily so long as you're willing to give up type checking?


Actually, it's even simpler: you should just be able to use signature overloading:

  myFunc(x: true): number
  myFunc(x: false): string
The article's assertion that TypeScript can't represent this is quite false.


Alas, no:

    foo.ts:1:10 - error TS2393: Duplicate function implementation.


Like this:

https://www.typescriptlang.org/play/?#code/GYVwdgxgLglg9mABA...

It's a bit of a hack, though - if you incorrectly implement myFunc so that, say, it returns a string even when x is true, it can violate the overloading assertions without any error or warning.


Thanks! If anyone else is playing along, to get this to work with tsc I needed to use "--strict".

Being able to use a function along those lines in a type safe manner is still pretty nifty, even if you can't write it with type safety.


No, because 1) you can't do (full) dependent types in TypeScript, 2) it's not clear what "dependent types" would even mean without type checking, and 3) using the union type you aren't giving up type checking at all.

The limitation is what comes later in the article - the dependent type can express the relationship between the argument and the returned type. But that's "out of scope" of the question of "typing a function that can return either a number or a string depending on the boolean argument". It only becomes a problem later on because to use the result you need to test the type (using `typeof`) even if you know you which boolean you passed in; that information doesn't end up tracked by the type system - although there actually are a couple of different ways to do this that satisfy this example in TypeScript, as suggested by some other comments.

Just using a union type in TypeScript isn't dissimilar to my suggestion of wrapping the result in an ADT; it's just that TypeScript makes this lightweight.


The dependent type question is, I think, subtly different: "a function whose return type is either a number or a string depending on the boolean argument."

The union type (or the more or less equivalent Either ADT) don't give you type checking because you can take either (sic) branch no matter what your boolean value was. You're free to write a function that takes false and returns an int, and the type checker will accept that function as correct.

No matter how you twist and turn in GHC Haskell or TypeScript, you can't prevent that just by the type signature alone, so you have to "trust me bro" that the code does what the comment says.

For this example that's trivial and laughable, but being able to trust that code does what the compiler-enforced types say and nothing more is perhaps a step towards addressing supply chain attacks.


Oh boy.


The first five chapters are unrelated to using the Cats library, and are an outstanding, illuminating introduction to how to think about FP in any language.


Li Haoyi! Thank you for developing your scala ecosystem and Hands On Scala. I just started using Scala again after a few years' break, using Mill, thanks to your recent blog post on the last 12 years. I forgot how easy Scala can be if you don't make it hard, and how just darn pleasant it is to code in. Would love to see Scala rise from the ashes of the FP flame wars and become Python devs' second language. Or even their first. Thanks for leading the charge!


I wish the world hadn't consolidated around Kubernetes. Rancher was fantastic. Did what 95% of us need, and dead simple to add and manage services.


Did you find Rancher v2 (which uses Kubernetes instead of their own Cattle system) is worse?


If I had a dime for every person that's asked for this.


You'd have a dime?


I found the article compelling and illuminating, but I wish someone had proofread it for the grammar. Half a dozen times I had to reread a sentence and concluded it wasn't correct English syntax.


The invention of the steel core made the stone facade unnecessary to support the building, so most new buildings are covered in glass instead of stone. That's related to less ornamentation, but to me that's the big distinction between beautiful old buildings and ugly new ones.

It also created a tremendous energy efficiency issue. Stone has much higher thermal mass than glass.


the steel core made it possible to made full glass facades, but it didn't make it necessary

it was even more so of a conscious decision not to use any ornamentation that they weren't limited to stone facades (btw many steel core buildings had stone facades until recently, among other materials like precast concrete - in the financial district of London most buildings pre 2010 are not glass, and most post 2010 are)

it just seems to be the case that the ruling elites like those buildings, and that's the main reason they are pervasive across skylines


Depends on where you live. In a hot, humid climate, that thermal mass works against you because it never cools off enough to let you be passively cool. In a desert that gets cold at night despite hot days, it can work.


Also much more light from big windows making a nicer interior, and an exterior much easier to clean.


I don’t know that the energy efficiency calculation is that simple. Stone is much more mass to move in the first place, and modern glass and insulation technology is very, very good.


The other thing that happened was plate glass got cheap after WW2 when the Pilkington float glass process was introduced.


Consider applying for YC's Summer 2026 batch! Applications are open till May 4

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

Search: