8 ms·
It's interesting that the very things that attracted the author to Clojure was what kept me from moving to it from Python. I enjoyed the syntax. Loved the immu
by hetman 8y ago
It's interesting that the very things that attracted the author to Clojure was what kept me from moving to it from Python.
I enjoyed the syntax. Loved the immutability. However, I wasn't able to understand the structure of program data at a glance even when reading my own code. The reliance on lists and maps everywhere meant that the structure of data was encoded in the code of the functions that created it and sometimes you had to go several functions deep just to understand the bit you wanted.
In Python if I'm returning a tuple that's more than 2 or 3 elements long, I know that it's time for, at the very least, a namedtuple because I've had to deal with code in the past that has mysterious 5-tuples etc that just becomes too tiring to deal with.
To be clear, big collections in Python aren't a problem as long as the type of the contained data remains uniform.
- kevin_thibedeau 8y agoThe fundamental problem with S-expressions is that they are intended for (1950s) machine readability and human ergonomics takes a back seat.
- iLemming 8y agosure, because Sure, because this (taken from React's JSX example page): <DashboardUnit data-index="2"> <h1>Scores</h1> <Scoreboard className="results" scores={gameScores} /> </DashboardUnit>; is more readable than this: [dashboard-unit {:data-index 2} [:h1 "Scores"] [scoreboard {:class-name "results" :scores game-scores]] Please tell me more about Lisp readability.
- lostmyoldone 8y agoI don't really see how JSX informs us about readability of s-expression vis-à-vis Python et al. Disregarding that, and in my opinion, properly formatted JSX might be a bit worse then s-expr for shorter stretches of code, but if/when you have a longer stretch, the visual symmetry in JSX would seem to tip the scale the other way. If there is a point to JSX, I would claim it's mostly that it looks different than the surrounding code that is the point, as it potentially makes it easier to parse and to clearly separate roles between code and design. While I'm frankly not a fan of either of the above-mentioned, I do find some of the arguments around the brilliance of s-expr to be perplexing. The most confusing argument is the one that s-expressions are good because everything looks the same, which to me sound like arguing that the best way to paint is to only use one color, which I vehemently disagree with. I think the easiest explanation of this conundrum boils down to a rather simple fact. Visual regularity is as confusing to some, as the lack of it is to others. People are different, sometimes shockingly so.
- mschaef 8y ago> The most confusing argument is the one that s-expressions are good because everything looks the same, which to me sound like arguing that the best way to paint is to only use one color, which I vehemently disagree with. The point of the syntax isn't necessarily that everything looks the same, it's more around why that's the case and what other properties it enables. In other words, if a homogeneous (and arguably less convenient) syntax is the downside, it's important to consider the upside too. This still not make it 'better' enough for to want to use, but maybe will shed some light on why reasonable people might think differently. The core concept behind Lisp syntax is that Lisp has a handful of core data structures, and the user syntax of the language is defined directly in terms of those structures. Clojure uses sequences, vectors, hashes to do things like represent blocks of code, argument lists, and type declarations. The structures used for this are the same as the structures uses in user code, and what you type in to the keyboard when you program are the normal textual serializations of these structures. So this gives a couple of benefits: 1) The character sequences used to represent the language are easy to parse in a structural way without a whole bunch of parsing logic. A structural editor for Lisp doesn't necessarily need as complete a grammar or parser to enable the structural features as does a language like Java, Scala, C, etc. 2) It's easier to generate or manipulate code. Most famously, this enables things like macros. Macros and code transformations are absolutely possible in languages like Java and the JS ecosystem, but less commonly used and more expensive to develop. There are many other examples of where these properties come in handy, but JSX turns out to be a reasonable illustration of why these are useful. Adding something like JSX to Javascript requires an explicit preprocessing state. Then, it also requires specific editor support to deal with the modified syntax. Once all that's done, what you have is a wrapper around 'React.createElement'. It says a lot about the value of application-specific syntax that people are willing to pay those costs to get a certain syntax, but the Clojure/Lisp approach (hiccup for markup) reduces the costs and makes that kind of thing significantly easier to do. Whether or not that's the tradeoff you choose to make is one thing, but there are reasons to make it.
- doteka 8y agoFor someone familiar with HTML/XML, so any developer in the last 30 years, yes it is. Your point being? I like the ideas behind clojure, I really do. I even wrote a non-trivial personal project with it. However, coming back to that code after two months was basically like the plot of Memento. I ended up rewriting it in JavaScript instead.
- iLemming 8y agoMy point being is: people often complain about readability of Clojure and Lisps in general without even giving it a heartfelt attempt. They complain about parentheses (which becomes a non-issue within literally hours after learning structured editing idioms). It's a matter of familiarity. Some prefer semicolons and other "visual garbage" in their code, I like minimalism and structure. No other language can retain readability on different screens like Clojure can. Even reading it in a narrow screen of a mobile phone - it would wrap, but still retain its readability. Good luck trying that with literally any other (non-lispy) language.
- profalseidol 8y agoAlmost anything (if not all) requires one to put in years of practice before one is adept. "a" non-trivial "personal" project probably won't cut it. Comparing that to your 30 years practice of XML is not at all useful.
- doteka 8y agoI didn't say anywhere I have 30 years of experience with XML. What I said is, EVERYONE is familiar with the syntax. JSX is especially suited for expressing HTML because it is, in fact, almost HTML. As to your other point - maybe. I'm not seeing anywhere near enough potential payoff to invest years into it, though. Also, I'd argue that makes it a terribly impractical language if you're interested in getting work done. To clarify, I don't agree one needs years to become competent in clojure. But if one did, that just makes it a worse value proposition.
- profalseidol 8y ago
- stickfigure 8y agoI genuinely can't tell if you're being sarcastic. The JSX looks immediately intelligible to me because I'm used to looking at HTML. The Clojure looks unfamiliar but it's not so strange that I can't imagine it feeling just as natural a way to represent the same data structure. It would just take a little while to get used to. The major issue I suppose is that this example is supposed to render to XML, which is closer to JSX than Clojure. But by that standard Vue (or XSLT) is even closer. I've done a little professional work in Clojure and wasn't a huge fan, but it didn't seem particularly bad (syntactically). It just seemed like something you had to get used to.
- iLemming 8y ago> The Clojure looks unfamiliar That's my point. It is simply "unfamiliar" to majority of developers who have never tried Lisps. And a lot of people throw baseless claims it to be "less readable" without even given it a try. A few years ago plain English to me was "unreadable". But I have learned the language. And look, today I can even make comments on HN. I guess it's a good thing I haven't dismissed the language because I was unfamiliar with it.
- gpderetta 8y agoBasically damnation with faint praise?
- cageface 8y agoJust about every innovative idea from Lisp, and there were quite a few of them, has been incorporated into modern programming languages. Except for sexpr syntax. Draw your own conclusions.
- lispm 8y agosexpr syntax has incorporated into 'modern' programming languages like Clojure, LFE, Hy, ...
- TeMPOraL 8y agoIndeed. Sexps are a syntax, so incorporating them in a language means you immediately start to look like a Lisp.
- kazinator 8y ago> Draw your own conclusions My conclusion is that those languages which incorporate S-exps become identified as some kind of Lisp. This is the case even when it's a misidentification; i.e. little else is there of any Lisp "DNA" other than the parentheses. Or else, those languages become identified as something that is not modern. Thus, no modern, non-Lisp language has S-exps.
- jonathanstrange 8y agoAh, the good old S-expression flamewar again! Every few years it comes up. This is, of course, mostly a matter of opinion and experience, but I find S-expressions highly readable and LISP syntax superior in readability to every other syntax I've seen, as long as different parentheses are allowed like in all modern LISP dialects. There are two other problems with LISP. First, it's so powerful that the semantics gets too rich, every author creates a DSL of its own with tons of macros and functions for every data structure. That makes code unreadable and difficult to maintain in the long run. At some point, every LISP program starts to look like a hack and you start spending most of your time transforming one data structure to another to interface with various packages. The second problem is the focus on dynamic typing. I've found strictly static compilation better for debugging. Racket is particularly bad in that respect, as it tends to use ad hoc symbols with contracts everywhere. Static enumeration types are just way better for that purpose. Ideally, they should even be tied to the functions they are used in (e.g. a "function parameter type" with appropriate scoping). These are the main drawbacks of LISP, maintainability and readability of code written by others is too low, because of a tendency to encourage hacks and DSLs.
- profalseidol 8y agoOne could say the same for almost all language. One can abuse java reflection and do all kinds of unreadable magic and code generation. If I can get one thing, I'd probably say practice in immutability. This simplifies a lot of things, even in java. In Clojure, immutability is first-class.
- panzerklein 8y agoClojure's answer to that problem and a couple of others is clojure.spec
- tarunkotia 8y agoOne way to read functional code is to focus on “what” rather than “why” of things similar to Unix commands.
- yomly 8y agoI feel like people who come to Clojure forget the lessons that were known from the time of SICP that just because you can program using data, does not excuse not building up an abstraction tower. If you have entities in your domain, presenting clean and encapsulated ways of interacting with them is a separate concern from navigating and modifying their underlying datastructure, which is an implementation detail. IMO the "it's just data" benefits of Clojure are that a lot of the common patterns which might have felt like being macro-worthy in CL/Scheme are achievable using things like keywords, which leads to more uniform code (rather than ad-hoc project-specific macros).
- hetman 8y agoWhile this approach did strike me as quite elegant in theory, what I found in practice was that a lot of those interfaces ended up just being boilerplate to give me access to the underlying elements of the data which I would have gotten for free in a more strongly typed language. In other situations, this approach would work well as long as what I was working on was fresh in my mind. However, when I had to come back to some code and extend its behaviour it would be back to digging through it to either understand the structure of the data... or understand the structure of the fancy abstraction I had built up on top of the data. It just didn't seem to be very time efficient in practice for the things I was trying to build.
- yomly 8y agoThat's an interesting insight - isn't the whole point of the indirection to free you from needing to understand the underlying data structure when extending things? I feel the heart of the issue is surrounding a similar problem that message-passing set out to solve, perhaps encapsulation? You set up some boundaries to a thing and define some contracts for interacting with it, and in return you are free to separate the implementation of that from the consumer of that data. I worry that when people program in Clojure, they forget all the discipline that was embedded in some of the better parts of the previous language/paradigms they came from and mistake that as liberation.