Hacker News new | past | comments | ask | show | jobs | submit | caligian's comments login

I have begun to liken elisp more after spinning some of my own utils.el. I am currently replicating my libraries from https://github.com/caligian/nvimconfig (only adding URLs for code examples)

The godforsaken perrenial problem of not having functions to deal with nested structures which are the bread and butter of stateful configurations, I was able to solve using nested table functions like I did in lua which made writing coherent configs much easier.

Apart from learning to use cl-labels for recursive lambdas and let-binding efficiently, I was able to quickly get productive with a custom API for stuff that does not have general-define-key and add-hook littered around. These features alongside emacs's more accessible API and baked in list and hash-table operators has made life easier. I can effectively throw around hash tables in place of alists which is what used to put me off emacs lisp but ht.el and some functions of my own greatly made me happy. Furthermore the fact that every last statement returns some value is just too good to make emacs a lisp REPL. That used to be the biggest annoyance in testing lua code for neovim functions. So I am super happy with that. The cherry on the cake for finally making a worthwhile REPL library that respects the project workspace. Now it feels right at home with a generic REPL library to use REPLs with any language as long as it has an REPL command. Similarly in contrast to neovim, emacs is lacking a code formatter plugin, similarly a vim-dispatch style plugin to quickly run predefined compile commands. After getting a grip on macros and making a use-package style macro, life became easier as now I could define formatters, compile commands all in the same place like use-package. After fiddling with gensym, I managed to make hygenic which made life easier for making future DSLs to map to objects or hash tables.

The best thing about macros is code generation in a specified way. In lua while making the API for neovim, table DSLs became a pain to write especially with all function definitions lying around and they barely looked like DSLs but deeply nested tables as they grew in depth. With macros, I can send around symbols without worrying about syntax errors. That makes things so much better when you can store code so easily instead of writing one dozen closures to store state. The biggest learning curve was the macros although I cannot proclaim that I am an intermediate at this, still a rookie but learning macros will make life with easier code generation when you can always pass around code in lists, manipulate the code and also eval them even in a function than a macro. Emacs lisp is enough competent with lua for configuration despite the lack of modules. Once you make clean functions and decide on handling only global state then it is as good as a lua module plus the able to grep all functions quickly.

So my question is this. Why are people still shitting on emacs lisp?it is a perfectly good language given lexical binding is completely useable? I suppose people look at nested alists and nested tables and for the latter. A-lists are not difficult to deal with but the constant cadr to get a value becomes quickly annoying


There is no 'corruption' happening anywhere.

When you register local variables, they are merely defined as register locations and have a default value of nil which is absence and hence memory saved. They would have to mark nil explicity as a new data structure which is probably wastage as they would have to allocate memory for every variable declaration that may or may not be used.

It is just nil, nil at a literal level with the exception being local variables which are handled differently as offsets to register locations than other dynamic languages without such 'local' qualifiers.

That should explain why variables can be nil but not ta les. You can hash nils but it would take up memory. I don't think it's logical to use memory for something you are already marking as absent. Why not use false instead?


As far as security is concerned, consider this example. I want to use erlang with lua. Those two are miles apart but not really when you boil everything down to a lua table. All containers are tagged tables such as having a metatable key saying 'tuple' or 'struct'. Then you serialize them back and forth via BIFs. Any value having a function will reject entire query. Furthermore a simple hash code can be forwarded after sending the data. The attacker would have to sync the client and server and make hash changes on both ends but since he cannot fuck with the server none of his tampering would work because it will be outright rejected. As far as transformer modules (aka configs) are concerned, they will be carried out AFTER the hash.


If lua is used only as an adapter, that is an intermediary between the client and host converting objects to table and vice versa. You cannot dump function definitions (hence only serializable) except in bytecode. Who'd pass that around? You can store code as pure function strings and eval them as a module to provide a transformer module. Certainly a hash can be embedded in the code or sent over the server to prevent tampering with no security headaches


I'd wager that if the person you're responding to posted because they were unsure if they understood you correctly, then after this comment they're probably sure that they don't. (But I could be wrong.)


My bad. What i meant is that code execution is alright rather than dealing with macro magic in yaml or excessively verbose nesting like in toml


Let's take another example. Consider structs as tagged tables with a metatable key that distinguishes it from ordinary tables. You can implement inheritance as chained __index closures for parent tables or simply chained tables. Or you can use the struct as is by defining a global table and creating a simple lookup. Theoretically the lookup will work faster because you can store the hierarchy as an list, run a simple index() to get the needed parent and call the method in the associated table. This is much faster than going to multiple chained tables thus slowing down lookup.

Another example is python iterators which requires a separate instance with __next__ method. It is not generic because now you can create n instances for n dicts just to use it in for syntax. Whereas in lua it is a simple closure returning the next value until nil


https://github.com/caligian/nvimconfig

https://github.com/caligian/lua-utils

The former uses the latter for nvim. And the latter makes lua perl with structs. We all loved perl for its lispy functions to deal with lists - grep, map, push, shift, unshift, etc. Nested ops are inspired by elixir.


It is constantly called one of the worst programming languages. Coders i know want to touch lua with a 10-feet pole.


Any language you can pick is considered one of the worst programming languages by at least a small pitchfork-wielding mob of programmers. Like Bjarne Stroustrup said, there are two kinds of languages - the ones people complain about, and the ones no one uses.

Getting worked up about defending the honor of programming languages is a waste of time. People either have technical reasons to choose one language over another within a specific use case, which is valid, or else their opinions are based on aesthetics or memes, which you can't really argue against effectively. Just accept that sometimes people won't like the things you like, for reasons you can't accept.

Also if you want to use arrays and structs in Lua, and you're fine being stuck with 5.1, you can always just use LuaJIT and have actual C structs and arrays. Best of both worlds, in my opinion.


Far from defending the lang's honour. There are many noteworthy things about lua. Firstly it encourages you to use query-able data structures. Lack of first class objects makes marshalling extremely easy. This is similar to using elixir which only as dicts, lists, tuples and structs. Arguably elixir is even simpler than lua when it comes to describing data because of lack of ANY OOP features that makes the object opaque with getters and setters


While attempting to teach callbacks to a room full of C# devs i figured lua was the easiest for creating readable examples. The language has very good teachable aspects. I'd pick lua over python as a teacher to teach data structures


I agree with your criticism. I could not properly use lua without creating my own set of table utils and structs (they are faster than classes)


Yes. My point is that it should not matter because you can stick to table indexing with +-1 or create a function for the same


So what does this "simple function" look like?


function mod0(x, y) return (x % y) + 1 end

Something like this? You replace % with mod0()


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

Search: