Are Symbols deprecated in Dart? - dart

From reading this (https://www.educative.io/edpresso/what-is-a-dart-symbol) it seems that Symbols are deprecated in Dart. But I've had trouble finding an explanation for why to avoid them. This answer (Dart symbol literals) gives some explanation of what symbols are in dart, certain cases when they're commonly used. And it suggests "you shouldn't need to use symbols outside of those cases." Shouldn't need is different than shouldn't. Are they deprecated or not? If they are deprecated, why?
The docs here: (https://api.dart.dev/stable/2.12.4/dart-core/Symbol-class.html) don't mention deprecation. I couldn't find any mention of Symbols here: (https://dart.dev/guides/language/effective-dart) either for or against.
In this example the symbol seems to be working as I'd like it to:
class TrafficLight {
Symbol color;
TrafficLight(this.color);
}
void main() {
var t = TrafficLight(#red);
print(t.color == #red);
print(t.color == #green);
}
//returns:
// > true
// > false
If I have thousands of traffic lights, thousands of identical Strings are a waste of RAM. What's the common / best practice way of handling these type of situations in Dart? Enums? Creating a TrafficLightColor class?
Thanks in advance for any light you can shed on this issue.
Response to comments
#julemand101
void main() {
String a = '123';
String b = a;
a += 'foo';
print('a: $a');
print('b: $b');
}
return is:
a: 123foo b: 123
If they were pointing to the same object, I'd expect return to be
a: 123foo b: 123foo
#julemand101, You're absolutely right, my thinking was off. Thanks for the explanation.

Symbols are not deprecated. They are mainly used for reflection-like functionality like dart:mirrors, Object.noSuchMethod (the memberName and namedArguments names) and Function.apply (again the named arguments names). If you don't need those, you likely don't need to bother with symbols. You can, they're just objects, but not particularly useful objects.
(Some libraries use private symbols, like #_foo to create a library-private sentinel object, but you could also just do final _mySentinel = Object();.)
The best way to handle the traffic lights situation is enums.
You could use symbol literals (#red, #green) or string literals ("red", "green") or magic numbers (1, 2), but the only approach to creating a fixed set of values to represent a specific thing that is language and type-system supported is enums.
You can make your own enum-like class if you want to, and it'll be just as good as enums, except that you won't get a warning if you forget a case in a switch.
(If you do use string literals, you'll likely find that they are canonicalized too, so the string data won't take up more space whether they occur once or thousands of times).

Related

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.

How to return a struct from an imported DLL-function in MQL4?

Is there a way to return a struct from an imported function in MQL4, without having to pass it as a parameter and making a memcpy?
Be cautious with any kind of DLL-interfacing, MQL4 Documentation states:
Passing ParametersAll parameters of simple types are passed by values unless it is explicitly indicated that they are passed by reference. When a string is passed, the address of the buffer of the copied string is passed; if a string is passed by reference, the address of the buffer of this string without copying it is passed to the function imported from DLL.Structures that contain dynamic arrays[], strings, classes, other complex structures, as well as static or dynamic arrays[] of the enumerated objects, can't be passed as a parameter to an imported function.When passing an array to DLL, the address of the beginning of the data buffer is always passed (irrespective of the AS_SERIES flag). A function inside a DLL knows nothing about the AS_SERIES flag, the passed array is a static array of an undefined length; an additional parameter should be used for specifying the array size.
More glitches apply... Then how to make it work?
Maybe a straight, heterogeneous multi-party distributed processing, which communicates rather results than function calls, independent of all nightmares of maintaining just DLL-imported functions API changes, is a way safer way to go. Using this approach for the last few years and since than have no problems with New-MQL4.56789 string-s that seized to remain string-s and silently started to become struct-s etc.
Worth to know about.
Anyway, welcome and enjoy the Wild Worlds of MQL4 -- may enjoy to click and read other posts on issues in MQL4/DLL integration and/or signalling/messaging in MQL4 domains. Feel free to ask more

How do I satisfy the compiler to eliminate warning 0052?

I have a desire to satisfy compiler warning level 5. So I have 32 warnings in one file FS0052 The value has been copied to ensure the original is not mutated by this operation
I've followed the only SO post that seems to be related to this warning, but since my type is being type provider generated by Microsoft I can't just go mark the field mutable to quiet the warning. plus making something mutable that actually shouldn't ever be mutated seems like a hack not a fix.
examples:
Nullable .GetValueOrDefault()
Nullable .ToString()
Guid .toString()
struct method calls of any sort I believe
What is the recommended way to deal with this warning from a proper functional perspective?
Not sure if you're still interested.
It seems to me that the compiler emits the warning when it is unsure whether the method call is going to destroy the state of original instance (this should mostly come from any library outside F#).
Explicit copy the value into a variable is, in my case, often mitigate the warning. For example:
open System
// generate the warning due to "ToString()"
let DirSeparator = Path.DirectorySeparatorChar.ToString()
// no warning
let ExplicitCopy = let x = Path.DirectorySeparatorChar in x.ToString()
let Alternative = sprintf "%c" Path.DirectorySeparatorChar
What is the recommended way to deal with this warning from a proper
functional perspective?
I found many questions about the issue, but this particular question I found nowhere else. After having fixed many such warnings, this is my conclusion.
I believe there is no single solution. (Unless you want to resort to silencing the warning all over the place with a compiler directive or something, and I certainly don't want to do that. I have a feeling you agree with me on that, having bumped up the warning level to 5.)
First option
There is frequently another way to code, without having to resort to intermediate values or other complex expressions.
For example, to silence the warning in this case
myStruct.someField <- myRecord.SomeField.ToString()
simply change it to
myStruct.someField <- string myRecord.SomeField
Second option
If you do not find a function or some way to easily rewrite your way out of it, and it is a particular case that repeats frequently in your source, then there is the possibility to create a function or functions that you can use in these cases in order to silence the warning.
For example, I use this function instead of GetValueOrDefault.
let valueOrDefault (v: 'a Nullable) = if v.HasValue then v.Value else Unchecked.defaultof<'a>
Third option
If you have only a single particular case or barely a handful of similar cases, then using an intermediate value is possibly the easiest way to silence the warning. I tend to comment the reason for the verbosity in these cases.

"const" In Objective-C and Cocos2D: Is It Me, Or Does It Seem To Be Taboo?

I'm not sure if this is the right place to ask this, since it's not really a technical question but more a question of style and coding practices...
I've always ben a fan of using "const" to define variables that will not be changing throughout their lifetime, most especially when they are parameters to functions/methods. This probably stems from my history with C++, where objects could be passed by reference rather than by pointer, but you wanted to ensure that the original value wasn't accidentally altered, either by you or by someone else on your team who was working on the same code snippet.
When looking through the headers for both Objective-C in general and Cocos2d specifically, I've noticed that there is a noticeable lack of use of this item. Now, I'm not against developing code as quickly as possible, and leaving off constraints such as these leave the developer the option to modify values as their code develops and evolves, but there are some instances where I believe that this laxity does not belong.
For example, in Cocos2D/UIKit, the "UIFont fontWithName" method takes "(NSString *)" as the parameter for the font name: does this method really need to reserve the right to alter the original string that was passed in? I personally like to define constant strings as "const" items, and I don't like the necessity of casting these as non-"const" when calling these methods.
Enough proselytizing: My question - Is the direction now moving towards less well-defined interfaces and more towards "lazy references" (which I do not consider to be a derogative term)?
Thanks in advance for any feedback....
Const wouldn't mean anything for Objective C class pointers, because it would have to be overloaded in a very confusing way for Objective C types. This is because there's no way to mark a method as const, as there is in C++, so the compiler could never enforce it.
That said, at my old company, we did declare global string constants using something like:
NSString* const kMyCoolString = #"Hello, world!";
The point being that it at least couldn't be reassigned to something else.
The closest analog in Objective C/Cocoa/Foundation are mutable/immutable versions of data structures, which doesn't really help your case.

What is the syntax for implicit cast operator in dart?

I would like to cast instances of my custom class A to int. What is the syntax of the implicit cast operator? (I thought I remembered that there is such a feature but I can't find it on the web)
int a = (new A());
You can also use as to help tell the tools "no, really, treat this object as this type".
A good example of this is when you have to deal with dart:html's querySelector() function.
FormElement form = querySelector('#sign-up') as FormElement;
In the above, the object returned by querySelector('#sign-up') is checked that it is really an instance of FormElement.
Learn more at https://www.dartlang.org/docs/dart-up-and-running/ch02.html#operators
Type annotations are not allowed to affect behavior in Dart. If you're not running in checked mode, then this:
int a = new A();
will work the same as this:
var a = new A();
at run-time. In other words, when not in checked mode, you're welcome to store your A in a variable annotated as an int, but no actual conversion takes place.
If you are running in checked mode, the first form will give you a runtime exception.
I'm not sure, but I think what you're asking for is a way to define a conversion between your class A and int that will happen automatically when "cast" to an int. No such thing exists, to my knowledge. You should simply define a method to do so. For example:
int a = new A().to_i();

Resources