HNHacker News
TopNewBestAskShowJobs

adamkl

1,061 karma · joined February 10, 2015

submissionscomments
adamkl··on Ask HN: Most interesting, mildly impractical, well-written books on software?
How about "The Land of Lisp"? [0]

It comes with a bonus music video! [1]

[0] http://landoflisp.com

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

adamkl··on When are enums not a code smell?
In Mark’s defence, our views on software development can change over time as we learn and grow.

Mark, for example, is now primarily a functional programmer and makes good use of F#’s type system:

https://blog.ploeh.dk/2015/08/10/type-driven-development/

So he might even agree with you these days (on the “baloney” part, but maybe not the “frog in a well”).

adamkl··on Anti-Patterns to Avoid in Lambda Based Apps
For point number 2:

> use AWS Step Functions to orchestrate these workflows using a versionable, JSON-defined state machine.

I think a better approach would be to use a proper workflow engine [0]. Using a standard modelling language like BPMN and the ability to monitor, audit, and optimize make this a better option than an Amazon-specific approach.

[0] https://www.infoq.com/articles/events-workflow-automation/

adamkl··on Ask HN: Do you use Model-Driven Engineering in your jobs?
I’m doing a lot of exploratory work with BPMN right now.

I think if your business is largely transactional (think Stripe), there is a lot of value to be had by framing your development as “business process automation”.

The term (and BPMN) has a lot of enterprise baggage, but some of the tools out there [0][1] are well suited to orchestrating services (and people where necessary) as a single automated process. The the ability to build that flow visually using BPMN, and then execute it in a workflow engine where you can monitor it, audit it, and optimize over time is pretty compelling.

Here’s an interesting read on the topic: https://www.infoq.com/articles/events-workflow-automation/

[0] https://github.com/camunda-cloud/zeebe

[1] https://github.com/flowable/flowable-engine

adamkl··on A visual C4 model tool for your team
This (icepanel.io) is just a graphical editor (with some very nice functionality) for C4 Model diagrams: https://c4model.com

The actual standard is quite light weight, which is its main selling point. The whole premise is that many teams find rigorous standards like UML and Archimate too heavy and thus resort to basic boxes-and-lines diagrams. C4 essentially says "take your boxes-and-lines and put full sentence descriptions on everything". Combine that will successive levels of detail, and you have the C4 standard.

You don't have to give up diagrams-as-code because you can create C4 diagrams with PlantUML [0] or using the C4 specific DSL [1].

[0] - https://github.com/plantuml-stdlib/C4-PlantUML

[1] - https://github.com/structurizr/dsl

adamkl··on BPMN and Microservices Orchestration
Part 1: https://camunda.com/blog/2018/08/bpmn-for-microservices-orch...

Part 2: https://camunda.com/blog/2018/08/bpmn-microservices-orchestr...

adamkl··on Mea culpa: How developers fix their own simple bugs differently from other devs
Maybe not exactly what you’re looking for, but this is a classic paper on the topic:

http://laputan.org/mud/

adamkl··on I closed a lot of browser tabs
I do this my having two windows open side-by-side (a 32” 4K monitor and a tiling window manager make this easy) and just drag a link from the left browser window over to the right. Not as nice as simply clicking, but usable.

If you’re willing to change browsers if necessary, Firefox has a Side View [0] extension that offers some functionality, though it’s just an “experiment” that hasn’t been updated in years.

[0] https://github.com/mozilla/side-view

adamkl··on What is simplicity in programming and why does it matter?
Here is an example that I'm quite partial to:

Presentation - https://www.infoq.com/presentations/DDD-Clojure/

Code - https://github.com/zololabs/zolodeck

Its a Domain-Driven/Hexagonal Architecture codebase written in Clojure. Its not uncommon to see this sort of approach in Java/C# so it makes comparisons of the code relatively easy.

While the overall code layout is the same as what you'd see in Java/C#, a big distinction is that the "entities" that make up the core functionality of the domain in the Clojure version are simple data structures (rather than classes), and the logic that operates on them are pure functions (rather than methods on the classes themselves).

With this approach, a lot of the hoops you'd usually jump through with dependency injection to enable testability go away, since its easy to test pure functions that operate on simple data structures, no mocking required.

This sort of approach isn't limited to Clojure [0], but Clojure makes it idiomatic.

[0] - https://www.destroyallsoftware.com/talks/boundaries

adamkl··on TDD from the Factorio Team
For those who want to see some REPL driven development in action:

https://vimeo.com/230220635

adamkl··on JsonLogic
I posted this in another thread, but it seems relevant to what you are looking for: https://stopa.io/post/265

It walks through the process of building a Lisp in JSON and the associated parser in JavaScript. It could be a good starting point to build out a cross-platform approach to sending logic over the wire.

adamkl··on JsonLogic
Here’s some great instructions on how to use JSON to do just that:

https://stopa.io/post/265

adamkl··on Lessons on Writing JavaScript and React from ClojureScript
I think claims of improved productivity when switching to Clojure have a lot to do with the person making those claims and where they are coming from.

I see Clojure as almost sub-set of JavaScript bundled with a great standard library akin to Lodash or Ramda. You can write very Clojure-y functional code with JavaScript, and if that is what you are already used to doing, than you might not see a big difference in switching to Clojure.

But JavaScript is a bit of a kitchen sink. You want classes, you got em. You want prototypes, you got em. Functional programming, sure. This wide mix of language features means that everyone’s experience with the language will be different, and if somebody is coming from a very object-oriented background, being exposed to the data-oriented functional approach of Clojure can be an eye-opener.

Personally, using Clojure had a huge impact on how I approach development (having from from a traditional C#/Java background). I consider myself much more productive now and view problems in a completely different light. I don’t write Clojure for work, I’m pretty much full-time Node.js these days, but I credit Clojure with changing my development practices for the better.

I guess what I’m saying is that it’s not necessarily Clojure-the-language that make people feel more productive, but maybe it’s just the development style that Clojure almost forces upon people that makes them feel more productive.

(And personally, I just love the elegance of a language with such minimal syntax... and an abundance of parens)

adamkl··on ClojureScript 1.10.844
Same here. I’m slowly writing some wrapper libraries for server side ClojureScript (starting with Express.js).

It’s a fun side project for now, but hopefully I can use it to convince some of my JavaScript loving co-workers to give Clojure a try.

adamkl··on ClojureScript 1.10.844
There is nothing that says ClojureScript can’t be used on the server side and integrate with the platforms you mentioned. It’s likely just a matter of writing wrapper libraries similar to what was done for many Java libraries.

The hard part is that most Clojure devs default to using the JVM server side so there’s not much appetite there to do the work to embrace JS server side frameworks.

adamkl··on ClojureScript 1.10.844
Immutability is baked into ClojureScript, so there’s no need for libraries like Immutable.js. Likewise, ClojureScript is all about manipulating a small set of code data structures (lists, vectors, maps, etc), and as such it has an extensive (!) set of functions built into the core language for doing just that, which eliminates the need for libraries like Ramada and Lodash.

Behind the scenes ClojureScript is transpiled to pure JavaScript with Google’s Closure compiler, so there’s no external dependencies on libraries like the ones mentioned above. It’s all just built into the language.

adamkl··on ClojureScript 1.10.844
“It's basically my perfect version of Javascript. No need to fumble with libraries like immutable.js, no need for additional libraries like ramda or lodash because the standard clojurescript library has everything+.”

This pretty much my view as well. There’s that classic joke comparing two books on JavaScript, the complete language vs. the good parts [0], and you could pretty much just replace the “good parts” book with ClojureScript.

It has everything you need and gets rid of most of the stuff that enables people to write bad code. (Assuming you like functional programming, of course)

[0] https://i.redd.it/h7nt4keyd7oy.jpg

adamkl··on How much can a Clojure developer do alone?
Function definitions and vars are a form of state that can accumulate in a REPL session. Its not just atoms.

This can lead to issues where you decide to refactor and rename a var (Clojure is all about concise and expressive names, so its not uncommon to do this.. At least not for me) but you might not catch every place the old var name is being used. Because both vars are still exist in the state of your REPL, everything seems to work, but once you compile your uberjar or whatever, things are broken.

A REPL isn't a replacement for good unit tests, and there are techniques for reloading your REPL state on save, but the issue of needing to keep the "REPL state in your head" is real, and not an artifact of doing things wrong. Just something that the developer needs to be aware of as a potential hiccup in the REPL experience.

adamkl··on REST vs GraphQL vs gRPC
Code generation and strong contracts are good (and C#/Java developers have been doing this forever with SOAP/XML), but they do place some serious restrictions on flexibility.

I’m not sure how gRPC handles this, but adding an additional field to a SOAP interface meant regenerating code across all the clients else they would fail at runtime while deserializing payloads.

A plus for GraphQL is that because each client request is a custom query, new fields added to the server have no impact on existing client code. Facebook famously said in one of their earlier talks on GraphQL that they didn’t version their API, and have never had a breaking change.

Really, I don’t gRPC and GraphQL should even be compared since they support radically different use cases.

adamkl··on I don't want to learn your query language (2018)
I believe Honey SQL might be just what you are looking for:

https://github.com/seancorfield/honeysql

adamkl··on Immutable Approaches
Agree that converting between JS and CLJS data structures is a pain.

The best approach to dealing with that is to isolate that interop at the edges of your program.

I’m currently, coincidentally, working on a wrapper for Express to do just that. The wrapper library is responsible for mapping between the Express req/res objects to simple ClojureScript maps. Combine that with a similar wrapper around something like fetch or axios and all my code can be pure ClojureScript.

I mean, that is the general practice in Clojure/Java land. Write wrappers around the native libraries to isolate the pain that comes from interop.

I’m a sucker for Clojure though, and willing to do the work.

adamkl··on Immutable Approaches
I definitely agree about the benefits of a mainstream language/big ecosystem when it compares to something more niche (Although ClojureScript with shadow-cljs [0] has an excellent interop story with the JavaScript ecosystem).

I’m not sure I can agree with the premise that “developer diligence” is a reliable approach immutability (or any other development ideals). Maybe in a small team of like-minded devs diligence is enough, but in the large, with a multi-paradigm language that allows pretty much anything, you can be sure to see pretty much anything!

[0] https://github.com/thheller/shadow-cljs

adamkl··on Immutable Approaches
I think it’s interesting that libraries like Immutable.js, Immer and Ramda show that there is a real appetite amongst JavaScript developers to embrace a more functional approach, but at the same time languages like ClojureScript, Elm, and Rescript don’t see more adoption.

I suppose it’s all a trade off. The pain of jumping through hoops with the libraries mentioned above vs dealing with an entirely different language and having to hire/train for it.

adamkl··on Learn Functional Programming Visually
I’ve found Grokking Simplicity [0] to be a great, pragmatic introduction to solving real-world problems with “functional thinking”.

All the code is JavaScript and it tries to walk you through how you might solve common, everyday business problems with a more functional approach. All without getting bogged down with terms like “monad” or “functor”.

This book (along with Domain Driven Design made Functional, mentioned elsewhere) are both great resources for getting introduced to “useful” functional programming.

[0] https://www.manning.com/books/grokking-simplicity

adamkl··on Using State Machines with React to Make a Confirmation Dialog (2020)
”Currently that runtime is a generic stateful "service" implementation provided by these libraries”

This is how I approached using XState in a proof of concept last year. I created a “service layer” made up of XState machines that handled different high-level aspects of the application behaviour; i.e. not tied specifically to a particular UI element. Things like managing the requests made during an OAuth flow and storing the authenticated user’s information.

This gave me a source of application state with well defined behaviours that I could use instead of “redux” and its usual accompaniment of boolean flags and thunks.

The best part of embracing the separation of state management from React is that I initially developed the application in Angular before lifting-and-shifting the “service layer” over to React and sticking in a “context”. All the application behaviours remained the same, it was just a matter wiring up some JSX in place of Angular’s HTML templates.

adamkl··on Software engineering topics I changed my mind on
> So while FP is just another tool, it's also a framework for thinking that helps people make better choices

I’ve been getting more into functional programming this past year (via Clojure, though my day-job is mostly JavaScript/TypeScript) and this is the big takeaway for me.

Type theory and monads may have their place, but thinking about separating logic from side-effects is, I think, the most valuable aspect of functional programming.

That is a thought process that you can apply in pretty much any language that will give you the biggest bang for your buck.

Edit: Here’s some great examples of the benefits of functional thinking without going off the deep end.

1. Boundaries by Gary Bernhardt - https://www.destroyallsoftware.com/talks/boundaries

2. Pits of Success by Mark Seemann - https://youtu.be/US8QG9I1XW0

3. Grokking Simplicity by Eric Normand - https://grokkingsimplicity.com/

adamkl··on VSCode, Dev Containers and Docker
To be perfectly honest, in this scenario, there isn't much of an advantage.

The container approach is lighter weight, and I found it easier to manage the configuration via Dockerfiles. Managing a full VM with the OS install is a bit of a pain.

That being said, I worked at an organization that did the VM approach using Vagrant. It wasn't as nice as the VS Code/Docker approach, but the results were similar.

adamkl··on VSCode, Dev Containers and Docker
It depends on how large your organization is and what specific quirks need to be configured to do your work.

Its not unusual for large organizations to have internally hosted registries (Artifactory), source control and network proxies. This usually requires setting up different config files (.npmrc for Node.js/NPM), installation of custom root certificates, ssh keys, etc. None of that includes project/team specific configurations and workflows.

Take all that and multiply it by thousands of developers and you have a recipe for an endless stream of Slack chats, email chains, and Teams messages repeating the same config questions and answers.

If you can reduce all that down to a single docker pull, while making sure everyone's development environment is consistent, it can be a big win.

adamkl··on VSCode, Dev Containers and Docker
To make it workable I had to just give up on the local host file integration.

I basically used the container like a VM. Configured it with all the tools I normally use (e.g. OhMyZsh, etc) and had it constantly running in the background. I would use VS Code as a front end and work directly inside the container (cloning repos and pushing commits).

It had its quirks but the main benefit was that my local machine was no longer a snowflake. I could easily move to any machine, pull my "development" image, spin up the container and everything was exactly as I liked it.

adamkl··on Flow-Based Programming
Rich Hickey gave a good talk on core.async and it does seem pretty similar in concept:

https://youtu.be/drmNlZVkUeE

← PreviousPage 2 of 7Next →