* Using setq to obtain a symbol from a list, so that I can assign a function to it @ 2008-04-22 2:28 srinik001 2008-04-22 5:19 ` srinik001 ` (2 more replies) 0 siblings, 3 replies; 16+ messages in thread From: srinik001 @ 2008-04-22 2:28 UTC (permalink / raw) To: help-gnu-emacs Hello, I would really appreciate some help on this. I am trying to do just about everything with Emacs (and Emacs Lisp) these days. One of the things I need to do in my job is to create XML files. I thought I would use Emacs rather than some other editor/tool. So, I am trying to write a tool that will enable me to write specific XML files by prompting me to enter values. Here is how I am trying to do it. First, I set a variable that will provide a "grammar" for my file that Emacs will help me write. An example is the following : of course, my actual problem is not about generating English sentences; this is just for illustration. (setq grammar '((sentence <- subject predicate) (subject <- article noun) (predicate <- verb))) I expect to generate functions that look like this: (defun sentence() (........some stuff .........) (subject) (predicate) (........some stuff again...)) What I want the system to do is to generate the function automatically. So, I should have functions for sentence, subject and predicate. I will of course hand-code the functions for article, noun and verb. I don't want to write the above defun; I want to generate it by using (setq sentence #'(lambda() ( (subject) (predicate)))). Of course, instead of "sentence". I want to use (car x) or something like that by reading the variable "grammar". Here is the problem: when I do this: (setq (car (expression that generates sentence) #'(lambda() (print "hello"))) I get an error. But if I do a (setq x (car ... ) to get the sentence symbol and THEN assign it, everything works. Is there something fundamental I am missing? Thanks, Regards, SK ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it 2008-04-22 2:28 Using setq to obtain a symbol from a list, so that I can assign a function to it srinik001 @ 2008-04-22 5:19 ` srinik001 2008-04-22 12:54 ` Barry Margolin ` (2 more replies) 2008-04-22 15:22 ` Ted Zlatanov 2008-04-22 19:59 ` Pascal Bourguignon 2 siblings, 3 replies; 16+ messages in thread From: srinik001 @ 2008-04-22 5:19 UTC (permalink / raw) To: help-gnu-emacs Oops... I got the subject wrong. Instead of " Using setq to obtain a symbol from a list, so that I can assign a function to it", it should read, "Using setq to assign value to the result of a function". Sorry about that. Regards, SK ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it 2008-04-22 5:19 ` srinik001 @ 2008-04-22 12:54 ` Barry Margolin 2008-04-23 4:40 ` srinik001 2008-04-23 5:10 ` Kevin Rodgers [not found] ` <mailman.10729.1208927476.18990.help-gnu-emacs@gnu.org> 2 siblings, 1 reply; 16+ messages in thread From: Barry Margolin @ 2008-04-22 12:54 UTC (permalink / raw) To: help-gnu-emacs In article <a4bb6deb-6337-43bd-95e4-64a29770c803@y18g2000pre.googlegroups.com>, srinik001@hotmail.com wrote: > Oops... I got the subject wrong. Instead of > > " Using setq to obtain a symbol from a list, so that I can assign a > function to it", it should read, "Using setq to assign value to the > result of a function". Sorry about that. Use set instead of setq. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group *** ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it 2008-04-22 12:54 ` Barry Margolin @ 2008-04-23 4:40 ` srinik001 2008-04-23 22:14 ` Pascal Bourguignon 2008-04-24 2:50 ` Barry Margolin 0 siblings, 2 replies; 16+ messages in thread From: srinik001 @ 2008-04-23 4:40 UTC (permalink / raw) To: help-gnu-emacs On Apr 22, 5:54 am, Barry Margolin <bar...@alum.mit.edu> wrote: > In article > <a4bb6deb-6337-43bd-95e4-64a29770c...@y18g2000pre.googlegroups.com>, > > srinik...@hotmail.com wrote: > > Oops... I got the subject wrong. Instead of > > > " Using setq to obtain a symbol from a list, so that I can assign a > > function to it", it should read, "Using setq to assign value to the > > result of a function". Sorry about that. > > Use set instead of setq. > > -- > Barry Margolin, bar...@alum.mit.edu > Arlington, MA > *** PLEASE post questions in newsgroups, not directly to me *** > *** PLEASE don't copy me on replies, I'll read them in the group *** Thanks for the tip. Now, it does not throw an error. But I still don't get what I want. Here is what I did: (setq grammar '((sentence ::= subject predicate) (subject ::= article noun) (predicate ::= verb))) --> This of course worked. I could see the individual elements, their car's and cdr's etc. Then I defined the "leaf" level things: (defun article() (insert "article")) (defun noun() (insert "noun")) (defun verb() (insert "verb")) Then I tried this: (dolist (x grammar) (set (car x) (dolist (y (cdr (cdr x))) (funcall y))) It threw an error saying that it did not know what subject was. Of course, the way the grammar was described in the list, it did not know that. So I tried reversing the grammar, thinking that if it went the other way, it would understand subject before it came to sentence. So, I tried this. (dolist (x (reverse grammar)) (set (car x) (dolist (y (cdr (cdr x))) (funcall y)))) It still gave the same error! It seems that when it does a set operation, it forgets it in the next iteration of the loop. I apologize if these are trivial questions, but while being *very* addictive, Lisp seems unlike anything else that I have done before; perhaps I need to study Lisp a lot more before giving myself exercises like these, by studying Pascal's reply more carefully - I need to look up many of the functions/terms he uses. For example, I don't really get the difference between the quoted and the unquoted - I know they are different but can't seem to be able to put my finger on the exact difference. Thanks, Regards, SK ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it 2008-04-23 4:40 ` srinik001 @ 2008-04-23 22:14 ` Pascal Bourguignon 2008-04-24 2:50 ` Barry Margolin 1 sibling, 0 replies; 16+ messages in thread From: Pascal Bourguignon @ 2008-04-23 22:14 UTC (permalink / raw) To: help-gnu-emacs srinik001@hotmail.com writes: > Thanks for the tip. Now, it does not throw an error. But I still don't > get what I want. Here is what I did: > > (setq grammar '((sentence ::= subject predicate) > (subject ::= article noun) > (predicate ::= verb))) > --> This of course worked. I could see the individual elements, their > car's and cdr's etc. Also, you shouldn't think it terms of car and cdr here. Don't define your grammar as plain lists like this. Define it as a grammar! (define-grammar simple-english :start-symbol sentence :productions ((sentence ::= subject predicate) (subject ::= article noun) (predicate ::= verb))) (Of course, you could represent such grammar exactly as you did, with a simple list of lists, but it would be better to define grammars as CLOS objects (or rather, CLOS-like objects, using eieio) or just plain structures). (require 'cl) (defstruct grammar start-symbol non-terminals terminals productions (generators (make-hash-table))) (defstruct production lhs rhs generator) (defmacro* define-grammar (name &key (start-symbol nil start-symbol-p) productions) `(progn (defvar ,name) (setf ,name (make-grammar :start-symbol ',(if start-symbol-p start-symbol (first (first productions))) :productions (list ,@(mapcar (lambda (prod-sexp) (destructuring-bind (lhs sep &rest rhs) prod-sexp `(make-production :lhs ',lhs :rhs ',rhs :generator (lambda () (error "not generated yet"))))) productions)))) (compute-terminals-and-non-terminals ,name) ',name)) (defun compute-terminals-and-non-terminals (grammar) (let ((non-terminals (mapcar (function production-lhs) (grammar-productions grammar))) (symbols (mapcan (lambda (prod) (copy-list (production-rhs prod))) (grammar-productions grammar)))) (setf (grammar-non-terminals grammar) non-terminals (grammar-terminals grammar) (remove-duplicates (set-difference symbols non-terminals))) grammar)) (defun grammar-symbol-generator (grammar symbol) (gethash symbol (grammar-generators grammar))) (defun set-grammar-symbol-generator (grammar symbol new-generator) (setf (gethash symbol (grammar-generators grammar)) new-generator)) (defsetf grammar-symbol-generator set-grammar-symbol-generator) (pprint (macroexpand '(define-grammar simple-english :start-symbol sentence :productions ((sentence ::= subject predicate) (subject ::= article noun) (predicate ::= verb))))) --> (progn (defvar simple-english) (setf simple-english (make-grammar :start-symbol 'sentence :productions (list (make-production :lhs 'sentence :rhs '(subject predicate) :generator #1= (lambda () (error "not generated yet"))) (make-production :lhs 'subject :rhs '(article noun) :generator #1#) (make-production :lhs 'predicate :rhs '(verb) :generator #1#)))) (compute-terminals-and-non-terminals simple-english) 'simple-english) (define-grammar simple-english :start-symbol sentence :productions ((sentence ::= subject predicate) (subject ::= article noun) (predicate ::= verb))) --> simple-english (grammar-terminals simple-english) --> (verb noun article) (grammar-non-terminals simple-english) --> (sentence subject predicate) (production-rhs (first (grammar-productions simple-english))) --> (subject predicate) > Then I defined the "leaf" level things: > > (defun article() > (insert "article")) > > (defun noun() > (insert "noun")) > > (defun verb() > (insert "verb")) > > Then I tried this: > > (dolist (x grammar) > (set (car x) (dolist (y (cdr (cdr x))) (funcall y))) > > It threw an error saying that it did not know what subject was. Well perhaps. Whatever. Perhaps you mean something like: (let ((grammar simple-english)) (dolist (terminal (grammar-terminals grammar)) (setf (grammar-symbol-generator grammar terminal) (make-terminal-generator grammar terminal))) (dolist (prod (grammar-productions grammar)) (setf (grammar-symbol-generator grammar (production-lhs prod)) (make-non-terminal-generator grammar (production-rhs prod))))) with: (defun make-terminal-generator (grammar terminal) (byte-compile `(lambda () (insert ,(symbol-name terminal)) (insert " ")))) (defun make-non-terminal-generator (grammar rhs) (byte-compile `(lambda () ,@(mapcar (lambda (item) `(funcall (or (grammar-symbol-generator ',grammar ',item) (error "No generator for %S" ',item)))) rhs)))) If you insist, you can always implement all these abstraction using cons car and cdr (but it might be more efficient, and simplier to use defstruct or eieio defclass). (funcall (grammar-symbol-generator simple-english 'sentence)) inserts: article noun verb > Of > course, the way the grammar was described in the list, it did not know > that. So I tried reversing the grammar, thinking that if it went the > other way, it would understand subject before it came to sentence. So, > I tried this. > > (dolist (x (reverse grammar)) > (set (car x) (dolist (y (cdr (cdr x))) (funcall y)))) > > It still gave the same error! It seems that when it does a set > operation, it forgets it in the next iteration of the loop. Lisp-1 vs. Lisp-2. See my first answer. > I apologize if these are trivial questions, but while being *very* > addictive, Lisp seems unlike anything else that I have done before; > perhaps I need to study Lisp a lot more before giving myself exercises > like these, by studying Pascal's reply more carefully - I need to look > up many of the functions/terms he uses. For example, I don't really > get the difference between the quoted and the unquoted - I know they > are different but can't seem to be able to put my finger on the exact > difference. It's the same difference as in English. Pascal's name is written "Pascal". (I'm writting about M. Blaise Pascal of course). Anyways, the first "Pascal" in the above sentence, you interpret it, by fetching from your memory your representation of M. Blaise Pascal: you evaluate it to the value of Pascal (in that context). The second "Pascal", you don't evaluate it. You take it letter for letter, because I quoted it. It represents itself, the word "Pascal". What would be the translation in lisp of that sentence about Pascal? It's the same in lisp: (let ((var 'var)) (format "The value of the variable %S is %S" 'var var)) --> "The value of the variable var is var" Oops, this example is too much. ;-) Let's try again: (let ((var '42)) (format "The value of the variable %S is %S" 'var var)) --> "The value of the variable var is 42" In the call to format, the argument 'var is evaluated. The special operator quote returns its argument unevaluated. Therefore var is not evaluated and returned as is, var itself. The last argument var is evaluated too. It's a symbol, so lisp tries to find its value. There's a binding of the variable var to the value 42, so the result is 42. format is then called with as argument the string, the symbol var and the fixnum 42. Here how you could translate the sentence about Pascal: (defstruct person name) (defvar pascal (make-person :name 'pascal)) (eql (person-name pascal) 'pascal) --> t The variable pascal is bound to a person whose name is the symbol pascal itself. You should read this tutorial specific to emacs lisp: http://www.gnu.org/software/emacs/emacs-lisp-intro/ and of course, browse alot the online documentation and the sources of emacs lisp function. But what you want to do involves plain lisp programming, so you could also learn more, by studying Common Lisp (or at least parts of Common Lisp that have equivalents or that are similar to emacs lisp). For general programming there is much more material to study Common Lisp than emacs lisp. There are some significant differences between the two lisps, but if you know how to program in Common Lisp, you should be able to program in emacs lisp easily (Common Lisp being a richer programming language, you will learn all the notions you have in emacs lisp). Practical Common Lisp http://www.gigamonkeys.com/book/ Common Lisp: A Gentle Introduction to Symbolic Computation http://www-cgi.cs.cmu.edu/afs/cs.cmu.edu/user/dst/www/LispBook/index.html http://www.cs.cmu.edu/~dst/LispBook/ See also: http://www.cliki.net/Education http://www.cliki.net/Online+Tutorials http://www.cliki.net/Lisp%20books -- __Pascal Bourguignon__ http://www.informatimago.com/ PUBLIC NOTICE AS REQUIRED BY LAW: Any use of this product, in any manner whatsoever, will increase the amount of disorder in the universe. Although no liability is implied herein, the consumer is warned that this process will ultimately lead to the heat death of the universe. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it 2008-04-23 4:40 ` srinik001 2008-04-23 22:14 ` Pascal Bourguignon @ 2008-04-24 2:50 ` Barry Margolin 2008-04-28 1:03 ` srinik001 1 sibling, 1 reply; 16+ messages in thread From: Barry Margolin @ 2008-04-24 2:50 UTC (permalink / raw) To: help-gnu-emacs In article <530940ca-d019-42d4-ba15-c8674a8eb858@59g2000hsb.googlegroups.com>, srinik001@hotmail.com wrote: > On Apr 22, 5:54 am, Barry Margolin <bar...@alum.mit.edu> wrote: > > In article > > <a4bb6deb-6337-43bd-95e4-64a29770c...@y18g2000pre.googlegroups.com>, > > > > srinik...@hotmail.com wrote: > > > Oops... I got the subject wrong. Instead of > > > > > " Using setq to obtain a symbol from a list, so that I can assign a > > > function to it", it should read, "Using setq to assign value to the > > > result of a function". Sorry about that. > > > > Use set instead of setq. > > > > -- > > Barry Margolin, bar...@alum.mit.edu > > Arlington, MA > > *** PLEASE post questions in newsgroups, not directly to me *** > > *** PLEASE don't copy me on replies, I'll read them in the group *** > > Thanks for the tip. Now, it does not throw an error. But I still don't > get what I want. Here is what I did: > > (setq grammar '((sentence ::= subject predicate) > (subject ::= article noun) > (predicate ::= verb))) > --> This of course worked. I could see the individual elements, their > car's and cdr's etc. > > Then I defined the "leaf" level things: > > (defun article() > (insert "article")) > > (defun noun() > (insert "noun")) > > (defun verb() > (insert "verb")) > > Then I tried this: > > (dolist (x grammar) > (set (car x) (dolist (y (cdr (cdr x))) (funcall y))) > > It threw an error saying that it did not know what subject was. Of > course, the way the grammar was described in the list, it did not know > that. So I tried reversing the grammar, thinking that if it went the > other way, it would understand subject before it came to sentence. So, > I tried this. > > (dolist (x (reverse grammar)) > (set (car x) (dolist (y (cdr (cdr x))) (funcall y)))) > > It still gave the same error! It seems that when it does a set > operation, it forgets it in the next iteration of the loop. There are several things wrong here. First, you're effectively doing: (setq subject ...) and then (funcall 'subject) But funcall expects subject to be a function name, not a variable name. What you probably want to do is: (setf (symbol-function (car x)) ...) The other problem is that you're not even assigning a function. You're setting subject to the return value of dolist, which is just nil. I'm not really sure how to recode what you're doing to get this right. You're obviously trying to write a parser-generator in Lisp. This has been done many times, I suggest you check Lisp code repositories, and see how they've done it. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group *** ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it 2008-04-24 2:50 ` Barry Margolin @ 2008-04-28 1:03 ` srinik001 0 siblings, 0 replies; 16+ messages in thread From: srinik001 @ 2008-04-28 1:03 UTC (permalink / raw) To: help-gnu-emacs > > The other problem is that you're not even assigning a function. You're > setting subject to the return value of dolist, which is just nil. I'm > not really sure how to recode what you're doing to get this right. > > You're obviously trying to write a parser-generator in Lisp. This has > been done many times, I suggest you check Lisp code repositories, and > see how they've done it. > > -- > Barry Margolin, bar...@alum.mit.edu Thanks, Barry and Pascal. Actually, I had something in mind far less ambitious than writing a parser-generator. I was trying to get it to do prompting, not parsing. That is, if I gave it a grammar like the one I posted, having coded the leaf-level functions by hand, I wanted to be able to enter the command "sentence" and have Emacs prompt me for subject, article etc., that is, lead me through the creation of an XML file without errors, without my having to remember what attributes made up a tag, what tag was contained within what tag etc. I certainly don't want to be writing a parser until I have a very good grasp of Lisp, which I don't at this point. Regards, SK ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it 2008-04-22 5:19 ` srinik001 2008-04-22 12:54 ` Barry Margolin @ 2008-04-23 5:10 ` Kevin Rodgers [not found] ` <mailman.10729.1208927476.18990.help-gnu-emacs@gnu.org> 2 siblings, 0 replies; 16+ messages in thread From: Kevin Rodgers @ 2008-04-23 5:10 UTC (permalink / raw) To: help-gnu-emacs srinik001@hotmail.com wrote: > Oops... I got the subject wrong. Instead of > > " Using setq to obtain a symbol from a list, so that I can assign a > function to it", it should read, "Using setq to assign value to the > result of a function". Sorry about that. Use set instead of setq: ,----[ C-h f setq RET ] | setq is a special form in `C source code'. | (setq [sym val]...) | | Set each sym to the value of its val. | The symbols sym are variables; they are literal (not evaluated). | The values val are expressions; they are evaluated. | Thus, (setq x (1+ y)) sets `x' to the value of `(1+ y)'. | The second val is not computed until after the first sym is set, and so on; | each val can use the new value of variables set earlier in the `setq'. | The return value of the `setq' form is the value of the last val. | | [back] `---- ,----[ C-h f set RET ] | set is a built-in function in `C source code'. | (set symbol newval) | | Set symbol's value to newval, and return newval. | | [back] `---- -- Kevin Rodgers Denver, Colorado, USA ^ permalink raw reply [flat|nested] 16+ messages in thread
[parent not found: <mailman.10729.1208927476.18990.help-gnu-emacs@gnu.org>]
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it [not found] ` <mailman.10729.1208927476.18990.help-gnu-emacs@gnu.org> @ 2008-05-17 22:14 ` David Combs 2008-05-20 2:42 ` Kevin Rodgers 0 siblings, 1 reply; 16+ messages in thread From: David Combs @ 2008-05-17 22:14 UTC (permalink / raw) To: help-gnu-emacs In article <mailman.10729.1208927476.18990.help-gnu-emacs@gnu.org>, Kevin Rodgers <kevin.d.rodgers@gmail.com> wrote: >srinik001@hotmail.com wrote: >> Oops... I got the subject wrong. Instead of >> >> " Using setq to obtain a symbol from a list, so that I can assign a >> function to it", it should read, "Using setq to assign value to the >> result of a function". Sorry about that. > >Use set instead of setq: > >,----[ C-h f setq RET ] >| setq is a special form in `C source code'. >| (setq [sym val]...) >| >| Set each sym to the value of its val. >| The symbols sym are variables; they are literal (not evaluated). >| The values val are expressions; they are evaluated. >| Thus, (setq x (1+ y)) sets `x' to the value of `(1+ y)'. >| The second val is not computed until after the first sym is set, and >so on; >| each val can use the new value of variables set earlier in the `setq'. >| The return value of the `setq' form is the value of the last val. >| >| [back] >`---- > >,----[ C-h f set RET ] >| set is a built-in function in `C source code'. >| (set symbol newval) >| >| Set symbol's value to newval, and return newval. >| >| [back] >`---- > >-- >Kevin Rodgers >Denver, Colorado, USA > > > Kevin, could you elaborate on that just a bit, on why setq is *not* the right thing to use. And, in general, when *do* you use plain set? THANKS! David ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it 2008-05-17 22:14 ` David Combs @ 2008-05-20 2:42 ` Kevin Rodgers 0 siblings, 0 replies; 16+ messages in thread From: Kevin Rodgers @ 2008-05-20 2:42 UTC (permalink / raw) To: help-gnu-emacs David Combs wrote: > In article <mailman.10729.1208927476.18990.help-gnu-emacs@gnu.org>, > Kevin Rodgers <kevin.d.rodgers@gmail.com> wrote: >> srinik001@hotmail.com wrote: >>> Oops... I got the subject wrong. Instead of >>> >>> " Using setq to obtain a symbol from a list, so that I can assign a >>> function to it", it should read, "Using setq to assign value to the >>> result of a function". Sorry about that. >> Use set instead of setq: >> >> ,----[ C-h f setq RET ] >> | setq is a special form in `C source code'. >> | (setq [sym val]...) >> | >> | Set each sym to the value of its val. >> | The symbols sym are variables; they are literal (not evaluated). >> | The values val are expressions; they are evaluated. >> | Thus, (setq x (1+ y)) sets `x' to the value of `(1+ y)'. >> | The second val is not computed until after the first sym is set, and >> so on; >> | each val can use the new value of variables set earlier in the `setq'. >> | The return value of the `setq' form is the value of the last val. >> | >> | [back] >> `---- >> >> ,----[ C-h f set RET ] >> | set is a built-in function in `C source code'. >> | (set symbol newval) >> | >> | Set symbol's value to newval, and return newval. >> | >> | [back] >> `---- > > Kevin, could you elaborate on that just a bit, on why > setq is *not* the right thing to use. > > And, in general, when *do* you use plain set? If I recall, the symbol whose value you want to set came from some data structure, the list mentioned in the subject. Since you don't know what that symbol is ahead of time, you can't use setq: setq is a special form that does not evaluate its SYMBOL argument, but sets that literal SYMBOL. On the other hand, set is a true function, meaning that all its arguments are evaluated before the function itself is called. So you can write any expression that evaluates to a symbol as its first argument. Hope that helps, -- Kevin Rodgers Denver, Colorado, USA ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it 2008-04-22 2:28 Using setq to obtain a symbol from a list, so that I can assign a function to it srinik001 2008-04-22 5:19 ` srinik001 @ 2008-04-22 15:22 ` Ted Zlatanov 2008-04-22 18:36 ` Pascal Bourguignon 2008-04-22 19:59 ` Pascal Bourguignon 2 siblings, 1 reply; 16+ messages in thread From: Ted Zlatanov @ 2008-04-22 15:22 UTC (permalink / raw) To: help-gnu-emacs On Mon, 21 Apr 2008 19:28:03 -0700 (PDT) srinik001@hotmail.com wrote: s> So, I am trying to write a tool that will enable me to write specific s> XML files by prompting me to enter values. Here is how I am trying to s> do it. You may want to look at the various templating packages available, in case one of them does what you want. Check out skeleton.el in particular (http://www.emacswiki.org/cgi-bin/wiki/SkeletonMode for some examples) since any element of the template can itself be a template. That will probably save you a lot of time. Anytime you find yourself auto-generating functions you should wonder if your data structure could be better (sometimes the answer is 'no' :) Ted ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it 2008-04-22 15:22 ` Ted Zlatanov @ 2008-04-22 18:36 ` Pascal Bourguignon 2008-05-17 22:20 ` David Combs 0 siblings, 1 reply; 16+ messages in thread From: Pascal Bourguignon @ 2008-04-22 18:36 UTC (permalink / raw) To: help-gnu-emacs Ted Zlatanov <tzz@lifelogs.com> writes: > On Mon, 21 Apr 2008 19:28:03 -0700 (PDT) srinik001@hotmail.com wrote: > > s> So, I am trying to write a tool that will enable me to write specific > s> XML files by prompting me to enter values. Here is how I am trying to > s> do it. > > You may want to look at the various templating packages available, in > case one of them does what you want. Check out skeleton.el in > particular (http://www.emacswiki.org/cgi-bin/wiki/SkeletonMode for some > examples) since any element of the template can itself be a template. > That will probably save you a lot of time. > > Anytime you find yourself auto-generating functions you should wonder if > your data structure could be better (sometimes the answer is 'no' :) Well, I wouldn't be so categoric. You could start by writting an "interpreter" of your data, but generating lisp is like implementing the "compiler", so I don't see much difference. It's so easy to do it in lisp, that you can go directly to the "compiler". -- __Pascal Bourguignon__ http://www.informatimago.com/ THIS IS A 100% MATTER PRODUCT: In the unlikely event that this merchandise should contact antimatter in any form, a catastrophic explosion will result. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it 2008-04-22 18:36 ` Pascal Bourguignon @ 2008-05-17 22:20 ` David Combs 0 siblings, 0 replies; 16+ messages in thread From: David Combs @ 2008-05-17 22:20 UTC (permalink / raw) To: help-gnu-emacs In article <874p9twxc3.fsf@hubble.informatimago.com>, Pascal Bourguignon <pjb@informatimago.com> wrote: >Ted Zlatanov <tzz@lifelogs.com> writes: > >> On Mon, 21 Apr 2008 19:28:03 -0700 (PDT) srinik001@hotmail.com wrote: >> >> s> So, I am trying to write a tool that will enable me to write specific >> s> XML files by prompting me to enter values. Here is how I am trying to >> s> do it. >> >> You may want to look at the various templating packages available, in >> case one of them does what you want. Check out skeleton.el in >> particular (http://www.emacswiki.org/cgi-bin/wiki/SkeletonMode for some >> examples) since any element of the template can itself be a template. >> That will probably save you a lot of time. >> >> Anytime you find yourself auto-generating functions you should wonder if >> your data structure could be better (sometimes the answer is 'no' :) > >Well, I wouldn't be so categoric. You could start by writting an >"interpreter" of your data, but generating lisp is like implementing >the "compiler", so I don't see much difference. It's so easy to do it >in lisp, that you can go directly to the "compiler". > >-- >__Pascal Bourguignon__ http://www.informatimago.com/ Pascal, If by chance you have (tutorial?) examples of this idea perhaps you could post them here, or point us to a site (one of yours?) that does have such tutorial examples. Of course various text-books contain an example or two, via hairy (*extremely* hairy) macros, but it'd be nice to see a whole bunch in one place, compared, and so on. As I understand it, lisp is *the* language for doing such things -- or has that changed over the years with the introduction (decades ago) of various functional languages? Thanks! David ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it 2008-04-22 2:28 Using setq to obtain a symbol from a list, so that I can assign a function to it srinik001 2008-04-22 5:19 ` srinik001 2008-04-22 15:22 ` Ted Zlatanov @ 2008-04-22 19:59 ` Pascal Bourguignon 2008-04-23 3:11 ` Timothy Hobbs [not found] ` <mailman.10727.1208920326.18990.help-gnu-emacs@gnu.org> 2 siblings, 2 replies; 16+ messages in thread From: Pascal Bourguignon @ 2008-04-22 19:59 UTC (permalink / raw) To: help-gnu-emacs srinik001@hotmail.com writes: > Hello, > > I would really appreciate some help on this. I am trying to do just > about everything with Emacs (and Emacs Lisp) these days. One of the > things I need to do in my job is to create XML files. I thought I > would use Emacs rather than some other editor/tool. > > So, I am trying to write a tool that will enable me to write specific > XML files by prompting me to enter values. Here is how I am trying to > do it. > > First, I set a variable that will provide a "grammar" for my file that > Emacs will help me write. An example is the following : of course, my > actual problem is not about generating English sentences; this is just > for illustration. > > (setq grammar '((sentence <- subject predicate) > (subject <- article noun) > (predicate <- verb))) > > I expect to generate functions that look like this: > > (defun sentence() > (........some stuff .........) > (subject) > (predicate) > (........some stuff again...)) > > What I want the system to do is to generate the function > automatically. So, I should have functions for sentence, subject and > predicate. I will of course hand-code the functions for article, noun > and verb. > > I don't want to write the above defun; I want to generate it by using > (setq sentence #'(lambda() ( (subject) (predicate)))). Of course, > instead of "sentence". I want to use (car x) or something like that by > reading the variable "grammar". > > Here is the problem: when I do this: > > (setq (car (expression that generates sentence) #'(lambda() (print > "hello"))) > > I get an error. > > But if I do a (setq x (car ... ) to get the sentence symbol and THEN > assign it, everything works. > > Is there something fundamental I am missing? You're near. First, remember that emacs lisp is a lisp-2. That means that a symbol can have both a function and a value. defun sets the function of the symbol. defvar (setf and setq) set the value of the symbol. (This is in opposition to scheme which is a lisp-1 and where you only need to assign a procedure value to a variable to define a function). So what do you want to generate? (defun sentence ...) or (setq sentence (lambda ....)) ? Also, something you might consider is that there is no package in emacs lisp, so whether you use the function slot or the value slot of these symbol, it is global. Imagine you want to edit an XML describing some graphic with lines and arrows at the beginning or the end of the lines. You could have have this kind of grammar: (define-grammar graphic-xml (graphic -> lines) (lines -> ) (lines -> line lines) (line -> beginning-of-line line-attributes end-of-lines) (beginning-of-line -> x y decoration) (end-of-line -> x y decoration)) Oops! You just redefined the emacs lisp functions beginning-of-line and end-of-line, and about 30% of the keypresses will now break... One solution would be to build composed symbol names. For example, the global functions and variables defined by ERC, the Emacs iRc Client all start with erc-. Another solution is to keep your generated functions in a hash-table indexed by the symbols. In this case, the hash-table defines in a way another namespace. Ok, so now let's address your main question. What you have is a list containing a grammar production like: ( <name> -> <item1> ... <itemN> ) and you want to get a _list_ like: (defun <name> () (<item1>) ... (<itemN>)) Well, there's really no difficulty. I'm sure you could easily do it. if defun gives you difficulties, try to generate this list instead: (donald <name> mickey (<item1>) ... (<itemN>)) Here it is: (defun generate-production (prod) (destructuring-bind (name separator &rest items) prod (list* 'defun name '() (mapcar (lambda (item) (list item)) items)))) (generate-production '(sentence <- subject predicate)) --> (defun sentence nil (subject) (predicate)) On the other hand, if you want to put these function into a hash-table, you could write: (defun generate-rhs (items) (list* 'lambda '() (mapcar (lambda (item) (list item)) items))) (defun store-production (grammar production) (destructuring-bind (name separator &rest items) production (setf (gethash name grammar) (byte-compile (generate-rhs items))))) (setq grammar (make-hash-table)) (store-production grammar '(sentence <- subject predicate)) We can call the function associated with sentence with: (funcall (gethash 'sentence grammar)) Note that we don't generate a setf, we just generate the (lambda ...) compile it, and put the resulting compiled function into the hash-table. As for: > (setq (car (expression that generates sentence) #'(lambda() (print > "hello"))) yes, you can use set in this situation: (destructuring-bind (name separator &rest items) production (set name (byte-compile `(lambda () ,@(mapcar 'list items))))) or, equivalently setf symbol-value: (destructuring-bind (name separator &rest items) production (setf (symbol-value name) (byte-compile `(lambda () ,@(mapcar 'list items))))) but it's probably better to but these function in a hash-table than in the value slots of the symbols. Instead of writting deep expressions such as: (list 'lambda '() (append '(save-excursion) (list (list 'insert '"<" (string name) '">")) forms (list (list 'insert '"</" (string name) '">")))) you can use backquote and comma to write it more easily: `(lambda () (save-excursion (insert "<" ,(string name) ">") ,@forms (insert "</" ,(string name) ">"))) so for example, you could write: (defun make-name (name) (intern (format "xml-insert/%s" name))) (defun generate-production (prod) (destructuring-bind (name separator &rest items) prod `(defun ,(make-name name) () (insert ,(format "<%s>" name)) ,@(mapcar (lambda (item) `(,(make-name item))) items) (insert ,(format "</%s>" name))))) (generate-production '(sentence <- subject predicate)) --> (defun xml-insert/sentence nil (insert "<sentence>") (xml-insert/subject) (xml-insert/predicate) (insert "</sentence>")) Finally, emacs is not modal. It would not be very emacs-like to do M-x xml-insert/document RET and to be prompted for half a hour to insert a whole document. Instead, you could do something like customize-variable. Try for example M-x customize-variable RET lisp-source-modes RET Most of the buffer is read-only, and there are left some area you can edit. There are some buttons, to insert or remove repeatitive areas. You could have a look at the sources of customize-variable to see how it's done and implement your structural editor like this. -- __Pascal Bourguignon__ http://www.informatimago.com/ THIS IS A 100% MATTER PRODUCT: In the unlikely event that this merchandise should contact antimatter in any form, a catastrophic explosion will result. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it 2008-04-22 19:59 ` Pascal Bourguignon @ 2008-04-23 3:11 ` Timothy Hobbs [not found] ` <mailman.10727.1208920326.18990.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 16+ messages in thread From: Timothy Hobbs @ 2008-04-23 3:11 UTC (permalink / raw) To: EMACS list Pascal Bourguignon <pjb@informatimago.com> writes: > but it's probably better to but these function in a hash-table than in > the value slots of the symbols. I am curious, why would this be better? I find that when an elisp program defines functions outside of the standard lisp symbols reading and modifying them becomes difficult or impossible. In the simplest scenario, simply finding out how functionality is implemented, I cannot use C-h f to jump to the doc string and ultimately, through that handy little hyperlink, source code. In a more involved case, I cannot advise, or redefine the function. > Finally, emacs is not modal. It would not be very emacs-like to do > M-x xml-insert/document RET and to be prompted for half a hour to > insert a whole document. Instead, you could do something like > customize-variable. Try for example M-x customize-variable RET > lisp-source-modes RET Most of the buffer is read-only, and there are > left some area you can edit. There are some buttons, to insert or > remove repeatitive areas. You could have a look at the sources of > customize-variable to see how it's done and implement your structural > editor like this. I just thought I would endose msf-abbrev-mode here. Thank you Timothy Hobbs ^ permalink raw reply [flat|nested] 16+ messages in thread
[parent not found: <mailman.10727.1208920326.18990.help-gnu-emacs@gnu.org>]
* Re: Using setq to obtain a symbol from a list, so that I can assign a function to it [not found] ` <mailman.10727.1208920326.18990.help-gnu-emacs@gnu.org> @ 2008-04-23 4:06 ` Barry Margolin 0 siblings, 0 replies; 16+ messages in thread From: Barry Margolin @ 2008-04-23 4:06 UTC (permalink / raw) To: help-gnu-emacs In article <mailman.10727.1208920326.18990.help-gnu-emacs@gnu.org>, Timothy Hobbs <tim.thelion@gmail.com> wrote: > Pascal Bourguignon <pjb@informatimago.com> writes: > > but it's probably better to but these function in a hash-table than in > > the value slots of the symbols. > I am curious, why would this be better? I find that when an elisp program > defines functions outside of the standard lisp symbols reading and modifying > them becomes difficult or impossible. In the simplest scenario, simply > finding out how functionality is implemented, I cannot use C-h f to jump to > the doc string and ultimately, through that handy little hyperlink, source > code. In a more involved case, I cannot advise, or redefine the function. Most of these things are unlikely to be done for dynamically-generated functions that are internal to an application like this. There's no source code for that "handy little hyperlink" to point to, because the function was created on the fly. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group *** ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2008-05-20 2:42 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-04-22 2:28 Using setq to obtain a symbol from a list, so that I can assign a function to it srinik001 2008-04-22 5:19 ` srinik001 2008-04-22 12:54 ` Barry Margolin 2008-04-23 4:40 ` srinik001 2008-04-23 22:14 ` Pascal Bourguignon 2008-04-24 2:50 ` Barry Margolin 2008-04-28 1:03 ` srinik001 2008-04-23 5:10 ` Kevin Rodgers [not found] ` <mailman.10729.1208927476.18990.help-gnu-emacs@gnu.org> 2008-05-17 22:14 ` David Combs 2008-05-20 2:42 ` Kevin Rodgers 2008-04-22 15:22 ` Ted Zlatanov 2008-04-22 18:36 ` Pascal Bourguignon 2008-05-17 22:20 ` David Combs 2008-04-22 19:59 ` Pascal Bourguignon 2008-04-23 3:11 ` Timothy Hobbs [not found] ` <mailman.10727.1208920326.18990.help-gnu-emacs@gnu.org> 2008-04-23 4:06 ` Barry Margolin
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).