* Re: Why is defun not executed during load-file?
@ 2021-05-30 22:48 Drew Adams
2021-05-30 22:57 ` Emanuel Berg via Users list for the GNU Emacs text editor
0 siblings, 1 reply; 28+ messages in thread
From: Drew Adams @ 2021-05-30 22:48 UTC (permalink / raw)
To: Help-Gnu-Emacs (help-gnu-emacs@gnu.org); +Cc: Emanuel Berg
> Macros are much more difficult to debug...
`macroexpand` and `macroexpand-1` are your friends.
Separate that first step, which is just reduction
(aka rewriting / reduction semantics), from the
subsequent step of Lisp-evaluating the sexp that
results from it.
So debug the macro-expansion step, to ensure you
get the sexp you want. And debug evaluation of
that sexp - separately.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Why is defun not executed during load-file? 2021-05-30 22:48 Why is defun not executed during load-file? Drew Adams @ 2021-05-30 22:57 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-05-31 2:05 ` [External] : " Drew Adams 0 siblings, 1 reply; 28+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-05-30 22:57 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: >> Macros are much more difficult to debug... > > `macroexpand` and `macroexpand-1` are your friends. Also, writing macros compared to writing functions typically involves more bugs... -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: [External] : Re: Why is defun not executed during load-file? 2021-05-30 22:57 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-05-31 2:05 ` Drew Adams 2021-05-31 2:56 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 28+ messages in thread From: Drew Adams @ 2021-05-31 2:05 UTC (permalink / raw) To: Emanuel Berg; +Cc: Help-Gnu-Emacs (help-gnu-emacs@gnu.org) > >> Macros are much more difficult to debug... > > > > `macroexpand` and `macroexpand-1` are your friends. > > Also, writing macros compared to writing functions typically > involves more bugs... Why do you think so? Most users write far fewer macros than functions. A relative lack of familiarity/practice might facilitate introduction of bugs. IF what you claim is true. But what evidence is there? Writing code that creates code is its own thing, granted - it's a bit particular. But if you did that as often as you write typical defuns I'm guessing you'd introduce about the same number of bugs. So yes, if "typically" one doesn't write macros then writing macros will perhaps "typically" involve more bugs. But a little perspective hints that there's nothing inherently buggy about writing macros. Is it harder to ride a bike than to skateboard? Depends on how used to each you are. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [External] : Re: Why is defun not executed during load-file? 2021-05-31 2:05 ` [External] : " Drew Adams @ 2021-05-31 2:56 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-05-31 5:05 ` Drew Adams 0 siblings, 1 reply; 28+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-05-31 2:56 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: >> Also, writing macros compared to writing functions >> typically involves more bugs... > > Why do you think so? [...] Maybe because it involves an extra layer, writing something that will write something that will do something instead of writing something that will do something... > But what evidence is there? Just keep on adding layers. Write something to write something to write something ... etc. It gets more difficult for each level added, is what we think. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: [External] : Re: Why is defun not executed during load-file? 2021-05-31 2:56 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-05-31 5:05 ` Drew Adams 2021-05-31 19:20 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 28+ messages in thread From: Drew Adams @ 2021-05-31 5:05 UTC (permalink / raw) To: Emanuel Berg; +Cc: Help-Gnu-Emacs (help-gnu-emacs@gnu.org) > >> Also, writing macros compared to writing functions > >> typically involves more bugs... > > > > Why do you think so? [...] > > Maybe because it involves an extra layer, writing something > that will write something that will do something instead of > writing something that will do something... > > Just keep on adding layers. Write something to write something > to write something ... etc. It gets more difficult for each > level added, is what we think. Fair enough; reasonable argument. But I still think the perceived difficulty comes from relative lack of practice. There are only 2 levels/layers involved. And they're completely separate: (1) macro-expansion of a sexp to a sexp, and (2) evaluation of the sexp resulting from #1. You write lots of Lisp functions. And you no doubt think nothing of adding "layers" by having a function that calls a function that calls a function... Even inhibiting evaluation with `quote' here and there doesn't seem weird, once a novice practices a bit and gets used to it. But all of that is (can be) really quite complex. It's just that you do that all the time - you're used to it. You don't write Lisp macros all the time. ___ The macro-expansion step is the only part that's a bit unusual - it's different from most of the Lisp code you write. Think of that step as just replacing one sexp by another. The input sexp has the form of a Lisp function call: a non-empty list whose car is a symbol. The output is normally a sexp of the same form, but it need not be - it can be any Lisp value (any list, vector, string, symbol, number, buffer, frame, syntax table, keymap,...). As far as step #1 is concerned, its result need not even be something that can be evaluated - or even read - without error. And you have Lisp completely at your disposal, for creating the output sexp, given the input sexp. ___ Once you have the macro-expansion step defined, the job's typically done. What's left is to verify that the output sexp _evaluates_ to the result you want - and that, for every possible input. That is, because the result of macro-expansion (#1) is typically evaluated, you do have to worry about that evaluation step (#2), yes. But if you only ever used `macroexpand' of sexp to sexp to sexp to sexp,... then you wouldn't need to bother with that worry. You'd just be transforming one list with a symbol car to another, to another, to another,... Macro-expansion isn't evaluation; it's reduction. Lisp evaluation rules don't apply to producing the output sexp from the input sexp. What rules do apply? Whatever rules you like. The only rule underlying it all is that the input needs to be a list with a symbol car. For those used to purely functional programming, that's all macro-expansion is: just reduction - term rewriting. You can look at it as a rewrite rule from input patterns to output patterns. But the rule can be implemented any way you like, using any Lisp code. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [External] : Re: Why is defun not executed during load-file? 2021-05-31 5:05 ` Drew Adams @ 2021-05-31 19:20 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-05-31 19:47 ` Stefan Monnier via Users list for the GNU Emacs text editor ` (4 more replies) 0 siblings, 5 replies; 28+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-05-31 19:20 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: >>>> Also, writing macros compared to writing functions >>>> typically involves more bugs... >>> >>> Why do you think so? [...] >> >> Maybe because it involves an extra layer, writing something >> that will write something that will do something instead of >> writing something that will do something... >> >> Just keep on adding layers. Write something to write >> something to write something ... etc. It gets more >> difficult for each level added, is what we think. > > Fair enough; reasonable argument. > > But I still think the perceived difficulty comes from > relative lack of practice. There are only 2 levels/layers > involved. And they're completely separate: (1) > macro-expansion of a sexp to a sexp, and (2) evaluation of > the sexp resulting from #1. > > You write lots of Lisp functions. And you no doubt think > nothing of adding "layers" by having a function that calls > a function that calls a function... Even inhibiting > evaluation with `quote' here and there doesn't seem weird, > once a novice practices a bit and gets used to it. But all > of that is (can be) really quite complex. > > It's just that you do that all the time - you're used to it. > You don't write Lisp macros all the time. > > The macro-expansion step is the only part that's a bit > unusual - it's different from most of the Lisp code > you write. > > Think of that step as just replacing one sexp by another. > The input sexp has the form of a Lisp function call: > a non-empty list whose car is a symbol. > > The output is normally a sexp of the same form, but it need > not be - it can be any Lisp value (any list, vector, string, > symbol, number, buffer, frame, syntax table, keymap,...). > As far as step #1 is concerned, its result need not even be > something that can be evaluated - or even read - > without error. > > And you have Lisp completely at your disposal, for creating > the output sexp, given the input sexp. > > Once you have the macro-expansion step defined, the job's > typically done. What's left is to verify that the output > sexp _evaluates_ to the result you want - and that, for > every possible input. > > That is, because the result of macro-expansion (#1) is > typically evaluated, you do have to worry about that > evaluation step (#2), yes. > > But if you only ever used `macroexpand' of sexp to sexp to > sexp to sexp,... then you wouldn't need to bother with that > worry. You'd just be transforming one list with a symbol car > to another, to another, to another,... > > Macro-expansion isn't evaluation; it's reduction. > Lisp evaluation rules don't apply to producing the output > sexp from the input sexp. What rules do apply? > Whatever rules you like. The only rule underlying it all is > that the input needs to be a list with a symbol car. > > For those used to purely functional programming, that's all > macro-expansion is: just reduction - term rewriting. You can > look at it as a rewrite rule from input patterns to output > patterns. But the rule can be implemented any way you like, > using any Lisp code. Hm ... interesting. Yeah, maybe we should start do that more? But I'm unsure even what is the entry point... What kind of things or problems could or should you solve with macros? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [External] : Re: Why is defun not executed during load-file? 2021-05-31 19:20 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-05-31 19:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-05-31 20:09 ` Marcin Borkowski 2021-06-07 2:19 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-05-31 21:40 ` Example use of macro to minimize and generalize the code Jean Louis ` (3 subsequent siblings) 4 siblings, 2 replies; 28+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-05-31 19:47 UTC (permalink / raw) To: help-gnu-emacs > Hm ... interesting. Yeah, maybe we should start do that more? Not really: it's better to avoid macros when you can. But it's better to use macros than to use `eval`. > What kind of things or problems could or should you solve > with macros? Whenever you find yourself forced to use `eval` ? Stefan ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [External] : Re: Why is defun not executed during load-file? 2021-05-31 19:47 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-05-31 20:09 ` Marcin Borkowski 2021-06-07 2:19 ` Emanuel Berg via Users list for the GNU Emacs text editor 1 sibling, 0 replies; 28+ messages in thread From: Marcin Borkowski @ 2021-05-31 20:09 UTC (permalink / raw) To: Stefan Monnier; +Cc: help-gnu-emacs On 2021-05-31, at 21:47, Stefan Monnier via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote: >> Hm ... interesting. Yeah, maybe we should start do that more? > > Not really: it's better to avoid macros when you can. > But it's better to use macros than to use `eval`. > >> What kind of things or problems could or should you solve >> with macros? > > Whenever you find yourself forced to use `eval` ? Or when you lack some syntactical construct you could find useful, like anaphoric-if. Or if what you need is closer to a "special form" than to a function. A typical case is when you need a construct which will be able to evaluate something or not, depending on the circumstances. Or when you need a construct which will evaluate some form(s) /after/ doing something (remember that when a function gets its arguments, they are all evaluated before even the first form of a function is evaluated!). Here (shameless plug!) is an example of something you couldn't achieve with functions alone (unless you wanted to wrap some code in `(lambda () ...)', which would be rather ugly): http://mbork.pl/2016-04-24_The_conditional-save-excursion_macro Hth, -- Marcin Borkowski http://mbork.pl ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [External] : Re: Why is defun not executed during load-file? 2021-05-31 19:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-05-31 20:09 ` Marcin Borkowski @ 2021-06-07 2:19 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-06-07 6:27 ` Jean Louis 2021-06-07 14:18 ` FW: " Drew Adams 1 sibling, 2 replies; 28+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-06-07 2:19 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier via Users list for the GNU Emacs text editor wrote: >> Hm ... interesting. Yeah, maybe we should start do that more? > > Not really: it's better to avoid macros when you can. > But it's better to use macros than to use `eval`. Ah, that's what I thought all along but it sounded cool when Mr Adams said it wasn't evaluated anymore but reduced (?) ... >> What kind of things or problems could or should you solve >> with macros? > > Whenever you find yourself forced to use `eval` ? OK so the hierarchy is: 1. `defun' (best) 2. `defmacro' (at least better than `eval') 3. eval (worse) That what you meant? Can one summarize in human language without references to Lisp perhaps when macros are used? I used them so seldom I don't know why people use them, even. I guess I did so good now I'm ignorant instead. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [External] : Re: Why is defun not executed during load-file? 2021-06-07 2:19 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-06-07 6:27 ` Jean Louis 2021-06-07 14:18 ` FW: " Drew Adams 1 sibling, 0 replies; 28+ messages in thread From: Jean Louis @ 2021-06-07 6:27 UTC (permalink / raw) To: help-gnu-emacs * Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2021-06-07 05:20]: > OK so the hierarchy is: > > 1. `defun' (best) > 2. `defmacro' (at least better than `eval') > 3. eval (worse) No need for panic. There is nothing so special that can take place with `eval' that cannot take place with `defun' or any bad programming. We already said Org is eval-ing so much. Every Babel source block in Org mode is eval-ed. 8 matches for "(eval " in buffer: org.el 8421: (eval `(let ,binds 9329: (or (eval checklist) 12473: (setq scope (eval scope))) 14231: (eval form) 14645: (result (if calendar-debug-sexp (eval sexp) 14647: (eval sexp) 16525: (eval org-speed-command)) 18337: (not (equal (symbol-value v) (eval (car (get v 'standard-value))))))) Org from Org babel: (defun org-babel-execute:emacs-lisp (body params) "Execute a block of emacs-lisp code with Babel." (let* ((lexical (cdr (assq :lexical params))) (result-params (cdr (assq :result-params params))) (body (format (if (member "output" result-params) "(with-output-to-string %s\n)" "(progn %s\n)") (org-babel-expand-body:emacs-lisp body params))) (result (eval (read (if (or (member "code" result-params) I have been `eval'-ing for years by using Perl, by using Common Lisp and now Emacs Lisp especially when it comes to replacement of text, variables, or keeping some program code in the database. Each time you press C-x C-e you are `eval'-ing Some data has to be eval-ed and some data arrives from other places but program file, or is generated in some way and there is nothing wrong with using `eval' wherever it is required. -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns In support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 28+ messages in thread
* FW: [External] : Re: Why is defun not executed during load-file? 2021-06-07 2:19 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-06-07 6:27 ` Jean Louis @ 2021-06-07 14:18 ` Drew Adams 2021-06-07 14:41 ` Emanuel Berg via Users list for the GNU Emacs text editor 1 sibling, 1 reply; 28+ messages in thread From: Drew Adams @ 2021-06-07 14:18 UTC (permalink / raw) To: Help-Gnu-Emacs (help-gnu-emacs@gnu.org); +Cc: Emanuel Berg > >> Hm ... interesting. Yeah, maybe we should start do that more? > > > > Not really: it's better to avoid macros when you can. > > But it's better to use macros than to use `eval`. > > Ah, that's what I thought all along but it sounded cool when > Mr Adams said it wasn't evaluated anymore but reduced (?) ... Mr. Adams also said: If you mean use `defmacro' more or something, then let me be clear that I'm NOT suggesting that. I'm not suggesting that people should define more Lisp macros. In general, don't define a macro if a function will do ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ what you want. I just wanted to point out that I think the supposed difficulty or bugginess of defining macros is due partly (largely?) to the fact that we (all of us) write macros much less often than we write functions. > Can one summarize in human language without references to Lisp > perhaps when macros are used? I used them so seldom I don't > know why people use them, even. I guess I did so good now I'm > ignorant instead. Syntax transformation: sexp1 to sexp2, followed typically (and automatically) by evaluation of sexp2. Without the evaluation step (i.e., with only "expansion"), a macro just substitutes one sexp (that's an expression - syntax) for another. When do you want to do syntax transformation? Typically to define a domain-specific language (which nevertheless has Lisp-like syntax). And "DSL" here can mean just define some accessor functions (macros) that speak more directly to the purpose/intent/meaning of the thing accessed. Another typical use is to define a control structure, that is, something that need not evaluate all of its args before invoking the body. E.g., a conditional or other predicate. You can't define something like `if' with `defun' in Elisp. You can defined it as a macro. I said all of this before, with examples: https://lists.gnu.org/archive/html/help-gnu-emacs/2021-05/msg01157.html ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: FW: [External] : Re: Why is defun not executed during load-file? 2021-06-07 14:18 ` FW: " Drew Adams @ 2021-06-07 14:41 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 0 replies; 28+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-06-07 14:41 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: > Mr. Adams also said: > > If you mean use `defmacro' more or something, then let > me be clear that I'm NOT suggesting that. I'm not > suggesting that people should define more Lisp macros. > > In general, don't define a macro if a function will do > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > what you want. > > I just wanted to point out that I think the supposed > difficulty or bugginess of defining macros is due partly > (largely?) to the fact that we (all of us) write macros > much less often than we write functions. Yeah, but how do you get more experience without doing it? So then it is all the way back to reality where it is more difficult and do involve more bugs and more difficult debugging? Or should I rephrase it so, macros are more difficult, it involves more bugs that are harder to fix, except for the people whose poor judgement and intuition has placed them in the undesirable situation where they in fact have AS MUCH experience with defuns as with macros? Still - doesn't sound right? But difficult to say what Lego piece is missing. Copenhagen maybe? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 28+ messages in thread
* Example use of macro to minimize and generalize the code 2021-05-31 19:20 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-05-31 19:47 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-05-31 21:40 ` Jean Louis 2021-05-31 23:37 ` Michael Heerdegen 2021-05-31 21:45 ` Example use of macro to minimize and generalize the code (2) Jean Louis ` (2 subsequent siblings) 4 siblings, 1 reply; 28+ messages in thread From: Jean Louis @ 2021-05-31 21:40 UTC (permalink / raw) To: help-gnu-emacs * Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2021-05-31 22:21]: > What kind of things or problems could or should you solve > with macros? Example use of macro: I have noticed that I am often repeating some structures, really boring, something like: (defun my-fun () (interactive) (let ((id (tabulated-list-get-id))) (if (and id (string= rcd-current-table "hyobjects")) (do-more) (warn something)))) instead: (defmacro when-tabulated-id (table id &rest body) (declare (indent 2) (debug t)) (ignore id) `(if id (progn ,@body) (if (or (eq ,table 'any) (string-equal ,table rcd-current-table)) (let ((id (tabulated-list-get-id))) (if id (progn ,@body) (message "Did not get ID"))) (message "This function is for table `%s' only" ,table)))) solves the problem and I get less code: (defun my-fun (&optional id) (interactive) (when-tabulated-id "hyobjects" id (do-something))) Imagine having 300+ functions where each function should maybe report something in case of error, like you can see in the macro. In this case I am minimizing code by using macro. -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns Sign an open letter in support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Example use of macro to minimize and generalize the code 2021-05-31 21:40 ` Example use of macro to minimize and generalize the code Jean Louis @ 2021-05-31 23:37 ` Michael Heerdegen 2021-05-31 23:59 ` Jean Louis 0 siblings, 1 reply; 28+ messages in thread From: Michael Heerdegen @ 2021-05-31 23:37 UTC (permalink / raw) To: help-gnu-emacs Jean Louis <bugs@gnu.support> writes: > (defmacro when-tabulated-id (table id &rest body) > (declare (indent 2) (debug t)) > (ignore id) > `(if id > (progn > ,@body) > (if (or (eq ,table 'any) > (string-equal ,table rcd-current-table)) > (let ((id (tabulated-list-get-id))) > (if id > (progn ,@body) > (message "Did not get ID"))) > (message "This function is for table `%s' only" ,table)))) There is something wrong with that definition however: the variable `id' is completely ignored, specifying something at that argument position is redundant. Tt may "work" by accident if the symbol `id' happens to be dynamically bound to the same thing that you specify as argument, but only when that exact variable name is used and only in dynamically binding Lisp. Normally the byte compiler warns about this kind of problem - of course only if you don't silence it ;-) Michael. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Example use of macro to minimize and generalize the code 2021-05-31 23:37 ` Michael Heerdegen @ 2021-05-31 23:59 ` Jean Louis 2021-06-01 0:34 ` Michael Heerdegen 0 siblings, 1 reply; 28+ messages in thread From: Jean Louis @ 2021-05-31 23:59 UTC (permalink / raw) To: Michael Heerdegen; +Cc: help-gnu-emacs * Michael Heerdegen <michael_heerdegen@web.de> [2021-06-01 02:38]: > Jean Louis <bugs@gnu.support> writes: > > > (defmacro when-tabulated-id (table id &rest body) > > (declare (indent 2) (debug t)) > > (ignore id) > > `(if id > > (progn > > ,@body) > > (if (or (eq ,table 'any) > > (string-equal ,table rcd-current-table)) > > (let ((id (tabulated-list-get-id))) > > (if id > > (progn ,@body) > > (message "Did not get ID"))) > > (message "This function is for table `%s' only" ,table)))) > > There is something wrong with that definition however: the variable `id' > is completely ignored, specifying something at that argument position is > redundant. I appreciate all comments. > Tt may "work" by accident if the symbol `id' happens to be dynamically > bound to the same thing that you specify as argument, but only when that > exact variable name is used and only in dynamically binding Lisp. You guessed it well, I am using it this way: (defun hyperscope-tabulated-action (&optional id) (interactive) (when-tabulated-id "hyobjects" id (hyperscope-ring id) (hyperscope-action id))) As there are many different tables which all have its ID, so the macro has to make sure it is invoked in the right table. There could be other ways to check that. Programs have their lexical binding true, maybe that one you did not expect. Such functions can be invoked programmatically or interactively, interactively there is check if there is right database table in the tabulated-list-mode, as otherwise it gives a warning that it is not invoked in that other different table. > Normally the byte compiler warns about this kind of problem - of course > only if you don't silence it ;-) That is why `ignore' is there. Ignore is there to suppress the byte compiler warning just as you guessed it. Otherwise: In when-tabulated-id: rcd-cf.el:165:45: Warning: Unused lexical argument `id' -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns Sign an open letter in support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Example use of macro to minimize and generalize the code 2021-05-31 23:59 ` Jean Louis @ 2021-06-01 0:34 ` Michael Heerdegen 2021-06-01 0:39 ` Jean Louis 0 siblings, 1 reply; 28+ messages in thread From: Michael Heerdegen @ 2021-06-01 0:34 UTC (permalink / raw) To: help-gnu-emacs Jean Louis <bugs@gnu.support> writes: > [...] > That is why `ignore' is there. Ignore is there to suppress the byte > compiler warning just as you guessed it. > > Otherwise: > > In when-tabulated-id: > rcd-cf.el:165:45: Warning: Unused lexical argument `id' Sure - but why do you add an argument to that macro that it (or its expansion) doesn't use at all? That's very confusing, it would be better to remove the argument. Or - could the macro be rewritten to not ignore that argument? Regards, Michael. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Example use of macro to minimize and generalize the code 2021-06-01 0:34 ` Michael Heerdegen @ 2021-06-01 0:39 ` Jean Louis 2021-06-01 0:59 ` Michael Heerdegen 0 siblings, 1 reply; 28+ messages in thread From: Jean Louis @ 2021-06-01 0:39 UTC (permalink / raw) To: Michael Heerdegen; +Cc: help-gnu-emacs * Michael Heerdegen <michael_heerdegen@web.de> [2021-06-01 03:35]: > Jean Louis <bugs@gnu.support> writes: > > > [...] > > That is why `ignore' is there. Ignore is there to suppress the byte > > compiler warning just as you guessed it. > > > > Otherwise: > > > > In when-tabulated-id: > > rcd-cf.el:165:45: Warning: Unused lexical argument `id' > > Sure - but why do you add an argument to that macro that it (or its > expansion) doesn't use at all? That's very confusing, it would be > better to remove the argument. Or - could the macro be rewritten to not > ignore that argument? I would like to improve but I have to understand what you mean. This is the macro, arguments are table, id and body. I need all of them. - table is there as I don't want my functions invoked in other tables, it could cause havoc; - ID is necessary; - functions can be then invoked programmatically and interactively with less arguments: So help me understand... (defmacro when-tabulated-id (table id &rest body) (declare (indent 2) (debug t)) (ignore id) `(if id (progn ,@body) (if (or (eq ,table 'any) (string-equal ,table rcd-current-table)) (let ((id (tabulated-list-get-id))) (if id (progn ,@body) (message "Did not get ID"))) (message "This function is for table `%s' only" ,table)))) -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns Sign an open letter in support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Example use of macro to minimize and generalize the code 2021-06-01 0:39 ` Jean Louis @ 2021-06-01 0:59 ` Michael Heerdegen 2021-06-01 1:25 ` Jean Louis 0 siblings, 1 reply; 28+ messages in thread From: Michael Heerdegen @ 2021-06-01 0:59 UTC (permalink / raw) To: help-gnu-emacs Jean Louis <bugs@gnu.support> writes: > - ID is necessary; Your macro calls always ignore what you specify at that argument's position. Instead, the macros refer to a (free) variable `id'. AFAICT, with your current implementation nothing would change if you would remove the macro argument (and the `ignore' call) and simply don't use it. Typically, the backquote expression in the macro body would have ",id" instead of "id" to include the value specified by the ID argument. The compiler warning is not just noise. Michael. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Example use of macro to minimize and generalize the code 2021-06-01 0:59 ` Michael Heerdegen @ 2021-06-01 1:25 ` Jean Louis 2021-06-01 14:02 ` Michael Heerdegen 0 siblings, 1 reply; 28+ messages in thread From: Jean Louis @ 2021-06-01 1:25 UTC (permalink / raw) To: Michael Heerdegen; +Cc: help-gnu-emacs * Michael Heerdegen <michael_heerdegen@web.de> [2021-06-01 04:00]: > Jean Louis <bugs@gnu.support> writes: > > > - ID is necessary; > > Your macro calls always ignore what you specify at that argument's > position. Instead, the macros refer to a (free) variable `id'. AFAICT, > with your current implementation nothing would change if you would > remove the macro argument (and the `ignore' call) and simply don't use > it. > > Typically, the backquote expression in the macro body would have ",id" > instead of "id" to include the value specified by the ID argument. The > compiler warning is not just noise. I do believe you see it what you say, but I didn't see what you say... (✿╹◡╹) -- so yes, now it works, thanks. I have removed `id' and `ignore' and there are no compiler warnings and there is for now no impact how I see that. That comes due to various testing, I have actually started it that way, there was no ID, then I messed something up and addedd ID and now you see more, and I removed it from bunch of functions. For now it works. (defmacro when-tabulated-id (table &rest body) (declare (indent 2) (debug t)) ;;(ignore id) `(if id (progn ,@body) (if (or (eq ,table 'any) (string-equal ,table rcd-current-table)) (let ((id (tabulated-list-get-id))) (if id (progn ,@body) (message "Did not get ID"))) (message "This function is for table `%s' only" ,table)))) -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns Sign an open letter in support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Example use of macro to minimize and generalize the code 2021-06-01 1:25 ` Jean Louis @ 2021-06-01 14:02 ` Michael Heerdegen 2021-06-01 16:33 ` Jean Louis 0 siblings, 1 reply; 28+ messages in thread From: Michael Heerdegen @ 2021-06-01 14:02 UTC (permalink / raw) To: help-gnu-emacs Jean Louis <bugs@gnu.support> writes: > (defmacro when-tabulated-id (table &rest body) > (declare (indent 2) (debug t)) > ;;(ignore id) > `(if id > (progn > ,@body) > (if (or (eq ,table 'any) > (string-equal ,table rcd-current-table)) > (let ((id (tabulated-list-get-id))) > (if id > (progn ,@body) > (message "Did not get ID"))) > (message "This function is for table `%s' only" ,table)))) Yes, better. The downside now is that using the macro hides the fact that the code depends on the id, and the resulting code is (still) hard to understand. Why don't you consider to make the id a real argument? Regards, Michael. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Example use of macro to minimize and generalize the code 2021-06-01 14:02 ` Michael Heerdegen @ 2021-06-01 16:33 ` Jean Louis 2021-06-01 16:54 ` Yuri Khan 0 siblings, 1 reply; 28+ messages in thread From: Jean Louis @ 2021-06-01 16:33 UTC (permalink / raw) To: Michael Heerdegen; +Cc: help-gnu-emacs * Michael Heerdegen <michael_heerdegen@web.de> [2021-06-01 17:03]: > Jean Louis <bugs@gnu.support> writes: > > > (defmacro when-tabulated-id (table &rest body) > > (declare (indent 2) (debug t)) > > ;;(ignore id) > > `(if id > > (progn > > ,@body) > > (if (or (eq ,table 'any) > > (string-equal ,table rcd-current-table)) > > (let ((id (tabulated-list-get-id))) > > (if id > > (progn ,@body) > > (message "Did not get ID"))) > > (message "This function is for table `%s' only" ,table)))) > > Yes, better. > > The downside now is that using the macro hides the fact that the code > depends on the id, and the resulting code is (still) hard to understand. > Why don't you consider to make the id a real argument? I wish I could fully understand but I don't, and I consider your advises important. How would I make the ID a real argument? Each of those functions has &optional id as if function is not capturing ID from tabulated-list-mode then it may receive it programmatically. Example: (defun hyperscope-new-appointment (&optional id) "Add new `Appointment' hyperdocument." (interactive) (when-tabulated-id "hyobjects" (let ((parent (hlink-parent id))) (hyperscope-add-new-appointment-hyperdocument parent)))) -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns Sign an open letter in support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Example use of macro to minimize and generalize the code 2021-06-01 16:33 ` Jean Louis @ 2021-06-01 16:54 ` Yuri Khan 2021-06-01 17:24 ` Jean Louis 0 siblings, 1 reply; 28+ messages in thread From: Yuri Khan @ 2021-06-01 16:54 UTC (permalink / raw) To: Michael Heerdegen, help-gnu-emacs On Tue, 1 Jun 2021 at 23:38, Jean Louis <bugs@gnu.support> wrote: > > > (defmacro when-tabulated-id (table &rest body) > > > (declare (indent 2) (debug t)) > > > ;;(ignore id) > > > `(if id > > Why don't you consider to make the id a real argument? > > I wish I could fully understand but I don't, and I consider your > advises important. > > How would I make the ID a real argument? I believe Michael is hinting at this: (defmacro when-tabulated-id (id table &rest body) `(if ,id … which means “at macro expansion time, substitute the value of the argument to the macro”, rather than your original (defmacro when-tabulated-id (id table &rest body) `(if id … which means “at evaluation time, substitute the value of the symbol 'id”. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Example use of macro to minimize and generalize the code 2021-06-01 16:54 ` Yuri Khan @ 2021-06-01 17:24 ` Jean Louis 2021-06-01 17:57 ` Yuri Khan 0 siblings, 1 reply; 28+ messages in thread From: Jean Louis @ 2021-06-01 17:24 UTC (permalink / raw) To: Yuri Khan; +Cc: Michael Heerdegen, help-gnu-emacs * Yuri Khan <yuri.v.khan@gmail.com> [2021-06-01 20:12]: > On Tue, 1 Jun 2021 at 23:38, Jean Louis <bugs@gnu.support> wrote: > > > > > (defmacro when-tabulated-id (table &rest body) > > > > (declare (indent 2) (debug t)) > > > > ;;(ignore id) > > > > `(if id > > > > Why don't you consider to make the id a real argument? > > > > I wish I could fully understand but I don't, and I consider your > > advises important. > > > > How would I make the ID a real argument? > > I believe Michael is hinting at this: > > (defmacro when-tabulated-id (id table &rest body) > `(if ,id > … > > which means “at macro expansion time, substitute the value of the > argument to the macro”, rather than your original > > (defmacro when-tabulated-id (id table &rest body) > `(if id > … > > which means “at evaluation time, substitute the value of the symbol > 'id”. I have removed `id' argument and now I have: (macroexpand '(when-tabulated-id "people" (ignore))) ⇒ (if id (progn (ignore)) (if (or (eq "people" 'any) (string-equal "people" rcd-current-table)) (let ((id (tabulated-list-get-id))) (if id (progn (ignore)) (message "Did not get ID"))) (message "This function is for table `%s' only" "people"))) If I would use ,d it would expand into number or nil, it seem it would end up same. Now I don't have compiler warnings, and functions work fine. Let me know if I am making errors in this. -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns Sign an open letter in support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Example use of macro to minimize and generalize the code 2021-06-01 17:24 ` Jean Louis @ 2021-06-01 17:57 ` Yuri Khan 2021-06-01 18:12 ` Jean Louis 0 siblings, 1 reply; 28+ messages in thread From: Yuri Khan @ 2021-06-01 17:57 UTC (permalink / raw) To: Yuri Khan, Michael Heerdegen, help-gnu-emacs On Wed, 2 Jun 2021 at 00:27, Jean Louis <bugs@gnu.support> wrote: > I have removed `id' argument and now I have: > > (macroexpand '(when-tabulated-id "people" (ignore))) > ⇒ (if id (progn (ignore)) > (if (or (eq "people" 'any) (string-equal "people" rcd-current-table)) > (let ((id (tabulated-list-get-id))) > (if id (progn (ignore)) (message "Did not get ID"))) > (message "This function is for table `%s' only" "people"))) > > If I would use ,d it would expand into number or nil, it seem it would end up same. > > Now I don't have compiler warnings, and functions work fine. > > Let me know if I am making errors in this. Yes you are. Your macro expands to a form that refers to a symbol named “id” from outer scope. Next, there are several possibilities: * The symbol is not defined, in which case the result of expansion will signal (void-variable id): (when-tabulated-id "people" (ignore)) ⇒ Debugger entered--Lisp error: (void-variable id) * The user of your macro has to define a variable named “id” globally or buffer-locally. This is bad because the name “id” is not namespaced. In your own package, any variable names you define should start with a prefix unique to your package. (setq id t) (when-tabulated-id "people" (ignore)) ⇒ nil * The user has to use your macro in a context where “id” is bound as a local variable or a function argument. If that’s your intent, you should document it in the docstring of the macro, but it’s fragile because nobody expects forms to behave this way. (let ((id t)) (when-tabulated-id "people" (ignore))) ⇒ nil (defun foo (id) (when-tabulated-id "people" (ignore))) (foo t) ⇒ nil * Lastly, you might have intended this macro to be used only by you. In that case, it should be namespaced to your package with a double hyphen after the prefix. Anyway, three month later, you forget that the macro depends on “id” and you stare at your (let ((id t)) …) or (defun foo (id) …) which doesn’t obviously use “id” and remove the binding. Suddenly everything breaks. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Example use of macro to minimize and generalize the code 2021-06-01 17:57 ` Yuri Khan @ 2021-06-01 18:12 ` Jean Louis 0 siblings, 0 replies; 28+ messages in thread From: Jean Louis @ 2021-06-01 18:12 UTC (permalink / raw) To: Yuri Khan; +Cc: Michael Heerdegen, help-gnu-emacs * Yuri Khan <yuri.v.khan@gmail.com> [2021-06-01 20:58]: > On Wed, 2 Jun 2021 at 00:27, Jean Louis <bugs@gnu.support> wrote: > > > I have removed `id' argument and now I have: > > > > (macroexpand '(when-tabulated-id "people" (ignore))) > > ⇒ (if id (progn (ignore)) > > (if (or (eq "people" 'any) (string-equal "people" rcd-current-table)) > > (let ((id (tabulated-list-get-id))) > > (if id (progn (ignore)) (message "Did not get ID"))) > > (message "This function is for table `%s' only" "people"))) > > > > If I would use ,d it would expand into number or nil, it seem it would end up same. > > > > Now I don't have compiler warnings, and functions work fine. > > > > Let me know if I am making errors in this. > > Yes you are. Your macro expands to a form that refers to a symbol > named “id” from outer scope. Next, there are several possibilities: > > * The symbol is not defined, in which case the result of expansion > will signal (void-variable id): > > (when-tabulated-id "people" (ignore)) > ⇒ Debugger entered--Lisp error: (void-variable id) Macro is exclusively used in functions as this: (defun my-fun (&optional id) "" (interactive) (when-tabulated-id "hyobjects" )) > * The user of your macro has to define a variable named “id” globally > or buffer-locally. This is bad because the name “id” is not > namespaced. In your own package, any variable names you define should > start with a prefix unique to your package. Do you mean all, or just global variables to have prefix? > (setq id t) > (when-tabulated-id "people" (ignore)) > ⇒ nil I understand, just macro is used exclusively in functions as above. Is that alright? > * The user has to use your macro in a context where “id” is bound as a > local variable or a function argument. If that’s your intent, you > should document it in the docstring of the macro, but it’s fragile > because nobody expects forms to behave this way. > > (let ((id t)) > (when-tabulated-id "people" (ignore))) > ⇒ nil > > (defun foo (id) > (when-tabulated-id "people" (ignore))) > (foo t) > ⇒ nil (◍•ᴗ•◍) that can be, but that is exactly how I expected it to behave. As the ID is either obtained programmatically which makes the macro work or from (tabulated-list-get-id) > * Lastly, you might have intended this macro to be used only by you. Yes, and I see difficulties in future if somebody else wish to use it. > In that case, it should be namespaced to your package with a double > hyphen after the prefix. Anyway, three month later, you forget that > the macro depends on “id” and you stare at your (let ((id t)) …) or > (defun foo (id) …) which doesn’t obviously use “id” and remove the > binding. Suddenly everything breaks. Breaking I can also understand. Macro or not macro my goal is to minimize programming, as 400+ functions are asking for (tabulated-list-get-id) and the ID can be in different tables. Maybe it can be solved without any macro. -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns Sign an open letter in support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Example use of macro to minimize and generalize the code (2) 2021-05-31 19:20 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-05-31 19:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-05-31 21:40 ` Example use of macro to minimize and generalize the code Jean Louis @ 2021-05-31 21:45 ` Jean Louis 2021-05-31 21:48 ` [External] : Re: Why is defun not executed during load-file? Michael Heerdegen 2021-05-31 23:41 ` Drew Adams 4 siblings, 0 replies; 28+ messages in thread From: Jean Louis @ 2021-05-31 21:45 UTC (permalink / raw) To: help-gnu-emacs * Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2021-05-31 22:21]: > What kind of things or problems could or should you solve with > macros? Another good use of a macro is with the database application where: - database user can define the type of the object, for example, database user "joe" could create new type named "bc evaluation" - the type of the object is accessible to user only, not to other users; - user edits the type and declares that the value should be evaluated with the external program named "bc". Such declaration could be simple "bc" instead of complex programming - macro generates a function specific for that user who needs to see the output from "bc evaluation" Thus it becomes a program that develops itself further based on users's input. -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns Sign an open letter in support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [External] : Re: Why is defun not executed during load-file? 2021-05-31 19:20 ` Emanuel Berg via Users list for the GNU Emacs text editor ` (2 preceding siblings ...) 2021-05-31 21:45 ` Example use of macro to minimize and generalize the code (2) Jean Louis @ 2021-05-31 21:48 ` Michael Heerdegen 2021-05-31 23:41 ` Drew Adams 4 siblings, 0 replies; 28+ messages in thread From: Michael Heerdegen @ 2021-05-31 21:48 UTC (permalink / raw) To: help-gnu-emacs Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> writes: > What kind of things or problems could or should you solve > with macros? My opinion is: Macros extend the language ("Lisp is a programmable programming language"). Using macros can be beneficial if the problem is of a kind so that adding new constructs to the language allows for abstractions or at least coding style that makes writing and reading code (and thinking) actually easier. If that's not the case, don't use them when possible. Michael. ^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: [External] : Re: Why is defun not executed during load-file? 2021-05-31 19:20 ` Emanuel Berg via Users list for the GNU Emacs text editor ` (3 preceding siblings ...) 2021-05-31 21:48 ` [External] : Re: Why is defun not executed during load-file? Michael Heerdegen @ 2021-05-31 23:41 ` Drew Adams 4 siblings, 0 replies; 28+ messages in thread From: Drew Adams @ 2021-05-31 23:41 UTC (permalink / raw) To: Emanuel Berg; +Cc: Help-Gnu-Emacs (help-gnu-emacs@gnu.org) > Hm ... interesting. Yeah, maybe we should start do that more? Dunno what you mean by "do that more". If you mean use `defmacro' more or something, then let me be clear that I'm NOT suggesting that. I'm not suggesting that people should define more Lisp macros. In general, don't define a macro if a function will do what you want. I just wanted to point out that I think the supposed difficulty or bugginess of defining macros is due partly (largely?) to the fact that we (all of us) write macros much less often than we write functions. > But I'm unsure even what is the entry point... I'm guessing that here you're asking about how to use a macro to just translate one Lisp sexp to another (where the first is a list with symbol car). If so, the answer is to use function `macroexpand'. (or `macroexpand-1' or `macroexpand-all'). That just does the first step: it expands an input sexp to its expansion. `eval', on the other hand, does both steps: it expands the input sexp and then it evaluates the resulting sexp. (defun bar (x y z) (format "%s, %s! Is the answer really %s?" y x z)) (defmacro foo (a b) `(bar ,b ,a 42)) (macroexpand '(foo "Hello" 'alpha)) ; ==> (bar 'alpha "Hello" 42) (eval '(foo "Hello" 'alpha))) ; ==> "Hello, alpha! Is the answer really 42?" > What kind of things or problems could or should you solve > with macros? Sexp translation. One common use is to define control structures (conditionals etc.), since a macro need not evaluate all (or any) of its arguments. Emacs Lisp (like most Lisps) is not lazy - functions evaluate all of their args before the function body is invoked. So you can't define a conditional such as `my-if' as a Lisp function. But you can define it as a macro. Another common use is to define access functions, e.g., provide recognizable, domain-specific names. E.g.: (defmacro antenna-frobulator (satellite) `(caddr (caar (cddr (cdaar satellite))))) Defining a domain-specific language is a major use case for Lisp macros. Of course, with Emacs Lisp the resulting language still has Lisp-like syntax to a large extent. But with Common Lisp you also have reader macros, which means you can end up with pretty much any syntax you want for your DSL. Most uses of macros are something like these. Paul Graham describes what Lisp macros are all about, what they're used for, and how to use them, in several of his essays, and in his book "On Lisp". Here's one such short essay - search for "macro": http://www.paulgraham.com/avg.html ___ What's a use case of just macro-expanding, i.e., just translating Lisp sexps, without evaluating the result? This is not common. Let me be clear about that. But as one example, the first non-trivial Lisp program I wrote did just that. It essentially used `macrolet' to define a zillion macros that translated all of the predefined forms (functions, special forms, macros) of Franz Lisp to Common Lisp (this was before Franz Inc. went Common). (Another part of the code translation translated predefined global variables.) The program was used to make a first, automatic, pass at translating lots of Franz-Lisp code to Common Lisp for a Lisp/Prolog machine we built. (This was back when there were few CL implementations. A preliminary implementation of Kyoto CL was all we had. We were writing a CL implementation for the Lisp machine.) Franz then was only dynamically scoped, and CL is lexically scoped, so exact translation is ultimately impossible. But a given sexp translation (e.g. `(apply #+ foobar)' could sometimes be relatively straightforward. (Actually, even `+' was not straightforward, as the type systems were different etc.) In a simple case, a sexp translation might only mean changing the order of some arguments. The two Lisps had a lot in common, even though they were also very different. There were plenty of "faux amis" and such. More generally, the output would be a sexp with lambda forms that had doc strings describing correspondences for functions/macros etc. (the closest correspondences to be found), args, limitations, etc. The result of translating a short program could thus be a large program of approximate code. The point was to serve as an aid to humans who had to produce a CL version of the code. We translated tons of code this way. The translation tool was only that - a tool that helped people translate code. You could also use the tool interactively to evaluate the translation result. That is, it gave us a way to to interpret Franz code on the fly using CL, in a first-pass way. That helped with testing & debugging. ^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2021-06-07 14:41 UTC | newest] Thread overview: 28+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-05-30 22:48 Why is defun not executed during load-file? Drew Adams 2021-05-30 22:57 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-05-31 2:05 ` [External] : " Drew Adams 2021-05-31 2:56 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-05-31 5:05 ` Drew Adams 2021-05-31 19:20 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-05-31 19:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-05-31 20:09 ` Marcin Borkowski 2021-06-07 2:19 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-06-07 6:27 ` Jean Louis 2021-06-07 14:18 ` FW: " Drew Adams 2021-06-07 14:41 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-05-31 21:40 ` Example use of macro to minimize and generalize the code Jean Louis 2021-05-31 23:37 ` Michael Heerdegen 2021-05-31 23:59 ` Jean Louis 2021-06-01 0:34 ` Michael Heerdegen 2021-06-01 0:39 ` Jean Louis 2021-06-01 0:59 ` Michael Heerdegen 2021-06-01 1:25 ` Jean Louis 2021-06-01 14:02 ` Michael Heerdegen 2021-06-01 16:33 ` Jean Louis 2021-06-01 16:54 ` Yuri Khan 2021-06-01 17:24 ` Jean Louis 2021-06-01 17:57 ` Yuri Khan 2021-06-01 18:12 ` Jean Louis 2021-05-31 21:45 ` Example use of macro to minimize and generalize the code (2) Jean Louis 2021-05-31 21:48 ` [External] : Re: Why is defun not executed during load-file? Michael Heerdegen 2021-05-31 23:41 ` Drew Adams
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).