3 ms·
static typing doesn't appear to be an effective tool for encoding intent Static typing is about as effective at encoding intent as intention revealing names. T
by stcredzero 8y ago
static typing doesn't appear to be an effective tool for encoding intent
Static typing is about as effective at encoding intent as intention revealing names. That is to say, if you are diligent and clever in how you structure and name things, a system can be very intention revealing.
HN user jerf has a method of revealing intent through types in golang, which he calls something like microtyping. Basically, everything has its own type, based on its domain semantics. So if you're using a float64 to store time deltas, you don't just use the float64. Instead, you base a TimeDelta type on float64.
type TimeDelta float64
Then golang allows you to attach methods to that type, which can then provide more opportunities for intention revealing. Also, this prevents a programmer from mistakenly using a float64 representing width and shoving it into a time calculation. Is this as ironclad as Eiffel Design by Contract or Haskell typing? No. However, I've been using it myself, and I can affirm that yes, the compiler will warn you about some semantic errors if you do it this way.
The big problem with the Intention Revealing Names pattern, is that there is no enforcement and that it is subjective. For this reason, it's likely to fall apart in a large enough project that lives long enough.
- vram22 8y ago>HN user jerf has a method of revealing intent through types in golang, which he calls something like microtyping. Basically, everything has its own type, based on its domain semantics. So if you're using a float64 to store time deltas, you don't just use the float64. Instead, you base a TimeDelta type on float64. >type TimeDelta float64 >Then golang allows you to attach methods to that type, which can then provide more opportunities for intention revealing. Also, this prevents a programmer from mistakenly using a float64 representing width and shoving it into a time calculation. IIRC, this technique, or something similar, is shown in The Go Programming Language book. F# also allows you to do similar stuff, I think.
- nikofeyn 8y agof# definitely allows this with single case discriminated unions. and in f#, you can add members to any type, which includes discriminated unions, records, classes, etc. in fact, you can add member functions somewhere else after the definition of the type. so you can define the type, write functional helper functions against that type and then later add member functions to the type that are defined in terms of the helper functions.
- vram22 8y agoDidn't know that stuff, cool, thanks. (In early stage of learning F#). That feature you mention sounds a bit like Ruby's open classes, where, in file B (or even in file A), you can add a method to a class C (where C is defined in file A), outside of the definition of C. I was just reading somewhere else recently that some other language also has this feature, maybe it was about Lisp, in the recent thread about it.
- infinite8s 8y agoThis is what strong typing is about - not having to specify the exact arbitrary machine types for a particular implementation, but using compiler checked types to enforce invariants of a design.
- deleted 8y ago[deleted]
- yogthos 8y agoThe kinds of errors where you have a type mismatch are wholly uninteresting in my experience, and get caught very early on in the development process. What I really care about is semantic correctness. For example, consider a sort function. The types can tell me that I passed in a collection of a particular type and I got a collection of the same type back. However, what I really want to know is that the collection contains the same elements, and that they’re in order. This is difficult to express using most type systems out there. Even when the type system is powerful enough to encode such semantics, it's both difficult to figure out how to express and understand the resulting specification.
- wtetzner 8y agoWell, you can create a SortedList type that is only returned from sort functions, so you can write functions that only accept sorted lists.
- yogthos 8y agoIt's not a question of whether you can do it in principle or not. My point was that I don't think it's an effective approach for creating such specifications compared to the alternatives such as runtime contracts.
- wtetzner 8y agoWhy is that? In fact, I would argue you want both. You want to use a contract to check the incoming data, but once it's been checked, you'd want to wrap it in a type that guarantees the property is set. Otherwise, you have to iterate over a potentially very large set of data to check if it's sorted every time you want to use a function that has that contract.
- smadge 8y agoI was curious about your example of expressing and validating that a sort function returns a sorted list using the type system. I found this paper [0] by McBride, McKinna, and Altenkirch about using dependent types in the language Epigram to do exactly that. I have only scanned it, and it remains to be seen if it truly is too "difficult to figure out how to express or understand the resulting specification." Hopefully with more research it will only become easier! [0] http://www.cs.nott.ac.uk/~psztxa/publ/ydtm.pdf http://www.cs.nott.ac.uk/~psztxa/publ/ydtm.pdf