HNHacker News
TopNewBestAskShowJobs

amzans

2,840 karma · joined August 9, 2016

submissionscomments
amzans··on I Don't Want to Be a Founder
Thanks for the inspiring story. I’m guessing that the 25K€ probably referrers to a GmbH in Germany :)

If so, would you say the GmbH/UG (Limited Liability Company) route is a good idea from the start for a solo founder of a bootstrapped SaaS?

I’ve been doing my research and maybe I’m wrong, but it seems like it has quite a lot of overhead for a first time solo founder like myself.

To clarify, I’m an expat in Germany, but I’ve even looked into setting up an LLC in the US or another limited entity because they appear more lightweight to operate than their counterparts in Germany. But then I end up in a complicated international tax situation.

I’m not seeking legal advice, just wondering if you have any tips now that you’ve gone that path several times successfully.

Cheers!

amzans··on Show HN: Timeflake, 128-bit roughly-ordered UUIDs
Hi everyone! Just wanted to mention the use case for this:

1) You want to have UUIDs in URLs that are not predictable (vs auto-increment integers).

2) So they should be random, but roughly-ordered over time so that your MySQL/Postgres indices stay fast and efficient as the dataset grows.

3) And simple to use across multiple machines (no coordination or centralized system required to generate).

4) It would be nice if they were compatible with standard 128-bit UUID representations (many libraries in Python handle uuid.UUID, but no third-party types).

Checkout the "Why?" section in the readme for a comparison to some of the alternatives.

Also if you don't want to have to use this library:

  import os
  import uuid
  import time

  timestamp = int(time.time() * 1000)
  randomness = int.from_bytes(os.urandom(10), byteorder='big', signed=False)
  value = ((timestamp << 80) | randomness).to_bytes(16, byteorder='big')

  uuid.UUID(bytes=value)  
  >>> UUID('016fd379-198f-3327-2bf0-d2a0f5d863d7')

Feel free to ask me anything.
amzans··on Ask HN: Who is hiring? (January 2020)
Stylight | Backend Engineer | Munich, Germany | Onsite | Visa Sponsorship

Stylight is hiring! We’re looking for a Backend Engineer to join our team and work on search and ranking for 30+ million partner products.

Our tech stack includes: Scala, Spark, Python, Airflow, BigQuery, Kubernetes, Elasticsearch, Athena.

Our search API is written in Scala (Finatra & Finagle), as well as our data ingestion systems. We also use Python extensively across our data pipelines and for some microservices.

I'm one of the developers on the team, if you're interested feel free to reach out to me!

https://about.stylight.com/backend-engineer-d-f-m

amzans··on Things I Learnt from a Senior Software Engineer
> Good engineers themselves design systems that are more robust and easier to understand by others. This has a multiplier effect, letting their colleagues build upon their work much more quickly and reliably - How to Build Good Software

The advice above is probably one of the things which would have the most impact across all your activities as a developer. When people talk about simplicity in software, they don’t necessarily refer to ease of use or number of lines of code, but instead it’s about how understandable a solution is given their shared knowledge.

amzans··on Show HN: Bild – A collection of parallel image processing algorithms in Go
Hey! I just added some basic benchmark numbers in case it's useful: https://raw.githubusercontent.com/anthonynsimon/bild/master/...

This will hopefully also make performance regressions over time a bit more visible.

amzans··on Scala 2.13 is now available
I work at a major online fashion aggregator and my team uses Scala extensively for our search API (with Twitter's Finatra) and also in several of our data pipeline systems (Akka, Spark).

When I joined a few years ago, I was honestly not most excited about working with Scala, but the more I got into it, the more I realised that Scala got a lot of things just right.

In particular, I really miss working with the collections and futures API whenever I switch to another language.

And it's overall a pretty good package: very predictable behaviour, easy to debug (IntelliJ Idea helps a lot here), fast runtime and high quality libraries available for pretty much anything you might need.

amzans··on When to Use TypeScript – A Detailed Guide Through Common Scenarios
You might be right and maybe there is some bias in the projects which I chose to think of. Certainly there are many projects that don't require the same amount of thought from day one.

What I'm referring to in my previous comment is when people underestimate the complexity added by the easy and quick solution today vs the high cost over time. Specially in critical projects.

amzans··on When to Use TypeScript – A Detailed Guide Through Common Scenarios
I couldn't agree more with you on this.

I often see good, actually simple solutions get turned down due to people saying "that's too complicated for what we need", only to later hear, after a couple of months in production, that nobody wants to touch the codebase anymore since it's unapproachable and the rewrite will not happen due to high risk since it's critical production code now.

amzans··on Traduora is now open source
I've just added basic support for importing and exporting gettext files. If you end up trying it out let me know how did it go :)
amzans··on Traduora is now open source
Thank you for the feedback. After a lot of thought I finally settled on AGPLv3 because it makes it easy for the users to use and benefit from any improvements developed by others.

I feel that it's the right way to do it. But I guess that only time will tell.

amzans··on Traduora is now open source
While traduora is also aimed at the use case you describe, the focus is on enabling small and medium teams to easily translate their projects without much overhead.

For example via automatic translations of your project or delivering translation updates over the air.

amzans··on Traduora is now open source
I think Pootle is a great project with a (much) longer history than traduora and it's very rich in terms of editing features.

While traduora will have a lot of commonly used editing features, I'd like the focus to be on enabling small and medium teams to easily translate their projects without much overhead. That's where upcoming features like automatic translations come in handy as they provide a good "starting point" for a lot of cases or also for example the ability to deliver translations over the air to your apps/websites.

I'm convinced that in open sourcing traduora, it’s an effective way to make the best product possible, while growing a community and giving developers confidence to build on top of it as a platform.

amzans··on Is Rails still relevant in 2018?
I've been interested in trying out Nest too. While I've just been toying around with it, it seems to strike a nice balance between fast to write and easy to scale (in terms of growing the codebase). Hopefully then the path from MVP -> full product becomes smoother.

It also makes good use of what Typescript has to offer, which IMO is very much welcomed.

amzans··on The U.S. Air Force learned to code and saved the Pentagon millions
I don’t know about the rest of Europe, but here in Germany people have openly talked about their salary with me in several occasions. Granted, it wasn’t any coworkers, it was always a friend or someone I knew.
amzans··on From Java to Go, and Back Again (2016)
What do you mean by "warn-up much faster"? Go doesn't have a JIT compiler so not sure what you need to warm up?
amzans··on Berlin-Munich high-speed train services carry 2M passengers in first six months
As a frequent Berlin-Munich traveller, it’s such a joy to now be able to make this route in less than 4 hours directly from and to the city center.

Last month I had to instead take a flight (direct ~1h) but it ended up being more stressful and pretty much taking the same time since you have to add the time it takes to get to the airport and go through security.

Not to mention that the trains are quite comfortable and there’s lot of room to walk or even sit down at the on board bistro for a beer or some food.

amzans··on Elixir at PagerDuty
Yet case classes with pattern matching and pure functions leads to some of the most readable code I’ve seen, without requiring much FP knowledge. Unlike OOP in which the logic is hidden away in some AbstractVisitorBuilderFactory and a sea of required classes to make that work.

Things can get rough when you take FP or OOP to their logical ends, the sweet spot lies somewhere in between.

amzans··on TypeScript 2.9 is now available
I understand the problem with that, and agree with you.

While it can be very empowering to have a "sandbox" language, when it comes to shipping features and working in a team setting, it can require a lot of discipline to keep the codebase approachable for others. Languages like Go or even Python seem to help a lot in there by having strong conventions and an "obvious" way to do things.

amzans··on TypeScript 2.9 is now available
IMO Scala has a lot of very well thought out features that complement each other, and this is only going to get better with the move towards Dotty.

For me it feels not as bloated as other languages which added features without thinking about how they fit to the existing ones. But I work a lot on Scala, so I'm probably biased since I know the language better than i.e. Typescript :)

amzans··on Go Is a Shop-built Jig (2014)
Edit: I had used a quote from the blog post as the title, but updated it to match the blog post as I realised it was a mistake.

The original title was: "Go feels under-engineered because it only solves real problems".

amzans··on Managing Multiple Python Versions with Pyenv
It isn't necessarily about solving a problem that we had with virtualenv. For us it was already working quite well. It just simplified a few things for us. Like isolating Python versions, and also made the process of downloading and installing multiple Python versions easier.
amzans··on Managing Multiple Python Versions with Pyenv
I've recently had great success at work in switching from virtualenv to pyenv + pyenv-virtualenv. It makes it much easier to reason about your Python installations and it helps in keeping the system Python (MacOS) from interfering.
amzans··on Leveraging the type system to avoid mistakes
We don’t do it for every type, instead on a case by case basis. IDs are usually the obvious ones since we might have a Product class with fields like ProductId, BrandId, List[TagId], SellerId, etc... and it’d be nice to not mess that up.

Another example is if you have some pricing info you could group it in a case class like:

  case class PriceInfo(price: BigDecimal, discount: BigDecimal, currency: Currency)
And then put that into your product class:

  case class Product(id: ProductId, price: PriceInfo, ...)
The nice thing about this is that all these related fields can be dealt with in context, i.e. if a function accepts a PriceInfo then it now has access to the price itself and the currency. Not to mention that a price without currency in an e-commerce app can be quite ambiguous.
amzans··on Leveraging the type system to avoid mistakes
Usually you would lookup the definition of those types just as you do for the function that you are trying to call. At least it’s a good idea to know what a function accepts before passing around your customer IDs ;)

And to answer your last question, yes in Scala you can use named parameters like in your example.

amzans··on Leveraging the type system to avoid mistakes
The problem with named parameters is that you can theoretically still pass the wrong value, and in practice not everyone is using named parameters on every function call.

By relying on the type system you can catch that issue at compile time and not have to worry about it.

We use this technique at work when there’s lots of fields in our data types as it’s nice to be able to keep track of the types during all the transformations and to avoid subtle bugs. Specially as the codebase is constantly changing.

amzans··on Leveraging the type system to avoid mistakes
Something that I enjoy very much in Scala is sealed traits + case classes.

  sealed trait Food
  case class FishTaco(size: FishSize) extends Food
  case class Burger(numPatties: Int) extends Food
  case class Spaghetti(sauce: PastaSauce) extends Food

It’s like Enums + Data Classes on steroids. You can pass around and transform your data as usual, but if you forgot to handle a specific case when doing pattern matching you’ll get a compile warning. For example in the following case:

  input match {
    case Burger(patties) => ...
    case Spaghetti(sauce) => ...
  }
The compiler will happily yell at you something like:

  warning: match may not be exhaustive.
  It would fail on the following input: FishTaco(_)

Little things such as this one help reasoning about your program since you can rely on the types describing what is possible and what is not.
amzans··on Software Testing Anti-patterns
Your point of view resonates with me.

Over the years, I've learned to test "what a thing is supposed to do, not how it does it". Usually this would mean to write high level tests or at least to draft up what using the API might end up looking like (be it a REST API or just a library).

This approach comes with the benefit that you can focus on designing a nice to use and modular API without worrying on how to solve it from the start. And it tends to produce designs with less leaky abstractions.

Of course YMMV.

amzans··on Akka Streams: A Motivating Example
I can very much relate to the pain points and benefits mentioned in the example.

Last year we had a project in which we had to take a stream of data that needed to be verified with several calls to an external system before being partitioned, transformed and inserted in batches to a relational DB. The system processes ~100 million messages per day (message length is ~1.5 KB) on 2 nodes each with 4 cores and 16 GB memory.

We built the routing and partitioning logic using Akka cluster since we wanted to have consistent hashing as we scale the number of stream workers horizontally. Initially, the stream processing was also done via Actors, which are a fantastic concurrency tool, but we soon found ourselves reimplementing a lot of the features mentioned in the article and needed to handle backpressure between each of the steps since the rates at which the producers put data into the system often burst for short periods of time. Last but not least, we suddenly had a huge amount of non-business logic that needed to be tested and maintained.

At some point we decided to rewrite the stream processing part to make use of Akka streams. I have to admit that I was initially skeptical given that no one on the team had previously worked with it and since some of us already had experience with Apache Spark, which could also be used to process the data.

Long story short, it was a breeze to rewrite as it consisted mainly of removing the non-business code and using the Akka streams stages to handle the batching, rate limiting and end to end backpressure for us. And similarly satisfying, our codebase was much smaller and readable.

Soon we will begin work on another project of similar nature, and while we are considering a couple of alternatives depending on the final requirements, Akka streams is definitely on the top of the list for us.

amzans··on Simplistic programming is underrated
The main advantage that I’ve seen when writing and reading functional instead of procedural/imperative code, is that the intention is usually clear.

We have a list of numbers that we want to square and add up, instead of the more mechanical steps with the loop approach.

amzans··on Show HN: Bt – BitTorrent library in Java 8
It's great to see projects like this on HN. Congrats man, well done!
← PreviousPage 4 of 5Next →