Create suffixed numbers Racket

string-append racket
number to string racket
cons racket
check-within racket
racket format
racket functions
continue racket
racket documentation

I'm trying to experiment with what I can do in Racket, and I want to suffix numbers with letters.

For this example, I'd simply like to represent 10000 as 10K, and 1000000 as 1M.

Is there way (with macros or otherwise) that I can expand 1M to:

(* 1 1000000)

Or something to that effect?

In Racket, things like 10K are identifiers, which normally would refer to variables. There are two ways to make them into numbers:

1: redefine what "undefined" identifiers mean

You can redefine what to do on an undefined identifier by defining a #%top macro.

#lang racket
(require syntax/parse/define
         (only-in racket [#%top old-#%top]))

(define-syntax-parser #%top
  [(_ . x:id)
   #:when (id-has-a-k-at-the-end? #'x)
   (transform-id-into-number #'x)]
  [(_ . x)
   #'(old-#%top . x)])

However, this has a subtle problem. If there are any identifiers or variables in your program with K's on the end, they could override any numbers that were written that way. You would need to be careful not to accidentally override something that was intended to be a number.

2: make a reader extension that turns them into numbers instead of identifiers

This will take more time, but it's closer to the "right way" to do this, since it avoids conflicts when variables happen to have K's on the end.

One of the easier ways to extend the reader is with a readtable. You can make a function that extends a readtable like this:

;; Readtable -> Readtable
(define (extend-readtable orig-rt)
  ;; Char InputPort Any Nat Nat Nat -> Any
  (define (rt-proc char in src ln col pos)
    ....)
  ...
  (make-readtable orig-rt
    #f 'non-terminating-macro rt-proc
    ...))

To use this to define a #lang language, you need to put the reader implementation in your-language/lang/reader.rkt. Here that's number-with-k/lang/reader.rkt, where the number-with-k directory is installed as a single-collection package (raco pkg install path/to/number-with-k).

number-with-k/lang/reader.rkt

#lang racket

(provide (rename-out [-read read]
                     [-read-syntax read-syntax]
                     [-get-info get-info]))

(require syntax/readerr
         syntax/module-reader)

;; Readtable -> Readtable
(define (extend-readtable orig-rt)
  ;; Char InputPort Any Nat Nat Nat -> Any
  (define (rt-proc char in src ln col pos)
    ....)
  ...
  (make-readtable orig-rt
    #f 'non-terminating-macro rt-proc))

;; [X ... -> Y] -> [X ... -> Y]
(define ((wrap-reader rd) . args)
  (parameterize ([current-readtable (extend-readtable (current-readtable))])
    (apply rd args)))

(define-values [-read -read-syntax -get-info]
  (make-meta-reader 'number-with-k
                    "language path"
                    lang-reader-module-paths
                    wrap-reader
                    wrap-reader
                    identity))

The main work goes into filling in the .... holes in the extend-readtable function. For example, you can make it recognize identifiers that end with K like this:

;; Readtable -> Readtable
(define (extend-readtable orig-rt)
  ;; Char InputPort Any Nat Nat Nat -> Any
  (define (rt-proc char in src ln col pos)
    (define v (read-syntax/recursive src in char orig-rt #f))
    (cond
      [(and (identifier? v) (id-has-a-k-at-the-end? v))
       (transform-id-into-number v)]
      [else
       v]))

  (make-readtable orig-rt
    #f 'non-terminating-macro rt-proc))

Once this is done, and you have the number-with-k directory installed as a package, you should be able to use #lang number-with-k like this:

#lang number-with-k racket

(+ 12K 15)
; => 12015

4.4 Strings, Creates a string of n characters by applying proc to the integers from 0 to (sub1 n) in between the last two strings, a prefix string, and a suffix string respectively. The ~a function is primarily useful for strings, numbers, and other atomic data. 4.3 Numbers. Numbers in The Racket Guide introduces numbers.. All numbers are complex numbers.Some of them are real numbers, and all of the real numbers that can be represented are also rational numbers, except for +inf.0 (positive infinity), +inf.f (single-precision variant, when enabled via read-single-flonum), -i nf.0 (negative infinity), -inf.f (single-precision variant, when enabled

The simplest to is to define the suffixes you need.

(define K 1000)
(define M 1000000)

Then write (* 3.14 M) for 3.14 millions.

As others mention, Racket supports scientific notation 3.14E6 is also 3.14 million.

Yet another alternative is to define functions K, M etc like:

(define (M x) (* x 1000000))

Then you can write

(M 3.14)

to mean 3.14 million.

1 Beginning Student, create a sorted version of the given list of numbers Determines whether some value is on the list if so, it produces the suffix of the list that starts with x if not,  Vertices can be any Racket values comparable with equal?. If a list of weights is provided, then the result is a weighted graph. Otherwise, the result is an unweighted graph. The number of weights must equal the number of edges. Non-existent edges return an infinite weight, even for non-existent vertices.

Racket does already have built in support for this, kind of, via scientific notation:

1e6 ; 1000000.0 ("1M")
2e7 ; 20000000.0

Numbers, A number can be written with one or both parts. You write the imaginary part of a complex number by appending an Xi suffix, where X is any real number. A  A list is immutable. That is, the value ' (1 2 3) is as unchanging as the numbers 1, 2, and 3 within the list. You can’t change a list to add new elements to it— but you can create a new list that is like the old one, except that it has another element.

[PDF] The Racket Guide, Racket values include numbers, booleans, strings, and byte strings. make-add-​suffix always refers to the argument for the call that created the function. In. The Racket Reference 4.3.1 Number Types. procedure If x is already a single-precision floating-point number, it is returned. procedure

CSC 270 Homework 3, This assignment is to be done in PLT Scheme/Racket. Develop a function suffixes which takes in a list (of strings, numbers, symbols, it doesn't matter) and  Josh Grant. Apparently, this user prefers to keep an air of mystery about them. 3 Create suffixed numbers Racket Nov 29 '18. 0 Creating a large random number

4 Intermediate Student with Lambda, Create suffixed numbers Racket. I'm trying to experiment with what I can do in Racket, and I want to suffix numbers with letters. For this example, I'd simply like to  =~ : (number number non-negative-real -> boolean) Purpose: to check whether two numbers are within some amount (the third argument) of either other eof : eof

Comments
  • I thought of #%top as well, and you could use identifier-binding to check whether the identifier already has a binding - if it does, you probably want to skip the transformation.
  • An identifier-binding check would not be enough to avoid the problems, because if the identifier is defined, it won't invoke #%top in the first place.