Language with apps hungarian support?

好久不见. 提交于 2019-12-25 08:03:11

问题


Basically, I wonder if a language exists where this code will be invalid because even though counter and distance are both int under the hood, they represent incompatible types in the real world:

#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;
}

That compiles with no warnings with "gcc -pedantic -Wall" and all other languages where I've tried it. It seems like it would be a good idea to disallow accidentally adding a counter and a distance, so where is the language support?

(Incidentally, the real-life example that prompted this quesion was web dev work in PHP and Python -- I was trying to make "HTML-escaped string", "SQL-escaped string" and "raw dangerous user input" incompatible, but the best I can seem to get is apps hungarian notation as suggested here --> http://www.joelonsoftware.com/articles/Wrong.html <-- and that still relies on human checking ("wrong code looks wrong") rather than compiler support ("wrong code is wrong"))


回答1:


In Ada you can have types that use the same representation, but are still distinct types. What a "strong typedef" would be (if it existed) in C or C++.

In your case, you could do

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

to create two new types that behave like integers, but cannot be mixed.

Derived types and sub types in Ada




回答2:


Haskell can do this, with GeneralizedNewtypeDeriving you can treat wrapped values as the underlying thing, whilst only exposing what you need:

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

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

Now you get the error:

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’

You can still "force" the underlying data type with "coerce", or by unwrapping the Ints explicitly.

I should add that any language with "real" types should be able to do this.




回答3:


You could ccreate an object wrapping the undelying type in a member variable and define operations (even in the form of functions) that make sense on that type (e.g. LEngth would define "plus" allowing addition to another length, but for angle).

A drawback of this approach is you have to create a wrapper for each underlying type you care about and define the appropriate operations for each sensible combination, which might be tedious and possibly error-prone.

In C++, you could check out BOOST support for dimensions. The example given is designed primarily for physical dimensions, but I think you could adapt it to many others as well.



来源:https://stackoverflow.com/questions/9927288/language-with-apps-hungarian-support

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!