Const Parameters By Default?

I've been tinkering around with Rust this past week. It's an interesting language that tries to blend together best practices of C++ as things that are compiler-enforced...and inherits some Haskell for good measure.

It's gotten me back to thinking about how basic choices make a big difference. And I feel like const parameters may make a good logical default. As it stands, people have to annotate functions to say (modifies) in a comment. Wouldn't it be better if you didn't get mutability unless you asked for it?

There could be a compromise for quick-and-dirty functions that if you don't annotate a parameter, then you get things mutable:

 data: [a b c]

 quick: func [blk] [append blk #quick]
 
 >> quick data
 == [a b c #quick]

 not-quick: func [blk [block!]] [
     append blk {You had time to write BLOCK!, why not <mutable> BLOCK!}
 ]

>> not-quick data
** Error: blk is `const`, mark parameters `<mutable>` or see MUTABLE

modifier: func [blk [<mutable> block!]] [
    append blk {Would <mut> be better?}
]

>> modifier data
== [a b c #quick {Would <mut> be better?}]

>> modifier const data
** Error: modifier wants its blk parameter to be mutable

(I have a little bit of a feeling of deja-vu writing this, so I've probably suggested it before.)

Anyway, it seems to me that looking around the language landscape, these kinds of small gestures of control are the least we can do. It would be better in the HELP to see when something modifies, and having it enforced from the beginning would be nice. Note that with BigNum, INTEGER! will be a type that can end up mutable...and it seems like stopping people from writing to integers you pass to routines by default is desirable.

of course, questions come up, e.g. for mixed needs of parameters. If you take a TEXT! or a BLOCK!, but only the BLOCK! is handled as mutable, what option should you use? Someone might have a read-only text and want to call your routine.

A cop-out would be to have some kind of <mixed> or <as-is> annotation that basically doesn't do checks for mutability or constness, and leaves it up to the routine. Not a great answer, but I don't know how often such a circumstance would come up. This could be a near-term option that would evolve into a better solution at some point.

How about
[Text! <mut> block!]
So only after the <mut> things get mutable, or add <nonmut> as well.
I'm unsure how much this would complicate the implementation.
Another idea: it's ok to use the immutable text! as long as the function doesn't write to it.

2 Likes

I think I'd prefer the shorter <mut> as well.