[HN Gopher] Types are a basic tool of software design (2018)
___________________________________________________________________
Types are a basic tool of software design (2018)
Author : gus_leonel
Score : 87 points
Date : 2024-12-31 10:00 UTC (3 days ago)
(HTM) web link (www.tedinski.com)
(TXT) w3m dump (www.tedinski.com)
| karmakaze wrote:
| (2018) btw.
|
| _I saw this much earlier in the day and dismissed it. I just now
| read more of it. I was first off-put by the title, but then it
| goes on to say:_
|
| > [...] design is about everything that's leftover after we
| remove all the function bodies. It worth taking a moment to think
| about what that looks like. Here are some of my own immediate
| thoughts: 1. Everything that's left is just types. [...]
|
| _Which reaffirms my suspicion that "Types!" are this writer's
| hammer for all of programming's nails, or possibly a click-bait
| writing device. There's probably a better article in here trying
| to get out as the end notes mention. [Maybe read them first.]_
|
| _But I couldn 't even agree with the first one:_
|
| > I meant for the main point of today's essay to be universal:
| hence my emphasis that types are central to design even in
| dynamically typed languages. [...]
|
| _I can 't say I've ever considered types/signatures when
| sketching out a design. That comes much later in prototyping and
| actual implementation--I suppose if I used Haskell that might be
| different._
| nightski wrote:
| I am skeptical. You don't even know if a relevant piece of data
| is say a number or text before you start writing out code? You
| don't think at all about how you will group data together? You
| don't think about the operations that will be performed on that
| data and how they will transform it?
|
| What do you think about when it comes to design?
| acchow wrote:
| Location of data, policies, cross-cutting concerns,
| latency/performance requirements, etc.
|
| "Much later" is probably an exaggeration. You get to types
| "soon after" the initial design.
| qayxc wrote:
| Types are a useful design tool to explore the problem
| domain first, while the rest are details that emerge from
| that. Sure, if one starts with architecture, you're right.
| The software _architect_ needs to consider these first. The
| programmer on the other hand ideally expects those as
| inputs.
|
| When tasked with wearing on multiple hats (architect,
| programmer, user), I agree with your point. From a
| programmer's point of view, however, (abstract) types are
| IMHO indeed a much more useful tool as they cover many of
| the other concerns (policies, performance, etc.), too.
| acchow wrote:
| In my experience, a software engineer wears all the hats
| nowadays. Even crossing into product design and user
| experience.
| nightski wrote:
| It's interesting that you think about those things without
| even understanding how you are going to solve the user's
| problem first. Aka functional requirements.
| packetlost wrote:
| I find this really hard to believe to be honest. Even dealing
| with things as rudimentary as a file handle are really thinking
| about a type of some abstract thing, even if you don't really
| conceptualize it as such. Types are _the_ way to put a name on
| that abstract classification, so in dynamically typed languages
| even the name of a variable or function assigns a
| classification to the data it holds /returns, even if it's only
| really enforced by the programmer.
|
| There are basically no untyped programming languages for a
| reason, types are a fundamental concretization.
|
| In fact, I would argue there is no such thing as untyped
| programming, there's just different degrees to which the
| programmer is the enforcer of correctness.
| oh_my_goodness wrote:
| Sure, I think the author overstates his/her case and "finds the
| One Ring". But it's not a dumb article. "Design is everything
| that's leftover after we remove all the function bodies" seems
| like a useful perspective.
| slowmovintarget wrote:
| Except it's not. The word "design" originated from the notion
| of marking out or pointing out. To do it well is to take the
| problem apart into small challenges that can be solved, with
| a plan on how to make the pieces hang together again.
|
| Design often includes algorithms, which don't devolve merely
| to types. So this statement only makes tangential sense if
| all you're ever building is CRUD applications.
| boscillator wrote:
| I pretty much always start with types/signatures when sketching
| out a design. I guess if there is a complicated algorithm, I
| might start with pseudo code for it, but even then, I probably
| want to start with what it's inputs are and what it's outputs
| are.
| oh_my_goodness wrote:
| I'm glad we finally found the 1 basic tool of software design. We
| can for sure stop thinking and arguing about that.
| seanwilson wrote:
| I love this before/after example of TypeScript being removed from
| a library as a clear illustration that only occasional simple
| type annotations are needed:
| https://github.com/hotwired/turbo/pull/971/files
|
| Looks like so much useful documentation for understanding the
| code, assistance for refactoring, and static checking (which are
| like always running, fast and exhaustive unit tests for free) for
| a modest amount of type annotations that each person on the team
| would need to recreate in their heads anyway. Static type
| checking is so useful for catching runtime errors to do with
| optional values and index/key not found error too, that always
| create a load of edge cases.
|
| Editing JavaScript with no types is scary, especially when you
| didn't write it. You're mostly guessing what the types must be
| and hoping your running code exercises enough edge cases to catch
| any problems. "You should write more tests" as an alternative
| rings hollow for me because (for the things they will check for
| you) types are more concise, exhaustively check all values, are
| ran continuously, are fast, aid with automatic refactoring,
| document the code in the same file its in, and will locate exact
| snippets that are causing errors. More often than not, test
| mostly check happy paths, aren't even close to as exhaustive, and
| nobody is writing tests that check every combination of function
| parameters being null vs non-null, string vs number etc. (which
| would be a huge amount of noise in your test suite that would
| slow down refactoring too). Types are a compliment to tests as
| well, not an alternative.
|
| I can't relate to arguments about types getting in the way (as
| long as you avoid trying to get too clever like with complex
| generics and TypeScript conditional types). Usually when this
| happens, it's because it's hard to reason the runtime edge cases
| in your own head and there's probably a simpler way to write it.
| I'd love a good non-niche example to the contrary. Worst case in
| TypeScript, you can use `any` as an escape hatch anyway so as
| long as you can add types to most of your program it's not a
| strong reason against for me.
| benatkin wrote:
| That PR is great. Not only do they get rid of TypeScript, they
| get rid of prettier and some gratuitous trailing commas.
| https://github.com/hotwired/turbo/pull/971/files#diff-865b8f...
|
| I'm not joking. I prefer the _after_.
|
| Edit: thanks. Yes, commas, not comments.
| lofenfew wrote:
| s/ent/a
| vallode wrote:
| I could not disagree more, but I am obviously open to it
| being a personal preference. I've spent months updating
| JavaScript codebases that are between 3 and 5 years old, most
| of them written with vanilla JavaScript. A _few_ of them were
| written with TypeScript at least partially and those files
| were the least mentally taxing to upgrade.
|
| Some of the codebases had tests, a good chunk of which could
| (and were) eliminated simply by using TSC as part of the
| build process. I think allowing the compiler and tooling like
| prettier to make choices for you leaves more space for you to
| think about the problem, not the myriad of problems _around_
| it.
| Shacklz wrote:
| Funny, I have exactly the opposite feelings.
|
| I've worked on dynamically typed code-bases in the past, and
| also on code-bases without formatters like prettier... and
| I'm not going back there.
|
| So many odd bugs can be avoided simply by taking a little bit
| of time and declaring some types. It doesn't have to be a
| super fancy type-system (I actually prefer if it isn't), but
| I really want to know whether something is expected to be a
| string or a number, or what properties an object can be
| expected to have, or what values a literal can accept, and so
| on. It's just so frustratingly time-consuming to figure out
| in hindsight. And all for some person's odd perception of
| simplicity.
|
| Same for formatters - all the squabbling over some personal
| preferences on how code should be formatted. Hell no. Let's
| install some opinionated formatter and let it do its job, I
| want to tackle more interesting problems than yet another
| narrow-minded discussion about necessity of semicolons,
| placement of whitespace or line-length.
|
| I'm at a point where I straight-up refuse to work with people
| who prefer to work that way; or at least require them to be a
| few departments away from me. They can be programming gods;
| if they can't be arsed to type their code so I can
| immediately grok it, they can program elsewhere.
| n144q wrote:
| Same.
|
| I sometimes write TypeScript for 2 hours straight without
| actually running the code or any unit test, and it would
| _just work_ -- the return value is exactly what you want. I
| don 't think I can do that for JavaScript for more than 15
| minutes even though they are the "same language".
| PittleyDunkin wrote:
| What's the benefit of removing the explicit typing? It
| strikes me as hamstringing readability of the code. This just
| feels like giving up and calling the status quo "beautiful"
| or something.
| bnetd wrote:
| To reinvent it.
| benatkin wrote:
| People tried to argue that in the PR, suggesting to
| change variable names.
|
| This one: https://github.com/hotwired/turbo/pull/971/file
| s#r1317386731
|
| > function buildFormData(formElement: HTMLFormElement,
| submitter?: HTMLElement): FormData {
|
| > It might be useful to know that submitter is optional
| argument here.
|
| > How would one express that? The variable now needs to
| be renamed?
|
| And two lines later:
|
| > const name = submitter?.getAttribute("name")
|
| It's already easy to see that submitter is optional.
| lelandbatey wrote:
| Only easy to see that it's optional if you read the
| source code vs. looking at the auto definition in your
| IDE/in autogenerated documentation.
| superb_dev wrote:
| Even with the find/replace errors that seemingly got merged?
| This PR feels like it was so rushed
| madeofpalk wrote:
| I can't imagine caring that much about trailing commas. The
| point of a tool like prettier is to not sweat such irrelevant
| details.
| slooonz wrote:
| Trailing commas actually have an important role.
|
| Let's say you have some code : const foo =
| { x: 1, y: 2, };
|
| and you want to add a field : const foo = {
| x: 1, y: 2, z: 3, };
|
| Without trailing commas, the diff is - y: 2
| + y: 2, + z: 3
|
| With trailing commas : + z: 3,
|
| The second diff is actually much clearer at what's
| happening.
|
| This is why it irritates me when people forget the trailing
| comma. It's not a problem in the moment. But I know it will
| be a small but avoidable cognitive burden on the _next_ PR
| (wait, why did "y" changed ? Oh, right, it didn't).
| fire_lake wrote:
| Maybe diff should change to suit programs, rather than
| programs change to suit diff.
| benatkin wrote:
| Indeed. That's why prettier ain't pretty.
| slooonz wrote:
| You want diff to know the syntax and semantics of every
| programming language out there ?
| benatkin wrote:
| It would be like a syntax highlighter. It's doable.
| slooonz wrote:
| But diff does not exists in a vacuum. It would need to be
| integrated to IDEs, editor, merge tools, PR tools. You
| now have to have `patch` understand and depend on the
| details of the syntax of your language. In a way that may
| break between different versions of diff and patch. Not
| even starting with variants of a language, different
| interpretations of how to handle the preprocessor/macros
| system, different editions of the same language.
|
| All that, just to not have to add a trailing comma ?
| benatkin wrote:
| Most things like patch would still use line diff. I think
| I would want this semantic diff in the merge request
| review and the logs. It could have definitions
| distributed with the syntax highlighters in language
| plugins in an editor/IDE, git CLI, and git forge.
| knubie wrote:
| This is possible already with tools like difftastic.
|
| https://github.com/Wilfred/difftastic
| DarkPlayer wrote:
| Difftastic would not solve the issue described by
| madeofpalk because it still highlights the added comma.
| You need a diff tool that can distinguish between
| optional and required syntax. So far I am not aware of
| any tool that supports this, except the one I am working
| on (SemanticDiff).
| madeofpalk wrote:
| Sure, I can get behind that. That's why we just automate
| these trivial things away.
| Jarwain wrote:
| I also like it because I can reorder items in an array
| without having to also add/remove a comma!
| motorest wrote:
| > I'm not joking. I prefer the after.
|
| Everyone likes the simplicity that comes with removing
| guardrails, but when easily preventable problems happen
| that's glanced over as an unavoidable fact of life.
| knubie wrote:
| > but when easily preventable problems happen
|
| _easily preventable_ is doing a lot of work here. This is
| assuming the types are already written and never need to be
| maintained. How often does the type checker catch a problem
| with the code vs the type definitions themselves?
| seanwilson wrote:
| > How often does the type checker catch a problem with
| the code vs the type definitions themselves?
|
| All the time? I've worked on code bases with multiple
| people without types, and whenever there's a place that
| can produce e.g. "string or null" or when a key might not
| be found in a collection, it produces edge cases
| everywhere that don't get noticed outside of the happy
| path, including after the code has been merged. You're
| forced to simulate in your head all the code paths, and
| remember which values might be optional which isn't
| scalable.
|
| Even typos like `object.detail.name` vs
| `object.details.name` cause runtime errors, or calling a
| function without the right number of arguments.
|
| I don't understand how someone can dislike writing type
| annotations so much that they're happy to have their time
| wasted on some of the most trivial bugs you can think of
| like this when automated assistance is right there. It's
| like not wanting to use a spellchecker when writing an
| article, or opting out of syntax checking code before
| it's ran to me.
|
| I get that problems with type definitions can be
| frustrating but it's better than runtime errors, and
| often indicates actual bugs, potential future bugs, or
| weird code. I'd love an example here. 90% of type
| annotation stuff I work with is mundane and simple (e.g.
| strings, numbers, arrays, something optional, object with
| basic fields) and is well worth the minimal effort. The
| more complex stuff usually gives you protection from
| tricky bugs so is worth the effort too.
| plagiarist wrote:
| > This one is interesting. I would have no idea what a
| "submitter's" purpose is here with or without Typescript.
|
| > I am excited to see how this code base changes without
| Typescript. The "types" or what things are will have to be
| communicated in some way. This may lead to very readable code.
|
| This is funny to me. "If we don't have the compiler checking
| types the developers will perfectly compensate with
| documentation, an improvement." Maybe remove the unit tests as
| well, then the developers will write accurate code.
| marcosdumay wrote:
| It's using that expendable developer time to free some
| precious extra developer-machine-CPU time.
|
| Who wouldn't want to spend some weeks or hard labor so their
| computers can work for a few less seconds? Let's keep what's
| really important in mind!
| hyperhello wrote:
| Grammar is the basic tool of writing. Atoms are the basic tool of
| physics. Etc.
|
| What I think this post is reaching for is not types, and it's
| beyond even abstract data structures. It's really templates,
| which is a general concept that gets used in every design
| scenario. Numbers are templates, integers are templates, bits are
| templates. We can describe how the idea works to each other and
| partly to the computer but it's up to the programmer to animate
| them.
|
| Once you understand the concept you see it everywhere. Super
| Mario is full of templates: you jump on an enemy's head, or
| sometimes it doesn't work but gives you a clue to do something
| else. Templates are nodes of understanding.
| bromuro wrote:
| I've lost you at the template part: do you mean _models_?
| xvinci wrote:
| > One of Haskell's most basic innovations (well, I'd guess it
| probably wasn't first, but compared to other relatively
| mainstream languages) was the ability to write the type of a
| function separately from writing the function body.
|
| Anyone familiar with the initial versions of C / C++? Both
| languages have offerd the ability to define your function
| signatures in header files for as long as I have known them, so
| if you wished to separate from the actual function body you
| should have been able to do that.
|
| But then Haskell can hardly have been the first mainstream? But
| maybe someone with more ancient knowledge could share some
| insights - thx.
| PittleyDunkin wrote:
| I wouldn't characterize a forward declaration of a function as
| a distinct definition of its types--any types in the forward
| declaration must match those in the implementation; there's no
| way to implicitly refer to the types used in the forward
| declaration to ensure a single place of typing.
| cess11 wrote:
| Arguably COBOL has it with its data division, as does Ada.
| codr7 wrote:
| Common Lisp supports something along those lines, mostly for
| optimization purposes.
| bionhoward wrote:
| Python does have something like interfaces and it's called
| Protocols
| https://docs.python.org/3/library/typing.html#typing.Protoco...
|
| Other classes can count as implementors of protocols without
| needing to subclass them, and static type hints will notify you
| if you make a function which accepts a protocol as an argument
| and pass something which doesn't implement it
| cess11 wrote:
| Could generalise it to 'data is the basic tool of software
| design', then the article would have to muddle shape, structure
| and type into a single type concept.
| algorithmsRcool wrote:
| I go a little back and forth on this with my experience in F#,
| which relies heavily on inferred types. You can write _a lot_ of
| F# before you need to add type annotations, but eventually,
| things become a spiderweb. The key issue is when you make a
| 'small' change to some method/value, the changes ripple through
| the program creating confusing errors sometimes where the
| compiler is trying to knit things together.
|
| After a while, I found myself adding back types in a decent
| number of places to "anchor" the type inference, indicating that
| a certain type/signature is fixed and a change should be
| carefully considered.
|
| I still don't know how folks deal with these kinds of changes in
| weakly typed languages without always allowing bugs to pour into
| their code over time. But I do love the "move fast" and low
| boiler-plate aspects of "typeless" coding.
| scalaisneat wrote:
| I agree with this sentiment but view it inherently as a feature
| of languages like f# and Haskell - That small ripple at compile
| times makes trusting refractors easier. After having
| experienced this, languages like python become really
| challenging to grok without heavy unit testing.
| kibwen wrote:
| There's also a middle ground which is to support function-
| local type inference, but not inter-function type inference,
| which guarantees that such an "anchor" is never all that far
| away (especially never in another file). This is the approach
| Rust uses.
| MoreMoore wrote:
| I think what a lot of people miss is that this ripple effect
| always exists. Whether you have strong types or weak types,
| it's hard and often impossible to avoid.
|
| All strong types do is make it explicit at compile time (and
| with static analysis), instead of leaving it to be discovered
| in tests or at runtime.
|
| This is why I'll use Python for small one-off scripts but
| anything that will be in regular use I prefer to do in Java.
| Even though I have many more years of experience with Python.
| jonathanlydall wrote:
| As someone who works in C# and TypeScript, I suspect that
| people who work in weakly typed languages either:
|
| - Don't have big projects.
|
| - Have lots of unit tests to cover some of what a C# or Java
| compiler would have caught through static analysis.
|
| - Don't even consider doing certain kinds of refactoring
| (which would be trivial on a strongly typed language) because
| they have no way of knowing what will break.
| leptons wrote:
| 4th option, they are just better than you are at managing
| dynamism.
| jonathanlydall wrote:
| Even ignoring for a moment that I consider being highly
| practiced at dynamism a largely pointless skill while
| strongly typed languages exist, sooner or later a code
| base which is always growing will reach a certain size
| where even the very best person in the world at dynamism
| will have to resort to unit tests to cover what a
| compiler can do for free, or just accept that certain
| refactoring or changes to the code base are unreasonably
| expensive to do with any reasonable level of confidence.
| leptons wrote:
| I'm the guy with a huge javascript codebase, written
| before typescript existed, and I have none of the
| problems you describe. Huge refactors are also not a
| necessity in every codebase, if the code was written well
| to begin with. And so far using typescript in other
| projects has not produced the supposed benefits a lot of
| people say are inherent with typescript. There is no
| magic happening that saves me from writing bad code,
| because I wasn't writing bad code before typescript.
| Refactoring isn't all that difficult either, even without
| tests. But I guess _YMMV_.
| thfuran wrote:
| Good code becomes bad when the requirements change
| sufficiently in ways the original design didn't
| anticipate.
| leptons wrote:
| Great, but that doesn't describe every Javascript project
| or use of Javascript. If you're describing big changes,
| chances are a refactor isn't what's needed, a rewrite is.
| And even when requirements change, it doesn't mean
| Javascript can't be refactored. It depends on the skill
| of the team. If you want to hire idiots then you're going
| to need more than strong types to get anything shipped. I
| doubt types would really help that much in some places
| because programmers love to invent their own footguns.
| samatman wrote:
| Is it really too much to ask to use the correct terms here,
| static and dynamic typing?
|
| Strong and weak are sort of coherent as a spectrum, but they
| aren't a typology, and they do not in any sense or in any
| case reduce to static vs. dynamic types. Conflating them is
| not useful: I can make a good case that Julia's type system
| is stronger than C's, but Julia is dynamically typed and C is
| statically typed.
|
| There's no reason to keep doing this. It's a malapropism, we
| could just.. not say that. Especially in a thread which is
| specifically about types.
| kybernetikos wrote:
| Having worked on a large js codebase back before typescript or
| flow or the closure compiler existed, I found that the process
| was not very different to any code - you check your
| preconditions on entry to code that will be called from
| elsewhere, it's just that those preconditions in a dynamically
| typed language may include the types of your arguments. If you
| do that, then type errors typically cause your code to fail
| fast, often on first load, in easy to understand ways. Overhead
| is just a couple of extra easy to understand lines at the top
| of about half your functions (probably less boilerplate than
| go's error handling forces on you).
|
| Given the fantastic iteration speed that the Web platform had
| (and still does to some extent) I didn't really miss a compiler
| for catching errors. The main improvement is that IDEs find it
| easier to support big refactoring.
|
| I also worked on a mid sized scala codebase a little later on.
| Scala is probably better now than it was then, but despite
| (perhaps because of?) the cleverer type system, everything was
| so slow that it actually took longer for many bugs to be
| highlighted by the compiler than they would have been found by
| hitting f5 in a browser window with a good js codebase. That
| was when I realised that as a developer I care a lot about when
| an error is highlighted in wall clock time and not at all about
| which compiler phase it was discovered in.
| titanomachy wrote:
| I think Scala has a good compromise here, where all function
| signatures require explicit types and (almost) everything else
| can be inferred. Maybe F# does the same? I find that this is
| enough "anchoring" to allow for sensible error messages most of
| the time, although occasionally I'll sprinkle in more
| annotations if the inferred types would be particularly
| confusing to readers (usually because they're too general).
| neonsunset wrote:
| > You can write a lot of F# before you need to add type
| annotations, but eventually, things become a spiderweb. The key
| issue is when you make a 'small' change to some method/value,
| the changes ripple through the program creating confusing
| errors sometimes where the compiler is trying to knit things
| together.
|
| I found working with type inference being its own skill. If you
| know how to place type annotations well, the ripple effect only
| affects one or two callsites and then the type inference just
| continues to infer what you meant in the subsequent code.
| Though we may be approaching the structuring of the code
| differently so YMMV. But I haven't had issues even with
| complicated member constraints which replicate dependent
| typing.
| taeric wrote:
| This is stretching the definition of "tool." I would go far in
| agreeing that types are fundamental to the vocabulary of software
| design. But calling them a basic tool feels off. Is akin to
| saying rooms or units are a basic tool of building design. I can
| see arguments for it, but tools typically refer to the various
| things that actively do something. Hammers and such. Maybe a
| level bar?
| motorest wrote:
| > This is stretching the definition of "tool." I would go far
| in agreeing that types are fundamental to the vocabulary of
| software design. But calling them a basic tool feels off.
|
| Sometimes I wonder if this type of article is just a rehash of
| object-oriented programming articles from the 90s where the
| keyword "class" is search-replace'd by "type".
| Waterluvian wrote:
| I'm not sure if this is obvious to the average developer and I'm
| late to the show, but a few years back things clicked for me when
| I grokked that _types exist no matter how you feel about them._
|
| You still have to reason about the types no matter what. But
| writing it down empowers you to offload a lot of mental load to
| the computer, asking it to check your work, give you feedback as
| you go. It also communicates intent to other humans who read it.
|
| One reason I like TypeScript is that there remains a, "just trust
| me" escape hatch when I'm testing/hacking something and don't
| want to "show my work" by writing out some complex type. (Funny
| how "show your work" is something math teachers have to fight
| many students to do. This feels like the same thing). But that
| complex type always existed. You're just saying "trust me on
| this." Writing it down doesn't conjure the type into existence.
|
| Rust also clicked for me when I understood that it's really just
| _more_ of the same thing: memory management, lifetimes, etc.
| exist no matter what. But it offers a way to show your work,
| formalizing intent, so that the checker /compiler can worry about
| the boring problems for you.
|
| In this sense, the issue is really about making decisions on just
| how much "trust me on this" is appropriate.
| fellowniusmonk wrote:
| Mereological Nihilism demonstrates that most types are an
| illusion.
|
| Space, Time, Minds. Those exist. Probably :)
| boscillator wrote:
| A lot of people are complaining that this seems too "obvious" in
| one way or another, but I think it can be useful to write down
| and be explicit about such an important underlying fact of
| programming. Completely understanding the types in your program
| forces you to think carefully about the domain.
| motorest wrote:
| > Completely understanding the types in your program forces you
| to think carefully about the domain.
|
| Isn't it the other way around? Types derived from analysing the
| problem domain? That's the basic premise of a bunch of software
| design techniques.
| leptons wrote:
| I enjoy coding in assembly language, where types are not really
| a thing. Yeah, it really forces you to think carefully about
| the domain. I'm not talking about a little bit of in-line
| assembly, I've written entire UI, device drivers, and
| everything else in assembly - many thousands of lines of code.
| Maybe this is why I don't feel like Typescript has solved
| anything much for me when I work with front-end code.
| game_the0ry wrote:
| Since adopting typscript, the way I usual approach my development
| is that I clearly define data types on ui and then the
| implementation details tend to reveal themselves.
|
| There is a quote I saw somewhere, forget where, but it was
| basically: define your data structure and the algorithms will
| reveal themselves.
| motorest wrote:
| > Since adopting typscript, the way I usual approach my
| development is that I clearly define data types on ui and then
| the implementation details tend to reveal themselves.
|
| That is aligned with the basic premise of Domain-Driven design:
| define a model of the problem domain, and everything else just
| falls in place.
|
| I wonder why these articles reinvent the wheel with functional
| programming hand-waving when DDD has been screaming this for
| years.
| PittleyDunkin wrote:
| > I wonder why these articles reinvent the wheel with
| functional programming hand-waving when DDD has been
| screaming this for years.
|
| These are two different levels of abstraction. If you're
| still enraptured by the fundamental mechanisms of computation
| (i.e. functional programming) you're not going to see the
| value in trying to figure out the best way to build via
| composing mechanisms of computation, whether it's functional,
| imperative, procedural, logic-based, lisp-based, object-
| oriented, message-passing, whatever. There's a reason why
| there aren't many DDD frameworks out there--it doesn't really
| benefit from tying to specific
| technologies/languages/ecosystems in the same way that the
| culture of "build shit as fast as possible" attitude
| dovetails well with the goals of Rails.
|
| I don't see why this is surprising; people re-discover old
| lessons daily, and petty details will always be conflated
| with broader themes and patterns--it's just how the human
| brain works. The discussion is what keeps us thinking about
| those old lessons. This is just a person's blog, not a
| journal trying to represent an industry.
| jpitz wrote:
| Could it be Linus Torvalds' "Bad programmers worry about the
| code. Good programmers worry about data structures and their
| relationships." ?
| game_the0ry wrote:
| Honestly, do not think so, but its close enough.
| azornathogron wrote:
| There's a well known quote from Fred Brooks too:
|
| ""Show me your flowcharts and conceal your tables, and I
| shall continue to be mystified. Show me your tables, and I
| won't usually need your flowcharts; they'll be obvious.""
|
| (Though from your description I suspect that's also not the
| one?)
| gonzus wrote:
| Probably by Fred Brooks, as summarized by Guy L. Steele Jr in
| https://dreamsongs.com/ObjectsHaveNotFailedNarr.html:
|
| > Fred Brooks, in Chapter 9 of The Mythical Man-Month, said
| this: _Show me your flowchart and conceal your tables, and I
| shall continue to be mystified. Show me your tables, and I won
| 't usually need your flowchart; it'll be obvious._ That was in
| 1975. Eric Raymond, in The Cathedral and the Bazaar,
| paraphrased Brooks' remark into more modern language: _Show me
| your code and conceal your data structures, and I shall
| continue to be mystified. Show me your data structures, and I
| won 't usually need your code; it'll be obvious._
| arialdomartini wrote:
| I'm reading Type Driven Development with Idris and this post
| really resonates with what I'm learning. Especially the idea of
| writing down the function's type to be guided how to implement
| it.
| arialdomartini wrote:
| PS: Type Driven Development with Idris is mentioned in the
| final notes. OP, I could not recommend it more!
| k3vinw wrote:
| Is it too simplistic or abstract to think of types as merely
| contracts?
| TypingOutBugs wrote:
| I think that works!
| renox wrote:
| > One of Haskell's most basic innovations [cut] was the ability
| to write the type of a function separately from writing the
| function body.
|
| I don't get it, what's the difference between this and C's
| function declaration?
| xigoi wrote:
| In C, you still need to write the types in the definition.
| andsoitis wrote:
| I really like the balance struck by Ada's type system, especially
| Application-Defined types to model the problem domain -
| https://learn.adacore.com/courses/Ada_For_The_CPP_Java_Devel...
|
| Other effective features of Ada's type system:
|
| - type ranges
| (https://learn.adacore.com/courses/Ada_For_The_CPP_Java_Devel...)
|
| - generalized type contracts using subtype predicates
| (https://learn.adacore.com/courses/Ada_For_The_CPP_Java_Devel...)
|
| - attributes
| (https://learn.adacore.com/courses/Ada_For_The_CPP_Java_Devel...)
| ddyevf635372 wrote:
| There are still so many devs who don't want to deal with types,
| and they love Ruby and Python, as well as JavaScript without
| types.
|
| It is quite difficult to work on large Ruby or Python projects;
| interfaces are not determined, and figuring out what's happening
| is painful.
|
| Still, so many devs love it, and they wanna keep working with
| Ruby and Python in this way.
|
| I kind of feel that experienced devs move on, and give up
| projects without types.
| bowsamic wrote:
| These days most Python devs I know use types
| neverartful wrote:
| The funny thing is that even for devs who don't want to declare
| their types will still have think about them to some extent.
| Even if it's correcting run-time errors indicating that some
| function or property doesn't exist for type 'X'. Plus, they get
| to guess at the types that are expected for various function
| calls in their own projects. Oh sure, you can add comments that
| document it right above/below the function, but do you remember
| to keep those up to date while you're in the middle of
| refactoring?
___________________________________________________________________
(page generated 2025-01-03 23:01 UTC)