I'm trying to make an immutable POINT class in Eiffel. Is the code below defines one? The {NONE} accessibility for the x and y fields is enough for it? Can I write something to the class invariant like x = x', or how else can I achieve immutability?
class POINT
    create
        make
    feature {NONE}
        x: DOUBLE
        y: DOUBLE
    feature
        make (x_: DOUBLE; y_: DOUBLE)
        do
            x := x_
            y := y_
        ensure
            set: x = x_ and y = y_
        end
    feature --accessors
        get_x: DOUBLE
        do
            Result := x
        ensure
            Result = x
        end
    end
 
                        
Eiffel does not allow to change attributes of a class by its clients. For example, the following code is rejected:
As a result, there is no need to provide getters (like in some other languages). You can just use
p.xprovided thatxis sufficiently exported to a client class. So, the code of your example can be simplified toNote that the creation procedure is not exported anymore, otherwise it would be possible to use it as a normal (i.e. non-creation) routine and to change the attributes, that is we would be able to do something as follows
and this would print
(2, 3), i.e. you would be able to change the value of the original objectp, making it mutable.Though, now the attributes cannot be changed directly, it's still possible to call feature
copyon an object of typePOINTand to change the whole object. If you want to avoid this situation as well, the feature can be redefined in the classPOINTto raise an exception, or even to have a postconditionFalsecausing the run-time to raise an exception for you: