Why no stored type properties for classes in swift? - language-design

Working through The Swift Programming Language, I was surprised to see that, unlike structures and enumerations, classes do not support stored type properties.
This is a common feature of other OO languages so I assume there was a good reason they decided not to allow it. But I'm not able to guess what that reason is, especially since structures (and enumerations) have them.
Is it simply that it's early times for Swift and it just hasn't been implemented yet? Or is there a deeper reason behind language design decision?
BTW, "stored type property" is Swift terminology. In other languages these might be called class variables. Example code:
struct FooStruct {
static var storedTypeProp = "struct stored property is OK"
}
FooStruct.storedTypeProp // evaluates to "struct stored property is OK"
class FooClass {
class var computedClassProp: String { return "computed class property is OK" }
// class var storedClassProp = "class property not OK" // this won't compile
}
FooClass.computedClassProp // evaluates to "computed class property is OK"
Edit:
I now realize this limitation is trivial to work around, e.g., by using a nested structure with stored properties:
class Foo {
struct Stored {
static var prop1 = "a stored prop"
}
}
Foo.Stored.prop1 // evaluates to "a stored prop"
Foo.Stored.prop1 = "new value"
Foo.Stored.prop1 // evaluates to "new value"
That seems to preclude their being some deep inscrutable language design reason for this limitation.
Given that and the wording of the compiler message that Martin Gordon mentions, I have to conclude that this is simply something (minor) left out.

The compiler error is "Class variables not yet supported" so it seems like they just haven't implemented it yet.

Extending the OP's nested struct trick for simulating stored type properties, you can go further and make it look like a pure stored type property from outside the class.
Use a computed getter and setter pair like:
class ClassWithTypeProperty
{
struct StoredTypeProperties
{
static var aTypeProperty: String = "hello world"
}
class var aTypeProperty: String
{
get { return self.StoredTypeProperties.aTypeProperty }
set { self.StoredTypeProperties.aTypeProperty = newValue }
}
}
Then you can do:
println(ClassWithTypeProperty.aTypeProperty)
// Prints "hello world"
ClassWithTypeProperty.aTypeProperty = "goodbye cruel world"
println(ClassWithTypeProperty.aTypeProperty)
// Prints "goodbye cruel world"

“For value types (that is, structures and enumerations), you can define stored and computed type properties. For classes, you can define computed type properties only."
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/cn/jEUH0.l
I think it's easy for Apple's Engineers to add stored type properties to classes, but not yet we know, maybe never in my opinion. And that's why there are labels ( static and class ) to distinguish them.
The most important reason may be it:
To avoid different objects have shared changeable variable
we know :
static let storedTypeProperty = "StringSample" // in struct or enum ...
can be replaced by
class var storedTypeProperty:String {return "StringSample" } // in class
but
static var storedTypeProperty = "StringSample"
is harder to be replaced by class phrase in class.
// I am new to Swift Programming Language actually and it's my first answer in Stack OverFlow. Glad to discuss with you. ^^

Related

Kotlin: variable in enum class can't be changed after initialization

When writing this example into the IDE:
enum class EnumTest {
FOO, BAR;
lateinit var foobar: String
}
I get the message With old Native GC, variable in enum class can't be changed after initialization on the "foobar" variable. I can't find anything about this message online. Also everything seems to work just fine, so my question is:
When and how does this affect me?
Thank you!
You could declare your values in a singleton object, set them there and reference it in the enum.
object Constants {
var FOO_STR = "bla"
var BAR_STR = "bar"
}
enum class EnumTest(val foobar: String) {
FOO(Constants.FOO_STR),
BAR(Constants.BAR_STR);
}
This code should work but also smells fishy.
Since an enum has an immutable flavor by design, I would not recommend this approach. I feel bad about posting this... but if your main problem is the resource heavy loading of these constants, maybe you do not need an enum to store those properties. Maybe just think of a simple singleton container with simple (named) properties.

Kotlin variables that are not in scope?

On https://github.com/mozilla/rust-android-gradle/blob/8183f9e927336011c7c09d75efd4f5f411940db1/plugin/src/main/kotlin/com/nishtahir/CargoBuildTask.kt#L19 we have this kotlin code:
open class CargoBuildTask : DefaultTask() {
var toolchain: Toolchain? = null
#Suppress("unused")
#TaskAction
fun build() = with(project) {
extensions[CargoExtension::class].apply {
I'm very confused as from where does extensions come from, as well as project. They aren't local variables, they aren't in a scope or something. What are they?
Inheritance is the answer to project.
CargoBuildTask : DefaultTask()
Do you see how CargoBuildTask inherits properties of DefaultTask?
Thus project is a property from DefaultTask. However, extensions is a property from project which is of Type Project.
Read this documentation on DefaultTask and you will have more understanding.
Kotlin's with is the answer to extensions.
In short, with with you can invoke methods without explicitly stating its subject. (Read more here)
For example, these two code snippets mean the exact same thing:
with("string") {
substring(3) //invoke method without subject
}
"string".substring(3) //Same as above
Here is the method from org.gradle.api.Project
ExtensionContainer getExtensions();
Now, If you are wondering how Java's getExtensions() turned into Kotlin's extensions, read this. Basically states that traditional Getters and Setters in Java are interpreted as Properties in Kotlin.
PS: If you are unsure of what Inheritance is in OOP/Kotlin, read this.
The projectcomes from the DefaultTask() inherited in the current class. Inheritance is used here which is a very basic concept. Read more about Kotlin's inheritance here.
The extensions comes from project using with which is one of the scope functions.
Read more about with here.
.
For example. Suppose you've a Data class.
data class PersonModel(val name: String, var age: Int)
And you create a model of it as
val personModel = PersonModel("Adam", 30)
Now, if you pass it to a with function as a reciever, you can access 'personModel`'s properties directly in the with's scope as:
with(personModel) {
//name is the property of personModel
val nameWas = name
//Declared var and can be editable.
age = 31
}
with works with functions as well where you can pass a function as a reciever to it and it returns the returned value of the function.
These scope functions (let, run, with, apply, also) are extremely useful in production environment.

Kotlin: does it make sense a property with private get and public set?

I am new to Kotlin, and I have been experimenting with the language. In Kotlin in Action, it says the following:
The accessor’s visibility by default is the same as the property’s. But you can change
this if you need to, by putting a visibility modifier before the get or set keyword.
I have tried to create a property that has a private getter and a public setter, as follows:
class BackingField {
var aProperty = 1
private get
set(value) {
field = value + 1
}
}
However, IntelliJ is suggesting me to remove the private modifier before get. Is is possible to have a public property with a private getter and a public setter? If so, what are some common applications of such entity? If not, could we conclude that what is stated in the book is partially wrong?
The book is not wrong per se. Because you can actually change the visibility on both the get and set but the set can't be more visible than the get according to this question:
Private getter and public setter for a Kotlin property
Remember that books and IDEs offer recomendations and not good design based on what you do.
The set can't be more visible than the get, as other said, but then remember that properties and backing fields is just an abstraction. You can have no backing field and declare your interface setter and getter methods with the access restrictions you wish for.
Given this use case, it's obvious that you have special requirements. I.e. the data is not just set, but also incremented by 1. So your external interface would probably have another name for it as well.
Having the syntac object.field = x invoke a setter function is suspect as well, cause the syntax implies no function invocation, as in java or C/C++ structs. it can bite you horribly and make you miss the fact that the assignment invokes a setter somewhere in your code - I would consider it bad design.
The feature of properties and getters/setters works mostly if you are working with data objects and pokos (plain old kotlin objects) only. It's very good for those cases, and can save you time, but once you stray off into more complex scenarios, as you are doing, it's weakness will begin to show.
In this case you don't need a setter, because the class will have access to it privately. The getter though, is something you have to define, and perhaps give a more apropriate name, like setAndIncrement.
class BackingField {
private var aProperty = 1
fun setAProperty(value:Int) { aProperty=value+1}
private fun getAProperty():Int { return aProperty }
fun print() {println(aProperty)}
}
fun main() {
var f = BackingField()
f.print()
f.setAProperty(10)
f.print()
println(f.aProperty) // Won't compile
}

Getter setter in C# VS2017

I've been starting to use VS2017 Community. This bugs me:
Below is normal getter setter from previous VS:
public string Name
{
get{ return _name;}
set{ _name = value;}
}
This is the new getter setter:
public string Name { get => _name; set => _name = value; }
Anyone can explain to me why the syntax is changed?
I wouldn't say they changed it, I would say they gave us some new syntax options. You can still use the "old" way of declaring getters and setters, but there is now also a more functional programming style of doing it as well. In C#6 Microsoft already introduced using expressions for getter only properties doing:
public int SomeProp => someMethod();
C#7 enhanced this support allowing it to be used for getters AND setters. One nice feature of this is with the new "throw expressions" feature which allows us to make some concise syntax. For example, before you had to do.
private string _name;
public string Name
{
get
{
return _name;
}
set
{
if (value == null)
throw new ArgumentNullException(nameof(Name));
_name = value;
}
}
We can now simplify this to:
private string _name;
public string Name {
get => _name;
set => _name = value ?? throw new ArgumentNullException(nameof(Name));
}
Granted, you could do the throw expression even without making the setter a lambda, but as you can see, for simple things, it makes the syntax very concise.
As with anything, use the syntax that makes the most sense to you and is most readable for the people who will be coding your application. Microsoft has been making a push to add more and more functional programming style features to C# and this is just another example of that. If you find it ugly/confusing/not needed, you can absolutely accomplish everything you need with the existing method. As another example, why do we have while and do while loops? I can honestly say I've used a do while loop maybe 5 times in my career. A while loop can do everything a do while can just with different syntax. However, there are sometimes where you realize that using a do while will make your code more readable, so why not use it if it makes things easier to follow?
The syntax hasn't changed: it has been improved. C# has been always backwards-compatible with syntax and grammar from previous versions.
Why property getters/setters can be implemented with lambda syntax (expression-bodied accessors)? Probably there's no scientific reason to do so, but there's a consensus about introducing useful functional programming constructs in C# as it turns the language into a more productive tool.
Just foillow up C#'s evolution since C# 2.0:
From delegates provided as regular methods to anonymous delegates.
LINQ, lambda-style delegates/expression trees.
Expression-bodied methods.
...and expression-bodied accessors! And probably future C# versions will introduce even more functional programming-style syntax and grammar.
You'll notice they removed the 'return' syntax, this was done (from what I've read) to make it more clear that they aren't functions (and when reflected can't be treated as functions and can't be made into delegates) but rather this kind of 'pseudo-function' (if you get what I'm trying to well get at).
So basically its to make it more clear that the getter is linking this this variable and the repeating for the setter. It also is because in newer versions you can do something like
public int MyInt => x ? y:z;
Which represents
public int MyInt
{
get
{
return x ? y:z;
}
}
Also both syntax should work, its just a new syntax that they added to bring it in line with the above example.
I know I am adding this details after a year, but just understood that my VS 2017 generated new syntax on my web user control, and that does not reflect on the aspx file when I wanted to set a value for it.
like
private bool _ShowBankDetailPanel = false; //To Show Bank details section in registration
public bool ShowBankDetailPanel { get => _ShowBankDetailPanel; set => _ShowBankDetailPanel = value; }
and on ASPX side you will NOT have property like
it is only recognize
old style getter setter....(I experience this,,, but I am be wrong)

c++/cli reference to property

Well, I haven't yet found something that says this is impossible, though I'm starting to think it might be. Can you make this work?
using namespace System;
template <typename T>
void unset(Nullable<T>& var) { var = Nullable<T>(); }
void unset(String^% var) { var=nullptr; }
//this is really a C# class in my situation, so I can't change its types
public ref class Foo
{
public:
property Nullable<Decimal> Dec;
property Nullable<int> Num;
property String^ Str;
};
int main()
{
Foo^ foo = gcnew Foo;
foo->Dec = Decimal(1.2);
foo->Num = 3;
foo->Str = "hi";
unset(foo->Dec);
unset(foo->Num);
unset(foo->Str);
Console::WriteLine(foo->Dec);
Console::WriteLine(foo->Num);
Console::WriteLine(foo->Str);
}
Update: unset is called from a code-generating macro which is called on about 50 params. I'd prefer not to have to go make varieties of the macro for each type.
It isn't possible. Setting a property requires calling the property setter function. There is no way to guess for the called method that it needs to call a function vs can assign the passed variable pointer. If you really want to do this then pass a delegate.
There is actually one .NET language that supports it, VB.NET generates code like this:
T temp = obj->prop;
func(temp)
obj->prop = temp;
There is however a dreadful aliasing problem with that, quite undebuggable. This goes belly up in the (rare) case where func() also uses the property. This is otherwise the way you'd work around the limitation, explicitly in your own code.
Beware that your code is wrong, possibly intentional, you are passing a C++ & reference, not a managed % interior pointer. The compiler is going to bitch about that, you can't create references or pointers to managed objects. They move. Unless the reference is to a variable on the stack. It doesn't otherwise change the answer.
For those who may end up here wondering how I got on with this, I ended up being lucky that the class I was working with was an LLBLGen Entity, so I was able to replace
unset(re->var);
with
{ SD::LLBLGen::Pro::ORMSupportClasses::IEntityField2^ f = re->Fields[#var]; \
if (f->IsNullable) \
f->CurrentValue = nullptr; }