LINUX.ORG.RU

Code review

 , ,


1

2

Продолжаю изучать лисп, пока еще нахожусь в самом-самом начале пути. Вот накидал классику - вычисление корней квадратного уравнения ( http://pastebin.com/HZrUN02k ).

С удовольствием выслашую советы как по оформлению кода, так и по реализации. Единственное дополнение - я использую табы шириной в 4 символа, но не нашел, как выставить ширину табов на pasterbin.com

Меня больше всего смущает возврат значения из функции calcX, мне кажется, что я это делаю не совсем верно.

Новая версия http://pastebin.com/h61E3gE1

Новая версия http://pastebin.com/mKJgvdAp

★★★★★

Последнее исправление: trex6 (всего исправлений: 4)

урованения

Русский тоже подучить не мешало бы.

По поводу стиля: все закрывающиеся скобки нужно оставить на последней строке кода.

По поводу возврата значения: убери x и setq x и возвращай просто результат исполнения функции.

feofan ★★★★★
()
Ответ на: комментарий от qaqa

QtCreator, но это сегодня, в прошлый раз была pluma. В QtCreator загрузил подсветку для синтаксиса, но не хватает автодополнения определенных мною функций и подсветки парных скобочек. Еще пробовал emacs, но пока что только начала вводного мануала прочитал и все.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

Если собираешься и дальше изучать, лучше осиль emacs. И советую выбрать другую реализацию — gcl неполноценен.

feofan ★★★★★
()
Ответ на: комментарий от feofan

Русский тоже подучить не мешало бы.

Спасибо за подсказку, исправился.

Я привык в C++ писать что-то типа

int funcName()
{
    int result = DEFAULT_VALUE;

    if( needAnotherValue)
    {
        result = ANOTHER_VALUE;
    }

    return result;
}

Вместо

int funcName()
{
    if( needAnotherValue)
    {
        return ANOTHER_VALUE;
    }

    return DEFAULT_VALUE;
}

Как подобный стиль применить в lisp? Или это будет для lisp совсем чуждо?

trex6 ★★★★★
() автор топика
Ответ на: комментарий от feofan

лучше осиль emacs

Да я понимаю, но пока что решил упор на язык сделать, а когда синтаксис и основные подходы пойму, буду изучать emacs.

И советую выбрать другую реализацию — gcl неполноценен

Совсем-совсем? Или для первичного изучения языка пойдет? Какую из реализаций посоветуешь?

trex6 ★★★★★
() автор топика
Ответ на: комментарий от bhfq

Еще бы, это ведь первое, что я написал. А конкретные советы по улучшению будут? Как это было бы правильно сделать?

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

смотря, что тебе нужно. Для начала хватит clisp. Потом сам выберешь.

feofan ★★★★★
()
Ответ на: комментарий от trex6

Можно так писать, но лисп располагает больше писать в функциональном стиле. Можно исключить лишние присвоения.

feofan ★★★★★
()
Ответ на: комментарий от trex6

Примерно так можно:

(defun read-int (print-name)
	(format t print-name)
	(read))


(defun square ()
	(let ((a (read-int "a="))
              (b (read-int "b="))
	      (c (read-int "c=")))
	(format t "a*x^2 + b*x + c = 0~%")
	(print-result 
		a b c
		(calcX a b c))))

Ну и calcX в таком же духе стоит переписать.

И ещё в Lisp не принят CamelCase. Вместо него используется some-name-define.

P.S. код не проверял, сейчас нету ничего под рукой.

Norgat ★★★★★
()
Ответ на: комментарий от Norgat

И ещё в Lisp не принят CamelCase. Вместо него используется some-name-define.

[ ACCEPTED ]

read-int

Думал про это, но руки еще не дошли. Учел.

код не проверял, сейчас нету ничего под рукой.

Да вроде бы верно все считает )))

trex6 ★★★★★
() автор топика

Непривычная индентация, закрывающие скобки на отдельной строке, camelCase вместо hyphen-delimited-names. Неплохой style guide: http://google-styleguide.googlecode.com/svn/trunk/lispguide.xml

Рекомендую пользоваться lisp-aware редактором (Emacs). Ну и sbcl вместо gcl.

theNamelessOne ★★★★★
()

(if (< b 0) (setf bSign "") ())

Вместо if без false-ветки лучше использовать when

theNamelessOne ★★★★★
()
                                                )
                                        )
                                )
                                (setq x () )
                        )
                )
                x
        )
)

Когда IDE сообщает что скобок много или не хватает такое становится не нужно. Вообще, для лиспов лучше всего таки Emacs. Я за него серьёзно взялся когда писал на Clojure - теперь всё в нём делаю.

Ну и как уже заметили - CamelCase это не лисповейно. Хотя в той же самой Clojure приходится его в некоторых случаях юзать как компромисс с JVM.

Debasher ★★★★★
()
Последнее исправление: Debasher (всего исправлений: 1)

Из setf и setq лучше выбрать что-то одно, лучше (ИМХО) первое.

(eql d 0)(zerop d)

Про выделение кода чтения значения коэффициента уже сказали.

theNamelessOne ★★★★★
()
Последнее исправление: theNamelessOne (всего исправлений: 1)

В calcX совершенно не нужные присваивания. Да и вообще у тебя их слишком много.

В общем, с учётов всего вышесказанного твой код может выглядеть так:

(defun read-var (name)
  (format t "~a=" name)
  (finish-output)
  (read))

(defun print-result (a b c x)
  (format t "Root(s) of square equation ~dx^2~@dx~@d=0: ~a~%"
          a b c x))

(defun calc-x (a b c)
  (let ((d (- (* b b) (* 4 a c))))
    (cond ((plusp d)
           (list (/ (+ b (sqrt d))
                       (* 2 a))
                    (/ (- b (sqrt d))
                       (* 2 a))))
          ((zerop d)
           (list (/ (- b) (* 2 a)))))))

(defun square ()
  (format t "a*x^2 + b*x + c = 0~%")
  (let* ((a (read-var "a"))
         (b (read-var "b"))
         (c (read-var "c")))
    (print-result a b c (calc-x a b c))))

PS. На самом деле у квадратного уравнения всегда два корня.

theNamelessOne ★★★★★
()
Ответ на: комментарий от theNamelessOne

PS. На самом деле у квадратного уравнения всегда два корня.

Ага, но ведь это учебный пример.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

Та же претензия, что и к предыдущей версии: лишние присваивания. Делай инициализацию при объявлении привязки в let. В том коде присваивания оправданы лишь для вычисления переменных bSign, cSign, без которых тоже можно обойтись, если воспользоваться модификатором at-sign директивы D (см. форматную строку для print-result тут).

Ну и (if (< b 0) (setf bSign "") ())(when (minusp b) (setf bSign ""))

theNamelessOne ★★★★★
()
Последнее исправление: theNamelessOne (всего исправлений: 1)
Ответ на: комментарий от theNamelessOne

when
minusp
форматную строку для print-result

Я ведь еще только-только вторую главу «ANSI Common Lisp» дочитал, так что все это у меня еще впереди. Но все равно спасибо.

trex6 ★★★★★
() автор топика
Последнее исправление: trex6 (всего исправлений: 1)
Ответ на: комментарий от theNamelessOne

лишние присваивания

Не очень понимаю как избавится от

(setf d (- (* b b) (* 4 a c)))
если необходимо дважды проверить значение d - на положительность и на равенство нулю. Сейчас не рассматриваем упрощение кода (действительно, можно два раза вычислить один и тот же корень и выкинуть на мороз calc-single-x), но мы попробуем это не учитывать. Примем как догму то, что нам необхдимо дважды оценить значение выражения.

Или подразумевается перенос этого из setf в let?

trex6 ★★★★★
() автор топика
Последнее исправление: trex6 (всего исправлений: 1)
Ответ на: комментарий от yyk

Ну так ведь ЛОР наше усё. Надо будет там зарегистрироваться, но пока что руки не доходят.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от yyk

Собственно при попытке войти выдает

Not Found
The requested URL /login was not found on this server.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от ugoday

Вообще на вкус и цвет, но пока язык изучаешь надо приучать себя к хорошему.

Интересует почему разное выравнивание выполняемого оператора в let (ф-ии square и print-result).

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

Вообще на вкус и цвет,

Бытиё определяет сознание. В данном случае, всё зависит от инструментария. Большинство лисперов используют slime, а его возможности и стиль форматирования по-умолчанию диктуют именно такой стель.

надо приучать себя к хорошему.

Зайди на cliki.net посмотри в каком стиле все оформляют исходник.

почему разное выравнивание выполняемого оператора в let (ф-ии square и print-result).

Моя невнимательность. как в square --- правильно.

ugoday ★★★★★
()

Поставь себе Lispbox. Оно уже скорее всего протухло, но для начального ознакомления с CL пока не знаешь Emacs вполне достаточно. Это по сути и есть Emacs с забанлденным CL. Я когда начинал изучать лиспы, пользовался им как обычным текстовым редактором, запомнил C-x C-s и мне хватало.

unlog1c ★★★
()

Да всё не так

Ты не знал, что в CL есть комплексные значения?

shamaz
()

Да че вы прицепились к пацану, скобки не там, отступы не такие... Можно подумать, он лисп учит, чтобы программы на нем писать?

anonymous
()
(defun solve-square-eq (a b c)
  (let* ((b% (/ b a))
           (c% (/ c a))
           (f1 (- (/ b% 2)))
           (f2 (sqrt (- (/ (expt b% 2) 4) c%))))

      (values (- f1 f2)
                   (+ f1 f2))))

Используй clisp и repl, а не хрень какую-то и скрипт.

shamaz
()
Ответ на: комментарий от anonymous

а для чего еще

Для того, чтобы смотреть на всех, как на говно, разумеется. Для чего еще можно изучать лисп?

anonymous
()
Ответ на: комментарий от anonymous

для того же, что и покупают последние гейфоны, машини и все то, что дает чуство илитарности.

Deleted
()
Ответ на: комментарий от Deleted

для того же, что и покупают последние гейфоны, машини и все то, что дает чуство илитарности.

Использование линукса туда же запиши.

unlog1c ★★★
()
Ответ на: комментарий от anonymous

Какой эффект? Пока еще только до 6-ой главы дошел. Ну и теперь у меня есть програмка скрипт, которая вычисляет корни квадратного уравнения на поле действительных чисел )))

trex6 ★★★★★
() автор топика
Последнее исправление: trex6 (всего исправлений: 1)
Ответ на: комментарий от shamaz

Я про его параметры еще прочесть не успел. Можно считать, что это мой хелловорлд на лиспе.

trex6 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.