Two days ago, Matthias Felleisen wrote: > > Your uses of values are covered in apply/map/append/list > trickeries. Using values might be more elegant, but yes, it's > currently not possible.
Not possible, but as usual, easy to play with (if you're willing to pay the runtime overhead). Since it's a semi-popular subject that comes up frequently enough, at some point I made it into a "language one-liner" thing -- it's a cute exercise but unfortunately multiple values are already an "exotic" enough feature to make it into a good enough first-language thing... You start with a quick macro as a first step (I haven't looked, but it's probably close to what Neil posted): #lang racket (define-syntax-rule (vals expr ...) (append (call-with-values (lambda () expr) list) ...)) (define-syntax-rule (app f expr ...) (let ([l (vals f expr ...)]) (apply (car l) (cdr l)))) The next step is to rename things so you can use it implicitly in the rest of the code for all function applications #lang racket (require (only-in racket [#%app r:app])) (define-syntax-rule (vals expr ...) (r:app append (r:app call-with-values (lambda () expr) list) ...)) (define-syntax-rule (#%app f expr ...) (let ([l (vals f expr ...)]) (r:app apply (r:app car l) (r:app cdr l)))) ;; (define (foo) (values list-ref '(x y z))) ((foo) 1) ; => 'y but then you take it in the other direction, and make it into a language instead, first do it with sub-modules: #lang racket (module values racket (define-syntax-rule (vals expr ...) (append (call-with-values (lambda () expr) list) ...)) (define-syntax-rule (app f expr ...) (let ([l (vals f expr ...)]) (apply (car l) (cdr l)))) (provide (rename-out [app #%app]) (except-out (all-from-out racket) #%app))) (require 'values) (define (foo) (values list-ref '(x y z))) ((foo) 1) ; => 'y And finally just remove the sub-module wrapper and make it into a "proper" language. (BTW, for people on IRC: one feature of rudybot is that you can initialize it from a URL holding some code -- so it's probably still possible to use "init http://tmp.barzilay.org/values.rkt" to play with this. (Yeah, just confirmed that it still works.)) Two days ago, Matthew Flatt wrote: > To elaborate on "currently not possible" (because this idea shows up > from time to time), allowing splicing of results in function-call > subexpressions would break equivalences that are currently exploited > by macros and the compiler. IMO, it's a bad idea for a more basic problem: you get functions to interact with each other based on where they appear in the code. The above is an extreme example of an application with three different types, so if you have: (define (foo) (values list-ref '(x y z))) (define (bar) 1) ((foo) (bar)) and you decide to return just the function from `foo', then you need to adjust `bar' too. This means that changes in return arity are very expensive since you need to track down all caller sites and revise them. (You need to do that now too -- but if you forget something you'd almost always get an error instead of random-and-possibly-buggy- behavior.) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! ____________________ Racket Users list: http://lists.racket-lang.org/users