HNHacker News
TopNewBestAskShowJobs

ceronman

2,861 karma · joined January 27, 2011

Programmer
submissionscomments
ceronman··on Bazel Release 1.0
I've worked with both and while Bazel definetely has a learning curve, mostly because is very different than Maven and Gradle, I actually find it considerably simpler than those two. Maven dependency management is really complex, and I'm tired of dealing with dependency hell. And Gradle doubles down on Maven complexity where you stop having declarative XML config and instead have actual Groovy/Kotlin programs.

So, please consider the difference between complex and unfamiliar.

ceronman··on Crafting Interpreters: Closures
From a functional perspective, this of course doesn't make any sense. But from an imperative perspective it does.

A common use for closures in imperative languages is to have custom control structures similar to `if`, `for`, `while`, etc. And in imperative languages mutating values is very important, if you want a new control structure you have to be able to mutate your surrounding variables.

Smalltalk only uses this kind of control structures based on closures. Ruby also uses this a lot, it even changes the meaning of `return` in closures (blocks) to return not from the closure but the enclosing function.

ceronman··on Microsoft to Explore Using Rust
"70% of all Microsoft patches are for memory-related bugs".

This says a lot. I'm sure Microsoft has very smart and competent engineers, yet they still get all these bugs. It's because manual memory management is really, really hard.

I'm baffled to keep hearing some people saying that manual memory management is okay when the evidence is this huge.

Perhaps for very simple programs is okay to do manual memory management, but for complex ones like most of them nowadays, it seems close impossible for humans to write safe programs.

ceronman··on GitHub Sponsors
I've been trying to find out which countries are eligible to receive payments, but I haven't found any information. Most likely I expect this to be like Kickstarter where basically only developers living in certain developed countries can participate.
ceronman··on Benefits of a Monorepo
My point was about the the fact that by declaring your dependencies explicitly, Bazel allows you to compile only the things you depend on, not everything in the monorepo. And once you have built your dependencies once, you don't have to build them again.

If you think about it, a package manager workflow (like maven, nuget, etc) is also a form of incremental compilation. You compile your libraries only once and publish them in binary form in some sort of repository and then import them. The difference is that if you want to make a change in both a library and an application this becomes hard to do with packages, while very easy with a monorepo and Bazel.

ceronman··on Benefits of a Monorepo
There is available tooling to help you with that, not only has to be discipline.

A monorepo oriented build tool such as Bazel will make sure that you don't compile more than needed. This is extremely efficient. In fact, in my company with a few hundred projects we tried it and it was 10 times faster than our previous Maven based workflow. These tools also help you with dependency management so you keep your code organized. The killer feature is that you finally have true Continuous Integration because the build tool will figure out any dependencies of the code that you change, rebuilding it and testing to make sure that nothing is broken.

ceronman··on Ask HN: How do you stay disciplined in the long run?
I also struggle with this. The best advice I've found is a 9 years old blog post by Derek Yu [1]: "Treat finishing things as a skill rather than a step in the process".

We all have different skills, we can be good at programming or at graphic design or at music composition or at communication. Having these skills give you advantage, but you have to remember that at some point you didn't have those skill, those were cultivated. If you treat finishing things as a skill that has to be cultivated, where you suck at first, but with enough practice you get better and better, then you get into a mindset that will allow you to be more and more disciplined. So start small, take smaller projects, as small as possible. Make sure you finish them, slowly increase the difficulty level, you will get there.

[1] https://makegames.tumblr.com/post/1136623767/finishing-a-gam...

ceronman··on Case Study: Monolithic Repository at Google (2018) [pdf]
That's interesting. In my experience, one of the major advantages of a monorepo is precisely CI. In fact, only after we tried a Monorepo we finally experienced true CI.

An example to illustrate this: You have a library X that depends on Library Y and application A that depends on X. Then when you make a change in Lib Y you want to make sure that the change doesn't break X or A. If A, X and Y live all in separate repositories with separate CI pipelines, then this is hard/cumbersome to solve. In a Mono-repo, if you use a build system like Bazel, it's very easy.

I believe when you say that your Jenkins setup is a mess, we experience a similar situation with GitLab CI. But I think it's important to realize that CI stands for "Continuous Integration". And running pipelines for every individual repository is not really testing integration, it's just testing an individual component. The solution is to use Bazel or similar. Then you will have proper CI.

ceronman··on 38% of bugs at Airbnb could have been prevented by using types
> - developers that don't think specifying types is helpful are still early in their careers (those who suffered in the dungeons of Java get some slack)

Developers who believe specifying types doesn't have any drawbacks are still early in their careers :D

ceronman··on 38% of bugs at Airbnb could have been prevented by using types
> "extensive" unit testing is a poor man's type checker

Wow! No!

If this is what you feel, you might have been doing unit testing wrong the whole time! Unit testing is a powerful technique that is useful regardless of your language. the first unit testing libraries and frameworks started with Statically Typed languages.

ceronman··on When FP? And When OOP? (2013)
I love how Reagent works and I do think it makes interactive applications simpler and easier to reason about.

That said, I think FP still has one disadvantage which is performance. This is because the underlying computer is 100% imperative and there are still a lot of work to make FP patterns efficient.

FP works well for interactive UIs because the number of objects that change in GUI is very small, so performance is not an issue. But take a video game, for example, then you have thousands of moving objects that are updated at 60FPS. Once you get that you notice is really hard to write the logic as a set of immutable state changes, object allocation becomes a bottleneck and then you discover that OO is more suitable, at least for now. Maybe later there will be ways to efficiently translate the FP patterns into the imperative CPU models.

ceronman··on Monorepo: please do
I work at a large organization (2000+ devs). We have used both a Monorepo and Polyrepo. After some extensive experience with both models my conclusion is that the Monorepo is by far a superior model, specially for a large organization.

Of course the Monorepo is not free of downsides, those mentioned in the original article are real, although a bit exaggerated in my opinion. VCS operations can be slow and scaling a VCS system is challenging, but possible. And the risk of high coupling and a tangled architecture is also very real if you don't use a dependency management system like Bazel/Buck/Pants.

But in my opinion the downsides of the Polyrepo are much worse and much much harder to fix. The main problem is that you need a parallel version control system like SemVer on top of your VCS. SemVer is fine for open source projects but for a dynamic organization is a nightmare because it is a manual process prone to failure. SemVer dependency hell is really hard to deal with and creates a lot of technical debt.

Additionally, once you go Polyrepo you lose true CI/CD. Yes, you still have CI/CD pipelines but those apply only to a fraction of the code. Once you get used to run `bazel test` and you know you will run every single test of any piece of code that could depend on the code you just changed, you never want to go back. Yes, you could have true CI/CD with Polyrepos, but it requires a lot of work and writing a lot of tooling that does not exist in the wild. It is cheaper to invest in scaling your VCS in a multi-repo.

ceronman··on Monorepo: please do
A star pattern still has most of the downsides of the multirepo approach. Specifically, it has the problem of needing a parallel version control (e.g. SemVer) on top of your individual repositories. This creates fragmentation, where different applications have dependencies on different versions of the libraries which ends up in dependency hell, technical debt, and CI hell.
ceronman··on Monorepo: please do
It's actually the other way around. The cost of dealing with all the downsides multiple version control systems is way higher than investing in tooling for the Mono-Repo. This is mentioned in articles by Facebook and Google.
ceronman··on Reasons Python Sucks
"There are only two kinds of languages: the ones people complain about and the ones nobody uses." -- Bjarne Stroustrup
ceronman··on Rust Analyzer in 2018 and 2019
To better understand why this project is trying to re-implement the compiler frontend, I really recommend this video from Anders Hejlsberg (creator of C# and TypeScript) explaining how modern compiler construction oriented towards IDE works:

https://www.youtube.com/watch?v=wSdV1M7n4gQ

ceronman··on Functional core, imperative shell (2012)
This is the same principle of the Clean Architecture. I like how Brandon Rhodes explain how to apply it in Python:

https://www.youtube.com/watch?v=DJtef410XaM

ceronman··on How true hackers write JavaScript
I don't know if the author is experienced or not. But something I do know, is that the more experience I get, the more I fear dependencies and the more I value simplicity.

HN is a simple website. I'm glad that they decided to keep the code simple as well. I love the fact that the code almost fits in a single screen. Zero dependencies. You can understand the entire code in a few minutes.

I think new developers greatly underestimate the negative impact of dependencies. Today, something like create-react-app downloads hundreds of megabytes of dependencies. Libraries, transpilers, compiler extensions, and various tooling. Of course all those things come with many advantages, but what most people miss is the huge cost of all that. The increased complexity introduced by dependencies. The unnecessary bloat.

Sure, the way you name your variables have an impact on readability. But it's nothing compared to adding thousands of dependencies to your project.

ceronman··on Guide to Data Classes in Python 3.7
If you need Python 2.7 support after 2020, consider asking a consulting company to provide it for you.

Python is maintained by volunteers. Providing support for more than 10 years is more than enough in my opinion. The community has moved on to 3, but I'm sure there will be companies doing consulting and fixing 2.x bugs for a fee.

ceronman··on John Carmack: My Steve Jobs Stories
A question from someone who has never seen a NeXT computer:

How is it possible that Doom was developed on NeXT?

As far as I know, Doom was first released for MS-DOS. Wouldn't be really hard to develop a MS-DOS game from another operative system and another CPU architecture? Specially at the time without engines abstracting platform details?

ceronman··on Python 2 will be replaced with Python 3 in the next RHEL major release
One mistake was providing 2to3 as a migration path. This required projects to move completely from 2 to 3, for libraries it meant that they had to either stop supporting 2 (which were the majority of their users) or forking and maintaining both versions. The remedy was to make it possible for libraries to be both 2.7 and 3.x compatible, using tools such as six.py and making some changes to 3.x to make it more compatible with 2 (e.g. adding u'' strings).
ceronman··on Python 2 will be replaced with Python 3 in the next RHEL major release
What do you mean by double standard? Everyone in the community, including the core developers, acknowledge that the 2 to 3 story was full of mistakes. They have promised not to make it again. And they took some actions to remedy the problems, and that's why Python 3 is finally succeeding.

I recommend this presentation by Victor Stinner at FOSDEM 2018 which talks about it: https://fosdem.org/2018/schedule/event/python3/

ceronman··on Python Idioms in Rust
Python had the primitives of functional programming since its conception. Those are not exclusive of pure FP languages.

Some particular names used in the examples were introduced by Python. For example the `enumerate` function or `zip`. I haven't seen those names used in programming languages older than Python, I know I might wrong. The point is that it's not crazy to believe that Rust design does borrow some things from Python (among other languages of course).

The article is comparing some particular Python idioms with Rust. The fact that those are functional I think is not particularly relevant. It's like someone seeing a comparison of Java and Go and saying that those are just the principles of imperative programming, or object oriented programming.

ceronman··on JDK 10: General Availability
'var' in C# and Java doesn't change strong or static typing at all. It's just type inference. Your code is still statically typed, the compiler and IDE will catch errors. It's just that it's smart enough to infer the types of redundant things instead of making you type it.

So instead of typing:

  AbstractConcreteFactoryFactory factory = new AbstractConcreteFactoryFactory();
You can just type it only once:

  var factory = new AbstractConcreteFactoryFactory();
ceronman··on Java call stack – from HTTP upto JDBC as a picture (2006)
Just to clarify, I am not criticizing the Java language. I'm criticising the use of excessive layered frameworks that increase complexity.

I like Java. It's simple and performant and has excellent tooling. I just don't like that sometimes I see a lot of incidental complexity in its ecosystem.

ceronman··on Java call stack – from HTTP upto JDBC as a picture (2006)
Thanks for sharing your experience. I have worked in both kind of projects. Both very big and heavy based in database access. One using Hibernate and one using plain SQL. We've had considerably more problems with the added complexity of Hibernate.

Hibernate does not save you from writing queries. You are still writing queries, just in a language different than SQL (e.g. JPA). It's an abstraction layer. The problem is that this abstraction is very leaky, so if you really want to write performant code with Hibernate you do need to understand how SQL and your database works. And if you really understand how it works, you end up realizing that the abstraction is kinda pointless because SQL is already a really fine abstraction over your database.

And if you need to scale, for example working with a replication setup with multiple db servers and having to deal with eventual consistency, then Hibernate really complicates things.

I think Hibernate is a good example of something that makes things easier at the beginning. At the cost of enormous complexity and difficulty in the long term.

ceronman··on Java call stack – from HTTP upto JDBC as a picture (2006)
This looks like the perfect example to illustrate the point that Rich Hickey tries to make in "Simple made easy" [1].

This huge call stack has been designed to make your life as a developer easy but the price you pay is an enormous amount of complexity.

I've been working a lot with a similar Java web stack and I feel how painful this complexity is. What is worse, is that I think that a lot of this complexity is incidental. There are libraries and frameworks designed to make some things easier, but in the process end up creating a lot of problems that then requires another library or framework to overcome that problem which also has other problems and so on... The result is a huge stack like this.

One concrete example of this is Hibernate. A tool designed to make it easier (apparently) to work with databases, but in the end create so many problems that the medicine ends up being much worse than the disease.

Resolving an HTTP request that returns a the result of a database call should not be this complicated! HTTP is simple! Why do we need so many calls to so many things. I'm not advocating for a flat stack of course, but certainly a stack this deep is a clear sign that something is wrong.

I very much agree with Rich Hickey, we need to stop thinking about how to make things easier and start thinking how to make them simpler.

[1] https://www.infoq.com/presentations/Simple-Made-Easy

ceronman··on Python 2.7 Countdown
I can see a company providing 2.7 support afterwards. I'm not sure if RedHat, but if there is demand, I totally see 2.7 support as a viable business, at least for awhile.

I think it's unlikely that the community will bring support. Most of the community already jumped to 3.x, and those who haven't will do in the next two years. Also, supporting legacy code is not something that volunteers love to do.

ceronman··on What MongoDB got right (2015)
I'm not convinced about the point of structured operation format.

I agree that manually building SQL strings can be cumbersome. But in practice you can use libraries that allow you to easily create them programmatically.

The JSON queries of MongoDB on the other hand, while they are simple to use programmatically, they are a pain to use outside of your program, for example for running ad-hoc queries, or generating a report from your data. And there is no library to fix this.

ceronman··on Perl and Undecidability (2008)
Perl is a very practical language. But this practicality has been achieved by building features on top of bad design. The result is a big, complex and quirky language. To make this worse, the community decided to "fix" this re designing the whole language from scratch. They created Perl 6 which has a much better design, but it's incompatible. The community now it's broken in two and the future doesn't look that good.
← PreviousPage 4 of 9Next →