Hacker News new | past | comments | ask | show | jobs | submit login

> I also don't get how running ... would result in a list of Tasks

That's the contract of 'map' in any FP. Turn a container of A into a container of B, and do nothing else (in this case - no telling tasks to start executing).

> Appending the exclamation mark will CPS transform that Task value ... is problematic as you need to also CPS transform the lambda

You may be overthinking it. I believe (!) is a syntax-only transformation which happens very early in the compiler pipeline. And I don't think you need to invoke CPS here:

  CPS From [https://matt.might.net/articles/cps-conversion/]
  The M function only has to watch for lambda terms. When it sees a lambda term, it adds a fresh continuation parameter, $k, and then transforms the body of the lambda term into continuation passing style, asking it to invoke $k on the result. Variables are unchanged
In Roc (and Haskell, Scala, Idris, ...) you don't need to generate a fresh $k under the hood, because it's already right there in the surface language (in this case, foo):

  foo = mytask! "abc"
is already equivalent to:

  mytask "abc" (\foo -> ... )
> See for example CPS-async in Scala:

Why didn't you mention Scala earlier :D. This is the same trick as Scala for-comprehensions. Here's an example in that repo: https://github.com/rssh/dotty-cps-async/blob/36f2e3b61542b39...

> Also every higher order function would need to be there in two variants.

Literally every HOF? Nah, but you're right that there is duplication - and there needs to be, since there is a distinction between:

  convert a *list of filenames* (input) into a *list of Tasks* (output) which will read those filenames

  convert a *list of filenames* into Tasks which will read those filenames, and return their *contents* (output)
If you have List and Task modules, then "do this List of Tasks" obviously has to live in List's source code or Task's source code. It's an N*M implementations problem, but fuck it. Computers do Lists of Tasks so it's worth implementing.

Haskell does a little better non the non-duplication front. By going down the typeclass/monad route, you can put the "do this List of Monads" in List.hs, and "Task is a Monad" in Task.hs, and you're all set. But it still makes a distinction between 'map the list' and 'map the list and return the results of running the monads inside it'. It calls them map and mapM respectively, and also has mapM_ which carries out the effects but also ignores the output.

Anyway, back to my Java day job where the duplication issue in the stdlib is solved by just ... leaving out functionality. Let's see how we tackle the List of Tasks issue: https://stackoverflow.com/questions/30025428/convert-from-li...




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: