Live data from Hacker News

Phantom Types in Gleam

blog.pd-andy.dev

1–10 of 13 posts

Re: Phantom Types in Gleam

#2
This is a good post and technique in general.

I used to use it extensively in C++: beware though of (super long) compile errors while nesting them through templates params. :)

Edit: I was wrapping pointers for instance to not mix GPU and CPU memory addresses, to define a unidirectional flow of memory transfers between devices (and avoid manual synchronisation and tracking)... etc.

You could somehow define a state machine through types and ensure compositional coherence.

Re: Phantom Types in Gleam

#3
It's kind of amusing reading this as a Typescript dev because I'm so used to Typescript's expressiveness I couldn't really work out which trick it was trying to tell me was novel.

The answer is structural typing (aka duck typing).

Re: Phantom Types in Gleam

#4
post #2

This is a good post and technique in general. I used to use it extensively in C++: beware though of (super long) compile errors while nesting them through templates params. :) Edit: I was wrapping pointers for instance to not mix GPU and CPU memory addresses, to define a unidirectional flow of memory transfers between devices (and avoid manual synchronisation and tracking)... etc. You could somehow define a state mac…

Using phantom types in state machine transitions is really cool, yeah. I came across a little gist that explored that idea in Elm [1] the other day, actually.

[1]: https://gist.github.com/rupertlssmith/88946c8d207d7ad64daf43...

Re: Phantom Types in Gleam

#5
post #3

It's kind of amusing reading this as a Typescript dev because I'm so used to Typescript's expressiveness I couldn't really work out which trick it was trying to tell me was novel. The answer is structural typing (aka duck typing).

Not quite. I guess in some ways phantom types achieve the opposite of structural typing.

In a language with structural typing, two types are considered equivalent if they share the same structure. With phantom types we can have a single structure and disambiguate between different uses without touching the underling structure. There's no difference between Id(User) and Id(Post) at runtime, the annotation is purely a compile-time restraint.

In fact, because of typescript's structural typing, the only way to use phantom types in ts is to have some dummy field of type `never` that the type system can use to disambiguate between the two [1].

[1]: https://gist.github.com/GoNZooo/243b23702df1fae38c966ae18832...

Re: Phantom Types in Gleam

#7
post #5
post #3

It's kind of amusing reading this as a Typescript dev because I'm so used to Typescript's expressiveness I couldn't really work out which trick it was trying to tell me was novel. The answer is structural typing (aka duck typing).

Not quite. I guess in some ways phantom types achieve the opposite of structural typing. In a language with structural typing, two types are considered equivalent if they share the same structure. With phantom types we can have a single structure and disambiguate between different uses without touching the underling structure. There's no difference between Id(User) and Id(Post) at runtime, the annotation is purely a…

Holy smokes, that would be irritating :D

Btw. is there a difference between these two:

    (s: string): PlainText => s;
    (s: string): PlainText => s as any as PlainText;
Syntax-wise I'd rather use the latter for it's more clear in typed JSX-context.

Re: Phantom Types in Gleam

#8
post #7
post #5

Earlier quoted context omitted.

Not quite. I guess in some ways phantom types achieve the opposite of structural typing. In a language with structural typing, two types are considered equivalent if they share the same structure. With phantom types we can have a single structure and disambiguate between different uses without touching the underling structure. There's no difference between Id(User) and Id(Post) at runtime, the annotation is purely a…

Holy smokes, that would be irritating :D Btw. is there a difference between these two: (s: string): PlainText => s; (s: string): PlainText => s as any as PlainText; Syntax-wise I'd rather use the latter for it's more clear in typed JSX-context.

As far as I know those two are equivalent. Definitely slightly clunkier, but is what it is.

Re: Phantom Types in Gleam

#9
post #5
post #3

It's kind of amusing reading this as a Typescript dev because I'm so used to Typescript's expressiveness I couldn't really work out which trick it was trying to tell me was novel. The answer is structural typing (aka duck typing).

Not quite. I guess in some ways phantom types achieve the opposite of structural typing. In a language with structural typing, two types are considered equivalent if they share the same structure. With phantom types we can have a single structure and disambiguate between different uses without touching the underling structure. There's no difference between Id(User) and Id(Post) at runtime, the annotation is purely a…

Yes, exactly, it's because of Structural Typing that you have to implement Phantom Types in that hacky way rather than Structural Typing being the "trick".
Post reply on HN