Juan Jose Garcia-Ripoll <juanjose.garciarip...@googlemail.com> writes:
> On Fri, Jun 1, 2012 at 12:20 PM, Stas Boukarev <stass...@gmail.com> wrote: > >> As per CLHS, >> http://www.lispworks.com/documentation/lw50/CLHS/Body/04_bc.htm >> "*" means unspecified part of the type specifier. >> >> (declaim (ftype (function * integer) f)) >> >> (defun f (a) >> (1+ a)) >> >> and then (compile-file "file.lisp") >> >> ;;; LAMBDA: Illegal lambda list *. > > > Actually, the behavior you expect is undefined. While * is used to design > parts of the type that are general, not specified, the situations in which > * is used are very precisely marked by the Standard. Note for instance the > difference between the grammar for the ARRAY type > > http://www.lispworks.com/documentation/lw50/CLHS/Body/t_array.htm#array > > and that of the FUNCTION type > > http://www.lispworks.com/documentation/lw50/CLHS/Body/t_fn.htm > > Only the former allows * > > One could allow ECL to "support" * by ignoring all function declarations > where it appears. I presume this would help with certain libraries that use > these nonstandard types. Let's revisit this. I'm not convinced that it is illegal. http://www.lispworks.com/documentation/lw50/CLHS/Body/04_bc.htm says "If a type specifier is a list, the car of the list is a symbol, and the rest of the list is subsidiary type information." (function ..) fits that. Now it states "Except as explicitly stated otherwise, the subsidiary items can be unspecified." Ok, we check http://www.lispworks.com/documentation/lw50/CLHS/Body/t_fn.htm nowhere does it state that it's not allowed. Back to 4.2.3 "If a list has one or more unspecified items at the end, those items can be dropped. If dropping all occurrences of * results in a singleton list, then the parentheses can be dropped as well (the list can be replaced by the symbol in its car). For example, (vector double-float *) can be abbreviated to (vector double-float), and (vector * *) can be abbreviated to (vector) and then to vector." So, just FUNCTION is allowed, but according to the above, it's the same as (function * *). It is indeed true that for other compound type specifiers * is explicitly mentioned as allowed. But what about cases when it's not allowed? There's a table of "compound type specifier names but that cannot be used as atomic type specifiers." and mod satisfies eql not values member or ====== and http://www.lispworks.com/documentation/lw50/CLHS/Body/t_and.htm * is not permitted as an argument. eql http://www.lispworks.com/documentation/lw50/CLHS/Body/t_eql.htm The object can be *, but if so it denotes itself (the symbol *) and does not represent an unspecified value. member http://www.lispworks.com/documentation/lw50/CLHS/Body/t_member.htm * can be among the objects, but if so it denotes itself (the symbol *) and does not represent an unspecified value. not http://www.lispworks.com/documentation/lw50/CLHS/Body/t_not.htm The argument is required, and cannot be *. or http://www.lispworks.com/documentation/lw50/CLHS/Body/t_or.htm * is not permitted as an argument. http://www.lispworks.com/documentation/lw50/CLHS/Body/t_satisf.htm The symbol * can be the argument, but it denotes itself (the symbol *), and does not represent an unspecified value. values http://www.lispworks.com/documentation/lw50/CLHS/Body/t_values.htm he symbol * may not be among the value-types. ====== So, all of them very explicitly forbid *. FUNCTION just happens to be the only of compound type-specifiers which can be used as just "function" and which doesn't mention *. Now why the type-specifiers above forbid */have a different meaning? Because it doesn't make sense for it to appear there. What would (not *) mean? Nonsense. But does it make sense for FUNCTION to have *? Of course, it would just mean that such a part can be anything, and indeed just "FUNCTION" working fine is an evidence of this. Is it useful? It is, (function * fixnum) denotes that it accepts whatever but returns a fixnum. Now somebody might say "But you can use (function (&rest t) fixnum) instead, which cannot be said for (vector *), because it has a different meaning from (vector t)." That's true, but (cons *) is equivalent to (cons t), and yet it's explicitly allowed: http://www.lispworks.com/documentation/lw50/CLHS/Body/t_cons.htm And let's look at the other parts of the standard. It has a lot of instances where things are not explicitly mentioned, but are implied from other parts, for example: http://www.lispworks.com/documentation/lw50/CLHS/Body/19_bc.htm "Except as explicitly specified otherwise, for functions that manipulate or inquire about files in the file system, the pathname argument to such a function is merged with *default-pathname-defaults* before accessing the file system (as if by merge-pathnames)." and http://www.lispworks.com/documentation/lw50/CLHS/Body/f_dir.htm doesn't mention anywhere that it merges the pathname, and yet nobody disputes that it should. And it even has the same wording "Except as explicitly stated otherwise". I have no doubt that (function * t) is a valid and useful type-specifier, and all other implementations accept it. -- With best regards, Stas. ------------------------------------------------------------------------------ LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers http://p.sf.net/sfu/logmein_12329d2d _______________________________________________ Ecls-list mailing list Ecls-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ecls-list