Live data from Hacker News

Why we built Vade Studio in Clojure

bytes.vadelabs.com

71–80 of 151 posts

Re: Why we built Vade Studio in Clojure

#71

Earlier quoted context omitted.

You wouldn't because of the repl. You would jack in and no exactly what m is.

As 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.

I've been using Clojure for a while and I rarely ever wonder "what 'm' is" - that almost never happens, despite the language being dynamically typed.

Data shapes in Clojure typically explicit and consistent. The context usually makes things quite obvious. Data is self-describing - you can just look at a map and immediately see its structure and contents - the keywords serve as explicit labels and the data, well... is just fucking data. That kind of "data transparency" makes Clojure code easier to reason about.

In contrast, in many other PLs, you often need to know the class definition (or some other obscured shit) to understand what properties exist or are accessible. The object's internal state may be encapsulated/hidden, and its representation might be spread across a class hierarchy. You often can't even just print it to see what's inside it in a meaningful way. And of course, it makes nearly impossible to navigate such codebases without static types.

And of course the REPL - it simply feels extremely liberating, being able to connect to some remote service, running in a container or k8s pod and directly manipulate it. It feels like walking through walls while building a map in a video game. Almost like some magic that allows you to inspect, debug, and modify production systems in real-time, safely and interactively, without stopping or redeploying them.

Not to mention that Clojure does have very powerful type systems, although of course, skeptics would argue that Malli and Spec are not "true" types and they'd be missing the point - they are intentionally different tools solving real problems pragmatically. They can be used for runtime validation when and where you need it. They can be easily manipulated as data. They have dynamic validation mechanisms that static types just can't easily express.

One thing I learned after using dozens of different programming languages - you can't just simply pick one feature or aspect in any of them and say: "it's great or horrible because of one specific thing", because programming languages are complex ecosystems where features interact and complement each other in subtle ways. A language's true value emerges from how all its parts work together, e.g.,

- Clojure's dynamic nature + REPL + data orientation

- Haskell's type system + purity + lazy evaluation

- Erlang's processes + supervision + fault tolerance

What might seem like a weakness in isolation often enables strengths in combination with other features. The language's philosophy, tooling, and community also play crucial roles in the overall development experience.

If one says: "I can't use Clojure because it doesn't have static types", they probably have learned little about the trade they chose to pursue.

Re: Why we built Vade Studio in Clojure

#72

Clojure 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.

You wouldn't because of the repl. You would jack in and no exactly what m is.

The compiler should know it for you, so you cannot get it wrong no matter what. The REPL here is a band-aid not a solution.

I mean, I love Clojure, and used it for personal and work projects for 10+ years, some of which have hundreds of stars on github. But I cannot count the time wasted to spot issues where a map was actually a list of maps. Here Elixir is doing the right thing - adding gradual typing.

Re: Why we built Vade Studio in Clojure

#73
post #46

Clojure 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.

One of the myriad reasons why Common Lisp is far superior to Clojure is the ability to (declare (type Integer m))

> myriad reasons why Common Lisp is far superior to Clojure

Some narrow view. Have you tried thinking that maybe Clojure intentionally chose not to include type declarations because they can lead to a messy middle ground? After all, maybe not every feature from Common Lisp needs to be replicated in every Lisp dialect? Besides, Clojure's Spec and Malli can be far more powerful for validation as they can define complex data structures, you can generate test data from them, you can validate entire system states, and they can be manipulated as data themselves.

If CL so "far superior" like you say, why then it can't be 'hosted' like Clojure? Why Clojure has Clojurescript, ClojureCLR, ClojureDart, babashka, nbb, sci, etc.? I'm not saying that to argue your specific point. Neither of them is 'superior' to another. They both have different purposes, philosophies, and use cases. Each has its strengths, pros, and cons. And that is actually very cool.

Re: Why we built Vade Studio in Clojure

#74
post #18

Interesting 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 gro…

> object oriented programming languages are so successful for systems that have to be maintained for ages,

ehmmm.... excuse me.... erghmm... what about Emacs? I'm sure, it absolutely can be count for a "successful system that have to be maintained for ages". For far, far longer than any Java-based project that ever existed.

Even though Elisp lacks:

- static typing

- OOP class system (until relatively recently)

- Modern package management (until ELPA/MELPA)

- Multi-threading model

- JIT compilation

Perhaps "the secret sauce" of successful software is in simplicity? Maybe some programmers just get it, and for others, it is such an obscure and mysterious entity. Some programmers write "programs to program computers", and some may have realized that they are not trying to solve purely technological problems, but they are, in fact, tackling socio-technological problems, and they write programs to communicate their ideas to fellow human beings, not machines.

Re: Why we built Vade Studio in Clojure

#75
post #46

Earlier quoted context omitted.

One of the myriad reasons why Common Lisp is far superior to Clojure is the ability to (declare (type Integer m))

> myriad reasons why Common Lisp is far superior to Clojure Some narrow view. Have you tried thinking that maybe Clojure intentionally chose not to include type declarations because they can lead to a messy middle ground? After all, maybe not every feature from Common Lisp needs to be replicated in every Lisp dialect? Besides, Clojure's Spec and Malli can be far more powerful for validation as they can define complex…

> not to include type declarations because they can lead to a messy middle ground?

What? Type declarations in CL (which came from prior Lisp dialects) were added, so that optimizing Lisp compilers can use those to create fast machine code on typical CPUs (various CISC and RISC processors). Several optimizing compilers have been written, taking advantage of that feature. The compiler of SBCL would be an example. SBCL (and CMUCL before that) also uses type declarations as assertions. So, both the SBCL runtime and the SBCL compiler use type declarations.

> why then it can't be 'hosted' like Clojure?

ABCL does not exist?

https://abcl.org

Re: Why we built Vade Studio in Clojure

#76

Clojure 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.

I seem to be the only one in HN and maybe the world, who worked with decent enough codebases where dynamic typing was no problem at all.

Not that I “feel” it was no problem, but there were no bugs found that could be traces down to that.

It was not a small codebase.

Re: Why we built Vade Studio in Clojure

#77

Because 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.

OOP generally "hides" data as internal state of class instances. Everything is private unless expressed as a method on an object. The two sentences around the one you quoted should answer the question as well: > With Clojure, we modeled the entire collaboration system as a stream of immutable data transformations. Each user action becomes a transaction in our system. And > When conflicts occur, our system can merge c…

Appreciate the breakdown.

Re: Why we built Vade Studio in Clojure

#78
post #44

> 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...

If it took fewer lines of code that's something to consider too.

Re: Why we built Vade Studio in Clojure

#79
post #13
post #7

Earlier quoted context omitted.

I 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 " is the future, it's going to be great…

Yeah, 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.

Just doing the the thing, oddly lets you sleep on it, and the brain often has the a more optimal way waiting in the morning.

Re: Why we built Vade Studio in Clojure

#80

Because 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.

In Clojure, treating data as a first-class citizen means that data structures (like maps, vectors, sets) can be:

1. Passed as arguments

2. Returned from functions

3. Stored in variables

4. Manipulated directly

5. Compared easily

Unlike some languages where data needs special handling or conversion, Clojure lets you work with data structures directly and consistently throughout your program.

This philosophy extends to how Clojure handles data transformations. For example, transducers are composable algorithmic transformations that can work on any data source - whether it's a collection, stream, or channel. They treat the data transformation itself as a first-class value that can be composed, stored, and reused independently of the input source.

This first-class treatment of both data and data transformations makes Clojure particularly powerful for data processing and manipulation tasks.

That's why Clojure often finds strong adoption in data analytics, fintech and similar domains. The ability to treat both data and transformations as first-class citizens makes it easier to build, for example: reliable financial systems where data integrity is crucial.

Post reply on HN