Search code examples
schemeracketvoidmap-function

Reading a file - where does '(#<void> ... #<void>) come from?


The following code is meant to display read text line-by-line:

#!/usr/bin/env racket
#lang racket/base

(require racket/string)
(require racket/file)


(require racket/file)
(display "Line by line with for loop:\n\n")
(define f "../file-to-be-read.short")
(define content (file->lines f))
(for ([l content]) (display l))
  
(define (do-sth-to-each-line fn-name) 
  (define f "../file-to-be-read.short")
  (define content (file->lines f))
  (map fn-name content))

(display "\n\nAnd now line by line with map and display:\n\n")
(do-sth-to-each-line display)

the code reads from ../file-to-be-read.short whose content is:

Not that I think you did not love your father,

But that I know love is begun by time,

And that I see, in passages of proof,

Time qualifies the spark and fire of it.

The result of the call to (do-sth-to-each-line display) is the following:

Not that I think you did not love your father,But that I know love is begun by time,And that I see, in passages of proof,Time qualifies the spark and fire of it.'(#<void> #<void> #<void> #<void> #<void> #<void> #<void>)

Where does '(#<void> #<void> #<void> #<void> #<void> #<void> #<void>) come from? Why doesn't (for ([l content]) (display l)) produce such unintended by me output?


Solution

  • #<void> is return value for display function, so '(#<void> #<void> #<void> #<void> #<void> #<void> #<void>) is result of map display over content (map and for both produce list of results, so for returns the same result).

    If you want to run some side effect for each element in the list, you should rather use for-each.

    Also, don't use define inside define, use let for introducing local variables, and consider using displayln:

    #lang racket
    (require racket/string)
    (require racket/file)
    
    (define (print-file filename) 
      (for-each displayln
                (file->lines filename)))
    
    (displayln "Now line by line with for-each and displayln:")
    (print-file "../file-to-be-read.short")