From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <emacs-orgmode-bounces+larch=yhetil.org@gnu.org>
Received: from mp11.migadu.com ([2001:41d0:8:6d80::])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
	by ms5.migadu.com with LMTPS
	id oIihCE7A52NwfAAAbAwnHQ
	(envelope-from <emacs-orgmode-bounces+larch=yhetil.org@gnu.org>)
	for <larch@yhetil.org>; Sat, 11 Feb 2023 17:20:30 +0100
Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
	by mp11.migadu.com with LMTPS
	id CAatCE7A52MrCAAA9RJhRA
	(envelope-from <emacs-orgmode-bounces+larch=yhetil.org@gnu.org>)
	for <larch@yhetil.org>; Sat, 11 Feb 2023 17:20:30 +0100
Received: from lists.gnu.org (lists.gnu.org [209.51.188.17])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(No client certificate requested)
	by aspmx1.migadu.com (Postfix) with ESMTPS id A8F46386AE
	for <larch@yhetil.org>; Sat, 11 Feb 2023 17:20:29 +0100 (CET)
Received: from localhost ([::1] helo=lists1p.gnu.org)
	by lists.gnu.org with esmtp (Exim 4.90_1)
	(envelope-from <emacs-orgmode-bounces@gnu.org>)
	id 1pQsbH-0003Ph-43; Sat, 11 Feb 2023 11:19:43 -0500
Received: from eggs.gnu.org ([2001:470:142:3::10])
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <arthur.miller@live.com>)
 id 1pQsbF-0003PZ-Lr
 for emacs-orgmode@gnu.org; Sat, 11 Feb 2023 11:19:41 -0500
Received: from mail-db3eur04olkn0810.outbound.protection.outlook.com
 ([2a01:111:f400:fe0c::810]
 helo=EUR04-DB3-obe.outbound.protection.outlook.com)
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <arthur.miller@live.com>)
 id 1pQsbD-0006xx-7D
 for emacs-orgmode@gnu.org; Sat, 11 Feb 2023 11:19:41 -0500
ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
 b=dlqRmXMcFgr+5DBGuk6eQEgzYXMoEgo+5jXtcmxm9T5yCJ1GsUxPH1yIeaao72RYYrEAf5GTKqm8o8VW0O5knBe28DyKxTMWA9GMpHYPHVETkHWym16xCCedX/48f1pkaaqwFubiFWYcnzqTErtefBCf+vwkh3oLFeX5mDa/j9f2BndOLaqWy27k5o3Qw7VH+Q84KQTZ6nBK80w0AVU9dtwYWPeRGpfcyJkEUBHdsyiTsxeNJfH/44vYi9YC3F0hvON4TKVNofgc3MpxvGfZVj6m1asN4j1K+vmWKfqjE15WN1099xa06o/L9hpEFLTXaYTnGJXrRlFIQ5kg6neTlw==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; 
 s=arcselector9901;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;
 bh=/Lcxx7XxmODNauiS+Bf2IVSI+WKJ/AzRFSAQDO86a7w=;
 b=Uptid8i0lYMl9fmYmJyHI1MLIN1+Rd44cn+Pba7jEexJgQbopQE5KKBCD2XBMH/fuPqaxFyCVlzM9lcnBlh79vYbLCHwtIvCjIV5Lv7bXsDx+YcqqgSzmi4CUQrZ7ozvOYZMU7X1Wh9TEqGq4ahKZD28/6Z73l4eKikkxY5SqFHuBK7onCaMsz2gKm9PEneMolsqXfvmVVVivf/k0C1O4gQDN6QP75zgYOh1VxJ3m+oJq6c61U6pi4V01J9u2sgtGsxKgezgxb8DioQlPrflldXGD1UUStfWYAIpDMNXMoK75ybnONQtjoFQrj0icvNw/eOaYbAZTMsFNYAPAzjvPw==
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none;
 dkim=none; arc=none
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=live.com; s=selector1; 
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=/Lcxx7XxmODNauiS+Bf2IVSI+WKJ/AzRFSAQDO86a7w=;
 b=dewQDa+LhrUq6CQ+ezC6QMOPigTJzXdqHXkvZvO0G2nceOZZygttNZ09K2fuDQZlmKDC7dI9mUmbPwyX+pPqFcbt1tO+SfL0DlPZSvDJvrFzu0LtYPpT7usrv9SEbxuPVDj82xTBr1A0XmY2terNxM7Kv7BV72xxtECUluZlhHv3mppeRa1/MYqIJV1EZkts3OqW+ujAMxQrF6CqvzpsMFEy48mJLFnalTWME3jtmr/8jVp3F1muDrDtujella4hdBx0OEZwQNnS/UMTzghhcHe/UhP+QWVUyKyQR0eB4mVaoSlFCvKba5tFKPayyOdd7v5U0z4u0if9D4pw1mvw3g==
Received: from AM9PR09MB4977.eurprd09.prod.outlook.com (2603:10a6:20b:304::20)
 by DBBPR09MB4602.eurprd09.prod.outlook.com (2603:10a6:10:202::17)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6086.22; Sat, 11 Feb
 2023 16:14:34 +0000
Received: from AM9PR09MB4977.eurprd09.prod.outlook.com
 ([fe80::f2af:9752:58df:ad9]) by AM9PR09MB4977.eurprd09.prod.outlook.com
 ([fe80::f2af:9752:58df:ad9%7]) with mapi id 15.20.6086.022; Sat, 11 Feb 2023
 16:14:34 +0000
From: Arthur Miller <arthur.miller@live.com>
To: Bruno Barbier <brubar.cs@gmail.com>
Cc: emacs-orgmode@gnu.org
Subject: Re: Problem with let/cl-letf binding stuff with org-capture
In-Reply-To: <63e74a8b.df0a0220.7f45d.5b05@mx.google.com> (Bruno Barbier's
 message of "Sat, 11 Feb 2023 08:58:01 +0100")
Message-ID: <AM9PR09MB4977306B77F9A5338764324596DF9@AM9PR09MB4977.eurprd09.prod.outlook.com>
References: <AM9PR09MB4977E7E66F2E6BD0345DF46496DE9@AM9PR09MB4977.eurprd09.prod.outlook.com>
 <63e69450.050a0220.9052f.652e@mx.google.com>
 <AM9PR09MB4977E771D98F9997736E0B7F96DF9@AM9PR09MB4977.eurprd09.prod.outlook.com>
 <63e74a8b.df0a0220.7f45d.5b05@mx.google.com>
Date: Sat, 11 Feb 2023 17:14:32 +0100
User-Agent: Gnus/5.13 (Gnus v5.13)
Content-Type: text/plain
X-TMN: [bYqj6aowCzX3RvqDByOxSMYYw/96R2my]
X-ClientProxiedBy: MM0P280CA0013.SWEP280.PROD.OUTLOOK.COM
 (2603:10a6:190:a::19) To AM9PR09MB4977.eurprd09.prod.outlook.com
 (2603:10a6:20b:304::20)
X-Microsoft-Original-Message-ID: <87o7q0ryfc.fsf@live.com>
MIME-Version: 1.0
X-MS-Exchange-MessageSentRepresentingType: 1
X-MS-PublicTrafficType: Email
X-MS-TrafficTypeDiagnostic: AM9PR09MB4977:EE_|DBBPR09MB4602:EE_
X-MS-Office365-Filtering-Correlation-Id: b4409da3-ed2f-467d-edf2-08db0c4b106c
X-Microsoft-Antispam: BCL:0;
X-Microsoft-Antispam-Message-Info: wOzEECQnZkYLghEj1R0lRTw0VUT2D2eiQTby1OJsEAQJd+0ye385O+J/DDX72gWK+nKSDgC4HawvJppNOV/Spw1cFxPFF1oMm35Y4xmsFvKVYjP6beao4IAHvM7RTmBX2YaY0IqcCbTNqqMmGptO9DhGisM7kGtV57Ecb2ypCIvN0fD47Yy8MTAnRB3wNUzCSnYLnF6gXgcbGslffYNZwrYUUgomqYJ/c7kFK2XfKkBFUK+dNliZ7B8eXeZunhZFhPCcFsFg9pDWjTummjvxSw9bFI6lUtukL5cO6g19hC9CCXSHeXKnCjvjcUWgGI4B3pWm3Zr4iCXrfBEWLuFc1l3YDdGMcD7dIzUVZQGruPBjYygHiItP/ttk5CfNkZFoSgNSgZndUVEOaAblAXQh8k6y5uqJSxi2POmKjHAWzHmf1hEojf8dvfitJNuCgNX7Ql5gwV4qrz44OMkg8OmWzlRLSQkZna2dAncUXMvnqOYWjzO/WAMfkwao/YGU/6ck+7kFqki0eRK6GZCCsITxSrYZoy/a6lH3i1BQLUGVkIdy21GtPWBojR1MlZX8vuvzX1UlMKfknoYU/abeN7KYFkKXsest8NfKo7WXLiXuOBFAtGJkqawOauHV/tQNqKzKmaMi+SFpkmE8YuHGvpaLlq51gmd+zlz8WiZZYhVAjBs=
X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1
X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?rFUcfo8HXZlpFuMjl4gQxz8l/Weq26oTQDQZpUyaiXt0Lu9lXth6PPFmYKMm?=
 =?us-ascii?Q?FpbE/aXObvr7UCkzJFcoByl87GRwj69dJaYF36rzNjyfXazsf+H3qHV/3Mo7?=
 =?us-ascii?Q?ll9fMXMQT7f7obYhKtaGkAeArpfFeZqldZXa91P3evdyVOElvZ+iTpQlqsS7?=
 =?us-ascii?Q?HG7e9ejm9fKMyuFxcz0UiU6dioRZHIfUsi6RYhr6lrvnvmI1eO+6MkDl4K/B?=
 =?us-ascii?Q?PiOhz3bU/+ubAnJtFQr+UPAF+uxk7lqVtDgyUe3RPJn14WIbMGkJH4Pt/ovN?=
 =?us-ascii?Q?cnIaqNE7CQuMGV3v2HigIFp3NVlx4XrbODwDLjvGXqxg4sI+aniMglrYq9/Z?=
 =?us-ascii?Q?Xtk4UKyGkEOOmdmJS0xK4GSl2kdiIrArsT1jWVlBLl4gqlDcLLXfzWTl+PDX?=
 =?us-ascii?Q?ZhRNVvClAflAD9auQ4Trlc0i1FRz9IX/oKlTvCFbbct0P12yJK/aj5BHnGE3?=
 =?us-ascii?Q?HLiLdnjAmWlG6cXrn2ahhD3+cm+duY6eL9hJbCJC9S3sny2y3NBHASTeEvn1?=
 =?us-ascii?Q?Jk5vz8Pz416xeig4l25fhNwwVUbI5lrkuoDtIqkjRy06W5dvjJVeGmiCYL5/?=
 =?us-ascii?Q?Ve92IewoPivpBHPfWuNX99IH0Lnodt+igiCJZ9r/7xJYziaokZRq/QMSvZ2+?=
 =?us-ascii?Q?TZRJrERqDgj8HhvguiwMXICvvFOvc5a8XsqZ+U0Djx5jYCBhCKMff1IpoOwU?=
 =?us-ascii?Q?1TiN+v013b0NuWWBqPtw4TEql/UUp/RXaJVgQKXeCbCJ4e4+nH3RjwzRcPT4?=
 =?us-ascii?Q?edLu/G5qOawbl1cdJYXEk1b5/3X2oHq+ZfkHPsqs7LOZ/kysgvVdlxsBcZfb?=
 =?us-ascii?Q?MMob0Xplq8fClcbgtNS98XvHreD7pLfHs3RSxTvVzcQZrNexXmdGvwBL77e9?=
 =?us-ascii?Q?X5Jn8X/zBbTEoOCxCRkPLL82rIk3Nduh853cSPD6VfVfXrRSCnUkAONeVqFg?=
 =?us-ascii?Q?yZ0RyiK6rNQYI+NN36EPNh5mxFylgAgDtnbA0Et/+XjnF4G3n/x7BqLEMuA9?=
 =?us-ascii?Q?Dqa19NPj24mfMssLGCwugYs2kxrSW0DAqtQZhbbD1KTOOcr1fmSxIolZFtIp?=
 =?us-ascii?Q?Odn1bcjhhQpH79JeWdhRqkiG1//17OnPQycWZmVPdrpTJ4gUuy458emuldXV?=
 =?us-ascii?Q?kOfq3u5gjWIrdmOu1gnxbd87JD43dTzepQQJrBmSGHXkT71+glsOBk0UhySg?=
 =?us-ascii?Q?ep+wW4Cj5afBldwo+MGfMVcm/77z4iyv4+4dc0UGHjFfDr6DMO0iWwKGUA7i?=
 =?us-ascii?Q?aoIxwqw+F2HfsqMvMFipxO3cx+HYUCKosuuwH1Jefg=3D=3D?=
X-OriginatorOrg: sct-15-20-4755-11-msonline-outlook-64da6.templateTenant
X-MS-Exchange-CrossTenant-Network-Message-Id: b4409da3-ed2f-467d-edf2-08db0c4b106c
X-MS-Exchange-CrossTenant-AuthSource: AM9PR09MB4977.eurprd09.prod.outlook.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Feb 2023 16:14:34.5086 (UTC)
X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted
X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa
X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000
X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBBPR09MB4602
Received-SPF: pass client-ip=2a01:111:f400:fe0c::810;
 envelope-from=arthur.miller@live.com;
 helo=EUR04-DB3-obe.outbound.protection.outlook.com
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,
 SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no
X-Spam_action: no action
X-BeenThere: emacs-orgmode@gnu.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "General discussions about Org-mode." <emacs-orgmode.gnu.org>
List-Unsubscribe: <https://lists.gnu.org/mailman/options/emacs-orgmode>,
 <mailto:emacs-orgmode-request@gnu.org?subject=unsubscribe>
List-Archive: <https://lists.gnu.org/archive/html/emacs-orgmode>
List-Post: <mailto:emacs-orgmode@gnu.org>
List-Help: <mailto:emacs-orgmode-request@gnu.org?subject=help>
List-Subscribe: <https://lists.gnu.org/mailman/listinfo/emacs-orgmode>,
 <mailto:emacs-orgmode-request@gnu.org?subject=subscribe>
Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org
Sender: emacs-orgmode-bounces+larch=yhetil.org@gnu.org
X-Migadu-Country: US
X-Migadu-Flow: FLOW_IN
ARC-Authentication-Results: i=2;
	aspmx1.migadu.com;
	dkim=pass header.d=live.com header.s=selector1 header.b=dewQDa+L;
	spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org";
	arc=pass ("microsoft.com:s=arcselector9901:i=1");
	dmarc=pass (policy=none) header.from=live.com
ARC-Seal: i=2; s=key1; d=yhetil.org; t=1676132429; a=rsa-sha256; cv=pass;
	b=sw6na/D/hBL3zqmRV2tP47E1mTir8O9c2BffMmKAb/XJyCFPLoR4INfSjnOw8La77DFnD+
	lgds+bCWoQUis56s752gR4uv0n/CTJP+rhUZAoDlMEjcJpSdoFuefb9Ncec09EuSbhWpjm
	avgWDJkpK20trntVDnpy+8wD6aN9+c1enSAxxznTKWIV659A6SAA/tvzJUUY52X7Bg56YO
	rW0RMXVnSOz1bkVu6WIHbLG90K/zUU1izvRyiRrKODfsFUf0bsRndBNJCnnjL/4liTh4zz
	3figXCeYWHORZCxBjn7NqBB8rd3JJ5zrp1Dyj4k7LcH7b6p7/5zu2lQ/lQQnBQ==
ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org;
	s=key1; t=1676132429;
	h=from:from:sender:sender:reply-to:subject:subject:date:date:
	 message-id:message-id:to:to:cc:cc:mime-version:mime-version:
	 content-type:content-type:in-reply-to:in-reply-to:
	 references:references:list-id:list-help:list-unsubscribe:
	 list-subscribe:list-post:dkim-signature;
	bh=/Lcxx7XxmODNauiS+Bf2IVSI+WKJ/AzRFSAQDO86a7w=;
	b=FSSFF/l61ytLPHUD5Bp9dXh3ownWQHuzSwIL8UvzcnlwmAilI97CV6ghIv5CxK80g/FrQx
	xh5mqKJZGgimTdnrdiMNp1ho3dN5b05HxDv5ipMce/f8lX5Mkc+oaku3VL0Y+3XRH5tcjG
	0uQeBdfYiU2rTg21rjPbvr0NJIQVKFhZ7wPdEpVeb/MYntqtuCMWT2AXisbvrUljs1uMw4
	saf1if+m7s+vLwFQci9QsW/9JrRmMgnNhgunj8ZnGK+4rkhvoHneSDjePz62L6RIbAHpPb
	b8IK7YhiagPbdamVbO2t+59hcTApD5FTWEF6rkwi7n2GeoyJ6wbztCKABrQbxg==
X-Migadu-Queue-Id: A8F46386AE
Authentication-Results: aspmx1.migadu.com;
	dkim=pass header.d=live.com header.s=selector1 header.b=dewQDa+L;
	spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org";
	arc=pass ("microsoft.com:s=arcselector9901:i=1");
	dmarc=pass (policy=none) header.from=live.com
X-Migadu-Scanner: scn0.migadu.com
X-Migadu-Spam-Score: -12.67
X-Spam-Score: -12.67
X-TUID: 3GXkYVW5SzSU

Bruno Barbier <brubar.cs@gmail.com> writes:

> Arthur Miller <arthur.miller@live.com> writes:
>
>>> Bruno Barbier <brubar.cs@gmail.com> writes:
>>> If you really want to just get the piece of text, you might be able to
>>> use the hook `org-capture-mode-hook' to replace the key binding to
>>> 'C-c C-c' in the capture buffer, so that it calls your own function that
>>> will take the string and call `org-capture-kill'.
>>
>> In this case you wouldn't like to replace the key binding, it would affect all
>> org-capture buffers; the point is just to replace it when called in certain
>> context (my-read-line). Let-binding the function in this context achieves
>> exactly the same effect of C-c C-c beng bound to my function but without
>> affecting all org-capture-buffers.
>
> The hook `org-capture-mode-hook' will be run in your special
> capture buffer. You can override the "C-c C-c" binding only there.

Yes and in every other capture buffer, so I would either have to test on some
variable, make another mode, or mode-map or something similar. Just to customize
on the key, instead of the value bound to that key.

>>
>> Yes, I am aware of both hooks and advising; but again, with those I would affect
>> all uses of the function, and that would lead to checking some global state or
>> variable to switch on, which is not optimal either. With let-binding we can have
>> different behaviour only in a certain context.
>
> Even if I could let bind the function at the right time, I would avoid
> that solution, as I can't garantuee that this global hack will not break
> other parts of Emacs (other captures, output filters, threads, timers,
> etc.).

Why do you think it will break other parts? This is not a global hack, on contrary it
exactly tries to prevent to be "global" in entire Emacs, by let-binding a name
to a local lambda, which becomes "global" only in that buffer. If that
explains.

Here is another version on the same theme, where I don't think you could modify the local
environment without let-binding at all:

#+begin_src emacs-lisp
(defun my-read-string (prompt)
  (let ((delta 20 )
        (minibuffer-mode-map org-mode-map))
    (window-resize (minibuffer-window) delta)
    (cl-letf (((symbol-function 'org-ctrl-c-ctrl-c)
               (lambda ()
                 (interactive)
                 (let ((s (buffer-string)))
                   (exit-minibuffer) s)))
              ((symbol-function 'minibuffer-mode) #'org-mode)
              ((symbol-function 'minibuffer-complete-and-exit) #'org-return)
              ((symbol-function 'org-kill-note-or-show-branches) #'keyboard-escape-quit))
      (read-string (concat "# Press C-c C-c to continue, C-c C-k to cancel\n# " prompt "\n\n")))))
#+end_src

read-string is written in C and creates its own minibuffer, which is deleted by
the time read-string exits. I don't know of any other way to cutomize exactly
*that* minibuffer, without installing a hook or advising some functions, which I
think is way less clean and much more "global" than just running the function in
a local environment. As I understand, let binding for this purpose is a normal
technique in lisps, but I am not an expert as said; I am actually experimenting
with this for the purpose of learning and seeing what is possible.

Of course, we can always write our own read-string function and re-implement the
function from scratch, which author of that blog actually did. The experiment
was to test if I can modify the existing functionality to re-use, rather than to
re-invent something. Since read-string functions does not let us specify buffer,
mode, etc, let binding is one way of doing it locally.

Considering how org-capture works, the same technique of just modifying the
local environment is not really applicable; now when you reminded me that
capture buffer lives longer then let-binding, I understand what happens. I can
access the buffer after org-capture exits, in my-read-string:

    (with-current-buffer
        (try-completion "CAPTURE" (mapcar #'buffer-name (buffer-list)))
         ( .... do the thng .... )

but I am not sure if I can do anything here without introducing at-least an
extra keymap, to not install into the org-capture-mode-map, so I can as well
create a minor mode, but at this point it is not much different than
re-invinting the read-string, so I'll terminate my experiment here :).

But I wouldn't speak in some generic terms like "use hooks" or "advise" instead
of let-binding. Let binding is a powerful and legitimate technique to modify
local environment of functions. I am not really sure where it stands in
abstraction, if it is sort-of template, or interface programming, since I am not
that familiar with lisp (yet), but I do understand it has very good and powerful
uses. Consider this (you can actually eval an run from gnus, or in scartch):

#+begin_src emacs-lisp
;;;; Project folder - org-capture related code
(defvar org-project-root-dir nil)
(defvar org-project-templates nil)
(defvar org-project-finalize-hooks nil)

(setq org-project-templates
      `(("W" "Web Projects")
        ("Wb" "Bootstrap Project" plain
         (function org-project-new)
         "A Bootstrap Project")
        ("Wh" "Web project" plain
         (function org-project-new)
         "Simple HTML Project")
        ("C" "C/C++ Projects")
        ("Cc" "C Console Project" plain
         (function org-project-new)
         "A Command Line Project with C")
        ("CC" "C++ Console Project" plain
         (function org-project-new)
         "A Command Line Project with C++")
        ("CG" "C++ GLUT Project" plain
         (function org-project-new)
         "Simple GLUT Project")
        ("CQ" "C++ Qt Project" plain
         (function org-project-new)
         "Qt Project")
        ("CK" "C++ Qt Quick Project" plain
         (function org-project-new)
         "Qt Quick Project")))

(defun org-project-new-project ()
  (interactive)
  (let ((org-capture-templates org-project-templates))
    (org-capture)))

(define-key global-map (kbd "C-S-n") #'org-project-new-project)


(defun org-project-new ()
  "Interactively create new directory for a project.

Directory should not exist prior to call to this function."
  (let ((project-path (read-file-name "Project name: "
                                      org-project-root-dir
                                      nil nil nil)))
    (cond ((not (file-directory-p project-path))
           (make-directory project-path)
           (let ((file-name (concat (file-name-nondirectory project-path) ".org")))
             (find-file (expand-file-name  file-name project-path))
             (goto-char (point-min))))
          (t (message "Directory %s already exists." project-path))))
  (if org-project-finalize-hooks (run-hooks org-project-finalize-hooks)))
#+end_src

The only extra work I did, was to actually create an interactive function to
specify a path, and I can re-use both org-capture template language and
interactive functionality already built into the org-capture. I get an entire
framework for free :). The real action is happening in hooks, where I init git,
copy some templates, license and some other boiler-plate stuff.

I don't know what would be the alternative, but let-binding on
org-capture-templates, let me clearly re-use the functionality without polluting
the global org-capture-templates variable and without re-implementing pretty
much anything.

As I understand, let binding is useful in lisp, and as legitimate technique as
hooks, or advices. As said, I am not an expert, but I think, it is probably
preferrable to advising, where possible, since advising is global to all
function instances, while let-binding affects only local function instances, if
I can borrow some of OOP terms here.

I am very interested to hear more on the topic, since I would definitely like to
learn more about different techniques.

Hope that explains a bit more on the background of the experiment :).

best regards
/a