-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
461 additions
and
196 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
#+TITLE: Iterative, real-world script development, Part 2. | ||
#+AUTHOR: Rostislav Svoboda | ||
#+DATE: {{{time(%B %d\, %Y)}}} | ||
#+OPTIONS: toc:nil | ||
# #+LaTeX_CLASS: article | ||
# #+LaTeX_CLASS_OPTIONS: [a4paper, 11pt] | ||
|
||
#+BEGIN_EXPORT html | ||
<style> | ||
blockquote { | ||
font-style: italic; | ||
} | ||
</style> | ||
#+END_EXPORT | ||
|
||
Let's convert the script from Fish shell to Guile Scheme in a straight manner, | ||
as if we were writing basically putting parenthesis around the fish-script | ||
statements and expressions. | ||
|
||
final script is below results are below | ||
|
||
Also create a download link for the python code used for conversion. | ||
|
||
Is it possible to edit the python code used for code generation? | ||
|
||
Plugins | ||
|
||
Fire up your ChatGPT (Model Plugins Beta gpt4, CoderPad plugin) alter-ego and... | ||
|
||
* Upload the `cleanup-checkout-cache.fish` and enter the prompt: | ||
#+BEGIN_SRC markdown :exports code | ||
Please analyze the Fish-shell script I'm sending you in the attachment and | ||
convert it to Guile Scheme according to the rules and guidelines I'm going to | ||
send you in the next step. | ||
|
||
We will proceed with the conversion step-by-step. | ||
|
||
After the step-by-step conversion is done, please combine all the steps | ||
together, convert the whole Fish script and provide me a download link to the | ||
resulting Guile Scheme script file. | ||
#+END_SRC | ||
|
||
... Make sure at this point that your alter-ego ChatGPT understands the | ||
uploaded Fish-script. | ||
|
||
* Enter the prompt: | ||
#+BEGIN_SRC markdown :exports code | ||
The conversion rules and guidelines are: | ||
|
||
- The conversion result consists of the following blocks: | ||
``` | ||
[Guile Scheme hashbang] | ||
[Docstring] | ||
[Some Guile Scheme snippet or snippets] | ||
[Converted code] | ||
``` | ||
|
||
- The generated Guile code must follow the same logic and have the same | ||
structure as the origin. | ||
|
||
- Keep the generated Guile code simple and well readable. Avoid nesting | ||
s-expressions if nesting is not present in the origin. Don't do any | ||
"smart" conversion. | ||
|
||
- Make sure all strings are properly surrounded with double quotes. | ||
|
||
- Make sure all generated s-expressions are syntactically valid! | ||
|
||
- Conversion of regular expressions: | ||
+ Escape only the backslashes by doubling them (`\` → `\\`). Do not | ||
escape other characters. | ||
+ Keep the structure of the regular expression unchanged. | ||
|
||
- Convert Fish-shell hashbang: | ||
``` | ||
#!/usr/bin/env fish | ||
``` | ||
to Guile Scheme hashbang: | ||
``` | ||
#!/usr/bin/env guile | ||
!# | ||
``` | ||
|
||
- After the docstring append this Guile Scheme snippet: | ||
```scheme | ||
(use-modules | ||
;; provides read-line | ||
(ice-9 rdelim) | ||
;; provides open-input-pipe | ||
(ice-9 popen)) | ||
|
||
(define (read-all-strings port) | ||
"Return a list of all lines of text from the PORT. | ||
Returns a list of strings." | ||
(let loop ((res '()) | ||
(str (read-line port))) ; read-line from (ice-9 rdelim) | ||
(if (and str (not (eof-object? str))) | ||
(loop (append res (list str)) | ||
(read-line port)) | ||
res))) | ||
|
||
(define (exec command-string) | ||
"Run the shell COMMAND using ‘/bin/sh -c’ with ‘OPEN_READ’ mode, ie. to read | ||
from the subprocess. Wait for the command to terminate and return a list of strings | ||
containing its output." | ||
;; (format #t "[DEBUG] command-string: ~a\n" command-string) | ||
(let* ((port (open-input-pipe command-string)) ; open-input-pipe from (ice-9 popen) | ||
;; `read-all-strings' must be called before `close-pipe'. | ||
(results (read-all-strings port))) | ||
(close-pipe port) ;; the return code of the command execution is ignored | ||
results)) | ||
``` | ||
|
||
- If there are any Fish-shell commands commented out, convert them too. | ||
|
||
- Whenever applicable prefer constructing strings using `(format ...)` instead | ||
of using `string-append` in the conversion result. | ||
|
||
- `exec` returns a list of strings, so for better readability of the DEBUG | ||
outputs use `string-join`. E.g. convert: | ||
```fish | ||
# printf "[DEBUG] <variable>:\n$<variable>\n" | ||
``` | ||
to: | ||
```scheme | ||
;; (format #t "[DEBUG] <variable>:\n~a\n" (string-join <variable> "\n")) | ||
``` | ||
|
||
- Simple conversion rules: | ||
| Fish shell code | Guile scheme code | | ||
|--------------------------------------------------------------------------------------------| | ||
| `set <variable> <value>` | `(define <variable> <value>)` | | ||
| `set --append <variable> <value>` | `(set! <variable> (append <variable> (list <value>)))` | | ||
| `$<variable>[$i]` | `(list-ref <variable> i)` | | ||
| `test -n "$<variable>"` | `(> (length <variable>) 0)` | | ||
| `test -d $<variable>` | `(access? <variable> F_OK)` | | ||
|
||
- Conversion of an empty Fish variable: | ||
| Fish shell code | Guile scheme code | | ||
|--------------------------------------------------------------------------------------------| | ||
| `set <variable> # ...` | `(define <variable> (list)) ; ...` | | ||
|
||
- Fish-shell uses parentheses for operating system command substitution: | ||
| Fish shell code | Guile scheme code | | ||
|--------------------------------------------------------------------------------------------| | ||
| `set <variable> (<OS-command>)` | `(define <variable> (exec "<OS-command>"))` | | ||
|
||
The `exec` is a Guile Scheme function accepting some command-string as a | ||
parameter. Here: | ||
|
||
+ The `"<OS-command>"` in the conversion result is built by printing to | ||
string: | ||
```scheme | ||
(format #f <guile-format-string> <variable0> ... <variableN>)` | ||
``` | ||
+ Make sure the regexp used for `grep` will be surrounded by properly | ||
escaped double quotes in the conversion result. E.g.: `grep ... \"~a\"` | ||
|
||
- `(define <variable> <value>)` cannot be used inside `(begin ...)`. Use | ||
`(let* ((<variable> <value>)) ...)` instead. | ||
|
||
- Conversion of the loops. Make sure you understand the specific actions | ||
performed within the loops and how other commands should be translated. | ||
Then: | ||
```fish | ||
for <index-variable> in <variable> | ||
... | ||
end | ||
``` | ||
corresponds to: | ||
```scheme | ||
(for-each | ||
(lambda (<index-variable>) | ||
...) | ||
<variable>) | ||
``` | ||
#+END_SRC | ||
|
||
... and keep on iterating the prompt again and again... and again and | ||
again... and again and again because even if our ChatGPT alter-ego is rather | ||
smart, it: | ||
- sometimes forgets what exactly the Fish shell scripts contains | ||
- escapes other than the backslashes, despite of being explicitly instructed not to do so. | ||
- occasionally freezes | ||
- can correct its mistakes but a couple of steps later starts to make the same mistakes again. | ||
- sometimes freezes at the last step, when the resulting Guile Scheme file. | ||
- etc. | ||
|
||
|
||
* Summary / Final thoughts | ||
|
||
Using ChatGPT is like trying to learn how to teach using the trial-and-error method. | ||
|
||
You can easily spend 10+ hours on improving your script conversion prompt and | ||
never get the consistency of good results. | ||
|
||
As of now. (December 2023) | ||
It's a learning process - how to use ChatGPT and how to craft prompts. | ||
|
||
Sometimes abandoning current dialogue are restarting the whole conversion from | ||
the scratch yields better results. When you can't get out of the valley of | ||
the local optimization minimum [TODO link to a picture] | ||
|
||
It's like building up a sandcastle too close to the sea. | ||
carefully crafting | ||
|
||
Since ChatGPT uses Python for text conversion a better idea might be to write | ||
the cleanup-script in Python and then try to convert it to Guile Scheme. | ||
|
||
need to try out the upcoming Gemini. | ||
|
||
Maybe | ||
|
||
Here is the Guile Scheme script anyway. (Compare with its Fish version) | ||
|
||
Warnings - read and understand the code before you run it. | ||
|
||
Decrease the variation parameter. | ||
|
||
See also | ||
https://www.zdnet.com/article/i-used-chatgpt-to-write-the-same-routine-in-12-top-programming-languages-heres-how-it-did/ |
Oops, something went wrong.