(frequencies (map second v))
;; => {"one" 2, "two" 2, "three" 1, "four" 1}
;; or:
(update-vals (group-by second v) count)
;; => {"one" 2, "two" 2, "three" 1, "four" 1}
;; +(#:'=v[;1];?v[;1])
;; flip(count each group v[;1];unique v[;1])
So, shorter than the readable K version in a Lisp. (println
"Log in by"
(case user-id
0 "root"
1 "local admin"
(format "regular user (id: %d)" user-id)))
In C, you have to introduce a variable for no good reason (or do some non-idiomatic, ugly, nested tertiary operators that get uglier the more cases we have). user_name = switch { ... }
Because switch is an statement. words.map &:length
# or
words.map { |w| w.length }
...because methods are really just polymorphic functions, but language designers chose syntax that doesn't compose elegantly. (println (if me? "me" "you"))
Because, duh, we wanted an `if`. if (is_me) {
println("me");
} else {
println("you");
}
Absolutely nothing. The parens on the conditional, the curly braces, the semicolons, the `else` keyword—they're essentially meaningless incantations to appease the compiler. And we've introduced an undesirable opportunity for the two branches to accidentally diverge over time.
With `datomic.api/with`, you can apply new datoms and get back a new DB value. Repeat this process as many times as you want, in as many directions as you want, switching as you choose. You're building a tree of immutable DB values—seems clearly like branching to me.
If by "read only" you mean that they're not persisted to disk, then that's an important point, but it surely doesn't obviate the utility of the functionality. It's useful in a number of cases, and especially testing scenarios like the Xata article describes.
If you built an immutable database that persists the branches, that is very cool and sounds useful—kudos! That said, I also don't want to downplay the utility of what Datomic does; it's a major help to me.