Earlier quoted context omitted.
Do you validate them? I assume you do. Feels like a great time to cast them too
'Parse, Don't Validate'
Use Your Type System
291–300 of 357 posts
Re: Use Your Type System
#292Im on the opposite extreme here in that I believe typing obsession is the root of much of our problems as an industry. I think Rich Hickey was completely right, this is all information and we just need to get better at managing information like we are supposed to. The downside of this approach is that these systems are tremendously brittle as changing requirements make you comfort your original data model to fit the…
Uhuh, so my age and my weight are the same (integers), but just have different types. Okay.
Re: Use Your Type System
#293I was doing this and used it for a year in https://github.com/bbkane/warg/ , but ripped it out since Go auto-casts underlying types to derived types in function calls: Type userID int64 func Work(u userID) {...} Work(1) // Go accepts this I think I recalled that correctly. Since things like that were most of what I was doing I didn't feel the safety benefit in many places, but had to remember to cast the type in othe…
Re: Use Your Type System
#294The problem with this post is that the author is conflating two different things. Using a type system to capture the units of a measurement or metric is straightforwardly better than having them be implied. Stripping a numeric value and unit down to just a value involves an obvious loss of information. That situation is wholly different than just wrapping your UUID in some bespoke type which doesn't provide any extra…
The same argument gets brought up in favor of dynamic typing. The point of typing is that you don't need all those repetitive tests.
Moreover, the coding feedback loop gets shorter since there's no need to wait until the tests run to find out a string was passed in instead of an int (or UserID).
Re: Use Your Type System
#295Earlier quoted context omitted.
Why would it be difficult to monitor the slowness? Wouldn’t a million function calls to the from_F_to_K function be very noticeable when profiling? On your case about swapping between image representations: let’s say you’re doing a FFT to transform between real and reciprocal representations of an image - you probably have to do that transformation in order to do the the work you need doing on reciprocal space. There…
I have many functions written by many scientists in a unique software over many years, some expect a data format the others another, it's not always the same function that is called, but all the functions could have been written using a unique data format. However, they chose the data format when writing the functions based on the application at hand at that moment and the possible acceleration of their algorithms wi…
type ID {
AsString string
AsInt int
AsWhatever whatever
}
function new type ID:
return new ID {
AsString: calculateAsString()
AsInt: calculateAsInt()
AsWhatever: calculateAsWhatever()
}
This does assume every representation will always be used, but if that's not the case it's a matter of using some manner of a generic only-once executor, like Go's sync.Once.Re: Use Your Type System
#296Earlier quoted context omitted.
I have many functions written by many scientists in a unique software over many years, some expect a data format the others another, it's not always the same function that is called, but all the functions could have been written using a unique data format. However, they chose the data format when writing the functions based on the application at hand at that moment and the possible acceleration of their algorithms wi…
If I understood the problem correctly, you should try calculating each format of the data once and reusing it. Something like: type ID { AsString string AsInt int AsWhatever whatever } function new type ID: return new ID { AsString: calculateAsString() AsInt: calculateAsInt() AsWhatever: calculateAsWhatever() } This does assume every representation will always be used, but if that's not the case it's a matter of usin…
I agree that would be a good solution, despite that my data is huge, but it assumes the data doesn't change, or doesn't change that much.
Re: Use Your Type System
#297Hard not to agree with the general idea. But also hard to ignore all of the terrible experiences I've had with systems where everything was a unique type. In general, I think this largely falls when you have code that wants to just move bytes around intermixed with code that wants to do some fairly domain specific calculations. I don't have a better way of phrasing that, at the moment. :(
The article is written in Go, in which - iirc - it's fairly easy and cheap to convert a type alias back to its original type (e.g. an AccountID to an int). Using the right architecture, you could make it so your core domain type and logic uses the strictly typed aliases, and so that a library that doesn't care about domain specific stuff converts them to their higher (lower?) type and works with that. Clean architect…
Re: Use Your Type System
#298Earlier quoted context omitted.
you never got a TypeError before? Python already has runtime type checking
If you have a TypeError it's already too late. Decorating everything with beartype means I can catch things way in advance. It also forces me to specify types to all my functions which really helps LLM. See for example in wdoc, my advanced personal RAG library: https://github.com/thiswillbeyourgithub/wdoc/blob/main/wdoc/...
Re: Use Your Type System
#299Isn't this just the newtype pattern?
It is. To some it is more fun to reinvent the wheel than to study history
To the best of my knowledge, the earliest specific term for the concept is painted types (Simonyi, 1976)[0], but I believe this was a new term for a concept that was already known. Simonyi himself quotes (Hoare, 1970)[1]. Hoare doesn't provide a specific term like painted type for the type being defined, but he describes new types as being built from constintuent types, where a singular constituent type is known as the base type.
Simonyi uses the term underlying type rather than base type. Hoare eludes to painted types by what they contain - though he doesn't explicitly require that the new type has the same representation as it's base type - so they're not necessarily equivalent, though in practice they often are. Simonyi made this explicit, which is what we expect from newtype in Haskell - and specifically why we'd specifically use `newtype` instead of `data` with a single (base) constituent.
If you're aware of any other early references, please share them.
---
[0]:https://web.archive.org/web/20170313211616/http://www.parc.c...
> These examples show that the idea of types is independent of how the objects belonging to the type are represented. All scalar quantities appearing above - column numbers, indices and so forth, could be represented as integers, yet the set of operations defined for them, and therefore their types, are different. We shall denote the assignment of objects to types, independent of their representations, by the term painting. When an object is painted, it acquires a distinguishing mark (or color) without changing its underlying representation. A painted type is a class of values from an underlying type, collectively painted a unique color. Operations on the underlying type are available for use on painted types as the operations are actually performed on the underlying representation; however, some operations may not make sense within the semantics of the painted type or may not be needed. The purpose of painting a type is to symbolize the association of the values belonging to the type with a certain set of operations and the abstract objects represented by them.
[1]:https://www.cs.cornell.edu/courses/cs4860/2018fa/lectures/No...
> In most cases, a new type is defined in terms of previously defined constituent types; the values of such a new type are data structures, which can be built up from component values of the constituent types, and from which the component values can subsequently be extracted. These component values will belong to the constituent types in terms of which the structured type was defined. If there is only one constituent type, it is known as the base type.
Re: Use Your Type System
#300Earlier quoted context omitted.
The “Stop at first level of type implementation” is where I see codebases fail at this. The example of “I’ll wrap this int as a struct and call it a UUID” is a really good start and pretty much always start there, but inevitably someone will circumvent the safety. They’ll see a function that takes a UUID and they have an int; so they blindly wrap their int in UUID and move on. There’s nothing stopping that UUID from…
> This is where the concept of “Correct by construction” comes in. This is one of the basic features of object-oriented programming that a lot of people tend to overlook these days in their repetitive rants about how horrible OOP is. One of the key things OO gives you is constructors . You can't get an instance of a class without having gone through a constructor that the class itself defines. That gives you a way to…
In my book, that's the most important difference with C, Zig or Go-style languages, that consider that data structures are mostly descriptions of memory layout.