Skip to content

Instantly share code, notes, and snippets.

@jcottrell
Created March 17, 2023 19:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jcottrell/1fbd3f3165bb9bf84bceacd499aa5fd9 to your computer and use it in GitHub Desktop.
Save jcottrell/1fbd3f3165bb9bf84bceacd499aa5fd9 to your computer and use it in GitHub Desktop.
ChatGPT trying to write Racket
#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