>> F: func [A][print type? :A print join "Arg: " A]
>> F "Foo"
string
Arg: Foo
>> F func [][return "Bar"]
function
Arg: Bar
I really got spoiled learning Rebol as my first language, I'd already internalized a ton of concepts long before they were introduced during school and college. Higher-order functions were the first time I really realized it, I guess here's another to add to the pile.Even knowing this though, that post really is really obtuse. Definitely could have been better written.
Basically in these languages, functions don't have a special syntax to be called, like F(), they just get called when used. So usage of a no-argument function is identical to a variable, and what happens depends on its datatype (function, string, whatever). The special :A syntax is to get the value without evaluating it if it is a function.
def int(i) = i.respond_to(:call) ? i.call : i.to_i
def f(i) = int(i) * 2
f in this case can take both ints and lambdas or anything call-able.In practice we'd usually do this via any of the normal conversion methods like expecting the caller to support to_i etc., and bear the complexity for us as needed unless there's a really compelling reason to think the caller will often want to defer the evaluation past the call site and into the method itself.
That's usually very obvious when you come across it, like e.g. if the argument is expected to come from a remote source, but as long as the API for how the method uses the value is clear, substituting the value for a deferred calculation is easy.