News for hackers. Stuff that matters.
Re:Why I still Lisp by mumblemumble on Sunday January 31, 2021 @11:44AM (#25980057)
I 100% agree that disastrous codebases are every bit as likely in other languages. But it somehow hurts more in a lisp.

I think that the syntax really is the culprit. In a language like Java, the Byzantine syntax and semantics enforce some minimum level of structure on the code. It's not much, but it's something, just enough to give an experienced programmer a few extra heuristics they can use to make sense of what they're seeing. Even some things that normally drive me nuts about Java, like the way that there's no standard way to call an anonymous function (because the invocation is done through a method whose name is allowed to vary) end up being useful bread crumbs when I'm reading somebody else's code.

In a Lisp, though, everything looks more-or-less homogeneous. You can memorize the names of special forms, but, beyond that, you can't quickly tell whether some thing you're looking at is data, a function, or a macro, or what. It all blends together into a disorienting fog. You need to go trace its provenance to see how some new value is defined or constructed before you can even tell what kind of thing it is. (This, tangentially, might be a great argument in favor of lisp-2, though I haven't spent enough time in a lisp-2 to have an opinion that's worth beans.) It may, in the grand scheme of things, be only a small reduction in what you can assume without careful study. But, in an unfamiliar codebase where you don't know much to begin with, every little scrap of knowledge counts.

It all points to an insight I should have had 20 years ago when I was working in Perl: Features that make a programming language pleasant to write tend to make it unpleasant to read, and vice versa.

Re:Why I still Lisp by lmilcin on Sunday January 31, 2021 @12:31PM (#25980576)
I spent a lot of time thinking about this.

What makes Perl or Clojure such fun languages to work with is they don't impose structure on you. You can do whatever the hell you want.

On the other hand result of this is the code represents basically how you think about the problem. Which would be very different for every person.

Languages with frameworks like Java+Spring, Ruby+Rails etc. are less "fun" to work with because you are not given so much freedom and likely have to fill in a lot of stupid, mundane boilerplate, but are easier to maintain in team setting because developers know more or less what to expect from the code. Very likely developers come with that knowledge and if you know one Spring application you know how to move around almost any Spring application.

Re:Why I still Lisp by vram22 on Sunday January 31, 2021 @01:55PM (#25981420)
It is the frameworks that give more rigidity and boilerplate, not so much those languages themselves (although Java does have more boilerplate than Ruby). You have a lot of freedom when you program in plain Java and Ruby vs. using frameworks in those languages. And that is at least partly by design. See the Template Method design pattern, which is the basis of frameworks that use Inversion of Control (IoC).
Re:Why I still Lisp by lmilcin on Sunday January 31, 2021 @02:22PM (#25981660)
Clojure frameworks are written by Clojure developers which means they don't give you structure, only tools to realize your freedom.

Frameworks that give a lot of structure are beneficial to novice developer because they need that structure. In absence of supervision, the various articles on the Internet, stack exchange answers on how to write a controller or other piece of Java app, give a novice developer necessary guidance on how to structure their code.

On the other hand as a more mature, knowledgeable and experience developer you may see that this structure is not perfect. It is repetitive and it has a lot of boilerplate and it does not suit well every application.

You may even figure out that every application has their own perfect framework, depending on its size and other characteristics and the problem it is trying to solve.

Clojure lets you design that framework and then write the application in perfect framework for your application.

That framework might be some zero-code decisions (like decisions on where to put which part of the code) but can also be some set of macros up to full blown DSL.

Assuming you are mature developer, you will know how to use these to solve your problem but if you don't then that's where the problem starts.

Re:Why I still Lisp by didibus on Sunday January 31, 2021 @03:08PM (#25982072)
Yes, frameworks are kind of like a smarter programmer starting you off with a code base already, so if you don't really know what you're doing you can't mess it up as much. I've still seen people mess it up, and generally it's when the developers begin to "play" with things they don't understand, like bringing in Aspect J, writing custom annotations, slowly moving logic to configuration files, starting to dynamically load modules in/out.

It's a bit of a struggle because an experienced dev will hate the framework, as they know better, but then as less experienced dev work on the code base it'll degenerate in a way the framework would have survived longer due to availability of documentation and Stackoverflow Q/A.

Re:Why I still Lisp by lmilcin on Sunday January 31, 2021 @04:41PM (#25982832)
There are two more points.

If you are tech lead or manager, these frameworks are really great value because they "give" (or more like let developer find) guidance on a lot of aspects of the application.

If you created your own perfect framework, you would be responsible for providing a huge amount of that kind of guidance, but if you are using Spring your every developer can just google the answer to most (or even almost all) of the problems.

And the second point is, again, if you are tech lead or manager, these frameworks are great help preventing your "highly intelligent" developers from making a mistake and developing their own framework. I put quotes intentionally, because some developers just think themselves to be very good developers but dismiss the risks and costs of developing software that is not core part of the project (aka NIH).

With Spring regulating most aspects of the application any damage from those kinds of actions is also limited.

Re:Why I still Lisp by kazinator on Monday February 01, 2021 @04:25AM (#25987046)
> mess it up [...] like bringing in Aspect J

And, see? That's from a Lisp guy. QED.

Re:Why I still Lisp by einpoklum on Sunday January 31, 2021 @06:32PM (#25983742)
> What makes Perl or Clojure such fun languages to work with

... while you're writing a small program by yourself ...

> is they don't impose structure on you. You can do whatever the hell you want.

You mean, there is nothing _preventing you_ from doing whatever the hell you want. That's not the same thing.

Re:Why I still Lisp by admax88q on Sunday January 31, 2021 @05:00PM (#25982967)
It feels like Lisp scales vertically and Java scales horizontally.

Java scales for number of developers, its idioms and ecosystem make it easier to have tons of developers on a single project.

Lisp scales on the size of problem that a small close knit team can solve.

Things like the macro system in Lisp encourage defining your own problem specific DSL, which is great for individual developer productivity, but bad for involving lots of developers.

Re:Why I still Lisp by kazinator on Sunday January 31, 2021 @05:36PM (#25983300)
Like the way those defclass and defmethod macros totally destroy programming at large.
Re:Why I still Lisp by lispm on Sunday January 31, 2021 @01:41PM (#25981307)
It may take a while to see the visual clues: indentation, formatting, structure patterns. Beyond simple lists, Lisp uses a variety of list structure patterns for language constructs. It's a bit like learning to ride a bike: initially it looks not possible to balance, steer and move forward at the same time.

One thing that's not that usual is that authors can implement new language constructs themselves. Thus one may need to understand that meta-syntax level when reading and writing new constructs. A starter book like SICP thus does not use this prominent feature: it does mostly NOT define & use macros.

Authors need to learn how to design new macro operators.

Re:Why I still Lisp by lmilcin on Sunday January 31, 2021 @02:06PM (#25981515)
I think it is important distinguish the necessary from accidental complexity.

Macros are typically more difficult to understand but if done well that would be because they are sinking complexity from a bunch of code.

For example, if a macro implements variations of repeating construct, you are removing those variations from your entire codebase and putting complexity of dealing with that into a single macro.

Now, the issue is when you start creating accidental complexity.

For example, there are various techniques that reduce overall complexity just by being consistent in how you do things. Using only hygienic macros or writing macros consistently in a way that allows the reader predicting what they do reduces a lot of perceived complexity.

If the reader of the code does not have to understand the macro to be able to more or less predict what it does and what are basic guarantees it provides, it reduces a huge amount of complexity when you try to read and understand.

If writing a macro can be compared to writing an operator in a language then all other language design rules apply. It would be a bad language that constantly surprises the user.

Unfortunately, Lisp code tends to be much more abstract with lots of complex, custom operators (macros) as building blocks. If these building blocks are not clear and cannot be relied upon (ie. you don't understand how they work and can't predict what they will do) then this is much more damaging to trying to understand how the codebase works than writing unclear functions.

Re:Why I still Lisp by lispm on Sunday January 31, 2021 @02:24PM (#25981675)
> sinking complexity from a bunch of code

Sometimes macros provide domain-level constructs. This creates very dense code - which can improve code understanding.

One thing I would recommend to put extra effort into macros, especially with these aspects:

One should write documentation what the macro expects and what it does. This way this has not to be inferred from reading the often quite complex code. Document the implemented syntax.

The macro should check the syntax of the forms. Provide error messages for rejected forms.

Re:Why I still Lisp by mumblemumble on Sunday January 31, 2021 @10:25PM (#25985190)
With those things in place, macros can absolutely be a net positive for code understanding. And if I saw that being done with any regularity at all, that would be great.

As I get older and more jaded, though, am coming to think that, in an office setting, it is a mistake to choose a language is optimized for maximizing the effectiveness of a thoughtful programmer. It's much more valuable to minimize the damage that can be done by a careless programmer.

One of the most sobering realizations of my career was that the most effective way to become your team's 10X programmer is not to work in a way that lets you be 10X more efficient than your colleagues. It's to work in a way that forces your colleagues to be 10X less efficient than you.

Re:Why I still Lisp by lmilcin on Monday February 01, 2021 @09:26AM (#25988928)
That is exactly what I have realized after decades of work.

There is a cap on how much work you can do individually. There is no cap on how much damage or improvement you can cause to other people you work with.

It does not matter how clever you are with your code if nobody else is going to be able to continue that work or support its results.

For this reasons I have developed following, informal rules I try to follow:

1. It is ok to be clever with the code if I am going to be only one to ever read or use it. This can assumed to be always false for production code. I limit my cleverness to PoCs, adhoc tools and emergencies.

2. Always think how other, and especially junior members of the team are going to develop and support my product. Is it too complex for them to follow? Is there something that can be done so there is less chance they are going to misuse it?

3. I use my cleverness to try to develop simpler and more reliable products. Simplicity is defined by how much work junior member of the team is going to have to expend to understand it. Reliability is defined by how likely it is to fail in face of junior team members operating / developing the piece of code.

4. If team members have trouble understanding or working with my products it is always my fault. Figure out how to make the product simpler or at the very least provide training and ensure they understand how it works.

Re:Why I still Lisp by kazinator on Sunday January 31, 2021 @10:14PM (#25985116)
> you can't quickly tell whether some thing you're looking at is data, a function, or a macro, or what

First of all, there are elements that are unmistakably data: "abc", 123.0E-13, #(1 2 3), :keyword :symbol.

The ambiguity is that a compound expression headed by a symbol could be anything. In order to to be fooled, we just have to read the entire top-level form from the outside in.

Well, that's what language is. For instance, if I'm saying "Bob believes that the Earth is flat", but you only catch my speech starting on at word "the", it looks like I'm saying that the Earth is flat. To get the real meaning (the belief is attributed to Bob), you need the whole sentence.

Or, until you hear the "nai" at the end of a long Japanese sentence, you have no idea that it's going to be negated.

Re:Why I still Lisp by blackrock on Sunday January 31, 2021 @09:13PM (#25984846)
> In a Lisp, though, everything looks more-or-less homogeneous. ... you can't quickly tell whether some thing you're looking at is data, a function, or a macro, or what. It all blends together into a disorienting fog.

I wonder if this is a feature of Lisp, instead of a defect.

When you call up a variable or a function or macro, the intent is to return some kind of result. If variables, functions, and macros all look alike, and then maybe it can be weaved more seamlessly into the code to create its own style.

You can also think of a variable, as a function call with zero parameters.