Is it possible to do a member overload with generic constraints? Here, I am trying to create and AddWithOption method to support both value types and reference types. If you look at the gist, I show several attempts to make this happen.
My workaround was simply to not overload the member. I renamed with one for value types to AddWithOptionValue. However, it would be cool if the overload worked. Any ideas?
Constraints are not part of method signature (per ECMA 335, I.8.6.1.5 Method signatures) meaning that in CIL you cannot have two methods which signatures differ only in constraints. In order to encode such signatures in CIL one need to use optional or required modifiers but this is not very trivial and today F# does not do that.
Related
I need a modifiable collection like a List or a Set to be passed as a parameter. Using Iterable doesn't guarantee this argument to have methods like add or remove.
Example method:
void foo(Iterable bar) {
bar.add(); // The method 'add' isn't defined for the type 'Iterable'.
}
Is there a class / interface for (modifiable) collections which guarantees those methods? If not, why?
There is not a modifiable type. Very early (before Dart 1) we had some other types in our hierarchy, but we decided to avoid including them because things were getting a bit too complex.
I still wish we'd shipped a List interface without the mutation members. 🤷
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.
I just started to study F# and accidentally wrote this binding
let List = 1
Now when I try to obtain List methods such as 'filter' I get this error
error FS0039: The field, constructor or member 'filter' is not defined.
Of course using method with full type name like Microsoft.FSharp.Collections.List.filter is still working.
I'm wondering why it is possible to use type name as identifier in F# and how I can set back name List to type List from Microsoft.FSharp.Collections.
When I tried to reassign like this
type List = Microsoft.FSharp.Collections.List<'T>
I get
Error FS0039: The type parameter 'T is not defined.
Thank you!
In F# you can redefine almost everything and shadow existing definitions. This applies to both types (well actually types have a different behavior regarding shadowing, they shadow their values as you open the namespaces) and values but not interchangeably since values and type (and also modules) can somehow coexist at the same time in the scope. The compiler will do his best to find out which one is.
You are not forced to, but it's a common good practice in F# not to use let bindings in uppercase.
Regarding your second question, you are using a type parameter in the right side which doesn't exist in the left side of the assignment, it should be:
type List<'T> = Microsoft.FSharp.Collections.List<'T>
But notice that filter doesn't belong to the type. It's rather defined in the List module.
You should just rename your let binding from List to something sensible - as Gustavo mentioned, your definition is shadowing the core List module from F# and there is no way to use List to refer both to your integer and to the module. Shadowing core functions will make your code pretty confusing. It's also a good idea to use camelCase for let bindings, but that's a matter of taste.
If you insist on shadowing List, then you won't be able to call List.filter using List.filter. If you wanted something shorter, you could define module alias:
module FsList = Microsoft.FSharp.Collections.List
Note that your attempt to do something similar with List<'T> does not do the same thing, because functions such as filter are in a module named List rather than being static members of the type. With this, you can call filter using FsList.filter.
See for example Data.Maybe.Base in the stdlib — all Maybe, Any, and All have a just constructor.
Agda allows these definitions. How can one specify which one to use?
Each data type comes with its own module. So Maybe, All and Any are all type constructors and modules simultaneously. Thus you can write Maybe.just, All.just or Any.just to disambiguate the constructor. Or it can be disambiguated by type inference (unification is a more appropriate term) or an explicit type signature like Thilo said in their comment. (It's not true however that you'll get an error if there some ambiguity -- you'll get an unsolved meta).
The terms "declaration" and "definition" are being used synonymously in Apple's Swift documentation and it's getting me confused.
Under the "Initialization" section (which talks about class initializers), Apple states:
You can set an initial value for a stored property within an initializer, or by assigning a default property value as part of the property’s definition.
Further in a subsection they state:
You can set the initial value of a stored property from within an initializer, as shown above. Alternatively, specify a default property value as part of the property’s declaration.
I thought a variable declaration was different than a variable definition.
You are right that those two mean different thing, THOUGH I think most of the people just use both of them in the same meaning and I think that is also the case of those AppleDocs. Here is great article on subject:
Summary
A declaration provides basic attributes of a symbol: its type and its
name. A definition provides all of the details of that symbol--if it's
a function, what it does; if it's a class, what fields and methods it
has; if it's a variable, where that variable is stored. Often, the
compiler only needs to have a declaration for something in order to
compile a file into an object file, expecting that the linker can find
the definition from another file. If no source file ever defines a
symbol, but it is declared, you will get errors at link time
complaining about undefined symbols.
After doing much searching across the web for legitimate explanations, I have seemed to have found an answer:
The problem is that the two terms overlap to some extent. Definitions also serve as declarations, because they inject an identifier of a certain type to a scope. However, a declaration isn't a definition because it doesn't entail storage allocation for the declared object. To add to the confusion, the semantics of definitions and declarations is slightly different when applied to types and functions, as I will show momentarily. So let's look at a more detailed analysis of these two terms.
Here is the article: Declarations and Definitions.
The article gives further explanation and examples.
Declaration of variable mean to tell compiler their is a var\funct\struct of particular data type. Definition of variable mean asking compiler to allocate memory to variable or define storage for that variable. you can define a variable only one time but you can declare it as many time you want.
I think Apple's Swift 4 Language Reference can be construed as the authoritative answer. From the Declarations section (emphasis mine):
A declaration introduces a new name or construct into your program.
For example, you use declarations to introduce functions and methods,
variables and constants, and to define new, named enumeration,
structure, class, and protocol types. You can also use a declaration
to extend the behavior of an existing named type and to import symbols
into your program that are declared elsewhere.
In Swift, most declarations are also definitions in the sense that
they are implemented or initialized at the same time they are
declared. That said, because protocols don’t implement their members,
most protocol members are declarations only. For convenience and
because the distinction isn’t that important in Swift, the term
declaration covers both declarations and definitions.