How to identify redefined variables or shadowed variables - f#

When using the same variable twice in the same scope with the F# compiler there is no warning or feedback. e.g.
let s = "abc"
let s = "def"
printfn "%A" s
results in
def
I have seen
Is there a way to have warnings for shadowing values in F# in Visual Studio?
F# value shadowing - is it possible to disable value shadowing within the same scope
Is there a way to get feedback about shadowed variables either by a compiler warning or visually in the editor. How can this be done?

First off, shadowing of variables in the same scope is not a bug or something that should be disabled. As Joel Mueller states it is legitimate, useful, and common.
Per MSDN
At any level of scope other than module scope, it is not an error to
reuse a value or function name. If you reuse a name, the name declared
later shadows the name declared earlier.
The Syntax Coloring feature of the Visual Studio extension F# Power Tools will highlight the current valid variable and show the shadowed variables as a light grey. e.g.
The extension can be installed from Visual Studio menu
Tools -> Extensions and Updates
Once the dialog opens
Select Visual Studio Gallery
In the upper right search box enter F# Power Tools
Since I have already installed it, the option to install is not shown.
The feature can be activated from the Visual Studio menu
Tools -> Options -> F# Power Tools -> General -> Syntax Coloring -> Grey out unused declarations
With option off:
with option on:
Note: After changing the option the source file(s) must be closed and then reopened for the change to take effect. Visual Studio does not need to be restarted for this but doing so will have the same effect.
Thanks to Ringil for noting my earlier invalid statement.
Note from source code:
Graying out unused declarations
Currently unused non public types, methods, functions and values declarations are checked. Beware that this
feature is only 100% reliable when the code has no type error. This
setting is available in General options. It is disabled by default
because there might be performance issues on large files.
F# Power Tools features list

Related

Microsoft Visual Studio extension (VSIX) lower case $safeprojectname$

Context
I'm developing a Microsoft Visual Studio extension, for which I've seen there are:
$projectname$ variable to get the name given to the project,
$safeprojectname$ variable to get the name given to the project with all unsafe characters and spaces replaced by underscore.
Source: https://learn.microsoft.com/en-us/visualstudio/ide/template-parameters?view=vs-2019
For example with project name "Tata yoyo" variables will be:
$projectname$ = "Tata Yoyo SWIG",
$safeprojectname$ = "Tata_Yoyo_SWIG".
The extension I'm building is for SWIG projects that will generate Java from C++, and in this context there is a swig.exe call that, among others, takes the Java package as parameter, for which I want it to be all lower case, but for now it is com.company.$safeprojectname$, then, not necessarily lower case (pointing the obvious: if project name is not lower case, package will not be lower case) and I then have to convert it manually to lower case.
What I'm looking for
From source page above (and other documentation pages) I've already seen there is no $lowercasesafeprojectname$ for example, then if anybody knows a way to do it from a function, script or any other way I would be glad.
Edit: while I want for this purpose a lower case safe project name I still want to keep the original $safeprojectname$, then even if #Ed Dore answer is relevant it is not the solution for me.
In any case, do not hesitate if this is not clear or you want more information.
Thanks
If you implement a custom wizard (IWizard) with your template, you can replace the respective token values in the ReplacementsDictionary passed to your IWizard.RunStarted method, with lowercased equivalents.
Sincerely,

F# value shadowing - is it possible to disable value shadowing within the same scope

I spoted a bug in my own code because of copy/paste. The same value name is shadowned by the copy/pasted in the same scope.
let func() =
let a = 1
let a = something_else
....
In C# I wont pass compile. is there a way to disable shadowing? at least within the same level of scope?
Thanks
You can't disable shadowing in F# -- it's an important language feature.
However, you can instruct the compiler to issue a warning or error which will help you catch cases of accidental shadowing.
In the project properties, add --warnon:1182 to the "Other flags" textbox (on the Build tab, under the platform target dropdown). This triggers a compiler warning when you accidentally shadow a variable and cause it not to be used anywhere. If you'd rather these cases cause compilation to fail, you can also add 1182 to the "Specific warnings" textbox under the "Treat warnings as errors" section of the Build tab.
Finally -- do install the Visual F# Power Tools extension. It provides additional syntax highlighting functionality and will indicate unused variables so they're easy to spot in your code.

F# Fractal - a bug I can't figure out

I'm trying to make an example I've found on the net work. It's a 3D fractal in F#. Here it is: http://tomasp.net/blog/infinite-cheese.aspx. The source code is available for download at the end of the article. The article and the sample were written in 2007, so I think the code is just slightly obsolete. There is one block of code that causes error and the code won't compile:
// Returns a cube with filtered sides
let private get_cube(incl_sides) =
[ for (side,trigs) in cube
when Set.mem side incl_sides
->> trigs ]
The when keyword is underlined, and the error message goes as follows:
Unexpected keyword 'when' in expression. Expected '->' or other token.
I can't figure out what's wrong with this. In an attempt to understand the code better, I searched the langauge specs. As far as I know, there is nothing about the Set.mem function or the ->> operator. Do you have any idea what could be wrong?
Try
[for (side, trigs) in cube do
if Set.contains side incl_sides then
yield! trigs]
The language has undergone a lot of changes since that code was written. In particular, the ->> operator has been replaced by yield!, Set.mem has been renamed to the more descriptive Set.contains, and comprehensions now use if ... then instead of when.
Yes, the version of the source code that is linked from the blog post is a bit old. You can find the latest (updated) version in the F# samples project on CodePlex. I think there may be some other changes, so it is best to get the version from CodePlex. (It includes FractalSimple.fs which is simpler version and Fractal.fs which also removes cube sides that are not visible).
The project contains standard Visual Studio 2008/2010 .fsproj project. The original version on the blog was written using F# CTP (from VS 2005 times) which had a completely different Visual Studio integration and used an obsolete .fsharpp project format (before MSBUILD format existed).
The when and ->> constructs have been used as a lightweight syntax for writing queries, but are now deprecated, to keep the syntax inside comprehensions consistent with the rest of the language. As kvb points out, you can use ordinary if .. then and the only non-standard thing is yield!, which means return all elements of the given sequence.

F# Suppress Warnings

Sometimes I get annoying pattern matching and indent warnings when compiling F#. Is there a way to disable warnings? I'm pretty OCD over warnings.
In case you forget, you can type
let rec x = lazy(x.Value)
and get the warning
This and other recursive references to
the object(s) being defined will be
checked for initialization-soundness
at runtime through the use of a
delayed reference. This is because you
are defining one or more recursive
objects, rather than recursive
functions. This warning may be
suppressed by using '#nowarn "40"' or
'--nowarn:40'.
which shows that you can use either the compiler flag --nowarn on the command-line, or use the hash-directive #nowarn in your code. The warning number for each warning will be part of the build output (the Visual Studio error list does not display the numbers, so if in VS, build and then inspect the build output). Also, if inside VS, you can go to the project properties page, "Build" tab, and use the "warning level" selector and "suppress warnings" field (a semicolon-delimited list of numbers) to control which warnings are diplayed via the VS UI.
(BTW, I believe #nowarn only turns off the warning in the current file, whereas --nowarn turns it off for the entire project being compiled.)
See: Compiler Options (F#)
--nowarn:<int-list>:
Disable specific warnings listed by
number. Separate each warning number
by a comma. You can discover the
warning number for any warning from
the compilation output.
This compiler option is equivalent to
the C# compiler option of the same
name. For more information, see
/nowarn (C# Compiler Options).

Set a default iteration path for a work item type on TFS

I try to tune my Team Foundation 2005 work items.
We have 5 iterations paths in the "Bug" work item type.
I would like it to default to a specific value, for example Iterations.Iteration2
I tried to add a DEFAULT rule in the work item type editor but couldn't set the iteration path.
How can I do that?
I'm getting the same error with TFS 2010 when I try to set a default rule for a work item type for a default iteration path.
It seems the rules engine for work items unfortunately doesn't allow this (as explained by this post and others I've seen around).
Create a Work Item Template.
If you're using VS, you'll need the Power Tools. If you're using the web interface, the feature is already built-in.

Resources