Вопрос достаточно наивный -- почему в sum-list рекурсия не сворачивается
в цикл?
(define summator
(lambda (initial-value)
(lambda (proc)
(proc
(lambda (value) (summator (+ initial-value value)))
initial-value))))
(define sum-list
(lambda (list-arg)
(let loop ((current-summator (summator 0))
(rest-list list-arg))
(current-summator
(lambda (next-proc result)
(if (null? rest-list)
result
(loop (next-proc (car rest-list))
(cdr rest-list))))))))
Это из-за замыкания lambda (next-proc result)? Если да, то как переписать
код, чтобы сворачивалось? :)
my @packCharacters = ('0'..'9', 'A'..'Z');
my %unpackCharacters;
my $decimalValue = 0;
map { $unpackCharacters{$_} = $decimalValue++ } @packCharacters;
sub packLongId
{
my $id = shift;
my $base = scalar @packCharacters;
my $packedId = '';
for ( my $currentValue = $id; $currentValue > 0; $currentValue = int($currentValue / $base) )
{
$packedId .= $packCharacters[ $currentValue % $base ];
}
return join "", reverse split //, $packedId;
}
sub unpackLongId
{
my $packedId = shift;
my $base = scalar @packCharacters;
my $id = 0;
my $currentPower = 1;
map
{
$id += $unpackCharacters{$_} * $currentPower;
$currentPower *= $base;
} reverse split //, $packedId;
return $id;
}
Переводит, вроде, нормально, но на больших числах начинает лажать.
packLong(11764992501273288845) => 2HDUTRXH5G84T
unpackLong("2HDUTRXH5G84T") => 11764992501273290285 ???
Накопал в цпане Math::BaseCalc, но он лажает точно так же
Застрял с реализацией потоков на схеме :(
Основные определения у меня такие:
(define-macro (stream-cons p q)
(let
((pv (gensym)) (qv (gensym)))
`(let
((,pv (lambda () ,p)) (,qv (lambda () ,q)))
(lambda (f) (f ,pv ,qv)))))
(define stream-car
(lambda (s) (s (lambda (p q) (p)))))
(define stream-cdr
(lambda (s) (s (lambda (p q) (q)))))
(define stream-for-each
(lambda (func stream)
(if (null? stream)
'done
(begin
(func (stream-car stream))
(stream-for-each func (stream-cdr stream))))))
(частично спер из sicp, частично подогнал под свои нужды).
Простенький поток типа (define ones (stream-cons 1 ones)) работает
отлично, stream-for-each можно пустить по нему навечно.
Однако что-нибудь чуток посложнее, почему-то, начинает жрать память:
(define stream-map
(lambda (func . streams)
(if (or
(null? streams)
(< 0
(apply +
(map (lambda (s) (if (null? s) 1 0)) streams))))
'()
(stream-cons
(apply func (map stream-car streams))
(apply
stream-map
(cons func (map stream-cdr streams)))))))
(define nums (stream-cons 1 (stream-map + ones nums)))
или даже
(define number-stream
(lambda (number) (stream-cons number (number-stream number))))
Стоит пустить по такому потоку stream-for-each, рано или поздно он
сломается от того, что сожрет всю оперативку.
Второй день уже не могу разобраться. Есть подозрение, что где-то я
скосячил в определениях. Возможно, кто-нибудь сможет мне помочь?
Изучаю сейчас сабж, и у меня возникли некоторые затруднения. Предположим, передо мной стоит простая задача: реализовать операции добавления числа и умножения на число некой последовательности чисел. Как это грамотно сделать с точки зрения функционального программирования?
В sicp предлагается вариант некого подобия ОО, это бы выглядело так:
(define make-sequence
(lambda (values-list)
(lambda (message)
(cond
((equal? message 'add)
(lambda (number)
(make-sequence
(map (lambda (value) (+ value number))
values-list))))
((equal? message 'scale)
(lambda (number)
(make-sequence
(map (lambda (value) (* value number))
values-list))))
(else
(display "Wrong message for make-sequence"))))))
И потом использование:
(define s (make-sequence (list 0 1 2 3)))
((s 'add) 4)
((s 'scale) 2)
Но, что-то, меня смущает эта псевдо-диспетчеризация :) А если мне надо будет миллион раз вызвать (s 'add), он ведь будет миллион раз делать cond, хотя я же явно ему указываю, что я хочу.
С другой стороны, мне явно надо определять нужные операции внутри make-sequence, чтобы получить замыкание, иначе придется все параметры передавать еще куда-то дальше, а если их не один, а десять, это тоже накладно :(
Сходу я придумал такой вариант, с возвращением списка замыканий:
(define make-sequence
(lambda (values-list)
(list
(lambda (number)
(make-sequence
(map (lambda (value) (+ value number))
values-list)))
(lambda (number)
(make-sequence
(map (lambda (value) (* value number))
values-list))))))
(define sequence-add
(lambda (sequence number)
((car sequence) number)))
(define sequence-scale
(lambda (sequence number)
((cadr sequence) number)))
И использование:
(define s (make-sequence (list 0 1 2 3)))
(sequence-add s 4)
(sequence-scale s 2)
Тут много можно под макросы упаковать, но для наглядности я оставил так. Сразу видны минусы: чтобы выполнить операцию, надо ползти по списку, что тоже должно быть накладно :(
Есть какая-нибудь устоявшаяся практика в реализации таких вещей?
Народ, а кто-нибудь уже делал или видел поддержку java generics в jde-mode? Или все-таки самому писать придецца?
Мб боян, но плз объясните мне, как закореннелому пользователю bsd, почему вы постоянно так активно возитесь с дистрибутивами? "Понравились шрифты в Kubuntu - заменил на нее FC" ~(c)
Ядро-то одно, неужели нельзя поставить один единственный дистрибутив (все равно какой) и потом на него уже вешать все, что требуется? Зачем ради emerge ставить генту, когда этот же емерж можно поставить пакаджем к слакваре?
Система: P4 2.4 512 Mb RAM, FreeBSD 5.3 / xorg 6.8.2 / ion3
Не так давно я делал portupgrade kde (у меня был 3.3), а в процессе экспериментировал с различными wm.
Когда дело дошло до иона, я в последствии так на нем и остался и новый кде уже стал не нужен :) Это действительно самый гибкий и удобный wm, который мне когда-либо доводилось видеть.
На скрине первый виртуальный десктоп (xmms и psi c 18 открытыми чат-окнами (один из них rss)). На втором у меня фаерфокс, на третьем kdevelop, на четвертом konsole (заметьте, все имеют собственные табы - они рулят), в пятом обычно запускается что-нибудь ненадолго.
Для статусбара я написал два собственных расширения (lua осваивается за 20 минут), один через sysctl считает загрузку процессора, другой выводит количество новых сообщений в псе (считает звездочки в заголовках :)) - очень удобно следить за ответами, когда сидишь в другом виртуальном десктопе
Однозначно всем рекомендую - скорость и удобство работы совершенно несравнимы с обычными реализациями оконных менеджеров
>>> Просмотр ( 1024x768, 76 Kb )