7 ms·
> There is no other language that places such an emphasis on programming directly with plain and naked data literals. Counterexamples: Erlang and Elixir. Argua
by klibertp 6y ago
> There is no other language that places such an emphasis on programming directly with plain and naked data literals.
Counterexamples: Erlang and Elixir. Arguably also Prolog. Also Lua. Many Schemes, and Racket. Of course, REBOL and Red. TCL probably, too.
I can't help but think that people making claims of "no other language has X" are in most cases wrong, and should study a bit more before making them.
There's a lot of hype in the article, I don't want to diminish the value of REPL-based workflows or conciseness[1] of the language, but the overall message that any fresh graduate can become a 10x programmer in under a month... Well, there's at least nothing humble about it, despite the article touting "humility" as a virtue of prospective Clojurists.
[1] Why aren't we all writing in APL/K/J if it matters that much?
- bobthechef 6y agoI also thought the bit about fresh graduates having no pride rather blanket. There are plenty of prideful fresh graduates with the kind of pride that experience hasn't yet tempered to produce a humble respect for the fact that you will die knowing next to nothing. Sadly, even some old timers never catch on to that.
- FPGAhacker 6y agoI haven’t written any Clojure for a few years now. So my knowledge and technique is out of date, but I have a contrary opinion on “repl driven” development vs many Clojure advocates. In short: your repl compiled code is state that you now have to track in your head. Yeah, great, you can compile a single function and it hot loads. It’s pretty awesome for experimenting and debug, but the longer your repl session is open and the more you change and compile, the more likely you are going to end up with a mixed state in memory that does not reflect how your program would behave if run from scratch. You are going to forget to save a change or your manual tinkering with a data structure will leave it inconsistent. These errors accumulate, like navigation error with an IMU. It’s got use cases for sure, and I miss hot reloading when I’m debugging in other languages, but it is far from being the ultimate feature a language can have.
- huahaiy 6y agoIf you write your code the correct way, there wouldn't be any states in your namespaces for you to keep track in your head. That only happens if your code is full of `(def some-state (atom {}))` or something like that. You are basically illustrating my point about "You probably cannot learn Clojure all by yourself". You need a mentor to show you how to do Clojure correctly, or you have the humility to learn the proper Clojure way. Sadly, most people would rather just try something and jump onto conclusions immediately.
- adamkl 6y agoFunction definitions and vars are a form of state that can accumulate in a REPL session. Its not just atoms. This can lead to issues where you decide to refactor and rename a var (Clojure is all about concise and expressive names, so its not uncommon to do this.. At least not for me) but you might not catch every place the old var name is being used. Because both vars are still exist in the state of your REPL, everything seems to work, but once you compile your uberjar or whatever, things are broken. A REPL isn't a replacement for good unit tests, and there are techniques for reloading your REPL state on save, but the issue of needing to keep the "REPL state in your head" is real, and not an artifact of doing things wrong. Just something that the developer needs to be aware of as a potential hiccup in the REPL experience.
- klibertp 6y ago> If you write your code the correct way, Then you don't need a REPL. This is a very weak argument, overall: there are programming techniques to compensate for any deficiency in the environment. The fact that you need to use them is already worse than not having to worry about it at all. > Sadly, most people would rather just try something and jump onto conclusions immediately. Just a gentle reminder, you're not talking to "most people" here. Nevermind me, we [EDIT: cut out the irrelevant details] I just want to say that assuming good faith and informed criticism are the better defaults for this forum.
- 8note 6y agoRepl development is great for exploration, when you don't quite know the right representation of your problem yet. The alternatives isn't changing your development environment, it's writing on a white board
- blacktriangle 6y agoI think it goes further than the language's support of data literals to the culture of the language itself. The Clojure community takes programing with data literals to, what I would call, a pathological extreme. It's as if nobody wants to write actual code, just data structures to be interpreted, regardless of how general those data structures are. The problem is everybody gets hung up on code is data but doesn't realize that data is not code. At some point that data has to be interpreted, and passing around custom data literals trusting they'll be understood correctly elsewhere in your program turns into its own challenge.
- huahaiy 6y agoYou are contradicting what your parent post is saying and agreeing with the OP. So you agree that Clojure is the most data-oriented programming language, but you feel like it is too extreme?
- blacktriangle 6y agoThat sums it up. I think Clojure is the most data-oriented programming language there is, but it gains that title not through features which other languages have as well, but through its general developer culture. And also, I do feel that the Clojure community often takes data-oriented programming too far.
- klibertp 6y agoREBOL and TCL are languages which go at least as far as Clojure in data-centric programming. Both feature incredibly elegant DSL for a variety of tasks, like constructing parsers or defining GUIs. Personally, I don't have an opinion on whether they (including Clojure) take it too far, but it's true that even that culture is not unique to Clojure :)
- huahaiy 6y agoI don't know about REBOL, but I did program TCL extensively in my graduate school years. I agree TCL has a lot of similarity in term of treating code as data like in Lisp, but I do not think it has such an emphasis on data oriented programming like in Clojure. That's just not true.
- jolux 6y ago>Why aren't we all writing in APL/K/J if it matters that much? In all seriousness I think writing more code in APL would probably cut down on bugs, but array-oriented languages are so far beyond how most programmers think about programming, and look so obscure, that I don't think there's any hope of them seeing widespread adoption. Most people loathe point-free Haskell, so I can only imagine what they'd think of the APL family.
- renox 6y agoWell I've had a few lesson in APL a long time ago and what I remember is that APL is a write-only language. So I doubt that it would 'cut down on bugs'
- Jtsummers 6y agoIt becomes less "write-only" as you build up experience. It's just not as readily learnable (if you're already a programmer) as most other languages. I mean, procedural and OO languages seem to have largely adopted a variation of Algol or C syntax with roughly comparable semantics to others in the same family. A programmer in C, Java, JavaScript, Fortran, Ada, Pascal, Go, Rust, Python, Ruby, etc. can mostly jump to the others and be able to at least read the program without much difficulty, though learning to write and extend the program (especially idiomatically) will take more time. APL's syntax and semantics are much different so it has a larger barrier for getting to the level of reading or extending programs written in it, but it's not impossible to reach that level with a bit of practice. I spent a few months doing APL for 2-3 hours a week in the evenings and I was able to develop a reasonable level of competence in it (though not so much I'd drop it on my CV), I can still read it pretty easily now a couple years later and without really touching it since then.
- jolux 6y ago>Well I've had a few lesson in APL a long time ago and what I remember is that APL is a write-only language. This is not how everyone who writes APL feels about it. It is recognized that it takes quite a while to really internalize how the operators work and compose, though. One advantage of APL stated by Aaron Hsu is that because the code is so small, if you find it confusing, you get in the habit of rewriting it frequently, and at least for him, it gets clearer over time. I have only dabbled myself (Primarily an OCaml and Elixir/Erlang programmer), but what understanding I have about empirical studies of software engineering suggests lines of code is more or less the only consistent predictor of defect count.
- nojito 6y agoF# is a cleaner example of putting data first.
- klibertp 6y agoYes; I didn't mention it because, while they are technically literals, you are expected to write your own types and use your own constructors. But yes, F#, OCaml, Haskell, Idris, Elm, etc. are also very data-centric.
- CraigJPerry 6y agoDoes F# not put types first and data second? Would it be idiomatic to do clojure style maps where the map keys end up being treated like pure functions that return a value.
- jolux 6y ago>Does F# not put types first and data second? The F# and ML view of the world is, roughly, that data and types are not separable in any way that's useful. Types are just how programmers make sense of data, and they exist in every language. The difference is whether or not the compiler will use them to help you make sense of your data as well, or whether you have to do your own manual type-checking. As for programming with maps the way it's done in Clojure, I would say generally no, that's not idiomatic F#, and it's a big blind spot for F#. OCaml has row polymorphic records, which would be a better fit for the treat-everything-as-a-map style of programming in a static language.
- jimbokun 6y ago> [1] Why aren't we all writing in APL/K/J if it matters that much? Because most programmers aren't nearly as productive as we could be. And because "concise" should be measure in the number of tokens needed to achieve certain functionality, not by excessive use of single character tokens.
- arabelladonna 6y ago> And because "concise" should be measure in the number of tokens needed to achieve certain functionality, not by excessive use of single character tokens. What's the difference if the symbols were meant to have specific mathematical meanings and are really meant to be the only representation? Plus, readability is subjective.
- CraigJPerry 6y agoI wonder if there’s a sweet spot for verbosity or if it doesn’t really correlate with bugs or productivity. I end up thinking about this pretty regularly. For example Kdb/q has always fascinated me, my initial reaction was that encoding meaning into fewer symbols surely causes cognitive overload and promotes programmer failure, and yet i saw some python code written by a quant converted to q by a kdb developer. The original python was well written, it relied on pandas and numpy but all fairly garden variety stuff. The q had exactly the same behaviour except some small changes for data ingestion. Around 500 lines of python, 16, not a typo, 16 lines of q. The performance comparison was absurd too.
- anonu 6y agoThis has been my experience as well. 10x factor reduction in LOCs and increase in performance when moving to kdb/q
- arabelladonna 6y ago> The q had exactly the same behaviour except some small changes for data ingestion. Around 500 lines of python, 16, not a typo, 16 lines of q. The performance comparison was absurd too. I think this comes down to every symbol having a defined behavior that can be optimized around, rather than building a framework for creating your own symbols (functions). Dyalog APL has some similarly insane "beating C"-type benchmarks. However, if you were to branch out into the more traditional constructs in Dyalog APL or J (K/Q have less of them due to being much, much less generalized), you'd probably see some significant performance decreases simply because they're more generalized. Eg. I doubt that Dyalog APL objects are as optimized as C++ objects. Note: I have no experience designing languages or building compilers/interpreters. I just wanted to put my two cents in, rather than leave this on the somewhat vague and "mystical" note.