From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: yyoncho Newsgroups: gmane.emacs.devel Subject: Re: Questions about throw-on-input Date: Fri, 8 May 2020 07:43:42 +0300 Message-ID: References: <87r1vwxktw.fsf@gmail.com> <831rnvly58.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000f9ce0705a51ba48c" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="104335"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Eli Zaretskii , emacs-devel To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri May 08 06:44:29 2020 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jWus9-000QzP-79 for ged-emacs-devel@m.gmane-mx.org; Fri, 08 May 2020 06:44:29 +0200 Original-Received: from localhost ([::1]:56374 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jWus8-0002qE-9w for ged-emacs-devel@m.gmane-mx.org; Fri, 08 May 2020 00:44:28 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:49070) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jWurd-0002RY-OD for emacs-devel@gnu.org; Fri, 08 May 2020 00:43:57 -0400 Original-Received: from mail-lj1-x232.google.com ([2a00:1450:4864:20::232]:46266) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jWurc-00046J-Ao; Fri, 08 May 2020 00:43:57 -0400 Original-Received: by mail-lj1-x232.google.com with SMTP id f18so236572lja.13; Thu, 07 May 2020 21:43:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=AA3kBYuITPxo9AMyOK7qulG6kqxNa9TcoCuHJmDh578=; b=Km9V15u7dsjCyXJSg5NXfT8wumnlVDQwI4hMuEsBMevEHwy35K7OGMQU5RYk9Qckrx WGNZ0Himjpj+A/KTdSxHZ5dBUQ0YZKI5CAGy8crybVMhqIymgF3HcYN7IZ2iWmFAvGGz 6Y34gclML8nnhrbXWXxI51Ph1Av8SJs1U3kvr2I5VC3ry/V1lrRPg+zHfVMn105vajtc YZA47ZwJ/znQSNCsnDRUjEAbMDMOu1MCnJFd4ILxCgfjyGCFdZ8wLVSzomxpHR3W1kU5 S+3O63R1QMXoO5Rg/5VRhHXfq4F3mNE4QfznqkkEiA/iwGDT8Xee0pJaRB042Tbq5tTF CuUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=AA3kBYuITPxo9AMyOK7qulG6kqxNa9TcoCuHJmDh578=; b=SaF7CbxOPUDsCEUJ6+dFRDcDknCiAkOl0y6TTEhCUlXEc0to1jQEtq6d4jhIvRZrOi PTGHh1yaxEHSzbN45SEfYsiKYVP+PR5zQOipw80aHwWtETa7Oq9UrzD7PLLm6VOtpWyj xaNy9/k7/21vD9OL936hbPl13k0MefkRn2FE/vGEgpQYST32eDnHY5CPNWqOoTFV2u8n 8fnVRHPKXF7dGiXxM2jeg8gfaWgpPOIJgWK8cCiw8mKUQxGXeYTEJeaprgIul9nusoS5 acxIRMDU98f4SKZlGEUrySrPvXI4LJ3pQw4i7QmpBF2ASIpmsetXqSvTOYpb8Kv5YhDN XYiQ== X-Gm-Message-State: AOAM533tAL0TCCeUrtROmNqJGGIGjZcG03GCL2eKs5+IkYn4dqFDhR6n o4UcD7Sg9ecO97oG+3+N9b/8aZ12UVV2dQmW71s= X-Google-Smtp-Source: ABdhPJz0IFKfTZyR9nZn7/TS8eeonm23ZBAfWBsvV0b7oRIbbcktB2BQYGp9SBCbLjVt9ymCq54hpJl0IQI2QMLeUy4= X-Received: by 2002:a2e:9605:: with SMTP id v5mr401966ljh.102.1588913034087; Thu, 07 May 2020 21:43:54 -0700 (PDT) In-Reply-To: Received-SPF: pass client-ip=2a00:1450:4864:20::232; envelope-from=yyoncho@gmail.com; helo=mail-lj1-x232.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:249243 Archived-At: --000000000000f9ce0705a51ba48c Content-Type: text/plain; charset="UTF-8" Sorry, I accidentally pressed send before finishing my reply. I was about to suggest using the quit-flag to indicate - "instead of quitting process events during the execution of the block", like that (let ((quit-flag :process-events)) (slow-operation)) Not sure if this will work but in case it works, it will be great! Thanks, Ivan On Fri, May 8, 2020 at 7:36 AM yyoncho wrote: > Hi Stefan, > > Thank you for your reply! Can you elaborate on "won't have the desired > semantics"? I would suggest something crazier - using inhibit-quit to > > Thanks, > Ivan > > On Fri, May 8, 2020 at 4:59 AM Stefan Monnier > wrote: > >> > Out of curiosity, do you think that having a function >> > (process-events) which will process all keyboard(?) events >> > and resume the current invocation can be implemented easily? >> >> It can be implemented, but it won't have the desired semantics. >> If you want something robust you have 2 options: >> >> - write in an event-driven style (or CPS style) so that you can easily >> stop at various points in the program and stash the rest of the >> computation for later. >> >> - use a thread (which will basically do the same, but transparently, >> i.e. without the awkward programming style.) >> >> >> Stefan >> >> >> > AFAIK a lot of gui toolkits have that kind of function, e. g. >> > >> https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.application.doevents?view=netcore-3.1 >> > >> > IMO it will be very useful for certain cases. >> > >> > Thanks, >> > Ivan >> > >> > On Thu, May 7, 2020 at 3:37 PM Eli Zaretskii wrote: >> > >> >> > From: Ivan Yonchovski >> >> > Date: Thu, 07 May 2020 10:31:23 +0300 >> >> > >> >> > >> >> > 1. In the following example: >> >> > >> >> > (dotimes (_ 10) >> >> > (message "Length %s" >> >> > (length >> >> > (let (result) >> >> > (catch t >> >> > (let ((throw-on-input t)) >> >> > (dotimes (counter 10000000) >> >> > (push (number-to-string counter) result)))) >> >> > result)))) >> >> > >> >> > .. after I execute the following block each of the 10 computations >> will >> >> be >> >> > canceled after pressing C-n for example, how do I force the handling >> of >> >> > the command to be processed? I tried redisplay but it does not help. >> >> >> >> Invoking redisplay won't help because the commands which interrupted >> >> the inner loop (C-n) were not yet executed. Emacs will process them >> >> only after the outer loop ends, because that outer loop is the last >> >> command, and it is still being executed. Emacs doesn't perform >> >> commands in the middle of another command. >> >> >> >> > (message "Length %s" >> >> > (length >> >> > (let (result) >> >> > (catch t >> >> > (let ((throw-on-input t)) >> >> > (dotimes (counter 10000000) >> >> > (push (number-to-string counter) result)))) >> >> > result))) >> >> > >> >> > >> >> > (run-with-idle-timer >> >> > 0.0 >> >> > nil >> >> > (lambda () >> >> > (message "Length %s" >> >> > (length >> >> > (let (result) >> >> > (catch t >> >> > (let ((throw-on-input t)) >> >> > (dotimes (counter 10000000) >> >> > (push (number-to-string counter) result)))) >> >> > result))))) >> >> > >> >> > The issue is with the second block, it seems like throw-on-input is >> >> > disregarded when used in run-with-idle-timer. Can anyone confirm if >> this >> >> > is a bug/desired behavior or I should use something else if I want to >> >> > run cancelable tasks in on-idle? >> >> >> >> When the time function is run, Emacs binds inhibit-quit to t (so that >> >> the user's C-g would not interrupt the timer function, for example). >> >> And throw-on-input uses quitting to do its job. >> >> >> >> Why do you need to interrupt an idle timer like that? The usual way >> >> of doing this is not to call expensive functions in an idle timer, and >> >> if you have a lot of processing, divide them into small enough chunks >> >> and do it piecemeal. That's what jit-stealth font-lock does, for >> >> example. >> >> >> >> --000000000000f9ce0705a51ba48c Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Sorry, I accidentally=C2=A0pressed send before finishing m= y=C2=A0reply.

I was about to suggest using the quit-flag= to indicate - "instead
of quitting=C2=A0process events duri= ng the execution of the block", like that

(le= t ((quit-flag :process-events))
=C2=A0 (slow-operation))
<= br>
Not sure if this will work but in case it works, it will be g= reat!

Thanks,
Ivan

On Fri, May 8, 2= 020 at 7:36 AM yyoncho <yyoncho@gma= il.com> wrote:
Hi Stefan,

Thank you for your rep= ly! Can you elaborate on "won't have the desired semantics"? = I would=C2=A0suggest something crazier=C2=A0- using inhibit-quit to=C2=A0

Thanks,
Ivan

On Fri, May 8, 2020 at = 4:59 AM Stefan Monnier <monnier@iro.umontreal.ca> wrote:
> Out of curiosity, do you think t= hat having a function
> (process-events) which will process all keyboard(?) events
> and resume the current invocation can be implemented easily?

It can be implemented, but it won't have the desired semantics.
If you want something robust you have 2 options:

- write in an event-driven style (or CPS style) so that you can easily
=C2=A0 stop at various points in the program and stash the rest of the
=C2=A0 computation for later.

- use a thread (which will basically do the same, but transparently,
=C2=A0 i.e. without the awkward programming style.)


=C2=A0 =C2=A0 =C2=A0 =C2=A0 Stefan


> AFAIK a lot of gui toolkits have that kind of function, e. g.
> https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.a= pplication.doevents?view=3Dnetcore-3.1
>
> IMO it will be very useful for certain cases.
>
> Thanks,
> Ivan
>
> On Thu, May 7, 2020 at 3:37 PM Eli Zaretskii <eliz@gnu.org> wrote:
>
>> > From: Ivan Yonchovski <yyoncho@gmail.com>
>> > Date: Thu, 07 May 2020 10:31:23 +0300
>> >
>> >
>> > 1. In the following example:
>> >
>> > (dotimes (_ 10)
>> >=C2=A0 =C2=A0(message "Length %s"
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (length
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(let (result)<= br> >> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(catch = t
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (let ((throw-on-input t))
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0(dotimes (counter 10000000)
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0(push (number-to-string counter) result))))
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0result)= )))
>> >
>> > .. after I execute the following block each of the 10 computa= tions will
>> be
>> > canceled after pressing C-n for example, how do I force the h= andling of
>> > the command to be processed? I tried redisplay but it does no= t help.
>>
>> Invoking redisplay won't help because the commands which inter= rupted
>> the inner loop (C-n) were not yet executed.=C2=A0 Emacs will proce= ss them
>> only after the outer loop ends, because that outer loop is the las= t
>> command, and it is still being executed.=C2=A0 Emacs doesn't p= erform
>> commands in the middle of another command.
>>
>> > (message "Length %s"
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (length
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(let (result)
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(catch t
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(let ((= throw-on-input t))
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (dotimes (counter 10000000)
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0(push (number-to-string counter) result))))
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0result)))
>> >
>> >
>> > (run-with-idle-timer
>> >=C2=A0 0.0
>> >=C2=A0 nil
>> >=C2=A0 (lambda ()
>> >=C2=A0 =C2=A0 (message "Length %s"
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(length
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let (result)=
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (catch= t
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (let ((throw-on-input t))
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 (dotimes (counter 10000000)
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 (push (number-to-string counter) result))))
>> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 result= )))))
>> >
>> > The issue is with the second block, it seems like throw-on-in= put is
>> > disregarded when used in run-with-idle-timer. Can anyone conf= irm if this
>> > is a bug/desired behavior or I should use something else if I= want to
>> > run cancelable tasks in on-idle?
>>
>> When the time function is run, Emacs binds inhibit-quit to t (so t= hat
>> the user's C-g would not interrupt the timer function, for exa= mple).
>> And throw-on-input uses quitting to do its job.
>>
>> Why do you need to interrupt an idle timer like that?=C2=A0 The us= ual way
>> of doing this is not to call expensive functions in an idle timer,= and
>> if you have a lot of processing, divide them into small enough chu= nks
>> and do it piecemeal.=C2=A0 That's what jit-stealth font-lock d= oes, for
>> example.
>>

--000000000000f9ce0705a51ba48c--