Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

Criticize my code

Name: Anonymous 2011-11-09 9:25

I'm trying to do perl-style string formating:

(let ([a 1] [b 2])
  (say "a=$a, b=$b"))


Here is what I wrote so far:

(module snv mzscheme
(require (lib "defmacro.ss"))
(require (lib "list.ss"))
(require (lib "string.ss"))
(require-for-syntax (lib "string.ss"))
(require (only (lib "../srfi/13.ss")
               string-null?))

(require snv-hlp)
(require-for-syntax snv-hlp)

(provide (all-from snv-hlp))
(provide (all-from (lib "string.ss")))

(provide-define-macro (fmt xs)
  (let ([r '()]
        [s 0]
        [l (string-length xs)])
    (times i l
      (let ([x (string-ref xs i)])
        (when (char=? x #\$)
          (when (> (- i s) 0) (push (substring xs s i) r))
          (push #\$ r)
          (set! s (+ 1 i)))))
    (push (substring xs s l) r)
    (set! r (reverse! r))
    (letrec
        ((fold-fmt
          (lambda (xs)
            (if (null? xs)
                null
                (let ([x (car xs)])
                  (set! xs (cdr xs))
                  (cons
                   (cond [(eq? x #\$)
                          (when (null? xs)
                            (error "missing argument to $"))
                          (set! x  (car xs))
                          (set! xs (cdr xs))
                          (cond [(eq? x #\$) "$"]
                                [else
                                 (let ([l (string-length x)])
                                   (if (or (< l 3) (not (char=? (string-ref x 0) #\{)))
                                       (let* ([s (read-from-string x)]
                                              [sl (string-length (symbol->string s))])
                                         (set! x (substring x sl l))
                                         (if (not (string=? x "")) (push x xs))
                                         `(expr->string ,s))
                                       (read-from-string (substring x 1 (- l 1)))))])]
                         [else x])
                   (fold-fmt xs)))))))
      `(string-append ,@(fold-fmt r)))
    ))

(provide-define-macro (say x)
  `(printf "~a~n" (fmt ,x)))
 
) ;; module snv

Name: Anonymous 2011-11-09 9:39

Lisp is shit.

Name: Anonymous 2011-11-09 9:41

>>2
No.

Name: Anonymous 2011-11-09 9:53


;I'm trying to do perl-style string formating:

(let ([a 1] [b 2])
  (say "a=$a, b=$b"))


;Here is what I wrote so far:

(module snv mzscheme
(require (lib "defmacro.ss"))
(require (lib "list.ss"))
(require (lib "string.ss"))
(require-for-syntax (lib "string.ss"))
(require (only (lib "../srfi/13.ss")
               string-null?))

(require snv-hlp)
(require-for-syntax snv-hlp)

(provide (all-from snv-hlp))
(provide (all-from (lib "string.ss")))

(provide-define-macro (fmt xs)
  (let ([r '()]
        [s 0]
        [l (string-length xs)])
    (times i l
      (let ([x (string-ref xs i)])
        (when (char=? x #\$)
          (when (> (- i s) 0) (push (substring xs s i) r))
          (push #\$ r)
          (set! s (+ 1 i)))))
    (push (substring xs s l) r)
    (set! r (reverse! r))
    (letrec
        ((fold-fmt
          (lambda (xs)
            (if (null? xs)
                null
                (let ([x (car xs)])
                  (set! xs (cdr xs))
                  (cons
                   (cond [(eq? x #\$)
                          (when (null? xs)
                            (error "missing argument to $"))
                          (set! x  (car xs))
                          (set! xs (cdr xs))
                          (cond [(eq? x #\$) "$"]
                                [else
                                 (let ([l (string-length x)])
                                   (if (or (< l 3) (not (char=? (string-ref x 0) #\{)))
                                       (let* ([s (read-from-string x)]
                                              [sl (string-length (symbol->string s))])
                                         (set! x (substring x sl l))
                                         (if (not (string=? x "")) (push x xs))
                                         `(expr->string ,s))
                                       (read-from-string (substring x 1 (- l 1)))))])]
                         [else x])
                   (fold-fmt xs)))))))
      `(string-append ,@(fold-fmt r)))
    ))

(provide-define-macro (say x)
  `(printf "~a~n" (fmt ,x)))
 
) ;; module snv

Name: Anonymous 2011-11-09 10:17

>>3
Lisp is shit.

Name: Anonymous 2011-11-09 10:22

>>5
Do you prefer PHP?

Name: Anonymous 2011-11-09 10:54

>>4

Does it only support single character symbols? I don't see anything for scanning variable length symbols, and checking for delimiters like spaces. But anyways, if you wanted to, you could write some functional tail cally helper functions. A function that would be nice for scanning through the words and stepping over them, would be a function that when given an index into the string, finds the index of the first delimiter character (like a space I guess. scheme supports a lot of characters in symbols) after that index.


(define (index-of-word-ending str start)
  (letrec ([helper (lambda (end)
            (if (is (string-ref str end) a delimiter character? Use a hash set of delimiter characters for great [i]success![/i])
              end
              (helper (+ 1 end))))])
    (helper start)))


When you know the location of the delimiter character, you have enough information to both generate the substring representing the word you scanned, and to continue the scanning from the end of the word.

(define (scan-string str)
  (letrec ([scanner (lambda (s i l r)
                      (cond [(>= s l)
                             (reverse r)]
                            [(eq? (string-ref str s) #\$)
                             (let ([end (index-of-word-ending str s)])
                               (scanner end end l (cons (substring str s end)
                                                        (cons #\$ r))))]
                            [else (put some code here that scans from s to the index of the next dollar sign, and then push that onto r using tail call)]))])
    (scanner 0 0 (string-length str) '())))

Name: Anonymous 2011-11-09 11:24

>>6
PHP is diarrhoea.

Name: Anonymous 2011-11-09 11:52

php/perl/ruby style string interpolation in lisp

delete all your worthless code and re-read SICP

this is absolutely pathetic.

Name: Anonymous 2011-11-09 12:03

> (define value 1000)
(let ((value 1000)) (regexp-replace* "\\$([a-zA-Z]*)" "value is $value." (compose1 expr->string eval string->symbol cdr cons)))
"value is 1000."

Name: Anonymous 2011-11-09 12:39

>>9
Lisp is shit.
SICP is shit.

Name: Anonymous 2011-11-09 14:07

>>6
Once you steal the manchildren category of languages' interpolation feature they will HAVE NOTHING LEFT!

Name: Anonymous 2011-11-09 17:52

>>7
Does it only support single character symbols?
To work correctly it needs a fullblown SEXP parser and I havent found how to get number of readed symbols from `read-from-string`. But I did a simple parens parser, so I can write (say "1+2 = $(+ 1 2)")

With CL it was a little easier, as I reused host's parser.

Name: Anonymous 2011-11-09 17:59

>>9
`printf` makes it hard to see, where args come from, which is a source for common errors.

Also, `say` should be variadic, to make long lines possible:
(say "Name: $name\n"
     "Occupation: $occupation\n")

Don't change these.
Name: Email:
Entire Thread Thread List