5 ms·
Sure thing, I'm still pretty new at F# but have a good handle on Typescript since I get to use it at work. The three main things I find similar are the syntax,
by bern4444 6y ago
Sure thing, I'm still pretty new at F# but have a good handle on Typescript since I get to use it at work.
The three main things I find similar are the syntax, ability to compose new types from other types, and the ability to limit types to certain options. Both support | as an OR and support an AND operation. F# does a bit more allowing the product of types though.
Syntax Example:
Typescript
---------------
type Check = {
amount: number;
account: number;
...
}
F#
--------------
type Check = {
account: int;
amount: int
}
I think I need to become a bit more familiar though with F# to understand the differences better. I hadn't yet heard the term nominal to describe a type system before so I'll look into it further. Perhaps I'm focusing more on the syntax than is warranted...
Completely separately, how does one properly format on HN? Is it possible? Is there a doc somewhere? I'm fairly new to commenting...
- jolux 6y agoFormatting is rudimentary but it exists: https://news.ycombinator.com/formatdoc https://news.ycombinator.com/formatdoc Your example is actually a really good one for discussing these differences, and the syntax is indeed similar. That TypeScript code is introducing a "type alias," which is a special name for another type, rather than a new type of itself. (https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-aliases https://www.typescriptlang.org/docs/handbook/advanced-types....) This is a concept that F# does not have, because F# doesn't support structural typing. In TypeScript, you could just as well specify that a function returns { amount: number; account: number; } directly, and it would be equally compatible with anything expecting a "Check," because Check is just a shorthand for that object type. I can't easily declare that a function accepts { account: int; amount: int; } in F#, I have to declare that it accepts "Check." That is the main difference between TS and F# here, and incidentally also the most basic difference between structural and nominal type systems. I'm not sure why the syntax is similar though, F#'s is based on OCaml's record syntax while TypeScript's is really just a JavaScript object literal but with semicolons instead of commas. I believe it supports commas too. It may be genuine coincidence, or the designers of TS may know of the ML family, which is highly influential among language designers and implementers.
- bern4444 6y agoThanks for the formatting link, exactly what I was looking for to format code a bit better. That actually helps me understand some F# code I wrote last weekend as well regarding construction of objects of a certain type... I didn't know about the difference between nominal vs structural types but your explanataion makes sense. It's the subtle distinction between a type vs a type alias that you pointed out. I personally use type aliases in typescript over interfaces, I think they're a more natural fit for JS than interfaces but that's a separate conversation :) Language design is really interesting especially the choices designers make. I feel like they must all pull at least in part from each other and would be curious to explore any relationships but if its total coincidence that's pretty incredible too.
- jolux 6y ago> I personally use type aliases in typescript over interfaces, I think they're a more natural fit for JS than interfaces but that's a separate conversation :) The TypeScript docs recommend the opposite, preferring interfaces. Interfaces are also structurally typed in TypeScript though; the major differences are that interfaces can only be used to declare object types: https://microsoft.github.io/TypeScript-New-Handbook/everything/#interface-vs-alias https://microsoft.github.io/TypeScript-New-Handbook/everythi...
- bern4444 6y agoI don't see that recommendation on the page... The fact that interfaces are limited to typing objects but type aliases can also be used for functions is an easy +1 to type aliases. My view is that declaration merging is a bit of an anti pattern that could cause trouble if two different people write an interface with the same name but to represent different data... now they get merged incorrectly. A type alias forces more explicit behavior where composition must be done by creating a new type alias as the union of two or more other types type Foo = Bar & Baz Edit: found the page, its here https://www.typescriptlang.org/docs/handbook/advanced-types.html#interfaces-vs-type-aliases https://www.typescriptlang.org/docs/handbook/advanced-types.... Yeah, not sure I agree yet but I could be persuaded... I don't think type aliases prevent extension, they just force it to be explicitly declared.