Back

Developing a Space Flight Simulator in Clojure

230 points5 monthswedesoft.de
iLemming5 months ago

I just can't wait to see how Jank gets production-ready and absolutely blows the indie gaming community. Hopefully, very soon.

msk-lywenn5 months ago

Programming is a tiny part of game development. No programming language would blow anything in the indie game community. It would be nice and welcome, but it wouldn’t revolutionize anything.

diggan5 months ago

> It would be nice and welcome, but it wouldn’t revolutionize anything.

I dunno, it'll certainly revolutionize my world once it's ready. A editor connected REPL, changes to running games on the fly while keeping existing state, using a well-designed language like Clojure but getting the performance (or similar) of C++ and native binaries.

It's pretty much a win-win-win for me, especially if I can replicate the speed of development I get with normal Clojure but for game dev.

dapperdrake5 months ago

If it is built in Lisp it will end up very customized. Just look at how far people take their emacs setups. It will be like a bespoke glove.

diggan5 months ago

Yes, you don't have to keep on selling it to me, you've hit oil already! I'm eager to reach the future :)

+1
iainctduncan5 months ago
dustingetz5 months ago

the Arcadia team spent several years on this hypothesis, I am not sure the idea of a Clojure REPL for gamedev is free of impedance mismatches

+1
ijk5 months ago
+1
iLemming5 months ago
MangoToupe5 months ago

> Programming is a tiny part of game development.

This is a weird take. It's a tiny part of game development until you can't program. Then you realize it's actually a huge part. Particularly for "indie" game development.

Ultimately code is just a tool, but it's still a tool that can translate into rapid iteration or into friction.

iLemming5 months ago

> Programming is a tiny part of game development.

Yeah, jut like writing is a tiny part of book publishing. What the heck are you even talking about? Programming is absolutely fundamental to game development - it's literally what makes games exist and function.

I'm not talking about "revolutionizing" anything, but maybe you haven't noticed how Unity democratized gamedev and how GDScript made game logic accessible. There is absolutely a sizable chunk of the market for the Lisp-based gamedev - look at Lua/Fennel gaming community - LÖVE2D, Pico-8, Defold engine, etc.

Having performant Clojure option (which Fennel ain't - it's only "like" Clojure) would be absolutely wonderful news.

suby5 months ago

I think Jank will find its people, but I don't know how many of those people will be indie game developers. I'm sure some will be, but on the whole I don't think most indie game devs are clamoring for using clojure, if only if it wasn't for the JVM or the performance. I doubt many indie game developers are even aware of what clojure or jank are, or even much about functional programming to be frank.

For indie game devs you're competing against engine ecosystems like Unity, Unreal, Godot. If someone is inclined for more of a DIY route, you're competing against Lua (love2D), C# (monogame), Javascript (...), or for the people who care about performance, C++, Rust, Odin, Zig, and soon even Jai. It's a very crowded competition space and again, I think overwhelmingly the people in this space aren't dreaming of programming in a functional style.

iLemming5 months ago

> you're competing against Lua

There's not exactly tiny community (but it's not huge either) that programs against Lua-based engines using Fennel - a Clojure-like Lisp. Jank, aimed to have one-to-one Clojure-parity, I think would be great news.

> the people in this space aren't dreaming of programming in a functional style.

IMO because they are extremely pragmatic and there still, doesn't exist a good, practical way to program games in a functional style. Jank may open that possibility.

pjmlp5 months ago

Then there are folks like Notch, that by not following such advices got gold, as they managed a great additive game, regardless of the technology stack being used.

There is also 80% of the mobile phone market available, in the context of JVM like ecosystem to target, and avoiding NDK tooling is gold if one really doesn't need it, as its experience still sucks after all these years.

suby5 months ago

I was not meaning to say that anyone was wrong for their technology choices. Personally I think Java is great and some of my favorite games are made in it. I'm just saying that I don't see jank or clojure for that matter catching on because it isn't where the head space of the indie gamedev scene is at, and I don't see this changing, especially given the number of competing stacks.

+1
dapperdrake5 months ago
pjmlp5 months ago

Ah, that is a good point.

MathMonkeyMan5 months ago

Guile has [multi-methods][1] and [fast hash maps][2], but not yet [dynamic vectors][3].

Clojure's data structures are easier to use, though.

[1]: https://www.gnu.org/software/guile/manual/html_node/Methods-...

[2]: https://www.gnu.org/software/guile/manual/html_node/Hash-Tab...

[3]: https://lists.gnu.org/archive/html/guile-devel/2022-01/msg00...

wedesoft5 months ago

Yes, I forgot. However Clojure multi methods are more generic in that the function computing the dispatch value can also be defined.

exabrial5 months ago

Clojure is such a departure for me, coming from C-Like languages. I have absolutely no idea whats going when looking at the code.

JoshCole5 months ago

Lisps (like Clojure) treat code as data (lists), so you write: `(if x (y) (z))` instead of Python’s `y() if x else z()`. So the code is more concise, but does less to walk a novice through it.

This gains a huge advantage, which allows even more concision: all code is data, so its easy to transform the code.

In Clojure if you want to add support for unless, a thing like if, but evaluating the opposite way you could do this: `(defmacro unless [p a b] `(if (not ~p) ~a ~b))`. Obviously if you wanted to do the same thing in Python you would in practice do `z() if x else y()`. However, you would do it that way because Python isn't as powerful a language. To actually do the same thing in Python you would need to...

1. Add __future__ support.

2. Update the Python language grammar.

3. Add a new AST type.

4. Add a new pass stage to the compiler.

5. Add a python library to integrate with this so you could use it.

Then you could do something like:

    from __future__ import macros

    defmacro unless(pred, then: block, else_: block = []):
        return q[
            if not u(pred):
                u*(then)
            else:
                u*(else_)
        ]

So in the trivial case its just hundreds of lines harder plus requires massive coordination with other people to accomplish the same feat.

This sort of, wow, it takes hundreds or thousands of lines more to accomplish the same thing outside of Lisp as it does to accomplish it within Lisp shows up quite often; consider something like chaining. People write entire libraries to handle function chaining nicely. `a.b().c().d().map(f).map(g)`. Very pretty. Hundreds of lines to enable it, maybe thousands, because it does not come by default in the language.

But in Lisp? In Clojure? Just change the languages usual rules, threading operator and now chaining is omnipresent: `(->> a b c d e (map f) (map g))`. Same code, no need to write wrapper libraries to enable it.

roenxi5 months ago

That doesn't look like a factor in the article though, he isn't using many if any macros that aren't part of the core language. And the one macro I do spot (defcfn) is pretty mild in context.

+3
sabellito5 months ago
wedesoft5 months ago

I use a few macros for creating contexts (i.e. with-texture, with-stencil, with-scissors, with-tar). Also I have macros for rendering (onscreen-render, offscreen-render). However I try not to overuse macros.

exabrial5 months ago

This was incredibly useful

roenxi5 months ago

Fun fact: the big difference isn't the syntax. Lisps only go from foo(bar baz) to (foo bar baz) which is a change but not really much of one. The change is actually the immutable and high performance basic data structures. Clojure can do something that something like C can't do - cheaply create a copy of something with a small change. That leads to a completely different preferred code style in the Clojure community that is a big departure from C-like languages which make heavy use of variables. The code is doing something practically different from what a C-like language can ergonomically handle.

Zambyte5 months ago

Clojure has a bunch of other syntactic structures not found in other lisps that makes it a lot more visually noisy. I'm very comfortable with Scheme and I can very quickly absorb Scheme code when reading it, but I have to very slowly decipher the code in the article.

+1
iLemming5 months ago
pjmlp5 months ago

Many of Lisp ideas are possible in C++, but I guess that depends how much you know it.

iLemming5 months ago

That's just existing muscle memory. Nothing is wrong with you and nothing is wrong with Clojure. I had the same feeling when I started with Lisp. Give it some time, it's absolutely worth it. Interestingly, every single programmer I introduced to Clojure as their very first programming language had no issues picking it up. Later, they complained about difficulties getting used to Javascript and Python.

rufusthedogwoof5 months ago

it's not code it's data. :) -macro

LouDNL5 months ago

As a Clojure developer for many years, this is one of the coolest projects I've seen! Going to read your blog with interest!

JoshCole5 months ago

Very cool work Jan!

Have you tried experimenting with ham-fisted? I've found the libraries in the techascent part of the Clojure ecosystem to be very good performance wise. Ditto for neanderthal.

wedesoft5 months ago

I am aware of Neanderthal. I think it is more suitable for larger tensors and matrices. Will have to check out what ham-fisted is about.

nodesocket5 months ago

Wow, this is impressive not using standard gaming framework like Unity or Unreal.

adastra225 months ago

I mean it is pretty cool, but do people not roll their own graphics engines anymore? When was in to hobby game dev back in 2000 or so, we all wrote our own systems.

viccis5 months ago

No, that's rightfully viewed as a waste of time if you want to make a game (vs if you want to make a game engine)

fkimexcited5 months ago

Using same game engines and physics lead to a generic look-and-feel, even if they do allow for a large amount of creativity and differences.

This _looks_ different, which is awesome!

Even if the atmospheric effects still need some honing, there's a ton of work around lighting to eventually be done, the edgy polys make it look about 20 years old, and it's a bit pixel-y around the edges, this is headed into a spectacular direction!

If my ADD were in charge of this project, here's what I'd add:

- Optional stars / environment - a universal simulation would be unrealistically computationally expensive, but just having stars would be neat. Later, a planet in the horseshoe nebula, or playing spherical versions of recorded or streaming video for AR or making homegrown music videos.

- Ability for others to share datasets - the Earth is f-ing awesome and I can't wait for the Moon! What about a place where users could share different datasets like Arrakis with it's sand dunes and 2 moons or Tatooine with its 3 moons, then maybe they could fly in a heighliner, landspeeder, frigate, or imperial lambda shuttle, or even the jetcar from Buckaroo Bonzai?

- Solar Mayhem - Simulate a crazy atmospheric and orbital space war simulation or arcade-style game with satellites, lasers, plasma / electrical discharges and arcing, dust and nanorobot clouds, cloaking, jamming, ramming, repairs by robots and soldiers in tethered spacesuits, zooming cameras and 2D/3D scanners in different wavelengths, spacefaring naval ships, UAPs and other secret government vehicles, and complex 20th century fantasies of space stations running on nuclear and otherworldly power.

- Eclipse Support - when you add the Moon, doing an eclipse is not just the shadow but you'll need to handle the cool colors on the edges when the moon is covering the Sun.

- Ocean Simulation - Orcas, fish, eels, coral, lobsters, octopi, old ruins, Atlantis with its merpeople, tictacs and other USOs!

- Beautiful water features in Baltic Sea, Yukon Delta, Mississippi River, Lena River, Petermann Glacier, Brunt Ice Shelf, South Georgia Island, Guinea-Bissau, New Caledonia, Patagonian Sea, and the Icelandic and Norwegian fjords.

- Weather simulation with a way to pull in current atmospheric data historically to fly through hurricanes and tornados or simulate tsunamis after earthquakes.

- Subterreania and the inner sun of the Earth.

- A 2D sim for flat earthers.

Capricorn24815 months ago

> Using same game engines and physics lead to a generic look-and-feel

Sure but they're talking about using the same game engine, not the same physics engine. I don't think anyone would say Split Fiction looks at all like Oblivion Remastered. Though they both use Unreal Engine 5

seabass-labrax5 months ago

That's would certainly be an awesome game, but did you know that your "Solar Mayhem" concept already exists? Children of a Dead Earth - it's probably a bit more austere by virtue of limiting itself to only somewhat-plausibly realistic weapons, mind you.

https://childrenofadeadearth.wordpress.com/

wedesoft5 months ago

That's a lot of features. Moon is on my TODO list though and eclipses would be nice as well.

seabass-labrax5 months ago

The hardware graphics acceleration stack is heavily shader-based now, so there's less and less graphics code being written in systems languages like C. In a way, people are still writing their own graphics engines, it's just for such a different platform from the unusual Turing-computer CPUs that all the old techniques go out of the window.

Nothing stopping you from writing it the old fashioned way though - you can just keep generating a single screen texture in the CPU and let the GPU idle!

pjmlp5 months ago

As old dog I find this kind of funny, because for folks of my age C was like C# is seen nowadays.

Any serious game would be pure Assembly, and when using Pascal, C or BASIC compilers, they would be full of inline Assembly, almost like a poor man's macro Assembler, as the quality of code generation was awful.

seabass-labrax5 months ago

Good point! Wasn't the Sony PlayStation significant for being the first console to ship with a C API from the manufacturer, or am I misremembering? I always thought that Net Yaroze sounded fantastic but never ended up getting one.

Oh, and another question on that topic: did you ever write self-modifying code for games, or had that already gone out by 2000?

simne5 months ago

Always, when read about "functional language usage in simulation", I check if OpenGL binding used. Other important things are physics engine and collision engine, because these are more than 90% of all code.

Unfortunately, just as I suspected, this project use OpenGL (nearly all implementations are C++), and C++ collision/physics engine.

So, looks like, in this project, Clojure is used just as high level script to orchestrate all C++ parts, may be later we hear about some game scripting, but for simulators they are not as need as for example for RPGs.

I agree, Clojure is better than C++ for orchestrate, but I have seen so tiny number of art persons familiar with functional paradigm, so this looks like beautiful dead end.

Again, this is really beautiful and respectful achievement for author, but people I seen working in gamedev will not accept such approach.

yogthos5 months ago

That's literally the whole point of using a high level functional language though. You use it to express the business logic of your app, the code that you care about. The fact that the underlying details of how rendering and physics are done is written in an imperative language doesn't really matter here. What I care about is maintaining the logic of my application, and that's what a language like Clojure makes easier to do.

simne5 months ago

Why not use some simpler, like old good UNIX Make? Or for business logic existing for a long time Lua, which is much easier to learn/use than Clojure.

I love functional paradigm, but sometimes fp lovers, looks like evangelists of Blockchain or LLMs - not bad things, but all have their limits, and not very useful without powerful support of large library of fp structures and debugging programs. So, trying to use fp, you dive into abyss, writing with fp, but debugging with low level C debugger.

BTW, as I know, OcaML, flagship of fp, just don't have graphics debugger, so people used to write on Haskell using old classic REPL technology, than, thanks to syntax similarity, most code just compile on OcaML without additional moves.

johnisgood5 months ago

OCaml supports imperative, functional, and OOP just fine, and you use whichever makes more sense, and it has a REPL, too, most popular one is called "utop", but "ocaml" works. As for graphics debuggers, I have no idea if OCaml has a graphical one (if that is what you meant), but there is ocamldebug[1][2].

That said, I agree, why not just use Lua? Seems like the perfect language when you only care about the game itself and not the underlying stuff. There are many other alternatives that are better than Clojure anyways. I might be pessimistic, but I doubt Clojure is going to catch on.

[1] https://ocaml.org/docs/debugging

[2] https://caml.inria.fr/resources/doc/guides/debug.en.html (contains section "Using the debugger under (X)Emacs")

+3
simne5 months ago
+1
iLemming5 months ago
iLemming5 months ago

> Lua, which is much easier to learn/use than Clojure.

As someone who used both, I can certainly argue for that point not being true at all, and in practice it isn't.

Lua's syntax is a mixed bag and even after years dealing with it, I just can't stand how ugly the darn lang is - I just never know how to format it for better readability. Metatables are powerful but conceptually complex; global by default and 1-indexed arrays - who the fuck even thought it was even worthy to call it "an idea" - those are just plain stupid. Nil handling can also get weird.

While Clojure for sure may feel like having a steeper learning curve, once you get past parentheses - it feels so much simpler.

+1
simne5 months ago
yogthos5 months ago

I can only assume you're trolling here or that you've never actually built any large applications in your life.

simne5 months ago

This is interest assumption, but let's think, who are building large applications?

I've taken part at some large apps built inside one company in extremely short time. And no, in my list only more or less adequate platforms - Perl, MS VBA on web.

And I've countless times just rebuilt some large systems from sources - FFMPEG, Unreal 4 environment, what interest, whole FreeBSD 4.x with BSD environment including XWindow is smaller than U4.

And what was really big pain, I tried to work with NASA OpenMCT, and because it was based on Javasript technologies, I spent huge amount of time to figure out, where end server-side and where begin client-side. I think you understand this is important, because each part debugged with very different instruments and techniques.

And what I must say there, games are very different in scale.

- Sure, exist very large games (named AAAA, like cinema movies, and have so huge download size, as for example new Stalker, that my friends working in telecom complained, it was like huge DOS attack when game came out). And what also interest, AAAA games tend to make their own custom game engine, yes, each game with own game engine, because for them easier to figure out in their own code than to learn ready game engines.

Also exist industry of game studios, medium businesses, but they tend to be much like big businesses just without resources to make own engine.

And also exist huge industry of independent -games (i will use indi- name), which have very small amount of code, because of tiny budgets or just "no-budget" work, in many cases literally made by one person, who making pictures, code and sound himself. And in reality I know very few cases, where indi- makes his own engine, but most others are slightly modified already known game mechanics.

What important - big business will not use subject code, nearly guaranteed, because they have very specific demands about maintenance, to fulfill them need at least medium company; there is more probability to reach medium business clients, they are trying to be "like a big boys", but in most cases possible to achieve some understanding; and the most probability is to reach indi- developers.

So, what we talking about now, is mostly about indi- developers, one-person sized commands, and it is very god if they will just use C-like languages, but you cannot account for them to use fp paradigm.

I cannot at the moment give estimate of distribution of game sizes, but now tend to appear more indi- developers with small games (and sure, using some made by other people.

https://nasa.github.io/openmct/

sethev5 months ago

Computers are stateful and imperative, so any functional language that runs on real computers has a stateful and imperative base. OpenGL vs not seems like an odd place to draw the line on what you would consider functional vs not.

simne5 months ago

> Computers are stateful and imperative

This is semi-Truth.

Modern off the shelf Microcomputers nearly all imperative, because marketing won, but when world was under Mainframes (nearly up to 1980), existed many examples FP-optimized architectures or high-level architectures, even some of them was commercially successful (Lisp computers and some high-level mainframes).

Also, most developers don't deal with naked hardware, but working with libraries of structures and libraries of high level algorithms, this named abstraction layer. Just some existing abstraction layers are less abstract and other are more abstract. As example, in Windows (and in most UNIXes) file abstraction is very simple and just imperative, but in MacOS it is OOP (derived from NEXTStep as I hear, based on ObjectiveC), and also exist some other OSes based on OOP languages, like BeOS, even when MacOS/BeOS are now running on same x86 hardware.

So possible just run inside higher level VM.

And mathematics is not prohibiting FP-machine, they could have very effective implementations with modern math.

What really problem, except of Prolog, I don't hear about high-level debuggers for fp languages, so writing on for example Ocaml, you once end up looking on fp structures with old C debugger, which sure don't see fp structures.

sethev5 months ago

A Lisp machine is no counterexample - they had assembly language instructions that were tailored for Lisp, but were still very much imperative. In fact, Clojure is significantly more functional than other Lisps, which used mutable cons cells extensively. Object oriented languages are also stateful and imperative, so I'm not sure why those are relevant here.

I'm not saying these things are bad - it's possible to imagine a computer architecture that makes functional programming easier, but it's really hard to imagine a useful computer that is not stateful and imperative! What would it do, in that case?

OpenGL vs not-OpenGL still seems like a very arbitrary way to classify simulations.

+1
simne5 months ago
wedesoft5 months ago

In the past I have done some rigid body physics in GNU Guile (see https://www.youtube.com/watch?v=zBq3kW2jVxs for example). Of course if you need to simulate many objects, you will hit performance problems sooner if you don't use C/C++/Rust. Also the developer of Jolt has solved quite difficult problems, so I was quite happy to use it instead of rolling my own.

beepbooptheory5 months ago

What would have been an alternative way to go here that would have been more acceptable to gamedevs?

tliltocatl5 months ago

There is an (IMHO quite underexplored) alternative of using HLL as a metalanguage for generating low-level code. Like Chisel/Spinal does for Verilog RTL, but with C or LLVM IR instead of RTL. I. e. terra-lang did this with Lua (afair didn't took off because of unfixably bad design choices from the start).

Why this matters: compile-time metaprogramming is the way to provide zero-cost abstractions. HLLs tends to avoid metaprogramming because it's hard, instead relying on rich runtime (i. e. late binding and dynamic dispatch). Sometimes (i. e. in game engine code) that's not really an option. And metaprogramming is best done is something lisp-like, rather than C-like or C++-templates like.

As to why this is underexplored, I think there are multiple reasons:

- The most important one: those who care about the language tends to spend so much time on the language that they never get to the actual product,

- We already have C++ templates which can do anything (they are also an unholy ureadable mess because they were invented for a completely different purpose) and C macros (which are also unholy unreadable mess because K&R hated macroprocessors passionately and curbed cpp to a bare unusable minimum). And people exposed to those conclude that any compile-time metaprogramming must necessarily be an unholy unreadable mess not worth exploring.

- Most library bindings are in C, so any such system should include a C parser. At which point you wonder why bother at all?

simne5 months ago

> using HLL as a metalanguage for generating low-level code

Unfortunately, this is very long known dead-end, because very few programs written evidence-based, but most just begin their life with first production release, and on some platforms (JVM), more than 90% of developer time spend to refactoring and maintenance of existing code, and many people don't know anything else.

So, templates are not enough to break through this wall, need infrastructure of libraries and debuggers, and may be macros, etc, designed specifically for fp and be at least on par with their imperative counterparts.

simne5 months ago

I don't know such way now.

From what I see, looking promising, to discontinue UNIX systems (based on C, and yes, Windows is also favor of UNIX, as NT was made directly on foundations of VMS from Digital), and switch to something more high-level, like OpenStep (with high usage of SmallTalk), or at least BeOS (based on C++).

Sure, would be better to use Prolog based OS, when one will appear, or may somebody will create OS based on OcaML (Haskell, Rust).

What I see problem for gamedev, in many cases they need very high performance, and when nearly all target (current) OSs are just C-machines, it is very much like discover epic huge wall, when need to switch from OcaML level to C to get additional few FPS.

So most people choose easy way, they learn just primitive subset of C++ and work with it.

https://en.wikipedia.org/wiki/Comparison_of_operating_system...

simne5 months ago

BTW I have an idea - for gamedev could be beneficial to make some VM engine (multiplatform), for example like BEAM, why not, but probably something much faster (like LLVM), but including rich library of structures and algorithms for structured data and optimized for GD, and with good debugging tools for high level structures.

This may become gamechanger, as it could be very fast, but high level abstraction, so people don't need to dive into machine level, and could work on high level.

simne5 months ago

From second view, looks like good way using ECMA-6 (for example) with Babel and some things added into browser debugger.

So, technically, high-level ECMA-6 language transpiled (more traditional word translated) to ordinary Javascript, and supplied file with structures, similar ideologically to C symbols tables, and within browser debugger (Chrome work) you could see not target JS but sources and debug on high level.

And when your code become mature, you just remove symbols tables and as usual, target optimized code become very much like obfuscated, and you could provide it as closed source.

So, as summary - must have all from list:

1. high-level language translator (may be into assembler, may be into some lover level language, as with ECMA-6 and JS)

2. some sort of debug support (as mentioned symbols tables)

3. good enough debugger, as much close to client platform as possible (Chrome is good example).

simne5 months ago

I worked with IBM PC clones and DOS for a long time. What I seen - just hexadecimal dumps, sometimes picture patterns and nearly nothing else.

Once one boy said me "this is Mac, on it things look different" and shown me just ordinary MS Office (for Mac) files in just standard utility. And I seen really other world - even on old MacOS (7..something), Office files was not just hexadecimal, but I easily see structure. Unfortunately, that's time I have not enough education in CS to understand how structures work, but some things was obvious. These was just some things partially implemented on ObjectiveC (too small objective part and too large C part), but any way it become significant shake of my world.

Unfortunately, in Linux I constantly see the same as in DOS - mostly just hexadecimal dumps, no structure, so developers don't have motivation to use structured data, as it will not help them on build and maintenance.

crichter5 months ago

Jan, This is awesome! I have been following your progress for quite some time now. I actually found your project because you liked my dream chaser model that I put on GitHub some time ago. Really Looking forward to what’s to come and to try out your simulator at some point!

wedesoft5 months ago

Thanks.

shaunxcode5 months ago

This is awesome! Very nice example of malli in practice!

wedesoft5 months ago

Thanks. Yes, Malli is really nice. Unfortunately it doesn't let you decorate type-tagged methods.

rookderby5 months ago

Beautiful visuals. I'd like something to dock with.

wedesoft5 months ago

Yes, space station docking is on my todo list.

Fire-Dragon-DoL5 months ago

This was an amazing blog post, thank you!

wry_discontent5 months ago

Is the code formatting not working for anybody else?

iLemming5 months ago

It took me a minute to realize that you're talking about code formatting on HN, and it has nothing to do with Clojure.

I was like: "What formatting are they talking about? It's darn Lisp - there's no 'formatting gripes' here..." The only thing Clojure devs have to agree on - to align or to indent, and that's all the formatting rules and conventions you need to know about.

Inexperienced newbies say: "Lisp is hard to read", which I think is completely overblown and in fact is the opposite - Lisp is so nicely readable, that even on a narrow screen of a phone it remains readable - the code simply wraps around - a trick Python and Haskell programmers especially hate.

simne5 months ago

I have yesterday tried to read docs (sure, find by google :) ), and there stated "Text after a blank line that is indented by two or more spaces is reproduced verbatim. (This is intended for code.)".

- Tried, and it really work.

https://news.ycombinator.com/formatdoc

simne5 months ago

Just for test purposes.

        ─────────────    
       /             \   
      /               \  
     /                 \ 
    /                   \
    │                   │
    │   circle of power │
    │                   │
    │                   │
    │                   │
    \                   /
     \                 / 
      \               /  
       \             /   
        ─────────────
lyu072825 months ago

just linking the code, I'm just saying that some people put functional languages on a weird pedestal. It doesn't just magically make your code good.

https://github.com/wedesoft/sfsim/blob/main/src/clj/sfsim/co...

wedesoft5 months ago

Yes, the main function is the worst part of the code. Whenever I discover a pattern, I refactor it and put it in a module.

iLemming5 months ago

So what's your point? I guess you haven't even used Clojure, just looked at this specific piece of code and decided for whatever reason is not "good"?

It's as if I posted some text in Sanskrit (which I don't know) and complained that some people put Bhagavad Gita on a weird pedestal - "verdic concepts don't make your religion magically better".

Can you elaborate the heck you're complaining about? Arguing that "this FP code doesn't look nice to me, but OOP generally does", without more context is like arguing that "this French poem doesn't sound nice to me, but English poetry generally does" without understanding either language deeply.

That's just comparing surface aesthetics rather than understanding the underlying paradigms, idioms, and design principles, not to mention the fact that Clojure isn't "purely functional" - it does have object-orientation and polymorphic dispatch and other mechanisms that you've apparently put on some other weird pedestal.