На каких языках ссылки по умолчанию не обнуляются? - PullRequest
6 голосов
/ 08 марта 2011

Из интереса я хочу прочитать о языках, которые сконструированы таким образом.Haskell один, верно?

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

И это только концепция функционального программирования?Он также существует в некоторых языках OO?

Ответы [ 6 ]

2 голосов
/ 08 марта 2011

Любой из производных от ML языков (одним из которых является Haskell) работает подобным образом, включая SML и F # (хотя null может просочиться в F # из взаимодействия .NET).Scala также обычно избегает null, но тот факт, что он находится на вершине JVM, делает его менее строгим, чем некоторые другие языки.

2 голосов
/ 08 марта 2011

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

Если вы хотите это поведение, вы должны изменить тип возврата вашей функции. Обычно для этого вы используете тип Maybe, например:

safeDiv :: Float -> Float -> Maybe Float

safeDiv a b
    | b == 0    = Nothing
    | otherwise = Just (a / b)

Это говорит о том, что safeDiv принимает два Float и возвращает тип Maybe Float. В теле функции я могу затем вернуть Nothing, если b равно нулю, в противном случае я возвращаю Just (a / b).

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

У Haskell, однако, есть исключения, которые могут быть выброшены и пойманы. Для чистых функций предпочтительно возвращать значение Maybe, а не просто выдавать ошибку, но даже некоторые функции Prelude (базовая библиотека) небезопасны. Например, head, который возвращает первый элемент списка, выдает ошибку, если список пустой, вместо того, чтобы возвращать значение, заключенное в Maybe.

1 голос
/ 10 марта 2011

C ++ был упомянут. Если бы я проектировал библиотеку C ++ с нуля (скажем, что-то вроде Qt), я бы фактически использовал указатели и ссылки в различных точках API, чтобы указать, может ли данный параметр или возвращаемый тип быть нулевым. Тогда видение «*» и «->» не будет в первую очередь визуальным индикатором того, что вы имеете дело с «нелокальным» объектом - это будет напоминанием о том, что вы имеете дело с чем-то, что может быть нулевым, и поэтому вам лучше проверить, так ли это.

Тип Maybe в Haskell очень прост, но это одна из лучших частей языка. Поступая таким образом в C ++, вы ничего не получите, но вы получите что-то, и я думаю, что это было бы весьма полезно. (Вкратце: если параметру функции не разрешено быть нулевым, проверка того, находится ли он во время выполнения, является вторым лучшим вариантом: если кто-то нарушил правила и дал вам нулевое значение, даже если вы проверите его, ничего еще нет Вполне разумно, что вы можете сделать что-то еще, кроме сбоя программы с помощью assert. Компилятору гораздо лучше установить, что он не может быть нулевым, и запретить вызывающим элементам передавать его в первую очередь.)

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

1 голос
/ 08 марта 2011

На ум приходят два языка, которые поддерживают как объектно-ориентированную парадигму, так и ненулевые типы: (возможно) C ++ и (определенно) Spec # .

Spec # - это формальный язык для контрактов API (под влиянием JML, AsmL и Eiffel), который расширяет C # конструкциями для ненулевых типов, предусловий, постусловий и инвариантов объектов. - с домашней страницы Spec # на Microsoft Research

Последнее, вероятно, не широко используется (если вообще используется).Там вы получаете необнуляемый тип, добавляя суффикс к ! (например, object! или string![]!).

Что касается C ++, я уверен, что кто-то умный найдет множество аргументов, почему C ++ долженне упоминаться здесь;Будучи сложным, деликатным языком, я уверен, что такие причины существуют.Мой аргумент для упоминания C ++ в любом случае заключается в том, что помимо указателей (*) (которые вполне могут быть 0), C ++ также имеет ссылки (&), которые должны быть инициализированы чем-то разумным.Основная проблема со ссылками, AFAIK, в том, что они не могут быть использованы для всего.Вероятно, есть определенные ситуации, например, с управлением памятью или умными указателями, когда вы не можете полностью избавиться от указателей.

Наконец, вы всегда можете попытаться создать свои собственные типы оберток, не допускающие значения NULL, например, в C #.Вероятно, как и многие другие, Джон Скит сделал это и написал об этом в блоге .Это работоспособное решение, но такой тип NotNull<T> может показаться немного громоздким, поскольку он не совсем интегрирован в язык, как в Spec #.

1 голос
/ 08 марта 2011

Вы обнаружите, что Nullable - это вопрос определения.

Большинство языков могут иметь указатели, допускающие обнуляемость, но не обнуляемые.Кроме того, многие языки предоставляют специальный объект null / nil, с помощью которого переменные инициализируются автоматически;Вы бы посчитали это обнуляемым?

С одной стороны, это специальное значение, отличное от всех значений, которые обычно хранятся в переменной (например, числа), и с этой точки зрения такое же, как если бы вы работали только с указателями на числа (обнуляемые).

С другой стороны, этот нулевой / ниль-объект является реальным объектом с реальным классом (в языках OO на основе классов) и будет понимать многие сообщения, которые вы отправляете ему, например asString (), так какреальный объект это не "ноль" в самом строгом смысле, верно?

0 голосов
/ 08 марта 2011

Это правда, что Haskell не имеет специального нулевого значения для каждого типа, но если вы работаете с реальными указателями, что позволяет FFI, вы можете создавать нулевые указатели.

...