Предыдущая страница Следующая страница [1] > 2 < [3] [4]

Автор Сообщение

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4171   2011-04-12 06:01 GMT+3 часа(ов)      
А что значит двоеточие перед символом?
В функциях - это именованные параметры, а в остальных случаях?
(destructuring-bind (x y z) (list 1 2 3)
(list :x x :y y :z z)) ==> (:X 1 :Y 2 :Z 3)

Это пример из книги. Тут что-то особенное подразумевается или нет?

"Знаки" ведь записываются с "#\" перед ними, строки в двойных кавычках.

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4172   2011-04-12 20:34 GMT+3 часа(ов)      
И ещё вопрос, многие функции принимают в качестве аргумента функцию. Например, count-if. Есть ли разница как записывать:
(count-if #'evenp #(1 2 3 4 5))
(count-if 'evenp #(1 2 3 4 5))
Результат одинаковый.

В книге сказано:
Цитата
Нотация #' является сокращением выражения «Получить функцию с данным именем». Без #' Lisp обратится к EVENP как к имени переменной и попытается получить ее значение, а не саму функцию.

Но второй вариант ведь тоже "не разрешает" "обращаться как к имени переменной".
Но не думаю, что решетка просто для красоты.

В документации не удалось найти, что эта решетка делает, как она правильно называется?

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4174   2011-04-13 00:08 GMT+3 часа(ов)      
> А что значит двоеточие перед символом?
Символ начинающийся с двоеточия является ключевым словом.
(keywordp :x) ==> T


> В документации не удалось найти, что эта решетка делает, как она правильно называется?
Плохо искали Sharpsign Single-Quote

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4181   2011-04-13 06:26 GMT+3 часа(ов)      
Цитата
misha :
Плохо искали Sharpsign Single-Quote

Действительно плохо. (:
В оправдание скажу, что искал так.
Но всё равно не понял почему "'" (quote ...) и "#'" (function ...) работают одинаково в данном случае.

Цитата
Символ начинающийся с двоеточия является ключевым словом.
А зачем/как они используются?
Гугл по запросу "common lisp" + "ключевые слова" фигню показывает...

Возможно надоел глупыми вопросами, но документация уж больно тяжело (сильно много перекрестных ссылок + непривычно) читается, а в книге practical common lisp многие мелочи опускаются.
Кстати, есть ещё хорошие книги по лиспу?

megamanx

Members


Статус

307 сообщений

Где: Russia
Род занятий:
Возраст:

#4184   2011-04-13 22:48 GMT+3 часа(ов)      
Цитата
А зачем/как они используются?

Использовал в функциях (я не уверен, может кто как ещё это делает).
При определении функции часто необходимо явно указать порядок переменных, например
(defun foo (&KEY a b c) (list a b c))

вызов
(foo) >>> (NIL NIL NIL)
(foo :a 1) >>> (1 NIL NIL)
(foo :b 1) >>> (NIL 1 NIL)
(foo :c 1) >>> (NIL NIL 1)
(foo :a 1 :c 1) >>> (1 NIL 1)
(foo :b 1 :c 1) >>> (NIL 1 1)

Можно также смешивать со значениями по умолчанию и x-supplied-p переменными. Значения по умолчанию - это просто
(defun foo (a b &OPTIONAL (c 10)) (list a b c))

вызов
(foo 1 2 3) >>> (1 2 3)
(foo 1 2) >>> (1 2 10)
(foo 1) >> error

если не указано значение по умолчанию, тогда замена на NIL
(defun foo (a &OPTIONAL b (c 10)) (list a b c))
вызов
(foo 1 2 3) >>> (1 2 3)
(foo 1 2) >>> (1 2 10)
(foo 1) >>> (1 NIL 10)

Связанные переменные используются для того, чтобы узнать, были ли заданы значения (т.е., был ли, например, вызов (foo 1 1) либо (foo 1 1 NIL))
(defun foo (a b &OPTIONAL (c 3 c-supplied-p)) (list a b c c-supplied-p))

вызов
(foo 1 2) >>> (1 2 3 NIL)
(foo 1 2 3) >>> (1 2 3 T)
(foo 1 2 4) >>> (1 2 4 T)
(foo 1 2 nil) >>> (1 2 NIL T)

P.S. Установи LispWorks, там документация Help | On Symbol... , объяснено всё достаточно понятно. (можешь не устанавливать, просмотреть онлайн)

отредактировал(а) megamanx: 2011-04-14 14:04 GMT+3 часа(ов)
I wish I'd made you angry earlier

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4186   2011-04-14 01:59 GMT+3 часа(ов)      
Спасибо за подробное объяснение, но с параметрами функций мне всё, вроде, ясно. (:
Оно достаточно неплохо вот тут описано (я именно по этой книге язык изучаю).
Не понятно именно нафига, допустим, такое:
(list :a :b :c) => (:A :B :C)

Есть ли у таких "ключевых" слов ещё какое-то применение или нет.

LispWorks устанавливал, как и кучу всяких других IDE (емакс не осилил ). "Help | On Symbol" - удобно, не знал. Но там ограничение по времени есть...

отредактировал(а) Имя пользователя: 2011-04-14 15:19 GMT+3 часа(ов)

megamanx

Members


Статус

307 сообщений

Где: Russia
Род занятий:
Возраст:

#4188   2011-04-14 14:05 GMT+3 часа(ов)      
действительно, нафига. В лиспе ключи === символы. Пока не появится человек, написавший это, видимо, истина будет где-то рядом.
http://stackoverflow.com/questions/1527548/why-does-clojure-have-keywords-in-addition-to-symbols
Там чел что-то порядочное говорит.

отредактировал(а) megamanx: 2011-04-14 15:05 GMT+3 часа(ов)
I wish I'd made you angry earlier

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4189   2011-04-14 15:44 GMT+3 часа(ов)      
За ссылку мега спасибо, там и правда всё понятно описано.
Oжидал от этих ключевых слов чего-то особенного, а всё оказалось проще. (:

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4205   2011-04-20 05:04 GMT+3 часа(ов)      
Вопрос насчёт "call-next-method".
В книге это было описано дотаточно мутно, погуглил, нашел такое объяснение:
archimag
Если упростить ситуацию, забыть про мультиметоды и eql, то call-next-method будет аналогичен вызову соответствующей виртуальной функции родительского класса в других языка.
(Это с лора, если кому-то интересно.)

Данное упрощенное объяснение меня как бы устраивает (eql и мультиметоды будут дальше, так что пока вперёд не забегаю), если бы не один нюанс.
А именно то, что в лиспе ведь разрешено множественное наследование! Так что же будет, если класс наследуется от двух и в нём используется call-next-method?

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4207   2011-04-20 22:12 GMT+3 часа(ов)      
Как оказалось, я снова забегал вперёд...
Цитата
Множественное наследование, немного усложняет идею специфичности, поскольку аргумент может быть экземпляром двух классов, ни один из которых не является подклассом другого. Если такие классы используются как специализаторы параметров, то обобщенная функция не может упорядочить их используя только правило, что подклассы являются более специфичными, чем их суперклассы. В следующей главе я опишу как понятие специфичности было расширено для обработки множественного наследования. Сейчас достаточно сказать, что существует алгоритм для упорядочения специализаторов классов.

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4226   2011-05-04 05:16 GMT+3 часа(ов)      
Ещё один, возможно наивный и глупый вопрос. Использовать в лиспе dll написаные на других языках можно, насколько я знаю (ну cffi и что-то там такое, детали не важны сейчас). А вот если из dll эксепшн (допустим, это плюсовая dll) прилететь может, то что будет? И что можно сделать?

Интересуют даже не мега подробности, а просто принципиальная возможность (или невозможность) это как-то разрулить. И если возможно, то примерный механизм.

Или даже немного "интереснее" - если длл кривая и может крашнуться. Что в таком случае?
Только, пожалуйста, не надо ответов в духе "не надо использовать кривые длл".
На тех же плюсах (для примера) можно создать отдельный процесс, ну и потом с этим процессом взаимодействовать.
А на лиспе? Возможно взаимодействие нескольких "лисповых процессов"?

megamanx

Members


Статус

307 сообщений

Где: Russia
Род занятий:
Возраст:

#4228   2011-05-04 22:53 GMT+3 часа(ов)      
Ты дошёл, пожалуй, до самого "нубского" вопроса. Нет спецификации на cffi, нет утверждённого метода работы с потоками, всё зависит от конкретной реализации, нет нормального компилятора в .exe. Это, ИМХО, один из главных поводов заглядываться на рэкет, или эрланг, или о'кэмл.
Что будет в таком-то случае... - этот вопрос вне контекста инструментария неразрешим.
Есть ли потоки и могут ли они взаимодействовать - есть, могут. Но не везде. Например, на sbcl под линухом могут, под виндой не могут, на lispworks с какими-то оговорками могут, на clisp могут, но сам clisp не может нормально работать и т.п.
I wish I'd made you angry earlier

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4229   2011-05-05 01:24 GMT+3 часа(ов)      
> А вот если из dll эксепшн (допустим, это плюсовая dll) прилететь может, то что будет?
Аварийно завершится! Винда даже окошко юзеру продемонстрирует

> И что можно сделать?
В принципе, если Ваше приложение не использует эту dll в нескольких потоках, тогда можно попытаться перехватить Сишное исключение. Но как Вы будете его обрабатывать, если оно не является стандартным? Т.е. как на него адекватно реагировать?

>Или даже немного "интереснее" - если длл кривая и может крашнуться. Что в таком случае?
...
На тех же плюсах (для примера) можно создать отдельный процесс, ну и потом с этим процессом взаимодействовать.

При этом необходимо остановить все потоки использующие эту dll, сгенерировать дамп и предложить юзеру послать его Вам.

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4234   2011-05-06 02:37 GMT+3 часа(ов)      
Цитата
megamanx :но сам clisp не может нормально работать и т.п.
А что с ним не так?


Цитата
misha :тогда можно попытаться перехватить Сишное исключение. Но как Вы будете его обрабатывать, если оно не является стандартным? Т.е. как на него адекватно реагировать?
То есть всё-таки можно?
А что делать... ну не знаю. (:
Можно хотя бы не дать приложению аварийно завершаться.

Цитата
misha :При этом необходимо остановить все потоки использующие эту dll, сгенерировать дамп и предложить юзеру послать его Вам.
Спасибо, конечно, за совет. (:
Но говорю же - ситуация теоретическая. Хотя и видел как-то на одном форуме, что у человека подобная проблема была. Ну а раз проблема теоретическая, то можно продолжить фантазировать и предположить, что к коду длл доступа нет, а использовать мега необходимость есть.
В таком случае можно создать отдельный процесс (именно процесс, не поток) и если он упадёт - можно будет перезапустить.
Ну да неважно.

Теперь менее странный (а может и наоборот, но, по крайней мере, не теоретический) вопрос - можно ли как-то модифицировать переданный в функцию параметр. В смысле не внутри, а чтобы "снаружи" это значение тоже изменилось.
Или это не просто нельзя, а ещё и не нужно? Обходиться возвращаемым значением?

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4236   2011-05-06 04:06 GMT+3 часа(ов)      
Хм, оказалось достаточно передать в функцию переменную с кавычкой...

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4237   2011-05-06 13:29 GMT+3 часа(ов)      
> То есть всё-таки можно?
А что делать... ну не знаю. (:
Можно хотя бы не дать приложению аварийно завершаться.

Все зависит от конкретной реализации. Это все-таки не является частью стандарта)

> В таком случае можно создать отдельный процесс (именно процесс, не поток) и если он упадёт - можно будет перезапустить.
Бред! Что будет если процесс впадет в бешенство?) Это не выход. К тому же большинство реализаций CL довольно тяжеловесны, поэтому процесс загрузки приложения довольно длительный и ресурсоемкий процесс.

> Теперь менее странный (а может и наоборот, но, по крайней мере, не теоретический) вопрос - можно ли как-то модифицировать переданный в функцию параметр. В смысле не внутри, а чтобы "снаружи" это значение тоже изменилось.
Или это не просто нельзя, а ещё и не нужно? Обходиться возвращаемым значением?
> Хм, оказалось достаточно передать в функцию переменную с кавычкой...

Не понял

megamanx

Members


Статус

307 сообщений

Где: Russia
Род занятий:
Возраст:

#4238   2011-05-06 14:22 GMT+3 часа(ов)      
Цитата
А что с ним не так?

У меня он постоянно норовит упасть. Когда несколько раз перезагружаю файл, когда находит ошибку и не может выйти из дебага, когда пытался работать с его сокетами и т.п. С регулярностью, примерно через три минуты после начала использования. Я не исключаю своих кривых рук.
Цитата
можно ли как-то править переданный в функцию параметр

Через макрос
I wish I'd made you angry earlier

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4239   2011-05-06 16:12 GMT+3 часа(ов)      
Цитата
misha :Бред! Что будет если процесс впадет в бешенство?) Это не выход.
Что значит "впадёт в бешенство"? (:
Процесс может зависнуть - в этом случае можно проверять периодически отвечает он или нет. И убивать, если не отвечает.
Или крашнуться - ну тогда пофиг. Запустим ещё раз.
Вообще я говорил скорее про возможное решение (довольно надуманной) проблемы как это можно было бы сделать на "другом языке". Про лисп (пока) слишком мало знаю.

Цитата
misha :Не понял
Это я снова фигню сказал - нашел пример рабочий, но не заметил сразу, что там вместо setf используется set.
(defparameter *test* 0) => *TEST*
*test* => 0
 
(defun change-to-eee(val)
(set val "eee"))
 
(change-to-eee '*test*) => "eee"
*test* => "eee"
 
(change-to-eee *test*) => ошибка


Цитата
megamanx :Через макрос
Ну да, про этот способ подумал, просто показалось, что это "неправильно". В смысле использовать макросы там, где они "не нужны".

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4240   2011-05-06 17:24 GMT+3 часа(ов)      
> Что значит "впадёт в бешенство"? (:
Я имел ввиду ситуацию, когда программа будет падать сразу после загрузки, а Ваш рестартер будет её запускать заново. Если речь о Лиспе, то в данной ситуации наиболее разумно будет работать с "бажной" dll через dll "обертку", которая будет обрабатывать все возникающие исключения и передавать их Вам в виде структуры.

> Ну да, про этот способ подумал, просто показалось, что это "неправильно". В смысле использовать макросы там, где они "не нужны".
Пробовали использовать лямбду.

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4241   2011-05-06 18:41 GMT+3 часа(ов)      
Цитата
misha :Пробовали использовать лямбду.

Не понял как. Можно немного подробнее?

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4242   2011-05-06 19:32 GMT+3 часа(ов)      
Например, можно так
(defmacro get-out-param (param)
`(funcall ,param))
 
(defmacro set-out-param (param val)
`(funcall ,param ,val))
 
(defmacro out-param (param)
`(lambda (&rest val)
(if val
(setq ,param (car val))
,param)))

Тест:
> (defun test (var)
(set-out-param var 123))
TEST
> (defvar x 0)
X
> (test (out-param x))
123
> x
123
> (let ((y -1))
(test (out-param y))
y)
123


Небольшой оффтоп.
На Рэкете это можно реализовать с использованием макротрансформеров.
#lang racket
 
(define-syntax-rule (out-param param)
(lambda val
(if (null? val)
param
(set! param (car val)))))
 
(define-syntax (with-out-params stx)
(syntax-case stx ()
[(_ args . body)
(with-syntax ([params
(datum->syntax
stx
(map (lambda (arg)
`(,arg (make-set!-transformer
(lambda (stx)
(syntax-case stx (set!)
[(set! out val) #'(,arg val)]
[out #'(,arg)])))))
(syntax->datum #'args)))])
#'(let-syntax params . body))]))

Тест:
(define (test val out1 out2)
(with-out-params (out1 out2)
(set! out1 val)
(set! out2 out1)
out2))
 
(define-values (x y) (values 0 1))
 
> (test 12345 (out-param x) (out-param y))
12345
> x
12345
> y
12345

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4244   2011-05-06 22:46 GMT+3 часа(ов)      
Спасибо за объяснения. Несколько вопросов:

1. Разницы использовать setq или setf ведь нет?
2. Зачем "(&rest val)" и "(car val)"? Как-то не уловил смысл разрешать передавать лямбде любое количество параметров и игнорировать их... что-то упустил? Изменил - тоже работает...
Да и как-то вообще не очень понял зачем там лямбда... просто чтобы получить как бы функцию, а не просто макрос?

3. А вообще так делать (в смысле изменять значения параметров) как бы неправильно? Ну то есть, не знаю, как сказать... "не по лисповски"? В смысле хочу понять или вот так вот макросы использовать для этого - это нормально или я просто изначально неправильно к решению подхожу.

В рэкет (пока) вникать не буду, сори. Мне бы "просто cl" для начала понять. (:

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4245   2011-05-07 00:53 GMT+3 часа(ов)      
> 1. Разницы использовать setq или setf ведь нет?
В данном случае разницы нет.

> 2. Зачем "(&rest val)" и "(car val)"? Как-то не уловил смысл разрешать передавать лямбде любое количество параметров и игнорировать их... что-то упустил? Изменил - тоже работает...
А Вы использовали get-out-param?

> 3. А вообще так делать (в смысле изменять значения параметров) как бы неправильно? Ну то есть, не знаю, как сказать... "не по лисповски"?
Как раз этот подход можно назвать классическим. Тут ведь дело не в макросах, а в умении работать с лямбдой.

megamanx

Members


Статус

307 сообщений

Где: Russia
Род занятий:
Возраст:

#4246   2011-05-07 00:58 GMT+3 часа(ов)      
Делать обёртку-функцию, которая возвращает значение переменной, которая хранится в доме, который построил Джек. Можно ещё одну обёртку сверху пристроить, и назвать получившуюся штуку dynamic-setf
I wish I'd made you angry earlier

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4247   2011-05-07 01:06 GMT+3 часа(ов)      
> Делать обёртку-функцию, которая возвращает значение переменной, которая хранится в доме, который построил Джек.
Ну, можно и так сказать Для Лиспа ведь случай неординарный.

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4248   2011-05-07 03:20 GMT+3 часа(ов)      
Цитата
misha :
А Вы использовали get-out-param?

Ну да, изменил только это:
(defmacro out-param (param)
`(lambda (val)
(if val
(setq ,param val)
,param)))



А ещё вопрос... можно ли как-то "быть уверенным", что если я передам в функцию, допустим, список, то его функция не изменит? Или только документацию/код смотреть?
Ну как передача по "константной ссылке"?

отредактировал(а) Имя пользователя: 2011-05-07 03:30 GMT+3 часа(ов)

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4249   2011-05-07 03:58 GMT+3 часа(ов)      
> А Вы использовали get-out-param?
>> Ну да, изменил только это:
Зачем врать?
По Вашему NIL не может быть значением переменной?(Проанализируйте Ваш макрос)

> А ещё вопрос... можно ли как-то "быть уверенным", что если я передам в функцию, допустим, список, то его функция не изменит?
Передайте его копию. У лиспа отсутствуют неизменяемые cons ячейки. А у Рэкета, например, они используются по умолчанию.

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4265   2011-05-12 17:35 GMT+3 часа(ов)      
Цитата
misha :
> А Вы использовали get-out-param?
>> Ну да, изменил только это:
Зачем врать?
Где враньё?
Возможно, я что-то недопонял, но уж точно не врал сознательно.

Цитата
misha :По Вашему NIL не может быть значением переменной?(Проанализируйте Ваш макрос)
Речь об этом - "(if val"? То есть если val - nil, то присваивания не произойдёт?
Так ведь это не мой макрос... в Вашем коде это тоже присутствует.
(Кстати, мне было бы удобнее на ты).

Кстати, зачем эта проверка там?

И я всё-таки не понял два момента:
1. Зачем в лямбде (&rest val) с использованием потом только первого значения списка параметров.
2. Какие преимущества в данном случае лямбда даёт? Ну то есть изначально целью было изменять параметр. Чтобы упросить задачу - допустим, нужна функция куда передаётся значение и его надо изменить. Не проще разве будет написать так:
(defmacro change-val(param val)
`(setf ,param ,val))

какие преимущества есть у Вашего способа и недостатки у варианта с простым макросом?

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4266   2011-05-12 19:20 GMT+3 часа(ов)      
Меня смутил ответ: "Ну да, изменил только это:", если только это, то get-out-param откажется работать.

> Кстати, зачем эта проверка там?
Я хотел создать подобие ключевого слова out. Если список параметров пуст, то val = nil, а это значит, что необходимо вернуть значение переменной, а не присваивать.

> какие преимущества есть у Вашего способа и недостатки у варианта с простым макросом?
А ты провел полноценное тестирование?

Имя пользователя

Members


Статус

32 сообщений

Где: Vietnam
Род занятий:
Возраст:

#4351   2011-05-22 04:52 GMT+3 часа(ов)      
Цитата
misha :
Меня смутил ответ: "Ну да, изменил только это:", если только это, то get-out-param откажется работать.

Действительно. Был невнимателен.

Такой вопрос - как бы попроще из строки слова извлечь? Вот нашел такой способ:
(defun words-from-string(input-string)
(with-input-from-string (input-stream input-string)
(loop while (peek-char nil input-stream nil nil)
collect (read input-stream))))
 
(words-from-string "eee asdas asdasdsa rfef") => (EEE ASDAS ASDASDSA RFEF)

Вроде, всё ок.
Но если захочется несколько разделителей добавить? В смысле, чтобы не только пробел, а ещё некоторые символы, причем одновременно.
Эта тема закрыта, публикация новых сообщений недоступна.


Онлайн :

0 пользователь(ей), 41 гость(ей) :




Реклама на сайте: