Provide #property for const and non-const structures in D - properties

I define a simple struct this way:
struct Person{
private string _name;
#property ref string name() { return _name; }
}
The #property annotation is really cool, but I don't know how should I use it properly.
The above is quite ok, but I cannot pass a Person to a function requiring in Person for instance:
void fun(in Person p) { ... }
To avoid copying Person I have to declare the parameter with ref, though I don't modify it.
So how to combine the property syntax with const-correctness?
edit:
To follow up, can the same apply to looping?
void fun(in Person[] people) {
foreach(Person p; people) { ... }
}
now I don't want to copy person, but I can't use ref Person since it's const. So I have to write ref const(Person) p in the loop which becomes loong.

Normally, what you'd do would be
#property string name() const { return _name; }
#property void name(string value) { _name = value; }
and you wouldn't bother with ref (certainly, for a string, there isn't much point). For more complex types that you want to avoid copying, you can return by const ref, e.g.
#property ref const(Foo) foo() const { return _foo; }
#property void foo(Foo value) { _foo = value; }
You could overload the setter so that it accepted ref Foo in addition to Foo, but there isn't much point, since you'd be copying the passed in Foo to assign it to _foo anyway.
And if you really want to, you can return by ref from the getter and overload it, e.g.
#property ref const(Foo) foo() const { return _foo; }
#property ref Foo foo() { _foo; }
in which case the non-const overload can be used as a setter, but if you're going to do that, why bother with a property? At that point, you might as well just make the member variable public, because the property isn't protecting it at all. By returning non-const ref, you've lost control over how the member variable is set and have effectively exposed it as a public member variable except that you have the extra plumbing of the function around it. The only advantages that it gives you are that you can do something before returning and that the type's invariant (if any) will be called when the property is called (whereas it won't with a public member variable), but because the variable can be set without you're control at that point, those benefits are of questionable value in comparison to the simplicity of simply making the member variable public.
So, in general, the first example is the way to go, and once in a while, the second is better, but it's arguably pointless to go with the third example.
EDIT:
As Kozzi11 points out, you can implement the 3rd example as
#property auto ref foo() inout { return _foo; }
or
#property ref inout(Foo) foo() inout { return _foo; }
instead of having two functions, but my point about it not really being much better than a public member variable still applies.
EDIT 2: With regards to your edit to the question...
If you want to avoid copying in the loop, you're going to have to be explicit with the type.
foreach(p; people) { ... }
will work, but it will copy each individual Person as it iterates over people, whereas
foreach(ref Person p; people) { ...}
or
foreach(ref const(Person) p; people) { ...}
will avoid copying each Person.

What about this:
import std.stdio;
void someFun(in Person person) {
writeln(person.name);
}
struct Person {
private string _name;
#property auto ref name() inout { return _name; }
}
void main(string[] args)
{
auto person = Person("Osoba Nova");
someFun(person);
stdin.readln;
}
EDIT: for loop you can ommit type
void fun(in Person[] people) {
foreach (p; people) {
writeln(p.name);
}
}

a property function is just a function, so you can overload it.
#property ref const(string) name() const { return name_; }
#property ref string name() { return name_; }

Related

How to skip defined getters or setters in Kotlin

In java you can do the follwing:
public class Foo {
private String bar = "text";
public void method() {
// direct access (no logic)
System.out.println(this.bar);
}
// only if you access the object from the outside
// you are forced to use the getter with some logic in it
public String getBar() {
System.out.println(this.bar);
return this.bar;
}
}
But if you define a getter or a setter with logic in Kotlin you are forced to always execute this logic when accessing the field:
class Foo {
var bar: String = "text"
get() {
println(field)
return field
}
private set
fun method() {
// this also executes the getter
// Is it possible to skip the getter
// and directly access the field?
println(this.bar)
}
}
Is there a better way to access the field without executing the getter or setter logic than creating your own fun getBar() in Kotlin?
There is no possible way to skip a getter or a setter, they are intended to block the direct access of a property.
What you can do is make a multi-reference to same value (fake-referencing):
private var _bar: String = "text"
var bar
get() {
// some operations intercepting the getter
return _bar
}
// direct access
_bar
// intercepted access public field
bar
In Kotlin the backing fields (in your case the private variable) are not exposed by design. There are a few exceptions explained here: https://kotlinlang.org/docs/reference/properties.html#backing-fields
All access to val and var happens through implicit getters and setters. A val resolves to a property with a getter() while var resolves to a property with a getter and a setter: https://kotlinlang.org/docs/reference/properties.html#properties-and-fields

OOP Observer Pattern: call notifyListener from outside of the subject

Is it ok for an Observer object to call notifyListeners() on an observable after changing some of its fields? What disadvantages could arise? Usually it's the subjects' responsibility to notify listeners of changes.
I frequently come across the following problem when wrapping model classes in an observable / subject e.g. to make them accessible in UI.
Should my subject notify its listeners whenever any field of the model object is changed or should I provide some kind of method setModel() that takes a new model object as an argument and only then notifies all listeners?
For example:
class MyData {
String myString;
int myInt;
}
class MyDataObservable {
private MyData data;
// constructor
void setString(String string) {
data.myString = string;
notifyListeners();
}
void setInt(int num) {
data.myInt = num;
notifyListeners();
}
void notifyListeners() {...}
void addListener(Observer o) {...}
}
I don't like that my subject basically mirrors all the properties of my model .. which is pretty ugly.
class MyDataObservable {
private MyData data;
// constructor
void setData(MyData data) {
this.data = data;
notifyListeners();
}
void notifyListeners() {...}
void addListener(Observer o) {...}
}
The downside of this approach is that I have to build a new copy of my data class everytime anything changes, even if it's just a bool flag on my model class.
So my idea was to allow for observers to notify other listeners when they changed something with e.g. an update function.
Are there other, more elegant alternatives?
EDIT
At the moment, making my data class an observable is not an option because I'm using a framework that provides an observable mechanism that can also hold business logic. For that reason I want to decouple my data class and the logic / observable.
In this case I would use inheritance rather than composition: MyData is-a Observable rather than Observable has-a MyData.
class Observable {
Collection<Listener> listeners
void addListener(Listener l) {...}
void notifyListeners() {...}
}
class MyData extends Observable {
String myString;
int myInt;
void setString(String string) {
this.myString = string;
notifyListeners();
}
void setInt(int num) {
this.myInt = num;
notifyListeners();
}
}

ReactiveCocoa: creating a signal that applies a map over an observer

From what I understand, the RACSubject equivalent of ReactiveCocoa 4 is the Observer class.
I want to have a signal and an observer linked together so that the signal sends events applying a map operation to the events sent to the observer.
In Obj-C it looks like this:
// ViewModel.h
#interface ViewModel
#property (readonly) RACSubject *someAction; //expects e.g. int values
#property (readonly) RACSignal *someSignal; //sends e.g. string values
#end
// ViewModel.m
//redeclaring the signal and action as readwrite
#implementation
- (id)init {
_someAction = [RACSubject subject];
_someSignal = [_someAction map:^id(NSNumber *index) {
return "Some string based on index passed in";
}];
}
#end
Now when someone pushes a value onto someAction, the someSignal will fire an event containing a derived value.
How do I achieve the same effect in Swift?
What I've been able to do so far is something like this:
public class ViewModel: NSObject {
public let (internalSignal, someAction) = Signal<Int, NoError>.pipe()
public var someSignal: Signal<String, NoError> {
get {
return self.internalSignal.map({ [unowned self](index: Int) -> String in
return "Some string value based on \(self.someArray[index])"
})
}
}
public let someArray = [1, 2, 3, 4, 5]
}
Which looks like a bad solution because
internalSignal should be private but needs to be declared public in order to match it to Signal's pipe
someSignal is computed every time it's needed therefore, even though the same signal could be reused over and over. Also can't be declared as a let constant.
You could initialize the members in init just like ObjC...
public class ViewModel: NSObject {
private let internalSignal: Signal<Int, NoError>
public let someAction: Observer<Int, NoError>
public let someSignal: Signal<String, NoError>
override init() {
(internalSignal, someAction) = Signal<Int, NoError>.pipe()
someSignal = internalSignal.map { index in
"Some string value based on \(index)"
}
super.init()
}
}
For someSignal you could also use lazy initialization, which allows the member to refer to self:
public class ViewModel: NSObject {
private let internalSignal: Signal<Int, NoError>
public let someAction: Observer<Int, NoError>
public private(set) lazy var someSignal: Signal<String, NoError> =
self.internalSignal.map { [unowned self] index in
"Some string value based on \(self.someArray[index])"
}
override init() {
(internalSignal, someAction) = Signal<Int, NoError>.pipe()
super.init()
}
}
Unlike the first piece of code, the lazy-var is initialized only before someSignal is used, not at the ViewModel's initialization.
Also, since it is a var, Swift allows you use mutate its value (there is no such thing as lazy let). We can restrict the permission using private(set), but this won't prevent you accidentally write self.someSignal = ... somewhere.
Alternatively, you could make someSignal an implicitly unwrapped optional and initialize manually:
public class ViewModel: NSObject {
private let internalSignal: Signal<Int, NoError>
public let someAction: Observer<Int, NoError>
public private(set) var someSignal: Signal<String, NoError>!
override init() {
(internalSignal, someAction) = Signal<Int, NoError>.pipe()
super.init()
someSignal = internalSignal.map { [unowned self] index in
"Some string value based on \(self.someArray[index])"
}
}
}

Access the getter and setter of a typescript property

I have a question about typescript properties: Is it possible to get the setter and getter of a typescript property or to declare a function argument to be of a property of X type?
The reason is to get some sort of "reference" to a variable which is not possible in plain JS without writing getter/setter wrappers or access the variable via parent object itself (obj["varname"]).
For example (with some working code and other parts speculative):
//A sample class with a property
class DataClass<T> {
private T val;
public get value(): T {
return this.val;
}
public set value(value: T) {
this.val = value;
}
}
//Different ways of modifing a member "by reference"
class ModifyRef {
public static void DoSomethingByGetterAndSetter(getter: () => string, setter: (val: string) => void) {
var oldValue = getter();
setter("new value by DoSomethingByGetterAndSetter");
}
public static void DoSomethingByObject(obj: Object, name: string) {
var oldValue = obj[name];
obj[name] = "new value by DoSomethingByObject";
}
//Is something like this possible?
public static void DoSomethingByProperty(somePropery: property<string>) {
var oldVlaue = someProperty;
someProperty = "new value by DoSomethingByProperty";
}
}
var inst = new DataClass<string>();
//Calling the DoSomethingByProperty if possible
ModifyRef.DoSomethingByProperty(inst.value);
//Or if not is something like this possible
ModifyRef.DoSomethingByGetterAndSetter(inst.value.get, inst.value.set);
The simplest way to do this would be to provide methods, rather than a property:
//A sample class with a property
class DataClass<T> {
private val: T;
public getValue(): T {
return this.val;
}
public setValue(value: T) {
this.val = value;
}
}
class ModifyRef {
public static DoSomethingByGetterAndSetter(getter: () => string, setter: (val: string) => void) {
var oldValue = getter();
setter("new value by DoSomethingByGetterAndSetter");
}
}
var inst = new DataClass<string>();
//Or if not is something like this possible
ModifyRef.DoSomethingByGetterAndSetter(inst.getValue, inst.setValue);
I've long found it very surprising that languages with properties don't include a convenient way to make a reference to a property, and have daydreamed about having this feature in C#. It ought to work on local variables as well.
A popular pattern for this kind of first-class or reified property is a single function that can be called in two ways:
no arguments: returns current value.
one argument: sets value, returns undefined.
Or in TypeScript terms:
interface Property<T> {
(): T;
(newVal: T): void;
}
The methods of jQuery objects often work like this. An example of this pattern in modelling pure data is in Knockout, in which such properties also support change subscriptions, and there's a rather elegant pattern for defining computed properties that automatically recompute when their dependencies change.

Computed property of closures

I would like to use a closure as a computed property. I mean something like the code below.
class MyClass {
typealias myFuncType = () -> (Void)
private var _myAction:myFuncType
var myAction:myFuncType = {
set(newAction){
self._myAction = newAction
}
}
}
Is it possible or will the compiler think that as I opened a bracked it must be the closure definition?
Closures (and functions) are advertised as first class citizens in swift, so you can store them in variables and properties like any other data type.
That said, your code is almost good, you just have to remove the '=' because otherwise it's considered as a stored property with inline initialization. The correct code is:
var myAction:myFuncType {
set(newAction) {
self._myAction = newAction
}
get { // see notes below
return _myAction
}
}
Some notes:
there's no need to use a computed property backed by a stored property - your code is equivalent to:
class MyClass {
typealias myFuncType = () -> (Void)
var myAction: myFuncType
}
if you need to make additional processing when setting the property, make use of Property Observers: willSet and didSet
in a computed property, if you implement a setter, you must also provide a getter