I've recently been trying to learn the Object-Oriented aspects of F#, and have become curious about how to restrict access to types/modules in the language.
More specifically, I want to know the difference between writing this:
Example.fsi
module Stack =
val foo : string
Example.fs
module Stack =
let foo = "foo"
let bar = "bar"
and alternatively this:
module Stack =
let foo = "foo"
let private bar = "bar"
Do they not accomplish exactly the same thing in the end? Coming from a C# background, I'm much inclined just to use the access modifiers over signature (FSI) files. They seem to be more versatile (can apply to modules/types in namespaces, for example), whereas I don't any situation in which signature files offer something that access modifiers don't.
They accomplish almost the same thing. (Note that you can use an .fsi file for types in namespaces too, was unsure what your comment about that meant.)
A signature file has a couple advantages:
You can make entities public for the duration of the file, but then private to the subsequent files of the project.
You can have just your short summary in the signature file, so the public interface is easy to read without having to scan tons of code.
The first bullet is not to be trifled with - within-assembly encapsulation like this is actually a pretty huge feature for very large projects. Being able to define a few types which are public to one another within File1.fs, but then only have a subset of those types/methods be public to the rest (File2.fs, File3.fs, etc.) is quite useful (a little bit like 'friend' in C++).
Related
I am writing a static library in Swift that will be reused in multiple projects. The problem is class and struct names I am using are common and can easily conflict with other libraries/frameworks. I don't see any obvious way to create my own namespace in Swift. What's the best way to avoid name collision between classes in multiple libraries/frameworks?
You don't to have to avoid. Just use the name you like. Then when you want to access to your class/struct/protocol..., just use your module name as a namespace.
Example:
import MyModule
let a: MyModule.Result // the Result type defined inside the `MyModule`
let b: Result // Swift's Result type
As others have said, if there is a conflict, you can always fully qualify the symbol name with the module name (See Cong's answer.)
Apple's suggested way to handle this in the days of Objective-C was to use your intials or your company's initials as a prefix for your symbol names. I'm not a big fan of that since it creates ugly names that obscure the underlying meaning.
Using an abbreviated version of the module name/framework name is a little better, and what Apple tends to do, e.g. UIKit views are UIViews, and AFNetworking's connection object might be an AFNConnection.
Others are arguing strongly in the comments that this is no longer needed and no longer recommended. (Like I said, I've never liked it anyway.)
I am trying to wrap my head around how to handle DI in F# when using WebApi with something like Ninject.
For example, in C# when i wire up my container I would simply tell the DI what the type resolves to, for example:
kernel.Bind<ISomeInterface>().To<SomeClass>();
My Api Controllers will automatically wire this when required by the controllers constructor.
Great, now I can add methods to the interface & class all day long w/o touching the container again.
However in F# (unless i am doing this completely wrong) I create partial applications and then pass them to the controller, every time I add a method i have to wire up again at the container. Maybe this is correct, I am not sure but it seems like a lot more wiring.
To clarify what I mean, lets take a typical REST Api. For each entity with CRUD - so for example:
Customer (Create, Read, Update, Delete).
Would I then have to inject each function into the controller?
So in this example, lets say that i have the service -> domain -> repo model:
let createCustomerFunc = createCustomerDomainFunc createCustomerRepoFunc
let getAllCustomersFunc = getAllCustomerDomainFunc getAllCustomerRepoFunc
let updateCustomerFunc cust = [...]
let deleteCustomerFunc id = [...]
let getSingleCustomerFunc id = [...]
Now in my container when i bind it, i would then do something like:
kernel.Bind<CustomerController>().To<CustomerController>()
.WithConstructorArgument(createCustomerFunc, getAllCustomerFunc, etc...)
|> ignore
Now if i add method: GetActiveCustomers I would then have to modify my code above to pass in the new partial application?
That feels ... wrong - am i simply approaching this incorrectly?
Using a DI Container provides some advantages, as well as some disadvantages.
The major advantage is that, if you have a large code base, you can use convention over configuration to wire up all the dependencies. With convention over configuration, you also get the benefit that your code will have to be more consistent, because it has to follow conventions.
There are several disadvantages, though. The most immediate is that you lose the rapid feedback from the compiler. You can much easier make a change to your system, and while everything compiles, the system fails at run-time. Some people hope that you can ask a DI Container to self-diagnose, but you can't.
Another, less apparent, disadvantage of using a DI Container is that it becomes too easy, as you say, to simply add more members to Controllers, etc. This actually increases coupling, or reduces cohesion, but the Reflection-based automation provided by DI Containers hides this problem from you.
Since I believe that the disadvantages outweigh the advantages, I recommend that you use Pure DI instead of DI Containers.
This goes for Object-Oriented Programming in C#, Visual Basic .NET, or Java, but applies equally to Functional Programming in F#.
In an unmixed Functional F# code base, I wouldn't use classes or interfaces at all; instead, I'd only compose functions together.
In a mixed code base with e.g. ASP.NET Web API, I'd cross the bridge between OOP and FP as quickly as possible. As I explain in my Test-Driven Development with F# talk (expanded material available on Pluralsight), I'd inject a function into a Controller like this:
type ReservationsController(imp) =
inherit ApiController()
member this.Post(rendition : ReservationRendition) : IHttpActionResult =
match imp rendition with
| Failure(ValidationError msg) -> this.BadRequest msg :> _
| Failure CapacityExceeded -> this.StatusCode HttpStatusCode.Forbidden :> _
| Success () -> this.Ok () :> _
That's the entire code base of that Controller. All behaviour is implemented by imp.
In the startup code of the application, imp is composed like this:
let imp =
Validate.reservationValid
>> Rop.bind (Capacity.check 10 SqlGateway.getReservedSeats)
>> Rop.map SqlGateway.saveReservation
You may argue that the above ReservationsController only defines a single Post method. What if a Controller has to expose more methods?
In that case, inject an implementation function per method. In a REST API, any Controller only ought to have 2-3 methods anyway, so that means, in effect, 2-3 dependencies. In my opinion, that's a perfectly acceptable number of dependencies.
The reason for the 2-3 method maximum is that in proper RESTful design, resources tend to follow a few interaction patterns:
GET
POST
POST, GET
PUT, GET
DELETE, GET
PUT, DELETE, GET
The full combination (POST, GET, PUT, DELETE) is a REST design smell, but all of that is an entirely different discussion.
Fundamentally, you are using functional code style in a object oriented framework. Since WebAPI required you to instantiate a controller, you have to bridge the OO to functional approach somehow.
Setting function values in a DI container is a rather awkward approach, since you have to manually bind to the constructor arguments. I would recommend an adapter pattern based approach, that is create a class to wrap the (static) function calls.
pub type CustomerFunctionAdapter() =
member x.CreateCustomer = createCustomerFunc
member x.GetAllCustomers = getAllCustomersFunc
// ...
and still bind with
kernel.Bind<ISomeInterface>().To<CustomerFunctionAdapter>();
This way, your changes and additions are in CustomerFunctionAdapter, rather that in your DI bindings.
Instead of importing a whole module, is there a way to open specific functions in another module? Something like:
open TestFuncs with [myTestFuncInOtherModule]
As you can see in the docs, the open keyword doesn't actually load a module or namespace. It just allows you to refer to elements in that module/namespace without refering to their fully qualified name.
Being so, when you use open you're just making it easier to call the functions in that module, not actually importing/loading them in memory, so the short answer for this question is that using the open keyword you can't do this to only one function.
You can achieve the same thing easily with a let binding, though:
let f = TestFuncs.myTestFuncInOtherModule
It's not currently possible, but I've actually put in a request for this to be added to the language. If you want to see this added in F# 4.0, one thing you could do is go vote for that request.
Another good workaround, that hasn't been mentioned yet by other answers, is to "pseudo-open" modules: assign a short name to modules whose contents you want to use. Like so:
module TP = Microsoft.FSharp.Data.TypeProviders
type mySchema = TP.SqlDataConnection<"...">
let db = mySchema.GetDataContext()
This gives you the convenience of not having to type the whole module name every time you want to reference its contents, but you maintain control of your namespace: this way there's no chance of accidental name collisions when you update a module to a new version and it adds new names.
You can refer to particular functions in another module using full function name ModuleName.funcName:
module One =
let square x = x * x
module Two =
let anothersquare x = One.square x
What is the proper functional way to handle pluggability in projects? I am working on a new opensource project in F# and can not seem to get the object oriented idea of plugins and interfaces out of my mind. Things I would like to be able to swap out are loggers, datastoring, and authentication.
I have been searching quite a bit for an answer to this and havent come up with much except for this:
http://flyingfrogblog.blogspot.com/2010/12/extensibility-in-functional-programming.html
The answer to this question would be different for different functional languages. F# is not purely functional - it takes the best from functional, imperative and also object-oriented worlds.
For things like logging and authentication, the most pragmatic approach would be to use interfaces (in F#, it is perfectly fine to use interfaces, but people do not generally use inheritance and prefer composition instead).
A simple interface makes sense when you have multiple different functions that you can invoke:
type IAuthentication =
abstract Authenticate : string * string -> bool
abstract ResetPassword : string * string -> void
You can use object expressions, which is a really nice way to implement interfaces in F#.
If you have just a single function (like logging a message), then you can parameterize your code by a function (which is like an interface with just a single method):
type Logger = string -> unit
For things like authentication and logging (that probably do not change while the application is running), you can use a global mutable value. Although if you want to synchronize requests from multiple threads and there is some mutable state, it might be a good idea to write an F# agent.
For recursion in F#, existing documentation is clear about how to do it in the special case where it's just one function calling itself, or a group of physically adjacent functions calling each other.
But in the general case where a group of functions in different modules need to call each other, how do you do it?
I don't think there is a way to achieve this in F#. It is usually possible to structure the application in a way that doesn't require this, so perhaps if you described your scenario, you may get some useful comments.
Anyway, there are various ways to workaround the issue - you can declare a record or an interface to hold the functions that you need to export from the module. Interfaces allow you to export polymorphic functions too, so they are probably a better choice:
// Before the declaration of modules
type Module1Funcs =
abstract Foo : int -> int
type Module2Funcs =
abstract Bar : int -> int
The modules can then export a value that implements one of the interfaces and functions that require the other module can take it as an argument (or you can store it in a mutable value).
module Module1 =
// Import functions from Module2 (needs to be initialized before using!)
let mutable module2 = Unchecked.defaultof<Module2Funcs>
// Sample function that references Module2
let foo a = module2.Bar(a)
// Export functions of the module
let impl =
{ new Module1Funcs with
member x.Foo(a) = foo a }
// Somewhere in the main function
Module1.module2 <- Module2.impl
Module2.module1 <- Module1.impl
The initializationcould be also done automatically using Reflection, but that's a bit ugly, however if you really need it frequently, I could imagine developing some reusable library for this.
In many cases, this feels a bit ugly and restructuring the application to avoid recursive references is a better approach (in fact, I find recursive references between classes in object-oriented programming often quite confusing). However, if you really need something like this, then exporting functions using interfaces/records is probably the only option.
This is not supported. One evidence is that, in visual stuido, you need to order the project files correctly for F#.
It would be really rare to recursively call two functions in two different modules.
If this case does happen, you'd better factor the common part of the two functions out.
I don't think that there's any way for functions in different modules to directly refer to functions in other modules. Is there a reason that functions whose behavior is so tightly intertwined need to be in separate modules?
If you need to keep them separated, one possible workaround is to make your functions higher order so that they take a parameter representing the recursive call, so that you can manually "tie the knot" later.
If you were talking about C#, and methods in two different assemblies needed to mutually recursively call each other, I'd pull out the type signatures they both needed to know into a third, shared, assembly. I don't know however how well those concepts map to F#.
Definetely solution here would use module signatures. A signature file contains information about the public signatures of a set of F# program elements, such as types, namespaces, and modules.
For each F# code file, you can have a signature file, which is a file that has the same name as the code file but with the extension .fsi instead of .fs.