Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non sequential Applicatives #559

Merged
merged 29 commits into from
Jan 28, 2024
Merged

Non sequential Applicatives #559

merged 29 commits into from
Jan 28, 2024

Conversation

gusty
Copy link
Member

@gusty gusty commented Oct 12, 2023

This is a key feature, we introduce a "parallel" instance of Applicatives which are normally not monads and therefore don't have sequential behavior.

The goal is to remove a bit friction when using the "interesting" applicative instances without breaking some basic rules which provides useful properties, but adding a different set of operation instead of the classical solution of new-type which involves wrapping and unwrapping all the time and pollutes a lot a simple piece of code.

We call them ZipApplicatives as existing F# core zip-like operations like zip tend to match them.

It's hard to define additional rules for them, but I would say in general we can expect the full zip -unzip roundtrip.
Nevertheless the rule that they don't obey is sequential guarantee, as opposed to the ones derived by Monads.

For Validation it was stated the above roundtrip doesn't hold (see #280), but actually if the monoid type is a set-like it does.

In general, list like will behave point-wise and computations will start in sequence but can finish in any order. The latter is not exactly the same as full parallel which would require using the threadpool, see dotnet/fsharp#10301 (comment) for more context on this distinction.

This design takes into consideration the principle of less surprising, namely:

  • Not breaking the rule of <*> equivalent to </ap/> which would give bad surprises in refactorings/optimizations.
  • Attempt to keep as much as possible existing F# function names, and introducing new ones only in cases where it would otherwise contradict the expectation.
#r @"C:\Repos\FSharpPlus\src\FSharpPlus\bin\Release\netstandard2.1\FSharpPlus.dll"

open FSharpPlus

let r0 = (+) <!> [500; 1000] <.> [1;2;3]
// val r0: int list = [501; 1002]

let x1 = Ok 1
let y1 = Error ["2 didn't work"]
let z1 = Error ["3 didn't work"]

let r1 = app {
    let! x = x1
    and! y = y1
    and! z = z1
    return (x + y + z)
}

// val r1: Result<int,string list> = Error ["2 didn't work"; "3 didn't work"]


let y2 = [2;20;30]
let z2 = [5;50;500; 100000000]

let r2 = app {
    let! x = app { return 1000 }
    and! y = y2
    and! z = z2
    return (x + y + z)
}

// val r2: int list = [1007; 1070; 1530]

Fixes #36
Partially inspired by Parallel

@gusty gusty force-pushed the master branch 4 times, most recently from 9b34ece to b2f3c8c Compare October 15, 2023 05:01
@gusty gusty mentioned this pull request Nov 23, 2023
4 tasks
@gusty gusty force-pushed the master branch 2 times, most recently from 484cff5 to 142c806 Compare December 18, 2023 08:18
@gusty gusty force-pushed the gus/parallel branch 2 times, most recently from fdee9ed to be059d7 Compare January 13, 2024 07:00
@gusty gusty closed this Jan 13, 2024
@gusty gusty reopened this Jan 13, 2024
@gusty gusty force-pushed the gus/parallel branch 3 times, most recently from b76ebfa to be059d7 Compare January 13, 2024 07:58
@gusty gusty changed the title Parallel Applicatives Non sequential Applicatives Jan 24, 2024
@gusty gusty force-pushed the gus/parallel branch 6 times, most recently from 4af4297 to c5de07d Compare January 24, 2024 14:29
@gusty gusty force-pushed the gus/parallel branch 2 times, most recently from 416f433 to c284312 Compare January 25, 2024 06:01
@gusty gusty merged commit 30d990e into master Jan 28, 2024
6 checks passed
@gusty gusty deleted the gus/parallel branch February 12, 2024 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants