From: pack.rat
Subject: transforming code into typed code
Date: 
Message-ID: <de64da02-1a56-4088-8d69-c22af441af8c@b1g2000hsg.googlegroups.com>
I cannot program in any language other than Lisp at this point.
Having gone through Fortran, C, Java, Python etc. before stumbling
upon Lisp, it's the only language I use.  I'm a scientist, not a
computer scientist, so I have a naive question.  Shouldn't it be
possible to write a Lisp macro that takes untyped functional code,
with an example of function inputs, and generate typed code
automatically?  I am trying to write this in the following (naivete
alert):  take a form, deconstruct it into function and arguments; take
the arguments, and evaluate their types from the given example
arguments, and change the function definition to reflect these types;
then step into the function and as you step through, keep evaluating
and declaring, until you end up at the end.  This will be purely
functional code with no side effects.  I am not trying to do type
inference (not smart enough to think about it), just trying to avoid
the pain of inserting declarations and `the' once I know the code
works in examples.  As I said, I am not a computer scientist, so I'm
not rolling around on the floor laughing about this, but shouldn't
macros be able to do this?  If so, has it been done already?  This is
what a compiler does in essence without the example arguments by using
type inference.

Thanks for any help.
Vipul Periwal
PS when you're done laughing, that is. :-)

From: namekuseijin
Subject: Re: transforming code into typed code
Date: 
Message-ID: <c569f81f-794d-49e4-873f-f6abf9edc359@i76g2000hsf.googlegroups.com>
On Sep 5, 12:30 pm, "pack.rat" <·········@gmail.com> wrote:
> I'm a scientist,

Are you really a scientist or a lab rat trying to conquer the world?

> a Lisp macro that takes untyped functional code,
> with an example of function inputs, and generate typed code
> automatically?... just trying to avoid
> the pain of inserting declarations

You're trying to avoid the pain of typing type declarations, by typing
long function input examples?  right...
From: Tamas K Papp
Subject: Re: transforming code into typed code
Date: 
Message-ID: <6idbifFq7lrmU1@mid.individual.net>
On Fri, 05 Sep 2008 10:53:40 -0700, namekuseijin wrote:

> On Sep 5, 12:30 pm, "pack.rat" <·········@gmail.com> wrote:
>> I'm a scientist,
> 
> Are you really a scientist or a lab rat trying to conquer the world?

This sort of tone is completely uncalled for.  Si tacuisses, ...

Tamas
From: namekuseijin
Subject: Re: transforming code into typed code
Date: 
Message-ID: <381b4a90-64ee-4d41-9fb3-9c755703dfed@c65g2000hsa.googlegroups.com>
On Sep 5, 3:20 pm, Tamas K Papp <······@gmail.com> wrote:
> On Fri, 05 Sep 2008 10:53:40 -0700, namekuseijin wrote:
> > On Sep 5, 12:30 pm, "pack.rat" <·········@gmail.com> wrote:
> >> I'm a scientist,
>
> > Are you really a scientist or a lab rat trying to conquer the world?
>
> This sort of tone is completely uncalled for.  Si tacuisses, ...
>
> Tamas

Look his email alias.
From: pack.rat
Subject: Re: transforming code into typed code
Date: 
Message-ID: <dc6aca81-a1d9-4804-a05c-1924ab41de30@l42g2000hsc.googlegroups.com>
It's funny actually.  You could look me up in Google and decide for
yourself if I'm a scientist or not.

In any case, all I want to do is write a function

(defun f (a b c) (...))

and when I'm sure everything works fine, have this transformed into

(defun f (a b c)
   (declare (type (type-of x_a) a))
   (declare ... )
   (..body..))

where (x_a x_b x_c) are example inputs to f that I supply to some
transformation function/macro/...
That doesn't strike me as too unreasonable.  I just wanted to know if
there was some way to do this all the way into
the body of the function, using the example invocation.  The functions
are all written so I'm actually trying to avoid
making mistakes.  For example I could invoke a Monte Carlo function
with one step to get all the variables typed, and
then run it for a few million steps with the compiled typed function.
As Guy Steele wrote, I'm only following "our natural
tendency towards brevity" - quoted in On Lisp.

Thanks to Pascal and Tamas for their help.
From: namekuseijin
Subject: Re: transforming code into typed code
Date: 
Message-ID: <5b07dac9-b9be-4a71-92a5-b7705488bb12@25g2000hsx.googlegroups.com>
On Sep 5, 5:35 pm, "pack.rat" <·········@gmail.com> wrote:
> It's funny actually.  You could look me up in Google and decide for
> yourself if I'm a scientist or not.

Sorry.  You email address, the request and that PS at the end sounded
kinda trollish.

> (defun f (a b c) (...))
>
> and when I'm sure everything works fine, have this transformed into
>
> (defun f (a b c)
>    (declare (type (type-of x_a) a))
>    (declare ... )
>    (..body..))
>
> where (x_a x_b x_c) are example inputs to f that I supply to some
> transformation function/macro/...
> That doesn't strike me as too unreasonable.

Ah!  By inputs I thought you meant data, rather than the types
themselves.  Indeed, a macro for it should be fairly trivial.
From: namekuseijin
Subject: Re: transforming code into typed code
Date: 
Message-ID: <e75bd0c1-1134-47e5-b4d2-f18ceb86847f@e39g2000hsf.googlegroups.com>
On 5 set, 17:59, namekuseijin <············@gmail.com> wrote:
> On Sep 5, 5:35 pm, "pack.rat" <·········@gmail.com> wrote:
> > (defun f (a b c) (...))
>
> > and when I'm sure everything works fine, have this transformed into
>
> > (defun f (a b c)
> >    (declare (type (type-of x_a) a))
> >    (declare ... )
> >    (..body..))
>
> > where (x_a x_b x_c) are example inputs to f that I supply to some
> > transformation function/macro/...
> > That doesn't strike me as too unreasonable.
>
> Ah!  By inputs I thought you meant data, rather than the types
> themselves.  Indeed, a macro for it should be fairly trivial.

Oops!  Didn't catch that type-of!

So, you're really wanting to type data rather than types, indeed.  And
*after* the function was defined.  Then I guess you either rewrite the
Lisp evaluator to do type inference and properly compiles the
functions or write a macro that outputs a function which evaluates the
types of the arguments at run-time.  That's slow and lame.

But frankly, it's too much trouble to be any worth, specially as
typing something like
(defun-typed (foo bar:string boz:int) ...)

Should save you a lot of typing rather than:
(defun (foo bar boz) ...)
(foo "foobar was here" 123)

And is also good style by properly documenting the code rather than
relying on external data to provide meaning to the functions.
From: Marco Antoniotti
Subject: Re: transforming code into typed code
Date: 
Message-ID: <54d36d19-b8c4-491f-9318-f2d881ed73e3@c65g2000hsa.googlegroups.com>
On Sep 5, 10:35 pm, "pack.rat" <·········@gmail.com> wrote:
> It's funny actually.  You could look me up in Google and decide for
> yourself if I'm a scientist or not.
>
> In any case, all I want to do is write a function
>
> (defun f (a b c) (...))
>
> and when I'm sure everything works fine, have this transformed into
>
> (defun f (a b c)
>    (declare (type (type-of x_a) a))
>    (declare ... )
>    (..body..))
>
> where (x_a x_b x_c) are example inputs to f that I supply to some
> transformation function/macro/...
> That doesn't strike me as too unreasonable.  I just wanted to know if
> there was some way to do this all the way into
> the body of the function, using the example invocation.  The functions
> are all written so I'm actually trying to avoid
> making mistakes.  For example I could invoke a Monte Carlo function
> with one step to get all the variables typed, and
> then run it for a few million steps with the compiled typed function.
> As Guy Steele wrote, I'm only following "our natural
> tendency towards brevity" - quoted in On Lisp.
>
> Thanks to Pascal and Tamas for their help.

Apart from Tamas and Pascal's suggestions, a general facility like the
one you are asking for is what is provided by the ML/Haskell family of
languages.  It usually goes under the name of "type inferencing" or
"type reconstruction" (cfr. Pierce's book "Types and Programming
Languages").  Some CL compilers do it rather well but not in a
standardized way, so YMMV.  In general, doing it the way it is done
according to current "typing" state of the art requires a lot of work.

Cheers
--
Marco
From: Paul Tarvydas
Subject: Re: transforming code into typed code
Date: 
Message-ID: <ga0pgb$l4v$1@aioe.org>
Marco Antoniotti wrote:

> 
> Apart from Tamas and Pascal's suggestions, a general facility like the
> one you are asking for is what is provided by the ML/Haskell family of
> languages.  

And, the compiler for the language "Self".

http://research.sun.com/self/papers/papers.html

pt
From: Marco Antoniotti
Subject: Re: transforming code into typed code
Date: 
Message-ID: <7a4ab0de-f534-47e5-8c1b-00e6c6665f70@x41g2000hsb.googlegroups.com>
On Sep 7, 4:46 pm, Paul Tarvydas <········@visualframeworksinc.com>
wrote:
> Marco Antoniotti wrote:
>
> > Apart from Tamas and Pascal's suggestions, a general facility like the
> > one you are asking for is what is provided by the ML/Haskell family of
> > languages.  
>
> And, the compiler for the language "Self".
>
> http://research.sun.com/self/papers/papers.html
>
> pt

Thanks for the pointer.  Self is one of those languages I always
wanted to grok and never had the chance to.

Cheers
--
Marco
From: Tamas K Papp
Subject: Re: transforming code into typed code
Date: 
Message-ID: <6id3ccFq7dvcU1@mid.individual.net>
On Fri, 05 Sep 2008 08:30:46 -0700, pack.rat wrote:

> I cannot program in any language other than Lisp at this point. Having
> gone through Fortran, C, Java, Python etc. before stumbling upon Lisp,
> it's the only language I use.  I'm a scientist, not a computer
> scientist, so I have a naive question.  Shouldn't it be possible to
> write a Lisp macro that takes untyped functional code, with an example
> of function inputs, and generate typed code automatically?  I am trying
> to write this in the following (naivete alert):  take a form,
> deconstruct it into function and arguments; take the arguments, and
> evaluate their types from the given example arguments, and change the
> function definition to reflect these types; then step into the function
> and as you step through, keep evaluating and declaring, until you end up
> at the end.  This will be purely functional code with no side effects. 
> I am not trying to do type inference (not smart enough to think about
> it), just trying to avoid the pain of inserting declarations and `the'
> once I know the code works in examples.  As I said, I am not a computer
> scientist, so I'm not rolling around on the floor laughing about this,
> but shouldn't macros be able to do this?  If so, has it been done
> already?  This is what a compiler does in essence without the example
> arguments by using type inference.

Dear Vipul,

I use SBCL for numerical computations.  I rarely need bother to optimize 
by declaring types, but when I do, I generally find that SBCL 
automatically does what you want if you declare the type of the function 
arguments - then it will infer the rest.  You may need to make a (speed 
3) declaration to get the most out of this.

I would not be surprised if other implementations did something similar.

HTH,

Tamas
From: Pascal J. Bourguignon
Subject: Re: transforming code into typed code
Date: 
Message-ID: <7c7i9qlggp.fsf@pbourguignon.anevia.com>
"pack.rat" <·········@gmail.com> writes:

> I cannot program in any language other than Lisp at this point.
> Having gone through Fortran, C, Java, Python etc. before stumbling
> upon Lisp, it's the only language I use.  I'm a scientist, not a
> computer scientist, so I have a naive question.  Shouldn't it be
> possible to write a Lisp macro that takes untyped functional code,
> with an example of function inputs, and generate typed code
> automatically?  I am trying to write this in the following (naivete
> alert):  take a form, deconstruct it into function and arguments; take
> the arguments, and evaluate their types from the given example
> arguments, and change the function definition to reflect these types;
> then step into the function and as you step through, keep evaluating
> and declaring, until you end up at the end.  This will be purely
> functional code with no side effects.  I am not trying to do type
> inference (not smart enough to think about it), just trying to avoid
> the pain of inserting declarations and `the' once I know the code
> works in examples.  As I said, I am not a computer scientist, so I'm
> not rolling around on the floor laughing about this, but shouldn't
> macros be able to do this?  If so, has it been done already?  This is
> what a compiler does in essence without the example arguments by using
> type inference.
>
> Thanks for any help.
> Vipul Periwal
> PS when you're done laughing, that is. :-)

Not naive at all.  This is basically what sbcl does, but from the
inside outward: types are infered from the types accepted by the
functions used  (search for "type inference").

Now of course, in some cases the operators may be still too generic.
For example, an arithmetic function is known not to work on strings or
random-states, but could still be applied to either subtype of
numbers.  In this case, instead of giving it an "example" input, you
can just tell it what type the expected arguments shall be:

(defun p2 (a b c)
  (lambda (x) (+ c (* x (+ b (* x a))))))

(funcall (p2 1 2 3) 4)                          : only integers
(funcall (p2 1/2 2/3 3/4) 4/5)                  : rationals
(funcall (p2 1.2 2.3 3.4) 4.5)                  : single-floats
(funcall (p2 #C(1 2) #C(2 3) #(C 3 4)) #(C 4 5) : complexes

If you know you will only work with a single type:

(deftype my-number-type () 'double-float)

(defun p2 (a b c)
  (declare (type my-number-type a b c))
  (lambda (x) 
     (declare (type my-number-type x))
     (+ c (* x (+ b (* x a))))))

So now the compiler can optimize the code generated so it works only
with one type.


*  (funcall (p2 1/2 23 #(3 4)) 4.5)

debugger invoked on a TYPE-ERROR in thread #<THREAD "initial thread" {10024C2061}>:
  The value 1/2 is not of type DOUBLE-FLOAT.

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(P2 1/2 23 #(3 4))
source: (SB-INT:NAMED-LAMBDA P2 (A B C) (DECLARE (TYPE MY-NUMBER-TYPE A B C))
                             (BLOCK P2
                               (LAMBDA (X)
                                 (DECLARE (TYPE MY-NUMBER-TYPE X))
                                 (+ C (* X (+ B #))))))
0] 0

* (funcall (p2 1.2d0 2.3d0 3.4d0) 4.5d0)

38.05d0
* 


-- 
__Pascal Bourguignon__
From: Stephen Compall
Subject: Re: transforming code into typed code
Date: 
Message-ID: <m263paxex1.fsf@nocandy.dyndns.org>
"pack.rat" <·········@gmail.com> writes:
> and evaluate their types from the given example arguments

Unfortunately, here lies the problem:

(defun numop (x y z)
  ops...)

Hmm, transform this please, using (numop 1 2 3):

(defun numop (x y z)
  (declare (type (eql 1) x) (type (eql 2) y) (type (eql 3) z))
  ops...)

Erm, that's not what I meant, please unify with (numop 42 84 167),
without using eql or member:

(defun numop (x y z)
  (declare (type (mod 43) x) (type (mod 85) y) (type (mod 168) z))
  ops...)

Anyway, Pascal spoke true; all you have to do is declare the types of
the arguments (which, as you can see, must be done anyway) and the rest
will likely be inferred.

-- 
But you know how reluctant paranormal phenomena are to reveal
themselves when skeptics are present. --Robert Sheaffer, SkI 9/2003
From: verec
Subject: Re: transforming code into typed code
Date: 
Message-ID: <48c19405$0$521$5a6aecb4@news.aaisp.net.uk>
Let's pretend for a minute that such a macro existed. How
would you use it? What is the interface? I'm guessing that
your intent is to provide some replacement to defun?

Say: deftyped.

Let's start:

(deftyped foo (args) ...

Ooops. Wait a minute. "deftyped" cannot really operate the
way you want it to, unless it has seen the "example call".
So the example call must precede the function definition,
Right? Because macro-evaluation is "single pass" ...

So, right now, eiter we're talking about some source file
anaylser that is not a macro at all, or, if we are talking
of a macro, then the example must come first... Hmmm

Let's try again.

(deftyped (f 1 "hello" 1.0d) (f count message coeff) ( ...

With some (a lot for me!) work, we could probably handle
this, because the example only used litteral values. Right.

But what about those values  that do not have litteral
representation? Those values for which the REPL prints out
#<xxxx> ?

That seems a worthy reseach project, but ... if you're so
keen on "static typing" why not giving Qi http://www.lambdassociates.org/
a try? As I understand it, Qi is "just" a library "on top of"
Common Lisp that allows you to stay in CL land all you want and
drop into (or is it: raise up to? :-) static typing within the
very same source file ... (Yes Mark Tarver has an excellent "sales
pitch" :-)

HTH
--
JFB

On 2008-09-05 16:30:46 +0100, "pack.rat" <·········@gmail.com> said:

> I cannot program in any language other than Lisp at this point.
> Having gone through Fortran, C, Java, Python etc. before stumbling
> upon Lisp, it's the only language I use.  I'm a scientist, not a
> computer scientist, so I have a naive question.  Shouldn't it be
> possible to write a Lisp macro that takes untyped functional code,
> with an example of function inputs, and generate typed code
> automatically?  I am trying to write this in the following (naivete
> alert):  take a form, deconstruct it into function and arguments; take
> the arguments, and evaluate their types from the given example
> arguments, and change the function definition to reflect these types;
> then step into the function and as you step through, keep evaluating
> and declaring, until you end up at the end.  This will be purely
> functional code with no side effects.  I am not trying to do type
> inference (not smart enough to think about it), just trying to avoid
> the pain of inserting declarations and `the' once I know the code
> works in examples.  As I said, I am not a computer scientist, so I'm
> not rolling around on the floor laughing about this, but shouldn't
> macros be able to do this?  If so, has it been done already?  This is
> what a compiler does in essence without the example arguments by using
> type inference.
> 
> Thanks for any help.
> Vipul Periwal
> PS when you're done laughing, that is. :-)
From: ·············@gmail.com
Subject: Re: transforming code into typed code
Date: 
Message-ID: <cb36119b-b43a-4428-a587-dcb291780bb4@k37g2000hsf.googlegroups.com>
On Sep 5, 4:18 pm, verec <·····@mac.com> wrote:
> Let's pretend for a minute that such a macro existed. How
> would you use it? What is the interface? I'm guessing that
> your intent is to provide some replacement to defun?
>
> Say: deftyped.
>
> Let's start:
>
> (deftyped foo (args) ...
>
> Ooops. Wait a minute. "deftyped" cannot really operate the
> way you want it to, unless it has seen the "example call".
> So the example call must precede the function definition,
> Right? Because macro-evaluation is "single pass" ...
>
> So, right now, eiter we're talking about some source file
> anaylser that is not a macro at all, or, if we are talking
> of a macro, then the example must come first... Hmmm
>
> Let's try again.
>
> (deftyped (f 1 "hello" 1.0d) (f count message coeff) ( ...
>
> With some (a lot for me!) work, we could probably handle
> this, because the example only used litteral values. Right.
>
> But what about those values  that do not have litteral
> representation? Those values for which the REPL prints out
> #<xxxx> ?
>
> That seems a worthy reseach project, but ... if you're so
> keen on "static typing" why not giving Qihttp://www.lambdassociates.org/
> a try? As I understand it, Qi is "just" a library "on top of"
> Common Lisp that allows you to stay in CL land all you want and
> drop into (or is it: raise up to? :-) static typing within the
> very same source file ... (Yes Mark Tarver has an excellent "sales
> pitch" :-)
>
> HTH
> --
> JFB
>
> On 2008-09-05 16:30:46 +0100, "pack.rat" <·········@gmail.com> said:
>
> > I cannot program in any language other than Lisp at this point.
> > Having gone through Fortran, C, Java, Python etc. before stumbling
> > upon Lisp, it's the only language I use.  I'm a scientist, not a
> > computer scientist, so I have a naive question.  Shouldn't it be
> > possible to write a Lisp macro that takes untyped functional code,
> > with an example of function inputs, and generate typed code
> > automatically?  I am trying to write this in the following (naivete
> > alert):  take a form, deconstruct it into function and arguments; take
> > the arguments, and evaluate their types from the given example
> > arguments, and change the function definition to reflect these types;
> > then step into the function and as you step through, keep evaluating
> > and declaring, until you end up at the end.  This will be purely
> > functional code with no side effects.  I am not trying to do type
> > inference (not smart enough to think about it), just trying to avoid
> > the pain of inserting declarations and `the' once I know the code
> > works in examples.  As I said, I am not a computer scientist, so I'm
> > not rolling around on the floor laughing about this, but shouldn't
> > macros be able to do this?  If so, has it been done already?  This is
> > what a compiler does in essence without the example arguments by using
> > type inference.
>
> > Thanks for any help.
> > Vipul Periwal
> > PS when you're done laughing, that is. :-)
>
>

I would use the ideas I have seen in Doug Hoyte's book Let over
Lambda.  He shows an example how to eliminate the (with-gensyms
variable).

His macro defmacro/g! looks for variables with names starting with g!
and automatically writes a code wrapper that will generate gensyms for
them.

Likewise, one could define a similar macro that would look for
variables starting with "l!" or "d!" and declare them as long integers
or double floats for example, and similarly to prefix function calls
in the same way.

This has actually other interesting applications in physical science
modeling (and other sciences as well):  Suppose I use the L!
designator for length.  And I decide (and specify) that lengths cannot
be negative.  So, I could have a macro that would include a check for
any argument that starts with L! to be non-negative.  Likewise, and
function that would calculate lengths would be prefixed with an L! (!L
'#funcname args), and the macro would generate code to make sure that
the calculated value is non-negative.

I was implementing just this in another language, when I thought that
there must be a better way.  And here I am, about a year and a half
later, still learning (and enjoying) lisp (and bugging folks along the
way), and not implementing the above scheme.

Mirko
From: Pascal J. Bourguignon
Subject: Re: transforming code into typed code
Date: 
Message-ID: <87sksenthr.fsf@hubble.informatimago.com>
·············@gmail.com writes:
> This has actually other interesting applications in physical science
> modeling (and other sciences as well):  Suppose I use the L!
> designator for length.  And I decide (and specify) that lengths cannot
> be negative.  So, I could have a macro that would include a check for
> any argument that starts with L! to be non-negative.  Likewise, and
> function that would calculate lengths would be prefixed with an L! (!L
> '#funcname args), and the macro would generate code to make sure that
> the calculated value is non-negative.

Why not, but why do with a reader macro (or other lexer level
processing) what can be done with normal s-expr.

Instead of writing l!string, write (length string).
Instead of writing l!car, write (length car).
Instead of writing (l!length-of-car *pjb*) write (length (car *pjb*)).

length here is not necessarily the cl:length function.  Think of it
like the dynamic operator of islisp.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

This is a signature virus.  Add me to your signature and help me to live.
From: ·············@gmail.com
Subject: Re: transforming code into typed code
Date: 
Message-ID: <44f17450-4ea2-4fd9-9f15-ea91decc87c8@c58g2000hsc.googlegroups.com>
On Sep 5, 6:00 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> ·············@gmail.com writes:
> > This has actually other interesting applications in physical science
> > modeling (and other sciences as well):  Suppose I use the L!
> > designator for length.  And I decide (and specify) that lengths cannot
> > be negative.  So, I could have a macro that would include a check for
> > any argument that starts with L! to be non-negative.  Likewise, and
> > function that would calculate lengths would be prefixed with an L! (!L
> > '#funcname args), and the macro would generate code to make sure that
> > the calculated value is non-negative.
>
> Why not, but why do with a reader macro (or other lexer level
> processing) what can be done with normal s-expr.
>
> Instead of writing l!string, write (length string).
> Instead of writing l!car, write (length car).
> Instead of writing (l!length-of-car *pjb*) write (length (car *pjb*)).
>
> length here is not necessarily the cl:length function.  Think of it
> like the dynamic operator of islisp.
>
> --
> __Pascal Bourguignon__                    http://www.informatimago.com/
>
> This is a signature virus.  Add me to your signature and help me to live.

Pascal,

I did not quite get your explanation, so, let me offer a more concrete
example, as I may not have been clear.

In particle collisions a useful quantity is the reduced mass:
(defun m* (m1 m2)
(/ (* m1 m2)
   (+ m1 m2)))

Now masses, must be positive.  Let me define a declaration (and I will
make it unecesseraly verbose), mass!, that I know is
a) a real number
b) > 0 (even neutrinos have mass)

and rewrite my code as

(dedeclfun mass!m* (mass!m1 mass!m2)
(/ (* m1 m2)
   (+ m1 m2)))

The declaration macro would rewrite the internals as follows

(and (rule-a m1) (rule-b m1))
(and (rule-a m2) (rule-b m2))
(let ((res (... the actual calculation shown above)))
   (and (rule-a res) (rule-b res))

The rule-a and rule-b would do the testing, and also output some kind
of meaningful error message with continuation.  These error conditions
could be specified in the original dedeclfun with some optional
arguments.  Actually, that is probably the harder part of coding.


Mirko
From: Pascal J. Bourguignon
Subject: Re: transforming code into typed code
Date: 
Message-ID: <87hc8todu4.fsf@hubble.informatimago.com>
·············@gmail.com writes:

> I did not quite get your explanation, so, let me offer a more concrete
> example, as I may not have been clear.
>
> In particle collisions a useful quantity is the reduced mass:
> (defun m* (m1 m2)
> (/ (* m1 m2)
>    (+ m1 m2)))
>
> Now masses, must be positive.  Let me define a declaration (and I will
> make it unecesseraly verbose), mass!, that I know is
> a) a real number
> b) > 0 (even neutrinos have mass)
>
> and rewrite my code as
>
> (dedeclfun mass!m* (mass!m1 mass!m2)
> (/ (* m1 m2)
>    (+ m1 m2)))

What I mean, is purely at the syntactic level.  I suggest that instead
of introducing a lexical notation such as  axis!varname, you could use
standard s-exps: (axis varname).  This would make it easier to write
macros generating them.

Also, you don't want to specify only the axis, you also want to
specify the units, not to do the same as NASA engineers, communicating
meter/second is if it was foot/furlong, thus crashing into Mars...

So (defunit m* ((kg m1) (kg m2))  -> (kg (* kg kg))
      (values (/ (* m1 m2) (+ m1 m2))
              (* (+ m1 m2) (- m1 m2))))
   (defunit speed ((dx m) (dt s)) -> ((/ m s))
      (/ dx ds))




-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NEW GRAND UNIFIED THEORY DISCLAIMER: The manufacturer may
technically be entitled to claim that this product is
ten-dimensional. However, the consumer is reminded that this
confers no legal rights above and beyond those applicable to
three-dimensional objects, since the seven new dimensions are
"rolled up" into such a small "area" that they cannot be
detected.
From: ·············@gmail.com
Subject: Re: transforming code into typed code
Date: 
Message-ID: <cae501f9-2abd-4991-97e1-cf435a194430@p25g2000hsf.googlegroups.com>
On Sep 6, 4:53 am, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> ·············@gmail.com writes:
> > I did not quite get your explanation, so, let me offer a more concrete
> > example, as I may not have been clear.
>
> > In particle collisions a useful quantity is the reduced mass:
> > (defun m* (m1 m2)
> > (/ (* m1 m2)
> >    (+ m1 m2)))
>
> > Now masses, must be positive.  Let me define a declaration (and I will
> > make it unecesseraly verbose), mass!, that I know is
> > a) a real number
> > b) > 0 (even neutrinos have mass)
>
> > and rewrite my code as
>
> > (dedeclfun mass!m* (mass!m1 mass!m2)
> > (/ (* m1 m2)
> >    (+ m1 m2)))
>
> What I mean, is purely at the syntactic level.  I suggest that instead
> of introducing a lexical notation such as  axis!varname, you could use
> standard s-exps: (axis varname).  This would make it easier to write
> macros generating them.
>
Sorry for being dense, but what do you mean by the (axis varname)
syntax?  If I understand correctly, you were implying a usage like
this:
(defun foo ((axis varname1) (axis varname2) (mass varname3))
  ...)

Is defun then a generic function, or is something else going on?

Thanks
From: Pascal J. Bourguignon
Subject: Re: transforming code into typed code
Date: 
Message-ID: <87bpyys7xc.fsf@hubble.informatimago.com>
·············@gmail.com writes:

> On Sep 6, 4:53�am, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> ·············@gmail.com writes:
>> > I did not quite get your explanation, so, let me offer a more concrete
>> > example, as I may not have been clear.
>>
>> > In particle collisions a useful quantity is the reduced mass:
>> > (defun m* (m1 m2)
>> > (/ (* m1 m2)
>> > � �(+ m1 m2)))
>>
>> > Now masses, must be positive. �Let me define a declaration (and I will
>> > make it unecesseraly verbose), mass!, that I know is
>> > a) a real number
>> > b) > 0 (even neutrinos have mass)
>>
>> > and rewrite my code as
>>
>> > (dedeclfun mass!m* (mass!m1 mass!m2)
>> > (/ (* m1 m2)
>> > � �(+ m1 m2)))
>>
>> What I mean, is purely at the syntactic level. �I suggest that instead
>> of introducing a lexical notation such as �axis!varname, you could use
>> standard s-exps: (axis varname). �This would make it easier to write
>> macros generating them.
>>
> Sorry for being dense, but what do you mean by the (axis varname)
> syntax?  

If you write mass, you mean the axis.  A unit vector on this axis
would be kilogram, kg.

When you have another axis, such as distance, with a unit vector named
meter, m,  you can build a vector by multiplying 150 kg by 2 m which
would give 300 kg.m.


I think there's not much point in restricting only the axis, as the
Mars Orbiter crash showed.
http://edition.cnn.com/TECH/space/9909/30/mars.metric/


> If I understand correctly, you were implying a usage like
> this:
> (defun foo ((axis varname1) (axis varname2) (mass varname3))
>   ...)


There's no need to override DEFUN, since the syntax changes.

(define-function-with-units speed ((dt m) (ds s)) 
  (declare (returns-unit (/ m s)))
  (/ dt ds))


> Is defun then a generic function, or is something else going on?

It would still be a macro, not a function.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

ATTENTION: Despite any other listing of product contents found
herein, the consumer is advised that, in actuality, this product
consists of 99.9999999999% empty space.
From: Chris Russell
Subject: Re: transforming code into typed code
Date: 
Message-ID: <0291a07c-6374-4067-af4d-9d8dc554328d@e39g2000hsf.googlegroups.com>
On 5 Sep, 21:18, verec <·····@mac.com> wrote:
> Let's pretend for a minute that such a macro existed. How
> would you use it? What is the interface? I'm guessing that
> your intent is to provide some replacement to defun?
>
> Say: deftyped.
>
> Let's start:
>
> (deftyped foo (args) ...
>
> Ooops. Wait a minute. "deftyped" cannot really operate the
> way you want it to, unless it has seen the "example call".
> So the example call must precede the function definition,
> Right? Because macro-evaluation is "single pass" ...

Nope. Macros can manipulate state as well as code.
This means you can call macros in the following manner.

(deftyped foo (args)..)

(eg foo args1)
(eg foo args2)
(eg foo args3)

(seal foo)

where deftyped and eg embed nil in the code but store a function body
and argument types in a table and seal embeds the finished function
within the code. Alternatively, eg could recompile the function each
time it is called with a new example.

Demonstration code below:

(let ((body (make-hash-table))
	       (arg-types (make-hash-table)))
  (defmacro deftyped (name args &rest fn-body)
    (setf (gethash name body) fn-body
          (gethash name arg-types) (mapcar #'list args))
    nil)
  (defmacro eg (name &rest args)
    (setf (gethash name arg-types)
          (mapcar  (lambda(literal list)
                     (cons (type-of literal) list)) args (gethash name
arg-types)))
    nil)
  (defmacro seal (name)
    `(defun ,name ,(mapcar (lambda (x) (car (last x))) (gethash  name
arg-types))
       (declare ,@(mapcar (lambda (x)
                             `(type (or ,@(butlast x))
                                     ,(car (last x))))(gethash name
arg-types)))
       ,@(gethash name body))))


Then run:

(deftyped plus (a b) (+ a b))

(eg plus 1 1)
(eg plus 1.0 1)
(eg plus #C(0 1) 1)
(seal plus)

CL-USER>  (macroexpand-1 '(seal plus))
(DEFUN PLUS (A B)
  (DECLARE (TYPE (OR (COMPLEX BIT) SINGLE-FLOAT BIT) A)
   (TYPE (OR BIT BIT BIT) B))
  (+ A B))
T
CL-USER> (plus 1 1)
2
CL-USER> (plus 1.0 1)
2.0
CL-USER> (plus 1 1.0)
; Evaluation aborted.
CL-USER>
From: verec
Subject: Re: transforming code into typed code
Date: 
Message-ID: <48c1d653$0$520$5a6aecb4@news.aaisp.net.uk>
On 2008-09-06 01:29:40 +0100, Chris Russell 
<·····················@gmail.com> said:

> On 5 Sep, 21:18, verec <·····@mac.com> wrote:
>> Let's pretend for a minute that such a macro existed. How
>> would you use it? What is the interface? I'm guessing that
>> your intent is to provide some replacement to defun?
>> 
>> Say: deftyped.
>> 
>> Let's start:
>> 
>> (deftyped foo (args) ...
>> 
>> Ooops. Wait a minute. "deftyped" cannot really operate the
>> way you want it to, unless it has seen the "example call".
>> So the example call must precede the function definition,
>> Right? Because macro-evaluation is "single pass" ...
> 
> Nope. Macros can manipulate state as well as code.
> This means you can call macros in the following manner.
> 
> (deftyped foo (args)..)
> 
> (eg foo args1)
> (eg foo args2)
> (eg foo args3)
> 
> (seal foo)
> 
> where deftyped and eg embed nil in the code but store a function body
> and argument types in a table and seal embeds the finished function
> within the code. Alternatively, eg could recompile the function each
> time it is called with a new example.
> 
> Demonstration code below:
> 
> (let ((body (make-hash-table))
> 	       (arg-types (make-hash-table)))
>   (defmacro deftyped (name args &rest fn-body)
>     (setf (gethash name body) fn-body
>           (gethash name arg-types) (mapcar #'list args))
>     nil)
>   (defmacro eg (name &rest args)
>     (setf (gethash name arg-types)
>           (mapcar  (lambda(literal list)
>                      (cons (type-of literal) list)) args (gethash name
> arg-types)))
>     nil)
>   (defmacro seal (name)
>     `(defun ,name ,(mapcar (lambda (x) (car (last x))) (gethash  name
> arg-types))
>        (declare ,@(mapcar (lambda (x)
>                              `(type (or ,@(butlast x))
>                                      ,(car (last x))))(gethash name
> arg-types)))
>        ,@(gethash name body))))
> 
> 
> Then run:
> 
> (deftyped plus (a b) (+ a b))
> 
> (eg plus 1 1)
> (eg plus 1.0 1)
> (eg plus #C(0 1) 1)
> (seal plus)
> 
> CL-USER>  (macroexpand-1 '(seal plus))
> (DEFUN PLUS (A B)
>   (DECLARE (TYPE (OR (COMPLEX BIT) SINGLE-FLOAT BIT) A)
>    (TYPE (OR BIT BIT BIT) B))
>   (+ A B))
> T
> CL-USER> (plus 1 1)
> 2
> CL-USER> (plus 1.0 1)
> 2.0
> CL-USER> (plus 1 1.0)
> ; Evaluation aborted.
> CL-USER>

Wow! Am I glad to be proven wrong!!! :-) :-) :-)

Though, on LW 5.1.1, first:

CL-USER 11 > (pprint (macroexpand-1 '(seal plus)))

(defun plus (a b)
  (declare (type (or (complex rational) single-float fixnum) a)
           (type (or fixnum fixnum fixnum) b))
  (+ a b))

is a bit different to your expansion, which explains why

CL-USER 12 > (plus 1 1.0)
2.0

works without complaining. Though, of course:

CL-USER 13 > (plus "s" #C(0.5 1))
In + of ("s" #C(0.5 1.0)) arguments should be of type number.

doesn't.

Well done!
--
JFB
From: Chris Russell
Subject: Re: transforming code into typed code
Date: 
Message-ID: <61aea35c-2e97-4931-9902-9cc64c191c10@d1g2000hsg.googlegroups.com>
On 6 Sep, 02:01, verec <·····@mac.com> wrote:
> Though, on LW 5.1.1, first:
>
> CL-USER 11 > (pprint (macroexpand-1 '(seal plus)))
>
> (defun plus (a b)
>   (declare (type (or (complex rational) single-float fixnum) a)
>            (type (or fixnum fixnum fixnum) b))
>   (+ a b))
>
> is a bit different to your expansion, which explains why
>
> CL-USER 12 > (plus 1 1.0)
> 2.0
>
> works without complaining. Though, of course:
>
> CL-USER 13 > (plus "s" #C(0.5 1))
> In + of ("s" #C(0.5 1.0)) arguments should be of type number.
>
> doesn't.
I think this is down to lispworks ignoring type information at when it
is not generating optimized code, while SBCL treats the types as
asserts in the same situation.
1.0 is not of type fixnum, so if it was checking it should be throwing
errors.

> Well done!
> --
Thanks :D.
From: John Thingstad
Subject: Re: transforming code into typed code
Date: 
Message-ID: <op.ug13s7xhut4oq5@pandora.alfanett.no>
P� Sat, 06 Sep 2008 12:25:14 +0200, skrev Chris Russell  
<·····················@gmail.com>:

> On 6 Sep, 02:01, verec <·····@mac.com> wrote:
>> Though, on LW 5.1.1, first:
>>
>> CL-USER 11 > (pprint (macroexpand-1 '(seal plus)))
>>
>> (defun plus (a b)
>> � (declare (type (or (complex rational) single-float fixnum) a)
>> � � � � � �(type (or fixnum fixnum fixnum) b))
>> � (+ a b))
>>
>> is a bit different to your expansion, which explains why
>>
>> CL-USER 12 > (plus 1 1.0)
>> 2.0
>>
>> works without complaining. Though, of course:
>>
>> CL-USER 13 > (plus "s" #C(0.5 1))
>> In + of ("s" #C(0.5 1.0)) arguments should be of type number.
>>
>> doesn't.
> I think this is down to lispworks ignoring type information at when it
> is not generating optimized code, while SBCL treats the types as
> asserts in the same situation.
> 1.0 is not of type fixnum, so if it was checking it should be throwing
> errors.
>
>> Well done!
>> --
> Thanks :D.


LispWorks checks type information if safety is 3. (Actually it checks the  
type if a variable is written to if safety >= 2)
Simulary when speed > safety it generates optimized codde.
It is not as good at type inference as SBCL so each new variable's type  
must be explicitly defined and often the return of a function with 'the'  
as well.

--------------
John Thingstad