How to compare two instances of the same struct in Cadence? - onflow-cadence

I'd like to compare two instances of the same struct to see if their fields have all the same value. I believe that according to the docs the equality operator wont't work on structs.
What would be the right approach here? Writing a custom equals method for the struct?

I believe your instincts are right, a custom equals method would be best. Other languages allow for for custom comparators so you can do things like create your own == operator for structs. But that’s not a feature atm in Cadence, so an equals methods like you suggested would work in this instance.

Related

Documentation comment for loop variable in Xcode

I know that we can use
/// index variable
var i = 0
as a documentation comment for a single variable.
How can we do the same for a loop variable?
The following does not work:
var array = [0]
/// index variable
for i in array.indices {
// ...
}
or
var array = [0]
for /** index variable */ i in array.indices {
// ...
}
Background:
The reason why I don’t use "good" variable names is that I’m implementing a numerical algorithm which is derived using mathematical notation. It has in this case only single letter variable names. In order to better see the connection between the derivation and the implementation I use the same variable names.
Now I want to comment on the variables in code.
The use of /// is primarily intended for use of documenting the API of of a class, struct, etc. in Swift.
So if used before a class, func, a var/let in a class/struct, etc. you are attaching documentation to that code aspect that Xcode understands how to show inline. It doesn’t know how to pickup that information for things inside of function since at this time that is not the intention of /// (it may work for simple var/let but not likely fully on purpose).
Instead use a simple // code comment for the benefit of any those working in the code however avoid over documenting the code since good code is likely fairly self explaining to anyone versed in the language and adding unneeded documentations can get in the way of just reading the code.
This is a good reference for code documentation in Swift at this time Swift Documentation
I woud strongly push back on something like this if I saw it in a PR. i is a massively well adopted "term of art" for loop indices. Generally, if your variable declaration name needs to be commented, you need a better variable name. There are some exceptions, such as when it stores data with complicated uses/invariants that can't be captured in a better way in a type system.
I think commenting is one area that beginners get wrong, mainly from being misled by teachers or by not yet fully understanding the purpose of comments. Comments don't exist to create an english based, psuedo-programming language in which your entire app will be duplicated. Understanding the programming language is a minimal expectation out of contributors to a project. Absolutely no comments should be explaining programming language features. E.g. var x: Int = 0 // declares a new mutable variable called x, to the Int value 0, with the exception of tutorials for learning Swift.
Commenting in this manner might seem like it's helpful, because you could argue it explains things for beginners. That may be the case, but it's suffocating for all other readers. Imagine if novel had to define all the English words they used.
Instead, the goal of documentation to explain the purpose and the use of things. To answer such questions as:
Why did you implement something this way, and not another way?
What purpose does this method serve?
When will this method of my delegate be called?
Case Study: Equatable
For a good example, take a look at the documentation of Equatable
Some things to notice:
It's written for an audience of Swift developers. It uses many things, which it does not explain such as, arrays, strings, constants, variable declaration, assignment, if statements, method calls (such as Array.contains(_:)), string interpolation, the print function.
It explains the general purpose of this protocol.
It explains how to use this protocol
It explains how you can adopt this protocol for your own use
It documents contractual requirements that cannot be enforced by the type system.
Since equality between instances of Equatable types is an equivalence relation, any of your custom types that conform to Equatable must satisfy three conditions, for any values a, b, and c:
a == a is always true (Reflexivity)
a == b implies b == a (Symmetry)
a == b and b == c implies a == c (Transitivity)
It explains possible misconceptions about the protocol ("Equality is Separate From Identity")

Can anyone explain Swift Combine's Subject.eraseToAnySubject() method and where it should be used?

I can see that Subject.eraseToAnySubject() returns the concrete Subject type AnySubject. I'm assuming this is using a type eraser pattern.
However, the apple docs provide almost no details: https://developer.apple.com/documentation/combine/passthroughsubject/3241547-erasetoanysubject
Can anyone explain how this works and where it should be used?
Also, would it be possible to use the some keyword to avoid using AnySubject?
In Combine, as you chain Publishers to Operators, the return type becomes complicated very quickly since it includes specific detail about each publisher in the chain.
For example a simple string Publisher with a filter and map Operator attached will have a return type of: <Filter<Map<Published<String, Error>>>>
eraseToAny uses a type eraser pattern to capture what's actually important about the return type. In the example given, adding an eraseToAnyPublisher will shorten the type to a more succinct <AnyPublisher<String, Error>>

Custom equality for intersection

I'm trying to find the intersection and union between two sequences that have related classes. In order to achieve this I would like to be able to provide a custom equality check to the intersect function. I do not want to override the equals and hashcode function. I would like an intersect function that also takes a function to check for equality.
Is there any clean way to achieve this without writing a custom intersection and union function?
What you're asking is probably not supported by the standard library. It is fairly easy to write your custom intersection/union methods. One other possibility is to wrap your instances like so:
class Wrapper[E](val wrapped: E) {
// Override equals/hashCode here
}
You then compute the union/intersection of Wrapper[E] and then use unionOfWrappers.map(_.wrapped) to get what you wanted. Of course, this will cause many Wrapper instances to be created and garbage collected.

Should I ever prefer operators overloading over functions/methods?

I feel like using operators overloading adds unnecessary complexity and ambiguity to the code.
Does it have its benefits in real-world cases where it's worth to use custom operators or overload existing operators instead of using functions or object methods?
Is it used on a regular basis or more just a funny exotic stuff to add a language a bit more hipness?
The main reason for overloading is comfort of using custom class with mathematic or logic background
like:
vectors
matrices
complex numbers
phasors,tensors,quaternions,...
finite fields
big-numbers (arbnum,biginteger,bigdecimal...)
custom precision floating and fixed formats
predicates,boolean,fuzy and probabilistic
strings,lists,ques
and much much more
If coded right you can write math equations directly and not bother to convert to set of function calls. The reading and understanding math code is much simpler and straightforward with operators.
Sometimes even non strictly math classes are used this way for example images or signals. In DIP/CV there are usually math/physics equations applied on those and overloaded operators make that more simple.
For the non-math classes
are operators usually useless/meaningless (as you feel) except for special operator= which is crucial for any class/struct with dynamic allocation members. Without it things like std:vector<> will not work properly.
Another example are comparison operators which are sometimes implemented for non math classes to make sorting easier.
from wiki
operator overloading—less commonly known as operator ad hoc polymorphism—is a specific case of polymorphism, where different operators have different implementations depending on their arguments
Swift has over 40 operators, all of them are overloaded and we are using them on regular bases. Do you prefer let sum = value.plus(anotherValue) over let sum = value + anotherValue ?? I am sure, you don't! If the value is custom type conforming to protocol Equatable, == operator must be overloaded and we do it regularly.
Is it a good idea to use custom defined operators (like ±, <*> etc ...)? In that area I am not sure. I am not big fan of this ...
Is it a good idea to overload + operator for something else than sum ? No, definitely not!

Where would custom subscripts be suited over methods/functions and why?

I've researched this in Swift and am confused on where custom subscripts are useful compared to methods and functions. What is the power in using them rather than using a method/func?
It's purely stylistic. Use a subscript whenever you'd prefer this syntax:
myObject[mySubscript] = newValue
over this one:
myObject.setValue(newValue, forSubscript: mySubscript)
Subscripts are more concise and, when used in appropriate situations, clearer in intent.
Which is an easier, clearer way to refer to an array element: myArray[1] or myArray.objectAtIndex(1)?
Would you like to saymyArray[1...3], or would it by just fine if you had to say something like myArray.sliceFromIndex(1).throughIndex(3) every time?
And hey, you know what? Arithmetic operators are also just functions. So don't we abandon them, so we'd have to say something like
let sum = a.addedTo(b.multipliedBy(c))
Wouldn't that be just the same really? What's the power in having arithmetic operators really?