Live data from Hacker News

Six years of professional Clojure development

falkoriemenschneider.de

191–200 of 209 posts

Re: Six years of professional Clojure development

#191

Earlier quoted context omitted.

> If you had a rigid system and slow turnaround from the start, you might not have gotten off the ground to get that far. I always see people say this and on the surface it seems to make sense, but I also always wonder what "rigid system" they're talking about. It's much, much faster to make big changes in every phase of a project in Haskell for me than it is in Elixir, so this is the perspective I'm seeing this from…

I don't have Elixir experience, but the natural way to get started in modeling data and state in Clojure quite obviously involves less ceremony and scaffolding than what you do in Haskell, and is less work to change around. Also, it's not just the amount of work, it's the complexity of the language. Clojure is really simple, so you don't h ave to spend much of your cognitive capacity juggling things related to the la…

I totally understand what you mean! At least I think I do. I have spent a significant amount of time going down the "type flex" rabbit hole. You can always make thinks a little safer, a little more concise, and so on.

In that sense I really do get off the ground much, much faster in Clojure. In fact, it's my favorite language for prototyping and the whole interactive execution model of the REPL makes we want to learn Emacs and do everything in some kind of lisp, rather than awk, sed, bash, dash, whatever.

I think the key ingredient for me with Haskell is to know when to stop. You can be very productive even as an intermediate Haskell user if you restrict yourself to the features with the highest return on investment. Everything else can be done later. But I also know that it's very tempting to stress out over these details.

As a very late conclusion to my various comments in this thread: if I got better at taming type related errors in Clojure I could very well see it being my go-to language for everything.

Re: Six years of professional Clojure development

#192

Earlier quoted context omitted.

> Good programming practice isn't a language feature its a programmer feature. I'll enjoy reading your production-grade brainfuck code. A language's built-ins and idioms greatly influence what you say and how you say it. If your mother tongue doesn't have words to describe any emotions you'll have a hard time explaining them. You're talking only about the other side of the coin. Yes, people can write terrible clojure…

Do you really think referencing brainfuck, a deliberately difficult language, is the right way to get your point across?

> > > Good programming practice isn't a language feature its a programmer feature.

> > I'll enjoy reading your production-grade brainfuck code.

> Do you really think referencing brainfuck, a deliberately difficult language, is the right way to get your point across?

I'm gonna assume you're not deliberately missing the point here and the confusion is genuine.

You were initially indirectly saying that "it doesn't matter what language you use, how the program ends up is 100% to the developer"

The other person made a joke/insight about that, since you think so, you should be able to write a program ready for production in Brainfuck, since your point was that the language doesn't matter.

Obviously, anything but Brainfuck would make it easier to both write and understand, therefore your point seems to not be 100% true, at least always.

The main point is not about Brainfuck, it's just an example. The point is about that the programming language _does_ matter, as well as the skill of the developer.

Re: Six years of professional Clojure development

#193

Earlier quoted context omitted.

Whether you get strong assurance of correctness from static typing depends on your domain, are you're working with a closed-world app like a compiler, or a talking to the rest of the world a lot? Though it's telling how little static checking by type systems is leveraged eg in LLVM, so even in closed systems the assurance payoff for static checking doesn't necessarily get good bang for the buck. Eg working with web b…

> Eg working with web based services, your code tends to communicate a lot with other services, and a very large % of bugs that make it further out than your dev laptop come from those interfaces. Making these part of the closed world of the static type system is done in some places but most static language users elect not to do it, preferring programmable checks in form of schemas or tests. Are you actually suggesti…

> Since I'm not here to convince anyone, I can say your straw man is the opposite of my experience. I've never been able to prototype and change a system in any phase of its lifetime faster than I've been in Haskell. Haskell has downsides, but speed of development and maintenance is one of its strong points.

Yup, and when it comes to fun, I've never had more fun programming that in Haskell, where I let the compiler check the annoying fiddly bits so my brain is free to tackle the meaty problems!

Re: Six years of professional Clojure development

#194
post #76

Earlier quoted context omitted.

I'd argue Clojure has all 3 Stability - one of Clojure's core tenets. Low language complexity - not much more than EDN and everything is an expression, plus a few extras like destructuring. Certainly simpler than any other language I have used. Extensibility - again, one of Clojure's strong points with macros. As for "Type systems removing the value of a repl" again, I disagree. Repl driven development is as much abo…

Stability in this context means "can make changes with confidence in the absence of tests". The more confident you can be, the more stable. Maybe not the right word though. > Repl driven development is as much about exploring the problem than it is writing code. Which is exactly what types give you. This even coined the term "type driven development" (same as "test driven development" on purpose").

> Stability in this context means "can make changes with confidence in the absence of tests". The more confident you can be, the more stable. Maybe not the right word though.

I'd call it "robustness".

Re: Six years of professional Clojure development

#195
post #95

I've used Clojure for going on 10 years now and it has been one of the most enjoyable programming languages I've ever used. But I've gone back to Scheme for a few ridiculous reasons. 1. TCO. Using `recur` in Clojure just breaks my thought process. 2. Difficulty in getting down to the metal when needed. Using JNI is painful. In Scheme, when needed, the FFI usually handles plain old C. Much easier in my opinion. 3. Com…

I don't understand arguments of the kind: "Lisp A vs. Lisp B". A Lisp is a Lisp. I am honestly so grateful for my younger self for the decision I made years ago to learn Lisp. These days, pretty much any platform, any hardware, or a VM supports at least one dialect of Lisp. And that's awesome! I switch between Lisps with relative ease: Scheme, Fennel, Clojure, Elisp, Common Lisp - they feel pretty much the same langu…

I think of the "Lisp A vs. Lisp B" discussions like describing the nuances of you favorite color. My favorite color is yellow, but that covers a lot of ground. I prefer a nice bright lemon yellow, but don't care for mustard yellow or brown as much. But any Lisp is better than Fortran just as I prefer any yellow over purple, for example.

I prefer Scheme to most other Lisps because of guaranteed TCO, the way continuations are handled, regularity of function names, and define-syntax macros.

Within the Scheme family, I usually prefer Chez for its performance, its FFI and because I happen to prefer an R6RS compliant system at the moment.

Just nuances.

Re: Six years of professional Clojure development

#196

Anybody here mixed code base between clojure and another language to have a concise / dynamic layer with some 'classic' statically typed modules underneath ? kotlin/java comes to mind due to JVM but maybe others.

Java and Clojure are probably pretty common. I sometimes use the Clojure numeric stack and Java (JavaFX) for the GUI portion of a program.

Re: Six years of professional Clojure development

#197

Earlier quoted context omitted.

You have a strawman example of piping via .member() because those () sometimes have arguments; that's what they are there for. Function application has not gone away; it's just combined with obj.member access. It can easily become an unreadable mess that will need some way of splitting across lines and indenting: something.first(other.foo(bar.f(x, y)).memb, z).second(x.y()).third(a, b, c) This: (third (second (first…

Of course you could work around s-expressions (and make your ALGOL-formatted language looks like Lisp, a common complaint against my own code by my coworkers), that wasn't my argument. Most aren't fond of Lisp syntax, regardless of how you dress it up, and thus writing in Lisps doom you to have fewer people to hand over your code to, and I don't think that scarcity is useful. I suspect the reason most don't like s-ex…

[deleted]

Re: Six years of professional Clojure development

#198

Earlier quoted context omitted.

You have a strawman example of piping via .member() because those () sometimes have arguments; that's what they are there for. Function application has not gone away; it's just combined with obj.member access. It can easily become an unreadable mess that will need some way of splitting across lines and indenting: something.first(other.foo(bar.f(x, y)).memb, z).second(x.y()).third(a, b, c) This: (third (second (first…

Of course you could work around s-expressions (and make your ALGOL-formatted language looks like Lisp, a common complaint against my own code by my coworkers), that wasn't my argument. Most aren't fond of Lisp syntax, regardless of how you dress it up, and thus writing in Lisps doom you to have fewer people to hand over your code to, and I don't think that scarcity is useful. I suspect the reason most don't like s-ex…

[deleted]

Re: Six years of professional Clojure development

#199
post #22

I loved clojure until working with it for a few years, with some of the famous best teams in Europe and America, including Cognitect people, who ill leave unnamed here. I fell out of love when I realised what the language is - a mutable, imperative, blocking IO by default language with lambdas and zero guarantees at compile time. Effects happen at any time, as it is an imperative language. Just like JS with a better…

I don't completely agree with all of the points but I am really glad that there are sensible critics of Clojure who don't position it as a perfect language.

I have been working exclusively with Clojure for over 2 years now and I came from mostly C# background and I still want to pull my hair out every time I have to fix a bug which wouldn't have happened in a language with a good compiler. Same goes for asynchronous programming, which I think is generally lagging behind by many years in JVM world.

Another issue I have is the lack of choice in quality third party libraries. A lot of them are created as wrappers over Java libraries and then abandoned and those that aren't usually lack in documentation and depth.

Re: Six years of professional Clojure development

#200

Earlier quoted context omitted.

You have a strawman example of piping via .member() because those () sometimes have arguments; that's what they are there for. Function application has not gone away; it's just combined with obj.member access. It can easily become an unreadable mess that will need some way of splitting across lines and indenting: something.first(other.foo(bar.f(x, y)).memb, z).second(x.y()).third(a, b, c) This: (third (second (first…

Of course you could work around s-expressions (and make your ALGOL-formatted language looks like Lisp, a common complaint against my own code by my coworkers), that wasn't my argument. Most aren't fond of Lisp syntax, regardless of how you dress it up, and thus writing in Lisps doom you to have fewer people to hand over your code to, and I don't think that scarcity is useful. I suspect the reason most don't like s-ex…

You seem to be stuck on this idea of deep function call nesting being an impediment, which is solved by foo.bar().baz() chained syntax using object dot notation.

But most mainstream languages have chained function call notation as a feature.

Furthermore, foo.bar().baz()... chaining is a fairly recently emerging idiom. It has been possible in a number of languages for decades already, but somehow didn't take off. You would hardly see chains of foo.bar().baz().xyzzy() in 1990 vintage C++ code bases, even though 1985 vintage C++ would easily support it.

Anyway, there is a dialect of Lisp which has integrated the dot syntactic sugar into S-expressions, according to this basic idea:

  This is the TXR Lisp interactive listener of TXR 257.
  Quit with :quit or Ctrl-D on an empty line. Ctrl-X ? for cheatsheet.
  Poke a few holes in TXR with a fork before heating in the microwave.
  1> '(quote x) ;; i.e. just like we have a 'x -> (quote x) sugar ...
  'x
  2> '(qref x)
  (qref x)
  3> '(qref x y) ;; we can have a x.y -> (qref x y) sugar
  x.y
  4> '(qref x y z)
  x.y.z
  5> '(qref x y z w)
  x.y.z.w
  6> '(qref x y 3 w) ;; (let's not when it's ambiguous with floating-point)
  (qref x y 3 w)
  7> '(uref x)  ;; ... and a .x.y (uref x y) sugar
  .x
  8> '(uref x y)
  .x.y
  9> '(uref x y z)
  .x.y.z
  10> '(uref x y 3 w)
  (uref x y 3 w)
Embedded compounds are possible, of course:

  11> '(qref (a) (b) c (d) e f (g))
  (a).(b).c.(d).e.f.(g)
I never intended this to be used for chaining! In fact, only in a fairly recent update to the list-builder object, did I fix it so it can do this:

  12> (new list-builder).(add 3).(add 4).(pend '(5 6 7)).(pend 8).(get)
  (3 4 5 6 7 . 8)
Needless to say, the methods have to return the object in order to make this possible. Before the update, the methods didn't have a specified return value.

In the first place, list-builder is an implementation mechanism under the build macro, which expresses it like this:

  13> (build (add 3) (add 4) (pend '(4 5 7)) (pend 8))
  (3 4 5 6 7 . 8)
so there is no reason to use list-builder directly in most code.

This chaining business is a minor benefit (if at all) of the dot notation. The main motivation is to make programming with structures and OOP more ergonomic. It has a big impact for programs that use data structures, because the use of data structures and OOP can pervade the entire program, and is a driver behinds its structure.

Anyway, anyone discussing S-expressions under the assumption that they do not have a dot notation that can be used for function chaining is simply unaware of the research having been done in this area in the TXR Lisp project.

Post reply on HN