Global constants in F# - how to - f#

I need to set a version number to be used in the AssemblyVersion attribute by several related projects.
In C# I use the following
public class Constants {
public const string Version = "1.2.3.4";
}
then it can be used as follows:
[assembly:AssemblyVersion(Constants.Version)]
What would be the equivalent construct in F#. All my attempts to come up with a binding which can be accepted as an attribute argument did not work.

Use the attribute Literal:
[<Literal>]
let version = "1.2.3.4"
[<assembly:AssemblyVersion(version)>]

Since I stepped into this trap myself I thought I'd share for anyone following.
A 'Literal' requires that the letter starts with a capital letter. This will hit you when you try to use the literal in a pattern matching construct.
Reference:
Literal attribute not working

Related

Does dart have an equivalent to C# discards?

C# discards prevent allocation of values not needed. Is there something similar in dart? I saw a lot of people use the underscore as if it were a discard, but using two at the same time (like this (_, _) => method() will say the variable _ is already defined.
Dart does allow you to use the same discard operator as C#. You can define a variable or final with a name of _. This works well with the rule avoid-ignoring-return-values (Dart Code Metrics) Importantly, if you name the variable with this, you will not encounter the warning unused-local-variable. However, there is another code rule called no_leading_underscores_for_local_identifiers. You can safely turn this off as long as you don't have someone in your team that has a habit of prefixing variable names with an underscore.
Ignoring the return value
Discarding the return variable
Unfortunately, it doesn't work the same way as C# because it involves an assignment, and you cannot assign two different types to it. You need to declare it as an Object?

Why does dart not allow method overloading?

I tried to use method overloading in some dart code and quickly learned that overloading is not offered in dart.
My questions are: why is it not offered, and what is the recommended alternative? Is there a standard naming convention since methods that do the same thing but with different inputs must have different names?
Is it standard to use named parameters and then check that the caller has supplied enough information to complete the calculation?
Say I have a method that returns how much money someone makes in a year, called yearlyIncome.
In Java, I would create a method like this
double yearlyIncome(double hourlyRate, double hoursWorkedPerYear)
And maybe another method like this
double yearlyIncome(double monthlyRate, int monthsWorkedPerYear)
and so on. They're all used to calculate the same thing, but with different inputs. What's the best, standardized way to do this in dart?
Thanks so much in advance.
Function overloading is not supported in Dart at all.
Function overloading requires static types. Dart at its core is a dynamically typed language.
You can either use different names for the methods or optional named or unnamed parameters
// optional unnamed
void foo(int a, [String b]);
foo(5);
foo(5, 'bar');
// optional named
void foo(int a, {String b});
foo(5);
foo(5, b :'bar');
Optional parameters can also have default values. Optional named and unnamed parameters can not be used together (only one or the other for a single function)
In the case of a constructor you can use named constructors as an alternative
Dart did not support overloading originally because it was a much more dynamic language where the declared types did not have any semantic effect. That made it impossible to use static type based overload resolution.
Dart has since changed to be more statically type, and there is nothing fundamentally preventing Dart from adding overloading today, except that it would be a huge work and a huge change to the language. Or so I'd assume, because there isn't any obvious design that isn't either highly complicated or hugely breaking.
What you do instead in Dart is to use optional parameters. A method like:
String toString([int radix]);
effectively have two signatures: String Function() and String Function(int). It can act at both signatures.
There are definite limits to how far you can go with just optional parameters, because they still need to have exactly one type each, but that is the alternative that Dart currently provides. (Or use different names, but that's not overloading, you can do that in languages with overloading too).
Optional parameters is also one of the complications if we wanted to add overloading to the Dart language - would existing functions with optional parameters would count as multiple overloadings? If you declare a class like:
abstract class WithOverloading {
String toString();
String toString(int radix);
}
is that then the same signature as:
abstract class WithoutOverloading {
String toString([int radix]);
}
Probably not because you can tear off the latter and get one function with an optional parameter, and you might not be able to tear off both functions from the former and combine them into one function. Or maybe you can, that's why it's not a trivial design question how to include overloading into the existing Dart language.

What does the "as" keyword do in Dart language?

I'm confused as to the uses of "as" keyword.
Is it a cast operator or alias operator?
I encountered the following code on the internet which looked like a cast operator:
var list = json['images'] as List;
What does this mean?
as means different things in different contexts.
It's primarily used as a type cast operator. From the Dart Language Tour:
as: Typecast (also used to specify library prefixes)
It links to an explanation of how as is also used to add a prefix to an imported library to avoid name collisions. (as was reused to do different things to avoid needing extra keywords.)
just to add the as keyword is now flagged by the linter and they prefer you to use a check like is
if (pm is Person)
pm.firstName = 'Seth';
you can read more here https://github.com/dart-lang/linter/issues/145
As the language tour says:
Use the as operator to cast an object to a particular type if and only if you are sure that the object is of that type.
Following with your example:
var list = json['images'] as List;
You would use as here to cast or convert json['images'] into a <List> object.
From another SO post (talking about explicit cast vs. as):
as ... is more like an assertion, if the values type doesn't match as causes a runtime exception.
You can also use it when importing packages. A common example is the dart:convert as JSON which then can be reached final foo = JSON.jsonDecode(baz)
It's casting, your code is similar as:
List list = json['images'];

Ambiguous match found when calling String.Split()

I'm programming in JScript.NET which is similar to C# . I want to split a string on multiple characters, in this case " - ".
The problem is when I do that like this (which should be the way to do it according to this thread):
var text = "test - test2";
var array = [" - "];
var val = text.Split(array, StringSplitOptions.None);
I get "Ambiguous match found". This is because the String class has both a Split(Char[], StringSplitOptions) and a Split(String[], StringSplitOptions) function, and the compiler doesn't know which one to use.
So my question is then. How do I tell the compiler that I'm using a string array when the arrays in JScript.NET are dynamically typed?
Edit: As far as I know, JScript.NET use the same APIs as C#. So this is the String class I'm using. However, I think the syntax is the same as JavaScript. Maybe someone could confirm this?
Edit2: So if there is a way to enforce a type in JScript.NET so the compiler knows which type is used, I guess that would be the answer for my case as well? JScript.NET does not have the same syntax as C#.
I figured it out once I realized I was coding in JScript.NET and not JScript, which led me to a bunch of useful guides. One of them specifically mentioned how to create typed arrays.
It turns out it was a easy as this:
var array : String[] = [" -"];

Clang tooling. Type name without keyword

I'm working on some clang tool, and I need to generate source code with types, that aren't specified explicitly.
The strings with types I get from clang::QualType is something like: class std::initializer_list<int>. The issue is to get type without keyword.
I've tried to dyn_cast<> types (clang::Type) to all heirs of TypeWithKeyword but the result is always null.
Of course I can delete all occurrence of "class", "struct", etc. from the string with type name, but I would like to solve this in "clang way".
The answer was simple.
Instead of using QualType::getAsString(), just needed QualType::getAsString (const PrintingPolicy &Policy).
So the code:
PrintingPolicy pp(f_context->getLangOpts());
string typeName = qualType.getAsString(pp);
Works well without changing fields of PrintingPolicy.

Resources