Skip to content

Commit

Permalink
TODO added questions
Browse files Browse the repository at this point in the history
  • Loading branch information
h0lg committed May 1, 2024
1 parent bcc58bd commit c151432
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/Fabulous/Cmd.fs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ module Cmd =

[ bind >> start ]

//TODO this doesn't use Async.Catch - is that intended?
//Is this misplaced here or should that be documented? Or is there some magic involved that turns an exn into None?
/// Command that will evaluate an async block and map the success
let performOption (start: Async<unit> -> unit) (task: 'a -> Async<_ option>) (arg: 'a) (ofSuccess: _ -> 'msg) : Cmd<'msg> =
let bind dispatch =
Expand All @@ -176,6 +178,10 @@ module Cmd =

[ bind >> start ]

//TODO Please trim the fat from this description.
//TODO There are some caveats and warnings against using Async.Start in the chapter behind that first link. Do they need to be reflected here?
//TODO When would I use this instead of OfAsyncImmediate? Why would I not always use OfAsyncImmediate? Are there some typical use cases?
// How can we help devs decide which sub-module to use?
/// For building Commands from Async functions queued to be run in the background, started on a thread pool thread using Async.Start.
/// Suitable for long-running or CPU-bound computations where you want to free up the UI thread to remain responsive to do other work.
/// See https://learn.microsoft.com/en-us/dotnet/fsharp/tutorials/async#asyncstart
Expand All @@ -202,6 +208,9 @@ module Cmd =
let inline msgOption (task: Async<'msg option>) =
OfAsyncWith.performOption Async.Start (fun () -> task) () id

// TODO I took parts of this description from the link source, suggesting this has an effect on async ops updating the UI.
// But using Cmd.OfAsync seems to work just fine for them as well. So why use this then?
// Is there an example out there demonstrating the effect - or can one be made up?
/// For building Commands from Async functions started immediately on the current operating system thread
/// using Async.StartImmediate. This is helpful if you need to update something on the calling thread during the computation.
/// For example if an asynchronous computation must update a UI (such as updating a progress bar).
Expand Down
7 changes: 7 additions & 0 deletions src/Fabulous/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ namespace Fabulous
open System
open System.Diagnostics

(*TODO Is either of these a program in the Elm sense? If so, where's the view in this one?
Or are these rather abstractions of or pre-cursors to an Elm Program?
AFAIU in the Elm architecture a "program" manages the application's (or component's) state, actions, and view rendering.
Please help me as a MVU/Elm newbie understand these types. *)
//TODO what's the 'arg?
/// Configuration of the Fabulous application
type Program<'arg, 'model, 'msg> =
{
Expand All @@ -21,6 +26,7 @@ type Program<'arg, 'model, 'msg> =
ExceptionHandler: exn -> bool
}

//TODO how is this different to the above? What's a 'marker? what's the 'arg?
type Program<'arg, 'model, 'msg, 'marker> =
{
State: Program<'arg, 'model, 'msg>
Expand Down Expand Up @@ -112,6 +118,7 @@ module Program =
/// </summary>
let withSubscription (subscribe: 'model -> Sub<'msg>) (program: Program<'arg, 'model, 'msg>) = { program with Subscribe = subscribe }

//TODO In what scenario would I want to use this?
/// Map existing subscription to external source of events.
let mapSubscription map (program: Program<'arg, 'model, 'msg>) =
{ program with
Expand Down
4 changes: 4 additions & 0 deletions src/Fabulous/Sub.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ namespace Fabulous

open System

//TODO if this is a Subscription ID...
/// Subscription ID, alias for string list
type SubId = string list

//TODO ...then is this not rather the Subscription...
/// Starts a subscription by supplying a Dispatch{'msg}
/// which it may use to start dispatching messages similar to Effect{'msg}.
/// Returns an IDisposable to stop it.
type Subscribe<'msg> = Dispatch<'msg> -> IDisposable

//TODO ...and this an ID'd Subscription list?
/// Subscription - Generates new messages when running
type Sub<'msg> = (SubId * Subscribe<'msg>) list

Expand All @@ -21,6 +24,7 @@ module Sub =
/// Aggregate multiple subscriptions
let batch (subs: Sub<'msg> list) : Sub<'msg> = List.concat subs

//TODO How does this relate to Program.mapSubscription ?
/// When emitting the message, map to another type.
/// To avoid ID conflicts with other components, scope SubIds with a prefix.
let map (idPrefix: string) (f: 'a -> 'msg) (sub: Sub<'a>) : Sub<'msg> =
Expand Down

0 comments on commit c151432

Please sign in to comment.