Unix is my IDE, vim is my editor.
Unix is my IDE, vim is my editor.
Yep. When everything about your IDE (unix) is programmable, it makes “modern” IDEs seem quite quaint.
Personally I make extensive use of https://f1bonacc1.github.io/process-compose/launcher/ to orchestrate a bunch of different shell scripts that trigger based on file changes (recompiling, restarting servers, re-running tests, etc.). Vim just reads from files as needed. It’s lightning fast, no bloat, and a world-class editing experience.
Yep. It does increasingly feel like developers like me who find it deeply disturbing and problematic for our profession and society are going to increasingly become rarer. Fewer and fewer people are going to understand how anything actually works.
Shit! Sorry, got my wires crossed, I actually meant locality of behavior. Basically, if you’re passing a monad around a bunch without sugar you can’t easily tell what’s in it after a while. Or at least I assume so, I’ve never written anything big in Haskell, just tons of little things.
I’m not sure if I entirely follow, but in general you actually have much better locality of behavior in Haskell (and FP languages in general) than imperative/OOP languages, because so much more is explicitly passed around and immutable. Monads aren’t an exception to this. Most monadic functions are returning values rather than mutating some distant state somewhere. Statefulness (or perhaps more precisely, mutable aliasing) is the antithesis of locality of behavior, and Haskell gives you many tools to avoid it (even though you can still do it if you truly need it).
I’m not really sure what you mean by “don’t really know what’s in it after a while”. It might be helpful to remember that lists are monads. If I’m passing around a list, there’s not really any confusion as to what it is, no? The same concept applies to any monadic value you pass around.
Yeah, that makes tons of sense. It sounds like Transaction is doing what a string might in another language, but just way more elegantly,
I think you might have misunderstood what I was describing. The code we write doesn’t actually change, but the behavior of the code changes due to the particular monad’s semantics. So for example, let’s say I write a query that updates some rows in a table, returning a count of the rows affected. In this Transaction
code block, let’s say I execute this query and then send the returned number of rows to an external service. In code, it looks like the API call immediately follows the database call. To give some Haskell pseudocode:
example :: Transaction ()
example = do
affectedRows <- doUpdateQuery
doApiCall affectedRows
return ()
But because of how Transaction
is defined, the actual order of operations when example
is run becomes this:
BEGIN;
to DBdoUpdateQuery
COMMIT;
to DBdoApiCall affectedRows
. Otherwise, do nothingIn essence, the idea is to allow you to write code where you can colocate your side-effectful code with your database code, without worrying about accidentally holding a transaction open unnecessarily (which can be costly) or firing off an API call mistakenly. In fact, you don’t actually have to worry about managing the transaction at all, it’s all done for you.
which fits into the data generation kind of application. I have no idea how you’d code a game or embedded real-time system in a non-ugly way, though.
I mean, you’re not going to be using an SQL database most likely for either of those applications (I realize I assumed that was obvious when talking about transactions, but perhaps that was a mistake to assume), so it’s not really applicable.
I also generally get the impression that you have a notion that Haskell has some special, amorphous data-processing niche and doesn’t really get used in the way other languages do, and if that’s the case, I’d certainly like to dispel that notion. As I mentioned above, we have a pretty sizeable backend codebase written in Haskell, serving up HTTP JSON APIs for a SaaS product in production. Our APIs drive all (well, most) user interaction with the app. It’s a very good choice for the typical database-driven web and mobile applications of businesses.
Ironically, I actually probably wouldn’t use Haskell for heavy data processing tasks, namely because Python has such an immense ecosystem for it (whether or not it should is another matter, but it is what it is)… What Haskell is great at is stuff like domain modeling, application code (particularly web applications where correctness matters a lot, like fintech, healthcare, cybersecurity, etc.), compilers/parsers/DSLs, CLI tools, and so on.*
I’m not sure what you mean by “locality of reference”. I assume you mean something other than the traditional meaning regarding how processors access memory?
Anyway, it’s often been said (half-jokingly) that Haskell is a nicer imperative language than imperative languages. Haskell gives you control over what executing an “imperative” program actually means in a way that imperative languages don’t.
To give a concrete example: we have a custom monad type at work that I’m simply going to call Transaction
(it has a different name in reality). What it does is allow you to execute database calls inside of the same transaction (and can be arbitrarily composed with other code blocks of type Transaction
while still being guaranteed to be inside of the same transaction), and any other side effects you write inside the Transaction
code block are actually collected and deferred until after the transaction successfully commits, and are otherwise discarded. Very useful, and not something that’s very easy to implement in imperative languages. In Haskell, it’s maybe a dozen lines of code and a few small helper functions.
It also has a type system that is far, far more powerful than what mainstream imperative programming languages are capable of. For example, our API specifications are described entirely using types (using the servant library), which allows us to do things like statically generate API docs, type-check our API implementation against the specification (so our API handlers are statically guaranteed to return the response types they say they do), automatically generate type-safe API clients, and more.
We have about half a million lines of Haskell in production serving as a web API backend powering our entire platform, including a mobile app, web app, and integrations with many third parties. It’s served us very well.
As a senior engineer writing Haskell professionally, this just isn’t really true. We just push side effects to the boundaries of the system and do as much logic and computation in pure functions.
It’s basically just about minimizing external touch points and making your code easier to test and reason about. Which, incidentally, is also good design in non-FP languages. FP programmers are just generally more principled about it.
https://daniel.haxx.se/docs/curl-vs-httpie.html
Httpie and xh only have a small subset of curl’s functionality, and IMO the claims of more intuitive UX is dubious at best. More magical and limiting is what I would say. Httpie in particular is slow as hell, too.
Daniel has a more thorough comparison of features across different alternatives here: https://curl.se/docs/comparison-table.html
It does not take long to use curl, not sure what you’re talking about. There’s not particularly special about what Postman does.
The same way you test any other API. Not really different. I tend to keep my request bodies in separate files organized in folders to keep things tidy.
Curl. Everything you described is not hard to do via scripts. I use it every day for all of my API testing needs. You’re also not limited to the features Postman provides.
You can easily write a script to make curl requests from a CSV.
Reviewers are not infallible and are largely focused on the meat of the MR rather than every single detail.
It reflects much more poorly on you than it does on them.
Don’t need the Ord
instance for equality, just Eq
is sufficient. Ord
is for inequalities.
The point of the post is that most mainstream languages don’t provide a way to automatically derive point-wise equality by value, even though it’s pervasively used everywhere. They instead need IDEs to generate the boilerplate rather than the compiler handling it.
Anarchism is not chaos, which is what it seems like you think it means. Anarchism is the opposition to hierarchy and is thus directly opposed to fascism and therefore Trump. No anarchist wants to see Trump win because it means fascism has won.
Yeah our corporate machines won’t run any external media. I assumed that was standard practice.
Spoken like someone who knows absolutely nothing about vim/unix.
It’s not necessary. Unlike on Windows, Linux users rarely download random packages off the internet. We just use package managers.
The software itself may or may not be more secure, but acquiring software is absolutely more secure. There’s so much Windows malware people unwittingly download from the internet. Downloading from a distro’s software repository simply doesn’t have that problem.
I’m sure it’s fine for small-scale usage, but overall it’s extremely inflexible and doesn’t really scale well at all. There’s also a lot of very basic functionality that’s straight up missing. For example, there’s no way to have a global epic priority. You can rearrange epics in an epic board, but the ordering of the epics there is not persisted elsewhere. There were many, many other shortcomings we kept running into.
Oh, and after a lot of our tickets had been imported (which itself was a huge undertaking since the auto import tools are complete trash), it started to be very slow. It feels like a very unfinished, unpolished product.
We use Gitlab’s CI/CD features extensively at my current job and it’s very, very nice. That’s what they are actually good at, not project management.
A real nerd would know that React is a library and HTML is a markup language, and neither are programming languages.