Discussion:
return type annotation
Add Reply
Nelson Alexandra
2020-06-20 13:40:45 UTC
Reply
Permalink
How should the return type of a function be annotated to functions?
Should it be annotated as documentation string or as
expressions like (check-type ..) or (ASSERT ..) or (declare (type ...))?
What is useful for human readers and what for the compiler?

How is it "usually" done?
Can someone point at representative examples in libraries?

Would you recommend libraries that help specifying argument and return
types?

Thanks in advance for comments.
Lieven Marchand
2020-06-20 15:10:15 UTC
Reply
Permalink
Post by Nelson Alexandra
How should the return type of a function be annotated to functions?
Should it be annotated as documentation string or as
expressions like (check-type ..) or (ASSERT ..) or (declare (type ...))?
What is useful for human readers and what for the compiler?
How is it "usually" done?
Can someone point at representative examples in libraries?
Would you recommend libraries that help specifying argument and return
types?
You can use DECLARE with ftype.

From the hyperspec examples:

(declare (ftype (function (integer list) t) ith)
(ftype (function (number) float) sine cosine))

So ith is a function that takes an integer and a list and returns
whatever.
--
Laat hulle almal sterf. Ek is tevrede om die wêreld te sien brand en die vallende
konings te spot. Ek en my aasdier sal loop op die as van die verwoeste aarde.
Nelson Alexandra
2020-06-20 16:39:48 UTC
Reply
Permalink
Post by Lieven Marchand
Post by Nelson Alexandra
How should the return type of a function be annotated to functions?
Should it be annotated as documentation string or as
expressions like (check-type ..) or (ASSERT ..) or (declare (type
...))? What is useful for human readers and what for the compiler?
How is it "usually" done?
Can someone point at representative examples in libraries?
Would you recommend libraries that help specifying argument and
return types?
You can use DECLARE with ftype.
(declare (ftype (function (integer list) t) ith)
(ftype (function (number) float) sine cosine))
So ith is a function that takes an integer and a list and returns
whatever.
Ah, I didn't noticed FTYPE yet, thank you.
Rob Warnock
2020-06-26 14:47:06 UTC
Reply
Permalink
Nelson Alexandra <***@i2pn2.org> wrote:
+---------------
| Lieven Marchand ***@wyrd.be writes:
| >You can use DECLARE with ftype.
| >From the hyperspec examples:
| >(declare (ftype (function (integer list) t) ith)
| > (ftype (function (number) float) sine cosine))
| >So ith is a function that takes an integer and a list and returns
| >whatever.
|
| Ah, I didn't noticed FTYPE yet, thank you.
+---------------

Also, a *very* important point to be aware of generally
[especially if you're coming to CL from statically-typed
languages] is that in CL a type declaration is *NOT* an
instruction to the compiler[1] to do things a certain way;
rather, it's a promise by you the programmer *TO* the
compiler that what you claim in the declaration is true,
and that the compiler can depend on it being true without
even checking it!! [For example, the compiler is allowed
to use your declaration to optimize the code without
questioning your declaration (though *some* compilers
might give you warnings in some cases, if they can detect
the misinformation).]

In short, if you lie to the compiler, prepare for nasal demons[2]...

CLHS: 3.2.2.3 Semantic Constraints
...
- The argument syntax and number of return values for all
functions whose ftype is declared at compile time must
remain the same at run time.
...
- Type declarations present in the compilation environment
must accurately describe the corresponding values at run
time; otherwise, the consequences are undefined. ...
...


-Rob

[1] All uses of "compiler" above should be understood to mean
"compiler or evaluator" [interpreter].

[2] https://www.urbandictionary.com/define.php?term=nasal+demons

-----
Rob Warnock <***@rpw3.org>
627 26th Avenue <http://rpw3.org/>
San Mateo, CA 94403
Nelson Alexandra
2020-06-27 12:17:31 UTC
Reply
Permalink
Post by Rob Warnock
+---------------
| >You can use DECLARE with ftype.
| >(declare (ftype (function (integer list) t) ith)
| > (ftype (function (number) float) sine cosine))
| >So ith is a function that takes an integer and a list and returns
| >whatever.
|
| Ah, I didn't noticed FTYPE yet, thank you.
+---------------
Also, a *very* important point to be aware of generally
[especially if you're coming to CL from statically-typed
languages] is that in CL a type declaration is *NOT* an
instruction to the compiler[1] to do things a certain way;
rather, it's a promise by you the programmer *TO* the
compiler that what you claim in the declaration is true,
and that the compiler can depend on it being true without
even checking it!! [For example, the compiler is allowed
to use your declaration to optimize the code without
questioning your declaration (though *some* compilers
might give you warnings in some cases, if they can detect
the misinformation).]
In short, if you lie to the compiler, prepare for nasal demons[2]...
CLHS: 3.2.2.3 Semantic Constraints
...
- The argument syntax and number of return values for all
functions whose ftype is declared at compile time must
remain the same at run time.
...
- Type declarations present in the compilation environment
must accurately describe the corresponding values at run
time; otherwise, the consequences are undefined. ...
...
-Rob
[1] All uses of "compiler" above should be understood to mean
"compiler or evaluator" [interpreter].
[2] https://www.urbandictionary.com/define.php?term=nasal+demons
-----
627 26th Avenue <http://rpw3.org/>
San Mateo, CA 94403
Thank you, taruss, rob. So, when the focus is correctness then in case
of Common Lisp it's better to leave out type declarations through
DECLARE and DECLAIM except when doing them "indirectly" through
CHECK-TYPE or ASSERT.
t***@google.com
2020-06-21 23:24:52 UTC
Reply
Permalink
Post by Lieven Marchand
Post by Nelson Alexandra
How should the return type of a function be annotated to functions?
Should it be annotated as documentation string or as
expressions like (check-type ..) or (ASSERT ..) or (declare (type ...))?
What is useful for human readers and what for the compiler?
How is it "usually" done?
Can someone point at representative examples in libraries?
Would you recommend libraries that help specifying argument and return
types?
You can use DECLARE with ftype.
(declare (ftype (function (integer list) t) ith)
(ftype (function (number) float) sine cosine))
So ith is a function that takes an integer and a list and returns
whatever.
FTYPE declarations are the official way to annotate functions, and would
arguably be the best answer for humans (or else comments).

The compiler is always free to ignore type declarations or any sort, although
production-level compilers will typically use them to optimize code. Note,
though, that type declarations of all sorts are *promises* to the compiler and
do not require that the compiler check them (the consequences are undefined if
the type is not as promised).
If you want to insure that the type (or return type) is actually checked, then
you must use the CHECK-TYPE function.

In code I'm familiar with, except for especially time critical code, types are
not specified. And FTYPE annotations are even more rare.
Robert Brown
2020-06-28 00:30:44 UTC
Reply
Permalink
Post by Nelson Alexandra
How is it "usually" done?
Can someone point at representative examples in libraries?
Repositories https://github.com/brown/sip-hash and
https://github.com/brown/city-hash use lots of type declarations.
Nelson Alexandra
2020-06-29 18:49:21 UTC
Reply
Permalink
Post by Robert Brown
[...]
Repositories https://github.com/brown/sip-hash and
https://github.com/brown/city-hash use lots of type declarations.
Many thanks for the hint!

Loading...