I agree... using the pipe operator for this would be confusing at best, and 
breaking at worst.  However it would still be cool to be able to connect 
multiple functions in one pass.  What about:


julia> function foreach(A::AbstractArray, f::Function, fs::Function...)
           for x in A
               f(x)
           end
           for g in fs
               foreach(A, g)
           end
           A
       end
foreach (generic function with 1 method)

julia> type MyType; x::Int; end

julia> A = map(MyType, 1:2)
2-element Array{MyType,1}:
 MyType(1)
 MyType(2)

julia> add_one!(mt::MyType) = mt.x += 1
add_one! (generic function with 1 method)

julia> add_two!(mt::MyType) = mt.x += 2
add_two! (generic function with 1 method)

julia> foreach(A, add_one!)
2-element Array{MyType,1}:
 MyType(2)
 MyType(3)

julia> foreach(A, add_two!)
2-element Array{MyType,1}:
 MyType(4)
 MyType(5)

julia> foreach(A, add_two!, add_one!, add_one!)
2-element Array{MyType,1}:
 MyType(8)
 MyType(9)


One note... this is different than applying "f(g(h(x)))" for each item 
independently.  In that case there may be simpler answers.  My use case is 
when the items depend on the state of others, and so the first operation 
needs to be applied to all items before starting the next operation.  In 
effect, I want to replace this:

for x in A; step1!(x); end
for x in A; step2!(x); end
for x in A; step3!(x); end

with this:

foreach(A, step1!, step2!, step3!)





On Wednesday, June 10, 2015 at 10:06:39 AM UTC-4, David Gold wrote:
>
> Pipe and map seem like related but orthogonal concepts; I don't know if 
> they ought to be given the same operator. But I may just be looking at 
> things wrongly.
>
> I'd sooner see a tricked-out array comprehension syntax. Something like
>
> ![ add_one(x) for x in A ]
>
> If the target array were ambiguous, one could write
>
> !A[ f(add_one(x), add_two(y)) for x in A, y in B]
>
> which could play well with some shorthand for taking a comprehension over 
> the entirety of an array, e.g.
>
> ![ add_one(.A) ]
>
> or
>
> !A[ f(add_one(A[.i]), add_two(B[.i])) ]
>
>
> On Tuesday, June 9, 2015 at 8:37:51 PM UTC-4, Tom Breloff wrote:
>>
>> Stefan: Yes that's obviously valid.  Simon's "foreach" is essentially 
>> what I mean.  
>>
>> Although overriding the pipe operator would probably break things, I 
>> think ideally there would be a built-in solution that looks similar to this:
>>
>>
>> julia> |>(A::AbstractArray, f::Function) = (for x in A; f(x); end; A)
>> |> (generic function with 7 methods)
>>
>> julia> type MyType; x::Int; end
>>
>> julia> add_one!(mt::MyType) = mt.x += 1
>> add_one! (generic function with 1 method)
>>
>> julia> A = map(MyType, 1:2)
>> 2-element Array{MyType,1}:
>>  MyType(1)
>>  MyType(2)
>>
>> julia> A |> add_one! |> add_one!
>> 2-element Array{MyType,1}:
>>  MyType(3)
>>  MyType(4)
>>
>>
>>
>>

Reply via email to