Hacker News new | past | comments | ask | show | jobs | submit login
Goism – Use Go instead of Emacs Lisp inside Emacs (github.com/quasilyte)
164 points by demiol on June 18, 2017 | hide | past | favorite | 76 comments



I haven't taken an incredibly close look at this, but it seems like a pretty bad idea. Elisp is definitely not a great language, and I'd like an alternative as much as the next Emacs user. But I feel pretty strongly that any alternative has to be a Lisp, or very close to one. Code-is-data/data-is-code is very important for the more "config-file" aspects of configuring Emacs. Being able to use and write DSLs to succinctly encode exactly how you want aspects of the editor to behave is a critical strength. I've tried systems that were configurable in Python and other good-but-non-Lisp languages, and it's always much more annoying, because the language is (purposefully) limited w.r.t metaprogramming and possible DSLs. That's a good thing when optimizing for maintainability by others and obviousness, but not so much when optimizing for maximum personal customizability.

Go seems like quite possibly the polar opposite of this, as far in the "keep it simple and understandable by literally everyone by cutting out many techniques for metaprograming and code reuse". Which perhaps is the point, but if so it seems like that point misses much of the draw of Emacs?

While this is definitely impressive technically, I think Guile Emacs is a much more plausible option.


I used Emacs Lisp for scripting tasks like code and data generation. It is great to have an ability to evaluate form right inside the spot you want results to be inserted. This kind of code does not require AST manipulations or macro.

Also, some of my projects that become bigger than 1000 LoC could benefit from static typing and (subjectively) better tooling.

By the way, I think extending Emacs in Racket would be great; just do not have an idea on how to implement that integration smoothly.


You may already know about Guile-Emacs, but in case not, take a look at https://www.emacswiki.org/emacs/GuileEmacs . Guile is not Racket, or more precisely Racket is no longer exactly Scheme, but they are closer to each other than to elisp.


I use elisp for scripting occasionally (very handy when you need to script on some server but the administrator does not want to install a Lisp compiler, and quite usable with the cl- libraries), and the biggest annoyance is that you need to use buffers to do file IO. That is another layer of boilerplate on top of the Lisp file IO facilities, compared to Bourne shell-style scripting.


    ;;; -*- lexical-binding: t -*-


I've dreamed of Rackmacs for a while now.

Racket seems like a near perfect match for the domain. Start with a hacky one-off script. Augment with unit tests. Code base grows and starts becoming more stable? Progressively migrate to Typed Racket.


The idea of using a language without Map/Reduce/Filter as a substitute for a Lisp, in an editor built around Lisp...seems vaguely antithetical to me.


You can call map/reduce/filter from Go code: `xs := lisp.Mapcar(f, ys)`.

Mapconcat is already used inside runtime implementation: https://github.com/Quasilyte/goism/blob/master/src/emacs/rt/... (Print and Println functions).


Why did you get downvoted for this?


Antithetical and immoral (immoral as in "violates ethical principles")


I agree Emacs Lisp is pretty inferior as far as lisps go, but IMO this seems pretty misguided.

Technically impressive, I'm sure, but will it be around for another 30 years?

If someone writes a module using this, will I be able to rely on that module keeping on working for the years to come?


The potential damage can be reduced.

There can be a backend that generates Emacs Lisp code. Not necessary optimized or idiomatic, but it could be a good starting point for rewriting.

But in general, I agree with you.


Why wouldn't that be the case? The golang authors have been pretty strong on backwards compatibility so far (even though it is admittedly a young language).


Is josteink talking about Go or Goism? Probably the latter.


I don't think inferiority of language is a strong argument either. JavaScript is pretty inferior as a programming language but that doesn't seem to have affected its popularity much.


I think that's neither here nor there. JavaScript has a lot of strengths that few other languages can claim at this point, thanks to how universal it is. Many people understand it, it can be used to build everything from desktop apps to mobile apps to servers, and it has one of the largest package repositories out there.

I'm far from a JS fanboy but I think your point lends credence to the idea of using JS more than it strengthens the use of Emacs Lisp.


I don't actually see the advantages for JavaScript. Seems every other month there is a new way to package it. So, everyone might know how to build with it, but few people know the same way of building.

Similarly, the package repository is not exactly inspiring. Similar patterns of many packages doing the same thing. Often not bringing new advantages to the table, so much as revising old weaknesses. Many rooted in choice of language.

Which is actually not too complain of JavaScript. I do like it. And I love that people are empowered to try things. Even if they were previously done. I do wish people knew more options, though. Including myself.


Trust me, I get it. I'm not a fan of JS for the exact stated reasons. It's fragmented and full of holes.

But the way I see it, JavaScript is like today's BASIC. In a very fragmented computer market, it seemed like BASIC was the one thing that ran common between a lot of home computers in the 80s. While it's not a perfect parallel, it seems with all of the different platforms that are around today it's hard to find a consumer platform that doesn't have a JavaScript interpreter jammed in it, be it an iPhone or a ChromeCast.

BASIC wasn't all sunshine and rainbows either, but it was more than enough to help unify a fragmented world. I think JavaScript is very similar in that respect, and when the dust starts to settle on modern JavaScript it will be closer to accomplishing that goal.

Whether or not NPM is actually so impressive though, I won't debate. It's useful, but uhh... yeah. The baseline quality is not quite near something like, say, PyPI.


That is actually a great comparison and a very strong argument for not using JavaScript. BASIC was big in the 1980s; where is BASIC today? Elisp code from the 1980s still runs or can be trivially ported to Emacs 25. Lisp is not a fad and Lisp never goes away.


Well, to be fair, I don't think JavaScript is at risk of dying the way BASIC did, for a lot of reasons that aren't really worth going into. If it is going to die, though, then WebAssembly is the writing on the wall.

Still, I think you're looking at this from a different angle than I am. I haven't seen one person suggest that it would be a good idea to take the Lisp out of Emacs; simply that having the option to script it with other languages would be nice.


> where is BASIC today?

On .NET, UWP and Microsoft Office macros. It even is supported by .NET Native compiler, something that F# is still WIP.

And yes, at enterprise level, there are new lines of VB.NET and VBA being written every day.


I don't see much VB around these days, it was stigmatized so much that just about every shop had to convert to c# (or something else) or they went under because due to the dead sea effect. 10 years ago half of all .net jobs would be VB.net, these days it's probably under 1/10th.

But that's kind of beside the point, VB.net is nothing like the BASIC of the 80's or the 90's, it's got more in common with java.


VB.NET is used a lot in life sciences for data analysis by people that know some programming, given that many places have Windows only desktop policy and the data readers happen to only have DLL or COM APIs as programming interface.

The medicine you might take, has been probably measured DRC reaction curves in some VB.NET application.

It is the surviving BASIC, the evolution of QuickBasic and Visual Basic into the .NET environment.

Regarding the 80's BASIC, GW-BASIC was probably the last one of such type of unstructured line numbered BASIC.


The last time I touched BASIC was Visual Basic 6. VB.NET is a great example of my point - from what I understand it was a huge pain to move VB6 applications to VB.NET


I hardly cared about VB since the Visual Basic 6 days, but then I got a few contracts in life sciences domain, and got to realize they are heavy users of it.

That is the tool that many researchers with some programming skills reach for, maybe they will some day move to Python or R, but VB is what they use currently.


and this is why I built an entire business around elisp. Elisp is not perfect but I am betting that it'll be around for at least 30 more years.


Also javascript is pretty good at creating dsls as far as non-lisps go. The only real mainstream competitors on this space are ruby, scala and, possibly, rust.


Neovim has a go client[1] for nvim's RPC API. Vim doesn't have bytecode to speak of, so of course there's no transpiler step. But it removes the friction of integrating between nvim <-> go, and that is "useful when it's useful". In particular it enabled a new UI[2] to be built in go.

[1] https://github.com/neovim/go-client

[2] https://github.com/dzhou121/gonvim


Dear God, no. No. Please, just give me Guile. Please. We've been so good. So patient. Guile.


What a sad idea.

Seriosuly, is that hard to learn Emacs Lisp? Even if one is using Go or Rust (etc) at work, any programmer worth his salt should at least already be familiar with Lisp syntax.

It is one of the easiest languages to learn!!


I love Emacs Lisp.

Emacs has really good support for it which continues to improve over time.

But.. I love more than one language (and more than one Lisp for sure). Will you try to persuade me that I am wrong in that regard?


Emacs only having elispallows me to fix the third party code that I have in my config, and simplifies all the things. Thoemacs already has C too now, there is module support. I guess it could be possible to use Rust via that interface too, and maybe go. But better keep these to a minimum because elisp is one of the things that makes emacs great


Another case where it'd be nice to have a "Why are we doing this?" section in the README.

If it's just a demo then it's neat. Interesting that it can be done.

On the other hand, if it's a real push to get people scripting Emacs with Go, then I don't see the point at all. It's solving a problem people don't really have.


> It's solving a problem people don't really have.

Isn’t "I want to script Emacs but I don’t like LISP" a problem to solve?


You're postulating a population that are willing to take on the cognitive burden of learning Emacs but who are unwilling to do the same for ELisp. I think that's a smallish population, almost entirely composed of people who want a Scheme, probably Guile, instead (but, like me, are plugging along in Elisp in anticipation of Emacs-Guile potentially shipping before the Rapture). People who want to script in Go, Common Lisp, Javascript, C, Fortran or the Power of Christ are currently pretty much entirely confined to the immediate teams working on those various projects. More power to them, no one who loves Emacs should ever tell anyone 'no, that's not appropriate for Emacs' (I think we established a pretty long time ago that weird esoteric projects out of left field are basically Emacs' wheelhouse, and often turn into really important sub-projects). But, I'm not interested, and I don't know any regular users of Emacs who would be.


I've actually met many programmers who used Emacs but knew zero Lisp of any kind, including Emacs Lisp. They were just happy using the available goods without looking under the hood.

I don't think it's that unusual. Emacs is quite popular. If even 25% of the user base coded in Lisp, it would be ... astonishing.


Absolutely. But I think that, when those programmers do decide "hey, now I want to write some custom code for Emacs", they don't then think "but not in Elisp".


It's pretty easy to get started coding in elisp. You essentially start doing it every time you use any command, so there's a mapping from a manual change to scripting it.

Source: am Emacs user, have a few (not a lot) functions that I cobbled together from things I did all the time.


Are there many (or even any) people in that situation, though?

Who decides they want a script-able editor, but then chooses one scripted in a language they don't like and don't want to learn?


> Are there many (or even any) people in that situation, though?

Probably not (except those who made that project).

> Who decides they want a script-able editor, but then chooses one scripted in a language they don't like and don't want to learn?

Mostly because the scripting language is not the first thing you think about when using an editor (just guessing here; I don’t have data on that). I started using Vim because its editing capabilities are quite powerful but its scripting language is really bad. Emacs’ LISP is great, but I can’t get used to the way Emacs commands work.


Why not? Elisp is not amazing but having a DSL and powerful metaprogramming lets you script things so much easier than a lot of languages. Viml is atrocious. There are some libraries tha use the metaprogramming to make it easier to program in as well. Vim is a good idea and makes editing text nice to use. Emacs is a good idea that everything is customizable and has a good level of abstraction to make things happen. Using evil inside Emacs makes a great editor. Spacemacs makes Emacs easier to use too with the mnemonic and ergonomic bindings and a mostly good ootb experience for how young it is.


I'd say the problem in that statement is "I don't like Lisp", and we should solve for that :)


A better thing to answer would be why people prefer less powerful languages to the more powerful, and what can be done about it? Framed that way,this seems like an XY problem.


Some optimizations are easier in Go than in Emacs Lisp, hence the potential quality of produced bytecode can be higher. For big packages that can be implemented in Go naturally (nearly without pain), this can be an advantage.

I found some optimizations that are not implemented inside Emacs lapcode optimizer. If I will port them to byte-opt everyone win, right (if they pass Emacs team review, of course)?


>why people prefer less powerful languages to the more powerful

Clearly, power is the only measure one should consider when picking a programming language. And Lisp surely has more power than Go. I'm going to guess 36.1% more power, to be exact.

>and what can be done about it

We could always start performing eugenics to get rid of them.

... Okay, I apologize for being an ass. But I hope my points aren't lost; the way you're phrasing things makes it feel like you're bitter that anyone would consider using something that's not Lisp.


>I'm going to guess 36.1% more power, to be exact. Where's this figure from?

>We could always start performing eugenics to get rid of them.

I meant more like what we could do to improve the more powerful languages to make them more appealing.

I'm less bitter than I am perplexed about the choice to use Go over Lisp.


It was sarcasm. Obviously one can't objectively measure the power of two languages. I assume you mean it has more powerful metaprogramming than Go, which is what everyone else is saying.

But I find the rhetoric quite closed-minded, because I doubt any of the people replying here who've just found out about this and are calling it a bad idea have actually tried it yet. Clearly, there are advantages to Lisp that you would lose if you tried to do something in Go. But nobody is acknowledging the reverse, that there may also be advantages in Go to Lisp that are unforeseen, even for this specific task.

All in all this is a disappointing development. I don't think it would go over the same in other text editor communities, because people seem very defensive about the use of languages in place of Lisp where they might not be so defensive about the use of languages in place of say, VimScript.


I think GP's idea was that having a more flexible language is specifically useful for configuring Emacs, not that Lisp is better than Go in every imaginable case.


I haven't tried the linked package, but it seems like the idea is that it can be used alongside Lisp. If so I'm not fully understanding how this isn't a reasonable idea. Surely _being able_ to use Go is not a bad thing and not useless?


In practice, it's close to useless. A lot of the power of Emacs comes from the homogeneity and that Emacs itself is mostly written in Emacs Lisp.

There have been attempts in the past to do similar bridges to Python and Javascript IIRC, but they ended up nowhere since they didn't mesh well with the existing ecosystem.

No matter how bad people think Emacs Lisp is (an incorrect impression, Emacs Lisp has improved tremendously) it's still a powerful Lisp and only a Lisp would provide the powerful extensibility that Emacs has.


I don't think the author is challenging most of the notions here. In fact, it seems pretty well inline with this.

I think language bridges suck, but this isn't one. It transpiles Go to Lisp bytecode, making it much closer to a first class citizen.

But more importantly, the tagline of the project isn't "Let's write Emacs in Go," nor is it "Emacs Lisp is bad," it's "Not a fan of Emacs Lisp? Hack Emacs in Go!" -- that seems pretty straightforward to me. The aim of this seems to be potential Emacs users who do not code Lisp and don't like it. There are plenty of reasons to not like Lisp, not just Emacs Lisp, including the power that it possesses, just like there are plenty of reasons to not like Go. To suggest otherwise would be elitist.

The way I see it, the potential here is to open Emacs scripting up to a wider audience of people who are not necessarily all the same kind of programmers, who may prefer more typing to more magic.


> There are plenty of reasons to not like Lisp

Would you please list those reasons?


I hope you're asking in good faith and don't really think Lisp is actually the best at everything.

Since you asked though, I'll go into my personal list. You'll note that much of these can just as easily be advantages depending on the situation and I'm by no means saying that this list applies to all things and all people (in fact it objectively doesn't.)

- The syntax: duh. Its elegant in how it mixes code and data, and unifies so much functionality into one syntax. But it has a number of disadvantages. One, the number of parens is cumbersome. You can get used to it, but it's still cumbersome. Two, it isn't always intuitive; sometimes infix syntax just plain feels ergonomically better, all flaws aside. This can absolutely be said about math. Lisp takes order of operations out of the picture, but the same would be true if you threw a shit to of parens into any language, so I feel that doesn't count.

- It's absolutely magical. It's so powerful that I wouldn't trust most programmers to wield it. It's so powerful I wouldn't trust me to wield it. I like programs that are obvious. One of Go's strengths is that it is very stupid, for example, leading to stupid code that is stupid readable by anyone (even if they're.. you get the idea.)

- Lisp feels like the world of wheel reinvention. I don't​ know if that's due to the language or the community that surrounds it, but I'd guess it's at least a little bit of both.

- Lisp is a dynamic language. By nature this is going to mean you can do less things with code statically. I'm a big fan of static typing for the obvious advantages it brings to larger projects.

- Finally, comfort. Lisp is obviously a language that has stood the test of time, but even despite that Lisp programmers are far and few in the industry. Most people are going to be familiar with imperative programming languages based off of C like syntax, or maybe something closer to Python. Either way, if you pick a random programmer off the street, you wouldn't assume they knew Lisp. (Unless their beard was really long.)


The question was in good faith and I sincerely thank you for such a well-written reply.

I think some of your points are valid, although some of them (syntax and static typing vs dynamic typing) are mostly down to preferences or getting used to different ways of working.

I think, for example, that, given the choice between those two, i'd rather have macros (lisp macros) instead of static typing.

As for the beard comment, yes, the longer the beard, the easier is to get into Lisp.

I just wanted to note, however, that Lisp is an imperative programming language, just as C or Python is. (Of course, Lisp also allows functional programming and Common Lisp allows fantastically good object oriented programming). So yes, i agree, "most people are going to be familiar with imperative programming languages based off of C-like syntax". But on the other hand, Lisp syntax is much easier to learn than C-like syntax.


It's a lisp. That is enough for a lot of us to want to use another language, irrespective of how much Emacs lisp improves.


If you don't like Lisp for editor programmoing, then an editor which is literally built upon a million lines of Lisp code seems to be a very bad choice. Even providing another extension language won't make the Lisp go away.


The implementation language does not matter to me - I'm not working on the code base, and have no interest in doing so. I don't care that there is lisp there, as long as I don't have to write it.


But this is the point that you're completely missing. Perhaps you have not spent a lot of time with Emacs?

The implementation language does matter a lot in this case, because the part of Emacs that is written in Emacs Lisp (~90% of Emacs) can and should be leveraged (modified, extended or used to build upon) at runtime by users. This is what gives Emacs it's tremendous flexibility and power.

Using anything other than a Lisp with semantics close to Emacs Lisp for user code that leverages what Emacs offers built-in, will be an exercise in frustration since a lot of the power I described will be so cumbersome to access and make use of. It's been tried before, multiple times by people not very familiar with Emacs Lisp, and it has never worked out.

Experienced Emacs Lisp developers immediately understand the futility and pointlessness of such endeavors which is why you never see them attempt them.


You should try digging deeper into Lisp before disqualifying in such a frivolous way.


You're jumping to conclusions you have no basis for.


'Not useless' is not a high enough bar in software. Flexibility always adds complexity, and complexity is a cost. Sometimes that cost is worth it, but the benefit needs to be much larger and clearer than 'not useless'.


Not a high enough bar for what exactly? So far this entire thread is a lot of vague talk spawning off the idea that it doesn't solve a problem. That's the statement I don't agree with. If enough people decided to use it, that's the only bar that actually matters. But it clearly solves a problem, just not necessarily a problem every Emacs user has.


...and write all the types (without generics) - no, thank you!

Sarcasm aside, Lisp is as much as possible well-suited for the job of text and AST processing, Emacs is one of the Lisp's "killer apps" and the second best "case study" after classic old-school AI code (PAIP).


Congratulations, keep up the good work.


How does it compare to something like https://github.com/janestreet/ecaml ?


I see three main approaches for the tasks projects like ecaml and goism try to solve:

1. Use a plugin system (ecaml)

2. Transcompile to a target language (gosim and emscripten-like platforms)

3. Embed another VM inside Emacs and call its eval

There are many differences between these approaches and I am not sure one of them is objectively better as a general solution.

For the end users, all of these approaches can deliver good level of integration (they require different sets of tricks to achieve that).


Replacing a 50s language which a 60s language! Amazing!


Being able to script the editor in something other than Lisp seems good to me (despite the objections of others in this thread). After all, many people are just scripting settings and stuff for themselves. Might as well not make them jump through hoops to do so.

I wonder about the implementation strategy -- why compile to Emacs LISP instead of doing a plugin (FFI) or RPC style setup?


What happens if I hover over a goism function and hit M-.? Do I get dumped into the go source?


Currently, no. Hope I get your question right..

Name mangling scheme preserves fully qualified package path. All goism sources live inside GOPATH (1), so nothing stops us from implementing a jump to Go definition.

For given `goism-foo/bar.baz` Emacs symbol, Go definition can be found in `GOPATH/src/foo/bar/` package. Exact location can be found by using existing Go tools (simple grep-like solution can work, too).

(1) It can change in future; see https://news.ycombinator.com/item?id=13368846 and even more relevant: https://github.com/golang/go/issues/17271


Why?


Is it possible to have a language transpire/compile to elisp?


It is possible to emit Emacs Lisp instead of bytecode/lapcode. This was the first code generator target actually.

Easier to debug, simpler to trust (for the end user) and not that hard to generate.

The problem is that it is harder to implement some features of Go in terms of Emacs Lisp without going down to the virtual machine level. Best examples are arbitrary return statements (can be emulated by throw/catch) and goto.


Could you implement arbitrary return with cl-block and cl-return-from?


With minor Emacs Lisp compiler patch (addition of %return, %goto and %label intrinsics), it is now possible to output Lisp that is optimal.

Possible implementation (about 20 lines of code): https://github.com/Quasilyte/goism/issues/57

Not sure if "defadvice" around "byte-compile-form" is acceptable for all users.


It is technically possible, but optimal solution will require more than catch and throw (cl-lib uses them) Simple demonstration: https://pastebin.com/vXp0qPw3

Some S-expressions with `cl-return' can be rewritten to avoid the need of it (by the optimizer); not sure it covers 100% of the cases though.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: