Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More Operator Overloading #297

Open
eeeey opened this issue Jul 20, 2014 · 9 comments
Open

More Operator Overloading #297

eeeey opened this issue Jul 20, 2014 · 9 comments

Comments

@eeeey
Copy link

eeeey commented Jul 20, 2014

Hi there,

I would like to suggest new language features, namely more operator overloading. It would be nice to be able to overload [] and () operators to create array-like access to data structures and functors. Examples:

package First
    class MyList<T>
        // Some stuff
        function operator[](int index) returns T
            return getEntry(index).elem

    class MyFunctor
        private real memory = 0.0

        function operator()(real r1, real r2) returns real
            memory += r1*r2
            return memory // Just an example

    init
        // Usage operator[]
        MyList<int> list = new MyList<int>()
        print(list[0].toString())

        // Usage operator()
        MyFunctor func = new MyFunctor()
        print(func(2.0, 3.0).toString()) // Displays 6
        print(func(2.0, 3.0).toString()) // Displays 12
        print(func(2.0, 3.0).toString()) // Displays 18 
endpackage

And keep the good work :)

@Frotty
Copy link
Member

Frotty commented Jul 20, 2014

We thought about that some time ago.
While I think [] might have some purposes, the () example only makes the code less readable and harder to understand. (a lot into the Nes' Jass Faction)

Someone else looking at this will have no idea what is actually happing since there is no jumptodecl for [] and ().

Granted, this is the same for the arithmetic operators, but I havn't seen it misused yet and it makes using vector much more easy to read and write.

However writing:

list.get(0).toString()

instead of

list[0].toString()

Doesn't seem as an improvement to me..

Also, Lists are mostly for looping. If you want direct access to values other datatypes are probably faster (like arrays, duh).

@eeeey
Copy link
Author

eeeey commented Jul 20, 2014

Well, the list was more an abstract example. It would be good to have those operators in general, because it really depends on the data structure if those are feasable. Example:

package First
    import HashMap

    init
        HashMap<int, int> map = new HashMap<int, int>()
        map.put(0, map.get(0) + 5)
        map[0] += 5 // Much nicer and readable, right?
endpackage

Or consider a Matrix class where you want to have 2d indexing:

Matrix<int> mat = new Matrix<int>(5, 5) // Create 5x5 Matrix

// Which one is more readable:
mat.set(2, 5, mat.get(2, 5) + 8) // this one
mat[2][5] += 8 // or this one?

// or alternately C# Style:
mat[2, 5] += 8

So actually an operator[] would improve readability a lot more than the +-*/ operators do already. The jumptodecl has the same problem with those aritmetic operators, so thats not really an argument.

Nes' coding is so unreadable because of his excessive macro/module abuse and abuses like faking this pointers and so on. Plus sacrificing everything for speed.

I don't think those operators would lead programmers into this direction. It is always the responsibility of the programmer to make his functions do the "intuitive correct" thing. You can also abuse the arithmetic operators to do completly unintuitive things. Or any other function which has name "doA" but does B instead. Such problems simply can't be avoided by any language, and therefore shouldn't IMHO.

There will be always bad styled code, but this shouldn't limit the capabilities of a language IMO.

@peq
Copy link
Collaborator

peq commented Jul 20, 2014

Overloading [] would be nice, but overloading function application is just too confusing, in my opinion. Jumping to declaration is not a big problem, it could work the same for [] as it does for the currently overloaded operators.

@eeeey
Copy link
Author

eeeey commented Jul 21, 2014

Ok, I guess you are right, operator[] should be enough.

It would just be cool if you could make it so that it can take an arbitrary number of arguments. So that you can for example write for a matrix class something like:

class Matrix<T>
    function operator[](int index) returns T
        skip // for linear indexing of the matrix
    function operator[](int row, int col) returns T
        skip // for 2d indexing of the matrix

init
    Matrix<int> mat = new Matrix<int>(3, 3)

    print(mat[5].toString()) // Access to the linear index 5
    print(mat[2, 3].toString()) // Access to row 2, column 3

Because this way the need of a proxy class to allow 2d-indexing could be avoided.

@Cokemonkey11
Copy link
Collaborator

I'm not a fan of overloading function declaration, but I do like [].

Can we have overloading for <, >, <=, >= operators?

There is a fairly well-defined convention for comparing tuples, for example:

public function vec2.op_lt(vec2 other) returns boolean
    return (this.x < other.x) or (this.x == other.x and this.y < other.y)

@peq
Copy link
Collaborator

peq commented Jan 30, 2016

I think for the comparison operator it would be nicer to link the operators to a comparable interface or type-class. It would feel strange to overload <, >, <=, >= and == with 5 separate functions.

Defining < for vec2 does not make sense in my opinion, because there is no default linear order. Some people might expect that the comparison is done by length instead of lexicographically.

@Cokemonkey11
Copy link
Collaborator

I think for the comparison operator it would be nicer to link the operators to a comparable interface or type-class. It would feel strange to overload <, >, <=, >= and == with 5 separate functions.

Yes, I would be happy with that as well. Seems like more work for you though :P

Defining < for vec2 does not make sense in my opinion, because there is no default linear order. Some people might expect that the comparison is done by length instead of lexicographically.

vec2 always has length of 2. For a template type like pair<T, T>, I agree with you, but for vectors of numbers I think the convention I mentioned above is really quite standard.

Python:

>>> (1, 2) < (1, 3)
True
>>> (3, 1) < (2, 5000)
False
>>> (1, 2) < (2, 1)
True

I did think of one exception - partial ordering https://en.wikipedia.org/wiki/Vector_clock#Partial_ordering_property

I think it makes sense for vec2 to have at least some default ordering.

@peq
Copy link
Collaborator

peq commented Jan 30, 2016

A Python tuple is something more generic. You can use tuples for many different things, so there will be some cases where lexicographical ordering makes sense.

But vec2 is really supposed to be a vector with 2 dimensions and there is no standard ordering for this domain. I also cannot think of an example where you want to ask a question like: "Is the position of unit A less than the position of unit B?". Comparing positions like this just does not make sense.

@Cokemonkey11
Copy link
Collaborator

Okay, I think that's fair. I argue that vec2 isn't necessarily for representing location of unit, but I can see that for the typical use case, having an ordering could do more harm than good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants