News for hackers. Stuff that matters.
Re:Names are not type safety by platinumrad on Sunday November 01, 2020 @10:19PM (#24964548)
You say that, on its own, a newtype is nothing more than a name and that names are not type safety, but then you give the example of using newtypes to prevent someone from adding a distance and a duration. I think it's a false distinction to say that the safety there is some kind of safety that isn't type safety.
Re:Names are not type safety by lexi-lambda on Sunday November 01, 2020 @10:28PM (#24964584)
Yes, on its own, a newtype is nothing more than a name. The safety comes from pairing a newtype with an encapsulation mechanism and a carefully-designed trust boundary.

Without an encapsulation mechanism, I do not consider using newtypes to wrap real numbers with units of measure sufficient to be called “type safety”; in my experience it still requires significant discipline to use properly (because the points of wrapping/unwrapping are usually fairly local and require delicate care).

Of course, this is a matter of both subjective definition and relative situation. One can theoretically imagine a codebase that conventionally uses units-of-measure wrappers so pervasively that the safety is genuine, since the places where values are wrapped/unwrapped are so well-defined that any misuse would stick out as wrong. However, I have never in my life seen such a codebase, so anecdotally I can only consider such measures more like the lines painted on a road to delineate lanes than a bona fide safety mechanism.

Re:Names are not type safety by Joker_vD on Monday November 02, 2020 @06:13AM (#24966781)
So basically, "if you don't use newtype to implement an abstract data type, you don't get any type safety because the on-spot wrapping/unwrapping is still possible".

On one hand, yes. On another, no. I am working right now on a Go codebase with lots of newtypes (well, the Go's equivalent), and they're generally casted to/from underlying primitive types basically in two places: when they're serialized into JSON, and where they're deserialized from JSON. And in several places in the middle of the code where you need an explicit cast, well, the cast is explicit. You actually have to consider it.

Mind you, in Go it's almost impossible to hide the newtype's constructor unless you jump through some rather unintuitive hoops. Is Go fundamentally type-unsafe? I don't think it is, although I sometimes wish some structs were impossible to zero-initialize. Then again, that's generally amended by unexporting the struct and exporting its interface instead.

Re:Names are not type safety by codygman on Monday November 02, 2020 @05:28PM (#24974237)
> Is Go fundamentally type-unsafe?

Interface{} and nil pointers point to yes.

Re:Names are not type safety by platinumrad on Monday November 02, 2020 @07:46PM (#24975166)
Neither of those is incompatible with Cardelli's definition of type safety. `interface{}` is not `void *`. Null pointer errors are not untrapped.
Re:Names are not type safety by lmm on Tuesday November 03, 2020 @07:33PM (#24985622)
Cardelli's definitions are extremely odd; if you take them literally then Python is type safe but Java is not.

In everyday language a downcast, even a checked one, is not a type-safe operation, and so to the extent that Go's limited type system makes it impractical to write programs without downcasts I'd say that Go is fundamentally type-unsafe.

Re:Names are not type safety by Joker_vD on Thursday November 05, 2020 @09:44AM (#24998655)
Well, it's a matter of taste, I guess. In my opinion any downcast that reliably distinguishes between valid and invalid values is type-safe. The behaviour of

    defer func() {
        if e := recover(); e != nil {
            fmt.Printf("not a string %v\n", e)
        }
    }()
    v := interface{}(5)
    u := v.(string)
    fmt.Println(u)
is well-defined: it will print "not a string", always.
Re:Names are not type safety by lmm on Friday November 06, 2020 @02:37AM (#25005800)
By that logic there's no such thing as a non-type-safe language, because all programs have behaviour.

Normally one would say a checked downcast like that is not type-safe, because you can't reason locally about the type behaviour of the downcast based on knowing the type of v. You would have to know the value of v, which is a Turing-complete problem in the general case.