Skip to content

"Big" async example program #250

@surprisetalk

Description

@surprisetalk

I thought it might be helpful to whip up a larger example that we can use as a milestone and discussion topic:

  • I included ; as where and . as record-access. I thought that's where we landed in our last discussion, but I may have misremembered. If these are welcome changes, I can open up a separate issue/PR.
  • My example relies heavily on async patterns. We haven't really discussed this yet, so I thought this might be a nice opportunity to get that conversation going. I also totally understand if we want to punt it.

I would eventually like to run the program via CLI like this:

scrap platform task < example-task.scrap

I'm hoping that the task platform can accept something like an Elm task.

Anyway, here's the example:

!!

! csv <- http { url = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data" }

! data <- 
    ( csv |> csv/decode { header = false } iris-decoder |> task/from-result
      ; iris-decoder = 
          csv/decode/map5 
            (sepal_length -> sepal_width -> petal_length -> petal_width -> species -> 
               { sepal_length
               , petal_length
               , sepal_width
               , petal_width
               , species
               }
            )
            (csv/decode/field float)
            (csv/decode/field float)
            (csv/decode/field float)
            (csv/decode/field float)
            (csv/decode/field text)
    )

! _ <- debug/print "First 10 rows:"
! _ <- data |> list/take 10 |> debug/print

! _ <- debug/print "Summary:"
! _ <- ( data |> group-by (row -> row.species) |> dict/map stats |> debug/print
         ; group-by : (a -> text) -> list a -> dict text (list a) =
             f ->
               list/foldl 
                 (x -> dict/update (f x) (maybe/default [] >> list/append [x] >> some))
                 dict/empty 
         ; stats = rows ->
             { sepal_length = rows |> list/map (row -> row.sepal_length) |> colstats
             , petal_length = rows |> list/map (row -> row.petal_length) |> colstats
             , sepal_width = rows |> list/map (row -> row.sepal_width) |> colstats
             , petal_width = rows |> list/map (row -> row.petal_width) |> colstats
             }
         ; colstats = cells -> 
             { count = list/length cells
             , mean = list/mean cells
             , mode = list/mode cells
             , median = list/median cells
             }
       )

! ()

So I guess the immediate questions:

  1. Should I open up a separate issue/PR for ; and .?
  2. Is there anything weird/unexpected here that needs explanation?
  3. Is it too early for async? Should I perhaps try to come up with a large synchronous example first?
  4. If we like this as a milestone to work toward, what small steps should I take next? Create issues for dict, list, type declarations, task, etc?

(I'm still learning how to be a good open-source collaborator... Please let me know how I can improve!)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions