Clean - Spicery/Nutmeg GitHub Wiki

When a procedure does not make any side-effects, it is said to be clean. Clean procedures are only allowed to call other clean procedures, finesses or functions - none of which can change store or perform I/O, directly or indirectly.

Clean procedures have a lot more freedom than finesses or functions. For example they are allowed to create mutable store and return it (but not mutate it) and they are allowed to take mutable arguments (but not mutate them). Like finesses they are free to use var variables internally and loops too. As a coder, you can declare a procedure to be @clean and the compiler will check this for you. The compiler actually determines the cleanliness of every procedure and uses this information to perform that check.

@clean
def revAppend( x, y ):
    ### x and y may be mutable lists, we don't mind.
    [ y.items(), x.items() ]
end

@clean
def sumList( list ):
    var sofar := 0
    for i in list do
        sofar <- sofar + 1
    endfor
end

Of course assignment is not allowed in pure functional style and you might prefer to explicitly exclude the use of var variables. To do this you require declarations to be val or better with the @inputs(val) annotation, that only allows val or const modifiers.

@clean @inputs(val)
def sumList( list ):
    reduce( nonop +, list, 0 )
end