статические методы делают Java псевдо-функциональным языком? - PullRequest
7 голосов
/ 25 февраля 2009

Я размышлял о сообщении Миско Хевери, что статические методы в Java - это смерть для возможности тестирования . Я не хочу обсуждать проблему тестируемости, но больше о концепции статических методов. Почему люди так его ненавидят?

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

Ответы [ 6 ]

4 голосов
/ 25 февраля 2009

Статические методы затрудняют тестирование, потому что их нельзя заменить, это так просто.

Как статические методы могут "имитировать" функции как объекты первого класса 1 ? Возможно, они хуже всего на этом фронте. Вы можете «подражать» функциям как объектам первого класса, создавая интерфейсы с одним методом, и действительно, Java-коллекции Google делают именно это в ряде мест (для предикатов, проекций и т. Д.). Это невозможно сделать статическими методами - нет способа (кроме отражения) передать концепцию «когда вы хотите применить функцию, используйте этот метод.

Нет, я не вижу, как статические методы помогают здесь. Они препятствуют изменению состояния (поскольку единственным доступным состоянием является глобальное состояние и любое изменяемое состояние, передаваемое через параметры), но они не помогают на стороне «функции как объекты первого класса».

C # имеет лучшую поддержку для этого (с лямбда-выражениями и делегатами), но даже это не так широко, как могло бы быть. (Сравните это с F #, например.)


1 Начиная с Java 8, ссылки на методы позволят преобразовывать методы в экземпляры соответствующих интерфейсов с одним методом, что сделает все это более актуальным. Еще в 2009 году было еще далеко ...

3 голосов
/ 25 февраля 2009

Одной из характеристик функционального программирования является неизменность данных. static подразумевает, что вам не нужен объект (экземпляр), представляющий состояние, так что это неплохое начало. Однако у вас есть состояние на уровне класса, но вы можете сделать это final. Поскольку (статические) методы вообще не являются первоклассными функциями, вам все равно понадобятся некрасивые конструкции, такие как анонимные классы, чтобы приблизиться к определенному стилю функционального программирования в Java.

FP лучше всего делать на функциональном языке, поскольку он имеет необходимый язык поддержка для таких вещей, как функции высшего порядка, неизменяемость, ссылочная прозрачность и т. Д.

Однако это не означает, что вы не можете программировать в функциональном стиле на императивном языке, таком как Java. Можно привести и другие примеры. Это не потому, что вы программируете на Java, вы делаете ООП. Вы можете программировать с глобальными данными и неструктурированными потоками управления (goto) на структурированном языке C ++. Я могу сделать ООП на таком функциональном языке, как Scheme. И т.д.

Стив Макконнелл упоминает разницу в программировании на языке против программирования на языке в Code Complete (также очень популярном справочнике по SO).

Короче говоря, если вы скажете, что «статические методы имитируют первоклассные функции», я не согласен.

Если, однако, и я думаю, что это была более важная тема, которую вы пытались донести, вы бы сказали, что «статические методы могут помочь в программировании в функциональном стиле на Java», я согласен.

3 голосов
/ 25 февраля 2009

Функционально! = Функция, и для записи я буду утверждать, что метод! = Функция ...

Java - это статически типизированный объектно-ориентированный язык. Java также поддерживает относительную чистоту таким образом, но его нет рядом с функциональным языком.

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

C ++ имеет функции, но C ++ также имеет классы. Поэтому в C ++ есть два типа функций: функции-члены и функции. Когда вы говорите метод, вы имеете в виду функцию-член. Потому что метод вызывается для экземпляра объекта. Но когда вы говорите статический метод, вы имеете в виду просто функцию (в смысле C / C ++). Это просто словарь для ссылки на элементы вашего кода. И в коде Java не может существовать вне класса, метод подразумевает, что он принадлежит какому-то классу, то есть типу.

Пока что ничего из того, что я сказал, не относится к функциональному программированию, но я думаю, что вы поняли, где ошибаетесь.

Я предлагаю вам взглянуть на чисто функциональные языки программирования, такие как Haskell или Erlang. Потому что функциональные языки программирования, как правило, тоже не имеют доводчиков.

Ваше утверждение, что статические методы могут использоваться для имитации функций, поскольку объекты первого класса звучат для меня очень странно. Это больше похоже на динамический язык программирования, чем на функциональное.

0 голосов
/ 25 февраля 2009

В Java нельзя передать функцию в качестве аргумента другой функции.

На функциональном языке, если у вас есть функция

def addOne(i) = i + 1

Вы можете передать это другой функции, которая, например, применяет ее ко всем элементам списка.

В Java с

public static int addOne(int i) { return i + 1; }

нет способа сделать это.

0 голосов
/ 25 февраля 2009

Если вы используете только статические методы, то вы программируете в процедурном, не объектно-ориентированном стиле.

Тем не менее, единственный контекст, который я могу придумать, где это будет нормально, - это во время первых уроков программирования, прежде чем вводится ориентация объекта.

0 голосов
/ 25 февраля 2009

Мое самое большое возражение против статических методов состоит в том, что они не полиморфны и что они не используются объектно-ориентированным способом, вместо этого вам нужен класс (не объект) для доступа к ним.

...