Hot answers tagged

131

Primitives, such as string or int, have no meaning in a business domain. A direct consequence of this is that you may mistakenly use an URL when a product ID is expected, or use quantity when expecting price. This is also why Object Calisthenics challenge features primitives wrapping as one of its rules: Rule 3: Wrap all primitives and Strings In ...


80

Type systems prevent errors Type systems eliminates illegal programs. Consider the following Python code. a = 'foo' b = True c = a / b In Python, this program fails; it throws an exception. In a language like Java, C#, Haskell, whatever, this isn't even a legal program. You entirely avoid these errors because they simply aren't possible in the set of ...


62

("Java", as used here, is defined as standard Java SE 7; "Haskell", as used here, is defined as standard Haskell 2010.) Things that Java's type system has but that Haskell's doesn't: nominal subtype polymorphism partial runtime type information Things that Haskell's type system has but that Java's doesn't: bounded ad-hoc polymorphism gives rise to ...


55

I would use the scope as a rule of thumb: The narrower the scope of generating and consuming such values is, the less likely you have to create an object representing this value. Say you have the following pseudocode id = generateProcessId(); doFancyOtherstuff(); job.do(id); then the scope is very limited and I would see no sense in making it a type. But ...


48

Technically speaking, Java does have type inferencing when using generics. With a generic method like public <T> T foo(T t) { return t; } The compiler will analyze and understand that when you write // String foo("bar"); // Integer foo(new Integer(42)); A String is going to be returned for the first call and an Integer for the second call based ...


44

Yes, I believe that they do. There are a few reasons that need to be considered in the selection of a language for a new project: Run-time speed. Compared to C/C++/Fortran, Perl and Python are so slow it's funny. Initialization speed. Compared to the above fast languages, Java falls over and cries as the JVM keeps loading and loading and...while(1).... ...


43

That quote points to a problem that occurs if the declaration and assignment of identifiers (here: instance members) are separate from each other. As a quick pseudocode sketch: class Broken { val foo: Foo // where Foo and Bar are non-nullable reference types val bar: Bar Broken() { foo = new Foo() throw new Exception() ...


39

The problem with this kind of discussion is simply that the terms "weak typing" and "strong typing" are undefined, unlike for example the terms "static typing", "dynamic typing", "explicit typing", "implicit typing", "duck typing", "structural typing" or "nominal typing". Heck, even the terms "manifest typing" and "latent typing", which are still open areas ...


38

Let's take a look at Java. Java can't have variables with inferred types. This means I frequently have to spell out the type, even if it is perfectly obvious to a human reader what the type is: int x = 42; // yes I see it's an int, because it's a bloody integer literal! // Why the hell do I have to spell the name twice? ...


37

I believe that understanding Haskell's type system is an amplifier to understanding functional programming. The thing about purely functional programming is that in the absence of side-effects, which allow you to do all sorts of things implicitly, purely functional programming makes the structure of your programs much more explicit. Haskell prevents you ...


36

There's a fair bit of incorrect information in ratchet freak's answer and in its comment thread. I'll respond here in an answer, since a comment is too small. Also, since this an answer after all, I'll attempt to answer the original question too. (Note however that I am not an expert on type systems.) First, the short answers to the original question are ...


33

Almost every word you might think of adding as a keyword to a language has almost certainly been used as a variable name or some other part of working code. This code would be broken if you made that word a keyword. The incredibly lucky thing about auto is that it already was a keyword, so people didn't have variables with that name, but nobody used it, ...


33

"Never" is the canonical answer to "when is type testing okay?" There's no way to prove or disprove this; it is part of a system of beliefs about what makes "good design" or "good object-oriented design." It's also hokum. To be sure, if you have an integrated set of classes and also more than one or two functions that need that kind of direct type testing, ...


33

The use of subtypes creates a lot of complications when doing generic programming. If you insist on using a language with subtypes, you have to accept there's a certain inherent complexity in generic programming that comes along with it. Some languages do it better than others, but you can only take it so far. Contrast that with Haskell's generics, for ...


32

Some suggested reading: Developers Shift to Dynamic Languages (PDF) On the Revival of Dynamic Languages (PDF) Static typing where possible, dynamic typing when needed: The end of the cold war between programming languages (PDF) The Security of Static Typing with Dynamic Linking (PDF) Combining Static and Dynamic Reasoning for Bug Detection (PDF) Dynamic ...


32

The most dynamically typed functional language is arguably Scheme. That said, Haskell's type system is an indicator of its purity. It's a question of "how does one measure purity?". Haskell's type system lets you easily cordon off impure actions in IO. To do that, you need a static type system. But let's say Haskell's type system has nothing to do with ...


30

Java's type system lacks higher kinded polymorphism; Haskell's type system has it. In other words: in Java, type constructors can abstract over types, but not over type constructors, whereas in Haskell, type constructors can abstract over type constructors as well as types. In English: in Java a generic can't take in another generic type and parameterize ...


30

Neither. I take it you're asking whether having the same set of field types is enough to classify as being the same class, or whether they have to be named identically as well. The answer is: "Not even having the same types and the same names is sufficient!" Structurally equivalent classes are not necessarily type-compatible. For instance, if you have a ...


29

Static type systems are all about preventing incorrect uses of data. There are obvious examples of types doing this: you can't get the month of a UUID you can't multiply two strings. There are more subtle examples you can't pay for something using the length of desk you can't make an HTTP request using someone's name as the URL. We may be tempted ...


29

The Hindley-Milner type inference is used for Hindley-Milner type systems, a restriction of System-F type systems. The interesting feature of HM type systems is that they have parametric polymorphism (aka. generics). That is the single biggest type system feature that Golang refuses to have. With that idiotic restriction, HM-style type inference is ...


28

A strong type system is a type system that has a compile-time restriction or run-time feature that you find attractive. A weak type system is a type system which lacks that restriction or feature. Seriously, that's it. You read the Wikipedia page, so you know that there are at least eleven different mutually incompatible meanings of "strongly typed". The ...


28

I'll take a simple example: C++ vs Rust. Here is a function used to throw an exception in C++11: [[noreturn]] void ThrowException(char const* message, char const* file, int line, char const* function); And here is the equivalent in Rust: fn ...


27

Haskell's type system is fully inferrable (leaving aside polymorphic recursion, certain language extensions, and the dreaded monomorphism restriction), yet programmers still frequently provide type annotations in the source code even when they don't need to. Why? Type annotations serve as documentation. This is especially true with types as expressive as ...


27

To expand on @KarlBielefeldt's answer, here's a full example of how to implement Vectors - lists with a statically-known number of elements - in Haskell. Hold on to your hat... {-# LANGUAGE DataKinds #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE DeriveFoldable #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE ...


26

Is spatial efficiency (and improved spatial locality, especially in large arrays) the only reason why fundamental types are often not classes? No. The other issue is that fundamental types tend to be used by fundamental operations. The compiler needs to know that int + int isn't going to be compiled to a function call, but to some elementary CPU ...


26

I'll give a short answer due to my lack of time at the moment, but I'm currently working on two big projects (> 100.000 LOC in Haskell) - flowbox.io and luna-lang.org. We use Haskell for all the parts, including the backend, compiler of our programming language and even the webGL based GUI. I have to admit that the strong type system and the "dependent ...


25

Inheritance and polymorphism are widely used because they work, for certain kinds of programming problems. It's not that they're widely taught in schools, that's backwards: they're widely taught in schools because people (aka the market) found that they worked better than the old tools, and so schools began teaching them. [Anecdote: when I was first ...


24

I would say "Yes". As you say, the purpose of Hungarian Notation is to encode information in the name that cannot be encoded in the type. However, there are basically two cases: That information is important. That information is not important. Let's start with case 2 first: if that information is not important, then Hungarian Notation is simply ...


24

Yes, definitely. Functions/methods that take too many arguments is a code smell, and indicates at least one of the following: The function/method is doing too many things at once The function/method requires access to that many things because it's asking, not telling or violating some OO design law The arguments are actually closely related If the last ...


24

Let the contract of operation o of Type T be that it halts for all inputs. Now decide whether operation o of subtype S <: T satisfies that contract: you have just solved the Halting Problem. More generally, S::o must compute the same function as T::o if S <: T. Deciding whether two programs compute the same function is called the Function Problem and ...



Only top voted, non community-wiki answers of a minimum length are eligible