-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to type Erlang terms without built-in types. #236
Comments
Great question/point, thanks! I've had some related thoughts around a kind of opaque/foreign type, e.g. for saying "this value coming back is type Full disclosure: I may be using the term "opaque type" incorrectly but I do think what we're talking about is information hiding to some degree? Would something like the following work do you think? module sets
opaque type set 'a
val addElement 'a : fn 'a (set 'a) -> (set 'a)
let addElement e s =
beam :sets :add_element [e, s] with
| s2 -> s2 I think if we have something like opaque types they would have to be disallowed in unqualified unions, e.g. Thoughts? EDIT: I used snake case, corrected to camel :( Old habits! |
Sounds sensible to me, though I could see some unions needing qualification and some not being confusing. |
I think it's more an issue for the type inferencer than anything else to be honest. Some details, given: opaque type set 'a
type t = int | set 'a Then here: let foo x = match x with
| i, isInteger i -> "got an integer"
| s -> "got a set" The typer actually has no way to know that
In this case things should be unambiguous for the typer: opaque type set 'a
type t = int | Set set 'a
let foo x = match x with
| i, isInteger i -> "got an integer"
| Set s -> "got a set" (I think we could even drop the opaque type set 'a
type t = Int int | Set set 'a
let foo x = match x with
| Int i -> "got an integer"
| Set s -> "got a set" (ignoring issues with decidability of record types that I've been reading hints of in 1ML papers but do not yet understand) |
opaque type set 'a
type t = Int int | Set set 'a
let foo x = match x with
| Int i -> "got an integer"
| Set s -> "got a set" This example where both are qualified looks like the clearest approach to me (perhaps because I'm used to Haskell and Elm). It would be my preference for there to be as few extra rules to remember in the language, especially if the rules are based around implementation details of the language. |
I tend to agree. Unqualified vs qualified (or untagged vs tagged) have come up a few times in conversation with both @danabr and @lepoetemaudit over the last year or so. Unions without constructors were consciously made part of Alpaca initially because Erlang programs could quite easily send a mix of types without constructors and I thought it might be best to support this. I'm less and less sure as time goes by :) One thing that might be more reasonable is to require constructors with a per-module switch to degrade the type system, allowing untagged unions in special cases for Erlang interop. I'm not 100% sure yet but I think "decidable by default, understand the rules if you want to play with fire" might be the better direction. |
Another alternative could be a system like Purescripts val decodeInt : fn foreignData -> result string int This can get boilerplate-y though. In Elm I write a lot of decoders that look like this: decoder : Decoder VideoLibraryItem
decoder =
decode VideoLibraryItem
|> required "id" int
|> required "title" string
|> required "created_at" date
|> optional "placer_name" (nullable string) Nothing and are run with decodeValue : Decoder a -> Value -> Result String a A "trust me, I know what I'm doing" escape hatch would likely be required though for places where this overhead is impractical. i.e. implementing alpaca_lib |
I think we're now moving a little into the realm of #7 here but that's probably a good thing. I'm not super keen on an unqualified "trust me" but a "trust me but check for me and explode if I got it wrong" I think is arguably helpful. For something like this we'd need to add guards and recursive checks at the code gen stage so there would be a performance penalty but might be worthwhile sometimes? |
Hello!
I wish to add a
set
module toalpaca_lib
. Given the term is defined in Erlang and not Alpaca how do I define the type?I could do something like
type set 'a = Set
but then I have thisSet
constructor that can be incorrectly used in place of an actual set term.Is something like
beam_type Set
needed? Or perhaps we could havetype set
without an= ...
for this.The text was updated successfully, but these errors were encountered: