It's interesting to compare this to a lot of tetris clones written in TypeScript. There are a few that take enormous pleasure in defining a type hierarchy and what not.
Contrasting that to the very compact representation of tetrominos
{:I {:color "#1197dd"
:dim [4 1]
:zero [1 0]
0 [[-1 +0] [+0 +0] [+1 +0] [+2 +0]]
1 [[+1 -1] [+1 +0] [+1 +1] [+1 +2]]
2 [[-1 +1] [+0 +1] [+1 +1] [+2 +1]]
3 [[+0 +1] [+0 +0] [+0 -1] [+0 +2]]}
and the very cute rotate function: (defn rotate [r] (-> r inc (mod 4)))
gives you a good idea what a Lisp is about.Clojure has better and more map handling functions in the std lib for sure, but I find that with the help of some libs you can write lots of Javascript in a Clojury way without too much hassle.
The goal actually is this: being able to write descriptive and understandable code for others and oneself.
Come back to the code a year later and is it still understandable? Lot's of cute character-level operators and fancy control flow is maybe not the way to go.
Except that with static types, you'd gain a lot of clarity, efficiency, and future maintenance, one of the downfalls of Lisp.
Both the game and the source are much more minimal, it's very easy to customise the rules. You can see the source here: https://github.com/gunn/tetris/blob/master/src/store.js
pure-store is a library I made for very simple but efficient state management. The entire source is this file: https://github.com/gunn/pure-store/blob/master/src/index.ts
[1] https://github.com/yogthos/clj-tetris/blob/master/src/tetris...
A few years ago some friends and I wrote a tetris clone to celebrate the 30th anniversary of tetris and learn ClojureScript in the process. Really fun group project.
Playable here: http://t3tr0s.com/