Автор | Сообщение |
qaqa
18 сообщений |
#6907 2013-02-04 11:09 GMT+3 часа(ов) |
Привет, всем!
Немного сумбурный и не очень принципиальный вопрос ![]() На данный момент предпочтительно применять define для внутренних определений, потому как более читабельно чем let формы. Но на практике это частенько приводит к ситуациям: (define x На мой взгляд let () режет глаза. Есть форма block из racket/block. В исходнике есть такой комментарий: (define-syntax (block stx) И в документации про нее есть немного. В приведенном выше примере (на мой взгляд) форма block была бы уместнее. Насколько я понимаю (может ошибаюсь), сейчас block эквиватентно let (). По крайней мере макростеппер показал одно и тоже. Сделал поиск по исходникам Racket и не нашел случаев использования. Я начал пользоваться вместо let (), но racket/block не входит в racket/base и постоянно ее подключать немного напрягает. Как считаете: был бы смысл в добавлении такой формы в base часть Racket? Кто нибудь еще пользуется? |
|
qaqa
18 сообщений |
#6913 2013-02-08 21:37 GMT+3 часа(ов) |
Друг дай закурить , а в ответ тишина...
Есть тут кто живой? ![]() |
|
misha![]()
1275 сообщений |
#6914 2013-02-08 22:38 GMT+3 часа(ов) |
ЦитатаНу, это с непривычки. У меня, например, появляется чувство дискомфорта, когда определения перемешаны с кодом. Правда если необходимо определить несколько больших локальных функций, то лучше использовать local. ЦитатаОшибаетесь. Нужно смотреть исходники ![]() ЦитатаЛично я в этом не вижу смысла. Тем более в base. ЦитатаНу, если он вам так нравится, то возможно вам стоит создать свой собственный диалект. |
|
Kergan
300 сообщений |
#6915 2013-02-08 22:49 GMT+3 часа(ов) |
define предпочтительно перед let только внутри internal definitions contex. в выражении (define id ...) на месте многоточия - expression context. так что пиши обычный let ([...] ...) вместо (let () (define ...) ...)
|
|
qaqa
18 сообщений |
#6916 2013-02-09 10:53 GMT+3 часа(ов) |
Цитата Действительно ошибся. Вот примеры: пример1, пример2. В обоих примерах варианты 1 и 3 раскрываются в одно и тоже. А вариант 2 содержит еще один let-values. отредактировал(а) qaqa: 2013-02-09 11:07 GMT+3 часа(ов) |
|
qaqa
18 сообщений |
#6917 2013-02-09 11:02 GMT+3 часа(ов) |
Цитата Вот для человека, который эту кухню не сильно глубоко знает, скажите - где грабли лежат? |
|
Kergan
300 сообщений |
#6919 2013-02-09 20:11 GMT+3 часа(ов) |
Какие грабли?
|
|
qaqa
18 сообщений |
#6920 2013-02-09 22:22 GMT+3 часа(ов) |
Цитата ЦитатаЯ был не прав, и let () не эквивалентно block на 100%. Но вот есть конструкция block. Есть ли какие то подводные камни, если пользоваться (block (define ...) ...), а не let ([...] ...)? |
|
rv82
46 сообщений |
#6921 2013-02-11 23:32 GMT+3 часа(ов) |
А почему бы не использовать let? Это только поначалу кажется, что код с let'ами нечитабелен. После небольшой практики это будет казаться естественным. Кстати, лично я не пихаю define внутрь других defin'ов. Другими словами, внутри функции лучше использовать именно let и ничего другого (не считая lambda, конечно же). Для некоторых реализаций scheme это не просто предпочтение, а требование.
С другой стороны, если Вам нравится использовать block, что Вам мешает это делать? Особенно, если Вы не собираетесь переносить свои программы на другие реализации scheme. Хотя и это не проблема. Данная конструкция легко реализуется с помощью макросов на любом scheme. отредактировал(а) rv82: 2013-02-11 23:39 GMT+3 часа(ов) |
|
qaqa
18 сообщений |
#6922 2013-02-12 09:40 GMT+3 часа(ов) |
Цитата Я не говорил, что код c let нечитабелен, я имел в виду, что с define читабельнее (но это субъективно). В плане кодирования (опять же субъективно) let менее удобен. Вот приведу небольшой пример, как я обычно пишу на Racket. Вот появилась какая то задачка, или просто идейку проверить захотелось - открываю DrRacket и пишу код в виде последовательных define в топе модуля. Ясно дело, что больше половины случаев define не нужны в топе, и их бы лучше в виде let* оформить сразу. Но вот может я так пишу коряво, не продумываю сразу структуру, с let я в любом случае вожусь чуть дольше чем стоило бы. Ну и я подумал на досуге, раз style guide нынче советует define для внутренних определений, то может есть способ не используя замену define на let отрефакторить такой говнокод? В коде самого Racket, видел что-то наподобие: (define-values (a b ...) Спрятав промежуточные define под let() получаем то, что требовалось. Но (опять же субъективно) режет глаза let в таком виде. И вот случайно наткнулся на racket/block и стал пользоваться им вместо let(). Захотелось обсудить - кто как к такому подходу относится. Раз Racket на совместимость с другими схемами уже забил, почему бы дальше не пойти ![]() Ну и у block судя по документации: Цитата Цитата Цитата есть особенность: Цитата Я не сильно глубоко все это знаю, может от такого подхода есть минусы серьезные? Возможно я вообще что-то неправильно делаю? ![]() отредактировал(а) qaqa: 2013-02-12 11:30 GMT+3 часа(ов) |
|
Kergan
300 сообщений |
#6923 2013-02-13 14:26 GMT+3 часа(ов) |
Цитата А они и не в топе, они в module level. По-этом нету никакого такого особенного смысла засовывать их еще в дополнительный let*. Цитата Вот по-этому block, видимо, и не стоит применять. |
|
qaqa
18 сообщений |
#6924 2013-02-13 16:25 GMT+3 часа(ов) |
Цитата Спасибо за поправку. Лучше мне такими терминами, без более глубокого вникания, не оперировать ![]() Цитата Есть смысл для повторного использования имен в промежуточных вычислениях. Вместо: (define x1 ...) Получается: (define z1 Или: (define z1 Цитата Меня только вот это ваше высказывание смущает ![]() |
|
Kergan
300 сообщений |
#6925 2013-02-14 14:29 GMT+3 часа(ов) |
Цитата а первый вариант чем не устраивает? посмотрел block - он реализован через явный local-expand с добавлением идентификаторов в контекст "руками". Я лично не сильно доверяю таким макросам. |
|
qaqa
18 сообщений |
#6926 2013-02-15 09:38 GMT+3 часа(ов) |
Цитата Не понятно - какой из ни первый. Меня бы устроил последний вариант, на месте block может быть любая адекватная форма. Можно и let() но режет глаз, на мой взгляд. Цитата В моем случае оно работает - это все мои аргументы ![]() По большому счету, мне не особо важно как это будет называться, и как это будет реализовано. Сейчас в racket нет идиоматичной конструкции для таких случаев, кроме (let ([id expr] ...)). В How to Program Racket во всех примерах let-офобия, а по этому случаю ничего не сказано. |
|
qaqa
18 сообщений |
#6944 2013-03-11 10:17 GMT+3 часа(ов) |
Наткнулся в http://racket-lang.org/irc-logs/20120318.txt:
16:52 chandler: I'm a little confused as to why (local (define y 1) y) doesn't work, actually. 16:53 chandler: Er, in a top-level context that is. 17:13 jeapostrophe: chandler: you are missing a paren 17:14 jeapostrophe: rudybot: (local [(define y 1)] y) 17:14 rudybot: jeapostrophe: your sandbox is ready 17:14 rudybot: jeapostrophe: ; Value: 1 17:14 chandler: Oh! 17:14 chandler: Sorry. I must not be able to read today. 17:19 chandler: Oh, it's `block' I was trying to think of, not `local'. 17:20 chandler: Though apparently `block' can't be used in an expression context... 17:21 jeapostrophe: chandler: ya, that's different/nicer, but actually unnecessary because 'begin' already does that now 17:22 chandler: Is there a form equivalent to (let () body ...) to let internal definitions be used in an expression context? It's obviously semantically unnecessary, but it's nice to not have an empty binding form where it's not needed. 17:27 jeapostrophe: chandler: begin does that 17:27 chandler: rudybot: eval (define x (begin (define y 1) y)) 17:27 rudybot: chandler: your sandbox is ready 17:27 rudybot: chandler: error: #<undefined>:1:17: define: not allowed in an expression context in: (define y 1) 17:28 chandler: What am I missing? 17:29 jeapostrophe: rudybot: (version) 17:29 rudybot: jeapostrophe: ; Value: "5.2.1" 17:31 jeapostrophe: chandler: hmm, i guess the splicing behavior of begin causes a problem. block works there though 17:31 chandler: rudybot: eval (define x (block (define y 1) y)) 17:31 rudybot: chandler: error: #<undefined>:1:17: define: not allowed in an expression context in: (define y 1) 17:33 jeapostrophe: rudybot: (require racket/block) (define x (block (define y 1) y)) 17:33 rudybot: jeapostrophe: hmm. i guess it depends on the kind of people that you're trying to ensure understand your code. i might be wrong, but i'd think any seasoned lisp programmer would automatically translate car, cdr to what those functions represent (i.e., first and rest). i agree it's a stumbling block for new programmers (since they have to understand new notation) and that the fewer such requirements are made for people to mem 17:33 jeapostrophe: rudybot: (define x (block (define y 1) y)) 17:33 rudybot: jeapostrophe: error: #<undefined>:1:17: define: not allowed in an expression context in: (define y 1) 17:34 chandler: jeapostrophe: Nevermind rudyboy; I see now. 17:34 jeapostrophe: doesn't work because it is parsed as (#%app block (define y 1) y) 17:34 chandler: "rudybot" 17:34 chandler: Yes, I figured that out. 17:34 jeapostrophe: because block isn't in racket or racket/base, but racket/block |
|