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

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

kvitaliy

Members


Статус

12 сообщений

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

#5179   2011-12-03 03:34 GMT+3 часа(ов)      
Привет!
Scheme я только недавно начал учить, потому мой вопрос скорее всего довольно простой, но я все же не понимаю, как найти на него ответ.

Итак:
у меня есть функция, которая возвращает список элементов с заранее неизвестными и различными типами, которые я к тому же не знаю.
Я хочу написать функцию, которая на вход получала бы имя типа и некий экземпляр, а на выходе говорила #t или #f в зависимости от того, совпадает ли тип экземпляра с указанным мной типом; при этом я хочу что бы функция выглядела как-то так:

 
(define (check-type-of-instance type instance)
(<значение type>? instance))
 


Собственно, вопрос: как сделать так, что бы значение формального параметра type "превращалось" в type? во теле определения?

Спасибо!

joba

Members


Статус

157 сообщений

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

#5180   2011-12-03 05:43 GMT+3 часа(ов)      
Например, так
> (define (check-type-of-instance type instance)
((eval
(string->symbol
(string-append
(symbol->string type)
"?")))
instance))
> (check-type-of-instance 'char 123)
#f

joba

Members


Статус

157 сообщений

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

#5181   2011-12-03 05:45 GMT+3 часа(ов)      
А если type - строка, то тогда еще проще
> (define (check-type-of-instance type instance)
((eval
(string->symbol
(string-append type "?")))
instance))
> (check-type-of-instance "char" 123)
#f

misha

Moderators


Статус

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

#5183   2011-12-03 13:46 GMT+3 часа(ов)      
А зачем этот костыль нужен? Может лучше по старинке (type? instance)?

2 joba
В данном случае использование eval довольно кривой подход, лучше написать макрос или использовать case.

joba

Members


Статус

157 сообщений

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

#5189   2011-12-03 17:57 GMT+3 часа(ов)      
>В данном случае использование eval довольно кривой подход, лучше написать макрос или использовать case.

Обоснуй.

misha

Moderators


Статус

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

#5190   2011-12-03 19:49 GMT+3 часа(ов)      
А что конкретно обосновать? Почему макрос лучше или case удобнее? Или может почему 'Eval is evil!'?

kvitaliy

Members


Статус

12 сообщений

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

#5191   2011-12-03 22:05 GMT+3 часа(ов)      
Цитата
joba :
А если type - строка, то тогда еще проще
....



Я аналогичным образом и сделал, но мне этот способ не кажется элегантным, что ли... Субъективно, конечно.

kvitaliy

Members


Статус

12 сообщений

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

#5192   2011-12-03 22:12 GMT+3 часа(ов)      
Цитата
misha :
А зачем этот костыль нужен? Может лучше по старинке (type? instance)?

2 joba
В данном случае использование eval довольно кривой подход, лучше написать макрос или использовать case.


Михаил, вы имеете в виду под костылем задачу в целом?
Скорее всего в моем случае это не так, потому что программа, в которой мне надо выполнять проверку типа, заранее не знает с какими типами ей надо будет работать после того, как её запустят. Поэтому, мне ничего другого в голову не пришло, кроме как в одном из фрагментов кода получить список текущих типов, что бы потом брать типы из этого списка и проверять соответствия им при работе к каждым конкретным экземпляром.

Я как раз хотел бы решить задачу с помощью макросов, но пока не понимаю как это сделать.

joba

Members


Статус

157 сообщений

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

#5193   2011-12-03 23:04 GMT+3 часа(ов)      
>Я аналогичным образом и сделал, но мне этот способ не кажется элегантным, что ли... Субъективно, конечно.

Постановка задачи у тебя не элегантная, поэтому и решение соответствующее.

misha

Moderators


Статус

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

#5194   2011-12-03 23:25 GMT+3 часа(ов)      
kvitaliy
Поэтому, мне ничего другого в голову не пришло, кроме как в одном из фрагментов кода получить список текущих типов, что бы потом брать типы из этого списка и проверять соответствия им при работе к каждым конкретным экземпляром.
А зачем "брать типы", если можно "брать предикаты"?

joba

Members


Статус

157 сообщений

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

#5195   2011-12-03 23:44 GMT+3 часа(ов)      
2 kvitaliy
"Тип" у тебя - это что вообще? Зачем они тебе? Предикатами нельзя обойтись?

joba

Members


Статус

157 сообщений

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

#5196   2011-12-03 23:49 GMT+3 часа(ов)      
>А что конкретно обосновать? Почему макрос лучше или case удобнее? Или может почему 'Eval is evil!'?

Все вместе. Причем не вообще, а "в данном случае".

misha

Moderators


Статус

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

#5198   2011-12-04 00:28 GMT+3 часа(ов)      
joba
>А что конкретно обосновать? Почему макрос лучше или case удобнее? Или может почему 'Eval is evil!'?

Все вместе. Причем не вообще, а "в данном случае".
Т.к. топикастер указал, что типы заранее известны, то логичнее было бы использовать case или написать макрос (check-type-of-instance type instance) -> (type? instance) (хотя в данном случае это не прокатит). Тем более что так будет гораздо эффективнее(быстрее), чем вызывать каждый раз eval. Кстати, eval используется в основном для создания интерпретаторов. И в большинстве случаев его применение свидетельствует о неправильном дизайне приложения. Возможно, поэтому eval не вошел в r6rs base.

отредактировал(а) misha: 2011-12-04 00:38 GMT+3 часа(ов)

kvitaliy

Members


Статус

12 сообщений

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

#5200   2011-12-04 01:38 GMT+3 часа(ов)      
Цитата
joba :
2 kvitaliy
"Тип" у тебя - это что вообще? Зачем они тебе? Предикатами нельзя обойтись?


Да, согласен, не надо было слово "тип" упоминать.

Как сделать то, что написал joba через eval, с помощью макросов? Просто хочу понять, как на основании значений переменных генерировать имена предикатов с помощью макросов. Как это сделать с помощью eval - мне понятно.

joba

Members


Статус

157 сообщений

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

#5202   2011-12-04 02:13 GMT+3 часа(ов)      
>Как сделать то, что написал joba через eval, с помощью макросов?

Например, так
> (require mzlib/defmacro)
> (define-macro (check-type-of-instance type instance)
(let ((pred (string->symbol (string-append type "?"))))
`(,pred ,instance)))
> (check-type-of-instance "char" 12)
#f


Но этот вариант считаю хуже, потому что макросы не первоклассные объекты, как функции => лишние самоограничения.

отредактировал(а) joba: 2011-12-04 02:23 GMT+3 часа(ов)

joba

Members


Статус

157 сообщений

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

#5203   2011-12-04 02:16 GMT+3 часа(ов)      
>Просто хочу понять, как на основании значений переменных генерировать имена предикатов с помощью макросов.

А зачем тебе это надо? Передавай в функцию сразу предикат и не дури головы:
(define (check-type-of-instance pred instance)
(pred instance))

kvitaliy

Members


Статус

12 сообщений

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

#5204   2011-12-04 02:32 GMT+3 часа(ов)      
Цитата
joba :
>Просто хочу понять, как на основании значений переменных генерировать имена предикатов с помощью макросов.

А зачем тебе это надо? Передавай в функцию сразу предикат и не дури головы:
(define (check-type-of-instance pred instance)
(pred instance))




что значит "передавай в функцию сразу предикат"? может я чего-то не понимаю, но где тут у вас предикат в терминах scheme?

joba

Members


Статус

157 сообщений

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

#5206   2011-12-04 02:52 GMT+3 часа(ов)      
>что значит "передавай в функцию сразу предикат"? может я чего-то не понимаю, но где тут у вас предикат в терминах scheme?

Почитай ты уже, что такое функции высшего порядка. Предикатом там должен быть pred, который есть параметр функции check-type-of-instance. Например, (check-type-of-instance char? 123) вернет ложь.

kvitaliy

Members


Статус

12 сообщений

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

#5207   2011-12-04 03:05 GMT+3 часа(ов)      
Цитата
joba :
>Как сделать то, что написал joba через eval, с помощью макросов?

Например, так
> (require mzlib/defmacro)
> (define-macro (check-type-of-instance type instance)
(let ((pred (string->symbol (string-append type "?"))))
`(,pred ,instance)))
> (check-type-of-instance "char" 12)
#f


Но этот вариант считаю хуже, потому что макросы не первоклассные объекты, как функции => лишние самоограничения.



Спасибо!
Вот, чего-то подобного я и хотел!

kvitaliy

Members


Статус

12 сообщений

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

#5208   2011-12-04 03:20 GMT+3 часа(ов)      
Цитата
joba :
>что значит "передавай в функцию сразу предикат"? может я чего-то не понимаю, но где тут у вас предикат в терминах scheme?

Почитай ты уже, что такое функции высшего порядка. Предикатом там должен быть pred, который есть параметр функции check-type-of-instance. Например, (check-type-of-instance char? 123) вернет ложь.



все же не ясно: допустим у меня есть список '("aaa" "bbb"). как мне сделать так, что бы выполнились выражения (check-type-of-instance aaa? 123) и (check-type-of-instance bbb? 123) ?

joba

Members


Статус

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

Members


Статус

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

Moderators


Статус

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

#5212   2011-12-04 04:12 GMT+3 часа(ов)      
joba
Но этот вариант считаю хуже, потому что макросы не первоклассные объекты, как функции => лишние самоограничения.
Не любишь макросы - юзай haskell
joba
>Т.к. топикастер указал, что типы заранее известны, то логичнее было бы использовать case или написать макрос

Обоснуй, что это логичнее.
Нужны обоснования? Стучи в личку Тут срач разводить не стоит.
joba
>Тем более что так будет гораздо эффективнее(быстрее), чем вызывать каждый раз eval.

Не согласен. Кстати, тот макрос выше, который я привел, очень ограниченная версия моей функции, которая через eval написана. Например, попытка вычислить (check-type-of-instance (string-append "ch" "ar") 12), где check-type-of-instance - вышеописанный макрос, выдаст ошибку, что нельзя сказать о функции check-type-of-instance написанной через eval.
Макрос - это макрос, он не может быть ограниченной версией функции
joba
>Кстати, eval используется в основном для создания интерпретаторов. И в большинстве случаев его применение свидетельствует о неправильном дизайне приложения.

Обоснований я так пока и не увидел. Конкретней давай.
Погугли

misha

Moderators


Статус

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

#5213   2011-12-04 04:15 GMT+3 часа(ов)      
;#!r6rs
;(import (rnrs base (6))
; (rnrs syntax-case (6)))
 
(define-syntax check-type-of-instance
(lambda (stx)
(syntax-case stx ()
[(_ type instance)
(identifier? #'type)
(with-syntax ([type?
(datum->syntax
#'type
(string->symbol
(string-append
(symbol->string
(syntax->datum #'type))
"?")))])
#'(type? instance))])))
 
(define-syntax define-macro
(lambda (stx)
(syntax-case stx ()
[(_ (id formals ...) expr body ...)
(identifier? #'id)
#'(define-syntax id
(let ([macros (lambda (formals ...) expr body ...)])
(lambda (stx)
(datum->syntax stx
(apply macros
(cdr (syntax->datum stx)))))))])))

kvitaliy

Members


Статус

12 сообщений

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

#5214   2011-12-04 04:54 GMT+3 часа(ов)      
misha, и Вам спасибо!
правда не очень понятно... второй (define-syntax ...) как связан с первым?

kvitaliy

Members


Статус

12 сообщений

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

#5215   2011-12-04 04:57 GMT+3 часа(ов)      
Цитата
joba :
>Спасибо! Вот, чего-то подобного я и хотел!

Рано радуешься...

>все же не ясно: допустим у меня есть список '("aaa" "bbb").

А мы давай не будем такой хрени допускать, а допусти у тебя есть список L = (list char? integer?). И теперь берем, например, (check-type-of-instance (cdr L) 123) или просто ((cdr L) 123) и получаем истину.



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

misha

Moderators


Статус

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

#5216   2011-12-04 05:02 GMT+3 часа(ов)      
kvitaliy

misha, и Вам спасибо!
правда не очень понятно... второй (define-syntax ...) как связан с первым?

Я хотел продемонстрировать как устроен define-macro.

kvitaliy

Members


Статус

12 сообщений

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

#5217   2011-12-04 05:07 GMT+3 часа(ов)      
я так и подумал.
буду разбираться.

joba

Members


Статус

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

Members


Статус

157 сообщений

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

#5219   2011-12-04 07:23 GMT+3 часа(ов)      
>но, у меня как раз случай такой, как я описал. я не знаю заранее, что там будет в L, потому что я не знаю, что за данные мне прийдут, которые мне надо будет интерпретировать как предикаты в программе.

Т.е. тебе присылают список какого-то мусора и тебе нужно интерпретировать его как предикаты? Бред какой-то. Так скажи тому, кто тебе будет эти данные присылать, чтобы присылал их в строгом формате, а именно, в виде списка имен (в виде символов) предикатов L = '(p1 p2 ...). Потом делаешь (map eval L) и получаешь список предикатов.


Онлайн :

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




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