1
$\begingroup$

There are some basic instructions about Composition on this site, but I'm still confused on how to use it when the functions I am composing have two parameter, such as:

t := RandomImage[1, {50, 50}, ColorSpace -> "RGB"]
picList = Array[t &, 3];
ImageResize[#, 500] &@*ColorConvert[#, "Grayscale"] & /@ picList

Mathematica graphics

But when the composition functions just have one parameter, the behavior is more predictable:

hh@*ff /@ picList

Mathematica graphics

Can anybody explain this strange behavior?

$\endgroup$
3
$\begingroup$

& has a very low operator precedence, in particular it's lower than @*'s precedence. That means that the right-hand & is actually defining an unnamed function with the body:

ImageResize[#, 500] & @* ColorConvert[#, "Grayscale"]

You can fix this by wrapping the right-hand function in parentheses:

ImageResize[#, 500] & @* (ColorConvert[#, "Grayscale"] &) /@ piclist

Or both of them for consistency:

(ImageResize[#, 500] &) @* (ColorConvert[#, "Grayscale"] &) /@ piclist

Of course, as you mentioned in a comment, that doesn't help much compared with

(ImageResize[#, 500] &) /@ (ColorConvert[#, "Grayscale"] &) /@ piclist

If you want to avoid the parentheses altogether, you could still define a pure function via the Function, but of course, that's even less terse, and technically you've just replaced parentheses with square brackets:

Function[ImageResize[#, 500]] @* Function[ColorConvert[#, "Grayscale"]] /@ piclist

You can also use the full form of @* instead:

Composition[ImageResize[#, 500] &, ColorConvert[#, "Grayscale"] &] /@ piclist

Alternatively, you could apply both transformations in a single function:

ImageResize[ColorConvert[#, "Grayscale"], 500] & /@ piclist

Or use infix notation for a nicer reading order:

# ~ColorConvert~ "Grayscale" ~ImageResize~ 500 & /@ piclist
$\endgroup$
  • $\begingroup$ Applaud for the last form :) $\endgroup$ – yode Mar 29 '16 at 12:17
  • $\begingroup$ Or we can use Composition[ImageResize[#,500]&,ColorConvert[#,"Grayscale"]&]/@picList to aviod the bracket $\endgroup$ – yode Mar 29 '16 at 12:25
  • $\begingroup$ @yode Oh, good point, I'll add that for completeness. $\endgroup$ – Martin Ender Mar 29 '16 at 12:33
  • 2
    $\begingroup$ For something this elaborate, I'd go with the penultimate snippet. Not worth having to try to look up precedence just to have compact code. $\endgroup$ – J. M. will be back soon Mar 29 '16 at 13:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.