unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* run-with-timer does not display message
@ 2014-07-15 13:47 Matthias Pfeifer
  2014-07-15 13:53 ` Thorsten Jolitz
       [not found] ` <mailman.5455.1405432451.1147.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 30+ messages in thread
From: Matthias Pfeifer @ 2014-07-15 13:47 UTC (permalink / raw)
  To: help-gnu-emacs

Hi there,

this may be a dump question but i could not find a good reason why it
should not work as expected...

I try to write a message to the messages buffer at some time in the future
via run-with-timer

(run-with-timer 5 nil '(lambda () (message "hello")))

however messge buffer does not get the message. Hints welcome...

thanks in advance.

Matthias


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

* Re: run-with-timer does not display message
  2014-07-15 13:47 run-with-timer does not display message Matthias Pfeifer
@ 2014-07-15 13:53 ` Thorsten Jolitz
  2014-07-18 16:26   ` Stefan Monnier
       [not found]   ` <mailman.5631.1405701027.1147.help-gnu-emacs@gnu.org>
       [not found] ` <mailman.5455.1405432451.1147.help-gnu-emacs@gnu.org>
  1 sibling, 2 replies; 30+ messages in thread
From: Thorsten Jolitz @ 2014-07-15 13:53 UTC (permalink / raw)
  To: help-gnu-emacs

Matthias Pfeifer <mpfeifer77@gmail.com> writes:

> Hi there,
>
> this may be a dump question but i could not find a good reason why it
> should not work as expected...
>
> I try to write a message to the messages buffer at some time in the future
> via run-with-timer
>
> (run-with-timer 5 nil '(lambda () (message "hello")))
>
> however messge buffer does not get the message. Hints welcome...

works for me using 

M-: (run-with-timer 5 nil '(lambda () (message "hello")))

,----
| [nil 21445 12740 521048 nil (lambda nil (message "hello")) nil nil
| 860000]
| 
| hello
`----

-- 
cheers,
Thorsten




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

* Re: run-with-timer does not display message
       [not found] ` <mailman.5455.1405432451.1147.help-gnu-emacs@gnu.org>
@ 2014-07-15 15:35   ` Emanuel Berg
  0 siblings, 0 replies; 30+ messages in thread
From: Emanuel Berg @ 2014-07-15 15:35 UTC (permalink / raw)
  To: help-gnu-emacs

Thorsten Jolitz <tjolitz@gmail.com> writes:

> works for me using
>
> M-: (run-with-timer 5 nil '(lambda () (message "hello")))

Yes, works for me as well using the above code and `C-x
C-e' or `eval-last-sexp' (which here should be
equivalent to `M-:' or `eval-expression'). "hello"
appears in the echo area as well as the message buffer.

-- 
underground experts united


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

* Re: run-with-timer does not display message
  2014-07-15 13:53 ` Thorsten Jolitz
@ 2014-07-18 16:26   ` Stefan Monnier
       [not found]   ` <mailman.5631.1405701027.1147.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 30+ messages in thread
From: Stefan Monnier @ 2014-07-18 16:26 UTC (permalink / raw)
  To: help-gnu-emacs

>> (run-with-timer 5 nil '(lambda () (message "hello")))
> M-: (run-with-timer 5 nil '(lambda () (message "hello")))

Please don't quote your lambdas!


        Stefan




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

* Re: run-with-timer does not display message
       [not found]   ` <mailman.5631.1405701027.1147.help-gnu-emacs@gnu.org>
@ 2014-07-18 21:34     ` Emanuel Berg
  2014-07-19 15:09       ` Sebastian Wiesner
       [not found]       ` <mailman.5686.1405782584.1147.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 30+ messages in thread
From: Emanuel Berg @ 2014-07-18 21:34 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> Please don't quote your lambdas!

Do you mean in that case or never?

I have had problems with lambdas and both parameters
and `let' bindings.

For example, this works but not without the
backtick/backquote (and the commas):

(defun shortcut-to-file (key-prefix key file-prefix file)
  (global-set-key
   (format "%s%s" key-prefix key)
   `(lambda ()
      (interactive)
      (do-show-file (format "%s%s" ,file-prefix ,file)) )))

And, at least

(equal '(1 2 3) `(1 2 3)) => t
(equal '(1 2)   `(1 2 3)) => nil

But I believe you, of course, just if you could
elaborate some...

-- 
underground experts united


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

* Re: run-with-timer does not display message
  2014-07-18 21:34     ` Emanuel Berg
@ 2014-07-19 15:09       ` Sebastian Wiesner
  2014-07-19 15:27         ` Eli Zaretskii
       [not found]       ` <mailman.5686.1405782584.1147.help-gnu-emacs@gnu.org>
  1 sibling, 1 reply; 30+ messages in thread
From: Sebastian Wiesner @ 2014-07-19 15:09 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: help-gnu-emacs

Am 18.07.2014 um 23:34 schrieb Emanuel Berg <embe8573@student.uu.se>:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
> 
>> Please don't quote your lambdas!
> 
> Do you mean in that case or never?
> 
> I have had problems with lambdas and both parameters
> and `let' bindings.

Enable lexical-binding in your Emacs Lisp files to avoid these.  

See https://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html and https://www.gnu.org/software/emacs/manual/html_node/elisp/Using-Lexical-Binding.html for details.

> For example, this works but not without the
> backtick/backquote (and the commas):

With lexical binding it does.

> (defun shortcut-to-file (key-prefix key file-prefix file)
>  (global-set-key
>   (format "%s%s" key-prefix key)
>   `(lambda ()
>      (interactive)
>      (do-show-file (format "%s%s" ,file-prefix ,file)) )))

With lexical binding it works without any quoting:

(defun shortcut-to-file (key-prefix key file-prefix file)
 (global-set-key
  (format "%s%s" key-prefix key)
  (lambda ()
    (interactive)
    (do-show-file (format "%s%s" file-prefix file)))))

The arguments are captured in a closure, and thus preserved when the lambda body is evaluated.

This is more efficient than your variant.  Lexical bindings are generally more efficient than dynamic ones, because local variables can be elided entirely, and the byte compiler can now inspect and byte-compile the lambda form.  

It’s also safer, because the byte compiler can now warn you about unused variables or free variables, which helps you to catch misspelled variable names.


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

* Re: run-with-timer does not display message
  2014-07-19 15:09       ` Sebastian Wiesner
@ 2014-07-19 15:27         ` Eli Zaretskii
  2014-07-19 17:08           ` Stefan Monnier
       [not found]           ` <mailman.5702.1405789759.1147.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 30+ messages in thread
From: Eli Zaretskii @ 2014-07-19 15:27 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Sebastian Wiesner <swiesner@lunaryorn.com>
> Date: Sat, 19 Jul 2014 17:09:32 +0200
> Cc: help-gnu-emacs@gnu.org
> 
> > (defun shortcut-to-file (key-prefix key file-prefix file)
> >  (global-set-key
> >   (format "%s%s" key-prefix key)
> >   `(lambda ()
> >      (interactive)
> >      (do-show-file (format "%s%s" ,file-prefix ,file)) )))
> 
> With lexical binding it works without any quoting:
> 
> (defun shortcut-to-file (key-prefix key file-prefix file)
>  (global-set-key
>   (format "%s%s" key-prefix key)
>   (lambda ()
>     (interactive)
>     (do-show-file (format "%s%s" file-prefix file)))))

I don't think Stefan meant backtick-type of quoting.  He meant this:

> M-: (run-with-timer 5 nil '(lambda () (message "hello")))
                            ^^^^^^^^



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

* Re: run-with-timer does not display message
  2014-07-19 15:27         ` Eli Zaretskii
@ 2014-07-19 17:08           ` Stefan Monnier
  2014-07-19 18:04             ` Drew Adams
       [not found]           ` <mailman.5702.1405789759.1147.help-gnu-emacs@gnu.org>
  1 sibling, 1 reply; 30+ messages in thread
From: Stefan Monnier @ 2014-07-19 17:08 UTC (permalink / raw)
  To: help-gnu-emacs

> I don't think Stefan meant backtick-type of quoting.  He meant this:

>> M-: (run-with-timer 5 nil '(lambda () (message "hello")))
>                             ^^^^^^^^

Indeed.  Of course, it's also good to avoid backquoting lambdas
(typically by using lexical-binding instead), but I'm focusing on trying
to kill the nasty '(lambda ...) habit that people keep reproducing all
over the place because it appears in so many examples.


        Stefan




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

* Re: run-with-timer does not display message
       [not found]           ` <mailman.5702.1405789759.1147.help-gnu-emacs@gnu.org>
@ 2014-07-19 17:43             ` Emanuel Berg
  2014-07-19 18:12               ` Stefan Monnier
                                 ` (3 more replies)
  0 siblings, 4 replies; 30+ messages in thread
From: Emanuel Berg @ 2014-07-19 17:43 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> I don't think Stefan meant backtick-type of quoting.
>> He meant this:
>>
>> M-: (run-with-timer 5 nil '(lambda ...
>
> Indeed.

Yes, of course I understood that because that was the
only quoting going on. That's why I supplied the
`equal' example that seems to indicate that quoting and
backticking (without commas) are equal (?).

Here is what I remember from this - I'm shooting from
the holster (a bit) here, feel free to correct
misconceptions/-assumptions:

OK, dynamic scope is when everything is looked up only
when needed, that's the dynamic (time) thing to it,
because things can be different at different
times. This is what makes the whole dynamic environment
in Emacs possible which, by comparison, makes even cool
languages like C a pain to work with for large,
interactive systems...

Lexical scope is when things are encoded once and then
they don't change because they are passed around as
they are. Because they can be encoded different things
it makes sense calling this lexical (because the value
is simply read, not looked up) and not "static".

This corresponds to an extent to
call-by-value/call-by-reference, and in compiled
languages there are super-advanced use of pointers and
heap data structures to make up for the lack of "the
dynamic".

Questions:

1. How do I put Emacs in lexical mode? Do I do that
   temporarily (?!) with a Elisp block around certain
   code? Or is it a global option? If so, won't that
   screw up everything else in unpredictable ways?
   Also, isn't there some hybrid mode where this gets
   sorted out in the background?

2. Interestingly, what I can see, my method, with
   backticks and commas, isn't that "lexical" - because
   then, there, the actual values are inserted?

-- 
underground experts united


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

* Re: run-with-timer does not display message
       [not found]       ` <mailman.5686.1405782584.1147.help-gnu-emacs@gnu.org>
@ 2014-07-19 17:49         ` Emanuel Berg
  0 siblings, 0 replies; 30+ messages in thread
From: Emanuel Berg @ 2014-07-19 17:49 UTC (permalink / raw)
  To: help-gnu-emacs

Sebastian Wiesner <swiesner@lunaryorn.com> writes:

> Enable lexical-binding in your Emacs Lisp files to
> avoid these ...

Thank you for that information and the URLs. Check out
my other post if you like. I'll read those links and
try to get it to work - of course, it already works,
but still, there aren't any advantages that are small
enough not to explore.

-- 
underground experts united


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

* RE: run-with-timer does not display message
  2014-07-19 17:08           ` Stefan Monnier
@ 2014-07-19 18:04             ` Drew Adams
  0 siblings, 0 replies; 30+ messages in thread
From: Drew Adams @ 2014-07-19 18:04 UTC (permalink / raw)
  To: Stefan Monnier, help-gnu-emacs

> >> M-: (run-with-timer 5 nil '(lambda () (message "hello")))
> >                             ^^^^^^^^
> 
> I'm focusing on trying to kill the nasty '(lambda ...) habit that
> people keep reproducing all over the place because it appears in
> so many examples.

And we might as well say *why* it should be killed: When you quote
a lambda form, the code simply creates a *list* (whose car is `lambda'
etc.) when it is evaluated.  That list can then be interpreted as a
function (or not, depending on the context - it is just a list).

But if you do not quote, then the lambda form is understood
immediately as being a *function*.  And that means that occurrences
of that function can be byte-compiled etc.



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

* Re: run-with-timer does not display message
  2014-07-19 17:43             ` Emanuel Berg
@ 2014-07-19 18:12               ` Stefan Monnier
  2014-07-19 20:06                 ` Lexical and Dynamic Scope Robert Thorpe
  2014-07-20 12:15               ` run-with-timer does not display message Sebastian Wiesner
                                 ` (2 subsequent siblings)
  3 siblings, 1 reply; 30+ messages in thread
From: Stefan Monnier @ 2014-07-19 18:12 UTC (permalink / raw)
  To: help-gnu-emacs

> Because they can be encoded different things it makes sense calling
> this lexical (because the value is simply read, not looked up) and not
> "static".

It's also called "static scoping".  And the name doesn't have much to do
with the implementation technique used.  It's called "lexical" because
the way a particular identifier use is matched to a particular variable
only depends on the shape of the program text rather than depending on
its run-time behavior.

> This corresponds to an extent to
> call-by-value/call-by-reference,

No.  CBV/CBR/CBN are orthogonal concepts to static/dynamic scoping.

> 1. How do I put Emacs in lexical mode? Do I do that

Put -*- lexical-binding:t -*- somewhere on the first line of your Elisp file.


        Stefan




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

* Lexical and Dynamic Scope
  2014-07-19 18:12               ` Stefan Monnier
@ 2014-07-19 20:06                 ` Robert Thorpe
  0 siblings, 0 replies; 30+ messages in thread
From: Robert Thorpe @ 2014-07-19 20:06 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> Because they can be encoded different things it makes sense calling
>> this lexical (because the value is simply read, not looked up) and not
>> "static".
>
> It's also called "static scoping".  And the name doesn't have much to do
> with the implementation technique used.  It's called "lexical" because
> the way a particular identifier use is matched to a particular variable
> only depends on the shape of the program text rather than depending on
> its run-time behavior.

I'll elaborate a bit....  What we're talking about here is where
variables are visible.  How those variables behave is a different
question.  They could only hold one type (classical static typing), hold
a set of types or hold any type ("dynamic" typing) depending on the
language.

Most languages have lexical scope.  The scope of a variable is defined
by a part of the program text.  For example, a variable Bar is defined
in a function Foo.  That means Bar is visible within Foo only.  The
section of text defines where variables can be accessed, that's why it's
called "lexical" or "static".  There can be multiple levels of lexical
scoping, for example in C some variables are visible everywhere in a
file.  One way of thinking about it is by thinking of a stack.  The
current lexical area and everything defined in it is the top of the
stack.  When the code exits that area that place on the stack disappears
(it's popped).  When a function call occurs a new entry on top of the
stack is created (a push).

Dynamic scope means that visibility follows code execution.  If a
variable Baz is defined by code executed in the past then it's visible
by present code.  If a local variable called Baz is defined then it's
used instead of the more global one.  The "higher level" value continues
to exist.  This can be thought of using stacks too, in a slightly
different way.  In the dynamic case there's a stack for every
*variable name*.  If a local variable is defined for a name that's
already used then a new value is pushed on the stack of variable values
and removed when the local area ends.

Stefan and the Emacs maintainers added lexical scope because it makes
Emacs Lisp faster and it's simpler to understand.

BR,
Rob



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

* Re: run-with-timer does not display message
  2014-07-19 17:43             ` Emanuel Berg
  2014-07-19 18:12               ` Stefan Monnier
@ 2014-07-20 12:15               ` Sebastian Wiesner
  2014-07-21 13:26                 ` Stefan Monnier
       [not found]               ` <mailman.5708.1405793578.1147.help-gnu-emacs@gnu.org>
       [not found]               ` <mailman.5754.1405858540.1147.help-gnu-emacs@gnu.org>
  3 siblings, 1 reply; 30+ messages in thread
From: Sebastian Wiesner @ 2014-07-20 12:15 UTC (permalink / raw)
  To: help-gnu-emacs; +Cc: Emanuel Berg

Am Samstag, 19. Juli 2014, 19:43:16 schrieb Emanuel Berg:

> 2. Interestingly, what I can see, my method, with
>    backticks and commas, isn't that "lexical" - because
>    then, there, the actual values are inserted?

Note quite.  The backquote is “static” in that it captures the *value* of the 
variable at the time the backquote is evaluated.  “Lexical” binding captures 
the *variable itself*.

This makes a difference if the variable is changed after capturing.  
Considering the following example:

ELISP> (let ((i 10))
         (setq f-lexical (lambda () i))
         (setq f-backquote `(lambda () ,i))
         (setq i 20))
20 (#o24, #x14, ?\C-t)
ELISP> (funcall f-lexical)
20 (#o24, #x14, ?\C-t)
ELISP> (funcall f-backquote)
10 (#o12, #xa, ?\C-j)

As you can see, changing "i" *after* creating the functions only affects the 
closure created by lexical binding.  The function created by the backquote is 
left untouched.

This specific behaviour is what makes lexical binding special:  Capturing 
*lexical variables* in closures, as opposed to capturing values (by 
backquotes) or just using dynamic variables.  You cannot easily and 
efficiently emulated this behaviour with macros and backquotes.




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

* Re: run-with-timer does not display message
       [not found]               ` <mailman.5708.1405793578.1147.help-gnu-emacs@gnu.org>
@ 2014-07-20 19:27                 ` Emanuel Berg
  2014-07-21 13:29                   ` Stefan Monnier
       [not found]                   ` <mailman.5813.1405950328.1147.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 30+ messages in thread
From: Emanuel Berg @ 2014-07-20 19:27 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> Because they can be encoded different things it
>> makes sense calling this lexical (because the value
>> is simply read, not looked up) and not "static".
>
> It's also called "static scoping".  And the name
> doesn't have much to do with the implementation
> technique used.  It's called "lexical" because the way
> a particular identifier use is matched to a particular
> variable only depends on the shape of the program text
> rather than depending on its run-time behavior.
>
> ...
>
> No.  CBV/CBR/CBN are orthogonal concepts to
> static/dynamic scoping.

Isn't CBR and dynamic alike in the sense than a value
is looked up somewhere outside of the "scope", say a
function in C, while CBV is lexical as the parameter is
just a way to refer to a value for convenience?

I don't know what CBN (call by name?) is but that in
the above sense would be dynamic as the name, once put
to use, is replaced by a value and that value has to be
looked up at that time.

If a reference is used as a reference, i.e., ignoring
what it refers to, then of course it is all the
same. It has to be looked up but otherwise why do it at
all?

>> 1. How do I put Emacs in lexical mode? Do I do that
>
> Put -*- lexical-binding:t -*- somewhere on the first
> line of your Elisp file.

So you can't do it for a specific function? I'm
starting to lean toward me preferring the backtick-comma
solution...

-- 
underground experts united


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

* Re: run-with-timer does not display message
       [not found]               ` <mailman.5754.1405858540.1147.help-gnu-emacs@gnu.org>
@ 2014-07-20 19:37                 ` Emanuel Berg
  2014-07-20 20:11                   ` Drew Adams
  2014-07-20 21:28                 ` dynamic and lexical scope, attempted summary with example (was: Re: run-with-timer does not display message) Emanuel Berg
  1 sibling, 1 reply; 30+ messages in thread
From: Emanuel Berg @ 2014-07-20 19:37 UTC (permalink / raw)
  To: help-gnu-emacs

Sebastian Wiesner <swiesner@lunaryorn.com> writes:

>> 2. Interestingly, what I can see, my method, with
>> backticks and commas, isn't that "lexical" - because
>> then, there, the actual values are inserted?
>
> Note quite.  The backquote is “static” in that it
> captures the *value* of the variable at the time the
> backquote is evaluated.  “Lexical” binding captures
> the *variable itself*.

Yes, the backtick-comma is to downright hard-code it,
although it is code, and not a human, who do the
hard-coding...

> This makes a difference if the variable is changed
> after capturing.  Considering the following example
> ...
>
> As you can see, changing "i" *after* creating the
> functions only affects the closure created by lexical
> binding.  The function created by the backquote is
> left untouched.

Yes, that is clear, but this example shows (to me) the
difference between using hard-coded values and using
variables (in general).

That example looks all-fine to me. Are you saying, with
dynamic scope, the `i' in the lambda wouldn't have been
affected by the `setq'? But to me, your example is the
way it should be, natural... Why then, would you want
to use dynamic scope, and why is it the default?

-- 
underground experts united


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

* RE: run-with-timer does not display message
  2014-07-20 19:37                 ` Emanuel Berg
@ 2014-07-20 20:11                   ` Drew Adams
  0 siblings, 0 replies; 30+ messages in thread
From: Drew Adams @ 2014-07-20 20:11 UTC (permalink / raw)
  To: Emanuel Berg, help-gnu-emacs

> Why...would you want to use dynamic scope, and why is it the default?

RMS replied to your question (a quarter-century before you posed it):
http://www.gnu.org/software/emacs/emacs-paper.html#SEC17



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

* dynamic and lexical scope, attempted summary with example (was: Re: run-with-timer does not display message)
       [not found]               ` <mailman.5754.1405858540.1147.help-gnu-emacs@gnu.org>
  2014-07-20 19:37                 ` Emanuel Berg
@ 2014-07-20 21:28                 ` Emanuel Berg
  2014-07-21  4:44                   ` dynamic and lexical scope, attempted summary with example Thien-Thi Nguyen
                                     ` (3 more replies)
  1 sibling, 4 replies; 30+ messages in thread
From: Emanuel Berg @ 2014-07-20 21:28 UTC (permalink / raw)
  To: help-gnu-emacs

As always, I think it is easier to discuss in terms of
an example...

This function is what started it all:

(defun shortcut-to-file (key-prefix key file-prefix file)
  "Make shortcut with key KEY-PREFIX KEY to FILE-PREFIX FILE."
  (global-set-key
   (format "%s%s" key-prefix key)
   `(lambda ()
      (interactive)
      (do-show-file (format "%s%s" ,file-prefix ,file)) )))

Is this correct?

In dynamic scope:
      
1. At the 4th line, the line that starts with `format',
   we see use of the arguments to the parameters
   `key-prefix' and `key' - because they are inside the
   defun, it is clear that those refer the the
   arguments passed as parameters.

2. At the 7th, last line, `file-prefix' and `file'
   appears. Those are preceded by commas so, in
   combination with the backtick, their values will be
   inserted - hard-coded. This bypasses the whole
   problem because it eliminates all evaluation of
   symbols (it is like Caesar and the Gordian
   knot). The drawback is that the lambda can't be
   byte-compiled as it is formally "just" a list.

3. If the lambda wasn't backticked and shot with
   commas, the defun would evaluate fine and even
   calling it wouldn't raise an error. However, when
   the keystroke was actually hit, the lambda wouldn't
   be within the defun anymore - it would be in the
   wild, and `file-prefix' and `file' would be
   interpreted as symbols, i.e., global
   variables. Those are probably not defined... but if
   they were, with `setq' for example, those values
   would be used (this would make for a total mess).

In lexical scope, the backtick and the commas aren't
necessary. The lambda can be expressed as a lambda and
nothing else, which means it can be byte-compiled. When
the symbols are encountered, those aren't looked for as
global variables, but rather the history of the place
they occurred in code is drilled down, until a scope is
encountered where they are defined, and those values
are used.

-- 
underground experts united


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

* Re: dynamic and lexical scope, attempted summary with example
  2014-07-20 21:28                 ` dynamic and lexical scope, attempted summary with example (was: Re: run-with-timer does not display message) Emanuel Berg
@ 2014-07-21  4:44                   ` Thien-Thi Nguyen
  2014-07-21  6:36                     ` Thorsten Jolitz
       [not found]                     ` <mailman.5796.1405924598.1147.help-gnu-emacs@gnu.org>
  2014-07-21  9:23                   ` Michael Heerdegen
                                     ` (2 subsequent siblings)
  3 siblings, 2 replies; 30+ messages in thread
From: Thien-Thi Nguyen @ 2014-07-21  4:44 UTC (permalink / raw)
  To: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 1354 bytes --]

() Emanuel Berg <embe8573@student.uu.se>
() Sun, 20 Jul 2014 23:28:58 +0200

   (defun shortcut-to-file (key-prefix key file-prefix file)
     "Make shortcut with key KEY-PREFIX KEY to FILE-PREFIX FILE."
     (global-set-key
      (format "%s%s" key-prefix key)
      `(lambda ()
         (interactive)
         (do-show-file (format "%s%s" ,file-prefix ,file)) )))

   Is this correct?

It is if it does what the designer desires.  :-D
I find ‘(format "%s%s" A B)’ unbeautiful, personally.

   2. At the 7th, last line, `file-prefix' and `file'
      appears. Those are preceded by commas so, in
      combination with the backtick, their values will be
      inserted - hard-coded. This bypasses the whole
      problem because it eliminates all evaluation of
      symbols (it is like Caesar and the Gordian
      knot). The drawback is that the lambda can't be
      byte-compiled as it is formally "just" a list.

I think using terms "insert" and "hard-coded" is confusing
in this context.  Also, "eliminated" is imprecise and thus
misleading.  To bake a cake, do you eliminate the flour?

-- 
Thien-Thi Nguyen
   GPG key: 4C807502
   (if you're human and you know it)
      read my lisp: (responsep (questions 'technical)
                               (not (via 'mailing-list)))
                     => nil

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

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

* Re: dynamic and lexical scope, attempted summary with example
  2014-07-21  4:44                   ` dynamic and lexical scope, attempted summary with example Thien-Thi Nguyen
@ 2014-07-21  6:36                     ` Thorsten Jolitz
       [not found]                     ` <mailman.5796.1405924598.1147.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 30+ messages in thread
From: Thorsten Jolitz @ 2014-07-21  6:36 UTC (permalink / raw)
  To: help-gnu-emacs


> (it is like Caesar and the Gordian knot)

I think Caesar was a bit late on the party, wasn't that Alexander a few
centuries earlier?

-- 
cheers,
Thorsten




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

* Re: dynamic and lexical scope, attempted summary with example
  2014-07-20 21:28                 ` dynamic and lexical scope, attempted summary with example (was: Re: run-with-timer does not display message) Emanuel Berg
  2014-07-21  4:44                   ` dynamic and lexical scope, attempted summary with example Thien-Thi Nguyen
@ 2014-07-21  9:23                   ` Michael Heerdegen
       [not found]                   ` <mailman.5792.1405917701.1147.help-gnu-emacs@gnu.org>
       [not found]                   ` <mailman.5805.1405934637.1147.help-gnu-emacs@gnu.org>
  3 siblings, 0 replies; 30+ messages in thread
From: Michael Heerdegen @ 2014-07-21  9:23 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <embe8573@student.uu.se> writes:

> As always, I think it is easier to discuss in terms of
> an example...

Right, but I think in this case, it's not a good idea to learn that in
passing.  I really recommend to read some literature about it - this
isn't trivial.  Both kinds of scope have their rights to exist and their
use cases.

When I first heard about scope, I though "This does only matter in
situations I avoid".  But lexical scope in a functional language
is a basis of lots of advanced programming techniques.  OTOH, dynamic
scope is as well imperative to programming in LISP.

It's explained e.g. here:

    http://www.paulgraham.com/onlisp.html

There are books easier to read than this, but the chapter about scope is
well understandable without reading the rest, I think.




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

* Re: run-with-timer does not display message
  2014-07-20 12:15               ` run-with-timer does not display message Sebastian Wiesner
@ 2014-07-21 13:26                 ` Stefan Monnier
  0 siblings, 0 replies; 30+ messages in thread
From: Stefan Monnier @ 2014-07-21 13:26 UTC (permalink / raw)
  To: help-gnu-emacs

> This specific behaviour is what makes lexical binding special:  Capturing
> *lexical variables* in closures, as opposed to capturing values (by
> backquotes)

While this is used occasionally, most uses of lexical-scoping don't care
about this "feature".  E.g. *all* uses of lexical scoping in the ML
family of languages (which don't have the equivalent of `setq').

> or just using dynamic variables.  You cannot easily and
> efficiently emulated this behaviour with macros and backquotes.

As mentioned in another message, the byte-compiler faces the same
problem.  And the way it solves it can be applied to backquoted lambdas
just as easily: just replace the variable with a cons cell whose `car'
contains the value.

IOW the byte-compiler will generate almost 100% exactly the same code for

   (let ((i 10))
     (setq f-lexical (lambda () i))
     (setq i 20))

as for

   (let ((i (list 10)))
     (setq f-lexical (lambda () (car i)))
     (setcar i 20))

and of course you can get the same result with backquote:

   (let ((i (list 10)))
     (setq f-lexical `(lambda () (car ',i)))
     (setcar i 20))


-- Stefan




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

* Re: run-with-timer does not display message
  2014-07-20 19:27                 ` Emanuel Berg
@ 2014-07-21 13:29                   ` Stefan Monnier
       [not found]                   ` <mailman.5813.1405950328.1147.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 30+ messages in thread
From: Stefan Monnier @ 2014-07-21 13:29 UTC (permalink / raw)
  To: help-gnu-emacs

>>> 1. How do I put Emacs in lexical mode? Do I do that
>> Put -*- lexical-binding:t -*- somewhere on the first
>> line of your Elisp file.
> So you can't do it for a specific function?

No.

> I'm starting to lean toward me preferring the backtick-comma
> solution...

99.9% of existing dynamically scoped Emacs Lisp will work just as well with
lexical-binding.  And the remaining 0.1% can usually be fixed very
easily by adding a few (defvar <myvar>).


        Stefan




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

* Re: dynamic and lexical scope, attempted summary with example
       [not found]                   ` <mailman.5792.1405917701.1147.help-gnu-emacs@gnu.org>
@ 2014-07-21 13:36                     ` Emanuel Berg
  2014-07-21 17:07                       ` Thien-Thi Nguyen
       [not found]                       ` <mailman.5826.1405962249.1147.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 30+ messages in thread
From: Emanuel Berg @ 2014-07-21 13:36 UTC (permalink / raw)
  To: help-gnu-emacs

Thien-Thi Nguyen <ttn@gnu.org> writes:

> I find ‘(format "%s%s" A B)’ unbeautiful, personally.

OK, how would you do it?

> I think using terms "insert" and "hard-coded" is
> confusing in this context.  Also, "eliminated" is
> imprecise and thus misleading.  To bake a cake, do
> you eliminate the flour?

But you understand it, right? I mean, what I mean?

The result of the _insertion_ of literal values at the
places of the parameters, will result in a function
that don't use variables (dynamic or lexical) but
_hard-coded_ values - that issue is _eliminated_.

Do you think it is correct in terms of technology?

Nevertheless, I would be interesting to hear if you
have a better way of putting it, as I happen to know
you are the only "Emacs beatnik" around?

-- 
underground experts united


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

* Re: dynamic and lexical scope, attempted summary with example
       [not found]                   ` <mailman.5805.1405934637.1147.help-gnu-emacs@gnu.org>
@ 2014-07-21 14:02                     ` Emanuel Berg
  0 siblings, 0 replies; 30+ messages in thread
From: Emanuel Berg @ 2014-07-21 14:02 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen <michael_heerdegen@web.de> writes:

> Right, but I think in this case, it's not a good idea
> to learn that in passing.  I really recommend to read
> some literature about it - this isn't trivial.  Both
> kinds of scope have their rights to exist and their
> use cases.
>
> When I first heard about scope, I though "This does
> only matter in situations I avoid".  But lexical
> scope in a functional language is a basis of lots of
> advanced programming techniques.  OTOH, dynamic scope
> is as well imperative to programming in LISP.
>
> It's explained e.g. here:
>
>     http://www.paulgraham.com/onlisp.html
>
> There are books easier to read than this, but the
> chapter about scope is well understandable without
> reading the rest, I think.

Yeah... I read so much. Five years of pitch-black
computer science. What do I get? Not a dime in my
pocket and only "read the Emacs manual", "read the
Elisp manual", read that, read this... Do I go around
telling everyone: write code, write code, write
code...? No. But the only reason I don't do that is
because I know no one or very few would actually do it
if I did. Well, let's see if anyone comments on the
material in a more applied way... stayed tuned for the
next episode of Operation Emacs - the same channel, the
same terminal!

PS. But thanks again for you other comments that were
very helpful. DS.

-- 
underground experts united


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

* Re: dynamic and lexical scope, attempted summary with example
       [not found]                     ` <mailman.5796.1405924598.1147.help-gnu-emacs@gnu.org>
@ 2014-07-21 14:08                       ` Emanuel Berg
  0 siblings, 0 replies; 30+ messages in thread
From: Emanuel Berg @ 2014-07-21 14:08 UTC (permalink / raw)
  To: help-gnu-emacs

Thorsten Jolitz <tjolitz@gmail.com> writes:

>> (it is like Caesar and the Gordian knot)
>
> I think Caesar was a bit late on the party, wasn't
> that Alexander a few centuries earlier?

Yeah... I've heard of him, wasn't he president before
Lincoln?

No, of course, the expression with Caesar is throwing
dices with some fatalistic irony to it. It doesn't
apply, so let me make up for that:

(1+ (random 6))

But... don't you have any comments on the code and the
comments?

-- 
underground experts united


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

* Re: dynamic and lexical scope, attempted summary with example
  2014-07-21 13:36                     ` Emanuel Berg
@ 2014-07-21 17:07                       ` Thien-Thi Nguyen
       [not found]                       ` <mailman.5826.1405962249.1147.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 30+ messages in thread
From: Thien-Thi Nguyen @ 2014-07-21 17:07 UTC (permalink / raw)
  To: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 1393 bytes --]

() Emanuel Berg <embe8573@student.uu.se>
() Mon, 21 Jul 2014 15:36:26 +0200

   Thien-Thi Nguyen <ttn@gnu.org> writes:

   > I find ‘(format "%s%s" A B)’ unbeautiful, personally.

   OK, how would you do it?

I would make sure A and B are always strings and use ‘concat’.
For filenames, i would use ‘(expand-file-name B A)’.

   > I think using terms "insert" and "hard-coded" is
   > confusing in this context.  Also, "eliminated" is
   > imprecise and thus misleading.  To bake a cake, do
   > you eliminate the flour?

   But you understand it, right? I mean, what I mean?

If i answer "no", then both of us may be fooling ourselves,
but in a safe way.  If i answer "yes", then there is only
one fool (me), but the foolishness i am capable of is huge.

   The result of the _insertion_ of literal values at the
   places of the parameters, will result in a function
   that don't use variables (dynamic or lexical) but
   _hard-coded_ values - that issue is _eliminated_.

   Do you think it is correct in terms of technology?

Mu!  (See above.)  Actually, i'd add "places" and "will
result" to my list of confusions.

-- 
Thien-Thi Nguyen
   GPG key: 4C807502
   (if you're human and you know it)
      read my lisp: (responsep (questions 'technical)
                               (not (via 'mailing-list)))
                     => nil

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

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

* Re: dynamic and lexical scope, attempted summary with example
       [not found]                       ` <mailman.5826.1405962249.1147.help-gnu-emacs@gnu.org>
@ 2014-07-21 22:11                         ` Emanuel Berg
  0 siblings, 0 replies; 30+ messages in thread
From: Emanuel Berg @ 2014-07-21 22:11 UTC (permalink / raw)
  To: help-gnu-emacs

Thien-Thi Nguyen <ttn@gnu.org> writes:

> I would make sure A and B are always strings and use
> ‘concat’.  For filenames, i would use
> ‘(expand-file-name B A)’.

Do you suggest this because "you should always verify
the input"? With `stringp', in this case?

If you verify all inputs as a matter of principle I
guess `file-exists-p' should be put somewhere as well?

And: `expand-file-name' - because it is more
portable/safe, replacing tilde with the literal
/home/user/ and possibly other housekeeping?

Well, all those considerations aren't really an issue
as the only person using this will be yours truly and
all possible bugs will be found instantly (and without
harm) and corrected. `expand-file-name' I'll use as a
matter of principle but verifying indata, for all
zillion defuns it would be lots of work for catching
accidental maluse of the software - does that usually
pay off? In my experience, I don't think so.

> If i answer "no", then both of us may be fooling
> ourselves, but in a safe way.  If i answer "yes",
> then there is only one fool (me), but the foolishness
> i am capable of is huge.
>
> The result of the _insertion_ of literal values at
> the places of the parameters, will result in a
> function that don't use variables (dynamic or
> lexical) but _hard-coded_ values - that issue is
> _eliminated_.
>
> Do you think it is correct in terms of technology?
>
> Mu!  (See above.)  Actually, i'd add "places" and
> "will result" to my list of confusions.

I know you understand because you have read the code
which you understand instantly. Of course English
cannot describe the code perfectly, but I bet it didn't
add to your confusion. If you know a better way to
describe it do tell.

-- 
underground experts united


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

* Re: run-with-timer does not display message
       [not found]                   ` <mailman.5813.1405950328.1147.help-gnu-emacs@gnu.org>
@ 2014-07-21 22:17                     ` Emanuel Berg
  2014-07-24  8:25                       ` Stefan Monnier
  0 siblings, 1 reply; 30+ messages in thread
From: Emanuel Berg @ 2014-07-21 22:17 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> 99.9% of existing dynamically scoped Emacs Lisp will
> work just as well with lexical-binding.  And the
> remaining 0.1% can usually be fixed very easily by
> adding a few (defvar <myvar>).

Do you think lexical scope is better for general
purposes and the Joe Elisp Hacker?

-- 
underground experts united


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

* Re: run-with-timer does not display message
  2014-07-21 22:17                     ` Emanuel Berg
@ 2014-07-24  8:25                       ` Stefan Monnier
  0 siblings, 0 replies; 30+ messages in thread
From: Stefan Monnier @ 2014-07-24  8:25 UTC (permalink / raw)
  To: help-gnu-emacs

> Do you think lexical scope is better for general
> purposes and the Joe Elisp Hacker?

Absolutely.


        Stefan




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

end of thread, other threads:[~2014-07-24  8:25 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-15 13:47 run-with-timer does not display message Matthias Pfeifer
2014-07-15 13:53 ` Thorsten Jolitz
2014-07-18 16:26   ` Stefan Monnier
     [not found]   ` <mailman.5631.1405701027.1147.help-gnu-emacs@gnu.org>
2014-07-18 21:34     ` Emanuel Berg
2014-07-19 15:09       ` Sebastian Wiesner
2014-07-19 15:27         ` Eli Zaretskii
2014-07-19 17:08           ` Stefan Monnier
2014-07-19 18:04             ` Drew Adams
     [not found]           ` <mailman.5702.1405789759.1147.help-gnu-emacs@gnu.org>
2014-07-19 17:43             ` Emanuel Berg
2014-07-19 18:12               ` Stefan Monnier
2014-07-19 20:06                 ` Lexical and Dynamic Scope Robert Thorpe
2014-07-20 12:15               ` run-with-timer does not display message Sebastian Wiesner
2014-07-21 13:26                 ` Stefan Monnier
     [not found]               ` <mailman.5708.1405793578.1147.help-gnu-emacs@gnu.org>
2014-07-20 19:27                 ` Emanuel Berg
2014-07-21 13:29                   ` Stefan Monnier
     [not found]                   ` <mailman.5813.1405950328.1147.help-gnu-emacs@gnu.org>
2014-07-21 22:17                     ` Emanuel Berg
2014-07-24  8:25                       ` Stefan Monnier
     [not found]               ` <mailman.5754.1405858540.1147.help-gnu-emacs@gnu.org>
2014-07-20 19:37                 ` Emanuel Berg
2014-07-20 20:11                   ` Drew Adams
2014-07-20 21:28                 ` dynamic and lexical scope, attempted summary with example (was: Re: run-with-timer does not display message) Emanuel Berg
2014-07-21  4:44                   ` dynamic and lexical scope, attempted summary with example Thien-Thi Nguyen
2014-07-21  6:36                     ` Thorsten Jolitz
     [not found]                     ` <mailman.5796.1405924598.1147.help-gnu-emacs@gnu.org>
2014-07-21 14:08                       ` Emanuel Berg
2014-07-21  9:23                   ` Michael Heerdegen
     [not found]                   ` <mailman.5792.1405917701.1147.help-gnu-emacs@gnu.org>
2014-07-21 13:36                     ` Emanuel Berg
2014-07-21 17:07                       ` Thien-Thi Nguyen
     [not found]                       ` <mailman.5826.1405962249.1147.help-gnu-emacs@gnu.org>
2014-07-21 22:11                         ` Emanuel Berg
     [not found]                   ` <mailman.5805.1405934637.1147.help-gnu-emacs@gnu.org>
2014-07-21 14:02                     ` Emanuel Berg
     [not found]       ` <mailman.5686.1405782584.1147.help-gnu-emacs@gnu.org>
2014-07-19 17:49         ` run-with-timer does not display message Emanuel Berg
     [not found] ` <mailman.5455.1405432451.1147.help-gnu-emacs@gnu.org>
2014-07-15 15:35   ` Emanuel Berg

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