Parameter Order in Rebol

With the advent of Point-Free expression, things that were wordy using SPECIALIZE are now succinct. You don't have to name the parameters...which saves typing and also keeps you from having to look it up:

next: specialize 'skip [offset: 1]
; ...becomes
next: (<- skip _ 1)

Though that placeholder is a little bit unsatisfying. Which means one starts looking at questions like "in Rebol, why isn't the offset to skip by first". In the narrow case of this specialization, it would make it a bit briefer and seem more natural...

next: (<- skip 1)

And to play devil's advocate, if Rebol is to be English-inspired instead of traditional OOP inspired...wouldn't you say:

"Skip 10 pages ahead"

Instead of the more awkward:

"Skip pages ahead by 10"

It's almost like the underscore in the partial specialization is playing the role of "by". But, anyway--is there some kind of universal rule to guide such decisions?

Most-or-Least Important Thing First

Since this looks very Haskell-y, here's a good summary paragraph from a StackOverflow answer on why Haskell users would favor (<- skip 1) to (<- skip _ 1):

"It's common practice in Haskell to order function parameters so that parameters which "configure" an operation come first, and the "main thing being operated on" comes last. This is often counter intuitive coming from other languages, since it tends to mean you end up passing the "least important" information first. It's especially jarring coming from OO where the "main" argument is usually the object on which the method is being invoked, occurring so early in in the call that it's out of the parameter list entirely!"

One thing about the least important parameter is it is often briefer to express. Consider the example we hit with DELIMIT when the data to act on was first:

delimit [
    "here" "is" "my"
    long block of code stuff
    "and we go on for a while"
] ","

By the time you get to the comma, you might have forgotten what you are doing. It seems it's pretty rare for the thing you're delimiting with to be coming from a long and complex expression, while the thing you're operating on may well be a giant expression (like a COLLECT).

So @johnk and I thought it seemed better to say:

delimit "," [
    "here" "is" "my"
    long block of code stuff
    "and we go on for a while"

So that was changed...and as a consequence we get natural-looking specializations now like:

spaced: (<- delimit space)

What does this mean for old-school institutions like SKIP? I don't know. But I do know it's getting faster and clearer to bend the system to anything you want it to be...


I think it has been mentioned somewhere before:

If refinements are their own parameters, couldn't parameters also be their own refinements?

This would mean, you could change the order of parameters at the callsite.

It feels a little weird, that you would have to add a parameter as refinement to the call, to move it to the end.

>> f: func [a b][print spaced [a b]]

‌>> f 1 2
1 2

‌>> f/a 1 2
2 1
1 Like

There's a little bit of a mechanical reason why this is hard, but yes, I did say... I intend to make this happen... !

RE: Parameter Order in Rebol

To pick this thread back up and expand it further... this issue is now emerging in return parameter ordering, with multi-returns. (Not that you wouldn't have had the issue of deciding parameter order before if you were doing multi-returns by way of a block...)

I've mentioned that I think error handling needs a reboot, and figuring out where error: belongs in the return order may be a thing. I also mentioned how we might somehow break that distinguished case out, like...

; function that returns 3 values and a possible error
[a b c].err: some-func arg1 arg2 arg3

We might even look at there being a difference between ordered returns and unordered ones:

foo: func [
    return: "main return"
    r2: "ordered return slot 2"
    r3: "ordered return slot 4"
    /foo: "unordered return"
    /bar: "another unordered return"

But even if a return has an ordered position, that doesn't have to mean that the caller has to ask for it. This would be a difference from ordered parameters being required.