From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Arthur Miller Newsgroups: gmane.emacs.devel Subject: Re: Declaring Lisp function types Date: Sat, 16 Mar 2024 08:46:24 +0100 Message-ID: Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="33798"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: emacs-devel@gnu.org To: acorallo@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Mar 16 09:28:01 2024 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 1rlPOa-0008Yg-CX for ged-emacs-devel@m.gmane-mx.org; Sat, 16 Mar 2024 09:28:01 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rlPON-0005uG-W9; Sat, 16 Mar 2024 04:27:48 -0400 Original-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 ) id 1rlOkV-0008Lv-C2 for emacs-devel@gnu.org; Sat, 16 Mar 2024 03:46:35 -0400 Original-Received: from mail-dbaeur03olkn2070.outbound.protection.outlook.com ([40.92.58.70] helo=EUR03-DBA-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 ) id 1rlOkT-0001Br-6F; Sat, 16 Mar 2024 03:46:35 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YtCkn/I/ICXgVyEpTnIGUF7J4LPlfrryyLGLuX3zaWhV2/13irP+75dss0FeHucV8YFt3BI0ViZJN//p2zXQJStZ9TZ4bc0cZGKG8JkiqUBOv4Rah8f+lL0nXbdadNm4c4qwGZc0MludeydypKoHobjSsjdurcWdpUQTWTaQ0ZNzxLn5aPB3Jpsp++4G4X+bMGy+WLLpYOZgKFqItTbzjJtpQnzKxeyn/mQimr4ddE4zgMlwkLrgruaorjSeoSt0QsJJrOBZZkGlbAQNqLABv/NqsjgJa5Vx0DpbOK7RQEIj8Xln88TZpHzht3HYjshptqi70AzUInOHb/GQzmVM2A== 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=dJdj9f2qcGu9/XymLk80tfG87G97GxowtlEMVTFWESI=; b=FBmYX1ShP68ZtiRJr2FS6lBn8njh8GeHdwW6Kh6PLqvXfqdK5ulqOhZ8XkukcY8Hkds8x2bpFDxHGitCH+46MY5uMhb10Zmk8anE/wftzXdlOb2yvDkbLV3WzG6aDGKg5pwYs0M1ArtU/U2nSEmTlXpz0vNAIc91x98ZGRUtD9oLRRrh1rb9xzKvaelL5Mr4Qos0S8ShiiRuLf9NzZve4VG8sf3P4wq9YOynWxiVv2ggdpU6MaTj2OSPC55ObugOAZDsrQaqzTQl4VL6TzYuzsdYyzcDB0H1V+3EywdhMfFa7CFZ3JFiLQiznkHdeAkk5d38lZddrwIz/Kn3fUrgxQ== 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=dJdj9f2qcGu9/XymLk80tfG87G97GxowtlEMVTFWESI=; b=kih6V54w2NMnq5JbwT1IzIQniqqbLz2PQB4nPZ9ERVV4I6P3UhT6IwZsDh6P218e+RmQKSzmmYOhGu906rgytpFPszphyfa6z4u8TahuyMuNvWBu+6YmvEQwMEygOKotOIoJron8TIEb8Cu9gjFRxgaOUNYZOpmmy10ROtPfG3Wr7yaJPgC2d/+bQ8alXW3fkH/AFXSLqnDnwJMI1w+6VuQjjn6zlRGkWpQthNFPCYMngUI/gE/Cx+HQRb606SOWo7wmtMjM4Kfn2WH8Jfk0f3M9cw70Qwqp//ITHQXIfkymz8zfrd/HHParTWJjIzhZ1+sEZ/3EM5WvH/FRsic4jA== Original-Received: from DU2PR02MB10109.eurprd02.prod.outlook.com (2603:10a6:10:497::14) by DB9PR02MB6634.eurprd02.prod.outlook.com (2603:10a6:10:21a::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7386.21; Sat, 16 Mar 2024 07:46:27 +0000 Original-Received: from DU2PR02MB10109.eurprd02.prod.outlook.com ([fe80::9549:47fe:660e:4d02]) by DU2PR02MB10109.eurprd02.prod.outlook.com ([fe80::9549:47fe:660e:4d02%4]) with mapi id 15.20.7386.020; Sat, 16 Mar 2024 07:46:27 +0000 X-TMN: [lpMhcmXOTXShdxI+z/5Cz6631FmfoKm7IH9xgnMejyQ=] X-ClientProxiedBy: OL1P279CA0009.NORP279.PROD.OUTLOOK.COM (2603:10a6:e10:12::14) To DU2PR02MB10109.eurprd02.prod.outlook.com (2603:10a6:10:497::14) X-Microsoft-Original-Message-ID: <87zfuyfwkv.fsf@live.com> X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU2PR02MB10109:EE_|DB9PR02MB6634:EE_ X-MS-Office365-Filtering-Correlation-Id: 903dd0d5-81b2-4c92-78a4-08dc458d2f62 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 38/VAJBj8FJ/npQDln+6/d3J5IBP3AwBMCjXo6fcObyTGCfgiXpboB9q3X5QStZbSmhfz4PYsnpHGftxBS1uUTQ7JAPYh/QGwaYnHN204ieayOLZPfAJu4R7uQcmSWa0JPSlLg9gM6yOra4K56q5cSXF022QRFsHfnhXRTGvVeo6GC5+6hLEd60f6KFXAJWulGUnAX91OhcFp/b/F/V8pPxdt7C9ZIA8MipbtAMjYJZ2Ix2qH2LxRzSYeRf2YlSgICwx9tWWuKuPmBrJGHw9YT9m2c+L73UA4ZiHBh+jPkK9dG6Cx/HvkgcWtq5jhhj7qErPotApuzlODLz07+jAQRZJQMeW628LeGuo7b2t7I0+j5kcITwsh6mOXzJEjm1+VnlaeUN3ID8E1118uj5vTI+iRldkVqv2FduQtVybcuMO3zKKyMCEDJMi8xeM428vHJXTYZH77GuSOK4P5gVQjrXEhUQACLlrDJT2Sc2HQN+uijHGOePqvZ1NMjpwDz9IJHlK29rx2ZwjmBmPaa18SnJVuEpcscKvxxpu6zQ7NqHvnyJoL1FVnEDOmBKjYZgM X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?N1BId0JORmVUL3E4N2wzYWNhRFp3Mk1DczNDTVpJaisyWjczV05TbnlrWFY4?= =?utf-8?B?TFkrOWVGTlhEZHNTQ1p0QnlPdW9XU05JRFBmR21GSCtweVNVRGgxOHI1OWNs?= =?utf-8?B?OVltN2pxMUx6NU5QaUFJQStzZmpvTWNraGFRMFR1N284M1VxbGZQT0xzclJy?= =?utf-8?B?R056N1NtTzdVZlc3QTRlc05lVS9CL2pLZnJKYmNMQi9vNnRMUE5HRnR0N0xy?= =?utf-8?B?MXN5SDF3elpySTVCcEhrR1hZNGpCeVFDUVlnQUVPdmhSOERDczdxRld0Zk9R?= =?utf-8?B?VDN3VEwxdnRTRUQzTXhSZDFNVlJaWVdiMmJTR0ZwaWw1TVNDbytEQWJGZ05o?= =?utf-8?B?Wkk4VjFFNklIZUNVN1kxTm9Zc3dhckF2ekFYWkRCb3VwTmFJUzBieXl0cTQ0?= =?utf-8?B?QzF0Rmo3SlNTRXJVVDZzK3FQQ1pBbVg5ZSs4eStyTENwQjhXWG8vajVKclBu?= =?utf-8?B?a0pmdUhVVlViNmhaRHNxU3l6bkRielZHMktBLzJ1WWRPZlhkUHpscEJWT0xI?= =?utf-8?B?bUNwSGNEV2NUckw1Y3lrMExtb2NURWJwZHJEcVFqeDBUaTdLcnVzZzlWalJk?= =?utf-8?B?LzBHNE0xY1JQMkc1SHgzZ2sycGVpYVBabTdmSHl0Y0N5bGFabVhiNE5DZUtl?= =?utf-8?B?ME1TN3VzNXg2TGVrVExpTVdtMlNvckxtL1A4Wk X-OriginatorOrg: sct-15-20-4755-11-msonline-outlook-ab7de.templateTenant X-MS-Exchange-CrossTenant-Network-Message-Id: 903dd0d5-81b2-4c92-78a4-08dc458d2f62 X-MS-Exchange-CrossTenant-AuthSource: DU2PR02MB10109.eurprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Mar 2024 07:46:27.0627 (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: DB9PR02MB6634 Received-SPF: pass client-ip=40.92.58.70; envelope-from=arthur.miller@live.com; helo=EUR03-DBA-obe.outbound.protection.outlook.com X-Spam_score_int: -5 X-Spam_score: -0.6 X-Spam_bar: / X-Spam_report: (-0.6 / 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, FAKE_REPLY_C=1.486, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sat, 16 Mar 2024 04:27:46 -0400 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 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-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:317100 Archived-At: Stefan Monnier via "Emacs development discussions." writes: >>> (declaim (ftype (function (integer integer) integer) sum)) >>> ;; ^^inputs ^^output [optional] >>> (defun sum (a b) >>> (declare (integer a b)) >>> (+ a b)) >> >> Non-starter for me: the separation into two steps makes it unclear what >> the declaration applies to (e.g. when re-running the above code, does >> the `declaim` apply to the old definition (the one active when the >> `declaim` is executed)=C2=AE the the one that's about to be installed)? >> >>> ;;2 >>> (defun sum (a b) >>> (declare (integer a b)) >>> (+ a b)) >> >> None starter because of how we defined `declare`, where we'd have to >> define every existing type as a valid declaration idenitifer. >> >>> ;;3 through 'defstar' (a CL library not in the standard) >>> (defun* sum ((a integer) (b integer)) >>> (+ a b)) >>> ;;4 again through 'defstar' >>> (defun* (sum -> integer) ((a integer) (b integer)) >>> (+ a b)) >> >> Acceptable, with some tweaks to better fit my favorite bikeshed color. >> >>> (defun sum (a b) >>> (declare (ftype (function (integer integer) integer))) >>> (+ a b)) >> >> The `f` of `ftype` is redundant with the following `function`, so we >> could shorten that to: >> >> (defun sum (a b) >> (declare (ftype (integer integer) integer)) >> (+ a b)) >> >>> (defun sum (a b) >>> (declare (function (integer integer) integer)) >>> (+ a b)) >> >> It's cute, I guess. Whether to prefer `function`, `ftype`, or Adam's `t= ype`, >> is largely a "bikeshed color" choice. I do prefer the latter two >> because we already know that this is a function, whereas we don't know >> that this is a *type* (and they're shorter, to boot). >> >> Later you said: >>> Fact is, we already use the form (function (ATYPES) RTYPE) as type >>> specifier for functions. So (ftype (function (ATYPES) RTYPE)) would be >>> the most correct form semantically, where `ftype` (or `type` or really >>> what we prefer) would be the declaration which takes the type specifier >>> as argument. >> >> Of course (declare (ftype (integer integer) integer)) >> would still end up generating something like >> >> (foo-declare-type 'sum '(function (integer integer) integer)) > >My fear it's this is a bit more convoluted and this extra step makes it >less understandable/justifiable. I like the symmetry of having >'function' both in the input (the declaration) and the output (the final >type itself). Maybe my background as physicist makes symmetry too >central for me? :) > >> so I see no semantic issue with using `ftype` or `type` here, unless >> there are functions whose type could take another form than (function >> )? Are you thinking of types like >> (or (function (int) int) (function (float) float))? > >That's a good example why it would be good to be able to accept the type >specifier as a declaration with no tricks. On the specific case I'm not >sure we want to support this in the inner machinery (at least for now). > >> More important I think is to document what such annotations mean and >> what they should look like (currently, this is not super important, >> because the annotations live together with the code that uses them, but >> if we move them outside of `comp.el`, the "contract" needs to be made >> more explicit). >> >> - How they interact with `&optional` and `&rest` (or even `&key` for >> `c-defun`). > >ATM we already support in type specifiers `&optional` and `&rest`: > >(subr-type (native-compile '(lambda (x &optional y &rest z)))) =3D> >(function (t &optional t &rest t) null) > >Not sure we want to handle &key as well as it looks to me not very >native to the elisp machinery. OTOH cl-defun just expands to the native >elisp call convention. > >> - What will/could happen if one of the arguments does not have the >> specified type? > >I think if ones does a declaration has to declare the type of all >arguments (rest should be optional). > >> - What will/could happen if the result does not have the >> specified type? > >I think we want to complete it with the inferred return type if we have >it or t otherwise. > >> - Do we have types to say "arg unused" or "no return value"? > >We don't have "arg unused" because the function type (or signature) is >like the contract with the outside word, it should not matter how (and >if) and arg is used inside. > >OTOH we have "no return value" and it's nil > >(subr-type (native-compile '(lambda (x) (error x)))) =3D> >(function (t) nil) > >> - Can we have higher-order function types, like >> >> (function (proc (function (proc string) void)) void) >> >> and if so, again, what does it mean in terms of what can happen if the >> runtime values don't actually match the announced types (e.g. what >> happens (and when) if we pass a function that has the "wrong type")? > >I don't kwnow if we want to allow this to be future proof, ATM certanly >the compiler does not use it and I don't think it could help code >generation. OTOH might be nice for documentation? > >As a note: AFAIR SBCL doesn't go beyond something like: >(function (integer function) function) > >That if arguments/ret values are functions it forgets the inner details >of their type specifier. > >Anyway I certanly agree we should better document this once it's shaped, >and I'll try my best. > >But generally speaking I've the feeling there might be other cases we >don't see ATM where accepting directly the type specifier as valid >declaration graciously/naturally solves potential issues we could hit >otherwise. > >Thanks Please, if you can, just (re)use SBCL syntax. It makes life easier for those who are already familiar. Those who are not have to learn something new anyway, so for them it does not matter. Great work, thank you working so much with this. best regards /arthur