Язык с приложениями венгерской поддержки? - PullRequest
0 голосов
/ 29 марта 2012

В общем, мне интересно, существует ли язык, где этот код будет недействительным, потому что, хотя counter и distance оба int находятся под капотом, они представляют несовместимые типы в реальном мире :

#include <stdio.h>

typedef int counter;
typedef int distance;

int main() {
    counter pies = 1;
    distance lengthOfBiscuit = 4;

    printf("total pies: %d\n", pies + lengthOfBiscuit);

    return 0;
}

Это компилируется без предупреждений с помощью "gcc -pedantic -Wall" и всех других языков, на которых я его пробовал. Кажется, было бы неплохо запретить случайное добавление счетчика и расстояния, так где же поддержка языка?

(Между прочим, реальным примером, который вызвал этот вопрос, была работа веб-разработчика на PHP и Python - я пытался создать «HTML-экранированную строку», «SQL-экранированную строку» и «необработанный опасный ввод пользователя» несовместимо, но лучшее, что я могу получить, - это венгерская нотация приложений, как предлагается здесь -> http://www.joelonsoftware.com/articles/Wrong.html <- и которая все еще опирается на проверку человеком («неправильный код выглядит неправильно»), а не на поддержку компилятора (« неправильный код <em>является неправильным "))

Ответы [ 3 ]

1 голос
/ 13 февраля 2015

Haskell может сделать это, с помощью GeneralizedNewtypeDeriving вы можете рассматривать упакованные значения как основную вещь, в то же время предоставляя только то, что вам нужно:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype Counter = Counter Int deriving Num
newtype Distance = Distance Int deriving Num

main :: IO ()
main = print $ Counter 1 + Distance 2

Теперь вы получаете ошибку:

Add.hs:6:28:
    Couldn't match expected type ‘Counter’ with actual type ‘Distance’
    In the second argument of ‘(+)’, namely ‘Distance 2’
    In the second argument of ‘($)’, namely ‘Counter 1 + Distance 2’

Вы все еще можете «принудительно» принудительно указать тип данных с помощью «coerce» или явным образом распаковав Ints.

Я должен добавить, что любой язык с «настоящими» типами должен это делать.

0 голосов
/ 31 марта 2012

В Ada у вас могут быть типы, которые используют то же представление, но все еще являются разными типами.Каким будет «сильный typedef» (если он существует) в C или C ++.

В вашем случае вы можете сделать

type counter is new Integer;
type distance is new Integer;

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

Производные типы и подтипы в Ada

0 голосов
/ 29 марта 2012

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

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

В C ++ вы можете проверить поддержку BOOST для измерений .Данный пример предназначен в первую очередь для физических измерений, но я думаю, что вы можете адаптировать его и ко многим другим.

...