9 ms·
Why we built Vade Studio in Clojure
- andrewstuart 2y agoLook these folks can do whatever the heck they want, use whatever language they want. However my criteria for selecting a language for use in a professional context: 0: fit to task - obviously the language has to be able to do the job - to take this seriously you must define the job and what its requirements are and map those against the candidate languages 1: hiring and recruiting - there must be a mainstream sized talent pool - talent shortages are not acceptable - and I don't buy the argument that "smart people are attracted to non mainstream languages which is how we find smart people", it is simply not true that "most smart people program with Scala/Haskell/Elixir/whatever" - there's smart and smarter working on the mainstream languages. 2: size of programming community, size of knowledge base, size of open source community - don't end up with a code base stuck in an obscure corner of the Internet where few people know what is going on 3: AI - how well can AI program in this language? The size of the training set counts here - all the mainstream languages have had vast amounts of knowledge ingested and thus Claude can write decent code or at least has a shot at it. And in future this will likely get better again based on volume of training data. AI counts for a huge amount - if you are using a language that the AI knows little about then there's little productivity related benefits coming to your development team. 4: tools, IDE support, linters, compilers, build tools etc. It's a real obstacle to fire up your IDE and find that the IDE knows nothing about the language you are using, or that the language plugin was written by some guy who did it for the love and its not complete or professional or updated or something. 5: hiring and recruiting - it's the top priority and the bottom and every priority in between. If you can't find the people then you are in big trouble I have seen this play out over and over where the CTO's favorite non-mainstream language is used in a professional context and for years - maybe decades after the company suffers trying to find people. And decades after the CTO moved on to a new company and a new favorite language. So what is a mainstream language? Arguable but personally it looks like Python, Java, JavaScript/TypeScript, C#, Golang. To a lesser extent Ruby only because Ruby developers have always been hard to find even though there is lots of community and knowledge and tools etc. Rust seems to have remained somewhat niche when its peer Golang has grown rapidly. Probably C and C++ depending on context. Maybe Kotlin? How cares what I think anyway its up to you. My main point is - in a professional context the language should be chosen to service the needs of the business. Be systematic and professional and don't bring your hobbies into it because the business needs come first. And for home/hobbies/fun? Do whatever the heck you like.
- danielscrubs 2y agoThe signal to noise ratio is way better if you take some eccentric language. The amount of knuckleheads that Ive had to interview just to get a single coherent developer is mind boggling (remote first).
- deleted 2y ago[deleted]
- ilrwbwrkhv 2y agoI think in order of average dev quality (highest to lowest) I recently found: Rust Common Lisp Go Ruby/Elixir C++ Python C# Typescript Java Javascript
- bitwize 2y ago> talent shortages are not acceptable - and I don't buy the argument that "smart people are attracted to non mainstream languages which is how we find smart people", it is simply not true that "most smart people program with Scala/Haskell/Elixir/whatever" - there's smart and smarter working on the mainstream languages. Smart people can be trained in any language and become effective in a reasonably short period of time. I remember one company I worked at, we hired a couple of fresh grads who'd only worked with Java at school based on how promising they seemed; they were contributing meaningfully to our C++ code base within months. If you work in Lisp or Haskell or Smalltalk or maybe even Ruby, chances are pretty good you've an interesting enough code base to attract and retain this kind of programmer. Smart people paired with the right language can be effective in far smaller numbers as well. The major drawback, however, is that programmers who are this intelligent and this interested in the work itself (rather than the money or career advancement opportunities) are likely to be prickly individualists who have cultivated within themselves Larry Wall's three programmer virtues: Laziness, Impatience, and Hubris. So either you know how to support the needs of such a programmer, or you want to hire from a slightly less intelligent and insightful, though still capable, segment of the talent pool which means no, you're not going to be targeting those powerful languages off the beaten track. (But you are going to have to do a bit more chucklehead filtering.) > if you are using a language that the AI knows little about then there's little productivity related benefits coming to your development team. This is vacuously true because the consequent is always true. The wheels are kind of falling off "Dissociated Press on steroids" as a massive productivity booster over the long haul. I think that by the time you have an AI capable of making decisions and crystallizing intent the way a human programmer can, then you really have to consider whether to give that AI the kind of rights we currently only afford humans.
- oldpersonintx 2y ago[dead]
- Nijikokun 2y agoUltimately, it all comes down to build what you're comfortable with. Additionally, when you're managing large organizations and teams. Build with what you can hire quickly for and easily scale with.
- mkreis 2y agoQuick (and cheap?) hires are not necessarily good hires. In my experience (and my theory) developer productivity can range from 0.5x to 5x and more, and those developers in the upper range tend to look for certain programming language which they enjoy, like Rust, Go, Elixir, Scala and Clojure. They are hard to get if you are on a "boring" stack like Java, NodeJS, PHP. So if you might need to invest some time and money to find the right people, but at the end you make a better deal: Even if the salary is twice as much, the productiviy is even more. Additionally less people means less communication overhead, which is another advante.
- deeviant 2y agoI find the opposite to be true, that best and most productive developers tend to be more language agnostic than average, although I'm not saying they don't have their preferences. Specifically, I find language evangelists particularly likely to be closer to .5x than 5x. And that's before you even account for their tendency to push for rewriting stuff that already works, because "<insert language du jour here> is the future, it's going to be great and bug free," often instead of solving the highest impact problems.
- ilkhan4 2y agoYeah, this has been my experience too. The mentality seems similar to "productivity hackers" who spend more time figuring out the quickest, most optimal way to do a thing than people who just do the thing.
- HeWhoLurksLate 2y agoOne of the things I've noticed is that people who just do the thing, take note of what's annoying, and fix the most annoying things about a process later on tend to make the most impressive dents in a system or process, especially since they spend time mulling over the idea in their head and so by the time they implement, they aren't "zero-shotting" a solution to what's generally a complex issue.
- smw 2y agoAnyone else unable to login with github to studio?
- noshitsherlock 2y agoYes, I was unable; just bumped me back to the login
- akashojha42 2y agoIt's working while I try right now. Could you share more about the error you faced?
- pntripathi9417 2y agoLooking into the problem. Apologies.
- jolt42 2y ago@OP "Model our domain as a graph of attributes and relationships" and "generate resolvers". I'm curious what your model looks like so that you are able to "generate resolvers"? I had looked into using Malli as the model, but curious what route you took.
- knubie 2y agoI think these words will make more sense in the context of Pathom. https://pathom3.wsscode.com/ https://pathom3.wsscode.com/
- heypragyan 2y agoWe use malli to define domain model. And generate pathom resolvers and mutations based on those.
- jimbokun 2y agoI'm curious if Elixir could provide a similar development environment? Seems like many similar capabilities, like a focus on immutable data structures, pure functions, being able to patch and update running systems without a restart, etc.
- kevinmershon 2y agoFor the most part, yes. CIDER and nREPL is better tech than IEX though. I live in both and Clojure is much more enjoyable.
- innocentoldguy 2y agoI came to the opposite conclusion for the following reasons: 1. IEx provides a robust and interactive debugging environment that allows me to dig into whatever I want, even when running in production. I've never lost state in IEx, but that happens fairly often in CIDER and nREPL. 2. IEx uses Elixir's compilation model, which is a lot faster than CIDER and nREPL, leading to faster debugging cycles. 3. IEx is tightly integrated with Elixir whereas Clojure's tools are more fragmented. 4. IEx doesn't carry the overhead of additional middleware that CIDER and nREPL do. I'm also not a fan of JVM deployments, so I've migrated all my code away from Clojure to Elixir during the past 10 years.
- smokel 2y agoInteresting story. I am not entirely convinced that all credit should go to the programming language here, though. My theory is that communicating abstractions is hard. If you work on your own, or in a (very) small team, you can come up with powerful abstractions that allow you to build amazing systems, quickly. However, sharing the underlying ideas and philosophy with new team members can be daunting. As systems grow, and mistakes are made, it becomes more and more likely that you run into serious problems. This may also be why Java and similar object oriented programming languages are so successful for systems that have to be maintained for ages, by large teams of developers. There are but few abstractions and patterns, and it does not allow you to shoot yourself in the foot, nor to blow your whole leg off. Conversely, this may also be why complex frameworks, such as Spring, are not always so nice, because they introduce (too?) powerful abstractions, for example through annotations. It may also clarify why more powerful languages such as Scala, Common Lisp, Smalltalk, Haskell, etc, consistently fail to pick up steam. Another theory is that not every developer is comfortable with abstract concepts, and that it simply takes a team of smart people to handle those.
- j45 2y agoClojure has some interesting advantages - which doesn't mean others might not. Rapid application technologies, methedologies, or frameworks are not unusual. I know some wonderfully productive polyglot developers who by their own choice end up at Clojure. It doesn't have to be for everyone. I wouldn't rule out that Clojure doesn't deserve credit. I wouldn't think it's a good idea to discredit Clojure from not having tried it myself. I do hope someone with extensive Clojure experience can weigh in on the advantages. How easy something is a codebase grows is something to really consider. This product regardless of how it's built is pretty impressive. I'd be open to learning advantages and comparisons without denying it.
- pntripathi9417 2y agoThis has actually been my experience. When I started with Clojure I was writing it badly. I came from NodeJS world. It even took me a week's time just to setup the working environment. With time you get to understand the power of simplicity. How to break the problem and compose the solutions to achieve your intended result.. That's where the power of Clojure came in for us.
- joeevans1000 2y agoIs there a technical reason I can't sign into Studio with email? I'll really try to avoid signing in with other platforms, but I'll consider Github if there's some reason it has to be. I'll never sign into a service with Google.
- j45 2y agoAgreed. If a google account goes away, so does the access to all your google authenticated stuff. I only use google for email logins for services I don't take seriously and am willing to lose.
- akashojha42 2y agoWe wanted to get the users on the Dashboard, building apps in as fewer clicks as possible while keeping the accounts secure. Google being the most widely used auth and GitHub, the developers' favorite, they have been our first choice. Your concern makes sense though and we'll be considering it in the next feature rollout.
- j45 2y agoAppreciate the reply. I think you have the right idea with getting people in as fast as possible. It is probably safe to say the email login folks don’t mind and maybe appreciate the extra step. In terms of starting quick as possible with the tool, maybe it’s possible to do shadow profiles where the app starts against a yet unnamed account (tied to a cookie) and when they start using the wizard and playing with it, at some point they have enough to save with a popup with login by id provider or email.
- pntripathi9417 2y agoNo specific reason. Will be rolling it out soon.
- justinl33 2y agoI've built similar systems using Apache Airflow and Temporal, but the complexity was overwhelming. Using simple maps with enter/leave phases for workflow steps is much cleaner than dealing with DAG frameworks.
- pntripathi9417 2y agoAbsolutely... That has been an epiphany for me as well.
- christophilus 2y agoClojure is a lot of fun to tinker with, but man… I love my static types. I think I’d hate to work on a large codebase in Clojure and constantly be wondering what exactly “m” is.
- ilrwbwrkhv 2y agoYou wouldn't because of the repl. You would jack in and no exactly what m is.
- satvikpendem 2y agoWith static types, I don't have the use the repl at all, I can simply hover over it in my editor.
- Zak 2y agoWith a REPL-connected editor (and most have a way to do this), you can simply hover over it in your editor as well. Even though most languages can have a REPL today, few integrate it in the development experience the way lisps do.
- iLemming 2y agoCorrection: It's not that you "don't have to use the REPL"; you simply cannot even have it in that case. REPL-driven development is quite a powerful technique, and no, "many other languages too" don't have it. For it to be "a true REPL," it must be in the context of a homoiconic language, which Clojure is. Sure, static typing is great, but perhaps you have no idea what it actually feels like - spinning up a Clojurescript REPL and being able to interactively "click" and "browse" through the web app programmatically, controlling its entire lifecycle directly from your editor. Similarly, you can do the same thing with remote service running in a kubernetes pod. It's literally like playing a video game while coding. It's immensely fun and unbelievably productive.
- hombre_fatal 2y agoAs nice as nrepl/cider are, doing what amounts to setting a breakpoint in the middle of a function to see what `m` looks like isn't a replacement for knowing the type without executing code. It's just something we put up with.
- android521 2y agoI can't find pricing on the same. Though it is no code, there must be a way for me to work with code directly if i wish to do so. No mobile apps. It would be great if you can generate both web apps and mobile apps.
- e12e 2y ago> Today, we're building Vade Studio with just three developers – myself and two developers who joined as interns when in college. (...) Here's what we've accomplished: (...) In how many man-hours/days? It's hard to know if the list is long or short only knowing that calendar time should be multiplied by three for calculating people time spent...
- j45 2y agoIf it took fewer lines of code that's something to consider too.
- iLemming 2y agoYes, Clojure can be very terse without being extremely cryptic. Even simple data representation, if you compare JSON and EDN - the latter would be almost twice as compact yet remain more readable than JSON. Clojure is not as terse as e.g., Haskell, but I think it wins by being more pragmatic. Of course, some seasoned Haskelites may disagree, in some rare cases, Haskell can prove to be fantastically pragmatic, but let's agree not to go down that rabbit hole of argumentation.
- j45 2y agoThat's a nice point, it's not about the shortest or the most verbose code.. maybe where relevant, something one or more people can learn quickly and become productive in contributing value. With many languages and frameworks having a decent amount of similar functionality and performance available, more and more is left to personal preference and interpretation of what to use. Popularity might matter when trying to hire juniors. Given how many juniors seem to appreciate sincere mentorship when it's mutual, I'm not super sure on this anymore. Popularity might not matter when trying to hire other types of developers, including seniors. It's less about what's popular, or the right badge to signal. Of the polyglot folks I get to know and are humble about their smarts, it's interesting how many independently have ended up on Clojure, or a few others. Universally there's usually a joke of how long can bash scripts do what's needed until a decision has been tied in.
- bitwize 2y ago> Each new layer of complexity fed my developer ego. I'm unable to understand this mindset. All the time I read things like "Developers love complexity because it feeds their egos" but I've never encountered a situation in which added complexity made me more proud of the work. Just the opposite: being able to do more made me more proud of the work I put in, and complexity was the price I paid for that ability. The greatest hacks, the ones that etch people's names into history, are the ones -- like Unix and the Doom engine -- that achieve phenomenal feats with very little code and/or extreme parsimony of design. This is no more true than in that famous ego-stroking/dick-measuring contest of programming, the demoscene. My favorite example being the 4k demo Omniscent: https://www.youtube.com/watch?v=G1Q9LtnnE4w https://www.youtube.com/watch?v=G1Q9LtnnE4w Being able to stand up a 100-node K8s cluster to provide a basic web service, connected to a React SPA front end to provide all the functionality of a Delphi program from the 90s doesn't stroke the ego of any programmer I know of; but it might stroke their manager's ego because it gives them an opportunity to empire-build and requisition a larger budget next year.
- marsavar 2y agoI was extremely puzzled by that statement too. I would hate to work with someone like that.
- jonathanlydall 2y agoIndeed, I often tell people that one of the “hardest” things to do in software development is actually managing complexity (on any significant sized code base that is, on smaller ones it’s probably not going to be an issue). Big long lived code bases are all about this battle against complexity and the speed at which you can add new or update features largely comes down to how well you’re doing at management of complexity.
- pntripathi9417 2y agoIt's been my personal experience. Being able to use kubernetes for infrastructure, grafana, prometheus, etc Elasticsearch for search, Mongodb as database, redis as caching layer. Knowing all these tech and being able to say you know these very well used to massage my developer ego... Now I am much more like: Use one system to best of it's capability. Use Postgres. Mostly you won't need anything else. I never resisted to urge to try out something new and shiny in production in earlier days. Now I mostly use boring technologies and things I am comfortable with running in production.
- dalton_zk 2y agoUncle Bob approved this article!! Incredible history, I feel like Clojure makes magic. What I like about functional programming is that it brings other perspectives of how things CAN work!! Congratulations by the life change
- low_tech_punk 2y agoBecause Clojure treats data as first-class citizens, we could build our own lightweight conflict resolution system using pure functions that operate on these transactions. What does it mean to say Clojure "treat data a first-class citizen"? I understand FP would treat function as first-class citizen, but the statement seems to mean something different.
- pntripathi9417 2y agoI am planning on writing how we have built the real time collaboration engine with conflict resolution. I think having a clear example would help in understanding. Subscribe the newsletter to know when it's live.
- SerCe 2y agoThey most likely refer to homoiconicity [1], as Clojure is a dialect of Lisp. However, it's hard to say for sure, and maybe they were simply referring to the built-in syntax for maps, lists, etc. [1]: https://en.wikipedia.org/wiki/Homoiconicity https://en.wikipedia.org/wiki/Homoiconicity
- iLemming 2y agoNot only due to homoiconic nature. All (well, technically not all, let's say most) Lisp dialects are homoiconic. Yet, there are some other aspects that make Clojure specifically well-suited for data manipulation: - immutability and persistent data structures (makes code easier to reason about [the data]; enables efficient concurrency - no locks; some algorithmic tricks that makes it very performant despite having to create copies of collections), - seq abstraction - unlike other Lisp where sequence functions are often specialized for different types, Clojure simplifies things by making baked-in abstraction central to the language - all core functions work with seqs by default. it emphasizes lazy sequences as a unified way to process data, i.e., memory efficiency and infinite sequences, etc. - rich standard library of functions for data transformation - destructuring - makes code both cleaner and more declarative - emphasis on pure functions working on simple data structures The combination of these features makes data processing in Clojure particularly elegant and efficient.
- linkerdoo 2y ago[dead]
- jitl 2y agoMaybe this architecture approach would be challenging in Java or Go, but the style of immutable data, don’t go crazy wrapping stuff in classes is very doable in most languages. We enforce “no mutation of data you did not just instantiate” at Notion, and use TypeScript’s powerful type system with tagged union types to ensure exhaustive handling of new variants which I really miss in languages that don’t have it (go). I guess the major advantage for Closure with this style is the “persisted” data structures end up sharing some bytes behind the scenes - it’s nice the language is explicitly situated around this style, rather than TypeScript’s chaotic Wild West kitchen sink design. What I don’t understand the advantage for “state management”. Like, you build a new state object, and then mutate some pointer from prevState to nextState… that’s what everyone else is doing too. There are times though when it’s nice to switch gears from function-and-data to an OO approach when you need to maintain a lot of invariants, interior mutability has substantial performance advantages, or you really want to make sure callers are interpreting the data’s semantics correctly. So our style has ended up being “functional/immutable business logic and user data” w/ “zero inheritance OO for data structures”. Whenever I read some open source TypeScript code that’s using the language like it’s Java like `class implements ISomething` ruining cmd-click go to method or an elaborate inheritance hierarchy it makes me sad.
- knubie 2y ago> What I don’t understand the advantage for “state management”. Like, you build a new state object, and then mutate some pointer from prevState to nextState… that’s what everyone else is doing too. Clojure's real super power is its reference type(s) (in particular the atom). Rich does an excellent job explaining them in this video: https://www.youtube.com/watch?v=wASCH_gPnDw&t=2278s https://www.youtube.com/watch?v=wASCH_gPnDw&t=2278s
- jokoon 2y agoAre functional language easier to make safe?
- thih9 2y agoDiscussing that seems like discussing tabs vs spaces. It depends; exact meaning, application and personal preference play a big role.
- thih9 2y ago> When conflicts occur, our system can merge changes intelligently because we're working with pure data structures rather than complex objects. This would have been significantly more complex in an object-oriented language. Not really, in an OO language state could have been stored in some data structure as well, with a way to serialize and deserialize. E.g. React made this very popular.
- lincpa 2y ago[dead]