
Hi, Max Mikhanosha wrote:
included patch was more to start the discussion and wasn't intended to be a finished product. Ah, ok. Indeed, one can wonder whether Iterate could provide a standardized means to return multiple values. The discussion is open.
collect (values a b c) returns 3 lists? That is too limited to be useful IMHO. In many cases, one wants to return values of different kind, e.g. a sum and a length, or a list. Iterates only mechanism for this is collecting into named variables. I believe no other mechanism would match Iterate's design (e.g. it's not Series or comprehensions), at least I can't think of any.
(if *result-var* `(values ,@(ensure-list *result-var)) nil) I believe putting *result-var* to different uses, either as symbol or list of symbols, may cause more headaches than good (consider user written extensions as macros). But I have not thought through the situation (lack of time).
- finding (the fixnum (values ....)) being same as enclosing each individual value in fixnum, otherwise code looks too heavy with relatively many values like >4 being returned.. LOOP has similar shortcut (loop for (a b c) fixnum) and its very useful.
There's a comment about this in the code, which seems to exclude exactly this situation: ;;; Possible extension: ;;; When more than one variable can occur, we allow a single ;;; the-expression to cover them all. Unfortunately, this makes ;;; things rather hairy--probably better to avoid it. ;[defun distribute-type-spec commented out] The comment (from J. Amsterdam) does not say what exactly becomes hairy. I have no clue wether Amsterdam means a hairy design or a hairy implementation or whatever.
For my own uses I'm pretty happy with a quick-fix I got. What do you mean? your patch, my defmacro-clause or something else?
Another reason is that even as you said implementing this with defmacro-clause does not allow (finding-values (values (the fixnum a) (the fixnum b)) type of expression, that would make "MAX" variable type known.
What do you mean? It should be straightforward to support this in my finding-values defmacro-clause, using THE. Generate (with (the type var1)) or (with (foo (the type var1) the ...)), with types taken from either the expression or the INTO variable list. Similarly for the syntax `maximizing (the type (foo))' The macro slowly grows cumbersome, as standard CL syntax is (the (values type1 ...) expression), but so far my macro special-cased the pattern (VALUES ...) as expressions, as in (find-values (values (the integer (foo)) (the real (bar))) maximizing ...) Maybe that would make a good tutorial example, as it shows how simple code grows more and more complex with the supported features? You may wish to explore the THE path (together with iter:declare-variables) for your performance-critical iteration needs.
- finding (n-values-of 2 (foo x)) ; returns 2 values returned by foo or - finding (2-values-of (foo x))) ; will have to parse symbol name What about (finding expr &optional VALUES 2 INTO var-spec) ? But then type decls would become cumbersome to parse, e.g. for (finding (the (values t1 t2) (floor x y)) values 2)
Also note that (the integer (values x y)) is a perfectly legal CL expression, but it's meaning is not to distribute the type across the 2 values. Thus one can argue that it's not allowed to extend the meaning of a legal expression to a different meaning. Such an extension could be plain wrong. E.g. consider a pseudo accessor FROB implemented as a macro, which expands to gethash. Saying (the integer (FROB)) means that I only care about the primary value, not the second "present-p" one, IMHO. (the (values integer integer) (FROB)) would be an error, as the second value is a boolean. Regards, Jorg Hohle