7 ms·
I find it amusing how these software architecture gurus always demonstrate their teachings with a cookie-cutter CRUD app. There are software which do things oth
by layoutIfNeeded 6y ago
I find it amusing how these software architecture gurus always demonstrate their teachings with a cookie-cutter CRUD app. There are software which do things other than making REST calls... Show me how you’d implement a basic MS Paint clone and we can talk!
- tarruda 6y agoI think the idea described by the op is how you're supposed to organize code when programming in Haskell. Having most of your application logic in pure functions makes it easy to test and reason about. While this is possible to do, it is easier said than done. Organizing the code this way requires a lot of time dedicated to thinking/rewriting, which is often not available in the usual corporate environment with strict deadlines.
- necovek 6y agoI think it only requires a change of mindset for a developer. Learning TDD truly will usually lead to functional code, even if you do not write your tests first. Eg. I can't imagine what would be hard for a MS Paint clone to achieve using this approach. There are always things with side-effects (IO, namely), agreed, but in this CRUD example, the integration bits are coupled in a way where you need a single trivial integration test. Similar approach can be applied to a GUI app, so I am not sure why does GP feel it can't? Any concrete things where you think you can't apply it? Sure, you'll have many more small functions, but I think the core takeaway should be that you can always structure code in away where integration functions are simply statement-lists (eg. no control-flow logic in them). That will usually require rest of your code to be functional. And yeah, it's harder to adapt existing code to this pattern, but introducing new code in an existing code base following functional pattern is trivial.
- tarruda 6y ago> Any concrete things where you think you can't apply it? I'd say that you can apply it mostly everywhere, however it is not friendly to most people that will maintain the code, and that is a problem since most software will have many maintainers over its lifetime. This reply to another comment I made on this thread should elaborate a bit more: https://news.ycombinator.com/item?id=24917764 https://news.ycombinator.com/item?id=24917764
- necovek 6y agoOh sure, there's always going to be some friction! So let me go on a tangent here. While the current education system is geared toward procedural programming for the most part (I imagine mostly theoretical computer science curriculums only focus on functional programming and lambda calculus too, but even then, only very late and very theoretical), the question is more of whether it is a better approach when applied "universally" (with non-functional languages, it's unlikely to be really pure)? If deemed that it is, functional proponents like me (and you, it sounds like) should push for it to get a better coverage in Universities than eg. OOP, even for OOP languages. Most academia is out of the software industry, so should we educate them or not? And how best to do that if the answer is yes? I do have a worry that some of it is also incomprehensible to some people, or that the barrier to entry is higher. Is such purity more reserved for those that also like mathematical abstractions? Now, the biggest problem I have with colleagues reviewing my code is that it seems too-simple, and they would have introduced another 2 layers of indirection/abstraction, but they can't really say that anything is wrong with my approach. It's really hard to get them to jump out of their "OOP bubble". The code is easy to maintain, but there is a big risk that someone will pop in and just turn it into one big side-effect mess that will be hard to maintain. But then again, that's what they would have done anyway, this has at least some chance of not becoming that :)
- kumarvvr 6y agoThis happens in a lot of tech talks too. Also a problem with explaining design patterns. I wish there was a talk, that took something like Microsoft Word and de-constructed it and explained how someone can program it, from first principles.
- solipsism 6y agoI don't think that would be particularly useful. In my experience, most of the problems you need to solve with a big application like Word are either very particular to the problem space (e.g. word processors, 3D game engines, etc) or very particular to that specific codebase (i.e. how engineers dealt with the decisions made earlier by previous engineers). The Word codebase is no work of art, I guarantee. Like any codebase of any size, it's more of a ball of duct tape and bailing wire.
- codebje 6y agoIf you wanted to be able to test your MS Paint clone, you might implement your drawing core without being dependent on a window existing. An off-the-cuff approach might be to have the core define a canvas interface with the rendering primitives it desires, and provide a suite of functions that will translate user input actions to canvas rendering primitives. A purely functional approach would involve a core of functions taking in a current state and returning an updated state and a list of canvas actions to take. Functions might include "select ellipse tool" and "set pen width to 5" and "click on canvas at point (3,15)" and return canvas primitives like "render ellipsis from (3,15) to (47,99) with stroke width 5, stroke colour black, and no fill". Unit testing of the core should obviously be quite simple to do, being totally independent of the GUI system.
- dnautics 6y agoWhat is it that makes you think you couldn't implement ms paint in this architecture? I've seen all sorts of thing with this sort of architecture, ranging from dungeon crawlers to distributed virtual machine orchestrators, to file system browsers, etc.
- layoutIfNeeded 6y agoE.g. I don't see how the text tool would work. Where's the transient state stored while the text is being entered, but not yet finalized? Similarly, how would drawing a line work? That is, drawing a long squiggle, that is continuously updated while drawing, but will still be undone/redone with a single Undo/Redo operation. I simply don't see how this fits the functional core + imperative shell pattern.
- mac01021 6y agoThe imperative shell could be something like while not is_closed(state) { (mouse_activity, kbd_activity) := get_mouse_and_kbd() //blocking call (state, is_modified) := update(state, mouse_activity, kbd_activity) if (is_modified) { draw(state) } } There is no reason that `update` and every function it calls cannot be pure. The state will have to include undo and redo histories, an indicator of the active mode, so that you might be in one mode while you're entering text, a different mode while you're dragging out a line or a shape, etc. It will include information about what drawing tool you have selected and what colors you've chosen for your ink and eraser. All that data will be used by the draw procedure to render the correct view of the state. The one issue here is that once your state gets to a certain level of complexity, as it certainly does in ms paint, it's not going to be performant without immutable "persistent" data structures, which are either not available or not widely used in python/js/ruby/c. If you're thinking i haven't achieved the goal here because the draw procedure is big and complicated and imperative, then maybe we need to replace draw(state) with view := render(state) draw(view) where render is pure and does almost all the work. But I'll leave thinking about what render looks like as an exercise for the reader (or to be described by an HN user who knows more about graphics programming than I do)
- 6y ago
- barumi 6y ago> Show me how you’d implement a basic MS Paint clone and we can talk! A MS Paint clone is one of those apps that fits rather nicely on a Clean Architecture. You have the domain model (raster image), you have the application layer (image processing operations over the raster image), and you have the IO/service layer (image exporters/importers, GUI, platform-specific features, etc).
- OneGuy123 6y agoAre you actually a programmer? You sound more like an academic with no real life experience on large software. You do realize that within those "neatly separated layers of yours" there will be an insane amount of complexity which will be impossible to separate in layers?
- barumi 6y ago> Are you actually a programmer? Why, yes I am. > You sound more like an academic with no real life experience on large software. Well, I do work as a software engineer for a FANG, so that does fit the bill I guess. > You do realize that within those "neatly separated layers of yours" there will be an insane amount of complexity which will be impossible to separate in layers? Well, there really isn't you know? I mean, unless you don't know what you're doing. In my line of work, the hardest problem is to reign in complexity. It's very easy to mess up and end up with insane amount of complexity, specially if you don't have a clue about what you're doing. In fact, as the saying goes, incompetent developers make complex things, while competent developers make simple things. It seems you make a living struggling with complex things that ends up piling on a lot of complexity. Perhaps you would do yourself a favor by improving your skillset and learn how not to follow that path.
- OneGuy123 6y agoTrust me I'm considered a very good developer and simplification is something I always put as top priority. You on the other hand still belive you can make everything totaly managable forever and always and in any situation. Your academic tone betrays you: you obviously believe you can always split things into neat little parts and then write books about it and how even in production this is so easy and always "just a bit of layering and it will work". Anyone who worked on real production systems over years knows that unless your company has infinite money for developers and infinite time that you will sooner or later get parts on which complexity starts getting layered on. But hey, "just add a few layers". Also being a FANG developer means nothing. I've heard stories about FANG company developers, they are not very FANG-like to say the least.
- stinos 6y agoThis is the feeling I get most of the time in these 'let me explain software architecture in 1 post' articles. You see, I agree with pretty much everything in the article and write code like that all the time. Because yes, it does work. But you learn stuff like that automatically after a couple of years. Still, this is just one simple function; the actual hard part is scaling that to 1k+ functions while still maintaining something clean and understandable. Sure you can draw this in an onion diagram, but actually executing that in real life is something else, and I almost never see practical examples of that in online articles simply because that is not possible I guess, only in actual code or in more alaborate books.