Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Const methods

A procedure that takes an object byref as const promises not to change it. That promise is only useful if the compiler can tell which of the object's methods keep it, and a const method is one that does.

type Rect
    declare const function Area( ) as float64     '' promises not to
    declare const function Describe( ) as ustring '' change the object
    declare sub Scale( byval k as float64 )
    w as float64
    h as float64
end type

const function Rect.Area( ) as float64
    return w * h
end function

'' A const method may call other const methods.
const function Rect.Describe( ) as ustring
    return w & " x " & h & ", area " & Area( )
end function

sub Rect.Scale( byval k as float64 )
    w *= k
    h *= k
end sub

'' A const parameter can be read, and its const methods called.
sub Report( byref r as const Rect )
    print "  "; r.Describe( )
end sub

dim as Rect r = ( 2, 3 )
Report( r )
r.Scale( 2 )                        '' an ordinary object can change
Report( r )

Output

  2 x 3, area 6
  4 x 6, area 24

declare const function Area( ) marks Area as a method that reads the object but never writes it, and the definition repeats the word: const function Rect.Area( ). Inside, the compiler holds the method to its promise: assigning a field w is refused with TKO0664: 'w' cannot be written from a const method, and calling Scale from it with TKO0665: a const method cannot call the non-const method 'scale'.

Report takes its rectangle byref as const, so it receives the caller's object without a copy and may not change it. It may call Describe and Area, which are const. Calling Scale is refused:

type Rect
    declare const function Area( ) as float64
    declare sub Scale( byval k as float64 )
    w as float64
    h as float64
end type

const function Rect.Area( ) as float64
    return w * h
end function

sub Rect.Scale( byval k as float64 )
    w *= k
    h *= k
end sub

sub Report( byref r as const Rect )
    print r.Area( )                 '' fine: Area is const
    r.Scale( 2 )                    '' refused: Scale is not
end sub
constcall.tiko(19,6): error TKO0935: 'scale' is not a const method, so a const object cannot call it
     |
  19 |     r.Scale( 2 )                    '' refused: Scale is not
     |      ^

Mark every method that only reads as const. A method left unmarked cannot be called on a const object at all, even though it changes nothing, and every procedure that takes the type byref as const loses it.

Activities

  1. Remove const from Describe and read the error. Which call does the compiler point at?
  2. Add a const function IsSquare( ) as boolean and call it from Report.