Здравствуйте, Sinclair, Вы писали:
G>>Типичный вызов из графической либы образца 90-х. Туплов в нем нет. S>Зато есть имена у параметров. Нажал Ctrl-space — увидел: "int Height".
Здравствуйте, Gaperton, Вы писали: G>Пишешь это в комментарии выше — никаких проблем.
Хм. Имена параметров ты один раз описываешь в декларации функции и потом пользуешься столько раз, сколько раз ты её вызываешь.
Комментарии ты предлагаешь писать при каждом вызове. Или ты имеешь в виду — описывать их в док-комментарии на функцию, который тебе будет показывать IDE?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Gaperton, Вы писали: G>>Пишешь это в комментарии выше — никаких проблем. S>Хм. Имена параметров ты один раз описываешь в декларации функции и потом пользуешься столько раз, сколько раз ты её вызываешь. S>Комментарии ты предлагаешь писать при каждом вызове. Или ты имеешь в виду — описывать их в док-комментарии на функцию, который тебе будет показывать IDE?
Последнее, конечно. Комментарий к функции хотя бы в пару строк писать все равно надо. Запись
get_point() -> %% { X::integer(), Y::integer() } — да что угодно тут писать можно, можно сверху или снизу
...
отличается мало. Данный пример завязан на синтаксис Эрланга, но это неважно.
Ключевой момент в том, что имена элементов тупла функциональной нагрузки не несут, компилятор их игнорирует — это по своей сути все равно комментарий. Потому, что поля задаются на самом деле порядком элементов в контрукторе, — так же, как и при вызове функции. Поэтому, это на самом деле не так важно, допускает синтаксис их писать в объявлении типа, или нет. Почувствовать это можно после некоторой практики употребления туплов. Понять — можно и так. Я тебе дело говорю, Синклер, поверь (и проверь сам — я знаю на слово ты не веришь, и это правильно) — нет тут большой проблемы .
Здравствуйте, Gaperton, Вы писали: G>-spec get_point() -> { X::integer(), Y::integer() } G>get_point() -> ...
G>от
G>get_point() -> %% { X::integer(), Y::integer() } — да что угодно тут писать можно, можно сверху или снизу G>...
G>отличается мало. Данный пример завязан на синтаксис Эрланга, но это неважно.
Я имею в виду — отличаются в плане возможности автоподсказки, а не контроля типов. Пример на С-подобном псевдокоде, при "хорошем синтаксисе" выглядел бы как-то так:
( int X, int Y ) get_point() { ... }
Вместо
void get_point( int & o_X, int & o_Y ) { ... }
Лучше, не так ли? И не ломает традицию синтаксиса С — возвращаемый тупл должен по возможности выглядеть похоже на аргументы функции, чтобы быть естественным продолжением языка, а не выглядеть уродливо. Сохраняя традицию С, имена X и Y должны быть доступны внутри определения функции, что, кстати, было бы офигенно удобно. Я бы сделал как-то так, добавляя туплы в С-подобный язык. Ну, разрешил бы еще писать просто return в таких случаях, вероятно, а также return с явным туплом. Разумеется, тупл сделал бы l-value.
Здравствуйте, Gaperton, Вы писали:
G>Лучше, не так ли? И не ломает традицию синтаксиса С — возвращаемый тупл должен по возможности выглядеть похоже на аргументы функции, чтобы быть естественным продолжением языка, а не выглядеть уродливо. Сохраняя традицию С, имена X и Y должны быть доступны внутри определения функции, что, кстати, было бы офигенно удобно. Я бы сделал как-то так, добавляя туплы в С-подобный язык. Ну, разрешил бы еще писать просто return в таких случаях, вероятно, а также return с явным туплом. Разумеется, тупл сделал бы l-value.
Это предложение, как ты видишь, отличается от предложения немерлистов своей простотой и минимальным надругательством над базовым языком. И поднятый вопрос об "опасности" туплов при таком подходе, как ты понимаешь — не стоит вовсе, ибо это есть органическое продолжение базового языка. Вот это и называется, ИМХО — добавлять туплы в язык _правильно_.
А то, что они добавлены по факту через задний проход — это уже не проблемы собственно туплов как таковых.
Здравствуйте, Sinclair, Вы писали:
J>>Вот интересно, нафига сделали Tuple<T>? Зачем кортеж с одним значением? S>Лично меня больше интересует другой вопрос: где Tuple? Т.е. кортеж с нулём значений?
. G>О как. А для группировки аргументов при вызове функции в ST тоже CPS предпочитают? Пример:
G>State = { start, X, Y, Z }, G>call( M, N, O, State ) G>...
Внутри себя ВМ манипулирует массивами. Именованные переменные это чисто синтаксический сахар. То есть, можно ВМ попросить сделать деструкцию массива. Так что конкретно этот твой пример можно развернуть через два блока так:
someMethod
"..."
"теперь делаем вызов с CPS"
self doSomeCall: [ :M :N :O :State |
[ :Start :X :Y :Z |
"тут мы имеем доступ и к M, N, O и к Start, X, Y, Z"
^ M * N + X + Y - Z."нелокальный возврат"
] valueWithArguments: State.
]
И, заметь, без особого синтаксического оверхеда Я проверил — работает.
Но я не думаю, что так хоть кто-то делает. Просто потому, что не-функциональные программы изначально проектируются по другому.
На любом языке, конечно, можно писать как на Фортране Но зачем? Так что пример, где нужно сделать деструкцию двух массивов, можешь не писать
Здравствуйте, Oksana Gimmel, Вы писали:
S>>>Лично меня больше интересует другой вопрос: где Tuple? Т.е. кортеж с нулём значений? J>>И зачем же он? OG>Как нормальная замена void. Чтобы можно было функции, возвращающие значения, и функции, не возвращающие значения, однотипно полиморфно обрабатывать.
Так для этого в функциональных языках ведь есть специальный тип, вроде (), зачем его с кортежами мешать?
Здравствуйте, jenyavb, Вы писали:
OG>>Как нормальная замена void. Чтобы можно было функции, возвращающие значения, и функции, не возвращающие значения, однотипно полиморфно обрабатывать.
J>Так для этого в функциональных языках ведь есть специальный тип, вроде (), зачем его с кортежами мешать?
One may also regard the unit type as the type of 0-tuples, i.e. the product of no types.
...
In the functional programming language Haskell, the unit type is called () and its only value is also (), reflecting the 0-tuple interpretation.
Здравствуйте, Oksana Gimmel, Вы писали:
OG>Здравствуйте, jenyavb, Вы писали:
S>>>Лично меня больше интересует другой вопрос: где Tuple? Т.е. кортеж с нулём значений?
J>>И зачем же он?
OG>Как нормальная замена void. Чтобы можно было функции, возвращающие значения, и функции, не возвращающие значения, однотипно полиморфно обрабатывать.
Здравствуйте, Jack128, Вы писали:
OG>>Как нормальная замена void. Чтобы можно было функции, возвращающие значения, и функции, не возвращающие значения, однотипно полиморфно обрабатывать.
J>А мона пример??
J>Tuple GetTuple0() {...} J>Tuple<int> GetTuple1 {...}
J>как можно полиморфно их обработать???
Ну, например, в Haskell следующий код будет работать независимо от того, возвращает ли функция f кортеж, () или что-то ещё:
Здравствуйте, Jack128, Вы писали:
J>А мона пример??
J>Tuple GetTuple0() {...} J>Tuple<int> GetTuple1 {...}
J>как можно полиморфно их обработать???
Например оба можно вызвать через Func<T> (полагаю что второй строчкой метод, а не свойство, судя по Get).
А иначе первый вариант пришлось бы через Action, а второй через Func<T> вызывать.