BorrowScript icon indicating copy to clipboard operation
BorrowScript copied to clipboard

Inferred gates?

Open WebReflection opened this issue 4 years ago • 1 comments

It's not instantly clear from the README why imported utilities or references, such as queue tasks don't require gates, but lamdas do for user defined, not imported, variables.

As I believe this idea would be better off with zero globals around, wouldn't be easier to have outer-scope references infeered, hence with automatic gates around?

The possibilities to discuss would then be:

  • what is the default gate behavior for these? read, write, move, or copy? I'd say read for const and write for let, as most common use cases, with the ability to override this behavior through the current syntax and explicit a copy, or a move
  • what makes exported references so special, compared to user defined values? ... why I can console.log everywhere, even in lambdas/arrows, but I need explicit gates around other values?

Thanks in advance for any kind of clarification/discussion/outcome 👋

WebReflection avatar Nov 12 '21 13:11 WebReflection

The concurrency part of the specification was drafted initially and left as a rough outline until we refined some of the more foundational language syntax. Gates came after I wrote the concurrency documents.

Initially I wanted to have the Queue be something that could be dependency injected and or managed such that there were multiple queues - perhaps that would be useful to testing or offloading certain workloads to certain processors however after some time thinking about it I think that might be an over optimization for a language with an intention of being simple.

I am thinking of dropping manual queue management and using a built-in concurrency method akin to Goroutines, spawned off a keyword and managed with Promise/Observable types.

What I am currently thinking about is breaking the convention set by other languages with async/await keywords and using async to spawn a coroutine that may or may not be on another thread.

This would disconnect await from async where await would only be used for essentially unwrapping a Promise which is unrelated to managing concurrency. async would not be used to decorate a function that uses an await as it could be inferred by usage.

function main() {
  async function(){
    console.log('Hello World')
  }()

  await time.sleep(time.Duration.Second * 5)
}

An alternative I was thinking about was using async and yield - to avoid confusing C#, Kotlin and JavaScript programmers.

function main() {
  async console.log('Hello World')

  yield time.sleep(time.Duration.Second * 5)
}

At this point I am mentally examining how this would fit in with the Promise pattern or if something like channel which can be passed into the the callback via a ownership gate is necessary

But yes callbacks, concurrent or not, will need to explicitly declare their gates to consume variables from an outer scope.

function main() {
  const foo = 'foo'

  async function()[read foo]{
    console.log(foo)
  }()

  await time.sleep(time.Duration.Second * 5)
}

alshdavid avatar Apr 03 '22 23:04 alshdavid