Outside Lisps, I have not seen any environment where you can start up your app, connect the editor to it, and then develop new code in the context of a running application.
This is absolutely true, however I don't particularly value this feature because most engineers typically already cannot separate concerns very well in industry so IMO if I had this I would not want people to use it. Very much a "it works ship it" trap.
. I also find that language design very much impacts conventions and architecture. Clojure’s focus on immutability naturally leads to code that’s largely referentially transparent and where you can reason about parts of the application in isolation without having to consider side effects and global state.
I'm with you here. I basically force almost every code base I end up working on into functional forms as much as possible.
When you pass data around, you can always simply look at the input/output data and know what the function is doing. Transforming data also becomes trivial since you just use the same functions regardless of what data structure you’re operating on, this avoids many patterns like wrappers and adapters that you see in OO style
Yep agreed, almost every role I step into I push the org to enforce this style of work.
Transforming data also becomes trivial since you just use the same functions regardless of what data structure you’re operating on, this avoids many patterns like wrappers and adapters that you see in OO style.
This is where you lose me, you still have wrappers and adapters, they're just not classes. They're functions. I still use those words regardless if I'm in Haskell or Typescript. Semantic meaning shouldn't be lost in functional style because it's part of architecture. Functional programming simply gives your basic building blocks better names and better division of responsibility, e.g. functor, applicative, monad, etc.
This is more of a how the saussage is made issue in my experience than a tooling selection issue. Clojure may make it easier to do the right thing but the actual forcing function is the company culture. Self-selection of Clojure as the company's tooling may create a correlation.
Most companies have the ability to implement fail fast workflows for their developers they simply choose not to because it's "hard". My preferred one is Behavior Driven Development because it forces you to constrain problems into smaller domains/behaviors.
An Adapter is typically a piece of code that transforms data between formats at various boundaries. Typeclasses remove the need for Adapters for functionality at library boundaries e.g. most thing have
map
where in javascript I can't do{}.map
with the EMCA standard. However typeclasses do not solve the problem of the literal data format and functionality differences between different implementations.For example I call some API using a Client and it returns bad gross data based on how that API is written, I would use an Adapter to transform that data into clean organized data my system works with. This is extremely helpful when your system and the external system have references to each other, but your data taxonomy differs.
A real example is that Google Maps used to have a distance matrix API where it would literally calculate matrices for you based on the locations you submit. Circa 2018 Google changed it's billing driving up the prices, which lead a lot of people to use alternative services like Here.com. Here.com does not have a distance matrix API. So in order to build a distance matrix I needed to write an adapter that made N calls instead of Google's 1 call and then stuff the Here.com responses into a matrix response compatible with Google's API which we unfortunately were using directly without an internal representation.
These concepts are still used/useful within functional contexts because they are not technical concepts they are semantic concepts. In functional languages an Adapter may just be a function that your responses are mapped over, in OOP style it might be a class that calls specific network client and mangles the data in some other way. Regardless of the technical code format, it still is the same concept and procedural form, thus it's still a useful convention.