Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Tetris in ClojureScript (shaunlebron.github.io)
295 points by simongray on June 14, 2021 | hide | past | favorite | 33 comments


This was the final push I needed to learn Clojurescript.

Absolute awesome work.

I always kept my distance from Clojure because of the reliance on the Java ecosystem but having a productive and stable language that is a pleasure to work in and that transpiles to JavaScript seems like a good deal. Plus a solid REPL-based workflow and rapid prototyping support, something I sometimes miss from more static languages.


If you are getting into clojurescript, take a look at shadow-cljs for the build tool. It provides a better experience than the built-in tooling IMO.


http://clojurescriptkoans.com/ is a great way to get started with the essence of the language.


Looks nice in demo... github shows also the ugly bits.


Great work!

I love the idea of making code and data alive, interactive and illustrative. Reminds me a bit of Bret Victor's talks, essays and prototypes illustrating how interactive, graphical thinking can enhance understanding and even creation.

Imagine our editors doing this by default, what it would mean for documentation, code quality and enhancing our ability to understand and communicate these concepts with augmented code.


Check out some of the videos on Youtube of the Genera Symbolics Lisp Machine platform.


Shaun Lebron has a bunch of interesting stuff on his github[0] involving closurescript.

I haven't toyed with closurescript yet, if anyone has any experience with it, what are its strengths and weaknesses? I' ve been learning scheme/racket for the past year and for learning purposes Dr Racket is more than enough for now, but sometime in the future I'd like to branch out of that.

[0]: https://shaunlebron.github.io/


- Low changes/grow. This demo was written in 2014 and it probably still look like as if it had been written in 2020. - Easy interop with any npm library. Just import and use it.


I wrote about my journey covering Clojure's pros and cons: https://medium.com/swlh/what-i-learned-after-writing-clojure...


"It has a slow startup time. Clojure runs on the JVM and has a significantly slower startup time compared to Node. Again, this is only a problem from an outsider’s perspective. We have REPL. You start the app only once, and it keeps running in the background. You can interactively include new changes, without having to startup every time."

I've been using Clojure for about 8 years and this is one of the talking points I find most annoying. The slow startup time is a disadvantage, and it should be owned. It disqualifies clojure from a large class of applications and if you're not honest about it you lose credibility, and you retard potential attempts to solve it. It doesn't mean you can't write software with Clojure, but be honest about the fact that it makes lots of types of usage (not all) a poor match.


Right. I find it annoying too, but for the opposite reason.

Since GraalVM, Babashka, and before them Lumo and Planck, or just plain CLJS + NodeJS, Clojure (the language) has several answers to those use cases, and it’s unclear to me at least why this is a point of contention regarding Clojure (the JVM implementation). Should we also bash CLJS for being single threaded?


And now that it's honestly approached as a potential issue, you can talk about the tradeoffs involved here. I haven't followed those projects closely so correct me if I'm wrong, but Babashka is an interpreter that implements a "substantial subset" of Clojure, right? GraalVM seems amazing, but it also is not a guaranteed seamless experience, either (no eval, partial support for reflection).


The faster startup time is one reason I've thought that clojurescript on Node (shadow-cljs makes this really easy) could become more popular than Clojure Classic.


If you want fast-starting CLI apps in Clojure, there's a wide variety of options such as:

- CLJS + node

- Babashka

- Graal native compiled Clojure

Here's a fast-starting CLI app I made in CLJS+node:

https://github.com/hugit-project/hugit


Your talk linked from https://shivekkhurana.medium.com/reaching-flow-state-with-cl... was absolutely brilliant.


ClojureScript is awesome.

There are several tools available for live-coding (REPL-driven development) such as more recent shadowcljs or the older Figwheel.

Rum is a powerful wrapper over React.js and you can live code and see instantaneous results in the browser (using shadowcljs or figwheel).

ClojureScript's strengths largely stem from Clojure -- collections as fundamental types, REPL, macros, immutable datastructures* and lovely syntax.

As far as cons go, it takes some time to start up a REPL and making release builds is an extra step, but should work just fine unless you're a newbie like me and you leave strange unnecessary lines in your code. Javascript and js/CSS interop is there, but it's not super obvious and takes some getting used to what it looks like -- luckily there are enough online writeups to make that process easier.

The addage "why clojurescript? Because clojure rocks and javascript reaches" sums up nicely the motivation.

You can have largely isomorphic code on the front-end and back-end, which lends nicely to creating server-side rendered versions of SPAs for search engine indexing and fast load times. However, the server-side copy and the client rendered copy must match exactly for this to work, which can be a bit of a "thread the needle" kind of problem.

* immutable datastructures are awesome, contrast with mutable datastructures and "location oriented programming" -- any time you "edit" a value you're actually creating a new datum. This is done with atoms (immutable data stores that need to be dereferenced to retrieve their value) and operations such as swap! and reset! that either apply a function to the current value of an atom, resulting in a fresh new atom with the new value, or overwrite the atom completely with some value, respectively.

So yeah, if you like live-coding and appreciate the power of lisp, it's a really nice fit. Yes, the way to do stuff is "opinionated" but it's opinionated in what many years of trudging through the tar pit* would suggest is the right (only?) way to do things.

* Out of the Tar Pit [http://curtclifton.net/papers/MoseleyMarks06a.pdf]

I highly recommend Rich Hickey's talk "Are we there yet?" to give you an overview of the motivations behind Clojure and subsequently ClojureScript. [https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hi...]


As you, I learned scheme first, chicken scheme! I like CLJS, your code will likely be small and expressive. The hot reloading another multiple of productivity added. And having a REPL that can connect to the browser is great. But CLJS has some pitfalls.

It's JS underneath so you still need to know it. Because eventually there is a large enough problem someone else solved and you need to understand their code, shipped as a npm package. When you are solving some problem and researching, most people use JS, so you will have to go through the extra step of translating JS code in your head to CLJS. This could be anything from browser quirks to React Native workarounds.

I don't think the tooling is enough for when complexity grows. It can be difficult to quickly understand how the code glues together, finding references to functions and refactoring. It is a dynamic language, and have all the problems that comes with that.

My assessment is that if you are making a browser only fronted with reagent (and reframe) and limited scope. Of course having a backend in either CLJ or CLJS as well to benefit the most.


That is really cool and well done, thanks for sharing.

One question I have though, is the square piece supposed to rotate like that, i.e. shift up and down while rotating? I think this might be a bug.


I agree, the rotation function could see some ergonomics improvements with minimal code changes.


That's really cool; thanks for sharing the code in an understandable way.

Here's a little 'game' I'm working on with some simple physics in ClojureScript: https://github.com/celwell/wordsmith


Shaun also released the really neat Parinfer package as well:

https://shaunlebron.github.io/parinfer/


I was surprised to see the repository was Archived. Is it not being maintained now?


I maintain an updated fork: https://github.com/oakmac/parinfer


Great demo!

Here's a simple Snake implementation I wrote in CLJS + quil a long time ago:

http://divs1210.github.io/snake-machine/


I wrote Pong in Clojure back in 2009 in <200 lines. https://imagine27.com/pong_in_clojure


Now I am tempted to share 2D breakout game I built using ClojureScript.

On Slide 3, if you drag piece(cursor) to leftmost or right most side, part of piece is getting chopped.

Great work by the way.


Which tool was used to create the presentation ?


looks like it is custom built: https://github.com/shaunlebron/t3tr0s-slides


That's one of the coolest programming demos I've ever seen!

Suggestion: make the completed rows fade asynchronously.


It does. <! reads from a channel that closes in the specified timeout. It is non-blocking. (similar to the away/async JS magic - rewrites the go block to a state machine)


An (partial) implementation of Tetris Attack (Panel de Pon) in Clojurescript


Cool, thanks for sharing.


awesome dev demo! no wall kick though :P




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: