22 ms·
Try Clojure
- hombre_fatal 2y agoMaybe online "learn lisp" repls should implement paredit keybindings in their editor and have a short section on how to manipulate s-expressions. Because you're gonna have to learn it to use the language, but it also helps people understand from the start that "oh, so using the language isn't actually complete shit". Instead, this fact always seems glossed over, and because of it anyone who spends 60 seconds writing lisp by hand into a repl assumes that's the lisp experience and nopes out forever. When in fact paredit makes lisps the easiest-to-edit languages in the world.
- askonomm 2y agoOr Parinfer. I personally like Parinfer more than Paredit, mainly because I can't be arsed to learn a gazillion keyboard shortcuts.
- hombre_fatal 2y agoOh, interesting. Yeah, that's even better for an onboarding tutorial. I didn't know it existed (used Clojure for 6 years a long time ago). Cool: https://shaunlebron.github.io/parinfer/ https://shaunlebron.github.io/parinfer/ I always thought that the surrounding tooling (having to learn how to edit parens productively, using nrepl/cider, maybe even emacs... with evil-mode of course) to be both the worst and then eventually the best parts of Clojure.
- askonomm 2y agoI'm one of those mainstream devs (who also did Clojure for 6 years, coincidentally) who never got into emacs, and always just used the Cursive IDE plugin for IntelliJ and its Parinfer editing mode. I know I probably didn't unlock true god mode of productivity, but it worked fine for me.
- hombre_fatal 2y agoI had already used vim by the time I found clojure during uni (back when I had the energy to learn major new things), but vim support sucked for things like evaluating code blocks in the buffer, so I tried emacs and immediately slapped on evil-mode (vim bindings inside emacs). For those six years I don't think I used emacs keybindings during that time except to move between files and execute clojure code. I couldn't be arsed to learn it. It was basically a fancier vim, haha. These days I use VSCode for all software. At some point in my 20s I found out there's life outside of coding so now I use a less esoteric editor. I'm sure its clojure / nrepl / paredit / parinfer support is fine. (Seems to be this: https://calva.io/ https://calva.io/) Back in 2010 the options weren't as great.
- stefcoetzee 2y agoYup, Calva's pretty great.
- simongray 2y agoI'm the same, always just used parinfer with IntelliJ, though I do know a few paredit key combos that I use occasionally (paredit isn't disabled just because parinfer is enabled).
- globular-toast 2y agoAt the very least they should have auto-closing and matching parens. I dread to think how many people have been put off Lisp because they think we actually type all those parens (in fact Lisp users have enjoyed IDE features many programmers could only dream of for decades).
- anentropic 2y agoI remember trying Clojure a few years ago, and Racket, and had similar problem with both... feels like everybody doing LISPs is using Emacs and it was hard to get a decent set up in VS Code configured and working properly
- writeslowly 2y agoI spent a few months writing a decent sized Clojure program just using my IDE's matching bracket highlighting and some sort of rainbow parentheses settings, and never found it very annoying. I'm not sure there are that many more parentheses than curly-bracket languages, it's just that all of the closing parentheses are more likely to cluster together at the end.
- jwr 2y ago> When in fact paredit makes lisps the easiest-to-edit languages in the world That is true and whenever I switch from Clojure to C, I immediately feel the pain (what do you mean I can't just kill or lift this entire expression?). But structured editing has a learning curve, so it's a difficult balancing game. Beginners are overwhelmed by all the parentheses, while experienced programmers don't even notice them and love the structured editing approach.
- neilyio 2y agoI use Helix [0] myself, which has tree-sitter based commands for moving + selecting up/down/forward/back by expressions. These are built-in and require no configuration. It's surprisingly excellent! Sure, the "language" of paredit features more powerful text manipulation that just simple movement... but combined with the new "jumping" in the latest Helix release [1], it makes for a very impressive keyboard-based navigation system. [0]: https://helix-editor.com https://helix-editor.com [1]: https://helix-editor.com/news/release-24-03-highlights/ https://helix-editor.com/news/release-24-03-highlights/
- silcoon 2y agoTryClojure author here. Thanks for the suggestions! I’ll look into adding parinfer soon and maybe add a section on the benefits of integrating Clojure with the editor.
- drpossum 2y agoI love clojure, but it's really lost a lot of the momentum it had as many imperative languages have adopted parts of functional programming (and much for the better) over the last many years. On the other side I've felt a lot of the ecosystem work that was done has a more "timeless" quality. Coupled with java interop I haven't ever felt wanting when I do reach for it for some hobby projects I keep up with. One thing I will say, since it takes a different tack and philosophy, I think any programmer learning some of it benefits from the different perspective.
- d4mi3n 2y agoIn my experience, the subsets of the community around clojure were one of the biggest problem with it. It's gotten better over the years, but circa 2016 - 2018 it had a spike in popularity despite being very hostile to newcomers. There was an almost apologist attitude towards rough edges or failure modes folks new to the community would fall into. I managed to work with it for a time despite that, but it left me with a bad taste in my mouth. It's really important to make your ecosystem and communities welcome to new users or they're destined to fade.
- bunderbunder 2y agoA somewhat similar thing I ran into is that existing Clojure code can be incredibly difficult to grok if you don't already know the language very well. Some of this comes from lisp's minimalist syntax, which makes it hard to even know what kind of thing you're looking at when you're encountering a new thing for the first time. But the problem is also compounded by some of Clojure's more distinctive (and powerful) features such as ad-hoc polymorphism and using maps to pass function arguments. The closest analogy from imperative languages that I can think of is another language that's famous for being incredibly productive in the hands of a skilled user, but whose code tends to feel kind of write-only: Perl.
- kazinator 2y agoIn Perl you have the dynamism, and the syntax. Evidently, 93% paint splatters, when OCRed, are valid Perl programs: https://www.mcmillen.dev/sigbovik/2019.pdf https://www.mcmillen.dev/sigbovik/2019.pdf I doubt that a similar thing is true for Clojure. Here, the only problem is that you don't know what the symbols and some of the notations mean. You can look at the unfamiliar syntax and know what is a child of what. Most operators are words you can search for.
- pants2 2y agoCool site, I've never tried Clojure before. My first reaction though is that (+ 1 1) is a highly unconventional and possibly confusing way of writing 1+1, and I'm not sure why that design choice came about.
- nayshins 2y agoSee S Expressions: https://en.wikipedia.org/wiki/S-expression https://en.wikipedia.org/wiki/S-expression
- rgrmrts 2y agoThat’s prefix notation [0] and not unique to clojure. [0]: https://en.m.wikipedia.org/wiki/Polish_notation https://en.m.wikipedia.org/wiki/Polish_notation
- weatherlight 2y agobecause lisp and consistency (some-function-name arg1 arg2)
- sek 2y agoLisp is one of the oldest programming languages developed in the 1960, it came before and is very elegant actually. You can write incredibly powerful things with this pattern and it's also really simple to build an interpreter for it with the stuff they had at their disposal at the time.
- baq 2y agoSee also: 'Recursive Functions of Symbolic Expressions and Their Computation by Machine' (1960) [1] [1] https://www-formal.stanford.edu/jmc/recursive.pdf https://www-formal.stanford.edu/jmc/recursive.pdf
- phoe-krk 2y agoTry 1 + 2 + 3 + 4 + 5 versus (+ 1 2 3 4 5) for one nice reason.
- netbioserror 2y ago
- MetaWhirledPeas 2y agoI love it! But is there a back button or key or command? I'm flaky and I need to re-read things a lot.
- varjag 2y agoIt should be trivial to add with all the promise of data immutability :)
- disambiguation 2y ago(prev-step) ?
- MetaWhirledPeas 2y agoWhoa, hacks! Thank you.
- DerCommodore 2y ago[flagged]
- dgoraa 2y agowhy do you need to disclose using that reader comment history has that appended to most of your comments, its rather annoying
- qnsoaejacniln 2y agoThere is XSS in the (my-name) part :) (my-name "<img src='#' onerror=alert(1) />")
- didibus 2y agoNice catch. Is it an issue though when the script injection only runs within your own browser session?
- Jeaye 2y agoNo. That in itself shouldn't be a cause for concern. Local users can do anything to their own machines already. It would be a concern if you persist this to then later be loaded by someono else's machine.
- hpeter 2y agoIt's not XSS if it's not cross-site.
- makach 2y agoThat's a great introduction, but... how to do an if statement would've been cool to add in the tutorial.
- masspro 2y ago<hot-take type="anecdata"> My Clojure experience was that basic dev experience things were shockingly behind where any other moderately popular lang is at. It's been some time though so all I remember clearly is bad error output. Stack traces are hard to read unless you install $random_lib. But worse than stack traces are type errors/"Java errors": if you give the wrong args to a function, the error output is completely inscrutable, generally a very short string like `java.lang.Foo does not implement IBar`, which is only helpful if you kind of know how the Java layer works and all your args are different enough types that you can guess which one it's talking about (bonus: anything function-like is just `IFn` so good luck). Ahhh and that made me remember: the doc situation even for stdlib is bad. Everyone around me used a third-party site clojuredocs.org which has broken-formatted auto-ingested versions of the plaintext official doc strings, because it is still the least bad option. No one has decided on a docstring format. No one has decided on code stylistic things either, which has mostly precluded the existence of auto-formatter tools. The lang itself is good and I recommend folks use a LISP sometime. I was just genuinely surprised a 17-year-old lang was lacking in these areas, and I'd be pretty careful about setting out on a long-term project with it, unless all of those things have radically improved from 6 months ago. (And like other folks said, you genuinely need editor integrations to not be wasting all your time on pren balancing. Not clj's fault, just LISPs in general.)
- neilyio 2y agoI'm an advocate for Clojure, and while I believe that the usability speed bumps are more than made up for, I completely agree with you. The awkwardness of Clojure's errors, REPL experience, and build tooling is a dealbreaker for many. A couple years with Rust has taught me that intuitive errors and tooling will funnel you far enough into language to get you productive, and then you're much more likely to stay. There's just no way I would have stayed long enough to be a Rust professional if it hadn't been for cargo and rust-analyzer. These "non-language" components of Clojure are just not easy enough to use, and its inhibited Clojure's growth. If, however, you do put in the time to grok these parts, the joy of using the language itself never fades.
- joshlemer 2y agoAlong the same lines with the docs, I also find it frustrating that a lot of the very most core basic abstractions and interfaces are left totally undefined in terms of documentation. Take `ISeq`'s definition. Surely, a candidate for the single most core interface. https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ISeq.java https://github.com/clojure/clojure/blob/master/src/jvm/cloju... But like, where is the javadoc? What exactly is supposed to be the contract of these methods `first`, `next`, `more`, `cons`? What's the difference between `next` and `more`? I really just don't like that. Are we just supposed to pick up the core contracts/abstractions through oral teachings and slack channel messages?
- munirusman 2y agoShameless plug: If you’re looking for an online compiler specifically designed for conducting interviews in Clojure, you might find [0] very useful. It’s designed to streamline coding interviews with real-time collaboration features. [0] https://codeinterview.io/languages/clojure https://codeinterview.io/languages/clojure
- Anduia 2y agoI found the red over gray combination a bit hard to read, so I checked it with a color contrast calculator: The contrast ratio here is 3.9:1 (text #DC2626, background #E5E7EB), and the minimum recommended for small text is 4.5:1. Sorry to be that guy :) I am enjoying the tutorial.
- parhamn 2y ago> (+ 1 2 '(1 2)) > "3(1 2)" Yup, I'm out.
- bunderbunder 2y agoFair. I don't mind dynamic typing so much, but I agree that getting clever with automatic type conversion is just plain wat. (reference to: https://www.destroyallsoftware.com/talks/wat https://www.destroyallsoftware.com/talks/wat)
- systems 2y agoI wouldnt call that getting clever, its just a string of what you did > (type (+ 1 2 '(1 2))) #object[String]
- bunderbunder 2y agoThe problem is how you get there. 1 and 2 are integers. '(1 2) is a list. None of them are strings, but + helpfully converts them to strings because ClojureScript is leaking some of JavaScript's wat behavior.
- ARandomerDude 2y agoThat's because this is actually ClojureScript (JS under the hood) running as a browser library. If you try that in Clojure, you'll get: > ClassCastException class clojure.lang.PersistentList cannot be cast to class java.lang.Number If you try it in a "proper" ClojureScript dev environment (shadow-cljs), you get nil as a result with this warning: > cljs.core/+, all arguments must be numbers, got [number cljs.core/IList] instead
- parhamn 2y agoThats actually good to know, I thought this was reflective of Clojure itself.
- 2y ago
- xyzzy4747 2y agoI'm happy with TypeScript, Go, and Rust. Don't feel like learning anything else.
- ekzy 2y agoThen… don’t? No ones is forcing you to try it or even to comment with your close-minded opinion. What does this comment bring to the conversation?
- zug_zug 2y agoI'm with you. I'll even go a step further, since I haven't heard anybody else say this: My hot take -- There are already too many programming languages in use and every engineers life would be easier and productivity would be higher if we standardized. There is almost no situation where making an entirely new language is the optimal solution. And the worst reason of all to make a language is anything aesthetic (e.g. spacing, parentheses, notations) -- all of those cases should be handled via native transpiling in the IDE.
- rads 2y agoHmm, maybe we could come up with a standard syntax? We could call it “Standard-expressions”, or perhaps “S-expressions”? That way an entire family of languages could use the same syntax. Now how do we get people to follow this standard?
- ekzy 2y agohttps://xkcd.com/927/ https://xkcd.com/927/
- zug_zug 2y agoI'm not sure if you meant this as evidence for or against my point, but this is exactly what I mean. Every year dozens of people think they're going to make some holy-grail language and it's 1% different from the prior version but now every single library needs to be rewritten, a dozen years of patches/bugs/security-holes must happen, whole resumes get shined up rewriting tech stacks that were perfectly capable, all for it to be thrown for the next shiny toy in less than a decade. A new language just fractures knowledge.
- jollyjerry 2y agoI still remember Professor Brian Harvey rolling out his terminal on a cart in Berkeley's CS61A and typing out commands in a scheme repl. Learning what a y-combinator was with Structure and Interpretation of Computer Programs, and building my own scheme compiler with scheme.
- bhasi 2y agoOh wow, I didn't know that "Y-Combinator" was not just a fancy name but was an actual computer science concept. Thanks!
- tankorsmash 2y agohttps://combinatorylogic.com/table.html https://combinatorylogic.com/table.html it's hard to read, but there's a ton.
- neilyio 2y agoIf you are new to Clojure and would like to experiment with it in a way that is immediately useful, I highly recommend the Babashka runtime for scripting [0]. It's very fun, approachable, and one of the more polished parts of the Clojure ecosystem. It's a particularly good entry point because unlike full-JVM Clojure it has a very fast startup time. Newcomers can use any file-watching /reloading tools (e.g. nodemon) that they're already familiar with to work with it interactively. Hopefully, a enthusiastic user will graduate to using a REPL connection in their editor for a fully interactive setup. But newcomers tend not to do this... its an unfamiliar workflow to most, and can be pretty cumbersome to setup. [0]: https://babashka.org https://babashka.org
- neilyio 2y agoAnd when you're ready to take the fun to the web, look no further than Biff: https://biffweb.com https://biffweb.com
- packetlost 2y agoI recently went through most of the Biff tutorial but found it seemed to be missing some parts later on that had me scratching my head. It was otherwise a very enjoyable experience and Biff seems like a great way to get a "batteries included" starting point for web (similar to something like Rails or Django, though maybe not as comprehensive as either of those).
- jacobobryant 2y agoMind sharing the parts of the tutorial you had trouble with, if you remember?
- packetlost 2y agoI'll see if I can go back and figure out where I lost track of things. I believe it was right around when making the message entry box functional. I ended up having to dig into the repo to see what I was missing.
- jakebasile 2y agoI'm glad this is back. A version of this existed in the ancient past and helped encourage me to try Clojure which ended up being by far the most impactful decision in my professional life. It went away for a while for reasons I'm unclear on. I use Clojure nearly daily at my job and at home. Sometimes it's standard Clojure, sometimes it's the excellent Babashka flavor which I use as a make-like task runner and Zsh-like script replacement. It's not the only language I use of course, and Go is a strong second place most of the time especially if I need something compiled to a single binary. But Clojure is where I generally feel most at home thanks to the irreplaceable REPL based development flow which is more like a dialogue with my program than your typical write compile run loop. Combine that with it running on the JVM and you have a wonderful set of tools to get things done in a pleasant way. I strongly encourage anyone with even a passing interest in Lisp and functional programming to give it a try. If you're using VSCode there is the excellent Calva plugin to help you out.
- nine_k 2y agoAs a side note, I'm always amazed by people who can use a highly expressive language (Clojure, Rust, even TS) but switch to Go when they feel like it (especially pre-1.18). To me, switching to a less expressive language is painful and infuriating. I remember having to switch from Python to Java 5, and how everything started to take 3 to 5 times longer code to express. Maybe the key thing is to only write small things in less expressive languages, like shell scripts, or small C functions to help performance or FFI, or, well, tiny Go utilities.
- ReleaseCandidat 2y agoI write less boilerplate in Go than in Rust, about as much in Go (but of course different ;) as in Haskell).
- nine_k 2y agoThat's cool! How do you manage? E.g. the `if err != nil { return err; }` stuff?
- talkingtab 2y agoI know many people will have problems with this post, but I am posting as information for clorjure-ophiles. Not reasons, but personal reasons why I don't do Clojure and will not try it. 1. When I read about Clojure (repeatedly) I like it. I am especially interested in transducers. I even built a half baked transducer engine in JavaScript using generators. There is clearly something here of value here. Any system that can produce transducers is worth learning. 2. I spent too many years of my life on Java. It was okay until someone wrote a thing in php (!!) in a day that would be have taken at least a month in Java. Maybe two. I understand the "good" of Java, but for me personally, the cost of that good is just incredible tedium. This is personal and I understand that. 3. However, as soon as I get to the part of installing Clojure where you install a JVM, I start hearing voices that say "It ain't me babe" and "Just say no to Java". PTSD? For a while there was Clojure-script and I started working with that, but it seemed to fall off the edge of the world. I will happily try Clojure again if it will compile itself or if it does not require the installation of a JVM. [ And last but not least of irrational reactions- anything associated with Oracle is to be avoided like the plague. sorry] [Edit: then I saw the stuff about Babashka so I will give that a try]
- default-kramer 2y ago> It was okay until someone wrote a thing in php (!!) in a day that would be have taken at least a month in Java. Maybe two. I understand the "good" of Java, but for me personally, the cost of that good is just incredible tedium. This is personal and I understand that. You understand that this has everything to do with Java and nothing to do with the JVM, right?
- phendrenad2 2y agoIs there a version of Clojure that compiles to LLVM or something? Sort of like what Scala-native was supposed to be (but never materialized). I like functional programming but I can't abide the Java ecosystem in 2024, it's just too archaic for my taste.
- baq 2y agothe top comment as of writing this reply points to https://babashka.org/ https://babashka.org/, but it's GraalVM instead of LLVM (which shouldn't really bother you)
- kolme 2y agoBabashka scripts are interpreted, the babashka binary itself is compiled with GraalVM. But: you can also build regular Clojure programs using GraalVM and create a fast-starting binary.
- ojw 2y agohttps://jank-lang.org/ https://jank-lang.org/
- neilyio 2y agoSoon there will be! https://jank-lang.org https://jank-lang.org
- lgrapenthin 2y agoDo they have a realistic shot at implementing immutable datastructures?
- Jeaye 2y agoOh for sure. That's not the tough part. :) jank uses immer for that: https://github.com/arximboldi/immer https://github.com/arximboldi/immer
- jomendoz 2y ago
- TZubiri 2y ago[flagged]
- whalesalad 2y agoType your Clojure symbolic expressions here =>(+ 1 2) 3 =>(* 1 2) 2 =>(* 2 2) 4 =>(/ 100 10) 10 =>
- twism 2y ago=>(def ÷ /) =>(def × *)?
- mise_en_place 2y agoWhat a bizarre critique of LISP, which allows you to arbitrary define symbols to mean literally anything.
- TZubiri 2y agoThat's the laziest excuse ever, I want good defaults, and maintainers somewhat receptive to criticism. "Technically you can configure our product to do what you want" is a great way to have shitty defaults and to ignore all criticism you don't want to heed. Also this is not a lisp critique, it's a clojure criticism. I get that lisp is simple, ancient and set in stone. Clojure or whatever layer on top of it should be defining this basic stuff on top of lisp. Are we expected to build a 3rd layer of lisp on top of lisp? And then what pass the burden to our users and let them define a 4th layer of what they actually want? We need opinionated developers who choose a set of values or industry or application, not indecisive devs who want to support every user.
- kazinator 2y agoWhat is your example of a bad default in Clojure, and what should it actually be? Is it the stuff in your grandparent comment? That there should be some binding for x out of the box so that (x 1 2) does something rather than error out? A lot of mainstream languages use * for multiplication, so that would just be inconsistent. I also don't agree with your strange requirements where you propose that the character ÷ (U+00F7 division symbol) be used for division, whereas for multiplication you are proposing the plain lower case x letter from ASCII (U+0078). What you want to pair with ÷ is the actual multiplication symbol × (U+00D7). Separately from that inconsistency, it's probably a bad idea to introduce one-letter like x into the standard library of a language, particularly one that is Lisp-1 (one namespace for functions and variables). Those math symbols ÷ and × are both hard to type (does not appear on keyboards and not supported nicely by common input methods) and easily confused for x. > We need opinionated developers Okay: Programming languages should stick to ASCII, get off my lawn. Supporting Unicode in identifiers is fine: give that to the application programmers to use in their programs, if they are so inclined, but for Pete's sake, keep it out of the language and libraries. (Some Lisp authors disagree; for instance, there is support for lambda being written using the actual Greek symbol in some Lisps.)
- socksy 2y agoAnother website in this vein is https://www.maria.cloud/ https://www.maria.cloud/ which is more geared up for teaching complete beginners programming, but I think with the basic paredit style controls and the evaluate-each-form-at-a-time style is I think a lot more realistic to the kind of REPL driven development that you actually use — typing directly into the REPL terminal window is very unergonomic imo. You’re much more likely to use something like VSCode’s Calva or emacs’ cider to send the form under the cursor to a REPL process somewhere.
- winrid 2y agoClojure looks productive. What frameworks libraries do people use to build web apps? Like, replacement for Django view layer and ORM (not looking to debate orms thanks)?
- whalesalad 2y agoThere is not a batteries included framework a-la Django or Rails for Clojure. I would argue that is one of the biggest pitfalls to the language/ecosystem. If you are building a web application, you will need to invent the entire thing yourself. There are micro frameworks and tools that exist standalone to deal with HTTP, DB ORM, etc... but that will be an exercise left to the reader. Some will say this is a good thing (and as a very experienced engineer I will agree) but the barrier to entry for a newbie is quite high in this regard. You have all the rope to hang yourself with - and you will. Especially if you are on a team full of lots of interns and junior folks.
- jiriknesl 2y agoThe closest to this (MVC framework with all features including migrations, API building, auth...) is Xiana https://github.com/Flexiana/framework/ https://github.com/Flexiana/framework/
- whalesalad 2y agoThis framework looks like an absolute nightmare to use.
- neilyio 2y agoCheck out Biff, it's very thoughtfully made: https://biffweb.com https://biffweb.com
- anentropic 2y agoIt's kind of surprising the most popular(?) web framework uses a weird/obscure db I have no doubt that XTDB is good, it is just surprising as a first choice and is not going to be easy to get up and running compared to the conventional alternatives (Is there even a hosted offering for XTDB? I like that it's open source but seems that you will have to grapple with all this stuff including a Kafka cluster https://docs.xtdb.com/guides/starting-with-aws.html https://docs.xtdb.com/guides/starting-with-aws.html)
- brabel 2y agoDoes this end at "Apply functions on lists"?? For some reason I can't get past that!
- spronket_news 2y agothis is super neat! how did you set up your fonts folder? what tooling did you use?
- stefcoetzee 2y agoFonts included in the repo. [0] Tooling is a combo of Shadow CLJS and Clojure CLI. [0] See `resources/public/fonts` here: https://github.com/eliascotto/tryclojure/tree/main/resources/public/fonts https://github.com/eliascotto/tryclojure/tree/main/resources... [1] https://github.com/thheller/shadow-cljs https://github.com/thheller/shadow-cljs [2] https://clojure.org/reference/clojure_cli https://clojure.org/reference/clojure_cli
- dang 2y agoRelated: Try Clojure – An interactive tutorial in the browser - https://news.ycombinator.com/item?id=30423856 https://news.ycombinator.com/item?id=30423856 - Feb 2022 (93 comments) Try Clojure in your browser - https://news.ycombinator.com/item?id=3366526 https://news.ycombinator.com/item?id=3366526 - Dec 2011 (26 comments) Try Clojure - https://news.ycombinator.com/item?id=1359682 https://news.ycombinator.com/item?id=1359682 - May 2010 (60 comments)
- __rito__ 2y agoClojure for the Brave and True by Daniel Higginbotham is a truly great resource to learn Clojure. I highly recommend it. It is also free online [0]. [0]: https://www.braveclojure.com/clojure-for-the-brave-and-true https://www.braveclojure.com/clojure-for-the-brave-and-true
- neilyio 2y agoSeconded. I'm also a big fan of Aphyr's "Clojure from the ground up" series: https://aphyr.com/posts/301-clojure-from-the-ground-up-welcome https://aphyr.com/posts/301-clojure-from-the-ground-up-welco...
- stefcoetzee 2y agoAgreed. Perhaps using VSCode with the Calva plugin if the reader has no previous experience with Emacs.
- rads 2y agoI think the writing style is too fluffy, but I realize some people like that. The true sin of this book is that it actually starts by teaching the reader Emacs, not Clojure. That's a huge distraction for a beginner who is probably coming from VSCode these days.
- okasaki 2y agoI was hoping it would be longer, like the tour of golang. As is it basically just shows you how to do arithmetic, which isn't interesting at all.
- amelius 2y ago> unlike full-JVM Clojure it has a very fast startup time I can't believe that after all these years Java still didn't fix their startup time.
- rtpg 2y agoMy understanding is that this isn’t really a JVM thing, but I might be wrong.
- koito17 2y agoYour understanding is correct. JVM startup accounts for a small portion of Clojure's startup time.[1] Most of the overhead is in compiling and loading clojure.core. Efforts have been made to remedy this issue[2] (e.g. direct linking, ahead-of-time compilation, ...), but this doesn't remove the fact that clojure.core is huge and virtually any Clojure program will be importing more than just clojure.core, so there is still a lot of var derefs to deal with, then code to compile, then classes to load, etc. [1] https://clojure-goes-fast.com/blog/clojures-slow-start/ https://clojure-goes-fast.com/blog/clojures-slow-start/ [2] https://clojure.org/reference/compilation https://clojure.org/reference/compilation
- didibus 2y agoWell, it's still partially the JVM at play. For example, if your application has big classes, and many classes, the JVM will be slow to start. This is what is happening here. Clojure is like a large-ish Java project, it has big classes, and many of them, with static initializers, that need loading at the start, and the JVM does all that slowly. In some sense it's Clojure's fault for having an implementation that causes slow JVM startup, but it's also the JVM's fault that the way Clojure uses it causes it to take a long time to start.
- pjmlp 2y agoThe various JVM implementations have mechanisms to fix that, like JIT caches and AOT compilation, which Clojure doesn't take advantage of. So it is indeeed a Clojure issue, not a JVM one.
- tastyminerals2 2y agoI have to admit, several years ago, a colleague of mine advised me if not to try Clojure but at least to read the "History of Clojure": https://dl.acm.org/doi/pdf/10.1145/3386321 https://dl.acm.org/doi/pdf/10.1145/3386321, which I never did. But one day I decided to watch Rich Hickey - Greatest Hits https://changelog.com/posts/rich-hickeys-greatest-hits https://changelog.com/posts/rich-hickeys-greatest-hits... I then read the "History of Clojure", and then jumped into learning it. This is probably one of the most fun languages to build with and one of the most beautiful ones. If not syntax-wise, rather in a way it allows you to express your thoughts via good design and composition that so nicely tickles your brain. If you are still searching for that one shiny tool, and none of them clicks, maybe try Clojure. It's one of the most concise and yet powerful languages I've seen.
- ryan-duve 2y agoI got what you described by learning Common Lisp just a few months ago. Do you think learning Clojure would get me something in addition to that or is it roughly the same?
- tmountain 2y agoDepends on your style of programming CL. Clojure is immutable by default with a heavy emphasis on concurrency and strong ties to the JVM as its host environment. The differences you’ll find mostly lie in those areas.
- epgui 2y agoIMO, Clojure is superficially/syntactically much more elegant and beautiful than Common Lisp or Scheme. I find this really helps you focus on what matters most.
- vindarel 2y agoBesides the superficial syntax, those are some differences pointed out by (common) lispers: https://gist.github.com/vindarel/3484a4bcc944a5be143e74bfae1025e4 https://gist.github.com/vindarel/3484a4bcc944a5be143e74bfae1...
- 2y ago
- quantisan 2y agofor some stories on Clojure in production, check out https://www.juxt.pro/clojure-in/ https://www.juxt.pro/clojure-in/
- tmtvl 2y agoSo here's something which I, as a Lisper, don't understand: Clojure has syntax for hash tables (the curly braces), why doesn't it use those for let-bindings, instead choosing to use vector syntax? (Of course I prefer standard Lisp syntax which can easily be extended for multiple-value and destructuring bindings: (let ((a 1) ((b c) (list 2 3)) (d e (values 4 5))) `#(,a ,b ,c ,d ,e)) ;; => #(1 2 3 4 5)
- puredanger 2y agoMaps are unordered, but let bindings are sequential so order matters.
- neilyio 2y agoClojure has some very expressive destructuring syntax as well: https://clojure.org/guides/destructuring https://clojure.org/guides/destructuring
- didibus 2y agoWhat's so different to Clojure's ? (let [a 1 [b c] (list 2 3) [d e] [4 5]] `(~a ~b ~c ~d ~e)) ;; => (1 2 3 4 5)
- tmtvl 2y agoBut what would be the equivalent of: (let ((quotient remainder (floor x y))) (+ (* quotient z) (* remainder (floor z y)))) Where floor is a function which returns multiple values rather than a list or vector of results? Also, but this is entirely on me being an absolute dullard, I like having the brackets around each binding as a kind of guardrails for my mind to not lose track of where I am and what belongs where.
- mysore 2y agoi wish it was easy to make android apps with clojure. not sure if itd be easier with jetpack compose + clojure or react native + clojurescript.
- stefcoetzee 2y agoThe CLJS + RN route is doable. [0] Not familiar with the other approach. [0] https://github.com/PEZ/rn-rf-shadow https://github.com/PEZ/rn-rf-shadow
- prabhasp 2y agoThere’s also clojuredart to do a dart / flutter app. I’ve been working on one, and it’s been pretty pleasant to work on.
- jackbravo 2y agoClojure is becoming popular in Mexico, and I'm guessing Brazil may see a similar situation, because of nubank. It is a popular destination to go work there for computer scientists, and they seem to work mostly in Clojure. I seem to remember they even employed some of the core members of the language? I think at some point they also bought the company of Jose Valim (Elixir's creator), but I think they are still mostly a Clojure shop.
- hlship 2y agoNubank purchased Cognitect (the consulting company behind Clojure) in 2020, as well as Platformatec (employers of Jose Valim); the latter was for access to Platformatec's project management expertise (see https://building.nubank.com.br/tech-perspectives-behind-nubanks-first-acquisition-deal/); https://building.nubank.com.br/tech-perspectives-behind-nuba... there is no Elixir code running at Nubank AFAIK. There is Python on the "other side" of the ETL pipeline, but everything user-facing is (again AFAIK) Clojure on the backend and TypeScript in the Android and iOS apps.
- zachromorp 2y agoI often encounter Clojure Chinese users (at least Chinese sounding names, don't know about their nationality). I wonder if Clojure is a thing in China ?
- zerg000000 2y agono. But because of the population, even 0.0001% of developers using it, it still has an observable impact on the community.
- memothon 2y agoMy favorite part of working in clojure is how easy it is to do common data structure operations. map, filter and reduce are extraordinarily powerful, especially when combined with the other core library functions.
- stefcoetzee 2y agoWith Specter [0] to lend a hand for more uncommon operations. ;) [0] https://github.com/redplanetlabs/specter https://github.com/redplanetlabs/specter
- cageface 2y agoWhat's the recommended stack for doing front end development with clojure these days?
- rads 2y agoHere is where I'd start for the path of least resistance while still using the most modern libraries: - Dependency management: https://clojure.org/guides/deps_and_cli https://clojure.org/guides/deps_and_cli - Clojure->JS compiler: https://github.com/thheller/shadow-cljs https://github.com/thheller/shadow-cljs - React integration: https://github.com/reagent-project/reagent https://github.com/reagent-project/reagent - Global state management (optional): https://github.com/day8/re-frame https://github.com/day8/re-frame You might also want a CSS framework. There are some options to write CSS in ClojureScript, but I prefer TailwindCSS which isn't a Clojure-specific thing and it works fine out-of-the-box with `.cljs` files. You can swap out Reagent for Helix, which is a lower-level and faster wrapper for React. That said, Reagent does work with React 18 just fine and there's tons of docs for it, so jumping to Helix first is a premature optimization IMO, especially if you're new to Clojure.
- BaculumMeumEst 2y agoClojure is a really interesting and well designed language with bad error messages and bad official tooling. It feels very sloppy. Compared to Go, it has a weak stdlib, is more memory intensive, and generally slower. You get beautifully concise code but it can be very hard to follow (or return to after time away). Go can look completely idiotic or unbelievably focused and practical, depending on the light. It is painful to give up Clojure’s very strong selling points but I find alternatives to be more pragmatic.
- hpeter 2y ago"weak stdlib": You can use the Java ecosystem, most of the things you need are there "it can be very hard to follow": I agree, if you are not a lisp developer it's really hard, but if you develop clojure everyday, it's as easy as anything else. The answer is usually clean code when it comes to clojure. Keep your functions small. "more memory intensive, and generally slower": yep, the JVM is more memory intensive than Go. No surprise there and Clojure adds up on top of that. Startup times are pretty slow too. But compared to python it's still fast. Apples to oranges. I would say Clojure and Go are both great languages that tackle different problems so it's not a fair comparison.
- BaculumMeumEst 2y agoHaving projects that make significant usage of interop feels kind of gross, but I guess that is an option yeah. Pig-latin java is probably less fun to write than Go. Regarding difficulty reading code, I'm not talking about syntax, I'm talking about the fact that many libraries define their own DSLs and you _cannot understand what they are doing_ by reading the code, you have to dig into the library internals to make sense of how they actually work, particularly when documentation is lacking or outdated. Many problems can be solved by either language, and I wish it was easier to justify reaching for Clojure.
- eliben 2y agoI loved my stint with Clojure, highly recommend it (https://eli.thegreenplace.net/2017/clojure-the-perfect-language-to-expand-your-brain/ https://eli.thegreenplace.net/2017/clojure-the-perfect-langu...)
- android521 2y agoClojure will get more adoption if they find a way to make it very easy to build cross platform mobile and web apps like React & React native. They need to keep adding libraries to make the eco-system bigger.
- daveliepmann 2y agohttps://github.com/Tensegritics/ClojureDart/ https://github.com/Tensegritics/ClojureDart/
- mariogintili 2y agothe Scicloj stack https://scicloj.github.io/ https://scicloj.github.io/ in my opinion competes with python when it comes to DS/ML. I find it a lot more comfortable to use if you use emacs bindings
- createaccount99 2y agoThe problem I see with clojure, isn't it missing autocompletes? You work with JVM/typescript libraries, but your editor isn't smart enough to pull types from those into clojure. That slows you down tremendously.
- ilikehurdles 2y agoNo. When working with JVM/typescript libraries you have their autocomplete information. If you need method autocomplete scoped to a type you can use the `..` macro for more concise call syntax: (ns my-project.core (:import (java.util ArrayList Collections))) (defn example [] (let [list (ArrayList.)] ; ArrayList constructor can be autocompleted (.. list (add "Hello") ; The .add method on ArrayLists will be autocompleted (add "World") (add "Clojure")) (Collections/sort list) ; The Collections.sort method will be autocompleted list)) this other form will a also autocomplete everything after the dot (.) to call a method on an object: (.toUpperCase some-str) but the trick with this arrangement is to write that variable some-str first, then if you write . in front of it the autocompletes will be relevant to that object. But I gratuitously used threading macros like .. or -> to make it match java-style code (in other words: (-> some-str (.toUpperCase))).
- createaccount99 2y agoThat's cool, I had no idea. In clojure itself I suppose you eval code and then get autocompeletes from the repl output? -- I mean for stuff with no types
- simongray 2y agoAutocomplete also works for the functions and vars in the namespaces. You don't really use methods in Clojure unless you're doing interop with Java or JS.
- FredrikMeyer 2y agoI use Emacs with Cider+clojure-lsp, and the autocomplete/refactoring tools are super good.
- nathants 2y agothe best reason to learn clojure is reagent[1], by far the best way to use react. shadow-cljs[2] makes using npm libraries easy. i’ve settled on go backends and reagent frontends as my default setup[3]. 1. https://reagent-project.github.io/ https://reagent-project.github.io/ 2. https://github.com/thheller/shadow-cljs https://github.com/thheller/shadow-cljs 3. https://github.com/nathants/aws-gocljs https://github.com/nathants/aws-gocljs
- jarl-ragnar 2y agoCompletely agree. Though I’ve also found an Elixir backend works well because of the power of the Beam VM.
- createaccount99 2y agoDoes your setup do code splitting, SSG? I can't really be shipping a blank html file in 2024, destroys SEO. Otherwise am interested in trying.
- nathants 2y agono, i’m not interested in seo. this setup is a single go binary that serves a single pre-gzipped html file from a lambda. that html file contains inlined js, that is a reagent app. there is also a favicon. total of 3 files in the lambda zip. you desired setup is certainly possible though. you’d probably want clojure on the backend though, so you could more easily do SSG.
- deleted 2y ago[deleted]
- phforms 2y agoReagent is nice and has been around for about a decade now, but I moved away from it towards very thin wrappers around React[1], because I felt like it was adding too much additional complexity on top of React, which is already quite complex on its own. I wanted a clearer view at what is going on and a simpler way to interop with native React components. Although it seems to catch up with experimental support of React 18 now, Reagent has fallen behind the latest developments in React and may not benefit from all of its performance optimizations. It is still using class components instead of hooks and there have been concerns that the runtime conversion of Hiccup may drag down performance. I guess in most cases it is not really an issue or in any way noticable, so if you’re not doing any fancy stuff it should be fine. I may even come back to Reagent at some point, since I have to admit that I miss the UI-as-data model with Hiccup. What I highly recommend, however, is using re-frame[2] for state management. It has also been around for a long time (2014, around the same time Reagent came along) and pioneered some popular ideas in that area. It may seem a bit overwhelming at first, but the docs provide a great introduction and I find the model very clear once you wrap your head around it. At the moment it depends on Reagent, but there are ways around that. [3] [1]: see Helix (https://github.com/lilactown/helix https://github.com/lilactown/helix) or UIx (https://github.com/pitch-io/uix https://github.com/pitch-io/uix) [2]: https://day8.github.io/re-frame/ https://day8.github.io/re-frame/ [3]: refx (https://github.com/ferdinand-beyer/refx https://github.com/ferdinand-beyer/refx) is an almost drop-in replacement without the Reagent dependency, but hasn’t been updated in a while. Alternatively, re-frame can be integrated with UIx/Helix by adding some interop code https://github.com/pitch-io/uix/blob/master/docs/interop-with-reagent.md#syncing-with-ratoms-and-re-frame https://github.com/pitch-io/uix/blob/master/docs/interop-wit...
- DeathArrow 2y agoI wonder why no functional language has the degree of success imperative or OOP languages have. Is functional programming too weird for majority of computer programmers? Is functional programming not optimal for solving industry problems? Maybe there is no functional programming that that is up to some set of standards? Is functional programming too complicated? I do enjoy functional programming myself, and while I don't use a functional programming language at work, I try to use functional programming paradigms when I finds it suits the probem.
- cageface 2y agoFunctional programming languages haven't gone mainstream but functional techniques are very common now. Higher order functions, immutable data structures, declarative UI frameworks, etc are things you're quite likely to encounter in a contemporary codebase these days.
- DeathArrow 2y agoThat's what I said. I do use functional programming techniques, I just wonder why functional programming languages don't see a larger following.
- cageface 2y agoGood question. I suspect it's because the downsides of losing the larger ecosystem of more mainstream languages outweigh the upsides of a functional language. The libraries, package managers, tooling, runtime, debuggers, documentation, and editors etc just aren't anywhere near as mature for Haskell or Ocaml as they are for Typescript or Python, for example.
- nequo 2y agoDebugging is a known sore point with OCaml for example. But what is the problem with the Haskell RTS or the OCaml runtime? Why is it not “anywhere as mature” as Python’s or something like Node for JS? Python’s had the GIL while Haskell has had a well functioning parallelized runtime for a long time. And both Haskell and OCaml’s runtimes outperform Python’s and are on par with Node.[1] As for documentation, every time I come back to Hoogle,[2] I remember how I miss it in other languages that just don’t have anything similar going. The lack of types doesn’t help, and reading the documentation of the Python standard library or a popular library like torch is sometimes like solving a puzzle because it’s unclear what a function or a class constructor really does or even what class’ instance it returns. [1] https://benchmarksgame-team.pages.debian.net/benchmarksgame/box-plot-summary-charts.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/... for CPU usage but their memory usage is comparable too, and OCaml’s benefits from the language’s eagerness. [2] https://hoogle.haskell.org/ https://hoogle.haskell.org/
- camelspotter 2y agothis example shows how "elegant" closure treats syntax errors, almost looks like a bad joke. => (+ 2 2 + 3) "4function Cg(a){switch(arguments.length){case 0:return Cg.s();case 1:return Cg.g(arguments[0]);case 2:return Cg.h(arguments[0],arguments[1]);default:for(var c=[],d=arguments.length,e=0;;)if(e<d)c.push(arguments[e]),e+=1;else break;return Cg.j(arguments[0],arguments[1],new gc(c.slice(2),0,null))}}3"
- zakkor1 2y agoThat's a bug in the JS interpreter they're running, not anything related to Clojure. Also, that's not a syntax error
- silcoon 2y agoNot a syntax error. TryClojure is running on SCI which is a interpreter that uses a Babashka version for Clojurescript compiler, not Clojure JVM. Babashka cli returns this, telling you clearly what the error is: user=> (+ 2 2 + 3) java.lang.ClassCastException: clojure.core$_PLUS_ cannot be cast to java.lang.Number [at <repl>:1:1]
- magicink81 2y agoClojureScript Koans is also quite nice: http://clojurescriptkoans.com/ http://clojurescriptkoans.com/
- alabhyajindal 2y agoIsn't it tiring to type so many parenthesis all the time? This is probably my first time encountering a Lispy language, other than Logo.
- puredanger 2y agoThe number of parentheses is the same, they're just in a different place. Isn't it tiring to type so many semi-colons and commas all the time?
- alabhyajindal 2y agoI think it's tiring because before every expression I have to type a (. It's not tiring to type semi-colors and commas because they are very well positioned on the keyboard and I don't have to reach out in the same way as I need to for the parenthesis. Plus, there are not a lot of semi-colons and commas in JS and Python.
- stefcoetzee 2y agoReplace in Python with 4-space / tab indentation.
- phforms 2y agoI know a lot of people think that you write more parentheses in Lispy languages, but actually in most cases you just type them in a different order, e.g. instead of `foo(x, y)` to call a function, you type `(foo x y)` and you even save a comma. Of course, there are constructs such as `let` and `cond` that are more parenthetically noisy (not so much in Clojure though), but on the flip side you don’t have to remember a lot of special syntax like in non-lisp languages. Most Lisp-people also use structural editing tools like paredit[1], which make it really easy to write and edit s-expressions. I found that after some time I didn’t really think that much about parentheses anymore. [1]: https://paredit.org https://paredit.org
- alabhyajindal 2y ago
- imzadi 2y agoI love Clojure. My dream is to be a clojure developer, but there aren't a lot of jobs available and everyone wants 87 years experience.
- stoica94 2y agoIf you ever need a clojure boilerplate to start a SaaS product or a startup, there is https://shipclojure.com https://shipclojure.com