Functional way of handling configuration for a library - f#

In C# a library might expose an interface which implementation you provide using a DI container, what is the functional way to go about this? I want to make something configurable in a library ('library-wide') and be able to set in from the main code.

You can certainly still use an interface and a DI container in F#. However, there are other approaches that functional programming offers that may also work for you. Some options might be:
Partial Application: You have a set of functions in a module that take the configuration information as their first parameter (say, as a record type). You can then partially apply these functions, passing just the configuration, returning functions that just take the remaining parameters. For example:
type Config =
{
ConnectionString: string
SuperMode: bool
NumberOfWidgets: int
}
module Library =
let login (config: Config) userName passwordHash =
// do stuff
()
let createWidget (config: Config) widgetName widgetValue =
// do stuff
()
let config = {ConnectionString = "localhost"; SuperMode = true; NumberOfWidgets = 3}
let configuredLogin = Library.login config // configuredLogin is a function taking userName and passwordHash
let configuredCreateWidget = Library.createWidget config // configuredCreateWidget is a function taking widgetName and widgetValu
Closures: You have a function that accepts the configuration and returns one or more other functions that close over the configuration and use it when called. For example:
let applyConfig (config: Config) =
(fun userName passwordHash ->
Library.login config userName passwordHash), // do login using the config
(fun widgetName widgetValue ->
Library.createWidget config widgetName widgetValue) // create the widget using the config
let login, createWidget = applyConfig config // Returns functions that close over the Config and use it when called
Choose whichever way best suits your needs, and don't rule out using a proven approach you're familiar with just because it isn't 'functional'.

Related

F# Singleton and disposing internal resources

In my AWS lambda function, I need to access secret values from the AWS Secret manager. I am using the AWSSDK.SecretsManager.Caching package to achieve this. To get the most out of the provided caching mechanism, I have decided to create a simple singleton wrapper around the SecretsManagerCache:
namespace MyProject
open Amazon.SecretsManager.Extensions.Caching
type SecretsProvider private () =
let secretsCache = new SecretsManagerCache()
static let instance =
SecretsProvider()
static member Instance = instance
member this.GetSecretString key =
secretsCache.GetSecretString key
This seems to be fine, but there is one thing that concerns me. The SecretsManagerCache implements IDisposable. I have tried writing
use secretsCache = new SecretsManagerCache()
but that gives me a compiler error saying 'use' bindings are not permitted in primary constructors. Is it OK to simply use the let keyword? Or should I implement a finalizer?
override this.Finalize() =
secretsCache.Dispose()
Or is there another way how to safely dispose an internal resource from a singleton?
You can wrap your SecretsManager in a SecretsProvider like you have done but implementing IDisposable to dispose of the SecretsManager object.
type ISecretsProvider =
abstract member GetSecretString : key:string -> string
type SecretsProvider () =
let secretsCache = new SecretsManagerCache()
interface IDisposable with
member x.Dispose() = ()
secretsCache.Dispose()
interface ISecretsProvider with
member this.GetSecretString key =
secretsCache.GetSecretString key
You can then declare your dependencies in your functions e.g:
f : ISecretsProvider->int->'T
g : 'T->unit
h : ISecretsProvider->unit
For a console application you can provide the only instance of this dependency in your entry point function:
[<EntryPoint>]
let main _ =
use sp = new SecretsProvider()
let a = f sp 2
g a
h sp
If you're using ASP.NET core you can do so with configureServices:
let configureServices (services : IServiceCollection) =
services.AddSingleton<ISecretsProvider, SecretsProvider>() |> ignore
Update: As Discussed with #Panagiotis Kanavos the SecretsProvider may not be necessary. You may use SecretsManager instead of ISecretsProvider an SecretsProvider in the above code. However, to achieve loose coupling interfaces are good practice, this will depend more on the complexity and goals of your overall solution.

Dart has a standard way to externalize settings like Java properties?

I'm looking for the right way to externalize the settings in my server Dart application.
In Java the common way would be a property file. Exists something similar in Dart?
You can just use a Dart script for your settings. No point in using a different format if there is no specific reason.
With a simple import you have it available in a typed way.
When the Resource class is implemented, I would just use a JSON file that is deployed with my program.
You could use a global variables, for example:
DB_URL = 'localhost:5432/mydb';
DB_PASS = 'my_pass';
then you could create a different configuration file for every enviroment. For example, for production you could create a production_config.dart which could contains:
loadConfig() {
DB_URL = '123.123.123.123:5432/mydb';
DB_PASS = 'my_prod_pass';
}
Then in your main function you could call production_config.loadConfig if environment is production, for example:
import 'production_config.dart' as prodConfig;
main(List<String> args) {
var ENV = getEnvFromArgs(args);
if(ENV == 'PROD') {
prodConfig.loadConfig();
}
//do other stuff here
}
In that way if you want to change from development to production you only need to pass an argument to your dart program for example:
dart myprogram.dart -env=PROD
The advantages of this approach are that you don't need to create a separate properties, json or yaml file for this, and you don't need to parse them. Furthermore the properties are type-ckecked.
I like putting configuration in a Dart class like what Günter Zöchbauer was talking about, but there is also the option of using the safe_config package. With this you enter the values in a yaml file. Quoting from the docs:
You define a subclass of Configuration with those properties:
class ApplicationConfiguration extends Configuration {
ApplicationConfiguration(String fileName) :
super.fromFile(File(fileName));
int port;
String serverHeader;
}
Your YAML file should contain those two, case-sensitive keys:
port: 8000
serverHeader: booyah/1
To read your configuration file:
var config = new ApplicationConfiguration("config.yaml");
print("${config.port}"); // -> 8000
print("${config.serverHeader}"); // -> "booyah/1"
See also an example from a setup in Aqueduct.
main() {
var env = const String.fromEnvironment("ENV", defaultValue: "local");
print("Env === " + env);
}
Give environment as option while running Dart App
pub serve --port=9002 --define ENV=dev
References:
http://blog.sethladd.com/2013/12/compile-time-dead-code-elimination-with.html
https://github.com/dart-lang/sdk/issues/27998

How to implement application wide variables

I'm trying to implement a settings module in my app which should contain information about current state of application. For example, if the user opens some file I need to store the file name. Since I'm still learning F# I want to do it as functional a possible.
I know I should create a new value everytime I change something, but where do I store this value? It should be a singleton and since it's immutable I struggle with the solution.
How do I implement such "global variable"? Does it even play well within functional approach?
This works just as it would within a function, with let mutable (used inside a module):
let mutable a = 4
a // gets a
a <- 6 // sets a
Or, you could use a mutable object as a static member (this example uses a mutable reference cell):
type Settings =
static member Filename = ref ""
Settings.Filename := "OpenMe.txt"
Global variables may be necessary sometimes, and this could be a viable use case, but they are considered dangerous. Values that change and influence a large portion of the program can make things rather unpredictable.
That said, in cases like yours, a single global variable can be a good solution. It could hold a record with the individual settings. I'd pay attention that any operations changing the global variable happen only when the program is in a well-defined state (i.e. not in the middle of a complicated operation) and guarantee that the variable's new value is sound.
Example:
type StateVariables =
{ Filename : string
Opened : int }
module State =
let mutable private cur = { Filename = ""; Opened = 0 }
let get () = cur
let openFile name =
// ...
cur <- { cur with Filename = name; Opened = cur.Opened + 1 }
You can store a global variable in a module:
module Settings =
let mutable FileName = ""
open Settings
FileName <- "foo"

Is there any way to use JavaScript attribute by default?

I just want somehow to say "I want all methods in this project use [JavaScript]"
Manually annotation every method is annoying
F# 3 lets you mark a module with the ReflectedDefinition attribute (aka [JavaScript] in WebSharper) which marks all the methods underneath.
See More About F# 3.0 Language Features:
(Speaking of uncommon attributes, in F# 3.0, the
[< ReflectedDefinition >] attribute can now be placed on modules and
type definitions, as a shorthand way to apply it to each individual
member of the module/type.)
I think Phil's answer is the way to go - when you can mark an entire module or type, it does not add too much noise and it also allows you to distinguish between server-side and client-side code in WebSharper.
Just for the record, the F# compiler is open-source and so someone (who finds this issue important) could easily create branch that would add an additional command line attribute to override the setting. I think this is just a matter of adding the parameter and then setting the default value of the reflect flag in check.fs (here is the source on GitHub).
At the moment, the main F# repository does not accept contributions that add new features (see the discussion here), but it is certainly a good way to send a feature request to the F# team :-)
If you annotate all your code with the JavaScript attribute, the WebSharper compiler will try to translate everything to JavaScript. A rule of thumb in WebSharper development is to separate server-side and client-side code, so you can simply annotate the module/class containing client-side code instead of every function/member if you're targeting .NET 4.5.
namespace Website
open IntelliFactory.WebSharper
module HelloWorld =
module private Server =
[<Rpc>]
let main() = async { return "World" }
[<JavaScript>] // or [<ReflectedDefinition>]
module Client =
open IntelliFactory.WebSharper.Html
let sayHello() =
async {
let! world = Server.main()
JavaScript.Alert <| "Hello " + world
}
let btn =
Button [Text "Click Me"]
|>! OnClick (fun _ _ ->
async {
do! sayHello()
} |> Async.Start)
let main() = Div [btn]
type Control() =
inherit Web.Control()
[<JavaScript>]
override __.Body = Client.main() :> _

Using F#'s built-in async support with *Async() methods

How do I use F#'s built-in support for async operations classes exposing the Event-based Asynchronous Pattern such as WebClient class?
let Download(url : Uri) =
let client = new WebClient()
let html = client.DownloadString(url)
html
When I try to change this to use "let!" in an async block (say as described in Soma's recent post)
let Download(url : Uri) =
async {
let client = new WebClient()
let! html = client.DownloadStringAsync(url)
return html }
I get an error message:
Type constraint mismatch. The type unit is not compatible with type Async<'a> The type 'unit' is not compatible with the type 'Async<'a>'
Edit: I'm really asking about the general question of using *Async() methods, WebClient is just an easy example. Microsoft says "... you should expose asynchronous features using the Event-based Asynchronous Pattern [ as opposed to BeginFoo()/EndFoo() ] whenever possible ..." so I would think there should be an easy way to consume an arbitrary *Async() method from F#.
The WebClient.DownloadStringAsync method is part of the .NET framework. It'll raise an event to signal its progress, and its return type is unit, so you don't want to use it, and there's no advantage in wrapping it in an async object.
The F# PowerPack defines an extension method, val webclient.AsyncDownloadString : uri -> Async{string}:
let Download(url : Uri) =
async {
let client = new WebClient()
client.Encoding <- Encoding.GetEncoding("utf-8")
let! html = client.AsyncDownloadString(url)
return html }
Unfortunately, the choice of name clashes with the existing webclient method, which can understandably cause confusion. However, I believe all of the F# async extensions begin with Async*.
[Edit to add in response to comments:]
Usually, .NET uses the BeginFoo / EndFoo pattern for concurrency. If the types are right, you can just use Async.BuildPrimitive beginMethod endMethod, which will return an Async wrapper for the method.
Sometimes objects don't use this pattern, like the WebClient, and you actually have to use Async.AwaitEvent to wait for an event to be fired, or write your own loop to repeatedly check to see if a bool is set. Here's a nice article on converting events to Async objects.
For what its worth, if you have F# installed, you should also have the source code which will give you an idea of how the F# team implements their async extensions. On my machine, the relevant file is located at:
C:\Program Files\FSharp-1.9.6.16\source\fsppack\FSharp.PowerPack\AsyncOperations.fs

Resources