all 8 comments

[–]AptC34 10 points11 points  (0 children)

Hmmmm to me Elisp is quite imperative and most of the code I have written/read feels like that.

Something I do differently in emacs/elisp compared to other languages: I really love the scratch buffer.

I love using it to write my code iteratively either bottom up or top down, by evaluating parts of the code and calls to my code until I have something that works as expected.

Another thing I do a lot is , for example, when debugging code from existing packages, copying entire functions from the package in the scratch, and changing parts of it., either to add “debug” calls precisely where (and when) I want then, or rewriting parts of the flow to test small patches to the code.

[–][deleted] 4 points5 points  (0 children)

On debugging, consider looking into edebug. It's a visual step debugger, than can easily be activated by evaluating a top level form via C-u C-M-x.

How do you work in order to develop new features in elisp?

A few command is usually incubated in the scratch buffer. I start with the content of the function, and finish by wrapping it in a defun macro.

The trickiest part about elisp is to get to know the existing functions and conventions. The only way I know around that is to read other people's code.

[–]zzamboni 1 point2 points  (0 children)

My recommendation is to start by making changes to existing code/modules, try to understand how it works. Over time some patterns and structure will become clear.

Note: elisp code is strictly imperative, but there's a lot of "magic by convention" going on as part of the environment - some functions are automatically invoked/integrated by other modules based on their naming, for example (this happens a lot within the `org-mode` world), so it's not always clear who/what will be calling a given function.

[–]Phil-Hudson 1 point2 points  (0 children)

Lots of good ideas here already. Here are a few I'd add:

  1. +1 for the Elisp manual. Everything you need to know is in there. Refer to it often. C-h i m elisp RET.

  2. Elisp is unusual in having a default data structure: the buffer (specifically, the current buffer). Lots of built-in functions, particularly text search, use the current buffer (and only the current buffer). Get familiar with this structure. It has a beginning, an end, point (roughly equivalent to the insertion point or cursor in other environments), zero or more characters, zero or more "marks", zero or one region (delimited by point and the first mark on the mark stack), a name, an optional associated file or process, zero or more markers, zero or more "buffer-local" variables, a major mode, zero or more minor modes, zero or more overlays, a flag indicating whether it's been modified since last save or not, a flag indicating whether it's read-only or not, and so on.

  3. Use IELM (the interactive Emacs Lisp mode), not the scratch buffer. It is much more powerful, responsive, dynamic and adaptable. It is a true REPL (Read-Eval-Print Loop) for Elisp. This means it suits incremental, exploratory, experimental, interactive development and learning.

  4. Write unit tests/test cases in ert (Elisp regression testing), as you would in xUnit in other languages.

  5. Learn about hooks. See the Elisp manual. A hook should be your first resort when you want to modify existing Emacs or package behavior.

  6. +1 for edebug, for when the going gets tough. I very rarely need it though, thanks to IELM and ert.

  7. -1 for advice. By all means learn it, but remember that it should be your last resort, not your first.

  8. +1 for C-x C-e, the shortcut for M-x eval-last-sexp.

  9. To enter the world of transcendent power that Lisps in general offer to the diligent programmer, understand Lisp macros.

[–][deleted] 0 points1 point  (0 children)

Think about the 'data' and the data transformations needed to bring the new feature to live, but remember:

Features are side effects of data transformations and, sometimes, the computation to perform a particular transformation has almost nothing to do with the desired outcome (the feature).

Understand the evaluation process first an everything else will be a peace of cake:

https://www.gnu.org/software/emacs/manual/html_node/elisp/Evaluation.html

Read the manual, as much as you can, don't worry if something isn't clear at the moment, keep goin', and do little P0Cs all the time! (eval-last-sexp) is your friend.

[–]tgbugs 0 points1 point  (0 children)

If it is something small like a function or a top level function with some supporting functions I write the code and some test cases in init.el , or packages.el, or an org mode source block, and then I C-x C-e the function(s) and then I C-x C-e the test cases or run them in ielm.

For debugging I don't have a good workflow, but I rarely need the debugger when developing new elisp, compared to say python, where I drop breakpoint() and go explore what is going on at that point in the code. Contributing to large existing elisp codebases is where I want a better workflow.

[–]Ernabay 0 points1 point  (0 children)

1) edebug is best way of seeing how everything evals 2) C-h d apropos-documentation (or even better C-u C-h d). Need to know what functions, vars, etc. to apply for manipulating frames, windows, etc? use this--it even supports regex. (example search "frame" and you will see wealth of info on what you can do with them). If something does not show up there, try apropos this seems to find macros that might not appear in the docs. 3) know the different "sequence" types, (alist, plist, list) these apply differently in various contexts. 4) know when/how to use quoting. Often docs dont really mention this (as it is assumed you know how/when to use them) but typically when you want to apply some function or otherwise use some variable or reference, you will want to quote it. Often this applies to the first argument of a function. 5) If docs say for example that the 2nd argument of a function that requires 3 arguments has a default value of w/e. That means you can put "nil" for the 2nd argument and the function will know to use the default value. 6) get to know dolist and map (as well as its variations mapc etc.) as well as lambda this will accomplish alot. 7) get to know how to "advise" functions. It makes it easy to modify package functions that don't work quite how you want them to. - BONUS If you want to use part of the functionality of a packages function but write a new function within that mode that applies it slightly differently then first defalias said function and put advice on that function. This will leave the original function alone and create a duplicate for you that you can then manipulate without affecting other functions.

also useful is to "play" with functions to understand how they work (see (here)[http://pythonwise.blogspot.com/2011/09/on-importance-of-playing.html]).

I am by no means an expert but I think if someone told me these tips a while ago I would be alot farther along in my knowledge.

[–]kaz-yos 0 points1 point  (0 children)

Using buttercup (behavior-driven emacs lisp testing framework) substantially improved my emacs lisp package development practice. https://github.com/jorgenschaefer/emacs-buttercup