LazyCall, again, sorry

It seems like the only way out of this pickle is to either mark containers you want to iterate (or scalars you don’t want to iterate). Anyways, here’s a proposal:

A lazy call object contains both a function and its arguments. For example,

LazyCall((a, b) -> a + b + 1, (A, B))

There is special syntax for making a lazy call.

.( ~A + ~B) is syntactic sugar for the above

You can call a function on a LazyCall, also with special syntax:

broadcast.( ~A + ~B + 1)

You could just as easily do:

filter.( ~A > 1)

Sorry for possibly derailing the thread. I just though I’d mention that an abstraction I’ve been working on for a long time could unequivocally sort out this conflict.

Here is another idea: ~ alone could signify an anonymous function, so

.( ~ + 1)

goes to

x - x + 1

so that

A |>
    .( ~ + 1)

could be a syntax for chaining

Not sure how to deal with functions like broadcast! in this proposal

Maybe

.( ~A = ~B + ~C + 1)

Goes to

LazyEquation( (b, c) -> b + c + 1, A, (B, C) )

???

Are you “marking” the objects to be treated as containers with a ~? Instead of always assuming everything is a scalar unless specially marked, it’s easier to go the other way since that requires no special syntax: (1,) .+ A .* (3,).

It might also be worth pointing out that I’m actively working on getting a “lazy” broadcast representation into 1.0: https://github.com/JuliaLang/julia/pull/25377. You won’t typically see or work with it, but it’s what will enable extensible fusion.

I guess (1,) .+ A .* (3,) could work too. You are missing out on the ability to choose other verbs. I’m not sure if it’s more terse or not.

#25377 looks really cool btw