kaka.farm

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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