As others have said, it sounds like you're overthinking it. For example, here's a simple and complete Racket program that you can paste into, e.g. test.rkt
and run from the command line using racket test.rkt
(Note: Prior posters have been mentioning the use of (module+ main ...) but that isn't strictly necessary.)
#lang racket
(define (factorial n)
(cond [(= n 0) 1] ; factorial of 0 is 1 by definition
[else (* n (factorial (- n 1)))])) ; e.g. in math, factorial(7) is (7 * factorial(6))
(displayln (factorial 5)) ; prints 120
Here's another example that does all the things you mentioned doing in Go. Again, you can copy/paste this into a .rkt file and run it from the command line:
#lang racket
; Example code responding to bsilver from the Racket Discourse,
; showing how Racket would do each of the things he mentioned doing in
; Go. His requests are preceded with '...', mine are in {}
(require racket/async-channel) ; ...you start with some imports...
; ...a package name
; {You don't need that in Racket}
(define (main) ; ...a main()
(define x (add1 7)) ; ...I can call another function that passes back the result
(displayln x) ; ...then call another function
(define y (* x 7)) ; ...just keep passing the data through these functions
(define ch (make-async-channel)) ; {create a channel (well, an `async-channel`, since `channel` is synchronous)}
(struct person (name age) #:transparent) ; {create that structure type you wanted, to be used later}
(async-channel-put ch y) ; ...hand them off to another routine via a channel
(thread
(thunk
; {create another thread to listen on the channel (not part of
; what you mentioned in Go but makes a good demonstration)}
(define age (sync ch)) ; {receive the value handed off through the channel}
(person 'bob age) ; ...that maybe passes the result to a structure
; {the above line creates an instance of structure type 'person'
; using the passed-in value for age. Hopefully that's what you
; meant by 'passes the result to a structure'}
(async-channel-put ch "Finished.") ; {tell the main thread that we're done}
))
; ...or through a network connection that was passed as an argument to it
(define socket (udp-open-socket))
(define udpport (udp-bind! socket "127.0.0.1" 22871)) ; {listen to UDP port 22871 on interface 127.0.0.1}
(do-network-thing udpport y)
(displayln (sync ch)) ; wait for a signal to come back on the channel, then clean up and finish
(udp-close socket)
)
(define (do-network-thing udpport val)
;...do something through a network connection that was passed as an argument to it.
; {I'm commenting this out because I don't want to actually deal with network code in an
; example, but it would send the byte string "hello, world" to the specified host
; machine/port}
;
; (udp-send-to socket target-host target-port #"hello, world")
; ...I need to check data at some point, I can write another function and just insert it into the flow.
;
; {Not sure what this means. Maybe anonymous functions? Racket's gotcha covered.
(when (equal? 11 val) ; {check the data}
((lambda (v) (display "inside anonymous func, v is: ") (displayln v)) val)) ;{write another function, insert it into the flow}
)
(main) ; {kick things off by calling main}