Open countvajhula opened 2 years ago
Actually, I'm not sure what I was thinking because the example above isn't hard in Qi, it would just be:
(~> () (time-apply + (list 1 2 3)) list)
One possible improvement could be to have a Racket-level macro that eliminates one step:
(~>* (time-apply + (list 1 2 3)) list)
This doesn't need parens around the first form since we would assume that it is a (Racket) expression that is going to generate any number of values. This form might also be preferable to ~>
in all cases where we would otherwise do (~> () ...)
.
I've gone back and forth between these and settled on the former because it's less to type and, to me, clearer that there are no more values as input to the initial expression. It would be nice to not have to write the ()
though.
(~> () (time-apply + (list 1 2 3)) list)
;; or
(~> (time-apply + (list 1 2 3)) apply list)
And, I think ~>*
could be a library macro (meaning it doesn't have to be provided by Qi for folks to start trying it out). I also admit that this case comes up fairly rarely for me, but maybe that's because so few things use multiple-valued returns :)
P.S. The apply
trick in my last post doesn't work with send
, either, so that's another argument in favor of using (~> () …)
That apply trick 😆 I had to do a double take.
re: ~>*
as a library function, are there other forms that could be included in such a library or would it be a dedicated one like (require qi/thread*)
?
I guess it would also include on*
and switch*
? Interesting.
On the other hand, if we consider multiple values as a first class citizen in Qi, then it feels natural that these forms should have an equal position in the core library to forms like ~>
that support single-valued Racket outputs. Would it make sense to move even ~>
, on
, switch
(everything except flow
) into libraries? Early in the compiler project we talked about the possibility of having qi/base
and qi
like racket/base
and racket
, but I think we were mainly thinking about the core language forms. Maybe this would affect interface macros too.
RE: libraries, I'm not really advocating one approach over another. Just that it can be done if that was desirable (say, to put it an experimental lib before committing to it publicly).
I could also see trying to extend ~>
and various other interface forms (https://docs.racket-lang.org/qi/Language_Interface.html#%28part._.Using_.Qi_from_the_.Host_.Language%29) to accept expressions that generate multiple values. Example:
(~> (1 (time-apply + (list 1 2 3)) 3))
;; equivalent to (values 1 <splice all the result values of time-apply> 3)
Working with multiple values in Racket is cumbersome, requiring the use of e.g.
call-with-values
. In Qi it's typically much more natural. So it would be great if in all such cases we could just use Qi. But in the case of a single expression that generates multiple values, Qi doesn't currently have an especially compelling way of handling it.E.g. the
time-apply
utility returns many values. We'd like to be able to use its results in a convenient way.With Racket:
With Qi, currently:
Preferable, something like:
Could it be even nicer?
Is
gen*
a good name for this?