mark.piffer
2022-1-31 11:14:09

@mark.piffer has joined the channel


mark.piffer
2022-1-31 11:15:02

:raising_hand:


spdegabrielle
2022-1-31 11:26:10

Welcome @mark.piffer :grinning:


spdegabrielle
2022-1-31 11:27:04

Here’s a checklist to make things easier when asking for help, in order: 1. It is ok to just ask the question - permission is not required. 2. What is the task? 3. How far have you come? 4. What exactly are you struggling with? 5. What approaches have you tried to solve it? Encouragement: you can get better - keep practicing and keep asking questions :heart:


mark.piffer
2022-1-31 12:24:05

Which is the correct way to letor define (i.e. bind names to) the first n values of a list? I tried to recurse with a values but this is obviously the wrong approach (define (values-rec n lst) (if (= n 1) (values lst) (values (first lst) (values-rec (- n 1) (rest lst)))))


mark.piffer
2022-1-31 12:25:24

Usage hould have been (values-rec 3 '("a" "b" "c" "d" "e"") -> "a" "b" '("c" "d" "e")


mark.piffer
2022-1-31 12:26:10

For (define-values ...)of course, I forgot


soegaard2
2022-1-31 12:26:10

If you have a list of values, say, '(1 2 3) and want to compute (f 1 2 3) you can use apply as in (apply f '(1 2 3)). In this case, you want to compute (values 1 2 3), so you can use (apply values '(1 2 3)).


soegaard2
2022-1-31 12:26:51

Where ’(1 2 3) needs to be a list of the first n elements of lst.


ben.knoble
2022-1-31 13:42:01

I would probably look at split-at to split the list, and then define-values with apply values on the head; or, use match-define with a pattern for your specific n (maybe a macro could generate part of it?)


mark.piffer
2022-1-31 14:38:28

I’m having a conceptual problem in understanding what values is actually returning


mark.piffer
2022-1-31 14:39:14

it is not a list, that much I do understand


soegaard2
2022-1-31 14:45:10

Normally an expressions evaluates to a single value: > (+ 1 2) 3


soegaard2
2022-1-31 14:45:38

Some computations naturally have two results.


mark.piffer
2022-1-31 14:46:25

yes, I read that in the Racket Reference


soegaard2
2022-1-31 14:46:41

For example: > (split-at ’(a b c d) 2) needs to return both (a b) and (c d).


mark.piffer
2022-1-31 14:46:48

but what is the type of a two-value result?


soegaard2
2022-1-31 14:47:23

You can think of two values as an implicit tuple.


soegaard2
2022-1-31 14:47:57

If you think of the computation in term of a stack, (values 10 11) simply pushes two values to the stack.


soegaard2
2022-1-31 14:48:34

In (define-values (a b) (values 10 11)) the identifiers are bound to the two top values on the stack.


mark.piffer
2022-1-31 14:48:55

how do functions consume these sstacked arguments?


mark.piffer
2022-1-31 14:49:19

only via the bound names?


soegaard2
2022-1-31 14:49:36

Most contexts expect to receive only one value. So for example (+ (values 10 11) 3) gives an error.


soegaard2
2022-1-31 14:50:31

You know about define-values and let-values but besides them call-with-values is the most imported way of using multiple values.



mark.piffer
2022-1-31 14:51:55

ah ok! That was the missing piece. Interesting.


mark.piffer
2022-1-31 14:52:02

thank you


soegaard2
2022-1-31 14:53:55

I don’t think multiple return values are unique to Scheme/Racket, but most programming languages don’t have them. Most other languages use tuples instead.


rokitna
2022-1-31 14:55:28

I believe compose can also be an alternative to call-with-values. I think ((compose list split-at) '(a b c d) 2) will give a first-class list instead of two values.


rokitna
2022-1-31 14:56:38

just tried it and it does :)


badkins
2022-1-31 15:01:24

Also, let-values , define-values, etc. are handy. <file:///Users/badkins/sync/github/racket/racket/doc/reference/values.html#%28def.%28%28quote.~23~25kernel%29._values%29%29|See here>


ben.knoble
2022-1-31 15:14:08

Conversely, compose1 forces a single value, which can be useful