Does Dart support constructs typically precluded by Optional Typing? - dart

Slide 33 of that presentation of optional typing (by Bracha) presents common constructs that should be precluded by optional typing, like public fields or class-based encapsulation. However, doesn't Dart have those constructs although it is is said to support optional typing?

Dart actually has neither of those constructs.
While it may look like Dart has public fields, in actuality implicit getters and setters are generated for each field, so that you are not accessing the field directly.
As far as class-based encapsulation, Dart has no such concept. Instead encapsulation is accomplished through the use of libraries. All classes that are part of a library may access private members of other classes in that library, while classes from a different library can not.

Related

Singletons with Dart enums?

One of the recommended ways of creating singletons in Java is to use an enum.
There are other ways of creating singletons in Dart, but with the new enhanced enums I got to wondering if this could be added to the list.
On a superficial level it seems possible:
enum Singleton {
instance();
const Singleton();
}
But would it really work to make a database helper or logger? Since the constructor needs to be constant, I don't think it would work, but am I missing a possible way of doing it?
As enums need a const constructor, they can contain no mutable fields.
Any functions declared inside the enum would need to be free of side-effects, and no more useful than top-level or static functions.
There's not much point to doing this. The Dart guidelines prefer top-level functions over classes containing only static members.

Why is using final, with no type, considered good practice in Dart? ie `final foo = config.foo;`?

I see this recommended in the dart style guide, and copied in tons of tutorials and flutter source.
final foo = config.foo;
I don't understand it, how is this considered best practice when the readability is so poor? I have no clue what foo is here, surely final String foo = config.foo is preferable if we really want to use final?
This seems the equivalent to using var, which many consider a bad practice because it prevents the compiler from spotting errors and is less readable.
Where am I wrong?
In a lot of cases is does not really matter what type you are using as long the specific type can be statically determined by the compiler. When you are using var/final in Dart it is not that Dart does not know the type, it will just figure it out automatically based on the context. But the type must still be defined when the program are compiled so the types will never be dynamic based on runtime behavior. If you want truly dynamic types, you can use the dynamic keyword where you tell Dart "trust me, I know what I am doing with this types".
So types should still be defined where it matter most. This is e.g. for return and argument types for methods and class variables. The common factor for this types is that they are used to define the interface for using the method or class.
But when you are writing code inside a method, you are often not that interested in the specific types of variables used inside the method. Instead the focus should be the logic itself and you can often make it even more clear by using good describing variable names. As long the Dart analyzer can figure out the type, you will get autocomplete from your IDE and you can even still see the specific type from your IDE by e.g. Ctrl+Q in IntelliJ on the variable if you ends up in a situation where you want to know the type.
This is in particular the case when we are talking about the use of generics where it can be really tiresome to write the full specific type. Especially if you are using multiple generics inside each other like e.g. Map<String, List<String>>.
In my experience, Dart is really good to figure out very specific types and will complain loudly if your code cannot be determined statically. In the coming future, Dart will introduce non-null by default, which will make the Dart compiler and analyzer even more powerful since it will make sure your variable cannot be null unless this is something you specifically want and will make sure you are going to test for null when using methods which are specified to not expecting null.
About "Where am I wrong?". Well, a lot of languages have similar feature of var/final like Dart with the same design principle about the type should still be statically determined by a compiler or runtime. And even Java has introducing this feature. As a experienced Java and Dart programmer I have come to the conclusion for myself that typing inside methods are really not that important in a lot of cases as long I can still easily figure out the specific type by using an IDE when it really matters.
But it does make it more important to name your variables so they are clearly defining the purpose. But I am hoping you already are doing that. :)

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.

Discussion Question: Why doesn't dart allow to declare enums in class?

I tried to declare an enum inside the class and it gave me an error stating can't have enum inside a class. I wanted to know the reason why but I didn't find anything on the internet. Declaring enum inside a class is allowed by major languages why not dart?
Dart does not allow nested type declarations in general. You can only declare types at top-level. This includes classes, mixins, typedefs and enums.
I believe the original reason was that it was not necessary, and implementing it inadequately was worse than not doing allowing it at all.
There is nothing inherently preventing Dart from allowing static types declared inside other types. Obviously, if Dart allowed classes statically declared inside classes, it would allow in arbitrary nesting of classes, so it really is a matter of allowing zero, one or an infinite amount of nesting. Dart currently has "one'.
Still, it's something that can be easily remedied if deemed wort the effort and a higher priority than other language changes.
The other option is to have non static nested types. That's a much bigger can of worms, and probably not something that's going to happen any time soon, if ever.
Dart doesn't allow declaring of Enum inside the class as far as I know. I've made that error before and it took me a minute to figure out what was wrong with my code. Declare/setup your Enum before your class like so:
enum Gender {
male,
female,
}
/// Then declare your class next
class MyClass {
/// The rest of your code goes here, and you still have access to your enum
}

F# - Type augmentation VS Type extension

What exactly is the difference between F#'s type augmentation and type extension, and do we really need both?
Are there situations where one is better than the other, and vice-versa?
I'm asking because I recently had a lecture in F# where the lecturer talked about both, and afterwards commented that he couldn't see the reason why both were included in the F# language.
Update:
Ok, so Vladislav Zorov links to a page with examples of using type augmentation both when defining your own types, and extending (or augmenting?) an external type.
pad links to an MSDN page where they call it intrinsic and optional type extension.
Both seem to illustrate the same thing. Can someone come with a concrete example of type extension and another concrete example of type augmentation perhaps, in order to explicitly clarify what the two things are exactly?
The following bits from MSDN's Type Extensions page are relevant (emphasis mine):
There are two forms of type extensions that have slightly different
syntax and behavior. An intrinsic extension is an extension that
appears in the same namespace or module, in the same source file, and
in the same assembly (DLL or executable file) as the type being
extended. An optional extension is an extension that appears outside
the original module, namespace, or assembly of the type being
extended. Intrinsic extensions appear on the type when the type is
examined by reflection, but optional extensions do not. Optional
extensions must be in modules, and they are only in scope when the
module that contains the extension is open.
The purpose of optional extension is clear. It helps you inject new functionalities to types not belonging to your assemblies. For examples, FSharpx uses it to create various helpers for parsing primitive types:
open System
type Boolean with
static member parse x =
match bool.TryParse(x) with
| true,v -> Some v
| _ -> None
Why do you need intrinsic extension then? The answer is its convenience. I find it useful to break down type definitions to multiple sections with clear purposes.
In many F# libraries, I saw the use of the following pattern: type definition -> utility functions -> intrinsic extension. In this way, you can define sophisticated utility functions on your types, make them available in modules and still can use them directly in your member definitions. You can look at Complex type in F# PowerPack to see the pattern.
EDIT:
To be honest, I often use type extension and type augmentation interchangeably. The thing that matters is whether they are intrinsic or optional.
They are different things. Type augmentations, when defined in the same namespace, module and source file, actually become part of the type when compiled. Type extensions (a.k.a. type augmentations for types outside of the module and source file) are implemented with .NET extension methods.
They both use the same syntax, the only difference is whether the type you mention is in the same namespace and assembly, i.e. you're augmenting your own code and the additional methods can be added to your type before compilation.
Source: http://tomasp.net/blog/fsharp-iii-oop.aspx
Edit:
This is a terminology mix-up, they are both referring to the same thing - intrinsic extensions are type augmentations of the first kind (i.e. same namespace and assembly), optional extensions are type augmentations of the second kind (i.e. 3rd party assembly, in the blog post this is the List<T> augmentation example).
I assume when your lecturer is talking about type augmentations, he's referring to intrinsic extensions, i.e. first kind type augmentations, and when he's talking about type extensions, he's talking about optional extensions, or second kind type augmentations.

Resources