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