Deutsch

C# - pattern matching - many discards

7804   6 7 8 9 10 11 12 13 14 15 16 все
Срыв покровов патриот10.03.24 08:02
NEW 10.03.24 08:02 
в ответ AlexNek 09.03.24 21:41

Я уже писал, что для меня это одно и то же.

В чем я ошибаюсь?

MrSanders коренной житель10.03.24 10:40
NEW 10.03.24 10:40 
в ответ Срыв покровов 09.03.24 20:09, Последний раз изменено 10.03.24 11:12 (MrSanders)
сорри за возможно глупый вопрос: но вот это разве не делегаты?

Вот кстати да, как уточняет AlexNek, было бы неплохо определиться, а что мы вообще делегатами называем.

Для меня делегат это "переменная-метод". Которую можно использовать как метод.

Т.е. чтобы можно было сделать так:

Function<Integer, Double> half = a -> a /2.0;
// Applying the function to get the result
System.out.println(half(10));

В яве так сделать нельзя.
И этот "конструкт" должен быть "first-class citizen". Выполнять все 4 требования. В яве ссылки нa методы нельзя сравнивать. Не работает.

import java.util.function.Function;
public class MyClass {
    public static String value(int i) {
        return "Value: " + i;
    }
    public static void main(String args[]) {
      Function<Integer, String> f1 = MyClass::value; 
      Function<Integer, String> f2 = MyClass::value;    
      System.out.println("Same method? : " + f1.equals(f2));
    }
}

Вернёт false.


Function<Integer, Double> half = a -> a /2.0; компилятором превращается в

Function<Integer, Double> half = new Function<Integer, Double>() {
  @Override
  public Double apply(Integer t) {
    return t / 2.0;
  }
}

Новый класс. Сделали ещё раз то же самое, получили ещё один новый класс. То же и с ссылками,

из Function<Integer, String> f1 = MyClass::value; получается

Function<Integer, String> f1 = new Function<Integer, String>() {
  @Override
  public String apply(Integer t) {
    return MyClass.value(t);
  }
}

Два раза использовали ссылку, получили два класса. Сравниваешь их, а они не равны. Что правильно, это же разные классы. А вот логично было бы иметь возможность писать f1 == f2 и получать true. Если б это были и правда ссылки на методы. Вот такая фигня, малята.

Срыв покровов патриот10.03.24 10:59
NEW 10.03.24 10:59 
в ответ MrSanders 10.03.24 10:40, Последний раз изменено 10.03.24 10:59 (Срыв покровов)

требования, чтобы два делегата с одинаковым содержанием язык считал одинаковыми, я вообще не понимаю зачем ты сейчас привёл.
Без этого они не считаются делегатами?

MrSanders коренной житель10.03.24 11:17
NEW 10.03.24 11:17 
в ответ Срыв покровов 10.03.24 10:59, Последний раз изменено 10.03.24 11:25 (MrSanders)

Про одинаковое содержание я не заикаюсь.

Я про ссылку на одинаковый метод. x = <ссылка на метод>; y = <ссылка на тот же метод>; x == y => false. А должно быть true если б это была "настоящая ссылка на метод".


Ну, или так, сейчас со ссылками на методы такая ситуация, как будто ты делаешь

String x = "abc";

int l1 = x.length();

int l2 = x.length();

и l1 у тебя не равен l2.


P.S. к half(10) вместо half.apply(10) вопросов нет?

AlexNek патриот10.03.24 12:01
AlexNek
NEW 10.03.24 12:01 
в ответ Срыв покровов 10.03.24 08:02
В чем я ошибаюсь?

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

Поэтому давайте разбираться вместе.

https://learn.microsoft.com/en-us/dotnet/csharp/programmin...

https://www.c-sharpcorner.com/article/send-method-as-param...


C#

"A delegate is a type that represents references to methods with a particular parameter list and return type"

"Delegates are similar to C++ function pointers, but delegates are fully object-oriented, and unlike C++ pointers to member functions, delegates encapsulate both an object instance and a method."


delegate declaration

public delegate int Operation(int i, int j);

instantiate a delegate

Operation operation = (i, i1) => i + i1;

invoke

int result = operation(1, 2);


Java

"Since Java 1.8 we have the Java.util.Function interface (remember Java uses interfaces to send methods as parameters)."


Interface Function<T,R>


delegate declaration - нет


код похожий на instantiate a delegate

Function<Employee, String> f0 = (e) -> e.toString();


выполнение

String result = f0.apply(e1);

Отличия есть и довольно большие, хотя визуально ничего особенно не видно

alex445 коренной житель10.03.24 12:14
NEW 10.03.24 12:14 
в ответ MrSanders 10.03.24 10:40, Последний раз изменено 10.03.24 12:20 (alex445)
сорри за возможно глупый вопрос: но вот это разве не делегаты?
Вот кстати да, как уточняет AlexNek, было бы неплохо определиться, а что мы вообще делегатами называем.
Для меня делегат это "переменная-метод". Которую можно использовать как метод.
Т.е. чтобы можно было сделать так:



Function<Integer, Double> half = a -> a /2.0;
// Applying the function to get the result
System.out.println(half(10));
В яве так сделать нельзя.
И этот "конструкт" должен быть "first-class citizen". Выполнять все 4 требования. В яве ссылки нa методы нельзя сравнивать. Не работает.





import java.util.function.Function;
public class MyClass {
    public static String value(int i) {
        return "Value: " + i;
    }
    public static void main(String args[]) {
      Function<Integer, String> f1 = MyClass::value; 
      Function<Integer, String> f2 = MyClass::value;    
      System.out.println("Same method? : " + f1.equals(f2));
    }
}
Вернёт false.

Function<Integer, Double> half = a -> a /2.0; компилятором превращается в




Function<Integer, Double> half = new Function<Integer, Double>() {
  @Override
  public Double apply(Integer t) {
    return t / 2.0;
  }
}
Новый класс. Сделали ещё раз то же самое, получили ещё один новый класс. То же и с ссылками,
из Function f1 = MyClass::value; получается



Function<Integer, String> f1 = new Function<Integer, String>() {
  @Override
  public String apply(Integer t) {
    return MyClass.value(t);
  }
}
Два раза использовали ссылку, получили два класса. Сравниваешь их, а они не равны. Что правильно, это же разные классы. А вот логично было бы иметь возможность писать f1 == f2 и получать true. Если б это были и правда ссылки на методы. Вот такая фигня, малята.

Толчея воды в ступе. Спор даже не о словах, а о буквах. Единственный вывод, что я делаю из этой простыни: Джава говно, Сишарп - конфетка (по сравнению с Джавой).

AlexNek патриот10.03.24 13:09
AlexNek
NEW 10.03.24 13:09 
в ответ alex445 10.03.24 12:14
Единственный вывод, что я делаю

При этом не следует забывать добавить, для себя лично.

Из-за того, что мне не нравится тот или иной язык, не следует что он плохой.

Давайте сравним русский, немецкий и китайский - какой из них лучше?

Срыв покровов патриот10.03.24 13:37
NEW 10.03.24 13:37 
в ответ AlexNek 10.03.24 12:01

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

Вы можете хоть из штанов выпрыгнуть, но это одно и то же.

AlexNek патриот10.03.24 14:44
AlexNek
NEW 10.03.24 14:44 
в ответ Срыв покровов 10.03.24 13:37
что вы мне тут пытаетесь доказать?

Абсолютно ничего. Я предложил разбираться вместе и привел мои рассуждения. Вы с ними несогласны и приводите свои - ну так это замечательно. Через какое то время можно будет найти и точки соприкосновения. Ну или точно определится с разногласиями.


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

Если подходить более строго, то переменная может иметь только лишь значение и тип, но да понятно, что имелось в виду.

Однако для меня это определение - всего лишь ссылка на метод. Типа как в Си. МС не трактует делегаты подобным образом. (A delegate is a type that represents references to methods with a particular parameter list and return type. Delegates are an object-oriented, type safe, and secure type that safely encapsulates a method)


Вот еще определение нашел: The delegate is a reference type data type that defines the method signature. You can define variables of delegate, just like other data type, that can refer to any method with the same signature as the delegate.

Насколько я понял, в Яве подобного определения нет.


И я совсем не уверен, что в Яве возможно что то подобное

public delegate void MyDelegate();
MyDelegate delg = () =>  Console.WriteLine("Test");
delg();
alex445 коренной житель10.03.24 15:13
NEW 10.03.24 15:13 
в ответ Срыв покровов 10.03.24 13:37, Последний раз изменено 10.03.24 15:17 (alex445)
что вы мне тут пытаетесь доказать? Что в с# Что в яве я могу определить переменную или свойство с определённым входным и выходным типом, а затем в коде переопределять ее как мне заблагорассудится.
Вы можете хоть из штанов выпрыгнуть, но это одно и то же.

Они пытаются доказать, что если в Джаве реализовано по-другому, то это не делегаты, как в Шарпе, а своя какая-то неведомая херня. Можно было бы сказать, что в Шарпе - ссылки на методы. Но они и тут бы возбудились - нет, в Шарпе делегаты! Спорят о словах и прочих неважных вещах, лишь бы увести в сторону от главного - в Джаве это реализовано хуже и костыльнее, не такое широкое применение имеет и не так хорошо интегнировано в язык и фреймворк.

MrSanders коренной житель10.03.24 17:01
NEW 10.03.24 17:01 
в ответ AlexNek 10.03.24 14:44

И я совсем не уверен, что в Яве возможно что то подобное

public delegate void MyDelegate();
MyDelegate delg = () =>  Console.WriteLine("Test");
delg();

Примерно так же, кроме последней строчки. В яве ссылка не метод превращается в объект. И пока что синтаксический сахар, чтобы вызвать deleg() не прикрутили. Runnable существующий тип, можно определить свой. Просто интерфейс с одним методом.


Runnable delg = () -> System.out.println("Print");
delg.run();

А как в шарпе можно присвоить delegate-у существующий метод класса? MyDelegate delg = <метод printX() объекта x1 типа X>;

7495 старожил10.03.24 17:05
7495
NEW 10.03.24 17:05 
в ответ alex445 10.03.24 15:13
Спорят о словах и прочих неважных вещах, лишь бы увести в сторону от главного...


Абсолютно согласен с вами, коллега, надо смотреть ширше и глыбже! Неважно на каком языке реализовано - главное результат!


Надо смотреть на уровень зарплаты, у кого зарплата больше - тот и прав! Практика является важным критерием истинности!


Кто пьёт смузи, у кого нестыдная машина, кто работает начальником - тот и прав! Эта истина проста, но не всем доступна! зло

Вопросы и Ответы - Программируем калькулятор пособий для беженцев вместе.
MrSanders коренной житель10.03.24 17:10
NEW 10.03.24 17:10 
в ответ alex445 10.03.24 12:14
олчея воды в ступе. Спор даже не о словах, а о буквах.

Многабуков. Понимаю. Лонгрид. В клиповый мозг не прогрузилось. Не плачь, оно тебе не надо. Просто сиди, не кукарекай, и всё будет хорошо!

AlexNek патриот10.03.24 17:56
AlexNek
NEW 10.03.24 17:56 
в ответ MrSanders 10.03.24 17:01
Примерно так же, кроме последней строчки...А как в шарпе

Судя пот ответу вы считает, что я тоже бросаю камни в Яву. Абсолютно не так. Я просто пытаюсь найти отличия.

И в данном случае опирался на это

https://docs.oracle.com/javase/8/docs/api/java/util/functi...

Про Runnable там не было. Интересно как с различными количеством параметров происходит?


Но опять таки, я не вижу определения типа, так как используются только существующие (видимо) интерфейсы.

AlexNek патриот10.03.24 18:08
AlexNek
NEW 10.03.24 18:08 
в ответ alex445 10.03.24 15:13, Последний раз изменено 10.03.24 18:09 (AlexNek)
в Джаве это реализовано хуже и костыльнее

А можно уточнить какой у вас опыт разработки приложений на Яве?

Могу сразу сказать, что у меня нулевой. Но если в каком то языке мне что то не нравится - это совсем не значит что язык из-за этого полное дёрьмо.


пытаются доказать

Это просто размышления вслух, как способ изучения материала.

Что то кому то доказывать, практически бесполезная трата времени. А может и того хуже https://ru.wikipedia.org/wiki/Рели�%...


alex445 коренной житель10.03.24 18:38
NEW 10.03.24 18:38 
в ответ MrSanders 10.03.24 17:01, Последний раз изменено 10.03.24 18:48 (alex445)
И я совсем не уверен, что в Яве возможно что то подобное
public delegate void MyDelegate();
MyDelegate delg = () =>  Console.WriteLine("Test");
delg();
Примерно так же, кроме последней строчки. В яве ссылка не метод превращается в объект. И пока что синтаксический сахар, чтобы вызвать deleg() не прикрутили. Runnable существующий тип, можно определить свой. Просто интерфейс с одним методом.




Runnable delg = () -> System.out.println("Print");
delg.run();
А как в шарпе можно присвоить delegate-у существующий метод класса? MyDelegate delg = <метод printX() объекта x1 типа X>;

Можно вывести тип делегата автоматически (начиная с 10 версии языка), если он совпадает с одним из Func или Action (до 16 параметров в каждом). Как раньше было сказано, в Дотнете определены Func или Action с числом обобщённых параметров до 16 (плюс возврат для Func), что позволяет покрыть практически все варианты функций. Тут в меню слева видно. Это позволяет работать фиче автоматического выведения типа делегата. Но если у вас свой тип, повторяющий один из уже готовых Func или Action - может не сработать, или приведёт к одному из Func-Action (тут я точно не знаю - не использовал). Посему лучше использовать уже готовый тип, если он совпадает с нужной вам сигнатурой по входящим параметрам и возврату, чтобы все выведения работали автоматически. Те, кто нарушают конвенции и изобретают велосипеды - да, должны страдать.


Так что объявлять свои типы делегатов для типичных методов - бесполезное занятие. Разве что кто-то хочет именно через имя типа делегата разъяснить, для чего он служит. Но это лишнее. В Дотнете существуют старые делегаты, которые ввели до появления пачек Action и Func - их оставили для совместимости. Но фактически Predicate это один из вариантов Func.


Ещё тут разъяснено, и как это делалось до версии 10.

alex445 коренной житель10.03.24 18:49
NEW 10.03.24 18:49 
в ответ alex445 10.03.24 18:38, Последний раз изменено 10.03.24 18:58 (alex445)

Да, кстати, что там в Джаве в качестве аналога деревьев выражений?


"Most times you're going to want Func or Action if all that needs to happen is to run some code. You need Expression when the code needs to be analyzed, serialized, or optimized before it is run. Expression is for thinking about code, Func/Action is for running it."


Я уже не говорю про динамический LINQ.

MrSanders коренной житель10.03.24 18:55
NEW 10.03.24 18:55 
в ответ AlexNek 10.03.24 17:56, Последний раз изменено 10.03.24 19:10 (MrSanders)
Судя пот ответу вы считает, что я тоже бросаю камни в Яву. Абсолютно не так. Я просто пытаюсь найти отличия.

Нет, мне просто интересно как в шарпе реализовали именно ссылки на методы, а не присваивание "имён" лямбдам. Я с этим в шарпе не сталкивался.


Про Runnable там не было. Интересно как с различными количеством параметров происходит?

В яве сделали через "функциональные интерфейсы". Любой интерфейс с одним методом считается "функциональным", т.е. может описывать тип функции (метода).

Runnable старый интерфейс, который был и до 8-й явы, и не лежит в java.util.function. Но так как у него один метод, то и он стал "фунциональным" :) И он прям подошёл для твоего примера, потому что параметров нет и ничего не возвращает.


Фишка в том, что любой метод класса или лямбду можно определить типом функционального интерфейса у которого единственный метод имеет те же параметры (количество и тип) и тот же тип результата (ну, про наследование и приведение типов не забываем) что и наш метод / лямбда. В примере, как add: два инта и возвращает инт.


public interface MyMethod { int add(int a, int b);}

// Не функциональный! больше одного метода
public interfce TooManyMethods {
  int add(int a, int b);
  int multiply(int a, int b);
}

MyMethod m = (a, b) -> a + b;

// маловато параметеров, ошибка будет
MyMethod wrong = a -> a + 10;

как-то так

Срыв покровов патриот10.03.24 18:56
10.03.24 18:56 
в ответ alex445 10.03.24 18:49

да вроде то же самое есть

    private static Function<Integer, Integer> multiply = x -> x * 2;

    private static Function<Integer, Integer> add = x -> x + 2;

    private static Function<Integer, Unit> logOutput = x -> {
        logger.info("Data:" + x);
        return Unit.unit();
    };

    public static Unit execute(Integer input) {
        Function<Integer, Unit> pipeline = multiply
                                               .andThen(add)
                                               .andThen(logOutput);
        return pipeline.apply(input);
    } 
alex445 коренной житель10.03.24 19:08
NEW 10.03.24 19:08 
в ответ Срыв покровов 10.03.24 18:56, Последний раз изменено 10.03.24 19:26 (alex445)
да вроде то же самое есть







<code>    private static Function<Integer, Integer> multiply = x -> x * 2;

    private static Function<Integer, Integer> add = x -> x + 2;

    private static Function<Integer, Unit> logOutput = x -> {
        logger.info("Data:" + x);
        return Unit.unit();
    };

    public static Unit execute(Integer input) {
        Function<Integer, Unit> pipeline = multiply
                                               .andThen(add)
                                               .andThen(logOutput);
        return pipeline.apply(input);
    } </code>

Это больше похоже на Select и SelectMany - просто пачка расширяющих методов с делегатами в качестве параметров, применяемых ко входным данным и результатам. А я спросил про деревья выражений - сериализация делегатов и функций, представление их в виде данных.


Вобщем, я поискал - нет такого в Джаве из коробки. Есть какие-то сторонние либы, разрабатываемые энтузиастами, типа JaQue. Это не сравнимо с Дотнетом и Шарпом, где подобные фичи разрабатываются, внедряются во фреймворк и поддерживаются на системном уровне самой компанией-разработчиком языка и фреймворка. В Дажве и большинстве других языков без крупного хозяина всегда такие проблемы - их экосистемы представляют из себя конструктор "сделай сам" - т.е. практически отсутствуют. Надо писать под десктоп? - Ищи гуёвую либу под Джаву. Надо под веб? - Ищи гуёвую либу для веба. Надо трёхмерную графику? - Ищи джавовый движок. И вот часто у Джавы и других языков либо нет нифига для этого, либо что-то стороннее, с поддержкой мелкой фирмочки или вообще тремя с половиной энтузиастами. Хочешь комплексное решение "всё из коробки, подогнанное"? - Иди к Майкрософт. Да, у них есть проблемы. Но у других их ещё больше. Что-то подобное есть лишь у Эппл. Но хуже, мельче, меньший охват (нет своей СУБД, например), и нужно менять ориентацию (в переносном смысле).

6 7 8 9 10 11 12 13 14 15 16 все