The D programming language reference shows two examples in the Declarations and Type Qualifiers section, so these are both possible:
struct S
{
int method() const
{
//const stuff
}
}
struct S
{
int method() immutable
{
//immutable stuff
}
}
From the docs:
Const member functions are functions that are not allowed to change any part of the object through the member function's this reference.
And:
Immutable member functions are guaranteed that the object and anything referred to by the this reference is immutable.
I've found this question, but all the answers are talking about data types, not storage classes. Same goes for the D const FAQ, even though it's an interesting read.
So what is the difference between the two definitions above? Are there expressions that can replace //const stuff and be legal but not //immutable stuff?
immutable methods may only be called on immutable objects. They can work with the guarantee* that their object (this) will not change, ever.
const methods may be called on const, immutable, or mutable objects. They guarantee that they themselves will not change their object, but other references may change the object.
I'd go with const unless you have a good reason to need immutable, as const functions are callable with all three mutability storage classes.
* At the type system level, anyway. Mutating an immutable object is possible, but causes undefined behavior.
Related
Check these two examples:
static const inside of class:
class SessionStorage {
static const String _keySessionExist = 'storage.key';
}
Just a const outside of the class:
const String _keySessionExist = 'storage.key';
class SessionStorage {
}
Is there any difference or implications between having a static const variable inside of a class or just having it declared as const outside of it in Dart?
Maybe the compiled code changes?
Which one is more performant?
Which one should we follow if the variable is private to the file?
The declaration for cons must be using const. You have to declare it as static const rather than just const.
static, final, and const mean entirely distinct things in Dart:
static means a member is available on the class itself instead of on instances of the class. That's all it means, and it isn't used for anything else. static modifies members.
final means single-assignment: a final variable or field must have an initializer. Once assigned a value, a final variable's value cannot be changed. final modifies variables.
const has a meaning that's a bit more complex and subtle in Dart. const modifies values. You can use it when creating collections, like const [1, 2, 3], and when constructing objects (instead of new) like const Point(2, 3). Here, const means that the object's entire deep state can be determined entirely at compile time and that the object will be frozen and completely immutable.
Const objects have a couple of interesting properties and restrictions:
They must be created from data that can be calculated at compile time. A const object does not have access to anything you would need to calculate at runtime. 1 + 2 is a valid const expression, but new DateTime.now() is not.
They are deeply, transitively immutable. If you have a final field containing a collection, that collection can still be mutable. If you have a const collection, everything in it must also be const, recursively.
They are canonicalized. This is sort of like string interning: for any given const value, a single const object will be created and re-used no matter how many times the const expression(s) are evaluated. In other words:
getConst() => const [1, 2];
main() {
var a = getConst();
var b = getConst();
print(a === b); // true
}
I think Dart does a pretty good job of keeping the semantics and the keywords nicely clear and distinct. (There was a time where const was used both for const and final. It was confusing.) The only downside is that when you want to indicate a member that is single-assignment and on the class itself, you have to use both keywords: static final.
Also:
I suggest you to have a look at this question
What is the difference between the "const" and "final" keywords in Dart?
Is there any difference or implications between having a static const variable inside of a class or just having it declared as const outside of it in Dart?
The obvious difference is that the static version must be referenced with the class name. Other than the change in name resolution, the should be the same.
Maybe the compiled code changes?
Which one is more performant?
They're both compile-time constants. There shouldn't be any difference.
Which one should we follow if the variable is private to the file?
If you want something that's private to a Dart library (which usually means the file), then prefix it with _. It doesn't matter whether it's global or static.
Consider this dart code:
T t = T() // id field defaults to null
List<T> list = List()..add(t);
t.id = '123';
print('${list.first.id}') // What's output?
My question is about whether passed items to List are copied over to List or it's a reference.
I've encountered this ambiguity because I'm using flutter_redux where an action contains an instance of class T. on reducer, I add this T instance to my state. later on, in the middleware, I update this t's id. But surprisingly id field on the state(in this case List) changes too! So my only guess is that objects are passed by reference. Is this assumption correct?
Everything in Dart is an Object, so anything you are passing is passed by reference.
From the Dart Language Tour:
Everything you can place in a variable is an object, and every object
is an instance of a class. Even numbers, functions, and null are
objects. All objects inherit from the Object class.
mutable/immutable objects
There is a difference however between mutable and immutable objects. Some objects are immutable, and therefore cannot be modified, while mutable objects can be modified.
An example of immutable objects is String objects.
An example of mutable object is List just like you observed in your example.
constness
Dart has another interesting type of object, and if you are familiar with C++ or C, you would have encountered these. These are compile-time constants (const), and carry with them an attribute of immutability. Any object can be declared as const at the point of creation, provided the constructor being called has been declared as const.
Watch out with const objects if you are passing them to functions that expect mutable objects because attempting to mutate the constant, will result in a runtime error.
void modl(final List<int> l) {
l.add(90);
print(l);
}
void main() {
List<int> l = const [1,2,3,4];
modl(l); // Uncaught Error
print (l);
}
Running the above program will result in an Uncaught Error because l is a compile-time constant.
See Detecting when a const object is passed to a function that mutates it, in Dart
In D I can specify const functions, like in c++:
struct Person {
string name;
// these two are the same?
const string getConstName() { return name; }
string getConstName2() const { return name; }
}
It seems that the above two are the same meaning. Is it true?
If so how can I return a const string rather than define a const function?
The two are identical. Function attributes can go on either side of a function. e.g.
pure Bar foo() {...}
and
Bar foo() pure {...}
are identical. The same goes for pure, nothrow, const, etc. This is probably fine for most attributes, but it becomes quite annoying when const, immutable, or inout is involved, because they can all affect the return type. In order for those attributes to affect the return type, parens must be used. e.g.
const(Bar) foo() {...}
returns a const Bar, whereas
Bar foo const {...}
and
const Bar foo() {...}
return a mutable Bar, but the member function itself is const. In most cases what you want is probably either
Bar foo() {...}
or
const(Bar) foo() const {...}
since it's frequently the case that having a const member function forces you to return const (particularly if you're returning a member variable), but you can have any combination of const between the member function and its return type just so long as it works with what the function is doing (e.g. returning a mutable reference to a member variable doesn't work from a const function).
Now personally, I wish that putting const on the left-hand side were illegal, particularly when the excuse that all function attributes can go on either side of the function isn't really true anyway (e.g. static, public, and private don't seem to be able to go on the right-hand side), but unfortunately, that's the way it is at this point, and I doubt that it's going to change, because no one has been able to convince Walter Bright that it's a bad idea to let const go on the left.
However, it is generally considered bad practice to put const, immutable, or inout on the left-hand side of the function unless they're using parens and thus affect the return type, precisely because if they're on the left without parens, you immediately have to question whether the programmer who did it meant to modify the function or the return type. So, allowing it on the left is pretty pointless (aside perhaps for generic code, but it's still not worth allowing it IMHO).
I am starting studying OOP and I want to learn what constitutes a class. I am a little confused at how loosely some core elements are being used and thus adding to my confusion.
I have looked at the C++ class, the java class and I want to know enough to write my own pseudo class to help me understand.
For instance in this article I read this (.. class attribute (or class property, field, or data member)
I have seen rather well cut out questions that show that there is a difference between class property and class field for instance What is the difference between a Field and a Property in C#?
Depending on what language I am studying, is the definition of
Property
Fields
Class variables
Attributes
different from language to language?
"Fields", "class variables", and "attributes" are more-or-less the same - a low-level storage slot attached to an object. Each language's documentation might use a different term consistently, but most actual programmers use them interchangeably. (However, this also means some of the terms can be ambiguous, like "class variable" - which can be interpreted as "a variable of an instance of a given class", or "a variable of the class object itself" in a language where class objects are something you can manipulate directly.)
"Properties" are, in most languages I use, something else entirely - they're a way to attach custom behaviour to reading / writing a field. (Or to replace it.)
So in Java, the canonical example would be:
class Circle {
// The radius field
private double radius;
public Circle(double radius) {
this.radius = radius;
}
// The radius property
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
// We're doing something else besides setting the field value in the
// property setter
System.out.println("Setting radius to " + radius);
this.radius = radius;
}
// The circumference property, which is read-only
public double getCircumference() {
// We're not even reading a field here.
return 2 * Math.PI * radius;
}
}
(Note that in Java, a property foo is a pair of accessor methods called getFoo() and setFoo() - or just the getter if the property is read-only.)
Another way of looking at this is that "properties" are an abstraction - a promise by an object to allow callers to get or set a piece of data. While "fields" etc. are one possible implementation of this abstraction. The values for getRadius() or getCircumference() in the above example could be stored directly, or they could be calculated, it doesn't matter to the caller; the setters might or might not have side effects; it doesn't matter to the caller.
I agree with you, there's a lot of unnecessary confusion due to the loose definitions and inconsistent use of many OO terms. The terms you're asking about are used somewhat interchangeably, but one could say some are more general than others (descending order): Property -> Attributes -> Class Variables -> Fields.
The following passages, extracted from "Object-Oriented Analysis and Design" by Grady Booch help clarify the subject. Firstly, it's important to understand the concept of state:
The state of an object encompasses all of the (usually static) properties of the object plus the current (usually dynamic) values of each of these properties. By properties, we mean the totality of the object's attributes and relationships with other objects.
OOP is quite generic regarding certain nomenclature, as it varies wildly from language to language:
The terms field (Object Pascal), instance variable (Smalltalk), member object (C++), and slot (CLOS) are interchangeable, meaning a repository for part of the state of an object. Collectively, they constitute the object's structure.
But the notation introduced by the author is precise:
An attribute denotes a part of an aggregate object, and so is used during analysis as well as design to express a singular property of the class. Using the language-independent syntax, an attribute may have a name, a class, or both, and optionally a default expression: A:C=E.
Class variable: Part of the state of a class. Collectively, the class variables of a class constitute its structure. A class variable is shared by all instances of the same class. In C++, a class variable is declared as a static member.
In summary:
Property is a broad concept used to denote a particular characteristic of a class, encompassing both its attributes and its relationships to other classes.
Attribute denotes a part of an aggregate object, and so is used during analysis as well as design to express a singular property of the class.
Class variable is an attribute defined in a class of which a single copy exists, regardless of how many instances of the class exist. So all instances of that class share its value as well as its declaration.
Field is a language-specific term for instance variable, that is, an attribute whose value is specific to each object.
I've been doing oop for more than 20 years, and I find that people often use different words for the same things. My understanding is that fields, class variables and attributes all mean the same thing. However, property is best described by the stackoverflow link that you included in your question.
Generally fields, methods, static methods, properties, attributes and class (or static variables) do not change on a language basis... Although the syntax will probably change on a per language basis, they will be function in the way you would expect across languages (expect terms like fields/data members to be used interchangably across languages)
In C#....
A field is a variable that exists for a given instance of a class.
eg.
public class BaseClass
{
// This is a field that might be different in each instance of a class
private int _field;
// This is a property that accesses a field
protected int GetField
{
get
{
return _field;
}
}
}
Fields have a "visibility" this determines what other classes can see the field, so in the above example a private field can only be used by the class that contains it, but the property accessor provides readonly access to the field by subclasses.
A property lets you get (sometimes called an accessor) or set (sometimes called a mutator) the value of field... Properties let you do a couple of things, prevent writing a field for example from outside the class, change the visibility of the field (eg private/protected/public). A mutator allows you to provide some custom logic before setting the value of a field
So properties are more like methods to get/set the value of a field but provide more functionality
eg.
public class BaseClass
{
// This is a field that might be different in each instance of a class
private int _field;
// This is a property that accesses a field, but since it's visibility
// is protected only subclasses will know about this property
// (and through it the field) - The field and property in this case
// will be hidden from other classes.
protected int GetField
{
// This is an accessor
get
{
return _field;
}
// This is a mutator
set
{
// This can perform some more logic
if (_field != value)
{
Console.WriteLine("The value of _field changed");
_field = value;
OnChanged; // Call some imaginary OnChange method
} else {
Console.WriteLine("The value of _field was not changed");
}
}
}
}
A class or static variable is a variable which is the same for all instances of a class..
So, for example, if you wanted a description for a class that description would be the same for all instance of the class and could be accessed by using the class
eg.
public class BaseClass
{
// A static (or class variable) can be accessed from anywhere by writing
// BaseClass.DESCRIPTION
public static string DESCRIPTION = "BaseClass";
}
public class TestClass
{
public void Test()
{
string BaseClassDescription = BaseClass.DESCRIPTION;
}
}
I'd be careful when using terminology relating to an attribute. In C# it is a class that can be applied to other classes or methods by "decorating" the class or method, in other context's it may simply refer to a field that a class contains.
// The functionality of this attribute will be documented somewhere
[Test]
public class TestClass
{
[TestMethod]
public void TestMethod()
{
}
}
Some languages do not have "Attributes" like C# does (see above)
Hopefully that all makes sense... Don't want to overload you!
Firstly, you need to select a language. For example, I would recommend you to select Ruby language and community. Until you select a language, you cannot escape confusion, as different communities use different terms for the same things.
For example, what is known as Module in Ruby, Java knows as abstract class. What is known as attributes in some languages, is known as instance variables in Ruby. I recommend Ruby especially for its logical and well-designed OOP system.
Write the following in a *.rb file, or on the command line in irb (interactive Ruby interpreter):
class Dog # <-- Here you define a class representing all dogs.
def breathe # <-- Here you teach your class a method: #breathe
puts "I'm breathing."
end
def speak # <-- Here you teach your class another method: #speak
puts "Bow wow!"
end
end
Now that you have a class, you can create an instance of it:
Seamus = Dog.new
You have just created an instance, a particular dog of class Dog, and stored it in the constant Seamus. Now you can play with it:
Seamus.breathe # <-- Invoking #breathe instance method of Seamus
#=> I'm breathing.
Seamus.speak # <-- Invoking #speak instance method of Seamus
#=> Bow wow!
As for your remaining terminology questions, "property" or "attribute" is understood as "variable" in Ruby, almost always an instance variable. And as for the term "data member", just forget about it. The term "field" is not really used in Ruby, and "class variable" in Ruby means something very rarely used, which you definitely don't need to know at this moment.
So, to keep the world nice and show you that OOP is really simple and painless in Ruby, let us create an attribute, or, in Ruby terminology, an instance variable of Dog class. As we know, every dog has some weight, and different dogs may have different weights. So, upon creation of a new dog, we will require the user to tell us dog's weight:
class Dog
def initialize( weight ) # <-- Defining initialization method with one argument 'weight'
#weight = weight # <-- Setting the dog's attribute (instance variable)
end
attr_reader :weight # <-- Making the dog's weight attribute visible to the world.
end
Drooly = Dog.new( 16 ) # <-- Weight now must provide weight upon initialization.
Drooly.weight # <-- Now we can ask Drooly about his weight.
#=> 16
Remember, with Ruby (or Python), things are simple.
I discovered in my question that Properties as defined in .Net are just a convenience syntax for code, and they are not tied to underlying variables at all (except for Auto-Implemented Properties, of course). So, saying "what is the difference between class property and class field" is like saying: what is the difference between a method and an attribute. No difference, one is code and the other is data. And, they need not have anything to do with each other.
It is really too bad that the same words, like "attribute" and "property", are re-used in different languages and ideologies to have starkly different meanings. Maybe someone needs to define an object-oriented language to talk about concepts in OOP? UML?
In The Class
public class ClassSample
{
private int ClassAttribute;
public int Property
{
get { return ClassAttribute; }
set { ClassAttribute = value; }
}
}
In the Program
class Program
{
static void Main(string[] args)
{
var objectSample = new ClassSample();
//Get Object Property
var GetProperty = objectSample.Property;
}
}
I have two methods like so:
Foo[] GetFoos(Type t) { //do some stuff and return an array of things of type T }
T[] GetFoos<T>()
where T : Foo
{
return GetFoos(typeof(T)) as T[];
}
However, this always seems to return null. Am I doing things wrong or is this just a shortfall of C#?
Nb:
I know I could solve this problem with:
GetFoos(typeof(T)).Cast<T>().ToArray();
However, I would prefer to do this wothout any allocations (working in an environment very sensitive to garbage collections).
Nb++:
Bonus points if you suggest an alternative non allocating solution
Edit:
This raises an interesting question. The MSDN docs here: http://msdn.microsoft.com/en-us/library/aa664572%28v=vs.71%29.aspx say that the cast will succeed if there is an implicit or explicit cast. In this case there is an explicit cast, and so the cast should succeed. Are the MSDN docs wrong?
No, C# casting isn't useless - you simply can't cast a Foo[] to a T[] where T is a more derived type, as the Foo[] could contain other elements different to T. Why don't you adjust your GetFoos method to GetFoos<T>()? A method only taking a Type object can easily be converted into a generic method, where you could create the array directly via new T[].
If this is not possible: Do you need the abilities an array offers (ie. indexing and things like Count)? If not, you can work with an IEnumerable<T> without having much of a problem. If not: you won't get around going the Cast<T>.ToArray() way.
Edit:
There is no possible cast from Foo[] to T[], the description in your link is the other way round - you could cast a T[] to a Foo[] as all T are Foo, but not all Foo are T.
If you can arrange for GetFoos to create the return array using new T[], then you win. If you used new Foo[], then the array's type is fixed at that, regardless of the types of the objects it actually holds.
I haven't tried this, but it should work:
T[] array = Array.ConvertAll<Foo, T>(input,
delegate(Foo obj)
{
return (T)obj;
});
You can find more at http://msdn.microsoft.com/en-us/library/exc45z53(v=VS.85).aspx
I think this converts in-place, so it won't be doing any re-allocations.
From what I understand from your situation, using System.Array in place of a more specific array can help you. Remember, Array is the base class for all strongly typed arrays so an Array reference can essentially store any array. You should make your (generic?) dictionary map Type -> Array so you may store any strongly typed array also while not having to worry about needing to convert one array to another, now it's just type casting.
i.e.,
Dictionary<Type, Array> myDict = ...;
Array GetFoos(Type t)
{
// do checks, blah blah blah
return myDict[t];
}
// and a generic helper
T[] GetFoos<T>() where T: Foo
{
return (T[])GetFoos(typeof(T));
}
// then accesses all need casts to the specific type
Foo[] f = (Foo[])GetFoos(typeof(Foo));
DerivedFoo[] df = (DerivedFoo[])GetFoos(typeof(DerivedFoo));
// or with the generic helper
AnotherDerivedFoo[] adf = GetFoos<AnotherDerivedFoo>();
// etc...
p.s., The MSDN link that you provide shows how arrays are covariant. That is, you may store an array of a more derived type in a reference to an array of a base type. What you're trying to achieve here is contravariance (i.e., using an array of a base type in place of an array of a more derived type) which is the other way around and what arrays can't do without doing a conversion.