From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 119702 invoked by alias); 28 Mar 2015 02:24:00 -0000 Mailing-List: contact kawa-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: kawa-owner@sourceware.org Received: (qmail 119676 invoked by uid 89); 28 Mar 2015 02:23:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL,BAYES_00,SPF_PASS autolearn=ham version=3.3.2 X-HELO: aibo.runbox.com Received: from aibo.runbox.com (HELO aibo.runbox.com) (91.220.196.211) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Sat, 28 Mar 2015 02:23:57 +0000 Received: from [10.9.9.209] (helo=mailfront04.runbox.com) by bars.runbox.com with esmtp (Exim 4.71) (envelope-from ) id 1YbgPh-000495-7a for kawa@sourceware.org; Sat, 28 Mar 2015 03:23:53 +0100 Received: from 76-9-71-51-rt-broadband-00.broadband.oakhurst.sti.net ([76.9.71.51] helo=toshie.bothner.com) by mailfront04.runbox.com with esmtpsa (uid:757155 ) (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.76) id 1YbgPX-0004un-25 for kawa@sourceware.org; Sat, 28 Mar 2015 03:23:43 +0100 Message-ID: <551610A8.4070504@bothner.com> Date: Sat, 28 Mar 2015 02:24:00 -0000 From: Per Bothner User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 To: kawa@sourceware.org Subject: Re: Kawa type-conversions References: <550C7D9C.7030102@bothner.com> <3E31B880-0FD8-4C1B-8EA5-15ED388861D7@theptrgroup.com> In-Reply-To: <3E31B880-0FD8-4C1B-8EA5-15ED388861D7@theptrgroup.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit X-IsSubscribed: yes X-SW-Source: 2015-q1/txt/msg00067.txt.bz2 On 03/20/2015 05:05 PM, Jamison Hope wrote: > >> These aren't really consistent: >> >> (if (? x::int 3.4) x #f) ==> 3 >> (instance? 3.4 int) ==> 3 > > I think you meant "==> #f" for the second one (otherwise they seem > pretty consistentÂ…). Right. (instance? 3.4 int) returns #f - which is fine, but (if (? x::int 3.4) x #f) currently returns 3 but should return #f. >> * As an incompatible change, converting float to int should (IMO) no >> longer be allowed for implicit conversions: >> >> (->int 3.4) ==> 3 >> (as int 3.4) ==> ERROR ;; incompatible change >> (define x::int 3.4) ==> ERROR ;; incompatible change > > Agreed, those last two just look weird. But what about (as int 3.0)? > In other words, is it an error to try to coerce *any* floating point > number to an int, or just when it isn't already integer-valued? (in > the R6RS sense). > > We already have `exact', so I don't have strong feelings either way, > as long as (as int (exact 3.0)) works. Likewise, I don't feel strongly about it, but it's easier to implement if (as int 3.0) is an ERROR. One important reason: If instead of a constant you have an inexact-valued expression you want to complain at compile-time. So I think a reasonable specification for (as int XXX) is that it works if and only if XXX has an exact integral type. (It might be reasonable to do range-checking, at run-time if needed.) > Here's one other feature I would like to see, which I *think* fits in with > your description of (convert TYPE VALUE) and (->TYPE VALUE). > > I would like a way to extend the system with custom conversion functions > for particular from/to type pairs. This would be a big help when > interacting with different Java libraries. I agree that could be useful. Of course, if we're distinguishing between explicit and implicit conversions we need to specify which custom conversions are explicit and which are implicit. You discuss an extra search mechanism (convention) for explicit conversion, but I don't understand how that so much more convenient than just re-defining the ->TYPE function. Customization of *implicit* conversion seems more interesting. Since we want static type-checking, that seems to imply that the custom conversion functions must be visible at compile-time. For example something like: (define-conversion (name::T1)::T2 (convert-T1-to-T2 name)) This would get compiled to a static method: public static T2 $convert_to$T2(T1 name) {convert_T1_to_T2(name); } When needing to do an implicit type conversion, the compiler picks "the most specific applicable" (in the sense of method overload resolution) conversion method and compiles in a call to the corresponding static method. I don't know how practical and safe this is. It could certainly easily be abused. > So perhaps (->TYPE VALUE) and (convert TYPE VALUE) could work > something like this: > > 1. If VALUE is an instance of TYPE, just return it. > > 2. If VALUE has a "toTYPE" method, invoke that. > > 3. If TYPE has a one-argument constructor which works on VALUE, > then return new TYPE(VALUE). Actually, we want to prefer factory methods over constructors. So perhaps: > 3a. If TYPE has a static one-argument method which works on VALUE, > named 'valueOf' then return TYPE.valueOf(VALUE). Likewise for 'make'. > > 4. Otherwise, starting with VALUE.getClass() and working up to > java.lang.Object, look for a function "FQCN->TYPE". If one > is found, then invoke it. > > Implemented interfaces should probably be in that search list, too, > and I'm not sure what to do about type aliases. I used > "xxx->complex" for the function names in that example, but maybe it > should be "xxx->gnu.math.Complex". -- --Per Bothner per@bothner.com http://per.bothner.com/