Live data from Hacker News

How LSP could have been better

matklad.github.io

51–60 of 229 posts

Re: How LSP could have been better

#51

I've read a bunch of articles about LSP, and some of the docs, but still not entirely sure what it is. I mean, abstractly I understand, but to truly understand what it's capable of doing and when I might need to use it... Does anyone have any good pointers?

LSP stands for Language Server Protocol. It's a communication protocol between the clients (text editors, debuggers, source viewers, etc) and the language servers.

Typically a language compiler runs over the source files and terminates once it's done. All the compilation states are gone. The language server is the compiler itself running for a long time; its aim is to maintain the compiled states of the source files alongside of the editing session in the editor client. It's ready to answer requests from the editor in regarding the source code.

E.g. The editor loads a source file. It sends a LSP request to the language server saying the file is opened. The language server would compile the file and maintain its compiled states. The compilation process might involve other source files as well. The language server reports any errors or warnings back to the editor. The editor shows them to the user right the way.

The user modifies a function and hits save. The editor sends a file-changed request to the language server. It recompiles the file and sends back any errors or warnings.

The user places the cursor at a function call and issues the jump-to-definition command. The editor sends a LSP request to the language server to look up the location of the definition of the function. The language server has all the compiled states of the source files and knows where the function definition is. It sends back the target location (file and line number). The editor can switch to the target file and jump to the line number.

LSP defines a whole bunch of these requests and responses (e.g. looking up the type of a variable, definition of a value, auto-completion suggestion of function parameters, etc). A language server for a language can implement these and suddenly all the clients that talk LSP can utilize the features.

Re: How LSP could have been better

#52

Earlier quoted context omitted.

I agree, and mentioning libraries seems like a non-sequitur to me. It’s handy to be able to integrate a language server written in Lisp with an editor made in Swift, for instance, without coming up with a way to link them as shared libraries. That sounds like a nightmare.

He is trying to say that LSP should be implemented as a set of libraries (like liblsppython.so). Your editor compiles with these libraries and provide API for plugin authors. It's not unreasonable to expect an editor's developers to know how to link a native library.

That’s the part I vehemently disagree with. There are servers written in a whole lot of languages. I’d bet there are Java servers written in Java. How are you going to link that into an editor written in C? What if the server’s written in Python? A shell script (crazy but legal!)? And even if you solve all of those for C, what if you want to write an editor in Swift. Now you have to implement all those shared library linkers again in that language.

Oooorrrrr, you could communicate with another process via stdin/stdout and call it a day.

Re: How LSP could have been better

#53

I hope we're nearing the end of the era where we're editing text in a bubble of tooling that understands ASTs but has to map everything back to text. I look forward making tabs vs spaces a viewer setting and not an author choice.

Agreed. Even beyond that it would be great for merging & conflict resolution too.

Right. Line-wise diff is such a crude instrument.

Re: How LSP could have been better

#56
post #34

The way a language server should work, imo, is it holds all the code and serves projections of the code on the fly to the editor. The user of the editor makes changes to the code and commits it back, at which point the language server parses the code and integrates it into the codebase, pretty-printing it to files as necessary for source control. But, the file layout should be an implementation detail that the editor…

That's exactly how LSP is designed. The editor e.g. requests 'the user is hovering over code , what should I show?' and the server responds with some Markdown text. Or 'the user wants to navigate to the thing under their cursor , where should I go?' and the server responds with a file/line. Once you try to use LSP for anything not in that form.. it's not so fun.

No, this is the opposite of how LSP is designed: LSP assumes the editor is looking at a file and this results in a complicated sync dance between editor state and file state. I want the editor to look at temporary buffers served up from the language server and have the code be “written” by sending the temporary buffer back to the language server which handles writing it out to files itself.

As far as I know, the only languages with something even vaguely like this are Pharo Smalltalk (with its git integration) and unison

Re: How LSP could have been better

#57
post #47

Earlier quoted context omitted.

That’s exactly the kind of thing LSP deals with. You have to get those settings into the server somehow, and the main methods are for the editor to send them to the server, or for the server to load them from somewhere in the filesystem or similar. A lot of those settings (like line length) are configured in the editor by the user. It makes a lot more sense to have a mechanism to communicate them over the same protoc…

LSP is a protocol for answering queries about the language model behind the text, not controlling anything about the text itself (expect for auto formatting, but that's a bit special). Those configurations seem to be in scope for the text editor, not the language server. In fact LSP is mostly configuration agnostic. It might use configuration for a particular query like autoformatting, but it's still request/response…

You have to tell the server how to interpret the code somehow. I mentioned line length. In Python, you may want one configurable max for code and another for comments. If you can pass those to the server, it can tell you which lines are too long using the standard mechanism for identifying errors and warnings. Otherwise, the editor would have to know how to parse the code so it could know whether a given line is code or comment. That’s the sort of thing LSP can do better.

That’s just one example, not the lone thing users would likely configure.

Edit: More concretely, here are some of the config knobs you can twiddle via LSP for the particular server I’ve been discussing: https://github.com/python-lsp/python-lsp-server/blob/develop...

There are other plugins around with settings that aren’t documented there, but are still configured through the same mechanism.

Re: How LSP could have been better

#58

Earlier quoted context omitted.

He is trying to say that LSP should be implemented as a set of libraries (like liblsppython.so). Your editor compiles with these libraries and provide API for plugin authors. It's not unreasonable to expect an editor's developers to know how to link a native library.

That’s the part I vehemently disagree with. There are servers written in a whole lot of languages. I’d bet there are Java servers written in Java. How are you going to link that into an editor written in C? What if the server’s written in Python? A shell script (crazy but legal!)? And even if you solve all of those for C, what if you want to write an editor in Swift. Now you have to implement all those shared library…

Use COM or something like it

Re: How LSP could have been better

#59
post #48

Earlier quoted context omitted.

I don't get his point? It basically amounts to "nuh uh, this is just bloat". >What type is this value?" Well, they say the way you should do that is—you know, you have your editor and then it's a hassle to make plugins. This is the made-up problem Ok so it's just a made up problem? Like, the "plug in" part or the need for having tooltips/completion etc? If he was referring to the perceived need of a plugin (vs. a mor…

He's saying (without saying it) that LSP is another instance of the "microservices everywhere" hype, and bad for the same reasons -- you have a problem, you try to solve it with a distributed system, now you have two problems and one of them is a set of microproblems. I don't think he is arguing against a standardized interface to language-specific logic, but arguing for that standard to be a library interface, not a…

He doesn't say why a library interface would be better. That's why I'm saying he doesn't even address the main point of LSPs, which is that they came in response to have your IDE or editor maybe-kind of plug into some libraries and wish for the best. Just saying that a library interface would be better because it's less complex is meaningless, when we obviously have not managed to get anything close to that for the past 40 years.

It's not super convincing to just dismiss the only solution that seems to have sort of worked by saying that we only had to keep doing it the way that never really worked.

I'm sure the implementation can be a lot better, but he does not provide any argument for why the architecture itself is bad. Sometimes abstractions are actually useful.

Re: How LSP could have been better

#60

Jonathan Blow criticized the performance and complexity of LSP in his talk at DevGAMM 2019 titled "Preventing the Collapse of Civilization" (timestamp 42m26s; https://youtu.be/pW-SOdj4Kkk?t=2546 ): > In the programming language world, there's this thing called Language Server Protocol that is pretty much the worst thing I've ever heard of. There are proponents of this all over, building systems for it right now that…

He was wrong on this issue. LSP reduces the MxN problem to Mx1 1xN, i.e. to M+N.
Post reply on HN