opened
kytrinyx
username_0
The contents of the SETUP.md file gets included in
the README.md that gets delivered when a user runs the `exercism fetch`
command from their terminal.

At the very minimum, it should contain a link to the relevant
language-specific documentation on
[help.exercism.io](http://help.exercism.io).

It would also be useful to explain in a generic way how to run the tests.
Remember that this file will be included with _all_ the problems, so it gets
confusing if we refer to specific problems or files.

Some languages have very particular needs in terms of the solution: nested
directories, specific files, etc. If this is the case here, then it would be
useful to explain what is expected.

---

Thanks, @tejasbubane for suggesting that we add this documentation everywhere.
See [exercism.io#2198](https://github.com/exercism/exercism.io/issues/2198).
Add helpful information to the SETUP.md
issue
created
Mousaka
username_1
Any progress on this issue? I'm a Linux user and I'm totally lost how to get started.
comment
created
kytrinyx
username_0
@username_1 I don't know that there has been any movement, but this would be a fantastic opportunity to figure out exactly what needs to go into there, if you're willing to help us think this through step by step.

The first thing I'm going to try to do is help narrow down where you're stuck—that might be an Exercism problem in general, or an F# problem specifically.

**Have you ever used Exercism before?** We're working on making Exercism easier to use and understand in general. We actually launched a prototype of a new design yesterday that's been in the works for quite a while. I wouldn't recommend trying the prototype yet if you're new to Exercism, but definitely check out the homepage as it does a great job of explaining what Exercism is: https://v2.exercism.io/

**How new are you to F#?** If you could say a little bit about what type of exposure you've had to F# before, that would help a lot.

And finally, I suppose, **what have you done so far in the process of trying to get started on this track?** (If it feels like the answer to that is "nothing, I have no idea where to begin" that's totally fine, too!)
comment
created
ErikSchierboom
username_2
@username_1 At the moment, we don't have a detailed workflow. But you should be able to follow the instructions on http://fsharp.org/use/linux/

We will be porting the F# track over to .NET Core, which will make the whole track completely cross-platform.
comment
created
Mousaka
username_1
I am quite new to F# but I have read half a book about it and I have had a basic "hello world"-webserver-project working. After not coding for a while and having a new computer I decided to give F# a go again. This time i started out with the quite new "Rider" IDE from jetbrains. I managed to open an old project of the Exercism "Leap" problem - that I totally forgot how I set up - and I submitted a solution successfully. I can probably manage to do this again if I spend some more time but after one evening trying to do it with Rider unsuccessfully and with MonoDevelop AND with Visual Code (briefly) I really felt like giving up.

After another 1½ hour spent today I managed to set up another exercism problem successfully but the setup is far from smooth compared to the other languages I've worked with in exercism.
What I did now is:
1. fetch exercism problem
2. Create new Library project, using Rider, with same name as the exercism test-file but without "test" at the end, e.g "SumOfMultiples", having checked the box "Put solution and project in the same directory" (this matters if you in the end want exercism CLI to find the file you want to submit). _Here I tried for a long time to create a project with the same name as the exercism problem folder "sum-of-multiples" but that results in some kind of namespace problem that I was not able to solve._
3. Move the exercism problem test file "SumOfMultiplesTest.fs" to my newly created project folder. _(Took me a while before I realized  this was an important step, earlier I just tried step 4 right away but then it would seem to work but the test file would not be able to open SumOfMultiples module)_
4. Right click on my project in Rider and clicked "Add existing item..." and selected the exercism test file that I had moved to project folder.
5. Right click on my project again and this time clicked on "Manage Nuget packages" (This took me a surprisingly long time to find for some reason) and search for and install NUnit
6. Remove the exercism problem folder "sum-of-multiples"
7. Close project in Rider
8. Rename my project folder from "SumOfMultiples" to "sum-of-multiples" and put in your exercism fsharp folder if it's not there already.
9. Open project/solution (btw what is the difference in F#?)
10. Code along and complete the problem, run tests etc.
11. Submit solution.

I really don't want to do all these steps for every new problem. I'm sure of course there are a lot smarter ways to this than what I just did but they can probably be difficult for a newbie like me to find. 

I hope this input can be of some help and I'm happy to try any suggested new solutions or help out more in some way.

Cheers
comment
created
kytrinyx
username_0
Ouch, yes! Neither would I.

@username_2 a few questions about this in general:

- Is this the process that you use?
- If not, is your process meaningfully different? Simpler?
- Is the process pretty much the same no matter which editor/IDE one uses?
- How much of this could be scripted?
- Or, alternately—could we provide more boilerplate up front to simplify the process?

You mentioned switching to .NET Core to make the process cross-platform, would that still involve significant setup for each problem?
comment
created
robkeim
username_3
@username_1 welcome to the F# track, and I'm sorry that you've had a rough time getting started :( I appreciate your tenacity and taking the time to share your feedback with us. I agree with @username_0's assessment that this is an F# track issue not a larger, Exercism issue.

IMO, newcomers to a given track should be able to get the Hello World up and running quickly and seamlessly otherwise it's not going to entice people to stay with the track. With the current F# setup, particularly on Linux we have definitely not achieved that goal.

I'd like to breakdown my response into two parts:
1. What (if anything) can we do in the short term to reduce the barrier of entry of the track?
2. What is the long term vision for the track?

### What (if anything) can we do in the short term to reduce the barrier of entry to the track?

For full disclaimer I am working on Windows so things aren't always the same, but when I did the F# track here was my flow:

Onetime setup:
1. Create a FSharpExercisimSolutions fsproj** in a directory separate from the Exercism repo
2. Install the Nunit NuGet package

Exercise per workflow:
1. Fetch problem
2. Copy exercise and test fs files into the directory containing FSharpExercismSolutions
3. Right click on fsproj and add the new files (I believe this step can be eliminated if you modify the fsproj to include all fs files using a wildcard)
4. Code solution and run tests
5. Copy final solution back to the exercism directory
6. Submit solution

@username_1 I would be curious to know if you tried this flow whether it works for you and if there are any Linux only pitfalls I didn't hit since I'm running on Windows.

** @username_1 you asked what the difference between an fsproj and a sln are and they are ways to split up code. A sln is a larger component that can contain multiple fsproj's inside. One common setup for small projects is to have one sln and then one fsproj for the code and one fsproj for the tests. Fsproj's can have dependencies between them. You don't actually need a sln and can work with a bare fsproj, although Visual Studio prefers having a sln.

### What is the long term vision for the track?

Microsoft has historically been a very Windows-centric company and the older implementations of .NET reflect that. You can get them to run on Linux but it requires a lot of manual tweaking and effort. However, recently Microsoft has changed and have started investing in cross platform which includes the .NET core @username_2 referred to. .NET core is something that's been designed from the ground up with non-Windows platforms in mind, they're not just an afterthought.

@username_2 has done an *incredible* job at migrating the C# track to using .NET core including a sample csproj (the fsproj equivalent for C#) for every exercise. That prevents people from having to write the boilerplate code that you do today. The workflow for people in the C# track is:
1. Fetch problem
2. Open csproj
3. Code solution and run tests
4. Submit

We want to get there with the F# track as well, but unfortunately it's not free. @username_2 could give a better estimate on how long it would take to do this, based on his experience doing it with the C# track, but it's something measured in days or weeks not minutes or hours is my guess.

@username_0 asked if .NET core would take a lot of work to setup each problem and the answer is no. After the initial investment to get .NET core setup, creating a new problem is not a lot of work. I just added a new exercise in the C# track which you can see here:
https://github.com/exercism/csharp/pull/378

The boilerplate code is the csproj which was a copy/paste from another exercise just renaming the file.
comment
created
rmunn
username_4
Here's the process I use on Linux:

1. I have a private BitBucket repo containing my code, checked out to `~/exercism/fsharp/`.
1. I have a two-line bash script called `doit.sh` in that folder, which looks like this:
    ```bash
    #!/bin/bash
    xbuild exercise.fsproj
    nunit-console bin/Exercise.dll
    ```
1. I have a `paket.dependencies` file in `~/exercism/fsharp` that looks like this:
    ```text
    source https://www.nuget.org/api/v2
    nuget FSharp.Core
    nuget NUnit
    nuget NUnit.Runners
    ```
1. I have an `exercise.fsproj` file that looks like this:
    ```xml
    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <ProductVersion>8.0.30703</ProductVersion>
        <SchemaVersion>2.0</SchemaVersion>
        <ProjectGuid>{116CC2F9-F987-4B3D-915A-34CAC04A73DA}</ProjectGuid>
        <OutputType>Library</OutputType>
        <RootNamespace>Exercise</RootNamespace>
        <AssemblyName>Exercise</AssemblyName>
        <Name>Exercise</Name>
        <TargetFSharpCoreVersion>4.4.1.0</TargetFSharpCoreVersion>
        <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
        <MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
        <OutputPath>bin</OutputPath>
        <PlatformTarget>x86</PlatformTarget>
    </PropertyGroup>
    <ItemGroup>
        <Reference Include="mscorlib" />
        <Reference Include="System" />
        <Reference Include="System.Core" />
        <Reference Include="FSharp.Core" />
        <Reference Include="nunit.framework">
        <HintPath>..\packages\NUnit.Runners\tools\nunit.framework.dll</HintPath>
        </Reference>
    </ItemGroup>
    <ItemGroup>
        <Compile Include="HelloWorld.fs" />
        <Compile Include="HelloWorldTest.fs" />
    </ItemGroup>
    <Choose>
        <When Condition="'$(VisualStudioVersion)' == '14.0'">
        <PropertyGroup>
            <FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
        </PropertyGroup>
        </When>
        <Otherwise>
        <PropertyGroup>
            <FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
        </PropertyGroup>
        </Otherwise>
    </Choose>
    <Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />
    </Project>
    ```

The first step in making this all work is to download Paket and run `paket install` from the main `~/exercism/fsproj` folder, so that I get the `packages/NUnit.Runners/tools/nunit.framework.dll` file that the `.fsproj` refers to. Then my process goes like this for each new exercise:

1. `cd ~/exercism/fsharp`
1. `exercism fetch fsharp`
1. Figure out which exercise was downloaded. For this example, let's say it was the "Dominoes" exercise.
1. `cd dominoes`
1. `cp ../hello-world/exercise.fsproj .`
1. Edit the local copy of the `exercise.fsproj` file and search-and-replace, changing `HelloWorld` to `Dominoes`. Since I use VS Code, I find it simplest to double-click on the text `HelloWorld`, hit Ctrl+D until all occurrences of that text have been selected, and then type the word `Dominoes` once, so it's edited everywhere.
1. In some cases, I have to add or remove one character in the name of the unit-tests file. (Some exercises have `FooTest.fs`, and some have `FooTests.fs`.) Not a big deal, just something to watch for.
1. Now I open `DominoesTest.fs` and `README.md`, and create `Dominoes.fs`, and start working on the exercise.
1. When I think I've got it, I go to the command line and run `../doit.sh`. Then if there are any compilation errors or failed unit tests, I fix the problem. If it compiled and ran fine, I run `exercism submit Dominoes.fs` and move on to the next exercise. (And I probably check my solution into Git and push it up to Bitbucket, so that I can work on the next exercise on a different computer if I need to).
comment
created
ErikSchierboom
username_2
There is indeed a bit of a learning curve, as well as some manual stuff you have to do at the moment. However, as @username_3 said, we are planning to move to .NET Core which will alleviate most if not all problems. The problem for a long time was: F# support on .NET Core was not in .NET Core 1.0, but with the recently released .NET Core 2.0, we can finally work on adding this integration. It is on the top of the list of the F# track's issues.
comment
created
ErikSchierboom
username_2
FYI: I've started working on this
comment
created
kytrinyx
username_0
@username_2 if you're able to describe it in a way where people could pick off specific pieces I could write about it in the next newsletter and tweet about it and maybe we could get people to help pitch in.
comment
created
ErikSchierboom
username_2
@username_0 Well, it's a bit hard as there is a fixed order and most of it is bulk updates. But I'll think about it! Thanks for the offer.
comment
created
rebelwarrior
username_5
This may be a weird question but why do we need NET.core at all? Isn't F# in mono as well? 
Is the testing Lib tied to net.core?

- David 

Sent from my mobile. 

>
comment
created
ErikSchierboom
username_2
Well, it is not .NET Core per se, I have not phrased it correctly. What we are doing is moving to .NET Standard 2.0, of which .NET Core 2.0 is one of the runtimes. The benefit of moving to .NET Standard 2.0 are many:

- The F# track then runs on the full .NET Framework, Mono and any machine that can run .NET Core 2.0
- We can use the updated .fsproj file format, which is much cleaner and easier to edit
- We can write instructions for the track using the .NET CLI, which runs on all .NET Core platforms so we only have to write the documentation for one use case

I hope I have explained things better. Mono will thus still be a completely viable runtime to use for the F# track.
comment
created
Mousaka
username_1
NOTE: My nunit.framework.dll did not have the same path as yours, mine was `..\packages\NUnit\lib\net45\nunit.framework.dll`

Then when fetching a new problem I can use my script -> https://gist.github.com/username_1/f3b4127d93b73279515d1343d693df3a and a required template fsproj file (mostly copied from the one @username_4 posted but I did some fiddeling with it) -> https://gist.github.com/username_1/c5d03a02faa2428eafe36db28bb60be4
```
 ./helpInit sum-of-multiples
```
and it will fetch the F# problem from exercism and setup the problem directive to be a fsproject
```
exercism/fsharp
├── helpInit
├── paket.dependencies
├── paket.exe
├── paket.lock
├── sum-of-multiples    <-- Script generates this folder and all it's content as seen here
│   ├── build.sh
│   ├── README.md
│   ├── SumOfMultiples.fs
│   ├── SumOfMultiples.fsproj
│   └── SumOfMultiplesTest.fs
└── template.fsproj
```
The build.sh file is the equivalent of @username_4 `doIt.sh` but I used msbuild instead of xbuild because warnings said xbuild is deprecated and I that I should. I also had to install and use nunit3-console.exe (which I after installing renamed to nunit3-console) instead of nunit-console which where throwing exceptions because of some incompatible versions of NUnit or something... Another pitfall was installing paket which seems to have some issues with the official Linux tutorial -> https://github.com/fsprojects/Paket/issues/2579
Came around that by just just downloading the latest paket.exe from github and used `mono paket.exe install` to install it.

This hacky solution took a while to make but after initial setup I can use this workflow for every new problem:
1. (being in exercism/fsharp) `./helpInit sum-of-multiples`
2. code my solution in file SumOfMultiples.fs (in any text editor / IDE)
3. run the build script that builds project and runs test
4. User `exercism submit fsharp sum-of-multiples/SumOfMultiples.fs` when finished.

## Thougts
My experience with F# on linux so far is that following different setups and tutorials are often not that straight forward at this point in time. There are many pitfalls and many inconsistencies. Depending on when you try to install the tooling by following instructions versions may have changed and the only possible way of installing something might not be what the "Getting started" page says anymore. 

Though I've learned a lot struggling the past days and I'm now able to start with my exercism problems it *REALLY* glads me to hear that @username_2, and hopefully others too, are working on creating a better future for F# and surrounding tooling in the land of Linux =) thank you
comment
created
petertseng
username_6
In case it can be helpful, I share what I did to work on the F# track. Here is the Vagrantfile I used:

```ruby
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure('2') do |config|
  config.vm.box = 'ubuntu/xenial64'
  # Hey why not put C# on too, since we have Mono ready to go...
  config.vm.synced_folder '../csharp', '/vagrant_csharp'
  config.vm.provision 'shell', inline: <<-SHELL
    ln -s /vagrant /home/ubuntu/fsharp
    ln -s /vagrant_csharp /home/ubuntu/csharp
    apt-get update
    apt-get install -y mono-devel fsharp nunit-console
  SHELL
end
```

Here is the `test.sh` I use.

```bash
#!/bin/sh

set -e

if [ $# -eq 0 ]; then
  srcfile=$(ls -1 *.fs | grep -v Test)
  if [ -z "$srcfile" ]; then
    echo "found no .fs files, run in a directory with one, or specify one."
    echo "usage: $0 [srcfile [testfile]]"
    exit 1
  fi
fi

if [ $# -lt 2 ]; then
  testfile=*Test.fs
  testdll="$(echo $testfile | cut -d. -f1).dll"
else
  testfile=$2
  testdll="$(echo "$testfile" | cut -d. -f1).dll"
fi

srcdll="$(echo "$srcfile" | cut -d. -f1).dll"
nunit=/usr/lib/cli/nunit.framework-2.6.3/nunit.framework.dll

fsharpc -a $srcfile
fsharpc -a -r:$nunit -r $srcdll $testfile
nunit-console --noxml $testdll
rm $srcdll $testdll
```

Given that my Exercism directory is ~/exercism:

* I place the Vagrantfile at `~/exercism/fsharp/Vagrantfile` and the `test.sh` at `~/exercism/fsharp/test.sh`
* I run `vagrant up` in `~/exercism/fsharp` (you can feel free to remove the two `csharp` lines from the Vagrantfile if you don't want them).
* I fetch the exercises (using the host machine, so that I don't need to install `exercism` on the Vagrant machine)
* I `vagrant ssh` onto the Vagrant machine and it's configured so that `~/exercism/fsharp/leap` on the host machine becomes `~/fsharp/leap` on the Vagrant machine.
* I run `test.sh` on the Vagrant machine; the test should run and fail.
* I complete the exercise using a text editor on the host machine (didn't want to install+configure a text editor on the Vagrant machine), meanwhile running `test.sh` on the Vagrant machine every so often to check my progress
* submit when done (again, on the host machine).
comment
created
petertseng
username_6
in case that makes it sound like the instructions are out of date, don't worry, I just tested them while writing this and they still work
comment
created
ErikSchierboom
username_2
@username_1 If you're interested, you can follow progress on this issue on my branch: https://github.com/username_2/fsharp/tree/dotnet-core
comment
created
Mousaka
username_1
@username_6 I like how you use vagrant to make the installation setup more consistent. If someone would try my setup it's likely they're gonna run in to trouble. But in some way isn't it kind of a weird setup to have to run tests in a VM but code on host? I guess maybe it's kind of like having a build server you push changes to except that it's the only way to run tests.
comment
created
petertseng
username_6
I guess I don't notice the difference because it's all in a terminal no matter whether it's on the host machine or the VM. It is possible I accidentally try to start up my text editor in the VM or test.sh on the host machine, but rare.
comment
closed
ErikSchierboom
username_2
issue
created
ErikSchierboom
username_2
@username_1 With #348 merged, the F# track should be a lot easier to get started with. It is all based on .NET Core now, so you are able to work on the track from a wide variety of platforms using either an IDE or the command-line interface.
comment
created
Mousaka
username_1
@username_2 Great job! I will try it out. I saw the PR you merged.. it looked like a lot of work.. so.. Really awesome that you did all that for all the F#-curious people out there!! thank you so much :confetti_ball: :+1:
comment
created
Mousaka
username_1
Really easy to fetch problems and get going now!! Love it. You only have to type three commands to run tests now
```
exercism fetch fsharp
cd problem-folder
dotnet test
``` 
replace last command with something like `<your_favourite_IDE> .` to open the project in your IDE
comment
created
ErikSchierboom
username_2
@username_1 Thanks for testing! Great to hear it works :)
comment