unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* "Backquote constructs" to "splice" values without "eval".
@ 2013-01-07 12:50 Oleksandr Gavenko
  0 siblings, 0 replies; 8+ messages in thread
From: Oleksandr Gavenko @ 2013-01-07 12:50 UTC (permalink / raw)
  To: help-gnu-emacs

I construct TLV (table-len-val) structs in string.

Is it possible to omit "eval" from second line by using some sugar code:

  (setq binstr-len 4)
  (setq binstr (eval `(unibyte-string ?s binstr-len ,@(make-list binstr-len ?x))))
  (assert (eq (+ 2 binstr-len) (length binstr)))

Another solution:

  (setq binstr (concat (unibyte-string ?s binstr-len) (make-list binstr-len ?x)))

Or "apply" stands for this purpose(??):

  (setq binstr (apply 'unibyte-string ?s binstr-len (make-list binstr-len ?x)))

Seems that "`" use current variable values when sexp *parsed*, while with
"apply" it use variable values on *evaluation*. Is I am right?

-- 
Best regards!




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: "Backquote constructs" to "splice" values without "eval".
       [not found] <mailman.16855.1357563071.855.help-gnu-emacs@gnu.org>
@ 2013-01-07 15:02 ` Barry Margolin
  2013-01-07 20:36   ` Oleksandr Gavenko
       [not found]   ` <mailman.16874.1357591009.855.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 8+ messages in thread
From: Barry Margolin @ 2013-01-07 15:02 UTC (permalink / raw)
  To: help-gnu-emacs

In article <mailman.16855.1357563071.855.help-gnu-emacs@gnu.org>,
 Oleksandr Gavenko <gavenkoa@gmail.com> wrote:

> I construct TLV (table-len-val) structs in string.
> 
> Is it possible to omit "eval" from second line by using some sugar code:
> 
>   (setq binstr-len 4)
>   (setq binstr (eval `(unibyte-string ?s binstr-len ,@(make-list binstr-len 
>   ?x))))
>   (assert (eq (+ 2 binstr-len) (length binstr)))
> 
> Another solution:
> 
>   (setq binstr (concat (unibyte-string ?s binstr-len) (make-list binstr-len 
>   ?x)))
> 
> Or "apply" stands for this purpose(??):
> 
>   (setq binstr (apply 'unibyte-string ?s binstr-len (make-list binstr-len 
>   ?x)))

The "apply" solution is usually the correct way to do it.

> 
> Seems that "`" use current variable values when sexp *parsed*, while with
> "apply" it use variable values on *evaluation*. Is I am right?

If you do:

(setq sexp `(unibyte-string ?s binstr-len ,@(make-list binstr-len ?x))
(setq binstr-len 6)
(eval sexp)

The first BINSTR-LEN in SEXP will be 6 because it's evaluated by the 
call to EVAL, the second one will be 4 because it's evaluated during the 
SETQ.  In neither case is it evaluated at read time; remember, backquote 
is just a shorthand for code that constructs the list at the time the 
expression is evaluated, so the first line is equivalent to:

(setq sexp (list* 'unibyte-string '?s 'binstr-len (make-list binstr-len 
?x)))

As you can see, the first UNIBYTE-STRING is quoted, the second one is 
not (because of the comma in the backquote expression), so the latter 
gets evaluated at the time of the SETQ.

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: "Backquote constructs" to "splice" values without "eval".
  2013-01-07 15:02 ` "Backquote constructs" to "splice" values without "eval" Barry Margolin
@ 2013-01-07 20:36   ` Oleksandr Gavenko
  2013-01-07 21:10     ` Jambunathan K
       [not found]   ` <mailman.16874.1357591009.855.help-gnu-emacs@gnu.org>
  1 sibling, 1 reply; 8+ messages in thread
From: Oleksandr Gavenko @ 2013-01-07 20:36 UTC (permalink / raw)
  To: help-gnu-emacs

On 2013-01-07, Barry Margolin wrote:

>> I construct TLV (table-len-val) structs in string.
>>
>> Is it possible to omit "eval" from second line by using some sugar code:
>>
>>   (setq binstr-len 4)
>>   (setq binstr (eval `(unibyte-string ?s binstr-len ,@(make-list binstr-len
>>   ?x))))
>>   (assert (eq (+ 2 binstr-len) (length binstr)))
>>
>> Another solution:
>>
>>   (setq binstr (concat (unibyte-string ?s binstr-len) (make-list binstr-len
>>   ?x)))
>>
>> Or "apply" stands for this purpose(??):
>>
>>   (setq binstr (apply 'unibyte-string ?s binstr-len (make-list binstr-len
>>   ?x)))
>
> The "apply" solution is usually the correct way to do it.

I also start thinking about "apply" with several list inside it:

  (apply '+ 1 '(2) '(3 4))

But above expression fail (only last arg expanded as list of args). To resolve
this issue I use expression:

  (apply '+ 1 (append '(2) '(3 4)))

But how about expression with atoms between (??):

  '(1) 2 '(3 4)

I write non-linear code:

  (apply '+ (append '(1) (cons 2 '(3 4))))

How to avoid call to "cons"?

-- 
Best regards!




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: "Backquote constructs" to "splice" values without "eval".
       [not found]   ` <mailman.16874.1357591009.855.help-gnu-emacs@gnu.org>
@ 2013-01-07 20:51     ` Barry Margolin
  0 siblings, 0 replies; 8+ messages in thread
From: Barry Margolin @ 2013-01-07 20:51 UTC (permalink / raw)
  To: help-gnu-emacs

In article <mailman.16874.1357591009.855.help-gnu-emacs@gnu.org>,
 Oleksandr Gavenko <gavenkoa@gmail.com> wrote:

> On 2013-01-07, Barry Margolin wrote:
> 
> >> I construct TLV (table-len-val) structs in string.
> >>
> >> Is it possible to omit "eval" from second line by using some sugar code:
> >>
> >>   (setq binstr-len 4)
> >>   (setq binstr (eval `(unibyte-string ?s binstr-len ,@(make-list binstr-len
> >>   ?x))))
> >>   (assert (eq (+ 2 binstr-len) (length binstr)))
> >>
> >> Another solution:
> >>
> >>   (setq binstr (concat (unibyte-string ?s binstr-len) (make-list binstr-len
> >>   ?x)))
> >>
> >> Or "apply" stands for this purpose(??):
> >>
> >>   (setq binstr (apply 'unibyte-string ?s binstr-len (make-list binstr-len
> >>   ?x)))
> >
> > The "apply" solution is usually the correct way to do it.
> 
> I also start thinking about "apply" with several list inside it:
> 
>   (apply '+ 1 '(2) '(3 4))
> 
> But above expression fail (only last arg expanded as list of args). To resolve
> this issue I use expression:
> 
>   (apply '+ 1 (append '(2) '(3 4)))
> 
> But how about expression with atoms between (??):
> 
>   '(1) 2 '(3 4)
> 
> I write non-linear code:
> 
>   (apply '+ (append '(1) (cons 2 '(3 4))))
> 
> How to avoid call to "cons"?

Now you can go back to using backquote to construct the list:

(apply #'+ `(,@'(1) 2 ,@'(3 4)))

But you still don't need to use eval.

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: "Backquote constructs" to "splice" values without "eval".
  2013-01-07 20:36   ` Oleksandr Gavenko
@ 2013-01-07 21:10     ` Jambunathan K
  2013-01-07 21:47       ` Oleksandr Gavenko
  0 siblings, 1 reply; 8+ messages in thread
From: Jambunathan K @ 2013-01-07 21:10 UTC (permalink / raw)
  To: Oleksandr Gavenko; +Cc: help-gnu-emacs

Oleksandr Gavenko <gavenkoa@gmail.com> writes:

> On 2013-01-07, Barry Margolin wrote:
>
>>> I construct TLV (table-len-val) structs in string.
>>>
>>> Is it possible to omit "eval" from second line by using some sugar code:
>>>
>>>   (setq binstr-len 4)
>>>   (setq binstr (eval `(unibyte-string ?s binstr-len ,@(make-list binstr-len
>>>   ?x))))
>>>   (assert (eq (+ 2 binstr-len) (length binstr)))
>>>
>>> Another solution:
>>>
>>>   (setq binstr (concat (unibyte-string ?s binstr-len) (make-list binstr-len
>>>   ?x)))
>>>
>>> Or "apply" stands for this purpose(??):
>>>
>>>   (setq binstr (apply 'unibyte-string ?s binstr-len (make-list binstr-len
>>>   ?x)))
>>
>> The "apply" solution is usually the correct way to do it.
>
> I also start thinking about "apply" with several list inside it:
>
>   (apply '+ 1 '(2) '(3 4))
>
> But above expression fail (only last arg expanded as list of args). To resolve
> this issue I use expression:
>
>   (apply '+ 1 (append '(2) '(3 4)))
>
> But how about expression with atoms between (??):
>
>   '(1) 2 '(3 4)
>
> I write non-linear code:
>
>   (apply '+ (append '(1) (cons 2 '(3 4))))
>
> How to avoid call to "cons"?

(apply '+ (loop for x in '(1 (2) (3 4))
		collect (if (numberp x) x (apply '+ x))))

There are also other predicates that you can use.  For eg., atom, consp,
listp.
-- 



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: "Backquote constructs" to "splice" values without "eval".
  2013-01-07 21:10     ` Jambunathan K
@ 2013-01-07 21:47       ` Oleksandr Gavenko
  2013-01-08  5:48         ` Jambunathan K
  0 siblings, 1 reply; 8+ messages in thread
From: Oleksandr Gavenko @ 2013-01-07 21:47 UTC (permalink / raw)
  To: help-gnu-emacs

On 2013-01-07, Jambunathan K wrote:

>> I also start thinking about "apply" with several list inside it:
>>
>>   (apply '+ 1 '(2) '(3 4))
>>
>> But above expression fail (only last arg expanded as list of args). To resolve
>> this issue I use expression:
>>
>>   (apply '+ 1 (append '(2) '(3 4)))
>>
>> But how about expression with atoms between (??):
>>
>>   '(1) 2 '(3 4)
>>
>> I write non-linear code:
>>
>>   (apply '+ (append '(1) (cons 2 '(3 4))))
>>
>> How to avoid call to "cons"?
>
> (apply '+ (loop for x in '(1 (2) (3 4))
> 		collect (if (numberp x) x (apply '+ x))))
>
> There are also other predicates that you can use.  For eg., atom, consp,
> listp.

Your trick work because + is associative operation.

I just start from example from 'apply' doc-string.

Consider example when 'some' func return region and 'another' require beg/end
pair:

  (defun some () ... (list beg end))
  (defun another (x beg end y) ...)

I think that this code ugly:

  (another x (car (some)) (cdr (some)) y)

If 'some' is complicated you need:

  (let* ( (region some) (beg (car region)) (end (cdr region)) )
      (another x beg end y)
    )

-- 
Best regards!




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: "Backquote constructs" to "splice" values without "eval".
  2013-01-07 21:47       ` Oleksandr Gavenko
@ 2013-01-08  5:48         ` Jambunathan K
  2013-01-08  5:51           ` Jambunathan K
  0 siblings, 1 reply; 8+ messages in thread
From: Jambunathan K @ 2013-01-08  5:48 UTC (permalink / raw)
  To: Oleksandr Gavenko; +Cc: help-gnu-emacs

Oleksandr Gavenko <gavenkoa@gmail.com> writes:

> On 2013-01-07, Jambunathan K wrote:
>
>>> I also start thinking about "apply" with several list inside it:
>>>
>>>   (apply '+ 1 '(2) '(3 4))
>>>
>>> But above expression fail (only last arg expanded as list of args). To resolve
>>> this issue I use expression:
>>>
>>>   (apply '+ 1 (append '(2) '(3 4)))
>>>
>>> But how about expression with atoms between (??):
>>>
>>>   '(1) 2 '(3 4)
>>>
>>> I write non-linear code:
>>>
>>>   (apply '+ (append '(1) (cons 2 '(3 4))))
>>>
>>> How to avoid call to "cons"?
>>
>> (apply '+ (loop for x in '(1 (2) (3 4))
>> 		collect (if (numberp x) x (apply '+ x))))
>>
>> There are also other predicates that you can use.  For eg., atom, consp,
>> listp.
>
> Your trick work because + is associative operation.
>
> I just start from example from 'apply' doc-string.

It is not clear to me what you are saying.  But I know that people who
are in Agra are searching for Taj Mahal, 99.9% of the cases.  You may
not visit Taj but atleast you can walk around Agra.  One is no better
than the other.

> Consider example when 'some' func return region and 'another' require beg/end
> pair:
>
>   (defun some () ... (list beg end))
>   (defun another (x beg end y) ...)
>
> I think that this code ugly:
>
>   (another x (car (some)) (cdr (some)) y)

Talking about ugly, while architecting something on a small scale is
sure way to get lost.

Aesthetics is over-rated.

ps: This is not a criticism of what you are doing but an observation
from my own experience.

> If 'some' is complicated you need:
>
>   (let* ( (region some) (beg (car region)) (end (cdr region)) )
>       (another x beg end y)
>     )

destructuring-bind, pcase, pcase*
-- 



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: "Backquote constructs" to "splice" values without "eval".
  2013-01-08  5:48         ` Jambunathan K
@ 2013-01-08  5:51           ` Jambunathan K
  0 siblings, 0 replies; 8+ messages in thread
From: Jambunathan K @ 2013-01-08  5:51 UTC (permalink / raw)
  To: Oleksandr Gavenko; +Cc: help-gnu-emacs

>> Consider example when 'some' func return region and 'another' require beg/end
>> pair:
>>
>>   (defun some () ... (list beg end))
>>   (defun another (x beg end y) ...)
>>
>> I think that this code ugly:
>>
>>   (another x (car (some)) (cdr (some)) y)
>
> Talking about ugly, while architecting something on a small scale is
> sure way to get lost.
>
> Aesthetics is over-rated.
>
> ps: This is not a criticism of what you are doing but an observation
> from my own experience.
>
>> If 'some' is complicated you need:
>>
>>   (let* ( (region some) (beg (car region)) (end (cdr region)) )
>>       (another x beg end y)
>>     )
>
> destructuring-bind, pcase, pcase*
                             ^^^^^^ 
It should be pcase-let, pcase-let*.



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-01-08  5:51 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <mailman.16855.1357563071.855.help-gnu-emacs@gnu.org>
2013-01-07 15:02 ` "Backquote constructs" to "splice" values without "eval" Barry Margolin
2013-01-07 20:36   ` Oleksandr Gavenko
2013-01-07 21:10     ` Jambunathan K
2013-01-07 21:47       ` Oleksandr Gavenko
2013-01-08  5:48         ` Jambunathan K
2013-01-08  5:51           ` Jambunathan K
     [not found]   ` <mailman.16874.1357591009.855.help-gnu-emacs@gnu.org>
2013-01-07 20:51     ` Barry Margolin
2013-01-07 12:50 Oleksandr Gavenko

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).