ChatGPT knows a ton about Racket apparently

I asked it "Implement the Bakery algorithm in the Racket programming language." AND IT ACTUALLY WORKED! I haven't reviewed the code in detail for bugs, but it's incredible that it managed to do anything at all.

#lang racket
(define (bakery n)
  (define (bakery-aux choosing)
    (let ([my-number (if choosing (add1 (max choosing)) 1)]
          [my-ticket (make-vector n 0)]
          [max-ticket (make-vector n 0)])
      (begin
        (vector-set! my-ticket my-number my-number)
        (vector-set! max-ticket my-number my-number)
        (for ([j (in-range (add1 n))])
          (let ([other-number (vector-ref my-ticket (modulo j n))])
            (when (and (not (zero? other-number))
                       (or (not (zero? (vector-ref max-ticket j)))
                           (< other-number (vector-ref max-ticket j))))
              (vector-set! max-ticket j other-number))))
        (when (not (zero? (vector-ref max-ticket (modulo n my-number))))
          (bakery-aux (vector-ref max-ticket (modulo n my-number)))))))
  (bakery-aux 0))

Have other people gotten it to generate any interesting stuff related to Racket?

1 Like

It's very impressive. Here's what it gave me when I asked:

Write a Racket program that accepts a number of command line parameters to interact with a REST API. The basic CRUD operations should be supported.

> #lang racket

(require net/http-client)

(define base-url "http://example.com/api/") ; replace with the base URL of the REST API

;; Function to make a GET request to the specified URL
(define (get-request url)
  (define response (get-pure-port (string->url url) '() '()))
  (port->string (car response)))

;; Function to make a POST request to the specified URL with the given data
(define (post-request url data)
  (let ([request-string (format "~a=~a" (car data) (cdr data))])
    (define response (post-pure-port (string->url url)
                                     (list "Content-Type" "application/x-www-form-urlencoded")
                                     request-string))
    (port->string (car response))))

;; Function to make a PUT request to the specified URL with the given data
(define (put-request url data)
  (let ([request-string (format "~a=~a" (car data) (cdr data))])
    (define response (put-pure-port (string->url url)
                                    (list "Content-Type" "application/x-www-form-urlencoded")
                                    request-string))
    (port->string (car response))))

;; Function to make a DELETE request to the specified URL
(define (delete-request url)
  (define response (delete-pure-port (string->url url) '() '()))
  (port->string (car response)))

;; Function to parse the command line arguments
(define (parse-args args)
  (define operation (car args))
  (define resource (cadr args))
  (cond
    [(equal? operation "create")
     (list "POST" resource (list (caddr args) (cadddr args)))]
    [(equal? operation "read")
     (list "GET" resource '())]
    [(equal? operation "update")
     (list "PUT" resource (list (caddr args) (cadddr args)))]
    [(equal? operation "delete")
     (list "DELETE" resource '())]))

;; Function to make the HTTP request and display the response
(define (make-request operation resource data)
  (define url (string-append base-url resource))
  (cond
    [(equal? operation "GET") (display (get-request url))]
    [(equal? operation "POST") (display (post-request url data))]
    [(equal? operation "PUT") (display (put-request url data))]
    [(equal? operation "DELETE") (display (delete-request url))]))

;; Parse the command line arguments and make the HTTP request
(let ([args (parse-args (command-line-arguments))])
  (make-request (car args) (cadr args) (caddr args)))

It can generate GUI code quite handily. In fact I've been using ChatGPT to quickly generate dialogs on a pinch.

Here's the result of the prompt:

Write a Racket program that displays a window with a text field, a Cancel button and a OK button.

> #lang racket

(require racket/gui/base)

(define frame (new frame% [label "Input Window"]
                         [width 300]
                         [height 200]))

(define text-field (new text-field% [parent frame]
                                   [label "Enter text here:"]
                                   [init-value ""]))

(define cancel-button (new button% [parent frame]
                                  [label "Cancel"]
                                  [callback (lambda (button event)                                              (send frame show #f))]))

(define ok-button (new button% [parent frame]
                              [label "OK"]
                              [callback (lambda (button event)                                          (send frame show #f)                                          (display (send text-field get-value))                                          (newline))]))

(send frame show #t)

Note that it correctly adds callbacks to each button, to close the window or display the input text!

1 Like

It fails to understand certain things about Racket functions, which is expected. For example, the following prompt generates a nice program, with missing required parameters for the controls. It's still a really nice try :

Prompt: Write a Racket GUI program that displays a large window, with two panels. The left panel contains a list box that lists the files in the current directory, and the right panel contains a text area that displays the text content of the file selected on the left side.

Result:

#lang racket

(require racket/gui/base)

;; define the main window
(define win (new frame% [label "File Viewer"]
[width 500]
[height 500]))

;; define the left panel (list box)
(define left-panel (new panel% [parent win]
[label "File List"]
[min-width 200]
[min-height 400]))

;; define the right panel (text area)
(define right-panel (new panel% [parent win]
[label "File Content"]
[min-width 300]
[min-height 400]))

;; define the list box for the left panel
(define file-list (new list-box% [parent left-panel]
[choices (directory-list ".")]
[min-width 200]
[min-height 400]))

;; define the text area for the right panel
(define text-area (new text-field% [parent right-panel]
[min-width 300]
[min-height 400]))

;; define the function that updates the text area when a file is selected
(define (update-text-area)
(let ([file-name (send file-list get-selection)]
[file-text (with-input-from-file file-name read-string)])
(send text-area insert file-text)))

;; connect the list box to the update function
(send file-list connect (lambda (x y) (update-text-area)))

;; show the main window
(send win show #t)

This would fail since (command-line-arguments) is a vector :stuck_out_tongue:

There's been lots of chatter on Slack and maybe also Discord about GPT + Racket.