Skip to content
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

Cheat sheet for annotations #572

Open
12 of 16 tasks
cristianoc opened this issue Oct 10, 2022 · 9 comments
Open
12 of 16 tasks

Cheat sheet for annotations #572

cristianoc opened this issue Oct 10, 2022 · 9 comments

Comments

@cristianoc
Copy link
Contributor

cristianoc commented Oct 10, 2022

Present a compact cheat sheet for decorators relevant for code generation. Here's a list of all decorators. Irrelevant ones to be removed:

  • @@deprecated
  • @@warning
  • @as only used for runtime representation, except for default arguments @as("someString") _
  • @bs.send.pipe
  • @dead
  • @deprecated
  • @deriving About runtime representation
  • @doesNotRaise
  • @genType
  • @get
  • @get_index
  • @ignore
  • @inline
  • @int not relevant: about runtime representation
  • @LiVe
  • @meth About runtime representation
  • @module
  • @new
  • @obj
  • @raises
  • @react.component
  • @return This mixes runtime representation and externals: a post-processing for results
  • @scope
  • @send
  • @set
  • @set_index
  • @string not relevant: about runtime representation
  • @this Requires annotations on both external and uses
  • @unboxed About runtime representation
  • @uncurry This guarantees that the curried function is treated as if it were uncurried
  • @unwrap Unwraps one level of unary polymorphci variants (e.g. [#Int(int) | #Str(string)]). Should probably be a language-level feature either<(int, string)>.
  • @Val
  • [?] @variadic Should this be a language-level feature?

A few examples covered:

// @val
// external setTimeout: (unit => unit, int) => timeoutID = "setTimeout"
external setTimeout: (unit => unit, int) => timeoutID = "setTimeout($1, $2)"

// @get external getName: window => string = "name"
external getName: window => string = "$1.name"

// @set external setName: (window, string) => unit = "name"
external setName: (window, string) => unit = "$1.name = $2"

// @get_index external get: (t, string) => int = ""
external get: (t, string) => int = "$1[$2]"

// @set_index external set: (t, string, int) => unit = ""
external set: (t, string, int) => unit = "$1[$2] = $3"

// @module("path")
// external dirname: string => string = "dirname"
external dirname: string => string = "import(path).dirname($1)"

// @new external create: unit => t = "Date"
external create: unit => t = "new Date()"

// @send external getElementById: (document, string) => Dom.element = "getElementById"
external getElementById: (document, string) => Dom.element = "$1.getElementById($2)"

// @module("library-x")
// @val external doStuff: (@as(json`{format:"utf8", includeStuff: false}`) _, string) => string = "doStuff"
external doStuff: string => string = "import(library-x).doStuff({format: 'utf8', includeStuff: false}, $1)"

// @val external doSomething: (@ignore 'a, 'a) => unit = "doSomething"
external doSomething: ('a, 'a) => unit = "doSomething($2)"

// @obj
// external action: (~name: string, unit) => _ = ""
external action: (~name: string, unit) => _ = "{name:$1}"

// @scope("Math") @val
// external floor: float => int = "floor"
external floor: float => int = "Math.floor($1)"
@cristianoc
Copy link
Contributor Author

How to describe the difference between @scope and @module ?

@IwanKaramazow
Copy link
Collaborator

I didn't know, but are the $1, $2 placeholder a thing?

@cristianoc
Copy link
Contributor Author

cristianoc commented Oct 10, 2022

Just a compact notation to describe what the examples do. But once all the uses of attributes are lined out, it might suggest a decent universal representation.

@cristianoc
Copy link
Contributor Author

Looks like @variadic can be moved to the language in principle e.g. little prototype: rescript-lang/rescript-compiler#5727

So it becomes about runtime representation and not about FFI.

@cristianoc
Copy link
Contributor Author

Just used import(-) to mark @module things. Just as a notation to differentiate from @scope.
And removed @variadic.
This gives a pretty small, self-contained set of things that can be expressed.

@IwanKaramazow
Copy link
Collaborator

Since import wasn't well received, a couple of ideas for importing values from javascript:

external "path" {
  dirname: string => string,
  renameSync as rename: (string, string) => string,
  "weird identifier" as ident: unit => unit
}

// entire module contents
external "leftPad" {
  * as leftPad: (string, int) => string
}

// import default export
external "./modules/school.js" {
  default as schoolName: string,
}
// or simply: (this could be too much)
external "./modules/school.js" as schoolName: string

@ryyppy
Copy link
Member

ryyppy commented Feb 3, 2023

@cristianoc is this issue about having a separate page that lists all possible constructs in one example? Or are you talking about extending our syntax lookup, that lists all the decorators already?

image

@cristianoc
Copy link
Contributor Author

@cristianoc is this issue about having a separate page that lists all possible constructs in one example? Or are you talking about extending our syntax lookup, that lists all the decorators already?

image

This is not necessarily about description only. It could be a different way to express FFI in future. Perhaps not super relevant for the doc site right now.

@cristianoc
Copy link
Contributor Author

A few additional comments from discussions with folks

@val standalone binds to globals. But in any recent JS version you wouldn’t need that anymore. There’s a global object now

I’m not sure how useful @this is. Binding to modern libraries that use OOP is a challenge. A mere @this might not be enough anyway

I’m not sure @scope is needed because we can just special-case a few built-ins like Math and others in @module

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants