String Formatting in Scheme

(import (chicken format)
        (chicken io))

(define-record-type point
  (make-point x y)
  point?
  (x point-x)
  (y point-y))

(define (main)
  ; Scheme offers several formatting options for various data types.
  ; Here's an example of formatting a point struct.
  (let ((p (make-point 1 2)))
    (printf "struct1: ~A\n" p)

    ; To include field names, we can define a custom formatting function
    (printf "struct2: ~A\n" 
            (format #f "{x:~A y:~A}" (point-x p) (point-y p)))

    ; For a representation similar to source code:
    (printf "struct3: ~A\n" 
            (format #f "#(point ~A ~A)" (point-x p) (point-y p)))

    ; To print the type of a value:
    (printf "type: ~A\n" (format #f "~S" (type-of p)))

    ; Formatting booleans
    (printf "bool: ~A\n" #t)

    ; Formatting integers
    (printf "int: ~D\n" 123)

    ; Binary representation
    (printf "bin: ~B\n" 14)

    ; Character representation
    (printf "char: ~C\n" #\!)

    ; Hexadecimal representation
    (printf "hex: ~X\n" 456)

    ; Formatting floats
    (printf "float1: ~F\n" 78.9)

    ; Scientific notation
    (printf "float2: ~E\n" 123400000.0)
    (printf "float3: ~E\n" 123400000.0)

    ; String formatting
    (printf "str1: ~S\n" "\"string\"")

    ; Double-quoted strings
    (printf "str2: ~S\n" "\"string\"")

    ; Hexadecimal representation of a string
    (printf "str3: ~X\n" (string->list "hex this"))

    ; Pointer representation (not directly available in Scheme)
    (printf "pointer: ~A\n" (format #f "0x~X" (object-address p)))

    ; Controlling width for integers
    (printf "width1: |~6D|~6D|\n" 12 345)

    ; Controlling width and precision for floats
    (printf "width2: |~6,2F|~6,2F|\n" 1.2 3.45)

    ; Left-justifying floats
    (printf "width3: |~6,2@F|~6,2@F|\n" 1.2 3.45)

    ; Controlling width for strings
    (printf "width4: |~6A|~6A|\n" "foo" "b")

    ; Left-justifying strings
    (printf "width5: |~6@A|~6@A|\n" "foo" "b")

    ; Using format to return a string
    (let ((s (format #f "format: a ~A" "string")))
      (print s))

    ; Writing to a different output port
    (fprintf (current-error-port) "io: an ~A\n" "error")))

(main)

This Scheme code demonstrates various string formatting techniques similar to those in the original Go example. Here are some key points:

  1. We use the (chicken format) and (chicken io) modules for formatting and I/O operations.

  2. We define a point record type to mimic the struct in the Go example.

  3. The printf function is used for most formatting operations, similar to Go’s fmt.Printf.

  4. Scheme’s formatting specifiers are different from Go’s. For example, ~A is used for general formatting, ~D for integers, ~F for floats, etc.

  5. Some operations, like getting a pointer representation, are not directly available in Scheme. We use object-address as an approximation.

  6. Width and precision control is done using ~w,dF syntax, where w is the width and d is the number of decimal places.

  7. Left-justification is achieved using the @ modifier.

  8. The format function is used to create formatted strings without printing them.

  9. fprintf is used to write to different output ports, similar to Go’s fmt.Fprintf.

Note that Scheme’s formatting capabilities may not exactly match Go’s in all cases, but this example provides a close approximation of the functionality demonstrated in the original Go code.