LINUX.ORG.RU

common-lisp, аргумент ф-ции и присваивание


0

0

Добрый) Не понимаю что за чертовщина творится):

(defparameter *db* (make-instance 'mp3-db))

(defun load-db (db)
  (setf db (cl-store:restore *db-place*)))

(load-db *db*)
приводит к тому, что *db* не изменяется. Такое ощущение, что ф-ция сама решает - надо писать в функциональном стиле). уже полчаса туплю над этим, непонятно :(

добавлю, что всё нормально сохраняется и (restore *db-place*) возвращает необходимый объект.

pseudo-cat ★★★
() автор топика

А почему, собственно, ожидается, что тут setf будет изменять значение другой переменной, кроме как db?

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

А при чём тут жаба, там параметры передаются по значению (если считать, что все значения классов - это указатели, пусть и ограниченные). Точнее будет, это не С++.

Begemoth ★★★★★
()
Ответ на: комментарий от guest-3484-2009

Это уже вопрос стиля - мне лично больше нравится вариант с макро, там не требуется цитировать символ.

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

В данном случае макрос это очень излишество. И в макросах надо следить за чистотой, и прочим. Не надо делать макросом то, что можно сделать функцией. Квотить совсем необязательно, это не единственный способ получить символ по имени. Есть и find-symbol и intern и так далее.

guest-3484-2009
()
Ответ на: комментарий от guest-3484-2009

В общем же случае, когда надо изменить какой-то place, не обязательно привязанный к символу, лучше заворачивать его в к-либо структуру - от списка, до объектов и структур(которые defstruct). И, по желанию, перегружать setf.

guest-3484-2009
()
Ответ на: комментарий от guest-3484-2009

Не знаю как там в жабе, но в с++ с присваивание прозрачнее.

Макрос используете потому что в setf-e place не вычисляется? Т.е. присваивается тому символу, который дан и если его нет, то что? почему ошибки нет, ведь db нигде не объявлено?

вариант с set привёл к этому:

The value #<MP3-DB {B354FD9}> is not of type SYMBOL.

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

В C++ то как раз хрен пойми как.
В Лиспе в функции всё передается по значению. Т.е. копируется. Если объект составной - последовательности, структуры, объекты итд - копируется ссылка.
db у тебя объявляется при объявлении параметра функции. Параметры - такие же переменные, как и через let. И через setf ты присваиваешь значение именно db, а не тому, что оно содержит.

Я так понимаю, ты не понимаешь разницы между символами и переменными.
Символ в лиспе это такая особая структура данных. Переменная - "место", имеющее имя, которое хранит значение. В случае с динамическими переменными(объявляемыми через defvar, defparameter и декларацию special), имя это обозначается символом(т.е. ячейка значения в структуре "символ" хранит то самое значение). В случае с лексическими - нет.

Суть примера с set в том, что set это (setf (symbol-value "symbol") "new-value"), то есть оно присваивает значение символу. И если передавать в функцию символ "*DB*", и потом на него кастовать set, символ "*DB*" получит новое значение.
http://www.lispworks.com/documentation/HyperSpec/Body/f_set.htm

guest-3484-2009
()
Ответ на: комментарий от guest-3484-2009

спасиб, теперь более-менее понятно)

В Лиспе в функции всё передается по значению. Т.е. копируется. Если объект составной - последовательности, структуры, объекты итд - копируется ссылка.

т.е. как и в с++ есть разделение на встроеные типы и определённые(не совсем так, но названия уже не вспомню)?

когда в функцию передаётся лексическая переменная, то можно и присвоить значение по ссылке и получить эначение по ней не зависимо от сложности структуры в ячейке, на которую указывает ссылка?

когда передаётся символ - то значение хранится в общей таблице символов и доступ к нему осуществляется по имени символа? поэтому мы и пишем (set 'var).

pseudo-cat ★★★
() автор топика
Ответ на: комментарий от guest-3484-2009

> В данном случае макрос это очень излишество. И в макросах надо следить за чистотой, и прочим.

В данном случае всё довольно просто.

> Не надо делать макросом то, что можно сделать функцией.

В общем случае - согласен. Но мне представляется, что то что хотел ТС как раз ближе к маросу, чем к функции.

> Квотить совсем необязательно, это не единственный способ получить символ по имени. Есть и find-symbol и intern и так далее.

Уж лучше цитировать.

Begemoth ★★★★★
()

>(defparameter *db* (make-instance 'mp3-db))
>(defun load-db (db)

> (setf db (cl-store:restore *db-place*)))

>(load-db *db*)


А что это ты делаешь?

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

cocoa это же под Mac OS X. Я по тому-то и вынужден писать прогу с некоторыми возможностями itunes, что у меня Linux. А, как всем жертвам ipod-ов известно, на этот самый айпод просто так музыку не залить((

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

вроде дочке gtkpod когда то поставил и оно работает до сих пор... Правда прошивку на иподе не обновлял.

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

спасибо за инфу. но в этом случае процесс первичен, цель вторична) моя первая програмка на cl и интересно её написать самому, а из gtkpod я, наверное, посмотрю библиотеки)

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