In Kotlin, I can override some existing operators but what about creating new operators? - operator-overloading

In Kotlin, I see I can override some operators, such as + by function plus(), and * by function times() ... but for some things like Sets, the preferred (set theory) symbols/operators don't exist. For example A∩B for intersection and A∪B for union.
I can't seem to define my own operators, there is no clear syntax to say what symbol to use for an operator. For example if I want to make a function for $$ as an operator:
operator fun String.$$(other: String) = "$this !!whatever!! $other"
// or even
operator fun String.whatever(other: String) = "$this !!whatever!! $other" // how do I say this is the $$ symbol?!?
I get the same error for both:
Error:(y, x) Kotlin: 'operator' modifier is inapplicable on this function: illegal function name
What are the rules for what operators can be created or overridden?
Note: this question is intentionally written and answered by the author (Self-Answered Questions), so that the idiomatic answers to commonly asked Kotlin topics are present in SO.

Kotlin only allows a very specific set of operators to be overridden and you cannot change the list of available operators.
You should take care when overriding operators that you try to stay in the spirit of the original operator, or of other common uses of the mathematical symbol. But sometime the typical symbol isn't available. For example set Union ∪ can easily treated as + because conceptually it makes sense and that is a built-in operator Set<T>.plus() already provided by Kotlin, or you could get creative and use an infix function for this case:
// already provided by Kotlin:
// operator fun <T> Set<T>.plus(elements: Iterable<T>): Set<T>
// and now add my new one, lower case 'u' is pretty similar to math symbol ∪
infix fun <T> Set<T>.u(elements: Set<T>): Set<T> = this.plus(elements)
// and therefore use any of...
val union1 = setOf(1,2,5) u setOf(3,6)
val union2 = setOf(1,2,5) + setOf(3,6)
val union3 = setOf(1,2,5) plus setOf(3,6)
Or maybe it is more clear as:
infix fun <T> Set<T>.union(elements: Set<T>): Set<T> = this.plus(elements)
// and therefore
val union4 = setOf(1,2,5) union setOf(3,6)
And continuing with your list of Set operators, intersection is the symbol ∩ so assuming every programmer has a font where letter 'n' looks ∩ we could get away with:
infix fun <T> Set<T>.n(elements: Set<T>): Set<T> = this.intersect(elements)
// and therefore...
val intersect = setOf(1,3,5) n setOf(3,5)
or via operator overloading of * as:
operator fun <T> Set<T>.times(elements: Set<T>): Set<T> = this.intersect(elements)
// and therefore...
val intersect = setOf(1,3,5) * setOf(3,5)
Although you can already use the existing standard library infix function intersect() as:
val intersect = setOf(1,3,5) intersect setOf(3,5)
In cases where you are inventing something new you need to pick the closest operator or function name. For example negating a Set of enums, maybe use - operator (unaryMinus()) or the ! operator (not()):
enum class Things {
ONE, TWO, THREE, FOUR, FIVE
}
operator fun Set<Things>.unaryMinus() = Things.values().toSet().minus(this)
operator fun Set<Things>.not() = Things.values().toSet().minus(this)
// and therefore use any of...
val current = setOf(Things.THREE, Things.FIVE)
println(-current) // [ONE, TWO, FOUR]
println(-(-current)) // [THREE, FIVE]
println(!current) // [ONE, TWO, FOUR]
println(!!current) // [THREE, FIVE]
println(current.not()) // [ONE, TWO, FOUR]
println(current.not().not()) // [THREE, FIVE]
Be thoughtful since operator overloading can be very helpful, or it can lead to confusion and chaos. You have to decide what is best while maintaining code readability. Sometimes the operator is best if it fits the norm for that symbol, or an infix replacement that is similar to the original symbol, or using a descriptive word so that there is no chance of confusion.
Always check the Kotlin Stdlib API Reference because many operators you want might already be defined, or have equivalent extension functions.
One other thing...
And about your $$ operator, technically you can do that as:
infix fun String.`$$`(other: String) = "$this !!whatever!! $other"
But because you need to escape the name of the function, it will be ugly to call:
val text = "you should do" `$$` "you want"
That isn't truly operator overloading and only would work if it is a function that can me made infix.

Related

F#: No abstract property was found that corresponds to this override

Hello fellow Overflowers. I am working on a group project to create a ray tracer that draws a 2D rendering of a 3D scene. The task I am currently on involves matrix transformation of objects (shapes), that need to be moved around, mirrored, sheared etc.
In working with shapes we have chosen to implement an interface that defines the type for a hit function. This hit function is defined in each shape, such as sphere, box, plane etc. When transforming a shape I need to transform the rays that hit the shape and the way to do that seems to be with a higher order function that alters the original hit function.
In order to do this I have implemented the function transformHitFunction, which seems to work, but the new type transformedShape, that implements the Shape interface, is giving me the error
No abstract property was found that corresponds to this override
which doesn't make any sense to me, as it works with other hit functions of the same type. Can anyone spot what's wrong?
I have tried to strip away all modules, namespaces and code that is not relevant to this issue.
type Transformation = Matrix of float [,]
type Vector =
| V of float * float * float
let mkVector x y z = V(x, y, z)
let vgetX (V(x,_,_)) = x
let vgetY (V(_,y,_)) = y
let vgetZ (V(_,_,z)) = z
type Point =
| P of float * float * float
let mkPoint x y z = P(x, y, z)
let pgetX (P(x,_,_)) = x
let pgetY (P(_,y,_)) = y
let pgetZ (P(_,_,z)) = z
type Material = Material
type Texture =
| T of (float -> float -> Material)
type Shape =
abstract member hit: Point * Vector -> (Texture*float*Vector) option
let transformPoint (p:Point) t =
match t with
| Matrix m -> mkPoint ((pgetX(p))*m.[0,0] + (pgetY(p))*m.[0,1] + (pgetZ(p))*m.[0,2] + m.[0,3])
((pgetX(p))*m.[1,0] + (pgetY(p))*m.[1,1] + (pgetZ(p))*m.[1,2] + m.[1,3])
((pgetX(p))*m.[2,0] + (pgetY(p))*m.[2,1] + (pgetZ(p))*m.[2,2] + m.[2,3])
let transformVector (v:Vector) t =
match t with
| Matrix m -> mkVector ((vgetX(v))*m.[0,0] + (vgetY(v))*m.[0,1] + (vgetZ(v))*m.[0,2] + m.[0,3])
((vgetX(v))*m.[1,0] + (vgetY(v))*m.[1,1] + (vgetZ(v))*m.[1,2] + m.[1,3])
((vgetX(v))*m.[2,0] + (vgetY(v))*m.[2,1] + (vgetZ(v))*m.[2,2] + m.[2,3])
let transformHitFunction fn (t:Transformation) =
fun (p:Point,v:Vector) ->
let tp = transformPoint p t
let tv = transformVector v t
match fn(tp,tv) with
| None -> None
| Some (tex:Texture, d:float, n) -> let tn = transformVector n t
Some (tex, d, tn)
type transformedShape (sh:Shape, t:Transformation) =
interface Shape with
member this.hit = transformHitFunction sh.hit t
Short answer
When having problems with implementing or overriding members, provide the argument list exactly as in the abstract or virtual member's definition. (Also, mind your parentheses, because additional parentheses can change the type of a member in subtle ways.)
E.g. in this case: member this.hit (arg1, arg2) = ...
Slightly longer answer
You're encountering a situation in which the difference between F#'s first-class functions and its support of object-oriented style methods is relevant.
For compatibility with the Common Language Infrastructure's (CLI's) object-oriented languages (and object-oriented programming style in F# programs), F# sometimes discriminates between not only functions and values, but even functions in the object-oriented and functional style.
F# uses very similar syntax for two things: the "classical" CLI methods that take an argument list (and also support overloading and optional parameters) versus F#'s own favorite function type FSharpFunc, which always takes one parameter but supports currying and may take multiple parameters via tuples. But the semantics of these two can be different.
The last line of the question tries to pass a function with tupled input to implement a method that takes two arguments the way a method in C# or VB.NET takes them: a CLI method's argument list. Directly assigning an F#-style first-class function won't work here, and nether would a single tuple argument; the compiler insists to get every argument explicitly. If you write the implementation with its complete method argument list, it will work. For example:
member this.hit (arg1, arg2) = transformHitFunction sh.hit t (arg1, arg2)
Another solution would be to declare hit as:
abstract member hit: (Point * Vector -> (Texture*float*Vector) option)
(Note the parentheses!) Now it's a property that contains a first-class function; you can implement it by returning such a function, but the type of the member subtly changed.
The latter is why even implementing the original interface as a single-argument function, e.g. like this:
member this.hit a = transformHitFunction sh.hit t a // error
will not work. More precisely, The compiler will refuse to see a as a tuple. The same issue applies to
member this.hit ((arg1, arg2)) = transformHitFunction sh.hit t (arg1, arg2) // error
What's wrong now? The outer parentheses define the argument list, but the inner parentheses use a tuple pattern to decompose a single argument! So the argument list still has only one argument, and compilation fails. The outermost parentheses and commas when writing methods are a different feature than the tuples used elsewhere, even though the compiler translates between the two in some cases.
At the moment, your transformedShape.hit is a non-indexed property. When invoked, it returns a function that you need to provide with a Point*Vector tuple, and you'll get the result you want. You'll be able to see that better if you add a helper binding: Hover over f here:
type transformedShape (sh:Shape, t:Transformation) =
interface Shape with
member this.hit =
let f = transformHitFunction sh.hit t
f
As others have remarked already, all you need to do is spell out the arguments explicitly, and you're good:
type transformedShape2 (sh:Shape, t:Transformation) =
interface Shape with
member this.hit(p, v) = transformHitFunction sh.hit t (p, v)

How do I turn the Result type into something useful?

I wanted a list of numbers:
auto nums = iota(0, 5000);
Now nums is of type Result. It cannot be cast to int[], and it cannot be used as a drop-in replacement for int[].
It's not very clear from the docs how to actually use an iota as a range. Am I using the wrong function? What's the way to make a "range" in D?
iota, like many functions in Phobos, is lazy. Result is a promise to give you what you need when you need it but no value is actually computed yet. You can pass it to a foreach statement for example like so:
import std.range: iota;
foreach (i ; iota(0, 5000)) {
writeln(i);
}
You don't need it for a simple foreach though:
foreach (i ; 0..5000) {
writeln(i);
}
That aside, it is hopefully clear that iota is useful by itself. Being lazy also allows for costless chaining of transformations:
/* values are computed only once in writeln */
iota(5).map!(x => x*3).writeln;
// [0, 3, 6, 9, 12]
If you need a "real" list of values use array from std.array to delazify it:
int[] myArray = iota(0, 5000).array;
As a side note, be warned that the word range has a specific meaning in D that isn't "range of numbers" but describes a model of iterators much like generators in python. iota is a range (so an iterator) that produced a range (common meaning) of numbers.

Algorithm to evaluate value of Boolean expression

I had programming interview which consisted of 3 interviewers, 45 min each.
While first two interviewers gave me 2-3 short coding questions (i.e reverse linked list, implement rand(7) using rand(5) etc ) third interviewer used whole timeslot for single question:
You are given string representing correctly formed and parenthesized
boolean expression consisting of characters T, F, &, |, !, (, ) an
spaces. T stands for True, F for False, & for logical AND, | for
logical OR, ! for negate. & has greater priority than |. Any of these
chars is followed by a space in input string. I was to evaluate value
of expression and print it (output should be T or F). Example: Input:
! ( T | F & F ) Output: F
I tried to implement variation of Shunting Yard algorithm to solve the problem (to turn input in postfix form, and then to evaluate postfix expression), but failed to code it properly in given timeframe, so I ended up explaining in pseudocode and words what I wanted.
My recruiter said that first two interviewers gave me "HIRE", while third interviewer gave me "NO HIRE", and since the final decision is "logical AND", he thanked me for my time.
My questions:
Do you think that this question is appropriate to code on whiteboard in approx. 40 mins? To me it seems to much code for such a short timeslot and dimensions of whiteboard.
Is there shorter approach than to use Shunting yard algorithm for this problem?
Well, once you have some experience with parsers postfix algorithm is quite simple.
1. From left to right evaluate for each char:
if its operand, push on the stack.
if its operator, pop A, then pop B then push B operand A onto the stack. Last item on the stack will be the result. If there's none or more than one means you're doing it wrong (assuming the postfix notation is valid).
Infix to postfix is quite simple as well. That being said I don't think it's an appropriate task for 40 minutes if You don't know the algorithms. Here is a boolean postfix evaluation method I wrote at some stage (uses Lambda as well):
public static boolean evaluateBool(String s)
{
Stack<Object> stack = new Stack<>();
StringBuilder expression =new StringBuilder(s);
expression.chars().forEach(ch->
{
if(ch=='0') stack.push(false);
else if(ch=='1') stack.push(true);
else if(ch=='A'||ch=='R'||ch=='X')
{
boolean op1 = (boolean) stack.pop();
boolean op2 = (boolean) stack.pop();
switch(ch)
{
case 'A' : stack.push(op2&&op1); break;
case 'R' : stack.push(op2||op1); break;
case 'X' : stack.push(op2^op1); break;
}//endSwitch
}else
if(ch=='N')
{
boolean op1 = (boolean) stack.pop();
stack.push(!op1);
}//endIF
});
return (boolean) stack.pop();
}
In your case to make it working (with that snippet) you would first have to parse the expression and replace special characters like "!","|","^" etc with something plain like letters or just use integer char value in your if cases.

Scala closures on wikipedia

Found the following snippet on the Closure page on wikipedia
//# Return a list of all books with at least 'threshold' copies sold.
def bestSellingBooks(threshold: Int) = bookList.filter(book => book.sales >= threshold)
//# or
def bestSellingBooks(threshold: Int) = bookList.filter(_.sales >= threshold)
Correct me if I'm wrong, but this isn't a closure? It is a function literal, an anynomous function, a lambda function, but not a closure?
Well... if you want to be technical, this is a function literal which is translated at runtime into a closure, closing the open terms (binding them to a val/var in the scope of the function literal). Also, in the context of this function literal (_.sales >= threshold), threshold is a free variable, as the function literal itself doesn't give it any meaning. By itself, _.sales >= threshold is an open term At runtime, it is bound to the local variable of the function, each time the function is called.
Take this function for example, generating closures:
def makeIncrementer(inc: Int): (Int => Int) = (x: Int) => x + inc
At runtime, the following code produces 3 closures. It's also interesting to note that b and c are not the same closure (b == c gives false).
val a = makeIncrementer(10)
val b = makeIncrementer(20)
val c = makeIncrementer(20)
I still think the example given on wikipedia is a good one, albeit not quite covering the whole story. It's quite hard giving an example of actual closures by the strictest definition without actually a memory dump of a program running. It's the same with the class-object relation. You usually give an example of an object by defining a class Foo { ... and then instantiating it with val f = new Foo, saying that f is the object.
-- Flaviu Cipcigan
Notes:
Reference: Programming in Scala, Martin Odersky, Lex Spoon, Bill Venners
Code compiled with Scala version 2.7.5.final running on Java 1.6.0_14.
I'm not entirely sure, but I think you're right. Doesn't a closure require state (I guess free variables...)?
Or maybe the bookList is the free variable?
As far as I understand, this is a closure that contains a formal parameter, threshold and context variable, bookList, from the enclosing scope. So the return value(List[Any]) of the function may change while applying the filter predicate function. It is varying based on the elements of List(bookList) variable from the context.

Why does Scala's semicolon inference fail here?

On compiling the following code with Scala 2.7.3,
package spoj
object Prime1 {
def main(args: Array[String]) {
def isPrime(n: Int) = (n != 1) && (2 to n/2 forall (n % _ != 0))
val read = new java.util.Scanner(System.in)
var nTests = read nextInt // [*]
while(nTests > 0) {
val (start, end) = (read nextInt, read nextInt)
start to end filter(isPrime(_)) foreach println
println
nTests -= 1
}
}
}
I get the following compile time error :
PRIME1.scala:8: error: illegal start of simple expression
while(nTests > 0) {
^
PRIME1.scala:14: error: block must end in result expression, not in definition
}
^
two errors found
When I add a semicolon at the end of the line commented as [*], the program compiles fine. Can anyone please explain why does Scala's semicolon inference fail to work on that particular line?
Is it because scala is assuming that you are using the syntax a foo b (equivalent to a.foo(b)) in your call to readInt. That is, it assumes that the while loop is the argument to readInt (recall that every expression has a type) and hence the last statement is a declaration:
var ntests = read nextInt x
wherex is your while block.
I must say that, as a point of preference, I've now returned to using the usual a.foo(b) syntax over a foo b unless specifically working with a DSL which was designed with that use in mind (like actors' a ! b). It makes things much clearer in general and you don't get bitten by weird stuff like this!
Additional comment to the answer by oxbow_lakes...
var ntests = read nextInt()
Should fix things for you as an alternative to the semicolon
To add a little more about the semicolon inference, Scala actually does this in two stages. First it infers a special token called nl by the language spec. The parser allows nl to be used as a statement separator, as well as semicolons. However, nl is also permitted in a few other places by the grammar. In particular, a single nl is allowed after infix operators when the first token on the next line can start an expression -- and while can start an expression, which is why it interprets it that way. Unfortunately, although while can start a expression, a while statement cannot be used in an infix expression, hence the error. Personally, it seems a rather quirky way for the parser to work, but there's quite plausibly a sane rationale behind it for all I know!
As yet another option to the others suggested, putting a blank newline between your [*] line and the while line will also fix the problem, because only a single nl is permitted after infix operators, so multiple nls forces a different interpretation by the parser.