From: Tamas K Papp
Subject: communicating return type of a function
Date: 
Message-ID: <6n3chiFjhip2U1@mid.individual.net>
Hi,

Frequently I encounter calculations where I fill a vector (or array)  
using a function (maybe mapping from another, but not in the example 
below).  Most of the time the return type is one for which it makes sense 
to use an array with a specific element type, say double-float, but not 
always.  I can specify the resulting element type manually, but it would 
be neater if the function could communicate it somehow.  For example, 
consider

(defun vector-fill (n function &optional
                   (return-type (return-type function)))
  (declare (function function)
	   (fixnum n))
  (let ((result (make-array n :element-type return-type)))
    (dotimes (i n)
      (setf (aref result i) (funcall function)))
    result))

Then return-type and functions that can report it could look like this:

(defun return-type (function)
  (funcall function 'return-type))
    
(defun my-function (&optional report-return-type-p)
  (if report-return-type-p
      'double-float
      (random 10d0)))

The problem is efficiency:

(vector-fill 10000000 #'my-function)

is about 40% slower (SBCL, (optimize (speed 3))) than

(defun my-function2 ()
  (random 10d0))

(vector-fill 10000000 #'my-function2 'double-float)

Is there some other way for a (possibly unnamed) function to communicate 
its return type?  Or should I just specify it manually all the time if I 
want speed?

Thanks,

Tamas

From: Barry Margolin
Subject: Re: communicating return type of a function
Date: 
Message-ID: <barmar-4E3456.12252001112008@mara100-84.onlink.net>
In article <··············@mid.individual.net>,
 Tamas K Papp <······@gmail.com> wrote:

> Hi,
> 
> Frequently I encounter calculations where I fill a vector (or array)  
> using a function (maybe mapping from another, but not in the example 
> below).  Most of the time the return type is one for which it makes sense 
> to use an array with a specific element type, say double-float, but not 
> always.  I can specify the resulting element type manually, but it would 
> be neater if the function could communicate it somehow.  For example, 
> consider
> 
> (defun vector-fill (n function &optional
>                    (return-type (return-type function)))
>   (declare (function function)
> 	   (fixnum n))
>   (let ((result (make-array n :element-type return-type)))
>     (dotimes (i n)
>       (setf (aref result i) (funcall function)))
>     result))
> 
> Then return-type and functions that can report it could look like this:
> 
> (defun return-type (function)
>   (funcall function 'return-type))
>     
> (defun my-function (&optional report-return-type-p)
>   (if report-return-type-p
>       'double-float
>       (random 10d0)))
> 
> The problem is efficiency:
> 
> (vector-fill 10000000 #'my-function)
> 
> is about 40% slower (SBCL, (optimize (speed 3))) than
> 
> (defun my-function2 ()
>   (random 10d0))
> 
> (vector-fill 10000000 #'my-function2 'double-float)
> 
> Is there some other way for a (possibly unnamed) function to communicate 
> its return type?  Or should I just specify it manually all the time if I 
> want speed?

There's no standard mechanism for this.  Common Lisp's introspection 
mechanisms don't include type declarations.  At one point during the 
standardization there was a proposal for environment inquiry functions, 
but we never got them quite right and it wasn't included in the final 
standard.

If you only need this for certain applications in your function, you 
could maintain a hash table, and provide your own defining macros that 
add the functions to the hash table.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Tamas K Papp
Subject: Re: communicating return type of a function
Date: 
Message-ID: <6n3phmFjekh1U2@mid.individual.net>
On Sat, 01 Nov 2008 12:25:20 -0400, Barry Margolin wrote:

> In article <··············@mid.individual.net>,
>  Tamas K Papp <······@gmail.com> wrote:
> 
>> Hi,
>> 
>> Frequently I encounter calculations where I fill a vector (or array)
>> using a function (maybe mapping from another, but not in the example
>> below).  Most of the time the return type is one for which it makes
>> sense to use an array with a specific element type, say double-float,
>> but not always.  I can specify the resulting element type manually, but
>> it would be neater if the function could communicate it somehow.  For
>> example, consider
>> 
>> (defun vector-fill (n function &optional
>>                    (return-type (return-type function)))
>>   (declare (function function)
>> 	   (fixnum n))
>>   (let ((result (make-array n :element-type return-type)))
>>     (dotimes (i n)
>>       (setf (aref result i) (funcall function)))
>>     result))
>> 
>> Then return-type and functions that can report it could look like this:
>> 
>> (defun return-type (function)
>>   (funcall function 'return-type))
>>     
>> (defun my-function (&optional report-return-type-p)
>>   (if report-return-type-p
>>       'double-float
>>       (random 10d0)))
>> 
>> The problem is efficiency:
>> 
>> (vector-fill 10000000 #'my-function)
>> 
>> is about 40% slower (SBCL, (optimize (speed 3))) than
>> 
>> (defun my-function2 ()
>>   (random 10d0))
>> 
>> (vector-fill 10000000 #'my-function2 'double-float)
>> 
>> Is there some other way for a (possibly unnamed) function to
>> communicate its return type?  Or should I just specify it manually all
>> the time if I want speed?
> 
> There's no standard mechanism for this.  Common Lisp's introspection
> mechanisms don't include type declarations.  At one point during the
> standardization there was a proposal for environment inquiry functions,
> but we never got them quite right and it wasn't included in the final
> standard.
> 
> If you only need this for certain applications in your function, you
> could maintain a hash table, and provide your own defining macros that
> add the functions to the hash table.

Thanks for the suggestion. 

I have been thinking about something that would implement a strongly 
typed layer on CL where needed, eg I could write functions using S-
expressions, then they would be specialized to the appropriate type, 
generate Lisp code with all the fancy declarations and then compile 
that.  Possibly something like a subset of what Qi does.

But I know very little about the theory behind these things, so I guess a 
lot of reading would be beneficial before I try.  If anyone could help 
with suggestions/pointers, I would appreciate that.

Thanks,

Tamas
From: Madhu
Subject: Re: communicating return type of a function
Date: 
Message-ID: <m34p2qpy59.fsf@moon.robolove.meer.net>
* Tamas K Papp <··············@mid.individual.net> :
Wrote on 1 Nov 2008 19:38:30 GMT:

| I have been thinking about something that would implement a strongly
| typed layer on CL where needed, eg I could write functions using S-
| expressions, then they would be specialized to the appropriate type,
| generate Lisp code with all the fancy declarations and then compile
| that.  Possibly something like a subset of what Qi does.
|
| But I know very little about the theory behind these things, so I guess a 
| lot of reading would be beneficial before I try.  If anyone could help 
| with suggestions/pointers, I would appreciate that.

Also consider Drew McDermott's NISP's approach

,---- <URL:http://www.cs.yale.edu/homes/dvm/> ----
|   * Nisp (version 2.93.22, 2006-12-01) is a strongly typed dialect of
|   Lisp, implemented as a collection of macros. Older versions of Nisp
|   (see below) were based on a tool set called "NILS," but recent
|   versions are based on YTools. (Hence it is referred to in some
|   places as YNisp.) The tar file contains a single directory called
|   ydecl which contains all the type-checking stuff.
`----

From that page: <URL:http://www.cs.yale.edu/homes/dvm/papers/nispman.pdf>

Also, types and the return type have to be specified when defining
foreign function interfaces, and each lisp system has ways of
representing them and syntax for specifying them.  (CFFI's choice
doesn't match my personal taste)

--
Madhu