Created
March 17, 2023 19:06
-
-
Save jcottrell/1fbd3f3165bb9bf84bceacd499aa5fd9 to your computer and use it in GitHub Desktop.
ChatGPT trying to write Racket
This file contains hidden or 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
#lang racket | |
(require rackunit) | |
#| | |
Comments are wrapped in #|with comments in between|# and commented out code starts with #; | |
The parts wrapped in square brackets [are my thoughts/comments on the results and general interaction. | |
ChatGPT prompt: | |
Me: I want you to create a racket program that will search a list of lists for an atom and either | |
return the whole list if the atom is found or add the atom then return the list if the atom is not | |
found. | |
[My working program (just after realizing the problem ChatGPT was trying to solve but before | |
running the first ChatGPT attempt). Total time to develop (with tests) 20 minutes. | |
My solution around midnight on 3/16 or 3/17, 2023] | |
|# | |
#;(define (search-list-of-lists list-of-lists atom) | |
(cond [(empty? list-of-lists) (list atom)] | |
[(member atom (car list-of-lists)) (car list-of-lists)] | |
[else (search-list-of-lists (cdr list-of-lists) atom)])) | |
#| | |
[It didn't understand exactly what I meant but I thought it was interesting that even though it | |
found a reasonable problem to solve it still couldn't solve it. Its problem was to return the | |
sublist that contained the atom I passed in or return a list of a list of the atom that was not | |
found. | |
There are two problems: | |
(1) the minor one is that it should return the same type of value in either case, a list with | |
depth of one. If it find 3 in '(3 4) then that's right but if 7 isn't found then '(7) | |
should be returned, not '((7)). | |
(2) the major problem was that it didn't work; not even with its own examples. See the tests at | |
the end of this file. | |
First I figured I'd solve the major problem (or try to get ChatGPT to do it and then sort out the | |
minor problem.] | |
ChatGPT: first try (2023-03-17 12:02am) | |
|# | |
#;(define (search-list-of-lists list-of-lists atom) | |
(define (search-sublist sublist) | |
(cond ((member atom sublist) sublist) | |
(else (cons atom sublist)))) | |
(let ((found (filter search-sublist list-of-lists))) | |
(if (null? found) | |
(list (list atom)) | |
(car found)))) | |
#| | |
[The problem here is that `filter` is looking for true or false return values from the function | |
that gets passed in (#t or #f values). The search-sublist function returns either the entire | |
sublist or the sublist prefixed by the atom, both considered true (or #t) by `filter` so the | |
`null?` always fails and the `(car found)` is always returned, which is just the first list of | |
the entire list since `filter` does not filter out anything.] | |
Me: I tried the first example and it came back '(1 2) which is wrong. Fix the program so that your | |
first example returns '(3 4) | |
[Its first example was: | |
> (search-list-of-lists '((1 2) (3 4) (5 6)) 4) | |
'(3 4) | |
which would be right except that when you run the code it returns '(1 2) every time.] | |
ChatGPT: I apologize for the mistake in my previous response. The issue is that the member function | |
returns the first element in the list that matches the search criteria, which in this case is not; | |
necessarily the entire sublist. To fix the program, we can modify the search-sublist function to | |
check if the atom is in the sublist using the memq function, which returns #t if the atom is in th; | |
sublist, and #f otherwise. Here's the updated code: | |
ChatGPT: second try (12:14am) | |
|# | |
#;(define (search-list-of-lists list-of-lists atom) | |
(define (search-sublist sublist) | |
(if (memq atom sublist) | |
sublist | |
(cons atom sublist))) | |
(let ((found (filter search-sublist list-of-lists))) | |
(if (null? found) | |
(list (list atom)) | |
(car found)))) | |
#| | |
[The program above is still wrong because the problem is with the `filter` not filtering anything | |
out. It got the issue wrong and so it switched `member` for `memq` and because it didn't even | |
understand the two funcitons (they differ on the comparison operator used) it was changing the | |
program in wrong ways.] | |
Me: It's still wrong. I got '(1 2) again. Changing the function from member to memq didn't fix it. | |
[When I replied with the above message it gave an error response with the "Regenerate response" | |
button several times.] | |
ChatGPT: I apologize for the confusion, and thank you for bringing this to my attention. I see now | |
that the issue is with the filter function, which returns a list of all sublists that satisfy the | |
search-sublist predicate, instead of just the first one. | |
Here's an updated version of the function that should work correctly: | |
ChatCPT: third try (12:43am) | |
|# | |
#;(define (search-list-of-lists list-of-lists atom) | |
(define (search-sublist sublist) | |
(if (memq atom sublist) | |
sublist | |
#f)) | |
(let ((found (findf search-sublist list-of-lists))) | |
(if found | |
found | |
(list (cons atom '()))))) | |
#| | |
[Still sticking with memq, it changed to `findf` instead of `filter`. This works. Time to fix | |
problem (1). Note that there is a difference between member and memq and it did not explain it | |
well.] | |
Me: It works except when the atom is not found. When the atom is found it returns a list but when | |
the atom is not found it returns a list of lists. When the atom isn't found it should return a list | |
of depth one. | |
[Again, lots of hanging and error message that "Something went wrong. If this issue persists | |
please contact us through our help center at help.openai.com.".] | |
[After allowing it to think for a long while I tried again and got this.] | |
ChatGPT: Thank you for pointing that out. I apologize for the mistake. Here's an updated version of | |
the function that returns a list of depth one when the atom is not found: | |
ChatCPT: fourth try (2:25am) | |
|# | |
#;(define (search-list-of-lists list-of-lists atom) | |
(define (search-sublist sublist) | |
(if (memq atom sublist) | |
sublist | |
#f)) | |
(let ((found (findf search-sublist list-of-lists))) | |
(if found | |
found | |
(list atom)))) | |
; | |
; [It works in all cases; it's just quite verbose. If I clean it up it turns into:] | |
; | |
#;(define (search-list-of-lists list-of-lists atom) | |
(or (findf (lambda (l) (member atom l)) list-of-lists) | |
(list atom))) | |
#| | |
Me: Can you optimize it to remove any duplicate code? | |
ChatGPT: Yes, certainly! One way to optimize the code and remove any duplicate code is to use the | |
cond function to check if the atom is found in the list of lists or not, and return the appropriate | |
result. Here's an updated version of the function: | |
ChatGPT: fifth try (2:38am) | |
|# | |
(define (search-list-of-lists list-of-lists atom) | |
(define (search-sublist sublist) | |
(if (memq atom sublist) | |
sublist | |
#f)) | |
(cond ((findf search-sublist list-of-lists) => identity) | |
(else (list atom)))) | |
; | |
; original ChatGPT examples put into rackunit tests but note that it couldn't pass these tests until | |
; iteration 3: | |
(check-equal? (search-list-of-lists '((1 2) (3 4) (5 6)) 4) '(3 4)) | |
(check-equal? (search-list-of-lists '((1 2) (3 4) (5 6)) 2) '(1 2)) | |
(check-equal? (search-list-of-lists '((1 2) (3 4) (5 6)) 7) '(7)) | |
(check-equal? (search-list-of-lists '() 1) '(1)) | |
#| | |
[At this point it's good enough to make me wonder why it isn't better. Even though it | |
misunderstood the original request, the problem was a close relative and its explanation of the | |
code was mostly accurate. | |
I heard the Fireship guy on youtube say that ChatGPT is where computer chess was in the late 90s. | |
The comprehension is high. The ability to explain code is high. It's seeming unwillingness to | |
write working code makes me wonder what guards are on it so it's not doing college computer | |
science homework. The original prompt was formulated from a homework problem with which I | |
recently helped someone. | |
I'm not exactly fearful of losing my job because it will remain largely the same: writing small | |
apps to glue together the work of others. Those others may be machines and it might take me an | |
hour to walk them through code I can write in 5 minutes. | |
It's a lot like the changes in chess or, even better, the changes from writing machine language | |
and assembly code to writing high-level languages. The game of chess changed when more people who | |
played chess could consult the computer for how to play chess better and analyze their games. The | |
move from low-level code to Smalltalk or Haskell or Clojure means there are far, far fewer pieces | |
of elegant, hand-crafted machine code out there; it means we lose out on a little of the speed | |
and efficiency in exchange for thinking about higher-level abstraction; it may mean we get | |
documentation of the code as the code changes. | |
My main take-away is that it's a new programming language. You type in human speech and get lower | |
level code. The better you understand both, the better you can get the machine to do its job. | |
|# |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment