gren-lang / gren-lang/compiler

How could task chaining work?

Open
#39 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

exploration
Dominant language
Haskell
Stars
503
Forks
29
PR merge metrics
No merged PRs in 30d

Description

If Gren is going to support backend platforms and improve the kind of side effects you can do in the browser by broadening browser API support, it would be very helpful to have some sort of syntax to help with the readability of Task heavy code.

This issue can be a placeholder to capture how other languages accomplish this, and examples of the kind of code that would benefit from such a feature.

How do other languages do task chaining?

Elm

Uses task values, no syntax sugar, manipulate tasks via Task.andThen and other Task functions.

makeTestDb : () -> Task String DB
makeTestDb () =
    Sqlite.makeDb
        |> Task.andThen
            (\db ->
                Fs.readFile "./sql/db.sql"
                    |> Task.andThen (\sql -> Sqlite.exec sql db)
                    |> Task.andThen
                        (\() ->
                            Fs.readFile "./sql/test-data.sql"
                                |> Task.andThen (\sql -> Sqlite.exec sql db)
                        )
                    |> Task.map (always db)
            )

JS

JS uses async/await and the Promise type. Functions can be marked as async, and expressions can be prefaced with await, which will lift the success value out of the promise or return the promise with the error on the spot.

async function makeTestDb() {
  let queries = await fs.readFile('create-db.sql')
  let db = await sqlite.createInMemory()
  await sqlite.exec(queries)
  let testData = await fs.readFile('test-data.sql')
  await sqlite.exec(testData)
  return db
}
F#

F# has an Async type which you can use like Elm’s Task and an async computation expression which allows flattening the callbacks and having a more direct control flow.

let makeTestDb () = async {
  let! queries = Fs.readFile "create-db.sql"
  let! db = Sqlite.createInMemory ()
  do! Sqlite.exec queries
  let! testData = Fs.readFile "test-data.sql"
  do! Sqlite.exec testData
  return db
}

https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/async-expressions


Code examples that would benefit from task chaining

TODO

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The issue names no compiler files, tests, or entry points. Start by comparing the Elm, JavaScript, and F# approaches documented here, then add concrete Gren examples and turn the placeholder into a scoped proposal with observable syntax and behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
elm, fsharp, javascript
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.