Hacker News new | ask | show | jobs
by thesuperbigfrog 2282 days ago
Ada does a great job in this regard. Using some examples in the article:

>> For example, say that you want to represent the number of books ordered. Instead of using an integer for this, define a class called Quantity. It contains an integer, but also ensures that the value is always between 1 and 240

The Ada code to implement this is:

type Quantity is new Integer range 1 .. 240;

>> instead of just using a string, define a class called UserName. It contains a string holding the user name, but also enforces all the domain rules for a valid user name. This can include minimum and maximum lengths, allowed characters etc.

The Ada code to implement this is:

with Ada.Strings.Bounded; package UserName is new Ada.Strings.Bounded.Generic_Bounded_Length (Max => UserName_Max_Length);

Dynamic predicates or even a string subtype could be used to further refine the UserName definition depending on exactly what restrictions are needed.

While it's not perfect, Ada does make it pretty easy to specify constraints on data types and will complain loudly when the constraints are violated.

2 comments

As an addendum, some of those features are also possible on Pascal/Modula variants, although not as expressive as Ada.
Oh my god. I wish C# had this.
Ada is pretty much still the only language that has this.
> Ada is pretty much still the only language that has this.

Common Lisp does too:

    (deftype quantity () '(integer 0 240))
    (defun foo (x)
      (declare (type quantity x))
      (1+ x))
    (foo 1) → 2
    (foo -1) → ERROR
    (defun valid-username-p (string)
      (and (< 8 (length string) 24)
           (every (lambda (char)
      (find char "abcdefghijklmnopqrstuvwxyz0123456789-_=./" :test #'char=))
    string)))
    (typep "foo" 'username) → NIL
    (typep "foobarbaz" 'username) → T
    (typep "foobar-baz" 'username) → T
    (typep "foobar-baz " 'username) → NIL
Common Lisp is pretty awesome.
Well, except for the fact that it's Common Lisp. ;)
Pascal:

    type
        Quantity = 1 .. 240;
        Colors = (Red, Green, Blue);
        Pixels = array [1..1024, 1..768, Colors] of Byte;
Just a small example how its type system already so much better than C, although not as good as Ada.
It's really not helpful to put examples here that are basically Animal IS Dog level of argumentation. Making toy types like that may help to convince some beginners, but really these features are just unflexible. They work if you're not doing any arithmetic on these values, in which case the type safety is not really needed in the first place. Otherwise (if you're doing arithmetic) they're very much a chore, making code more verbose and in many cases raising complexity to the point where you're starting to introduce enterprisey uber-complicated systems that can easily lead to many thousand lines of boilerplate for solutions that are looking for an actual problem.

And overall, Pascal's type system is NOT so much better. Not strictly better at all, if at all any better. It's a chore to do the simplest things, starting from the mess that is the various types of strings, to a confusing memory management story, continuing with extremely verbose type declaration syntax (which requires to add many additional names), to the mess that is 0-based vs 1-based indexing, and let me not start with the messy object systems that were put on top in Delphi.

If you ask me it's definitely WORSE over all, although for example Delphi has nice aspects to it, especially in the IDE.

Oh yeah, and if Ada was ever adopted by a significant adoption of programmers, then they probably have committed suicide in the meantime.

Yeah not every developer is able to cope with programming languages that promote engineering best practices.

By the way, better check your github issues.

Check your github issue answers! Thank you for checking the project finally, as promised :-) https://github.com/jstimpfle/language/issues/2

I don't know how much effort you put into finding this, but the result feels almost like a certificate of quality to me and confirmed my opinion that this style of coding is pretty f*ing safe in practice. And that while I spent definitely less than 1% time on debugging memory issues (running valgrind twice, according to my git history, compared to working on this project during 7 months, initially 2.5 months full time, leading to an estimate of about 500h of development time).