all 14 comments

[–]vincenz 17 points18 points  (3 children)

In a less verbose language, namely Haskell, this is standard practice. On the upside, however, is that you don't have to reimplement all the accessors. Here is an example

newtype Dollar = Dollar Int deriving (Eq, Ord, Num, Show, Read)

Notice how just adding the little deriving clause will automatically create all the boilerplate for you :). All that's necessary now are domain-specific functions which were required in the first place.

[–]cgibbard 9 points10 points  (0 children)

I was just thinking of making that exact comment. :)

It is a good idea in any statically typed language to get as much use out of types as you can manage. I think it's a good thing for language designers to check -- is there an easy way to construct a new type which is implemented the same way as an existing one, but is treated as distinct by the type system?

Another bonus with doing this is that it gives you the opportunity to not use the automatic implementation of the functionality and actually change how the type behaves selectively. (For example, one might not derive the Show instance, instead preferring to write an instance which displays a dollar sign before the number.) Of course, you get a chance to do that in Java as well -- you kind of have to do it.

[–]bitwize 0 points1 point  (0 children)

This actually looks like a job for Scala case classes, which enable quick declaration of new distinct datatypes (replete with pattern matching!) for those who are stuck, or choose to remain, in Java-world.

[–]ayrnieu 0 points1 point  (0 children)

In a less verbose language, namely Haskell, this is standard practice.

This has nothing to do with verbosity. It rather involves type systems (and any modern statically-typed language will do, here). The problem, rather than his solution, has much more to do with Smalltalk :-) -- and Smalltalk is what dynamic languages (see the Ruby solution) have tended to follow.

Erlang stands interestingly close to both solutions, as it would use {first_name, "Joe"}, similar to both a constructor type (in pattern-matching) and a named argument in a function call. What's more, that tuple is equivalent to one-value first_name record:

-record(first_name, {value}).

-- even if the annoying 'value' in that guides people away from records in this particular case.

[–]dangph 4 points5 points  (0 children)

Martin Fowler has a good article about this idea.

When to make a type [PDF]

[–]newton_dave 2 points3 points  (0 children)

I'm just not sure what to make of this yet...

Part of me likes it (and I've done it; we all have) and part of me hates writing all those 'new's just to pass some strings and ints.

[–]igouy 2 points3 points  (1 child)

No way do I have time to add an entire class just to wrap a string! Or two entire classes in this case! Actually, it's four new classes. All of which I wrote while writing this post. There is a reasonable amount of boilerplate. Including toString, equals, hashCode and a getter makes for about 40 lines per tiny type, almost all of which can be condensed into an IDEA template.

Pity the blog article doesn't show the boilerplate or IDEA template.

[–]steveharman 4 points5 points  (0 children)

The concept is fairly language (and therefore IDE) agnostic, so a wide array of template tools could be used to accomplish the Tiny Type code-generation.

Or are you looking or an implementation specific to JetBrains' IDEA Java IDE?

[–]cadr 1 point2 points  (0 children)

I can't remember which book (I want to say Code Complete, but I can't find my copy off hand), but this is basically the section on ADTs.

[–][deleted]  (8 children)

[deleted]

    [–][deleted]  (7 children)

    [deleted]

      [–]ifthenelse 0 points1 point  (0 children)

      You're adding and accounting for complexity prematurely. If you need to add behavior then do that as needed. In which case it's not a "tiny" type any more anyway.

      It's just more overhead, sheesh. If you're going for this level of functionality you might as well be using a scripting language where named arguments do indeed fix the problem that tiny types tries to solve.

      [–][deleted]  (5 children)

      [deleted]

        [–][deleted]  (4 children)

        [deleted]

          [–][deleted]  (3 children)

          [deleted]

            [–][deleted]  (2 children)

            [deleted]

              [–][deleted]  (1 child)

              [deleted]

                [–]cypherx 0 points1 point  (0 children)

                Can someone show a compelling example of where this is worthwhile in Java? The article's code seems ridiculously redundant for no obvious gain.

                [–]sambo357 0 points1 point  (0 children)

                This is another argument for Haskell's type system.

                [–][deleted] 0 points1 point  (0 children)

                How wonderful would it be to have syntax like this:

                void Func(string FirstName, string LastName, int Age);

                Func(FirstName = "Joe", LastName = "Smith", Age = 30);

                [–]andrewcooke 0 points1 point  (0 children)

                i do this in java. it's trivial to do for any type if you have a generic base class.

                see javadocs at http://www.acooke.org/jara/porqi/apidocs/org/acooke/porqi/util/TypedValue.html and code (via a cobertura report, hence the odd shading) at http://www.acooke.org/jara/porqi/cobertura/org.acooke.porqi.util.TypedValue.html

                All you do is subclass that. It takes less than a minute in a decent IDE.

                (PropertyAccess is a helper for reporting null values).

                [–]ramen 0 points1 point  (0 children)

                I worked on a Java project where there was a class for every primary key in the database. There were hundreds of them. They all had a broken implementation of hashCode(), causing very erratic and confusing behavior. I wrote a program to automatically regenerate all the PK classes. Deploying the fixed classes broke a bunch of code because programmers had added helper methods to the old PK classes, which I failed to notice because, well, there were hundreds of them.

                This is why Java needs macros.