call-process-chatgpt.org (9767B)
1 #+author: 2 3 * ChatGPT explaining Emacs Lisp 4 5 A perplexed friend asked ChatGPT what my code does. I shared it with 6 a bunch of people and a person on #systemcrafters-general:matrix.org 7 then suggested I ask ChatGPT for improvements. 8 9 ** Original 10 11 #+begin_src elisp 12 (progn 13 (defun kakafarm/call-process-with-string-as-input (program &optional input-string &rest args) 14 (with-temp-buffer 15 (let ((our-output-buffer (current-buffer))) 16 (if input-string 17 (with-temp-buffer 18 (let ((our-input-buffer (current-buffer))) 19 (progn 20 (erase-buffer) 21 (insert input-string) 22 (apply 'call-process-region 23 (buffer-end -1) 24 (buffer-end 1) 25 program 26 nil 27 our-output-buffer 28 nil 29 args)))) 30 (apply 'call-process 31 program 32 nil 33 our-output-buffer 34 nil 35 args))) 36 (buffer-string))) 37 38 (kakafarm/call-process-with-string-as-input "cat" 39 "cat says moo") 40 (kakafarm/call-process-with-string-as-input "echo" 41 nil 42 "echo echo echo")) 43 #+end_src 44 45 ** Explanation by ChatGPT 46 47 #+begin_quote 48 The code defines a function named kakafarm/call-process-with-string-as-input. This function takes three arguments: program, input-string, and args. It executes a command-line program (program) and returns the output as a string. The input-string argument is optional and allows passing input to the program. 49 50 The function starts by creating a temporary buffer using the with-temp-buffer macro. This buffer will be used to store the output of the command. The variable our-output-buffer is bound to the current buffer. 51 52 Next, there is a conditional statement that checks if an input-string is provided. If it is, another temporary buffer (our-input-buffer) is created to hold the input string. The erase-buffer function clears the our-input-buffer, and the insert function inserts the input-string into the buffer. 53 54 Then, the function call-process-region is called with arguments (buffer-end -1) and (buffer-end 1), which represent the beginning and end of the our-input-buffer. This function executes the specified program with the given input and redirects the output to our-output-buffer. The args are also passed to the call-process-region function. 55 56 If no input-string is provided, the function call-process is used instead. It directly executes the program with the given args, without any input. 57 58 After executing the command, the buffer-string function is called to retrieve the contents of the our-output-buffer. This value is then returned as the result of the function. 59 60 Finally, the function is invoked twice to demonstrate its usage. In the first invocation, the program "cat" is executed with the input string "cat says moo". In the second invocation, the program "echo" is executed without any input, but with the arguments "echo echo echo". 61 62 Overall, this code snippet defines a utility function that simplifies calling command-line programs and capturing their output in Lisp. It demonstrates the flexibility of Lisp in handling strings, buffers, and external processes. 63 #+end_quote 64 65 ** Improvements by ChatGPT 66 *** Code 67 68 #+begin_src elisp 69 (defun kakafarm/call-process-with-string-as-input (program &optional input-string &rest args) 70 (if input-string 71 (with-temp-buffer 72 (insert input-string) 73 (apply 'call-process-region (point-min) (point-max) program nil t nil args)) 74 (apply 'call-process program nil t nil args))) 75 76 (list (kakafarm/call-process-with-string-as-input "cat" "cat says moo") 77 (kakafarm/call-process-with-string-as-input "echo" nil "-n" "echo echo echo")) 78 #+end_src 79 80 *** Explanation 81 82 #+begin_quote 83 Improvements: 84 85 Removed unnecessary progn wrapper around the defun. 86 Simplified the logic for handling input strings. No need for nested with-temp-buffer calls and separate buffer variables. 87 Replaced (buffer-end -1) and (buffer-end 1) with (point-min) and (point-max) respectively for clarity. 88 Replaced (buffer-string) with t in call-process-region to discard the output buffer and avoid unnecessary memory allocation. 89 Removed unnecessary nil argument in call-process. 90 These improvements make the code cleaner and more efficient. 91 #+end_quote 92 93 ** Doom? 94 95 My friend asked if it make sense. Does it? 96 97 *** Running the code 98 99 #+begin_src elisp 100 (progn ; Adding a progn so I can run both expressions in one go. 101 (defun kakafarm/call-process-with-string-as-input (program &optional input-string &rest args) 102 (if input-string 103 (with-temp-buffer 104 (insert input-string) 105 (apply 'call-process-region (point-min) (point-max) program nil t nil args)) 106 (apply 'call-process program nil t nil args))) 107 108 (list (kakafarm/call-process-with-string-as-input "cat" "cat says moo") 109 (kakafarm/call-process-with-string-as-input "echo" nil "-n" "echo echo echo"))) 110 echo echo echo ; The result after running eval-last-sexp (C-x C-e). 111 #+end_src 112 113 I've expected a string return value of the whole progn expression, yet 114 what I've got was an insertion to this here buffer. 115 116 We are safe... 117 118 ... 119 120 for now. 121 122 ** Yes, we are safe. 123 124 https://chat.openai.com/share/08cc30e5-21ce-4549-9f3b-7de82d40f9b9 125 126 Copying it here: 127 128 #+begin_quote 129 Shared Chat• 130 Model: Default 131 Improve Lisp program. 132 July 7, 2023 133 can you improve this program please? 134 #+end_quote 135 136 #+begin_src elisp 137 (progn 138 (defun kakafarm/call-process-with-string-as-input (program &optional input-string &rest args) 139 (with-temp-buffer 140 (let ((our-output-buffer (current-buffer))) 141 (if input-string 142 (with-temp-buffer 143 (let ((our-input-buffer (current-buffer))) 144 (progn 145 (erase-buffer) 146 (insert input-string) 147 (apply 'call-process-region 148 (buffer-end -1) 149 (buffer-end 1) 150 program 151 nil 152 our-output-buffer 153 nil 154 args)))) 155 (apply 'call-process 156 program 157 nil 158 our-output-buffer 159 nil 160 args))) 161 (buffer-string))) 162 163 (list (kakafarm/call-process-with-string-as-input "cat" 164 "cat says moo") 165 (kakafarm/call-process-with-string-as-input "echo" 166 nil 167 "-n" 168 "echo echo echo"))) 169 #+end_src 170 171 #+begin_quote 172 ChatGPT 173 174 Certainly! Here's an improved version of the program: 175 176 lisp 177 #+end_quote 178 179 #+begin_src elisp 180 (defun kakafarm/call-process-with-string-as-input (program &optional input-string &rest args) 181 (if input-string 182 (with-temp-buffer 183 (insert input-string) 184 (apply 'call-process-region (point-min) (point-max) program nil t nil args)) 185 (apply 'call-process program nil t nil args))) 186 187 (list (kakafarm/call-process-with-string-as-input "cat" "cat says moo") 188 (kakafarm/call-process-with-string-as-input "echo" nil "-n" "echo echo echo"))) 189 #+end_src 190 191 #+begin_quote 192 Improvements: 193 194 Removed unnecessary progn wrapper around the defun. 195 Simplified the logic for handling input strings. No need for nested with-temp-buffer calls and separate buffer variables. 196 Replaced (buffer-end -1) and (buffer-end 1) with (point-min) and (point-max) respectively for clarity. 197 Replaced (buffer-string) with t in call-process-region to discard the output buffer and avoid unnecessary memory allocation. 198 Removed unnecessary nil argument in call-process. 199 200 These improvements make the code cleaner and more efficient. 201 I've expected a string return value of the whole progn expression, yet 202 what I've got was an insertion to this here buffer. 203 ChatGPT 204 205 Apologies for the misunderstanding. If you would like the whole progn expression to return a string instead of inserting it into a buffer, you can use the with-output-to-string macro. Here's the updated code: 206 207 lisp 208 #+end_quote 209 210 #+begin_src elisp 211 (progn 212 (defun kakafarm/call-process-with-string-as-input (program &optional input-string &rest args) 213 (with-output-to-string 214 (if input-string 215 (with-input-from-string input-string 216 (apply 'call-process-region program nil standard-output nil args)) 217 (apply 'call-process program nil standard-output nil args)))) 218 219 (kakafarm/call-process-with-string-as-input "cat" "cat says moo")) 220 #+end_src 221 222 It had imagined a new form called 223 src_elisp{with-input-from-string}. It does not work. 224 225 #+begin_quote 226 In this version, the with-output-to-string macro captures the output of the progn expression and returns it as a string. The standard-output stream is used as the output destination for the call-process-region or call-process functions, depending on whether an input string is provided. 227 228 Please note that the (kakafarm/call-process-with-string-as-input "echo" nil "-n" "echo echo echo") part from your original code has been removed since it wasn't necessary for demonstrating the changes. Feel free to add it back if needed. 229 Continue this conversation 230 | 231 Terms of use 232 | 233 Privacy policy 234 235 Improve Lisp program. 236 #+end_quote