I have an application, call it App1. It is mostly C#. I'm writing a dll in F#. It cointains a class, Class1. I want this class to belong to the App1 namespace.
If I add namespace App1 on the top of my .fs file, it complains that a namespace cannot contain values (I have some lets in my file).
If I add "module App1" under the namespace, it compiles, but I cannot access the namespace from outside. Any help?
Thanks
It's simplest to separate out the class code from the freestanding functions -- I'd do something like
#light
namespace App1
open ModuleWithFunctionsIn
type Class1 = class
(* stuff goes here *)
end
and pull the free-standing functions in from a separate module
I do not remember exact answer, but what I did is inspecting F# assemblies with .NET Reflector. Often this answers all questions like this.
Related
I'm doing some restructuring of a project of mine, and decided to make a separate library project for a big part of it.
My problem lays in that I have multiple files with modules where many of them should be hidden from user API, how do I achieve this? I have not tried this before so are unfamiliar to how the library structure are different from commandline projects, and how to scope things correctly. If I can see every file in the lib project from
other project why do we have the Library.fs file?
To formalize a little. Say that I have SomeCode.fs and Library.fs
SomeCode.fs
module SomeCode
type SomeType = ...
let someFunc1 ... = ...
// things to hide here
// depend on hidden code
let SomeFunc2 ... = ...
Library.fs
namespace SomeLib
module Mod1 = ...
This is intended to target other F# project. How to structure this so the API would only see the right things, and still be maintainable?
internal is your friend here. If you declare a module
module internal MyNamSpace.MySecretModule
this is only accessible from within your project.
The module Library you keep public, and this is your API.
internal can also be used on individual functions, in case you want to hide just some functions.
A fairly common way of hiding part of a module is also to employ the following pattern
module MyModule =
[<AutoOpen>]
module internal MySecretModule =
let apa = 1
// Bunch of other internal stuff
// Can use stuff from MySecretModule, but other projects cannot
let bepa = apa + 1
In F#, can I omit the class name when calling a static method?
Example:
In C#, I can do something like:
using static Bizmonger.Patterns.MessageBus;
...
Publish("SOME_MESSAGE");
instead of:
MessageBus.Publish("SOME_MESSAGE");
Can I do something like this in F#?
In F#, you can use open on namespaces (just like using in C#) or on modules (which is useful when the API you are calling has been written in F#), but not on static classes (which is what you'd need when calling C# libraries).
One thing that you can do though to make the code a bit shorter is to define a type alias:
type M = Bizmonger.Patterns.MessageBus;
// Now you can write just
M.Publish("SOME_MESSAGE")
// Rather than writing the full
MessageBus.Publish("SOME_MESSAGE");
There is a feature request on the F# UserVoice to allow using open on static classes (just like in C#) and so if you'd like this to happen, please upvote and comment there.
I also learned that I could implement a function to serve as a wrapper for clients to call instead.
Create a wrapper function
module Messages
open Bizmonger.Patterns
let Publish (message:string, payload:_) =
MessageBus.Publish(message, payload)
Client
Then a client can now invoke a function without specifying a class name.
open Messages
...
Publish("SOME_MESSAGE", null);
Say I defined a private function in a dart file hello.dart:
_hello() {
return "world";
}
I want to test it in another file mytest.dart:
library mytest;
import 'dart:unittest/unittest.dart';
main() {
test('test private functions', () {
expect(_hello(), equals("world"));
}
}
But unfortunately, the test code can't be compiled. But I do need to test that private _hello function. Is there any solution?
While I agree that private methods/classes shouldn't be part of your tests, the meta package does provide an #visibleForTesting attribute, and the analyzer will give you a warning if you attempt to use the member outside of its original library or a test. You can use it like this:
import 'package:meta/meta.dart';
#visibleForTesting
String hello() {
return "world";
}
Your tests will now be able to use it without error or warning, but if someone else tries to use it they'll get a warning.
Again, as to the wisdom of doing this is another question - usually if it's something worth testing, it's something that's worth being public (or it'll get tested through your public interfaces and that's what really matters anyway). At the same time, you might just want to have rigorous tests or test driven principles even for your private methods/classes so - Dart lets you this way.
Edit to add: If you're developing a library and your file with #visibleForTesting will be exported, you are essentially adding public API. Someone can consume that with the analyzer turned off (or just ignore the warning), and if you remove it later you may break them.
Several people believe we shouldn't test private directly: it should be tested through the public interface.
An advantage of following this guidance, is that your test won't depend on your implementation. Said differently: if you want to change your private without changing what you expose to the world, then you won't have to touch your tests.
According to this school of though, if your private is important enough to justify a unit test, then it might make sense to extract it in a new class.
Putting all this together, what you could do here, is:
Create a kind of helper class with this hello method as public. You can then easily unit test it
Let your current class use an instance of this helper class
Test the public methods of your current class which relies on _hello: if this private has a bug, it should be catch by those higher level tests
I don't like either of the above answers. dart's private variable test design is very bad. dart's private visibility is based on library, and each .dart file is a library by default, similar language is rust, but rust can write test code directly in the file, there is no private visibility problem, while dart does not allow this.
Again, I don't think #visibleForTesting is a valid solution,
Because #visibleForTesting can only be used to decorate public declarations, it serves as a mere analysis reminder that developers cannot invoke these declarations in other files,
But from a syntax point of view, developers can't use the _ prefix either, so the form, public, private, becomes confusing. and violates dart's own naming rules.
The argument that one should not test private, or that they should be separated into other classes, is like a justification that is completely unacceptable.
First, private exist because they belong to a business logic/model etc. in a contextual relationship, and it does not make logical sense to separate it into another class.
Second, if you must do this, it will greatly increase the complexity of the code, for example, you move to other classes will lose access to the context variables, or you have to pass a separate reference, or have to create an instance of the class, indeed, then you can finally do some mocks, but you also add a layer of abstraction,
It's hard to imagine that if you were to do this for the whole project, you'd probably double your entire code layers.
For now, If you want your dart package to get more than 90% coverage,
you should not define any private.
It sounds harsh, but that's the real story.
[Alternative] No one seems to have mentioned this yet,
Using part / part of to expose the privates, you can define a test-specific .dart file as the public interface to the library(file) to be tested, and use it to expose all the private declarations that need to be tested. you can name them xxx.fortest.dart
But this is more of a psychological solution, since you are still essentially exposing all private variables/methods
But at least, it's better than splitting class,
Also, if one day dart finally solves this problem, we can simply delete these .fortest.dart files.
A suggestion would be to NOT make methods/classes private but to move code, where you want to hide implementation details, to the lib/src folder.
This folder is considered private.
I found this approach on the fuchsia.dev page in this section under "Testing".
If you want to expose those private methods/classes, that are located in the src folder, to the public, you could export them inside your lib/main file.
I tried to import one of my libraries A (projects are libraries) into another library B and couldn't import code that was in the src folder of library A.
According to this StackOverflow answer it could still be possible to access the src folder from A in library B.
From the dart documentation
As you might expect, the library code lives under the lib directory and is public to other packages. You can create any hierarchy under lib, as needed. By convention, implementation code is placed under lib/src. Code under lib/src is considered private; other packages should never need to import src/.... To make APIs under lib/src public, you can export lib/src files from a file that’s directly under lib.
I have a name clashing problem while opening some .Net assemblies in my F# code using
open System.IO
The only option I found and use now is to provide the full names of types for conflicting types, but this is a little bit boring.
Is there any possibility to define an alias for .Net namespace in F# to prevent name clashing?
F# does not support aliasing of namespaces - only modules and types. So, to resolve the conflicts between .NET assemblies, you will, unfortunatelly, need to define aliases for all the types you're using.
This may be slightly easier thanks to the fact that F# type aliases are viewed as normal type declarations (by the F# compiler, not by the runtime). This means that, unlike with C# using keyword, you can define them in a spearate file:
// Aliases.fs
namespace SysIO
// Open the 'System' namespace to get a bit shorter syntax
// ('type File = File' is interpreted as discriminated union)
open System
type File = IO.File
type Directory = IO.Directory
In the rest of your application, you can now use SysIO.File. You still have to write the aliases, but at least you don't have to do that in every file...
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I'm starting to code in F# and am calling functions from functions with functions as parameters - there are plenty of learning resources online. Now I am trying to put together the pieces into something more than just a collection of functions. Unfortunately I'm not finding many resources dealing with structure, design, or even how the 'bits' tie together.
I've found the namespace keyword (e.g. namespace MyOnlyNamespace) but I get a compiler error on the functions that I've placed inside the namespace:
Namespaces cannot contain values. Consider using a module to hold your value declarations.
When I add module CoolFunctions I get
Unexpected start of structured construct in definition. Expected '=' or other token
So I have a multi-part question (but please answer any part that you can)
What is a module?
Is it like a class (something like a VB.NET module) or is it something else altogether?
If something else, then are there classes in F#?
Are there other structures that I should be using instead?
How do I declare a module?
To give some specific recommendations about choosing between namespaces, modules abd classes in F#:
If you're writing functions using let that are expected to be used from F#, then putting them inside a module is the best choice. This gives you API similar to List.map and other basic F# functions.
Regarding naming, you should use camelCase unless you expect C# users to call the functions too. In that case, you should use PascalCase (and note that module will be compiled to a static class).
If you're writing type delcarations, then these should generally be placed in a namespace. They are allowed inside modules too, but then they'll be compiled as nested classes.
If you're writing F# classes, then they should be placed in namespaces too. In generall, if you're writing F# code that will be called by C#, then using classes is the best mechanism as you get full control of what the user will see (F# class is compiled to just a class).
If you have a file, it can either start with namespace Foo.Bar or module Foo.Bar, which places all code in the file inside a namespace or a module. You can always nest more modules inside this top-level declaration. A common pattern is to start with a single namespace and then include some type and module declarations in the file:
namespace MyLibrary
type SomeType =
// ...
module SomeFuncs =
let operation (st:SomeType) = // ...
concerning the design of F# components there is a very good draft online.
JPalmer allready pointed you to the syntay problems but I think some other questions deserve more:
What is a module?
Yes JPalmer is right - modules are compiled into static classes but do we really care inside F#?
IMHO you should use more modules than classes when programming in F#.
In OOP you define your classes and the methods within.
In FP you define simple types (without behaviour) and a bunch of functions to transform them. And the natural place to collect those functions is the module.
Is it like a class (something like a VB.NET module) or is it
something else altogether?
A VB module is indeed a good comparision.
If something else, then are there classes in F#?
Yes you can use classes in F# - it's a complete .net languague and .net is OOP. You can do practically everything in F# you could do in C# of VB.net (only certain cases generic constraints can be a pain)
Are there other structures that I should be using instead?
No - collect your functions into modules but of course use records and abstract data-types for your data.
How do I declare a module?
Have a look at the online docs: Modules (F#) - there you will find everything you need.
What is a module:
A module is compiled down to a static class. But I think of modules as being analogous to namespaces in C#
there are classes in F# - use
type SomeType(constructor,args) =
....
If you have
namespace Name
module Mod
....
this won't compile - as you know, you can use a few alternatives
module Namespace.Module
as the first line in the file
or
namespace Name
module Mod =
....