rokucommunity / rokucommunity/brighterscript
Add closure support
Open
Nobody has claimed this yet.
enhancement
- Dominant language
- TypeScript
- Stars
- 208
- Forks
- 68
- Avg merge
- 8h 39m
- Merged PRs (30d)
- 39
Description
BrighterScript should support closures.
Here's a quick example:
sub onButtonClick(event)
response = "" 'gets set by closure below
checkEmail = (domain) => {
inputValue = m.emailAddressTextEditBox.text
if inputValue.endsWith(domain) then
response ="valid"
else
response = "invalid"
end if
}
checkEmail("@roku.com")
return responseMessage
end sub
would transpile to:
sub onButtonClick(event)
local = {
event: event
}
local.response = "" 'gets set by closure below
local.checkEmail = {
type: "arrow-function",
scopes: [local],
m: m,
func: function(__closure, domain)
inputValue = __closure.m.emailAddressTextEditBox.text
if inputValue.endsWith(domain) then
__closure.scopes[0].response ="valid email"
else
__closure.scopes[0].response = "invalid email"
end if
end function
}
local.checkEmail.func(local.checkEmail, "@roku.com")
return responseMessage
end sub
Considerations:
- the moment a closure is created, we force all local variables onto an AA, and there are no longer any true local variables. This allows the "local" scope to get "captured" and flow through any child closures
- since a closure needs type tracking, this can only be implemented in the alpha branch.
- Add a
ArrowFunctioninterface type which can be used as function parameters and other types.sub Validate(validationFunction as ArrowFunction) validationFunction() 'transpiles to validationFunction.func(validationFunction) end sub - In the initial release, we will restrict closures from being passed into any parameter/assignment not explicitly marked as
ArrowFunctionsub main() arrowFunc = () => { return true } name = "bob" name = arrowFunc' ERROR: arrow function cannot be assigned to non-closure existing variable logInfo(arrowFunc) 'ERROR: arrow function cannot be passed as parameter not explicitly marked as `ArrowFunction` callArrowFunc(arrowFunc) ' OK arrowFunc = ()=> {return false} ' OK since previous var was also an arrow function end sub sub logInfo(anything as dynamic) print anything end sub sub callArrowFunc(func as ArrowFunction) func() end sub - Nested closures should be supported. For example:
transpiles to:sub onButtonClick(event) outerName = "outer" outerFunc = () =>{ innerName = "inner" print outerName innerFunc = () => { print outerName; innerName } innerFunc() } outerFunc() end subsub onButtonClick(event) local = { event: event } local.outerName = "outer" local.outerFunc = { scopes: [local], m: m, func: function(__closure) local = {} local.innerName = "inner" print __closure.scopes[0].outerName local.innerFunc = { scopes: [__closure.scopes[0], local] m: __closure.scopes[0], func: function(__closure) print __closure.scopes[0].outerName; __closure.scopes[0].innerName end function end function local.innerFunc.func(local.innerFunc) end func } local.outerFunc.func(local.outerFunc) end sub
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No implementation files or tests are named. Start on the alpha branch by locating the parser, type-tracking, and transpilation entry points, then compare their current behavior with the closure examples in this issue. Done means supporting captured and nested closures, ArrowFunction typing, and the stated assignment and parameter restrictions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100