Трудность в понимании использования let и лямбды в Scheme

Мне трудно понять объем следующего кода:

 (define (create-counter (x 1))
(let ([count 0])
(lambda()
(let ([temp count])
(set! count (+ x count)) temp))))

если я использую:

(let ((c (create-counter ))) (+ (c) (c) (c) (c)))

код работает, однако, если я попытался с:

(+ (create-counter)(create-counter)(create-counter)(create-counter))

Это не работает и дает мне 0. Может кто-нибудь, пожалуйста, помогите мне понять это полностью? если возможно, пожалуйста, сравните с другим языком, таким как C / C ++, мне было бы легче поймать это. Спасибо

1

Решение

(define (create-counter (x 1))
(let ([count 0])
(lambda()
(let ([temp count])
(set! count (+ x count)) temp))))

Переводится на:

auto create_counter(int x=1){
int count=0;
return [x,count]()mutable{
int r=count;
count+=x;
return r;
};
}

Простая функция C ++ 14, возвращающая объект замыкания.

Когда вы делаете это:

(let ((c (create-counter ))) (+ (c) (c) (c) (c)))

Это:

auto c = create_counter();
auto r = c()+c()+c()+c();
return r;

Он создает один счетчик, затем запускает его 4 раза, возвращая 0 1 2 3 и добавляя к 6.

В этом случае:

(+ ((create-counter))((create-counter))((create-counter))((create-counter)))

Это:

auto r = create_counter()()+create_counter()()+create_counter()()+create_counter()();
return r;

Который создает 4 счетчика и запускает каждый из них один раз. При первом запуске счетчика вы получаете 0. Так что это добавляет к 0.

Закрывающий объект имеет состояние. Он возвращает большее число каждый раз, когда вы звоните.

Теперь вы можете быть не знакомы с C ++ 11/14 lamnda.

auto create_counter(int x=1){
int count=0;
return [x,count]()mutable{
int r=count;
count+=x;
return r;
};
}

Является

struct counter {
int x,count;
int operator()(){
int r=count;
count+=x;
return r;
};
};
counter create_counter(int x=1){
return {x,0};
}

с некоторым синтаксисом сахара.

Я исправил синтаксическую ошибку в исходном коде. Я не эксперт, так что, возможно, я ошибся.

Кроме того, счетчик создания briefer выглядит так:

auto create_counter(int x=1){
return [=,count=0]()mutable{
int r=count;
count+=x;
return r;
};
}
2

Другие решения

Когда вы вызываете «create-counter», он создает счетчик, а затем возвращает процедуру, которая ссылается на этот конкретный счетчик. Когда вы вызываете «create-counter» четыре раза, вы создаете четыре отдельных счетчика; каждая процедура относится к своему счетчику. Когда вы вызываете «create-counter» один раз, а затем получающуюся процедуру четыре раза, она создает только один счетчик и увеличивает его четыре раза.

Сложно сравнить это с C, поскольку C и C ++ довольно слабы в области замыканий; нелегко вернуть функцию, определенную внутри другой функции.

Ближайшим аналогом может быть «встречный» объект в C ++; думать о «create-counter» как о конструкторе для объекта, содержащего одно целое число, а результирующую процедуру — как о методе «increment», который увеличивает счетчик, содержащийся в этом объекте. Во втором примере вы создаете четыре отдельных объекта, а в первом примере вы создаете один объект и вызываете его метод «приращения» четыре раза.

2

По вопросам рекламы [email protected]