HN user

cutety

131 karma
Posts0
Comments61
View on HN
No posts found.

Also, unfamiliar with PHP, but a few years ago I somehow ended up maintaining/managing one or two reasonably trafficked Wordpress sites that some (untechnical) friends put together, so every now again I get to learn how weird some shit in PHP is. And it’s that time again, because the comment about name conflicts was confusing as I could’ve sworn that during couple times I’ve had to actually poke around PHP code I saw it had namespaces. After some quick googling though, I was able to confirm a) PHP has “namespaces” and b) they seem to work like most other “features” (i.e. not like you’d expect if you’ve programmed in anything but PHP) [1].

However, C has the a similar convention [2] (though the convention is — as far as I’m aware — for the sake of maintainability/readability as the compiler has no problem telling the difference between to things named the same, the person reading it probably will. While, as I understand it, PHP will just overwrite anything with the same name in the file/lib you include).

It seems like PHP is heading in the right direction, but I have no idea why anyone would pick it up or start anything new with it these days, I don’t care how well done and the nice and new stuff is, it’s the decade of utter mess it’s built on top of that has uninterested me. Don’t get me wrong, since “acquiring” the Wordpress sites I’ve gone from a blind PHP hater, to at least understanding/appreciating it (but still won’t actually touch it with a 10ft pole). PHP is brain dead easy to deploy and scale up, compared to ruby/python/node (which aren’t _that_ difficult to deploy), PHP is basically the web equivalent of a static binary, in that you can just drop in and it’s basically ready to go. PHP also actually really fast, it’s seriously impressive how fast it can render WP pages especially when you consider the absolute spaghetti/thrown together/clusterfuck code it’s running — Wordpress itself is pretty yikes from the code I’ve seen, but the plugins, Christ, the 50 million sloppy buggy poorly coded plugins — PHP can absolutely run laps around other a decently coded site in other languages (at the cost of having to use PHP I guess ).

[1] https://kornel.ski/en/phpns

[2] https://softwareengineering.stackexchange.com/q/404613

Regarding portability, I recently came across this project: https://github.com/spawnfest/bakeware

I haven’t gotten around to actually trying it myself, but it advertises that it can compile Elixir projects into a single binary you can copy, paste & run (on Linux & MacOS). It’s not the greatest solution, and the mentioned ~0.5s startup time doesn’t make it great for cli tools when compared to Go/Rust/C.

I’m mostly just happy to see there are people out there trying to make Elixir/Erlang easier to use, as much as I love the language, some of the tooling and deployment methods (releases) make me groan.

My favorite “console wars” story that I came across a while back, and is relevant to pricing advantage, is when Sony more-or-less immediately killed the Sega Saturn before it’s US release.

Right after Sega’s E3 presentation announcing the Saturn, US release date, and it’s $399 price tag, it was Sony’s turn. The guy from Sony walked up to the mic, said “$299”, and walked off stage. [1]

[1] https://youtu.be/ExaAYIKsDBI

I hate to sound elitist or whatever, but I’m just tired of seeing a blog title something about writing a scalable or “enterprise” web app and the content almost always being “write modular code, write comprehensive tests, and don’t write spaghetti code though usually through the veil of domain drive design jargon (whether or not they don’t use the term DDD or they are literally quoting Dr Bob blog posts and including vague graphics showing the “boundaries”). But, any decent developer will literally come to the same realizations after spending a significant amount on anything that’s not a toy/pet project. I also get that not everyone has had that realization and this blog may be insightful/helpful to them, it’s just not the content I was hoping to come across as it’s something I’m very interesting to hear what others are doing.

I’m not going to pretend I’m some hardass enterprise engineer, but my only time spent on frontend work these days are on two different applications that solely exist because the actual enterprise software sucked so much that these applications exist. So, I like to think I at least have an idea. As over the years the features have been added to the apps, and more of the “fun little quirks” in the data. Which is why I want to hear how real “enterprise” level frontends are being handled. Believe me, I know the value of keeping my code modular, and I really know the value of keeping logic out of presentation, but if working with enterprise software, and software that’s deployed to 30+ different departments to standardize and centralize processes they’ve been doing themselves for 50+ years (under the guise of “making their jobs easier” but really they central office where just tired of having to deal with the random of assortment and varying quality of data, lol) there’s always another edge case. I cringed when they mentioned that using one of the big frameworks, and forgoing global styles, because after a couple years of “the frameworks built in css isn’t totally the way we need it” (or more likely, “fucking updates broke the UI on a minor release for no reason”) or “oh using the current components we use to do that don’t take data that way or return it the way we need either, and it’d take too long to replace, just create a new set for this feature” it’s not going to be the nice paradise where everything is siloed off just like in Uncle Bob’s blog. I just this week got sick of UI framework’s because the built in component I needed wasn’t able to handle the task in the exact right way, so I had to make adjustments to it, and I’m just that’s never going to break in the future... not to mention that absolutely none of them are really doing any more than the bear minimum accessibility wise, which is one of the reasons to use a framework was to eliminate that boilerplate. So, I just started tinkering with the new Vue3 composition API to build a UI framework that literally has no styles attached just dom elements that know how to setup their aria-attributes, handle keyboard events so a mouse isn’t the only method, etc (as well as if they weren’t passed given enough information to make themselves complaint with the aria guidelines). To style them, I’m just going to make pass in a list of tailwind classes in a config files at build time, that they can (optionally) but will in no way the actual core framework itself is dependent on.

I just want to hear how some real enterprise team are managing their frontend (and more importantly their commentary — I can find code online but without the context it’s not the same) when they have 100x the amount of edgecase legacy bullshit I have to deal with and likely 1000x the burden of buroqracey

This reminded me of a question I’ve had, which is only tangentially related, but I’m hoping I’ll be able to get pointed in the right direction or told that the idea is stupid either is fine.

Login/Auth is one of the few areas that I have always just used whatever the standard library is for the platform because I don’t want to fuck it up, so I just have always gone with the tried and true sign in form -> server side sessions. I didn’t do anything more “advanced” until I started at the university I’ve worked out for a couple years now, and that’s still just been a SAML(?) request flow with our SSO (ugh) Shibboleth. If you’re lucky enough to be unfamiliar with Shib, it’s not that great, it does the job, but just barely while simultaneously holding our infrastructure hostage. I think SSO is great, but Shib (in our current architecture, and in my — potentially ignorant — opinion) is unnecessarily limiting while providing no real benefit. I’ve had an idea floating around in my head that could make it useful/less restrictive, since it’s not going to go away in lieu of something more modern, but I’m not sure if it makes sense/is secure/whatever. So, here’s my current issues with it.

Every web application that needs to use SSO at the university has to first send a request to the centralized authentication team — which consists solely of the creator of Shibboleth — this request is almost always sent back within 5 minutes with some condescending/snarky remark about how something wasn’t filled out correct, while also giving you the correction to be made, and told to submit it again (instead of just not being a dick and correcting it himself). Dealing with his shit attitude once a year or two l, I could handle, but my team is currently responsible for like 20-30 apps using SSO, and usually have to do this dance every at least once 2-3 months.

Once that’s over with and the app’s host name is now setup with the central idp. However, to utilize the idp, the app server requires the Shib service provider to execute the callback flow. Once again, wouldn’t be that awful if it weren’t for the fact that the Shib SP only officially supports 2 web servers Apache HTTPD and (I think) Tomcat or Jetty. An unofficial nginx plugin for Shib exists, but because we are “lucky” enough to have the Shib creator be the sole dictator of the SSO service, and nginx does not have his blessing (because fuck you, that’s why). Once again! I could deal with Apache, I prefer nginx, but ok I never have to actually manage Apache’s configs so it wouldn’t an issue, but it requires a version of Apache that doesn’t support shit like websockets.

However, what really makes it un enjoyable, is when it passes back the user auth info, it ACCORDING TO THE DOCS, should also include some additional data like the affiliations the user has, what departments they belong to, etc. What actually happens is outside of the users uid, it only reliably will give you their primary affiliation (staff/student/faculty) but not any others they may have. On the off chance you get the departments they belong to, they’re actually just numbers that correspond to a department — not the id commonly used by anything else which would be annoying but useful still — these numbers are seemingly only used by it, and nobody seems to have the full mapping(???). There’s a list of other useful attributes it supposed to return but nobody has ever seen it happen, lol. So now if an app wants to restrict itself to just certain departments/affiliations, it has to now check with another api or have that data piped into its DB from the central data store daily, to be able to do that. Among other things like not supporting sign out without jumping through hoops for every app that decides to let users sign out with a button, confusing documentation, and mountains of XML. It’s sucks.

My idea is to consolidate it into a single auth service for all my teams apps, as we’d just have to make on last request for the auth service host name, and it’d be the only one required to use Apache. Basically serve as a middle man, to pass requests to the idp, then lookup the data that’s supposed to be there from Shib, and provide that back to the app in one swoop. Is this reasonable? What’s the best approach to managing the Shib session? As it will set a cookie for the auth service host, not the app host, so I have thought about sticking the Shib session into the auth service session data to prevent the same user automatically getting authorized if they use another of our apps they may not have access to (i.e. I want don’t want the Shib session to work across app domains if a user has a session in one app and not the other). Almost every other week I feel there is an article about rolling auth wrong, so I just haven’t wanted to bother with it. So is my idea stupid? Is this an actual appropriate use for JWTs to store the Shib session id in while the auth service still will use cookies (with that JWT inside or an id to lookup that JWT)? Or should I use OAuth here? I can’t find any information that definitively describes my situation anyway, and every other article I read about setting up auth flows contradicts the one before it, or just says let the experts handle it or whatever, which unfortunately they apparently have been and the experience as dev sucks. Any information would be greatly appreciated, or just a definitive “it’s a stupid idea” would be appreciated as well so I can stop thinking about a world where I can use NGINX at work.

I’m still runnin a 2012 (non retina) without any issues, and I plan on keeping it until it literally won’t boot. What’s funny is I was initially annoyed as I got it a few weeks before they announced they were releasing the first Retina display models (discontinuing the non retinas), however getting the last non-retina generation was a blessing because that’s was that was when they also began making upgrading MacBooks nearly impossible (non upgradable ram/and I believe some weird half SSD/half disc drive that didn’t come in >512GB or something like that). So getting the last (upgradable) MacBook Pro was the better deal because two or so years ago I upgraded the RAM to 32GB and because it was also the last MacBook to have a CD drive (that I never used) I was able to rip it out, put a $5 hardrive bracket in it’s place and threw the original (I think) 750GB or whatever HDD where the CD drive used to go, and popped in a nice 1TB SSD into the main disc drive, and nowadays it’s almost always plugged into a monitor so I wouldn’t really even be using the retina anyway.

Sadly though, I think I got the last generation of great MacBooks, and as much as I love it I fear for the day it finally dies, because I’m probably not getting another MacBook unless something changes, and there still isn’t a laptop out there that comes close to the good MacBooks (I know good one’s exist and I’ll manage, but they’re still not the same)

Elixir v1.10 6 years ago

I've only had 2 complaints with gen_statem, the docs were initially some of the most confusing/unclear and the state_functions callback mode (which I think partially is to blame for my first complaint as I was expecting a more gen_server like api with handle_* functions -- which exists but the docs use the state_functions for most of the examples and the handle_event just kinda getting some "oh by the way this exists" examples). I actually initially decided to just keep using gen_server's with a "status" or whatever value in their state as I figured it was good enough. At some point over the next few weeks I actually ended up having this talk[1] pop up in the recommend videos, and I figured I give it a watch to see if it would help make sense of gen_statem or at least just confirm that I don't need it. And while watching it, once he started explaining actions (timeouts, state_timeouts, postponing, etc) I realized that gen_statem literally solves so many problems that I've had in the back of my mind on the project I was working on like "I should figure out a way to change the state of A and do something when it doesn't receive any messages from X,Y,Z processes" (gen_statem's timeouts!) or "how should I handle messages received while attempting to recover, I guess I could put them in a queue or something..." (oh, gen_statem will let me postpone them until it's healthy!). It took a couple more re-readthroughs of the docs to fully grasp, but now it gets included in almost everything I work on, it's so useful (though I guess I should've assumed those were already solved problems by the BEAM/OTP as usual).

However, now my biggest complaint about Elixir is that gen_statem didn't get any official wrapper. StateServer looks like almost exactly what I would want out of an official Elixir wrapper. I also like to see the addition of `handle_continue` as well, because the first thing I did before migrating any of the gen_server's to gen_statem's was create a small wrapper module to a) make the handle_* return values more in like with GenServer's (basically just making it {:(no)reply, (transition|keep), data, [actions]}) and b) add a quick and dirty handle_continue callback because I use it all the time with GenServer. And this literally just looks like a more polished version of that, so thanks!

[1] https://www.youtube.com/watch?v=_4MTIffWhYI

Elixir v1.10 6 years ago

Definitely agree, though I respect the effort/desire to learn Erlang first given the fact the first time I saw Erlang code I was so confused/put off by it, the syntax was so foreign (not c-like, not lispy), variable names up capitalized, atoms are bare words, source files are just tons of functions, the tooling isn’t anything like modern languages (though since Elixir and hex/mix, that situation has gotten way better), then you’ve got all the OTP behaviors which are entirely unique to Erlang/BEAM, Erlang’s documentation though excellent and extensive isn’t by any means beginner friendly (IMO), and to top it all off, unless you’re coming from another pure functional language you have to deal with working in a new paradigm. Basically, Erlang is intimidating, which is unfortunate because how powerful BEAM and the OTP behaviors are.

However, Elixir wraps up the power of the BEAM and OTP in a much more approachable package. The syntax is much more familiar (thanks Ruby), provides tooling on par with (and better than some) popular modern languages, the language itself also provides more modern user friendly features (macros, pipe operator, protocols, etc). All with a community that is very beginner friendly and willing to help.

If you want to make use of OTP/BEAM, Elixir is by far the best way to enter. When you learn Elixir, you will also learn the major OTP behaviors and concepts (Supervisors, GenServers, Applications, Registry). Eventually you’ll find that there are even more goodies in the beam not directly exposed by Elixir (genstatem, ets/dts/menisia,timer,digraph — are a few of my favorites). Fortunately though, you can call Erlang modules/code directly from Elixir (and vice-versa), so you’ll then eventually dip your way into playing with Erlang modules as needed and when you approach the docs after having experience with OTP with Elixir, you’ll notice a lot of things are familiar and the Erlang docs become much less intimidating.

Basically Elixir is a much easier entry point to Erlang. Erlang is a great language, but very different with a lot of new concepts and which can kill your motivation to learn how awesome the BEAM is, so if you want to learn Erlang, by all means give it ago, but if you find yourself frustrated/confused with it, try Elixir for a while, then come back to Erlang and I bet it will be a lot easier.

When I initially saw Erlang, I was put off, the docs were confusing and I would avoid them at all costs, always try to look for an Elixir wrapper. Now after having worked with Elixir a lot? I frequently find myself going to the Erlang docs first to find a solution instead rather than hex or whatever. I can easily grok my way through an Erlang projects source, which previously was completely foreign to me. Will I ever likely write anything serious in pure Erlang? Probably not. Am I saying if you learn Elixir you will also just pick up Erlang? Absolutely not. What it will do though is make the process of learning Erlang (if that’s the goal), and it’s absolutely massive built in library of tools/abstractions/patterns that no language I’ve seen comes close to replicating an order of magnitude easier.

Stream would technically better, however given the discussion is about Map/Reduce, the only thing Stream has in common with Map/Reduce is it's lazy. If you wanted something comparable (mapping is done in parallel, reducing as well just over partitions), then you'd want to use the Flow[1] library. As it does the same thing as Stream.map |> Enum.reduce just parallelized/partitioned, and what's great is the Flow module is more-or-less a drop in replacement for Enum/Stream (with a few caveats like calling Flow.partition before Flow.reduce). But, with just some quick a dirty benchmarks you can see Flow outperforms Stream on all but the smallest data set (range 1..100):

    with_stream = fn range ->
      range
      |> Stream.filter(&(rem(&1, 3) == 0))
      |> Stream.map(&(&1 * &1))
      |> Enum.reduce(0, &Kernel.+/2)
    end
    
    with_flow = fn range ->
      range
      |> Flow.from_enumerable()
      |> Flow.filter(&(rem(&1, 3) == 0))
      |> Flow.map(&(&1 * &1))
      |> Flow.partition()
      |> Flow.reduce(fn -> [0] end, fn val, [acc | _] ->
        [Kernel.+(val, acc)]
      end)
      |> Enum.sum()
    end
    
    iex(4)> Benchee.run(
    iex(4)>   %{"stream" => with_stream, "flow" => with_flow},
    iex(4)>   inputs: %{"small" => 1..100, "medium" => 1..10_000, "large" => 1..10_000_000}
    iex(4)> )
    Operating System: macOS
    CPU Information: Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
    Number of Available Cores: 4
    Available memory: 8 GB
    Elixir 1.9.4
    Erlang 22.2.1
    
    Benchmark suite executing with the following configuration:
    warmup: 2 s
    time: 5 s
    memory time: 0 ns
    parallel: 1
    inputs: large, medium, small
    Estimated total run time: 42 s
    
    Benchmarking flow with input large...
    Benchmarking flow with input medium...
    Benchmarking flow with input small...
    Benchmarking stream with input large...
    Benchmarking stream with input medium...
    Benchmarking stream with input small...
    
    ##### With input large #####
    Name             ips        average  deviation         median         99th %
    flow          0.0994        10.06 s     ±0.00%        10.06 s        10.06 s
    stream        0.0782        12.78 s     ±0.00%        12.78 s        12.78 s
    
    Comparison:
    flow          0.0994
    stream        0.0782 - 1.27x slower +2.72 s
    
    ##### With input medium #####
    Name             ips        average  deviation         median         99th %
    flow           83.87       11.92 ms    ±20.48%       11.30 ms       25.53 ms
    stream         74.88       13.35 ms    ±32.02%       12.32 ms       30.22 ms
    
    Comparison:
    flow           83.87
    stream         74.88 - 1.12x slower +1.43 ms
    
    ##### With input small #####
    Name             ips        average  deviation         median         99th %
    stream        4.98 K        0.20 ms    ±87.16%       0.169 ms        0.56 ms
    flow          0.70 K        1.42 ms    ±21.58%        1.35 ms        2.52 ms
    
    Comparison:
    stream        4.98 K
    flow          0.70 K - 7.06x slower +1.22 ms
[1] https://hexdocs.pm/flow/Flow.html

type out code

This is, in my opinion, probably the most important step that some may skip when learning out of a book. Sure, if you’re already familiar with the language and are using the book to learn concepts, feel free to skip this step, but when you’re learning a language absolutely type out and run the code alongside as you move through the text.

First you’ll have confirmation that your system is configured correctly and everything is installed.

Second you will make typos/copy things incorrectly, this will allow you to start getting familiar with the languages errors. And since you’ll have the (hopefully) correct code to compare to, you can easily find out what caused that error. I like to try to debug without looking back at the text first, but if I can’t figure out in 2-3 tries, I look.

Most importantly, by typing in and running everything, through the sheer amount of repetition you’ll start building up “muscle memory” for the general syntax patterns/idioms/workflow.

I love using books to learn new languages, and is usually the first route I go. I’ve tried learning a few new languages just by reading, then trying to build something, but I find without spending the time actually typing out the examples, when I go to build I constantly have to reference syntax/how to do x, and end up losing any motivation I had.

This may just be my bias against NoSQL (I’ll qualify this with I don’t believe it should never be used, but 90% of use cases psql/MySQL/etc is likely the better choice these days), but when it comes to choosing a DB engine when you want ACID transactions, I’d pick the one that was built to handle ACID transactions from the start, rather than one that just added it with this large caveat in the middle of the docs:

In most cases, multi-document transaction incurs a greater performance cost over single document writes, and the availability of multi-document transaction should not be a replacement for effective schema design. For many scenarios, the denormalized data model (embedded documents and arrays) will continue to be optimal for your data and use cases. That is, for many scenarios, modeling your data appropriately will minimize the need for multi-document transactions.

So, to be able to have one of the core features of SQL, you lose the biggest feature of NoSQL which is super fast writes. Which, they try to remind you that if you model your data in correctly, by creating denormalized documents with embedded data, you probably won’t need them anyway. Which just makes me cringe at having to maintain these huge unstructured documents just so you get faster writes since you don’t have to worry about ACID.

Or, you can use Postgres, which was built with ACID from the start, using technology and design patterns proven over decades, and has support for JSONB if you need unstructured/document storage that you can also (fairly) efficiently query.

Maybe I’m just woefully uninformed, but I just can’t imagine a use case for Mongo unless your dealing with Google level data/traffic, and fortunately in their case, they have enough money to hire enough people that actually know how & when to use Mongo effectively to the point that it’s not just a fancy way to write to /dev/null.

I’d actually be really interested in some non-Google scale use cases for Mongo, like where Postgres’ performance was actually an issue, and how much Mongo actually outperforms it, and the trade offs/issues switching. Most posts I’ve seen are of the opposite migration, but I want to see what all the hype for a DB engine (what I’ve always saw as one of the less _sexy_ areas of CS, at least in marketability, compared to ML/AI or Programing Language/Compilers)

The 2-4GB RAM isn’t a hard requirement in my experience. I initially had the whole Docker compose stack running on a single $5 DigitalOcean droplet, and didn’t experience any issues for personal usage. Since they also distribute it to you as Docker containers, you can also set resource limits, specifically for the MSSQL container, to prevent it from hogging all the RAM.

I currently have my Bitwarden instance hosted on my Docker swarm cluster, which is just 3 $5 DO droplets and 1 with like 2GB and RAM and 2vCPUs. But, a quick look shows that currently all the BW containers are running on the $5 ones. I have the MSSQL container’s RAM limited to 1GB as well.

As for the x86 requirement, that’s likely the case, I’m assuming you mentioned it because you’d like to run it on some ARM device like a RPi. I haven’t tried running their containers on an ARM device so I can’t say they’ll be compatible, but I know docker’s ARM compatibility has improved so maybe someone has got them running on some ARM device.

Would you be able to give an example or two where you would reach for go vs elixir and vice-versa?

I’ve tinkered with Go, and while it was fairly enjoyable to work with on the small scale, but the lack of generics and constant err != nil checks, and Go 2 on the horizon, I decided to hold off on building anything non-trivial with it.

I’m currently rewriting a Rails app into smaller elixir components, the Rails app is mostly consists of several potentially long running processes that gathers large amounts of data from various sources, does some light transformations, and then combines it and outputs it in various forms. Elixir has been immensely more pleasurable to write in, as OTP, along with things like GenStage and Flow, seem like a perfect fit for this task. And, while go’s channels are cool, they don’t seem nearly as powerful as elixirs actor model/OTP — at least for this example.

The one advantage of Go I can immediately think of is using it for some networking heavy app, which is an area Elixir/Erlang has room for improvement, as making some simple outside http requests isn’t nearly as dead simple, iirc.

That’s more-or-less how I feel about Python, it’s a solid language, first one I learned and only one used outside some C++ for school, for several years. But, after branching off into other languages, I’m just really not that interested in Python. Maybe it’s because I’m not particularly interested in ML or data science, which outside of it almost being the ubiquitous intro language, is really the big draw to it these days. I just don’t find Python sexy, which isn’t a bad thing, it’s just not as fun to use, which can also be a good thing as it can prevent some shitty hacks just because I wanted to code golf/try some obscure language features.

Though, I’m a bit of a language junky, I love playing with new languages that largely break away from the classic C Style. My daily languages I use, and actually deeply enjoy working with are Ruby, JS/TS (mostly TS now-a-days), and Elixir. Likely Haskell is the next language I’ll try to seriously learn, as it’s one I just want to check off my list. But, I’ve also dabbled around with rust, tried to drink the lisp koolaid, but couldn’t get past the (((())))))) - I hope one day to try again to see what the hype is about, and I occasionally check up on Idris, but I’m going to let that one mature a bit more/at least get Haskell under my belt before I give it a serious effort.

With all that said, Python is solid, but with all the other options out there, it just seems terribly boring. Maybe that’s largely due to my lack of meaningful work with it in the past few years, but I’m not at all interested in using it anymore. Also, the whole white space thing is a huge turn off, Which is one of the things I actually used to really like about it.

Windows Sandbox 8 years ago

The app I use to do that is literally called AppCleaner, been using it for years it’s one of the first things I install.

For example, the other day I moved Word to the trash, 5 seconds later I get the AppCleaner pop up letting me know it found an additional 2GB of shit that Word just littered around my machine that wouldn’t have gotten removed by just deleting the app. And unfortunately, that definitely hasn’t even been the worst offender I’ve run into, and at this point I’m very rarely not surprised by the amount of leftover crap that doesn’t get removed when deleting an app.

Yeah, I’m aware you can pin versions in a requirements.txt, but does that also pin those packages dependencies? For example, if I had two pinned packages (A, B) and they both depend on package C, what happens if A updates to depend on a higher version of C that contains changes that break package B? Can you pessimistically (Gemfile ~>, or NPM ^) pin versions, or are you only limited to just equals X and the greater/less than operators?

Now that I’ve wrote that out, I’m wondering if packages can even pin their deps required versions. I’ve only published one python package years ago, and I can’t remember if that’s possible. Which I shouldn’t have to even worry about in a modern package management system.

I know the above example wouldn’t be possible in any of the systems I mentioned above, because the aside from installing packages, they ensure that the versions of every package are compatible. That’s why lockfiles are so important, assuming you’re downloading decent packages, the package manager can assure you that they’re all going to work together, also allowing you to update without having to worry about some random deeply nested dep isn’t going to break some other package when it gets updated, making updating (usually) a breeze.

In pips current state, it seems more or less like a slightly more strict NPM before yarn made them get their shit together (still vastly prefer yarn). The only difference is your packages are wherever Venv puts them instead in a “pip_modules” folder in the project, which is at least better than a global free-for-all. Though, that also might be less of a headache than dealing with Venv, I hope it’s gotten better since I’ve used it, because that was always such an annoyance.

Python was my first programming language, and though I don’t personally reach for it anymore (at least very rarely), it’s package management is the one large reason I don’t want to use it. All the other complaints I see about the language I don’t give much merit to, people like to complain, every language has it’s quirks and some people just can’t look past them. But, while not a solved problem, there are tons of great package managers Python could learn from to make pip not suck. How is there not a standard way/built in lock system, or even a single standard package manifest (Gemfile, package.json, cargo.toml, mix.exs, or even composer.json) — which all (except maybe composer, it’s the one I’m least familiar with) are supported by default by the language, and have version locking.

I know pythons big thing is backwards compatibility, and breaking things is almost the biggest sin in that community (python2...), and maybe I’m ignorant, but I just don’t see how implementing a single standard package manager with a standard manifest and lockfile would break anybodies anything. All they have to do is make it so pip still works without it, and if they want to see how to do that, just look at NPM, who before this year was notorious for errant package versions due to the lack of lockfiles, but now they have it and I think pretty much everyone was happy about it. They literally could just port bundler to Python and call it a day, the code is open source, they can look at how it works, and it’s one of the most well regarded package managers out there, I’ve maybe run into 2 issues ever with it. The only other package manager I see get more praise is cargo, which they could (should) also look at for inspiration.

I know things have been improving. When I was using Python daily, the standard was still punching in some incantations to start of Virtual Env (which still confuses the hell out of me to this day) and piping the contents of a requirements.txt file into pip (with I think at least some level of version locking). But, from what I’ve gathered is there are some solutions being built to bring pip out of the early 2000s, but they’re quite fragmented efforts, and they all fall short in different places.

Python is a great language, pip and all the bullshit that comes with it is terrible.

I also have a few domains on Google, but I’m actually not a huge fan it. Aside from it being slightly more expensive, outside of the domain search UI, I find the UI for managing a domain clunky, and confusing. I’d imagine it would be easier to use if I were more bought in to the Google ecosystem (e.g. GSuite) as there are tons of options for integrating your domain with google services whether or not you use them. However, I only use google domains, and all of the stuff they’re pointing at are on other services (Digital Ocean, ProtonMail, etc.) so most of the management UI for me is just noise. Because of that, along with most of my stuff being on DO, I just have them all pointed to to DO’s nameservers, and I do all my management through DO’s DNS service (which is free) and don’t have to use google’s UI after setting the nameservers. DO’s UI is quite a bit cleaner and easier to use (in my opinion), and the tight integration with DO’s other networking tools (API access for LetsEncrypt and Floating IPs mostly) is just a nice plus.

I’ll (hopefully remember to) switch my domains over to (probably) namecheap as it’s usually the most recommended one in these threads to save a few bucks a year when it comes time to renew them.

I’ve definitely worked with more APIs that I dread working with, but off the top of my head one of the most pleasant I’ve used has been Rollbar.

At my workplace we own/maintain/create a lot of custom small apps for various groups, as well as a fewer larger scale ones (and a few of those are pretty legacy). Prior to Rollbar, we just had random apps kinda using things like NewRelic, but most of the time if we needed to track an error, it meant diving into logs. But, getting everything on Rollbar was an absolute breeze, and the best part (and a sign of a good API/Service) is once the initial setup is done, that’s literally been it, no constant fussing with configs, service changes, it’s been set and forget.

The setup process is more-or-less:

1) Add the app from the web UI 2) Install the gem into the Rails app 3) Setup the token’s for prod/staging environments 4) If the app has a JS frontend, add the JS package 5) Setup the client token 6) Deploy

And after that all errors are being piped into the dashboard, and (almost) out of the box, I’ll be able to see the line it occurred at, the trace back, the IP it came from, the user it occurred with, number of occurrences, and receive notifications when a shitload of errors starts occurring, all from an easy to use dashboard. It’s even a bit better for frontend errors, because you can also see the series of clicks/events the user made leading up to the error.

And a few more clicks in the web UI, you can have it link the errors directly to your source control and issue tracker.

The “RQL” (SQL-like query language) feature initially didn’t seem that useful, but overtime it’s actually come in really handy being able to query the errors in a fairly powerful way.

The documentation is great, they provide official APIs/packages for almost all popular languages & frameworks (with the caveat being focused on web dev).

Definitely a service I’d recommend to any shop that doesn’t have a solid error tracking system in place. I can’t think of a single issue I’ve had with the service in the year+ we’ve been using it.

I can give you something close to that. In a thread from 1995[1] some users were skeptical and not buying the C++ hype:

A typical programmer uses FORTRAN, COBOL, C or if they believe the hype, C++. Typical programmers don't use functional languages.

From quite a few posts I saw I gathered that a lot of people thought C++ was not going to gain any real adoption, and an OO C was stupid. Which, looking at it from today’s point of view is hilarious. Makes you wander what new thing we’ll all think is just a trend but will become ubiquitous in 20 years.

[1] http://computer-programming-forum.com/23-functional/b8bd46e4...

I cannot stand Apache, not the foundation, the web server. We are stuck with it at work, and I groan when I have to venture into an httpd.conf. XML is so clunky and verbose, I have no idea why it caught on as the defacto config language for so many “enterprise” projects other than there weren’t any better choices at the time. Which, that’s fine, XML sucks, but so does YAML (though not nearly as much). Aside from that, which for me at least if I see a project that uses XML I immediately start looking for alternatives, in my experience Apache’s documentation sucks. It feels archaic to get through, not a lot of useful examples, just mostly things like “here how to pass in the default values”. The default Apache logs suck. Reverse Proxying requires way more XML config to setup than it should. I could go on and on about my disdain for Apache/httpd.

When we have options like Nginx, Caddy, or even Traefik, which mostly work out of the box, things like reverse proxying take a line or two of config, and they have good to really good docs, I have no idea why anyone would pick Apache over any of those unless they are working in an environment that is soo entrenched in enterprise software, like Apache, switching isn’t an option.

Because of httpd, I’ve mostly avoided Apache projects. So, I don’t have too much hands on experience for much else to compare, only a lot of (I’m sure biased/frustrated) reading of others experiences.

However, I did decide to give OpenWhisk recently. If I hadn’t already known, I would’nt have believed you if you told me it was an Apache project. I haven’t yet had to look at any XML, minimal time spent on config, it supports modern platforms/techniques out of the box, and it has a CLI that doesn’t suck. Pretty much the opposite of my experiences with httpd. I assume all of this is due to it being a new project without 20+ years of built up enterprise cruft.

So, at least for me, I’ll be avoiding any older Apache projects if I’m able to find a comparable modern one. But, just because there old enterprise stuff sucks to deal with for the average not-enterprise person, that doesn’t mean there new stuff will too, and I’ll be totally willing to give it a shot. One thing Apache has proven is even though the user experience may kinda suck, the underlying tech is usually pretty fucking solid, open source, and you’ll likely not have to worry about breaking changes every month (or decade).

Perl 11 8 years ago

I would agree, however bundler & rvm are incredibly easier to setup and use when comparing to Python’s virtualenv (and the few other alternatives frequently brought up). I’m not sure there is even an equivalent for the Perl ecosystem, as I gave learning Perl an actual effort a while ago (no idea why) and all it’s quirks and weird syntax immediately turned me away and I’ve never looked back.

Perl 11 8 years ago

without a lot of the strange quirks of perl

And instead with a lot of the strange quirks of Ruby!

\s, only kind of, I love Ruby but it does have a few quirks that I see confuse some people coming from other languages when they start writing non-trivial Ruby code (literally everything is an object being a big one — “what do you mean a class is an object?! modules too?!”).

However, these quirks are much, much easier to learn, understand, and possibly eventually come to like, rather than some (many) of the quirks that exist in Perl.

Seconding BitWarden. It’s the only open source/self host able password manager I could find that provides all the features that I wanted from closed source/hosted password managers (1pass/lastpass). The chrome extension and iOS app are great, have auto fill support unlike some other open source password managers (KeeWeb).

Self hosting it is super easy to setup, they just give you a docker compose file, and a few commands later it’s ready to go. It’s also fairly easy to modify the compose file to deploy it to a Docker Swarm cluster, which is how I have mine setup.

Next.js 7 8 years ago

I can’t think of any particularly good articles, or things of that nature. But, you’ll mostly be utilizing Vuex to store, mutate, & fetch data. If you aren’t already familiar with it, the docs are great [1]. It’s fairly simple to use, and as your app grows you’ll likely find yourself writing more and more boiler plate store code, but fortunately, there are a ton of really great plugins/utilities the community has built for Vuex that help eliminate a lot of that boiler plate, and make it easier to work with an ever growing store. The Awesome Vue repo [2] has a pretty comprehensive list, and you can probably get some ideas of how you’d like to work with it from seeing all the options, for example Vuex-persistedstate & vuejs-storage allow you to interface with localstorage, while Vuex-pathify provides a nice, less verbose interface for actually working with the data in the store, and then there are things like vuex-api and vuex-rest-api that eliminate a lot of boilerplates code for interacting with apis to fetch/update data.

[1] https://vuex.vuejs.org/

[2] https://github.com/vuejs/awesome-vue/blob/master/README.md#v...