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. Мне кажется, это не очень красивый момент в поведении языка. В данном-то случае это есть необходимо зло и плата за поддержку ООП и ФП.
Блин. Есть два подхода. Затенение имен и перегрузка имен. Выбор одного из вариантов — это не более чем дизайнерский выбор. Объективных причин тут нет. Это дело вкуса и общего дизайна языка.
Прекрати искать какой-то сакраментальный смысл там где его нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, VladD2, Вы писали:
VD>Похоже тебе снова не с кем поспорить.
А в чем проблема-то?
VD>Я тебе свою точку зрения иложил. Спорить мне не о чем.
Ну так я ее не понял. Почему f(x) и f(x, y) это разные имена, а x = 1 и x = { someobject } — нет? Принцип-то какой?
То, что в скобочках после f — это часть описания *функции*, т.е. значения, которая у нас справа пишется. У тебя получается, что тип значения каким-то загадочным образом меняет имя.
Вот мне эта концепция непонятна.
ВВ>>Локальные функции отличаются тем, что привязка к имени, т.е. к переменной уже произошла. VD>Нет никакой привязки к имени. Это ты сам выдумал.
Это как? А где она? Это не я выдумал, это терминология, используемая в большинства ФЯ.
Я выдумал только термин "call by value"
VD>В Немерле есть процедура разрешения перегрузки которая запускается каждый раз когда идет попытка скомпилировать вызов (любой и чего угодно).
Я тебе задавал выше вопрос, ты не ответил.
def f(x) { x + 1} — это объявление переменной f типа int->int или же нет?
VD>>>Технически — это возможно. ВВ>>Я вижу, что технически это возможно, но мне эта возможность кажется странной. VD>Замечательно. И что? Я уже раз 10 повторил, что твоих исходные аргументы ошибочны.
Какие именно?
VD>А то что тебе что-то кажется не естественным или попросту не нравится я даже не хочу оспаривать. VD>Есть люди которые думают с точностью до наборот. Причем их не мало, так как это стандартное мышление человека пришедшего с C# и не успевшего обжиться с непривычными для себя подходами.
Ну а есть люди, которые не думают с точностью до наоборот, причем тут это? Многие ведь могут прийти к Немерле не из шарпа, а из, скажем, Окамла.
ВВ>>Здесь я никакого биндинга не вижу. VD>Смешно. Это батенька не более чем сематика. И она такова какой ее кто-то придумал. Видить здесь можно что-то исключительно телепатически.
Что значит "не более чем семантика"? А какой биндинг ты видишь во втором случае? Или для этого-то как раз телепатия и используется. Во втором случае я не вижу не то, что биндинга, но даже объявляение какого-либо имени.
Это вообще примеры кода из "двух миров".
ВВ>>Я понимаю так, что есть call by value, а есть перегрузка. VD>Это очередная чушь. Иди посмотри что значит употребляемый тобой термин. ВВ>>Когда функция становится значением, то понятие перегрузки теряет смысл. VD>Смысл стремительно теряют твои слова. А функция в немерле всегда рассматривается как ссылочный объект (если уж говорить о семантике). И никаких "вэлью" там даже рядом не стояло.
Ты, я вижу, любитель поспорить о терминах. Тебе непонятно, что я имел в виду? Речь всего лишь о том, что функция является таким же значением, как и любое другое, и вызов функции есть операция над этим значением — такая же, как + для целых или вещественных чисел. Т.е. есть конкретное значение, записанное по адресу funName, над которым совершается операция call. Такова семантика большинства ФЯ.
ВВ>>Немерле пытается схитрить и когда у нас есть обращение к некоторому имени f, вместо него может произойти вызов функции-члена с таким же именем вместо того, чтобы вызвать функцию, которая является значением переменной f. Мне кажется, это не очень красивый момент в поведении языка. В данном-то случае это есть необходимо зло и плата за поддержку ООП и ФП. VD>Блин. Есть два подхода. Затенение имен и перегрузка имен. Выбор одного из вариантов — это не более чем дизайнерский выбор. Объективных причин тут нет. Это дело вкуса и общего дизайна языка.
Выбор тут диктуется не дизайнерскими предпочтениями, а тем, какой парадигме следует язык. ФП требует функций как значений, ООП — перегрузки. Вот и вся проблема. Совмещать и то, и другое приходится "на стыке" ООП и ФП, но зачем это совмещать там, где это не требуется, мне непонятно.
Re[14]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Выбор тут диктуется не дизайнерскими предпочтениями, а тем, какой парадигме следует язык. ФП требует функций как значений, ООП — перегрузки. Вот и вся проблема. Совмещать и то, и другое приходится "на стыке" ООП и ФП, но зачем это совмещать там, где это не требуется, мне непонятно.
Так никто и не предлагает взять и совместить, тем более что предлагаемый синтаксис был в виде def-end, а не цепочка def-ов (что противоречит концепции затенения имен). Я просто спросил, насколько подобный функционал может быть актуален (кстати вопрос этот мне задал человек пришедший из C#).
/* иЗвиНите зА неРовнЫй поЧерК */
Re[14]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Я тебе задавал выше вопрос, ты не ответил. ВВ>def f(x) { x + 1} — это объявление переменной f типа int->int или же нет?
В Немерле — Нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, VladD2, Вы писали:
ВВ>>Я тебе задавал выше вопрос, ты не ответил. ВВ>>def f(x) { x + 1} — это объявление переменной f типа int->int или же нет? VD>В Немерле — Нет.
А во что тогда компилируется def f = fun(x) { x + 1 }? Функцию в Немерле вообще можно рассматривать как значение (не в смысле ref/value) — такое же, как и любое другое (числа, строки и пр.)?
Re[15]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, hardcase, Вы писали:
ВВ>>Выбор тут диктуется не дизайнерскими предпочтениями, а тем, какой парадигме следует язык. ФП требует функций как значений, ООП — перегрузки. Вот и вся проблема. Совмещать и то, и другое приходится "на стыке" ООП и ФП, но зачем это совмещать там, где это не требуется, мне непонятно. H>Так никто и не предлагает взять и совместить, тем более что предлагаемый синтаксис был в виде def-end, а не цепочка def-ов (что противоречит концепции затенения имен). Я просто спросил, насколько подобный функционал может быть актуален (кстати вопрос этот мне задал человек пришедший из C#).
А что дает это and? Зачем он? Этот момент я вообще не понял. and — это объявление взаимо-рекурсивных функций вообще-то.
Re[16]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, Воронков Василий, Вы писали:
ВВ>>>Я тебе задавал выше вопрос, ты не ответил. ВВ>>>def f(x) { x + 1} — это объявление переменной f типа int->int или же нет? VD>>В Немерле — Нет.
ВВ>А во что тогда компилируется def f = fun(x) { x + 1 }? Функцию в Немерле вообще можно рассматривать как значение (не в смысле ref/value) — такое же, как и любое другое (числа, строки и пр.)?
Если бы ты читал то что я пишу внимательно, то вопросов бы задавать не пришлось. В:
def f = { _N_lambda_1234(x) { x + 1 } _N_lambda_1234 };
где _N_lambda_1234 — это гарантированно уникальное имя не видимое для программиста.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, Воронков Василий, Вы писали:
ВВ>А что дает это and? Зачем он? Этот момент я вообще не понял. and — это объявление взаимо-рекурсивных функций вообще-то.
Вот это и делает.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[17]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, VladD2, Вы писали:
ВВ>>А что дает это and? Зачем он? Этот момент я вообще не понял. and — это объявление взаимо-рекурсивных функций вообще-то. VD>Вот это и делает.
А где там рекурсия?
Re[17]: [Фич риквест] Перегрузка локальных функций
Здравствуйте все, противники перегрузки локальных функций могут начинать меня бить за сабж, высказанный в irc.
VD>>Я тебе свою точку зрения иложил. Спорить мне не о чем.
ВВ>Ну так я ее не понял. Почему f(x) и f(x, y) это разные имена, а x = 1 и x = { someobject } — нет? Принцип-то какой? ВВ>То, что в скобочках после f — это часть описания *функции*, т.е. значения, которая у нас справа пишется. У тебя получается, что тип значения каким-то загадочным образом меняет имя. ВВ>Вот мне эта концепция непонятна.
Можно подумать о семантике в другом ключе. Приступим.
Давайте посмотрим на классы. Там есть некоторые данные и функции, замкнутые на эти данные. Что это напоминает? { mutable x=1; def f() { x=5; } }
Единственная разница в том, что в непосредственно теле класса нельзя писать код и замыкание захватывает переменные, объявленные и после определения функции (метода) тоже. Можно было бы вообще развить такой подход, что весь код в теле класса исполняется при загрузке класса, тогда например связывание происходило бы только с переменными выше определения, но это по-моему слишком радикально. Зато тогда появляется больше доводов в пользу унификации синтаксиса с введением def для полей и методов. С геттерами/сеттерами тогда правда не совсем понятная ситуация, но можно сказать, что это всего-лишь не вписывающийся в общую картину синтаксический сахар для вложенных классов с переопределёнными оператором = и приведения к типу. Хотел ещё сказать про идею эквивалентности переменных функциям, но не буду, потому что тогда с учётом перегрузки появляется возможность определения переменных с одним именем и разным типом, выбираемых в зависимости от их типа в операции.
В общем похоже мне с этими идеями надо форкать немерле и идти экспериментировать
Что же до языка в текущем виде, то на перегрузку локальных функций меня натолкнуло вот что: во-первых есть перегрузка обобщённых локальных функций (по дженерику), во-вторых есть зачатки сопоставления с образцом через tuples comprehension как например в def f((1,a),b), которая будет вызвана только когда в кортеже нулевой элемент равен 1, в противном случае произойдёт ошибка, в-третьих некоторую аналогию с классами я привёл выше. В принципе ничего не запрещает ввести перегрузку локальных функций с возможностью переопределения уже определённых выше функции, кроме того концепцию tuple comprehension'ов неплохо было бы развить в сопоставление с образцом по-типу того же хаскеля, при чём не только на кортежи среди аргументов, но и на сами аргументы. Если пойти дальше, то аналогичный механизм можно вкрутить в методы. Очевидно реализация через прокси-функцию с match.
Основные мои аргументы основываются именно на однородности языка, т.к. разнородность усложняет его и может отталкивать адептов.
Кстати, по поводу ВВ>Немерле пытается схитрить и когда у нас есть обращение к некоторому имени f, вместо него может произойти вызов функции-члена с таким же именем вместо того, чтобы вызвать функцию, которая является значением переменной f. Мне кажется, это не очень красивый момент в поведении языка. В данном-то случае это есть необходимо зло и плата за поддержку ООП и ФП.
можете привести примеры? Пока не смог добиться описанного поведения.
Спасибо за внимание.
Re[18]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, Воронков Василий, Вы писали:
ВВ>>>А что дает это and? Зачем он? Этот момент я вообще не понял. and — это объявление взаимо-рекурсивных функций вообще-то. VD>>Вот это и делает.
ВВ>А где там рекурсия?
Где "там"?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, VladD2, Вы писали:
ВВ>>>>А что дает это and? Зачем он? Этот момент я вообще не понял. and — это объявление взаимо-рекурсивных функций вообще-то. VD>>>Вот это и делает. ВВ>>А где там рекурсия? VD>Где "там"?
В изначальном примере. Предлагается, как я понимаю, разрешить перегрузку только для функций, объявленных через and — и какая тут связь, я не вижу.
Re[11]: [Фич риквест] Перегрузка локальных функций
Здравствуйте, VladD2, Вы писали:
VD>имеют один и тот же тип int -> int. Так что с точки зрения резрешения перегрузки они ничем не отличаются. Более того, когда метод и локальная функция имеют одинаковое имя, они могут попасть в один список перегрузки компилятор выберет из них лучшую или сообщит об ошибке (неоднозначности).
А можно поподробнее с этого места? Желательно с примером. Такой вот код у меня приводит к ошибке, независимо от того, объявляется ли локальная или анонимная функция:
Здравствуйте, Воронков Василий, Вы писали:
ВВ>В изначальном примере. Предлагается, как я понимаю, разрешить перегрузку только для функций, объявленных через and — и какая тут связь, я не вижу.
Что ты у меня то спрашиваешь? Я это не предлагал и не одобрал.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.