[untitled]
1 pointsby bedobi0 comments
fun doSomething(user: User) { if (user is Student) { do this } else { do that } }
which is insane data class User (id: Int, name: String, email: String)
and for those Users who are students, create a Student that points to the user data class Student (userId: Id, blabla student specific attributes)
and vice versa for the Employees data class Employee (userId: Id, blabla employee specific attributes)
then, your types can simply and strongly prevent Students from being sent into functions that are supposed to operate on Employees etc etc (but for those cases where you really want functions that operate on Users, just send in each of their Users! nothing's preventing you from that flexibility if that's what you want) The current state of software safety discussion resembles the state of medical safety discussion 2, 3 decades ago (yeah, software is really really behind time).
Back then, too, the thoughts on medical safety also were divided into 2 schools: the professionalism and the process oriented. The former school argues more or less what Uncle Bob argues: blame the damned and * who made the mistakes; be more careful, damn it.
But of course, that stupidity fell out of favor. After all, when mistakes kill, people are serious about it. After a while, serious people realize that blaming and clamoring for care backfires big time. That's when they applied, you know, science and statistic to safety.
So, tools are upgraded: better color coded medicine boxes, for example, or checklists in surgery. But it's more. They figured out what trainings and processes provide high impacts and do them rigorously. Nurses are taught (I am not kidding you) how to question doctors when weird things happen; identity verification (ever notice why nurses ask your birthday like a thousand times a day?) got extremely serious; etc.
My take: give it a few more years, and software, too, probably will follow the same path. We needs more data, though. Either<Error, Foo>
then, in the HTTP layer, your endpoint code just looks like return fooService
.getFoo(
fooId
) //Either<Error, Foo>
.fold({ //left (error) case
when (it) {
is GetFooErrors.NotAuthenticated -> { Response.status(401).build() }
is GetFooErrors.InalidFooId -> { Response.status(400).build() }
is GetFooErrors.Other -> { Response.status(500).build() }
}
}, { //right case
Response.ok(it)
})
the benefits of this are hard to overstate.
The valuable part of Software Engineering isn't PARSING a solution into code and back again, taking into account all the idiosyncrasies and edge casey bugs of any given language chosen for the implementation. Of course that is a discrete and impressive skill, but it's no longer terribly valuable.
The valuable part of Software Engineering is "given this problem, what's an elegant, efficient, testable, scalable, maintainable, observable solution?".
Most of CS is already a solved problem, so even that is mostly a matter of assembling those solved-problem pieces together and choosing the flavor of how it's expressed. (for me, it's pure functions, for others, it might be OOP)
AIs are pretty good at that too, so it seems to me like the Software Engineers role is now to cultivate taste (what, in a perfect world, systems SHOULD look like) and balance it with pragmatism. (what does the system/business/time/resource constraints look like TODAY)