Автор | Сообщение |
kvitaliy
12 сообщений |
#5179 2011-12-03 03:34 GMT+3 часа(ов) |
Привет!
Scheme я только недавно начал учить, потому мой вопрос скорее всего довольно простой, но я все же не понимаю, как найти на него ответ. Итак: у меня есть функция, которая возвращает список элементов с заранее неизвестными и различными типами, которые я к тому же не знаю. Я хочу написать функцию, которая на вход получала бы имя типа и некий экземпляр, а на выходе говорила #t или #f в зависимости от того, совпадает ли тип экземпляра с указанным мной типом; при этом я хочу что бы функция выглядела как-то так:
Собственно, вопрос: как сделать так, что бы значение формального параметра type "превращалось" в type? во теле определения? Спасибо! |
|
joba
157 сообщений |
#5180 2011-12-03 05:43 GMT+3 часа(ов) |
Например, так
> (define (check-type-of-instance type instance) |
|
joba
157 сообщений |
#5181 2011-12-03 05:45 GMT+3 часа(ов) |
А если type - строка, то тогда еще проще
> (define (check-type-of-instance type instance) |
|
misha![]()
1275 сообщений |
#5183 2011-12-03 13:46 GMT+3 часа(ов) |
А зачем этот костыль нужен? Может лучше по старинке (type? instance)?
2 joba В данном случае использование eval довольно кривой подход, лучше написать макрос или использовать case. |
|
joba
157 сообщений |
#5189 2011-12-03 17:57 GMT+3 часа(ов) |
>В данном случае использование eval довольно кривой подход, лучше написать макрос или использовать case.
Обоснуй. |
|
misha![]()
1275 сообщений |
#5190 2011-12-03 19:49 GMT+3 часа(ов) |
А что конкретно обосновать? Почему макрос лучше или case удобнее? Или может почему 'Eval is evil!'?
|
|
kvitaliy
12 сообщений |
#5191 2011-12-03 22:05 GMT+3 часа(ов) |
Цитата Я аналогичным образом и сделал, но мне этот способ не кажется элегантным, что ли... Субъективно, конечно. |
|
kvitaliy
12 сообщений |
#5192 2011-12-03 22:12 GMT+3 часа(ов) |
Цитата Михаил, вы имеете в виду под костылем задачу в целом? Скорее всего в моем случае это не так, потому что программа, в которой мне надо выполнять проверку типа, заранее не знает с какими типами ей надо будет работать после того, как её запустят. Поэтому, мне ничего другого в голову не пришло, кроме как в одном из фрагментов кода получить список текущих типов, что бы потом брать типы из этого списка и проверять соответствия им при работе к каждым конкретным экземпляром. Я как раз хотел бы решить задачу с помощью макросов, но пока не понимаю как это сделать. |
|
joba
157 сообщений |
#5193 2011-12-03 23:04 GMT+3 часа(ов) |
>Я аналогичным образом и сделал, но мне этот способ не кажется элегантным, что ли... Субъективно, конечно.
Постановка задачи у тебя не элегантная, поэтому и решение соответствующее. |
|
misha![]()
1275 сообщений |
#5194 2011-12-03 23:25 GMT+3 часа(ов) |
kvitaliyА зачем "брать типы", если можно "брать предикаты"? |
|
joba
157 сообщений |
#5195 2011-12-03 23:44 GMT+3 часа(ов) |
2 kvitaliy
"Тип" у тебя - это что вообще? Зачем они тебе? Предикатами нельзя обойтись? |
|
joba
157 сообщений |
#5196 2011-12-03 23:49 GMT+3 часа(ов) |
>А что конкретно обосновать? Почему макрос лучше или case удобнее? Или может почему 'Eval is evil!'?
Все вместе. Причем не вообще, а "в данном случае". |
|
misha![]()
1275 сообщений |
#5198 2011-12-04 00:28 GMT+3 часа(ов) |
jobaТ.к. топикастер указал, что типы заранее известны, то логичнее было бы использовать case или написать макрос (check-type-of-instance type instance) -> (type? instance) (хотя в данном случае это не прокатит). Тем более что так будет гораздо эффективнее(быстрее), чем вызывать каждый раз eval. Кстати, eval используется в основном для создания интерпретаторов. И в большинстве случаев его применение свидетельствует о неправильном дизайне приложения. Возможно, поэтому eval не вошел в r6rs base. отредактировал(а) misha: 2011-12-04 00:38 GMT+3 часа(ов) |
|
kvitaliy
12 сообщений |
#5200 2011-12-04 01:38 GMT+3 часа(ов) |
Цитата Да, согласен, не надо было слово "тип" упоминать. Как сделать то, что написал joba через eval, с помощью макросов? Просто хочу понять, как на основании значений переменных генерировать имена предикатов с помощью макросов. Как это сделать с помощью eval - мне понятно. |
|
joba
157 сообщений |
#5202 2011-12-04 02:13 GMT+3 часа(ов) |
>Как сделать то, что написал joba через eval, с помощью макросов?
Например, так > (require mzlib/defmacro) Но этот вариант считаю хуже, потому что макросы не первоклассные объекты, как функции => лишние самоограничения. отредактировал(а) joba: 2011-12-04 02:23 GMT+3 часа(ов) |
|
joba
157 сообщений |
#5203 2011-12-04 02:16 GMT+3 часа(ов) |
>Просто хочу понять, как на основании значений переменных генерировать имена предикатов с помощью макросов.
А зачем тебе это надо? Передавай в функцию сразу предикат и не дури головы: (define (check-type-of-instance pred instance) |
|
kvitaliy
12 сообщений |
#5204 2011-12-04 02:32 GMT+3 часа(ов) |
Цитата что значит "передавай в функцию сразу предикат"? может я чего-то не понимаю, но где тут у вас предикат в терминах scheme? |
|
joba
157 сообщений |
#5206 2011-12-04 02:52 GMT+3 часа(ов) |
>что значит "передавай в функцию сразу предикат"? может я чего-то не понимаю, но где тут у вас предикат в терминах scheme?
Почитай ты уже, что такое функции высшего порядка. Предикатом там должен быть pred, который есть параметр функции check-type-of-instance. Например, (check-type-of-instance char? 123) вернет ложь. |
|
kvitaliy
12 сообщений |
#5207 2011-12-04 03:05 GMT+3 часа(ов) |
Цитата Спасибо! Вот, чего-то подобного я и хотел! |
|
kvitaliy
12 сообщений |
#5208 2011-12-04 03:20 GMT+3 часа(ов) |
Цитата все же не ясно: допустим у меня есть список '("aaa" "bbb"). как мне сделать так, что бы выполнились выражения (check-type-of-instance aaa? 123) и (check-type-of-instance bbb? 123) ? |
|
joba
157 сообщений |
#5209 2011-12-04 03:29 GMT+3 часа(ов) |
>Т.к. топикастер указал, что типы заранее известны, то логичнее было бы использовать case или написать макрос
Обоснуй, что это логичнее. >Тем более что так будет гораздо эффективнее(быстрее), чем вызывать каждый раз eval. Не согласен. Кстати, тот макрос выше, который я привел, очень ограниченная версия моей функции, которая через eval написана. Например, попытка вычислить (check-type-of-instance (string-append "ch" "ar") 12), где check-type-of-instance - вышеописанный макрос, выдаст ошибку, что нельзя сказать о функции check-type-of-instance написанной через eval. Макрос check-type-of-instance, который будет полноценной версией моей функции check-type-of-instance, не будет "быстрее" этой функции. >Кстати, eval используется в основном для создания интерпретаторов. И в большинстве случаев его применение свидетельствует о неправильном дизайне приложения. Обоснований я так пока и не увидел. Конкретней давай. отредактировал(а) joba: 2011-12-04 04:02 GMT+3 часа(ов) |
|
joba
157 сообщений |
#5211 2011-12-04 03:48 GMT+3 часа(ов) |
>Спасибо! Вот, чего-то подобного я и хотел!
Рано радуешься... >все же не ясно: допустим у меня есть список '("aaa" "bbb"). А мы давай не будем такой хрени допускать, а допусти у тебя есть список L = (list char? integer?). И теперь берем, например, (check-type-of-instance (cdr L) 123) или просто ((cdr L) 123) и получаем истину. |
|
misha![]()
1275 сообщений |
#5212 2011-12-04 04:12 GMT+3 часа(ов) |
jobaНе любишь макросы - юзай haskell ![]() jobaНужны обоснования? Стучи в личку ![]() jobaМакрос - это макрос, он не может быть ограниченной версией функции ![]() jobaПогугли ![]() |
|
misha![]()
1275 сообщений |
#5213 2011-12-04 04:15 GMT+3 часа(ов) |
;#!r6rs |
|
kvitaliy
12 сообщений |
#5214 2011-12-04 04:54 GMT+3 часа(ов) |
misha, и Вам спасибо!
правда не очень понятно... второй (define-syntax ...) как связан с первым? |
|
kvitaliy
12 сообщений |
#5215 2011-12-04 04:57 GMT+3 часа(ов) |
Цитата но, у меня как раз случай такой, как я описал. я не знаю заранее, что там будет в L, потому что я не знаю, что за данные мне прийдут, которые мне надо будет интерпретировать как предикаты в программе. |
|
misha![]()
1275 сообщений |
#5216 2011-12-04 05:02 GMT+3 часа(ов) |
kvitaliyЯ хотел продемонстрировать как устроен define-macro. |
|
kvitaliy
12 сообщений |
#5217 2011-12-04 05:07 GMT+3 часа(ов) |
я так и подумал.
буду разбираться. |
|
joba
157 сообщений |
#5218 2011-12-04 06:05 GMT+3 часа(ов) |
>Не любишь макросы - юзай haskell
Так говоришь, будто бы не существует Template Haskell. >Нужны обоснования? Стучи в личку. Тут срач разводить не стоит. Ну тогда писал бы мне сразу в личку свое "В данном случае использование eval довольно кривой подход, лучше написать макрос или использовать case". Сам "срач" развел, сам же теперь и свел. >Макрос - это макрос, он не может быть ограниченной версией функции Я имел в виду, что тот макрос check-type-of-instance наследует слишком малую часть функциональности объекта check-type-of-instance, который функция использующая eval. Можно написать другой макрос, который будет наследовать больше функциональности того объекта-функции, но тогда он не будет "быстрее", как ты говорил. А сравнивать эффективность в каком-то плане двух объектов, которые имеют разную функциональность, бессмысленно. >Погугли По запросу, например, 'eval is evil' там какая-то хрень про php и прочий мусор. Короче, давай конкретные ссылки, где обосновывается почему eval "в данном случае" "довольно кривой подход", если сам не можешь обосновать. Или же признай, что ты просто ляпнул свое "экспертное" мнение про использование eval лишь бы ляпнуть, и на этом тогда закончим. |
|
joba
157 сообщений |
#5219 2011-12-04 07:23 GMT+3 часа(ов) |
>но, у меня как раз случай такой, как я описал. я не знаю заранее, что там будет в L, потому что я не знаю, что за данные мне прийдут, которые мне надо будет интерпретировать как предикаты в программе.
Т.е. тебе присылают список какого-то мусора и тебе нужно интерпретировать его как предикаты? Бред какой-то. Так скажи тому, кто тебе будет эти данные присылать, чтобы присылал их в строгом формате, а именно, в виде списка имен (в виде символов) предикатов L = '(p1 p2 ...). Потом делаешь (map eval L) и получаешь список предикатов. |
|