If you use contextFraction.pl, and use Context("Fraction"), then you can make
$slopeeval = Fraction(-$dx-> eval(x => $x, y => $y), $dy-> eval(x => $x, y => $y))
using two arguments to Fraction. It will be a Fraction object with the numerator and denominator reduced. (I'm not sure what happens if the numerator and denominator are not integers, but the sample code given in the post will produce integers.)
You can also make
$slopeeval = Fraction((-$dx-> eval(x => $x, y => $y)) / ($dy-> eval(x => $x, y => $y)))
which carries out the division and passes one (likely decimal) argument to Fraction. The result will be a reduced fraction that is probably equal to what you fed it, as long as the denominator of what you fed it was not too large.
I'd do your $f, $dx, $dy, etc in Numeric context. Then switch to Fraction context to make this $slopeeval. Then go to ImplicitEquation context to write the equation, but remember to set the reduceConstants flag to 0 so that the string fraction is not reduced to a decimal again.