Questions Regarding My First Program

28 views
Skip to first unread message

IF Karona

unread,
Feb 23, 2021, 5:59:23 PM2/23/21
to Racket Users
Hi everyone,

I am new here, and I have a couple of questions related to the code that follows this message.

1. I want to learn functional programming. When it comes to solving the problem of making a simple chatbot such as this, is there an approach that is more consistent with functional programming?
2. I would prefer to not have to use multiple spaces every time I want to indent. Does Dr. Racket have anything comparable to the tab functionality of other programs?

Thank you for letting me join your community!

Karona

;example.rkt

#lang racket

(require racket/match)

(define (say str)
    (printf "Chatbot: ~a\n" str))

(define (handle-input str)
    (cond
      
        [(regexp-match #px"(?i:Hello,* world!)" str)
            (say "I would not know about the rest of the world, but I can hear \
you just fine.")]
      
        [(regexp-match #px"(?i:I( am|'m) learning how to program in Racket,* world!)" str)
            (say "Racket is a great language, and it is lovely that you are \
learning it, but does literally everyone need to know?")]

        [(regexp-match #px".*,+\\s*world!" str)
            (say "Did the whole world really need to hear that?")]
      
        [else (say "Did you really just say something without addressing the \
world? I am so proud of you! :,)")]))

(let loop ()
    (display "Input: ")
    (define str (read-line (current-input-port) 'any))
    (handle-input str)
    (loop))

Sage Gerard

unread,
Feb 23, 2021, 7:05:21 PM2/23/21
to racket...@googlegroups.com

I can't speak to DrRacket since I never use it, so I'll focus more on the first question.

Functional programming typically deals with these considerations (among others):

  • Write functions that return values purely in terms of arguments.
  • Defer side-effects until you can't.

A goal to make the program produce the same output given the same input, every time.

One example would be to redefine `say` such that it doesn't immediately print. Maybe just return the string you want said.

(define (say str)
  (format "Chatbot: ~a\n" str))

(I'd personally use a struct representing a message, sender, etc. but that's beside the point)

This change makes the function "pure" in that the same input returns the same output, and there are no side-effects in doing so. But this creates a problem where you need to "rope in" that value somewhere. How that happens depends on the program. A program that reports download progress will handles side-effects differently than a program that prints a report before stopping.

One approach is to update program state in the same (functional) way. If we assume the chat history is a list, where the first element is the most recent message, then this version of `say` adds a string to the chat.

(define (say chat-history str)
  (cons (format "Chatbot: ~a\n" str)

        chat-history))

I'd start with this kind of thinking until you get to the point where side-effects are unavoidable. Since your program appears interactive, you can still print in the loop. But think about what your program would be like if you print ONLY in that loop.

Others can probably say more, but hopefully this helps you start.

--
You received this message because you are subscribed to the Google Groups "Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/2f107ab5-2efd-4c33-83f6-eb5751664cb6n%40googlegroups.com.
--
~slg

John Clements

unread,
Feb 23, 2021, 7:30:42 PM2/23/21
to Sage Gerard, racket...@googlegroups.com
I *always* use DrRacket… but I admit I may not understand the indenting part of your question.

In DrRacket, when you hit the “tab” key, it should move the text on the line to the “correct” position, according to Racket’s indentation rules. Also, whenever you hit return, the cursor should be automatically indented to the appropriate column. Finally, you can highlight a block of text and hit “tab”, and it will all be re-indented.

Is this different from what you’re observing, or from what you’re expecting?

John Clements
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/d3da9796-979d-cad9-36e5-91380939630c%40sagegerard.com.

Reply all
Reply to author
Forward
0 new messages