import is a keword, yet the following works fine:
import 'dart:io';
void main() {
import() {
print("Imported");
}
import();
}
Is this supposed to work?
Is the language sufficiently stable that using this will continue to work?
What is special about import versus say class, which does not work and what other keywords/may be are fair game?
Yes, this is supposed to work. And I think that yes, you can be reasonably sure that this will continue to work. To explain, let's take a look at the language specification.
Section 16.1.1 (Reserved words) explains that a reserved word may not be used as an identifier; it is a compile-time error if a reserved word is used where an identifier is expected. Here is the list of reserved words: assert, break, case, catch, class, const, continue, default, do, else,
enum, extends, false, final, finally, for, if, in, is, new, null, rethrow, return, super, switch, this, throw, true, try, var, void, while, with. Note that import isn't mentioned here.
Then, sections 12.30 (Identifier Reference) explains that there is a set of built-in identifiers which looks like this: abstract, as, dynamic, export, external, factory, get, implements, import, library, operator, part, set, static, typedef. And it is a compile-time error if a built-in identifier is
used as the declared name of a class, type parameter or type alias. Note that import falls into this group -- so you can't use it as a type, but you can use it elsewhere (like in your case, as a function name).
And a non-normative part of the section 12.30 explains the difference: Built-in identifiers are identifiers that are used as keywords in Dart, but are not reserved words in Javascript.
Just to note, in this answer, I quoted the PDF form of the Dart Language Specification version 0.30.
Related
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?
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.
why
-(void)addSimpleListener:(id<XXSimpleListener>)listener
convert to swift look like this:
func add(_ listener: XXSimpleListener?) {
}
but change the method to this
-(void)addSimpleListener:(id<XXSimpleListening>)listener
and it will convert to this
func addSimpleListener(_ listener: XXSimpleListening?){
}
Xcode (or whatever tool you are using to do the conversion) is merely following Swift API guidelines. Specifically:
Omit needless words. Every word in a name should convey salient information at the use site.
More words may be needed to clarify intent or disambiguate meaning, but those that are redundant with information the reader already possesses should be omitted. In particular, omit words that merely repeat type information.
In the first case, the words SimpleListener in addSimpleListener is repeating the type of the parameter, so they are removed from the method name. However, in the second case, SimpleListener and SimpleListening does not look the same to whatever tool you are using, so it thinks that SimpleListener should be kept.
In my (human) opinion though, I think the method should be named addListener, because:
Occasionally, repeating type information is necessary to avoid ambiguity, but in general it is better to use a word that describes a parameter’s role rather than its type.
Listener is the role of the parameter.
I understand closures, even though I scarcely use them, but whenever I can squeeze one I have no idea of how to name it.
The best I can think of is sticking a "make" before what would be the name of the function:
function makeSortSelection(settings1, settings2) {
return function() {
/* sort stuff attending to settings1 and settings2 */
};
}
$("#sort-button").click(makeSortSelection('ascending',foo));
(I almost always use them in Javascript, but I guess this is a very language-agnostic question)
Sadly, most examples I found of closures just use "foo" or "sayHello". I like to give all my functions a verb as name: functions "do stuff", and their name reflects it ("sortSelection", "populateForm"). In the same spirit, how should I name closures, that "do things that do stuff"? What conventions do you use, and what are the most common?
PD: I tend to use Google's style guide when in doubt, but it says nothing about this.
Closures aren't nameable entities. Functions are nameable but a closure isn't a function.
Rather than define "a closure" it is easier to define the circumstances under which closure arises.
A (lexical) closure (in javascript) occurs and continues to exist as long a persistent external reference to an inner function exists, but neither the outer function nor the inner function nor the reference to the inner function is, in itself, a closure. Pragmatically speaking, a closure is a construct comprising all these elements plus a feature of the language by which garbage collection is suppressed when they exist.
In my opinion it is wrong, as some claim, that "all functions are closures". Yes, all functions have a scope chain, but a closure should only be regarded as existing once an outer function has completed and returned, and a persistent reference to an inner function exists.
By all means give the returned function a verb-based name, just like any other named function - there's no need to regard it differently just because it is was returned by another function. In every respect the returned function is just a function - it just happens to be a function with access to the scope chain of the (execution context of the) outer function that brought it into being - nothing more than that.
EDIT:
I just realised I didn't address the critical point of the question - rephrased "how to name a function that exists for the express purpose of forming a closure by returning a function".
Like you, I have a problem here.
Most often I use the "make" prefix, as in your example. This seems to be best most of the time.
I have also used "_closure" as a suffix, This doesn't obey the "verb rule" but has the advantage of being independent of natural language. "Make" is strictly an English word and speakers of other languages will probably choose to use their own "faire", "machen" etc. On the other hand, "closure" is universal - it remains, as far as I'm aware, untranslated in other languages. Therefore, "closure" as a suffix (or prefix) could be better in scripts that are likely to be used/modded on a world-wide basis.
I noticed that in many community Objective-C classes and in Apple's frameworks they name some of the variables using a convention that prefixes variables with an underscore, such as: _name. What is the reason for having the underscore. Should I be doing this in my own classes? If so where and when should I use it?
That's called uglification. The point is that you never use it, so no variable name or #define you create could ever interfere with Apple's code.
Ironically, many people create header guards with such names, because they see the system headers do it.
From C99 7.1.3 "Reserved identifiers":
All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
(They mean reserved for the system library.)
Note: I'm not sure of the exact relationship between C99 and Apple ObjC, but you might as well have naming conventions that work across the entire C language family. In particular ObjC++ would require valid C++ names, which have the additional requirement of no double underscores anywhere.
In Cocoa, it's a convention to indicate the something is private and shouldn't be used externally. However, it's unofficial convention, particularly in light of wording like this in the documentation:
Method names beginning with “_”, a single underscore character, are reserved for use by Apple.
However, that recommendation specifically applies to methods, not variables. So if you'd like to prefix your variables with underscores, go right ahead. That being said, if you're using the underscore prefix to indicate the private nature of some data, perhaps you shouldn't be exposing it in the first place...
Underscores get in the way of readability. Also with LLVM in place of GCC, I am getting rid of header side ivars and using header side properties. Be sure to make your properties non atomic unless you really want reads and writes synchronized for thread safety. unless you specify non atomic, it will default to atomic - which will deprive you of some performance.
also by convention, never start accessors with get. setters Should start with set but no getters with get. Read up on KVO and KVC for more about the conventions and what they are good for.
I do however like underscores in Enumeration naming list. Here the underscores help me pick out the suffix in 5 or more lines that all start with the same stem.
Like
typedef NSInteger COMPASS_DIRECTION;
enum {
COMPASS_DIRECTION_NORTH,
COMPASS_DIRECTION_EAST,
COMPASS_DIRECTION_SOUTH,
COMPASS_DIRECTION_WEST,
};