How to programmatically modify a function definition

This is my first time wading into metaprogramming in Mathematica, so take this with a pinch of salt. I can get the DownValues of myfunction and strip out the cases of Print commands, then build a new function newfunction by setting DownValues like so:

(* any old function will do *)
myfunction[x_, y_] := Module[{p = 0},
  p = x^2 + y^2;
  Print["test1: " <> ToString@p];
  If[p < 1, p = p^2 + 1, p = y - x];
  Print["test2: " <> ToString@p];
  Do[
   Print["blah" <> ToString@i];
   , {i, 3}];
  Return[p]
]

DownValues[newfunction] = ReleaseHold[
   DeleteCases[
     DownValues[myfunction][[1]],
     fn_[___] /; fn === Print, Infinity,
     Heads -> True
     ] /. myfunction -> newfunction
   ];

myfunction[6, 3]
(*
> test1: 45
> test2: -3
> blah1
> blah2
> blah3

returns -3
*)

newfunction[6,3]
(* returns -3 *)

You might want to look into ways to suppress Print though, because the above technique looks pretty dangerous and will probably go wrong in unexpected ways. Suppress Print[ ]s?


To operate on notebooks

Let nb be the notebook you want to alter obtained with NotebookGet[]. For instance, it could be nb = NotebookGet[EvaluationNotebook[]]. Instead of EvaluationNotebook[], you could have something like First@Select[Notebooks[], Information[#, "FileName"] === "MyProg" &].

nb /. HoldPattern@RowBox[{
      x___, Optional[";", ";"],
      RowBox[{"Print", "[", ___, "]"}],
      Optional[";", ";"], y___}] :>
   RowBox[{x, y}] // NotebookPut

Note: This will not extensively tested. Like the method below, it may result in errors in the code. It should work well if each Print[] statement occurs in a CompoundExpression.

To operate on definitions in the kernel

The function cleanup[sym, pat] will delete all expressions matching pat from the definitions of a symbol sym. Use _Print to delete Print statements.

cleanup[sym_Symbol, pat_] := 
 Language`ExtendedFullDefinition[sym] = 
  DeleteCases[Language`ExtendedFullDefinition[sym], pat, Infinity]

Deleting Print[..] as an argument to something other than CompoundExpression may result in errors on execution. For example:

DeleteCases[Hold[Module[{}, Print["Hi there!"]]], _Print, 
  Infinity] // ReleaseHold

Module::argmu: Module called with 1 argument; 2 or more arguments are expected.

(* Module[{}]  *)

Adding a semicolon, Module[{}, Print["Hi there!"];], prevents the error.

Example

Example function to clean up, showing a variety of values (DownValues, SubValues and UpValues):

ClearAll[addto];
call : addto[x_, y_] := (Print["main routine called: ", 
    HoldForm[call]]; x + y);
call : addto[x_][y_] := (Print["operator form called: ", 
    HoldForm[call]]; addto[x, y]);
addto /: call : 
   addto[x_] + y_ := (Print["upvalue form called: ", HoldForm[call]]; 
   addto[x, y]);

Test:

addto[3][4]

operator form called: addto[3][4]

main routine called: addto[3,4]

(*  7  *)
addto[3] + 5

upvalue form called: 5+addto[3]

main routine called: addto[3,5]

(*  8  *)
cleanup[addto, _Print]
(*
Language`DefinitionList[HoldForm[addto] -> {OwnValues -> {}, 
   SubValues -> {HoldPattern[call : addto[x_][y_]] :> 
      CompoundExpression[addto[x, y]]}, 
   UpValues -> {HoldPattern[call : addto[x_] + y_] :> 
      CompoundExpression[addto[x, y]]}, 
   DownValues -> {HoldPattern[call : addto[x_, y_]] :> 
      CompoundExpression[x + y]}, NValues -> {}, FormatValues -> {}, 
   DefaultValues -> {}, Messages -> {}, Attributes -> {}}]
*)

Test again:

addto[3][4]
(*  7  *)
addto[3] + 5
(*  8  *)

That's not a real answer... But I failed to format it as a comment. Again.

You're opening a deep can of worms now, called "metaprogramming".

Please search for "metaprogramming" and discover excellent posts by Leonid Shifrin and others.

In your particular case:

increment = Function[{x}, Print[x]; x + 1]

You can try something like this:

increment //. { 
  HoldPattern @ CompoundExpression[a___, _Print, b___] :> 
   CompoundExpression[a, b]} 

The original increment has a tree representation:

enter image description here

The result will look like:

enter image description here

Generally speaking you can use rewrite rules to manipulate the structure of the expression (most of the times you will have to inactivate the expression with 'Hold' and friends)