1

I want to be able to write a cons with some of the cells being placeholders for later evaluation. I know I can use backquote constructs, but it tries to evaluate the cons immediately.

To clarify, provided I have a variable my-value, I could do: (setq my-cons `(my-key ,my-value))

But this won't satisfy my needs, as it's evaluated immediately. I can't use my-cons, without knowing about its structure, to create another cons like '(my-key "another-value"). I need to be able to provide the structure as a variable, and fill it with real data later.

Think about format function: We define a string, with some placeholders, and then use format to inject our data into the string. What I need, is analogous to a format string, but for cons.

Detailed use-case: I want to convert a org-mode todo entry to a Jira ticket. org-jira and ejira, both have a shortcoming: they only read some basic data (project, ticket type summary). Since Jira is customizable, each project could have its different set of required fields. A useful org-todo-to-jira would allow you to define a mapping between org properties, and Jira fields. I want my org DEADLINE to be interpreted as

{
  duedate: "deadline-value-here"
}

and my :estimation: to be interpreted as

{
  estimation: {
    originalEstimation: "estimation-value-here"
  }
}

But a user might want another mapping. The cleanest thing that I thought of, was an alist defined by defcustom: the car of each cell being a property, and the cdr being another cons, defining the structure for that field: telling us how that field should be converted to a json. The car lets me know where to find that property in org todo entry, and the cdr lets me know where should I put that value in my json.

Kamyab
  • 41
  • 5
  • 5
    I don't understand the question. What do you mean by "reusable"? When do you "need it to" be evaluated? Most importantly, what's an example of something you want to do but can't? (Could you show some pseudo-code which indicates how you wish things worked?) – phils Aug 28 '21 at 10:57
  • Sorry for the ambiguity, I've updated the quetsion. – Kamyab Aug 28 '21 at 11:57
  • 4
    I still don't understand. My best guess is that you should define a function which generates and returns a cons? – phils Aug 28 '21 at 13:06
  • Oh :D A function won't do the job, cause I still need to know how should I interpret the value. Some values should be interpreted like '(my-key my-value), some values should be interpreted like '(my-key '(id my-value)) and so forth. I need to get a structure, and put the value in that structure. – Kamyab Aug 28 '21 at 13:25
  • I need to know how should I define a cons with some placeholders, that will be eventually replaced with actual data. My first thought was putting something like :placeholder: in cons, and then recursively search for :placeholder: and replace it with a value. But I think there should be a better, more efficient way. – Kamyab Aug 28 '21 at 13:37
  • https://emacs.stackexchange.com/tags/elisp/info – Drew Aug 28 '21 at 16:57
  • The question is unclear (to me). So far, it seems like just using the backquote form that you show is the answer. Where, how, and when variable my-value is bound or set is something else - do that any way and any place you like. – Drew Aug 28 '21 at 17:00
  • Your question is really too vague to have a proper answer, but you will probably end up using either a function or a macro. I would start by writing out the data structure explicitly each time it is needed. Later you may find a nicer way to construct it, but when you are first writing a program it is not a good idea to get hung up on such details. Note that if you are querying a database, the database library may provide some tools you can use. – db48x Aug 28 '21 at 17:05
  • @Drew I think the elisp tag was relevant. My question was not about customizing emacs, nor it was specifically about the application I'm writing. It was a question about doing something purely elisp-related. Anyway, I found a way of doing it, I hope it clears up what I was trying to do. I've also updated the question and clarified it as best as I could. I agree it was too cryptic (hopefully, now it's less cryptic). Thank you for your answers. – Kamyab Aug 28 '21 at 18:27
  • (1) Please read the tag description again. The tag is not for "doing something" with Elisp. (2) And no, for me anyway, your answer doesn't clear up what you're trying to do. – Drew Aug 28 '21 at 20:06

1 Answers1

-1

I ended up doing this:

If I set a my-cons variable like this:

(setq my-cons '`(my-key ,placeholder))

Whenever I want to replace placeholder with something else, I could do(eval my-cons))

(let ((placeholder "my-value"))
  (print (eval my-cons)))

;; prints (my-key "my-value")

Kamyab
  • 41
  • 5
  • 2
    Why on earth would you write this rather than (defun my-cons (argument) (cons 'my-key argument)), or if you really want to hard-code the name placeholder, (defun my-cons () (cons 'my-key placeholder))? Neither your question nor the comments under it make it clear what you want, but I can't imagine a question where this would be a reasonable answer. – Gilles 'SO- stop being evil' Aug 28 '21 at 20:27
  • Because I can't make any assumption about the cons structure. What I was trying to do, was getting some data from org-mode properties, and adding them to nested json. Why would I write a function for every possible configuration? In this way, I only make a mapping between org-mode property names and how their value is to be structured. – Kamyab Aug 29 '21 at 04:24
  • I did ask for an example of what you were trying to do, and "getting some data from org-mode properties, and adding them to nested json" is the closest you've come to providing that example. If you had said that and then provided the pseudo-code showing how you wished it worked, and why your existing code was not satisfactory, people could have provided answers. As it was, your edits were all very abstract and unclear, and I still don't know where you've having a problem, so perhaps you could go ahead write up that example in detail. – phils Aug 29 '21 at 13:26
  • 1
    @phils I want to convert a org-mode todo entry to a Jira ticket. org-jira and ejira, both have a shortcoming: they only read some basic data (project, ticket type summary). Since Jira is customizable, each project could have its different set of required fields. A useful org-todo-to-jira would allow you to define a mapping between org properties, and Jira fields. I want my org DEADLINE to be interpreted like {duedate: "deadline-value-here"}, and my :estimation: to be interpreted like {estimation: {originalEstimation: "estimation-value-here"}}. But a user might want another- – Kamyab Aug 29 '21 at 17:50
  • 1
    -mapping. The cleanest thing that I thought of, was a alist defined by defcustom: the car of each cell being a property, and the cdr being another cons, defining the structure for that field: telling us how that field should be converted to a json. The car lets me know where to find that property in org todo entry, and the cdr lets me know where should I put that value in my json. – Kamyab Aug 29 '21 at 17:56
  • Please add that description to the question: that's where it belongs, not in a comment. The more information you can provide in the original question, and the more concrete that information is, the better your chances of getting a good answer. You might also want to read this page: https://emacs.stackexchange.com/help/how-to-ask – NickD Aug 29 '21 at 20:04
  • @NickD I've edited my question, and clarified it as best as I could. If it's still vague, then sorry, I've already found my answer, and don't want to waste anybody's time. Thank you all. – Kamyab Aug 29 '21 at 21:27
  • 1
    Well I still think you want a function. Keep your alist for mapping things to other things, but write a function (one function, which you can call for each of the properties in turn), which takes the input, processes it with the alist, and returns the output. – phils Aug 29 '21 at 22:52
  • I agree with @phils's last comment: this sounds like a simple template engine. Does it have to be done in emacs? If not, you might want to investigate something like Jinja2 – NickD Aug 29 '21 at 23:41
  • I'd already developed most parts of that function, but this was the missing piece. And yes, it has to be in emacs, as the whole point is improving the integration of org-mode with Jira. – Kamyab Aug 29 '21 at 23:59