Numeric separator syntax: Difference between revisions
Thundergnat (talk | contribs) (→{{header|Perl 6}}: Add a Perl 6 example) |
mNo edit summary |
||
Line 1: | Line 1: | ||
{{draft task|Syntax}} |
{{draft task|Syntax}} |
||
Several programming languages allow separators in |
Several programming languages allow separators in numerals in order to group digits together. |
||
;Task: |
;Task: |
Revision as of 16:00, 30 August 2019
Several programming languages allow separators in numerals in order to group digits together.
- Task
- Show the numeric separator syntax and describe its specification. E.g., what separators are eligible? Can there be multiple consecutive separators? What position can a separator be in? Etc.
Perl 6
Perl 6 allows underscore as a grouping / separator character in numeric inputs, though there are a few restrictions.
<lang perl6># Any numeric input value may use an underscore as a grouping/separator character.
- May occur in nearly any position, in any* number. * See restrictions below.
- Int
say 1_2_3; # 123
- Binary Int
say 0b1_0_1_0_1; # 21
- Hexadecimal Int
say 0xa_bc_d; # 43981
- Rat
say 1_2_3_4.2_5; # 1234.25
- Num
say 6.0_22e4; # 60220
- There are some restrictions on the placement.
- An underscore may not be on an edge boundary, or next to another underscore.
- The following are all syntax errors.
- say _1234.25;
- say 1234_.25;
- say 1234._25;
- say 1234.25_;
- say 12__34.25;</lang>
Racket
Vanilla Racket does not have numeric separator syntax. However, it can be defined by users. For instance:
<lang racket>#lang racket
(require syntax/parse/define
(only-in racket [#%top racket:#%top]) (for-syntax racket/string))
(define-syntax-parser #%top
[(_ . x) #:do [(define s (symbol->string (syntax-e #'x))) (define num (string->number (string-replace s "_" "")))] #:when num #`#,num] [(_ . x) #'(racket:#%top . x)])
1_234_567.89 1_234__567.89</lang>
- Output:
1234567.89 1234567.89
In the above implementation of the syntax, _
is the separator. It allows multiple consecutive separators, and allows the separator anywhere in the numeral (front, middle, and back).
Implementation details: any token with _
is considered an identifier in vanilla Racket. If it's not defined already, it would be unbound. We therefore can define #%top
to control these unbound identifiers: if the token is a number after removing _
, expand it to that number.
If we wish to disallow multiple consecutive separators like 1_234__567.89
, we could change it easily:
<lang racket>#lang racket
(require syntax/parse/define
(only-in racket [#%top racket:#%top]) (for-syntax racket/string))
(define-syntax-parser #%top
[(_ . x) #:do [(define s (symbol->string (syntax-e #'x))) (define num (string->number (string-replace s "_" "")))] #:when num (syntax-parse #'x [_ #:fail-when (string-contains? s "__") "invalid multiple consecutive separator" #`#,num])] [(_ . x) #'(racket:#%top . x)])
1_234_567.89 1_234__567.89</lang>
- Output:
1_234__567.89: invalid multiple consecutive separator in: 1_234__567.89