H>Сейчас такое объявление функций компилятор скушает, но второе объявление f переопределит первое.
Ни разу не ощутил их нехватки за всё время работы на Nemerle, так что [имхо] смысла в таких перегрузках нет. Более того я бы даже переопределения запретил, с сообщением "already defined in visible scope". А то ловил один раз подлянскую ошибку из-за этого.
Здравствуйте, VladD2, Вы писали:
VD>Господа, с фичреквестами мы завязали. У нас бэта.
VD>Надо допиливать баги и делать релиз. Иначе язык умрет не родившись.
Это понятно, просто на канале этот вопрос всплыл, вот я его и вынес на обсуждение. Интересно всетаки, что остальные думают.
Мне так эта опция не нужна, по крайней мере никогда потребности в ней не испытывал.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Здравствуйте, VladD2, Вы писали:
VD>>Тут как раз проблем нет. Вывод типов подберет нужный вариант. С методами же работает?
ВВ>А что будет происходить в том случае, когда подходят оба?
Дык а на этот счет у компилятора есть сообщение про неоднозначность.
Здравствуйте, hardcase, Вы писали:
ВВ>>А что будет происходить в том случае, когда подходят оба? H>Дык а на этот счет у компилятора есть сообщение про неоднозначность.
А как разрулить неоднозначность? Как мне *явно* передать именно метод 1, а не 2?
Здравствуйте, hardcase, Вы писали:
H>Это понятно, просто на канале этот вопрос всплыл, вот я его и вынес на обсуждение. Интересно всетаки, что остальные думают. H>Мне так эта опция не нужна, по крайней мере никогда потребности в ней не испытывал.
Когда я только познакомился с немерлом, этот вопрос у меня тоже возник. Но сейчас он даже не возникает.
Локальные функции в основном используются как строительный материал, а не как АПИ. Для первого перегрузка не нужна. Зато возможность многократно что-то переопределять вполне неплохо работает.
Вообще новичкам (особенно пришедшим с шарпа) надо понять, что главное отличие локальных функций немерла не в том, что они не поддерживают перегрузку (это как раз мелочи), а в том, что важно их положение внутри метода, так как они очень часто используют замыкание. Это опять же следствие того, что локальная функция — это строительный блок. Она не имеет смысла вне контекста решения задачи метода.
Если нужна перегрузка — объявляйте полноценные методы. При этом вам будет доступна вся прелесть привычных технологий : полиморфизм (перегрузка и переопределение) и отсутствие зависимости от порядка следования методов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Воронков Василий, Вы писали: ВВ>>А что будет происходить в том случае, когда подходят оба? VD>Как и в случае методов — выдваться сообщение об ошибке. Но это уже почти наверняка ошибка в программе, так как глупо делать одинаковые функции.
Ну т.е. предполагается, что при возникновении неоднозначности разрулить эту ситуацию никак нельзя будет? Только переименовать метод?
Что-то мне не нравится такая перегрузка. Польза сомнительна, а вред...
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Ну т.е. предполагается, что при возникновении неоднозначности разрулить эту ситуацию никак нельзя будет? Только переименовать метод?
С методами и сегодня все именно так. И, заметь, никто не жужжит!
ВВ>Что-то мне не нравится такая перегрузка. Польза сомнительна, а вред...
Я не агитирую за введение перегрузки для локальных функций. Я просто указываю не беспочвенность твоих подозрений.
Нет проблем с методами, не будет и с локальными функциями.
Разные сигнатуры дают именно для того чтобы можно было отличить одну функцию от другой. И если какой-то болван создал неотличимые перегрузки, то самое логично что можно сделать — это выдать сообщение об ошибке.
Учитывая, что для локальных фунций нет никаких проблем их переименовать — этот вопрос просто высосан из пальца.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
ВВ>>Ну т.е. предполагается, что при возникновении неоднозначности разрулить эту ситуацию никак нельзя будет? Только переименовать метод? VD>С методами и сегодня все именно так. И, заметь, никто не жужжит!
Мне казалось, что есть некий способ конверсии делегат -> функциональный тип.
ВВ>>Что-то мне не нравится такая перегрузка. Польза сомнительна, а вред... VD>Я не агитирую за введение перегрузки для локальных функций. Я просто указываю не беспочвенность твоих подозрений.
Дело в том, что функциональный тип — это call by value. В данном же случае предполагается вводить *видимость* того, что это не так, благодаря тому, что вывод типов будет сам выбирать нужную функцию. И сие на мой взгляд несколько смешивает напитки.
VD>Нет проблем с методами, не будет и с локальными функциями. VD>Разные сигнатуры дают именно для того чтобы можно было отличить одну функцию от другой. И если какой-то болван создал неотличимые перегрузки, то самое логично что можно сделать — это выдать сообщение об ошибке. VD>Учитывая, что для локальных фунций нет никаких проблем их переименовать — этот вопрос просто высосан из пальца.
Сам вопрос про перегрузку высосан из пальца. Мне вообще непонятно, почему бы не связывать разные функции с разными именами. Зачем одинаковые имена?
Здравствуйте, Воронков Василий, Вы писали:
ВВ>>>Ну т.е. предполагается, что при возникновении неоднозначности разрулить эту ситуацию никак нельзя будет? Только переименовать метод? VD>>С методами и сегодня все именно так. И, заметь, никто не жужжит!
ВВ>Мне казалось, что есть некий способ конверсии делегат -> функциональный тип.
Казалось бы причем тут делегаты?
ВВ>>>Что-то мне не нравится такая перегрузка. Польза сомнительна, а вред... VD>>Я не агитирую за введение перегрузки для локальных функций. Я просто указываю не беспочвенность твоих подозрений.
ВВ>Дело в том, что функциональный тип — это call by value. В данном же случае предполагается вводить *видимость* того, что это не так, благодаря тому, что вывод типов будет сам выбирать нужную функцию. И сие на мой взгляд несколько смешивает напитки.
Чушь какая-то.
Давай проще поступим. Тебя что-то не устраивает в том как методы (обычные, те что в классах и модулях объявляются) используются в качестве функциональных значений?
VD>>Нет проблем с методами, не будет и с локальными функциями. VD>>Разные сигнатуры дают именно для того чтобы можно было отличить одну функцию от другой. И если какой-то болван создал неотличимые перегрузки, то самое логично что можно сделать — это выдать сообщение об ошибке. VD>>Учитывая, что для локальных фунций нет никаких проблем их переименовать — этот вопрос просто высосан из пальца.
ВВ>Сам вопрос про перегрузку высосан из пальца. Мне вообще непонятно, почему бы не связывать разные функции с разными именами. Зачем одинаковые имена?
Это уже другой вопрос. Обоснование может быть элементарное — единообразие языка. Раз для методов есть перегрузка, то и для локальных функций тоже она должна быть (это я пересказываю свои умозаключения времен начального знакомства с немерлом).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
ВВ>>Мне казалось, что есть некий способ конверсии делегат -> функциональный тип. VD>Казалось бы причем тут делегаты?
Ну аналогичная неоднозначность в шарпе решается явным привидением к делегату определенного типа.
ВВ>>>>Что-то мне не нравится такая перегрузка. Польза сомнительна, а вред... VD>>>Я не агитирую за введение перегрузки для локальных функций. Я просто указываю не беспочвенность твоих подозрений.
ВВ>>Дело в том, что функциональный тип — это call by value. В данном же случае предполагается вводить *видимость* того, что это не так, благодаря тому, что вывод типов будет сам выбирать нужную функцию. И сие на мой взгляд несколько смешивает напитки.
VD>Чушь какая-то.
Я не вижу особой разницы между:
def x = 1;
и
def f(x) { x + 1 };
И то, и другое вводит некое имя, которое связывается со значением. В первом случае значение — это интегральный тип, во втором — функциональный.
И перегрузка во втором случае имеет не намного больше смысла, чем в первом.
Собственно, не знаю как в Немерле, но как правило синтаксис объявления функции вида:
let f x = x + 1
есть лишь сахар для:
let f = fun x -> x + 1
VD>Давай проще поступим. Тебя что-то не устраивает в том как методы (обычные, те что в классах и модулях объявляются) используются в качестве функциональных значений?
Да в принципе нет. Ну так они на то и методы, чтобы использоваться *в качестве* функциональных значений, сами по себе они не являются функциональными типами.
ВВ>>Сам вопрос про перегрузку высосан из пальца. Мне вообще непонятно, почему бы не связывать разные функции с разными именами. Зачем одинаковые имена? VD>Это уже другой вопрос. Обоснование может быть элементарное — единообразие языка. Раз для методов есть перегрузка, то и для локальных функций тоже она должна быть (это я пересказываю свои умозаключения времен начального знакомства с немерлом).
Единообразия языка уже нет — есть методы, а есть фунциональные типы. Это плата за гибридность.
Re[10]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Ну аналогичная неоднозначность в шарпе решается явным привидением к делегату определенного типа.
Не решается. Оба метода могу приводиться к одному делегату. А если это не так, то у них разные типы, и значит компилятор разберется и так. В крайнем случае есть приведение к функциональному типу.
ВВ>Я не вижу особой разницы между:
ВВ>
ВВ>def x = 1;
ВВ>
ВВ>и
ВВ>
ВВ>def f(x) { x + 1 };
ВВ>
Ну, и не вижу. Но тут можно сказать, что f(x : int) и f(x : string) — это разные имена.
ВВ>И то, и другое вводит некое имя, которое связывается со значением. В первом случае значение — это интегральный тип, во втором — функциональный. ВВ>И перегрузка во втором случае имеет не намного больше смысла, чем в первом.
Если некоторая мысль приходит в разные головы, то в этой мысли определенно что-то есть. Не находишь?
Еще раз. Я не выступаю за перегрузку для локальных функций. Я просто указал на несостоятельность твоих исходных аргументов.
ВВ>Собственно, не знаю как в Немерле, но как правило синтаксис объявления функции вида:
ВВ>
ВВ>let f x = x + 1
ВВ>
ВВ>есть лишь сахар для:
ВВ>
ВВ>let f = fun x -> x + 1
ВВ>
В немерле это не так. В нем все наоборот. Базовой вещью являются функции (локальные, глобальные или экзеплярные методы), а всевозможный лямбды уже строяются на их базе.
Таким образом код:
fun(x) { x * x }
преобразуется компилятором в:
{ def f(x) { x * x } f }
Ну, а код:
x => x * x
или
_ * _
вообще является сахаром (макросами или фичами компилятора) и всегда переписывается в лямбду первого образца.
VD>>Давай проще поступим. Тебя что-то не устраивает в том как методы (обычные, те что в классах и модулях объявляются) используются в качестве функциональных значений?
ВВ>Да в принципе нет. Ну так они на то и методы, чтобы использоваться *в качестве* функциональных значений, сами по себе они не являются функциональными типами.
Ну, так локальные функции тут ничем не отличаются. Так что правила перегрузки можно было бы распространить и на них. Технически — это возможно.
ВВ>Единообразия языка уже нет — есть методы, а есть фунциональные типы. Это плата за гибридность.
Ты похоже заблуждаешься еще глубже. Есть методы, локальные функции и функциональные значения в роли которых могут выступать как методы, так и локальны функции. Вопрос же перегрузки локальных функций совершенно никак не влияет на это положение вещей.
Простой пример. Функция:
def f(x : int) { x * x }
и метод:
module X
{
public M(x : int) : int{ x - x }
}
имеют один и тот же тип int -> int. Так что с точки зрения резрешения перегрузки они ничем не отличаются. Более того, когда метод и локальная функция имеют одинаковое имя, они могут попасть в один список перегрузки компилятор выберет из них лучшую или сообщит об ошибке (неоднозначности).
Так что сдается мне, что ты просто не верно понимаешь суть вопроса.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, VladD2, Вы писали:
VD>Ну, и не вижу. Но тут можно сказать, что f(x : int) и f(x : string) — это разные имена.
Мне это непонятно. Имя одно — f. Можно сказать, что и
def x = { X = 1, Y = 2 }
def x = { Name = "", LastName ="" }
это разные имена.
ВВ>>И то, и другое вводит некое имя, которое связывается со значением. В первом случае значение — это интегральный тип, во втором — функциональный. ВВ>>И перегрузка во втором случае имеет не намного больше смысла, чем в первом. VD>Если некоторая мысль приходит в разные головы, то в этой мысли определенно что-то есть. Не находишь?
Сомневаюсь, что эта мысль будет приходить в головы к людям, писавших до этого на чистых ФЯ.
VD>Еще раз. Я не выступаю за перегрузку для локальных функций. Я просто указал на несостоятельность твоих исходных аргументов.
ВВ>>Собственно, не знаю как в Немерле, но как правило синтаксис объявления функции вида:
ВВ>>
ВВ>>let f x = x + 1
ВВ>>
ВВ>>есть лишь сахар для:
ВВ>>
ВВ>>let f = fun x -> x + 1
ВВ>>
VD>
_ * _
VD>вообще является сахаром (макросами или фичами компилятора) и всегда переписывается в лямбду первого образца.
Я запись вида def f(x) { x * x } читаю так: объявляется имя f, значением которого является функция типа int->int. Это неверно?
В таком разрезе я ожидаю от имени f такого же поведения, как если бы значением его была бы строка или целое число.
VD>>>Давай проще поступим. Тебя что-то не устраивает в том как методы (обычные, те что в классах и модулях объявляются) используются в качестве функциональных значений? ВВ>>Да в принципе нет. Ну так они на то и методы, чтобы использоваться *в качестве* функциональных значений, сами по себе они не являются функциональными типами. VD>Ну, так локальные функции тут ничем не отличаются. Так что правила перегрузки можно было бы распространить и на них.
Локальные функции отличаются тем, что привязка к имени, т.е. к переменной уже произошла.
VD>Технически — это возможно.
Я вижу, что технически это возможно, но мне эта возможность кажется странной.
ВВ>>Единообразия языка уже нет — есть методы, а есть фунциональные типы. Это плата за гибридность. VD>Ты похоже заблуждаешься еще глубже. Есть методы, локальные функции и функциональные значения в роли которых могут выступать как методы, так и локальны функции. Вопрос же перегрузки локальных функций совершенно никак не влияет на это положение вещей. VD>Простой пример. Функция: VD>
def f(x : int) { x * x }
Я здесь вижу биндинг значения функционального типа к имени f.
VD>и метод: VD>
module X
VD>{
VD> public M(x : int) : int{ x - x }
VD>}
Здесь я никакого биндинга не вижу.
VD>имеют один и тот же тип int -> int. Так что с точки зрения резрешения перегрузки они ничем не отличаются. Более того, когда метод и локальная функция имеют одинаковое имя, они могут попасть в один список перегрузки компилятор выберет из них лучшую или сообщит об ошибке (неоднозначности). VD>Так что сдается мне, что ты просто не верно понимаешь суть вопроса.
Я понимаю так, что есть call by value, а есть перегрузка. Когда функция становится значением, то понятие перегрузки теряет смысл.
Немерле пытается схитрить и когда у нас есть обращение к некоторому имени f, вместо него может произойти вызов функции-члена с таким же именем вместо того, чтобы вызвать функцию, которая является значением переменной f. Мне кажется, это не очень красивый момент в поведении языка. В данном-то случае это есть необходимо зло и плата за поддержку ООП и ФП.
А вот в случае с перегрузкой локальных функций мы еще больше запутываем ситуацию, когда это не несет никаких реальных бенефитов.
С функциями есть два противоположных подхода — call by value и перегрузка. Я понимаю, что в ряде случаев их приходится смешивать, когда речь идет о поддержке кардинальных возможностей таких как ООП. Но все же, мне кажется, смешивать их стоит как можно меньше.
Re[12]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Мне это непонятно. Имя одно — f. Можно сказать, что и ВВ>
ВВ>def x = { X = 1, Y = 2 }
ВВ>def x = { Name = "", LastName ="" }
ВВ>
ВВ>это разные имена.
Похоже тебе снова не с кем поспорить.
Я тебе свою точку зрения иложил. Спорить мне не о чем.
ВВ>Локальные функции отличаются тем, что привязка к имени, т.е. к переменной уже произошла.
Нет никакой привязки к имени. Это ты сам выдумал. В Немерле есть процедура разрешения перегрузки которая запускается каждый раз когда идет попытка скомпилировать вызов (любой и чего угодно).
VD>>Технически — это возможно.
ВВ>Я вижу, что технически это возможно, но мне эта возможность кажется странной.
Замечательно. И что? Я уже раз 10 повторил, что твоих исходные аргументы ошибочны.
А то что тебе что-то кажется не естественным или попросту не нравится я даже не хочу оспаривать.
Есть люди которые думают с точностью до наборот. Причем их не мало, так как это стандартное мышление человека пришедшего с C# и не успевшего обжиться с непривычными для себя подходами.
VD>>Простой пример. Функция: VD>>
def f(x : int) { x * x }
ВВ>Я здесь вижу биндинг значения функционального типа к имени f.
VD>>и метод: VD>>
module X
VD>>{
VD>> public M(x : int) : int{ x - x }
VD>>}
ВВ>Здесь я никакого биндинга не вижу.
Смешно. Это батенька не более чем сематика. И она такова какой ее кто-то придумал. Видить здесь можно что-то исключительно телепатически.
ВВ>Я понимаю так, что есть call by value, а есть перегрузка.
Это очередная чушь. Иди посмотри что значит употребляемый тобой термин.
ВВ>Когда функция становится значением, то понятие перегрузки теряет смысл.
Смысл стремительно теряют твои слова. А функция в немерле всегда рассматривается как ссылочный объект (если уж говорить о семантике). И никаких "вэлью" там даже рядом не стояло.
ВВ>Немерле пытается схитрить и когда у нас есть обращение к некоторому имени f, вместо него может произойти вызов функции-члена с таким же именем вместо того, чтобы вызвать функцию, которая является значением переменной f. Мне кажется, это не очень красивый момент в поведении языка. В данном-то случае это есть необходимо зло и плата за поддержку ООП и ФП.
Блин. Есть два подхода. Затенение имен и перегрузка имен. Выбор одного из вариантов — это не более чем дизайнерский выбор. Объективных причин тут нет. Это дело вкуса и общего дизайна языка.
Прекрати искать какой-то сакраментальный смысл там где его нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.