Это хороший способ, чтобы реализовать позвольте-с?


Я реализовал давайте-с макроса, который принимает список ассоциации, ввел символы, что позволяет код, чтобы привязать их соответствующие значения для локальных переменных.

Он предназначен, чтобы иметь подобный эффект на JavaScript и С, но без Сс сопутствующими проблемами (вы явно указать переменные для связывания).

(define-syntax let-with
  (syntax-rules ()
    ((let-with alist (key ...) expr ...)
     (let ((key (cond ((assq 'key alist) => cdr))) ...) expr ...))))

Я хотел бы услышать любые усовершенствования позвольте-сс интерфейса и/или реализации.

Пример использования:

(define alist '((first . "Jane")
                (last . "Doe")))
(let-with alist (first last)
  (string-append first " " last))    ; "Jane Doe"

Ключи, которых не существует в входящие алист получает неопределенное значение; они не преминут вам привязан, в отличие от языка JavaScript с.



289
4
задан 23 марта 2011 в 04:03 Источник Поделиться
Комментарии
1 ответ

В JavaScript с заявлением позволяет изменять объект членами. Это может оказаться невозможным для некоторых типов значений (например, строк), используя давайте-с макро как определено выше.


Можно сделать вывод, позвольте-С , чтобы привязать значения из нескольких списков ассоциации. Он мог бы иметь вид:

(let-with
((alist0 (key00 key01 key02...))
(alist1 (key10 key11 key12...)))
expr0
expr1
...)

Помимо того, что более общий, в данной формы напоминает пусть форма. Я предпочитаю это по простой форме, хотя я бы понял, если ваш вкус и потребности отличаются.

Вот моя реализация общей форме--он использует два вспомогательных макросов, один для создания двух списков (журналистам и их соответствующие разделы), а другое излучать фактический код (который выглядит почти точно, как ваш выше определение):

(define-syntax let-with
(syntax-rules ()
((let-with bindings . body)
(gen-let-with bindings () () body))))

(define-syntax gen-let-with
(syntax-rules ()
((gen-let-with () alists keys body)
(emit-let-with-code alists keys body))
((gen-let-with ((alist (key)) . rest-bindings) alists keys body)
(gen-let-with
rest-bindings
(alist . alists)
(key . keys)
body))
((gen-let-with ((alist (key . rest-keys)) . rest-bindings) alists keys body)
(gen-let-with
((alist rest-keys) . rest-bindings)
(alist . alists)
(key . keys)
body))))

(define-syntax emit-let-with-code
(syntax-rules ()
((emit-let-with-code (alist ...) (key ...) (expr ...))
(let ((key (cond ((assq 'key alist) => cdr))) ...) expr ...))))

Возможно, есть более простое определение. Я не играл с макросами в некоторое время. =)


Вот некоторые примеры:

(define alist '((first . "Jane") (middle . "Q") (last . "Doe")))
(define blist '((first . "John") (middle . "R") (last . "Lee")))
(define clist '((first . "Jose") (middle . "S") (last . "Paz")))
(define first '((title . "Ms") (suffix . "Esq")))

(let-with
()
"Hello, world!") ; => "Hello, world!"

(let-with
((alist (first middle last)))
(string-append first " " middle ". " last)) ; => "Jane Q. Doe"

(let-with
((alist (first))
(blist (middle last)))
(string-append first " " middle ". " last)) ; => "Jane R. Lee"

(let-with
((alist (first))
(blist (middle))
(clist (last)))
(string-append first " " middle ". " last)) ; => "Jane R. Paz"

(let-with
((first (title))
(alist (first))
(blist (middle))
(clist (last))
(first (suffix)))
(string-append first " " middle ". " last)) ; => "Jane R. Paz"

(let-with
((alist (first middle last)))
(set! first "Rose")
(string-append first " " middle ". " last)) ; => "Rose Q. Doe"

(let-with
((alist (first middle last)))
(string-append first " " middle ". " last)) ; => "Jane Q. Doe"

Так давайте-с расширяется в единый давай, третий-на последний пример работает.

Последние два примера демонстрируют неспособность изменить значение в соответствующий список ассоциации.

2
ответ дан 19 апреля 2011 в 07:04 Источник Поделиться