1. 5

    This project does not involve machine learning. If anything, its development might be called “machine teaching”. I know how to play through Castlevania. And the challenge was to capture my knowledge into a computer program.

    That was unexpected these days. Good job! :)

    1. 2

      That was unexpected these days.

      It is also well written down on a nicely formatted page. This is exactly the kind of content I am reading Lobste.rs for, thanks.

      (Okay, I’ve also been obsessed with Castlevania the last few weeks, that’s perfect timing)

      1. 1

        Because of the TV series? I enjoyed that a lot myself. When Bloody Tears finally started playing…

        1. 2

          Mostly due to discovering Curse of the Moon, which is essentially a re-imagination of Castlevania III (on which the series is based) which reminded me that I much prefer the Konami-created Castlevanias to the games that are coming out as part of the Metroidvania revival. Timespinner is nice for a low-budget game but I’m playing Portrait of Ruin and the music and sprite-work that went into the game are just top-notch. Heaps of fun despite being 12 years old by now.

    1. 1

      Did I really just invent a design pattern?

      1. 4

        I think that is just the adapter pattern. I would say your example images are more or less similar to the ones of the adapter pattern.

        Furthermore, I don’t think your definition of dependency abstraction actually is that different from the definition of dependency inversion.

        Dependency Abstraction: Instead of depending on something external, define yourself an abstract interface.

        Compared to DI:

        A. High-level modules should not depend on low-level modules. Both should depend on abstractions. B. Abstractions should not depend on details. Details should depend on abstractions.

        You state that if DA is applied to on a “one layer above”, it is equivalent to DI. I think that this is based on a false assumption that the locality aspect (“high level” vs. “low level”) is a thing worth considering. The locality aspect (“high level” vs. “low level”) is not that relevant here, since it should not matter where the interdependent models are. The only thing that matters is that the dependency is not concrete, but abstract, i.e. typically an interface in most languages.

        Thus, any definition of “dependency abstraction” is more or less dependency inversion. The basis is that there is no run-time dependency to the concrete implementation, i.e. something that receives a MysqlUserRepository only depends on a UserRepository, and the dependency is at compile-time when the dependency is provided in the dependency injection phase (i.e. something like new UserController(new MysqlUserRepository(...)).

        I also think the wording of DA is rather ambiguous: what is external? Is the difference meaningful whether it is internal, for example, in the same binary; external if it’s in the same system, network or process? I think you could say instead:

        instead of depending on something concrete, depend on something abstract.

        And we’ve come full circle to the definition of DI.

        1. 1

          If both are on the same layer then “inverting” the dependency is not helpful because it does not decouple the two components any more than before. You need the adapter on the layer above in addition and that is not mentioned in the context of dependency inversion. Also, DI implies an “implements” relationship from Y to Iy which does not exit in DA. There XAdapter implements Iy instead.

          The adapter pattern alone is not enough to decouple two components.

          Thus, dependency abstraction is neither dependency inversion nor an adapter. It somewhat combines them and modifies DI a little.

          Where I can agree with you is that DA and DI described in one sentence are practically identical. I still argue that they differ in significant details.

          1. 1

            Could you elaborate what you mean by above?

            I still think the adapter pattern captures the essence of the definition. It specifically lets you build modules that implement IY without having class Y implements IY.

            1. 1

              I’m using “above” in the sense of a layered architecture. For example, the user interface layer is above the business logic layer. The data model layer is above the SQL database layer. The application is above the operating system.

              The adapter pattern is an obvious solution to the problem. It does require an existing interface though and you need to “apply half a dependency inversion” to create it.

              Maybe we could phrase it like this: Let the DI principle be “depend on abstractions not on concretions”. Then there is the DI pattern which turns “X uses Y” into “X uses Iy which implements Y”. In contrast, the DA pattern turns “X uses Y” into “X uses Iy and YAdapter inherits from Y and implements Iy”. Now DI and DA patterns are clearly different. Both realize the DI principle.

      1. 5

        I maintain a home server providing DNS, video streaming, and some automation.

        I use Ubuntu LTS in auto update mode for the 5 years of security updates. I made the release upgrade to 18.04 already but it is nice to know I could have waited three more years.

        I use CFEngine for configuration management. Somewhat overengineered but I want to have and hone that skill. I picked CFEngine because it is old and mature. I don’t know any system (Puppet, Salt, Ansible, Chef) that I actually like.

        Years ago I tried to make some Sandstorm apps but I never got them to run well.

        1. 1

          0 refers to the first changeset in the repo, which is handy. There’s no easy way to refer to this in git

          Can there be multiple first changesets in a Mercurial repo? There can be in in git and I find it helpful. It happens if you merge two repos.

          1. 2

            That’s possible in hg with “pull –force”, you’d end up with two changesets and are children of the null changeset. The second descendent of null would not have changset number 0 though.

            1. 2

              Yep. You could use hg log -r root() to see all of the root revisions though.

            1. 3

              I see absolutely no reason why anything except cryptocurrency needs “blockchain”. And I’m the kind of guy with a bitcoin sticker on his laptop.

              1. 5

                I think DNS alias NameCoin is a good idea. Adoption is an unsolved problem though.

                1. 7

                  Namecoin is a cryptocurrency. (coin is right in the name!) Yes, it’s neat that you can attach name registration to cryptocurrency, but you still have A Cryptocurrency and everything associated with that (51% attacks, PoW power waste or unproven experimental PoS schemes, etc.)

                  1. 2

                    Namecoin is the quintessential cool idea with no usage. Its main use case seems to be academic papers.

                    1. 2

                      NIST has this flowchart about blockchain use, which contains the question “Are the entities with write access having a hard time deciding who should be in control of the data store?”

                      I’m not in the DNS business but it seems that the current system of centralized control is good enough for all involved parties. There is probably some conflict about that, but not in public.

                1. 20

                  But when you try to argue with me that it is normal for my government’s online tax submission system to require Adobe Flash and the delivery of that overprivileged opaque blob to my browser, that’s when you get the “public money, public source code” response, liberally drizzled with the “holy fuck, how do you breathe” stare.

                  Comedy gold (and so true)

                  It does make one wonder how in this day and age there so many companies using free software but never truly contributing back, and then daring to complain when shit like this happens.

                  I’ve spoken to quite a few people working at wildly different companies recently and all of them responded the same when I asked them if they contributed to open source: Well, when there’s a nasty bug in the code we might fix it and contribute it, but as a rule, we do not.

                  Most of these companies are afraid to give up their so-called “competitive edge” so they keep all their code completely closed.

                  1. 9

                    It does make one wonder how in this day and age there so many companies using free software but never truly contributing back

                    Basic economics and common sense: 100% selfish organizations dedicated to maximizing profits and externalizing costs maximize use of FOSS but minimize development. The licensing they choose makes it easy. They’re literally just telling companies to screw them over. Some then try to justify contradictory positions of “company should give back” and “we should use licenses that encourage them not to.”

                    This problem made me push licenses like Prosper. It says you can do anything with and share the software so long as you’re not making money off it. If you make money, you negotiate a commercial license which might require just money, sharing code back, or whatever. These licenses can be refined to have more of the software freedoms in them. I already nailed down most of the concepts with the only thing that’s a problem is transition from shared source to FOSS if company stops maintaining the software. There’s tricks for them to stretch it. Most of the freedoms are easy to simulate, though, in a non-commercial, free-to-use, shared-source license.

                    1. 5

                      I see two problems with Prosper:

                      1. The software cannot get into Debian and FOSS distributors, because it is not free enough.
                      2. How can you handle contributions with requiring contributors to hand over their copyright? This is a barrier to participate.
                      1. 3
                        1. That’s their choice. They’ll reject it, allow it as a proprietary inclusion like blobs/flash/whatever, or it becomes a standalone thing users install. One of my ideas was using paid, add-on software released under Prosper to fund [F]OSS dependencies. So, it not making it into Debian could ironically be a good thing for Debian. ;)

                        2. I don’t know enough about legalities to answer that. Some of it would need to be fleshed out by experts. I will say I was going to setup the Prosper-like license to work the same way OSS licenses worked. For non-commercial use, their contributions automatically create a derivative, it’s licensed the same way irrevocably/perpetually, and they get a copy. Like original, the derivative is still non-commercial. Some contributors won’t participate in that. Some will as we see with people building on Microsoft and IBM technologies.

                    2. 8

                      At some previous jobs we relied on FOSS projects up and down the stack, but there was enough red tape in place that to contribute anything back to those projects would take months, if you were allowed to do it at all. It didn’t matter whether the changes actually had anything to do with the company’s “competitive edge”—the decision makers were too conservative to let anything that “belonged to us” leak out to anyone else. The devs were mostly in favor of contributing back, but are you really going to burn time (and goodwill with the higher-ups) to submit a small new feature to some logging library?

                    1. 17

                      I don’t like it, but I guess I’m not the target audience anymore.

                      Previously it was important to introduce the language. What is it about? “Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.”

                      Today you can probably assume that people either know what makes Rust unique or they don’t care. Instead people are kind of hesitant to try it. Why should you try Rust? “Rust: The programming language that empowers everyone to become a systems programmer.” Hm, “empowers” sounds nice. I want to be empowered…

                      I don’t think it’s perfect as a tag line though. First, it assumes you know what “systems programming” is and that you want to do that. Second, it suggests that you are not a rockstar programmer. You are just one of everyone.

                      1. 4

                        Scroll down a bit and they’ve still got a description of the language proper, though they seem to have rephrased it as “Performance, Reliability, Productivity” (which seems like a good description).

                        My biggest complaint is that white-on-maroon kind of hurts my eyes.

                      1. 4

                        I hope they change the tag line: “Rust: The programming language that empowers everyone to become a systems programmer.”

                        In my experience, “systems programmer” is used to mean “I write programs that are hard, so I can look down on people who do mere ‘scripting’ programming”

                        1. 9

                          I think Wikipedia sums it well:

                          […] application programming aims to produce software which provides services to the user directly (e.g. word processor), whereas systems programming aims to produce software and software platforms which provide services to other software, are performance constrained, or both […]

                          Source: https://en.wikipedia.org/wiki/System_programming

                          1. 3

                            I’ve just now realized that to me, “systems programming” is basically equivalent to “not having to care about unicode”.

                            I really like this.

                            1. 1

                              So an alternative to find would not have to deal with filenames or directory names that contain Unicode?

                              Or if you’re writing a database engine, you don’t have to support Unicode?

                              I’m being a tiny bit sarcastic, but it’s also interesting to investigate the boundary between “user” and “systems” programming.

                              Edit wording

                              1. 1

                                It’s certainly a matter of perspective to a large degree (one developer’s platform is another developer’s application), but from where I sit, yes, find, databases and such are definitely more in the “applications” direction.

                                The “systems programming” I deal with consists of things like filesystems (please please please don’t shove unicode in there), block storage layers, thread scheduling, memory allocators, etc.

                                1. 2

                                  The “systems programming” I deal with consists of things like filesystems (please please please don’t shove unicode in there)

                                  Hah, doesn’t one of the new macOS file systems do this? IIRC, they require valid UTF-8 and I think even do normalization. With that said, I am not knowledgeable about file systems, so I don’t actually know at which level of abstraction these rules are implemented.

                                  Anyway, I love Unicode. A significant fraction of the work I’ve done in Rust land has involved Unicode in one form or another. But my area of interest is text search, so that makes sense. Whether that’s “systems” or not, I dunno. ¯\_(ツ)_/¯

                                  1. 3

                                    Hah, doesn’t one of the new macOS file systems do this?

                                    I haven’t really been paying too much attention to Apple recently, though it certainly seems believable – their filesystems have been case-insensitive since time immemorial, so madness of that sort was already well-established there…

                          2. 6

                            I thought this was a really great description of both the ambiguity of the term and its origin.


                            1. 4

                              Thanks for sharing. This article does a good job of exploring why this is such an ill-defined term. In particular I find the early pre-Osterhout definitions to make much more sense than the modern usage. His dichotomy really seems to have set the discourse back significantly.

                              1. 1

                                Huh, I thought the definitive treatise on the nature of systems programming was this.

                              2. 6

                                We’re not fully happy with the tag line currently and happily take suggestions. “systems programming” being a fuzzy term is one of the problems. The spirit is definitely what we want, but if someone were to find a better way to phrase it, I’d be very happy.

                                1. 6

                                  My translation of “systems programmer” is “we don’t do GUIs”. ;)

                                  1. 3

                                    Yet many GUIs outside of the web context are written in systems programming languages :)

                                    1. 1

                                      Sounds like rust alright.

                                    2. 4

                                      I like the spirit of the tagline. Systems programming is a real thing, it’s genuinely difficult to do correctly - and Rust is helping make that situation better, so that more people can write less buggy systems code.

                                      1. 1

                                        This is cynical, although sometimes true.

                                        1. -6

                                          Systems programming is genuinely difficult in a way that, frankly, GUI programming just isn’t.

                                          1. 10

                                            If you just switch “GUI programming” and “Systems Programming”, this statement checks out, too. Modern GUI programming with backends and networks is a complexity beast. Add translation and such on top and it becomes incredibly hard.

                                        1. 4

                                          Here are my thoughts on concrete actions we can take.

                                          To make it feasible to support the open-source projects we depend on (with money and/or code depending on circumstances), we need to have fewer dependencies. In light of this, the dependency graph of a typical Node.js project is insane. Some newer languages, like Rust, seem to have the same problem.

                                          I suggest that for software that runs on GNU/Linux, we limit ourselves to what’s packaged in Debian, because Debian seems to do a very good job of vetting the legal status of the software it packages.

                                          Debian should disable Internet access during package builds, if it doesn’t already do so, so we can’t cheat and pull in unvetted dependencies directly from npm or the like when building our own packages.

                                          Then we should definitely support Debian itself in any way we can.

                                          For web development in particular, these restrictions eliminate many popular frameworks and libraries. What does that leave us with? Python, PHP, Java, or Go on the back end, and jQuery on the front end? Have I overlooked anything?

                                          On making software simpler, there is some complexity we simply can’t eliminate without causing real harm to users. For example, when developing a GUI, we have to make it accessible to people with disabilities (e.g. blind people), or else some people can’t do their jobs. A GUI isn’t as simple as drawing pixels on screen and taking input from a keyboard and mouse (probably only in Western languages), as one did in the “good old days”. But a terminal-based UI will be rejected by practically everyone. So we’re stuck with our current complex GUI platforms. At least we can limit the extra complexity we add on top.

                                          1. 3

                                            Debian does build without internet access. That is why you can still build ancient Debian versions. It comes with all its dependencies.

                                          1. 3

                                            Good idea. I just put a “nice” and “renice” into my apt wrapper.

                                            1. 1

                                              May I ask which distribution and how the wrapper plays nice with upgrades of apt itself? Or is it just by another name, and you run it manually?

                                              I’m assuming it’s a shell script, would that be correct?

                                              1. 2


                                                Here it is. I think the biggest advantage is that I always forget the sudo and this makes it implicit.

                                              1. 1

                                                That was an interesting experience. That page is one of the worst I have ever seen in terms of readability. I had click on the “readability” switch, resize my browser window, and increase the font size. Later I figured out how to force-enable Firefox reader mode because it was not available by default.

                                                With regards to content, I agree with all the general statements and disagree with most of the details. I guess one of the most debatable points is the number of languages.

                                                “Pick a programming language that scales” Yes, I agree with that. Less languages means less complexity. Good.

                                                “Common Lisp, Scala, F#, Haskell, OCaml, Clojure, Erlang, Racket, are possibly valid choices” Uh, I would not have picked those. Haskell, OCaml, Clojure, Erlang and Racket can become quite a barrier if you want to do performance tuning. Scala and F# are on platforms where Java and C# should be just as good.

                                                “Anything more than a performance-critical loop in C, C++, Java, Assembly or PL/SQL is a failure.” Uh, C++ and Java are languages that scale fine for me. Especially C++ is a very broad language which can do high-level abstract stuff and low-level performance stuff. It has other issues like memory-safety and hard syntax, but we are talking about scalability here.

                                                I would suggest one programming language and one scripting language. That might be C++ and Python. Or Java and Groovy. Or Rust and Lua. Well, probably Python as scripting language in any case. The programming language depends on the domain you are in.

                                                1. 4

                                                  I read the first part of the piece thinking that it was trying to capture the “essence” of MVC in its original form. When I reached the conclusion, it seemed that the author was suggesting it doesn’t really matter. I like that message, and I think it’s the conclusion of the piece, but I wish it were written a bit more definitively.

                                                  1. 4

                                                    My conclusion is little bit more nuanced and the last paragraph together with the meme image tries to communicate that.

                                                    Yes, in general it does not really matter. We agree on that. It is just a term and usually people roughly understand each other when they use it.

                                                    It does matter when you are actively trying to design something. If you “apply the MVC pattern” it might mislead you. Tonnydourado mentioned that “maybe, just maybe, there can be more layers in a system than models, views and controllers”. Don’t shoehorn your design into MVC. It is not a timeless pattern to which good designs gravitate towards. That matters because it introduces unnecessary complexity (thus technical debt) into your software.

                                                    1. 1

                                                      What I meant didn’t matter is mostly the question of “what was the original MVC?”

                                                  1. 5

                                                    I think the author meant to refer to Alan Kay instead of Alan Key. Still, though it’s an interesting article doesn’t detract from it.

                                                    1. 3

                                                      Thanks. Fixed that.

                                                    1. 1

                                                      Isn’t it obvious that as a web developer you have to chase new technology all the time? I avoid that industry for exactly that reason.

                                                      Now I’m in embedded/automotive and things move more slowly here. We just switched to this “shiny new” technology called CMake. Well, there are trade-offs…

                                                      Most programming is stuff which either nobody uses (startups, R&D) or everybody hates (legacy code).

                                                      1. 6

                                                        What’s worse is a lot of the change in the webdev space is not substantially better. The actual changes that bring big benefits, such as simple architecture, pervasive immutability, or controlled side effects require too much of a mind shift to catch on. So, what takes its place is incrementalism. You’re not allowed to question core web tech (HTML/CSS/JS) b/c the devs are hamstrung by sunk costs of making the spaghetti work.

                                                      1. 3

                                                        I have been thinking about something like this myself because it is promising technology for edge computing ideas. I would not have chosen V8 though. It is too complex. Simplicity is a prerequisite for security.

                                                        My idea would be to use binary translation like Qemu does. The biggest problem is not the code itself though. The bigger attack surface is the interface for IO. Code is useless without IO after all. The interface will probably grow a lot to make development convenient.

                                                        I think Google tried something like this for browser plugins if I remember correctly.

                                                        edit: That was Native Client (NaCl, PNaCl). Now only used for ChromeOS.

                                                        1. 2

                                                          Looking further somebody already did that. I would like to see a comparison of Cloudflare Workers to http://www.zerovm.org/.

                                                          I guess the primary argument is: ZeroVM is dead since four years.

                                                        1. 10

                                                          They talk like language-based security is new. Yeah, there’s a ton of these in the literature. Anything enforcing memory safety (eg Softbound+CETS or SAFEcode), control-flow integrity (esp Code-Pointer Integrity w/ segments), data-flow integrity, information-flow control, etc might be useful to build on here. Many are designed for C, too, which is closer to metal than Javascript, has tons of automated checkers (eg RV-Match from RVI), and a certifying compiler (CompCert).

                                                          The other drawback is you have less layers of protection if operating in process with language-based and/or tactical mitigations. The MMU can isolate what we call known unknowns where something goes wrong (eg bitflip or RAM decay on protection mechanism), the app goes rogue, and it’s still contained a bit. That’s why the strongest approach from high-assurance security is still separation kernels: microkernels designed specifically for security that fit into L1 caches, are often mathematically verified in some way, support individual apps running in own address space optionally on a language runtime, and support VM’s for legacy apps. Muen is an example of that approach for x86, seL4 an example for ARM (mainly ARM), and INTEGRITY-178B a commercial example for PPC (beware marketing hype).

                                                          1. 3

                                                            The only reason this was possible at all is the open-source nature of V8, and its standing as perhaps the most well security tested piece of software on earth.

                                                            Seems they have convinced themselves that extensive testing is good enough.

                                                            1. 2

                                                              Yeah, their solution seems great until it doesn’t work. With v8 in the browser, a sandbox escape compromises the environment of a single process/context. Really bad for sure. However, on their platform, sandbox escape seems like it would be /worse/, having the potential to compromise multiple contexts, and thus multiple customers.

                                                              Let’s just hope nothing bad happens I guess?

                                                              1. 3

                                                                A new attempt at Software-Isolated Processes being harder to get right than a parser? Nah. They’ll prolly be safe. ;)

                                                                1. 3

                                                                  On a nicer note, the author just showed up on HN: it’s kentonv from Sandstorm and Cap n’ Proto. Gives me a little more confidence that it will be designed and/or implemented well. I still stand by original comment, though, since it’s the same stuff I told him when he was doing Sandstorm. Although more projects exist, the fundamentals of what worked and didn’t are still the same.

                                                              1. 20

                                                                “When people got a computer science degree, they can program. They only have to learn the rest of software development now.”

                                                                Once heard a quote like that, but cannot attribute it anymore.

                                                                1. 9

                                                                  From what I’ve heard, it’s more like.. when people get a computer science degree, they get a piece of paper. They may or may not be able to program. They may get a job in the field. They may or may not need to learn software development.

                                                                  1. 11

                                                                    The comments on tech forums with hiring managers say they use coding exercises specifically cuz most grads applying cant code. Many say the numbers they filter were huge, too. A necessary evil.

                                                                    1. 4

                                                                      I believe I can teach a person the mechanics of programming in a very short time. The hard part of programming isn’t the coding.

                                                                      1. 5

                                                                        It may or may not be the blocker. They might not even be able to mentally solve problems with step by step commands. Whatever part it is, the people submitting applications can code a solution to something that prints every 3rd number from 1 to 100. Super-simple stuff. Others’ code couldnt even compile in other discussions.

                                                                        1. 1

                                                                          You really can’t, in general. I have tutored intelligent, dedicated people who simply couldn’t get it. I think the fundamental limitation is not intellectual, but in any case it’s very real and prevalent.

                                                                  1. 3

                                                                    I use Notepad++ for editing. As an architect I don’t do much coding anymore and the changes I do are usually trivial (at least if you look at the diff). I would prefer vim but my IT-controlled Windows environment makes it suck too much. The others mostly use VisualStudio or VisualStudioCode afaik.

                                                                    For unittesting we use Googletest and Cantata. The later is necessary to instrument code for coverage statistics. While gcc and other compilers can do this for you, various compilers for embedded targets don’t. Unfortunately, Cantata does not even support C++11 completely/reliably, so we are restricted to using C++11 minus some features.

                                                                    Debugging happens with VisualStudio, gdb, or the Lauterbach tools depending on the platform.

                                                                    For building, we recently switched to CMake from a homegrown system. Our CMake is heavily adapted and does not look idiomatic.

                                                                    For coding rules (e.g. MISRA) we primarily use QAC. This sucks because the licensing model does not allow to check pull request with Jenkins.

                                                                    That is all the external tooling I can think of for now. There is plenty of internal tools as well.

                                                                    1. 2

                                                                      I only have some fun titles for you: http://beza1e1.tuxen.de/articles/titles.html

                                                                      Architect would fit if you are responsible for the overall architecture, but product teams sounds like the teams are independent?

                                                                      1. 1

                                                                        They are independent-ish. Some of the products have overlapping (or nearly so) functionality and came via acquisitions. Some of the products already interoperate so there’s some architecture across products (which I will probably be involved with designing/organiziing).