jestarray
2020-4-2 07:03:22

maybe i need to re-think my function lol… in short i need to flatten out a variation of lists because my function takes in everything as a rest


soegaard2
2020-4-2 07:04:57

Can you use flatten?


jestarray
2020-4-2 07:08:06

ill check tomorrow


jestarray
2020-4-2 07:09:47

think i tried that before and it didnt cover all the cases i need. honestly im just calling the function in too many werid ways lol


jestarray
2020-4-2 07:09:52

thanks guys


mark.warren
2020-4-2 08:54:09

When using classes in racket, is it normal to throw exceptions when an object is created if the initialisation values are invalid?


soegaard2
2020-4-2 09:15:20

It’s normal to throw an exception to indicate an unusual situation.


mark.warren
2020-4-2 09:15:58

Thanks, I thought it would be sensible.


sorawee
2020-4-2 09:45:10

You can also use contract to do this



sorawee
2020-4-2 09:45:28

Specifically on the “An initialization argument contract”


mark.warren
2020-4-2 09:52:06

Ah good thought, thanks.


sorawee
2020-4-2 15:21:28

@mflatt I want to check an existence of a submodule. I know that module-declare? exists, but it seems that to get it working, I need to set load? to #t. Otherwise, it won’t work. Is there an alternative way that doesn’t involve module loading? Thanks!


sorawee
2020-4-2 15:37:47

Found a workaround. I will let it load, but in a new namespace. This way, when I dynamic-require, it will load again.


sorawee
2020-4-2 15:38:41

Context: I am modifying the compiler to collect some statistics, so when loading happens is kinda important


greg
2020-4-2 15:40:45

Weird. I thought (call-with-values (lambda () (void)) list) would be '() but in fact it is '(#<void>). I thought void meant 0 values.


soegaard2
2020-4-2 15:42:05

<void> is the invisible value - the default printer doesn’t print it - except as part of a compound value.


sorawee
2020-4-2 15:42:58

Yeah, AFAIK, (void) is a single value that is handled specially by the printer to print nothing.


sorawee
2020-4-2 15:43:45

That’s why it’s possible to write (define x (void)). If it’s multiple values (0 values), then that would be an error


sorawee
2020-4-2 15:44:13

E.g., (define x (values)) fails.


greg
2020-4-2 16:02:58

I thought there was supposed to be a correspondence between function parameters and return values. And just like a function can accept zero values, it can return zero values.


greg
2020-4-2 16:03:58

using (void) above is maybe a red herring. (call-with-values (lambda () (newline)) list) also produces not '() but '(#&lt;void&gt;).


soegaard2
2020-4-2 16:07:09

I can think of a couple of reasons. 1. The convention of returning #<void> instead of “no values” is older than the introduction of values . 2. A single value (#<void>) is probably easier to handle for simple interpreters/compilers.


greg
2020-4-2 16:12:37

read-eval-print-loop is, modulo some continuation prompt handling, simply (call-with-values (lambda () ((current-eval) ___)) (lambda results (for-each (current-print) results)))


greg
2020-4-2 16:13:03

(print (void)) prints #&lt;void&gt;. It does not print nothing.


greg
2020-4-2 16:13:33

@sorawee ^


sorawee
2020-4-2 16:14:02

Oh, I meant the top-level printer


soegaard2
2020-4-2 16:14:09

Ditto.


sorawee
2020-4-2 16:14:29

((current-print) (void)) ((current-print) 1)


soegaard2
2020-4-2 16:14:32

&gt; (void)


greg
2020-4-2 16:15:59

I mean I thought why the REPL prints nothing is because results is the empty list


greg
2020-4-2 16:16:43

Not because of anything about current-print.


greg
2020-4-2 16:17:40

I thought I “knew” something basic about call-with-values and multiple values and I’m surprised/confused.


soegaard2
2020-4-2 16:19:43

Well, it is surprising when you stumble upon it the first time.


sorawee
2020-4-2 16:20:17

I guess another reason that it’s not done in that way is that, (when #f 1) evaluates to (void), and (when #t 1) evaluates to 1. Some people might write (define x (when b 1)), and this would cause an error if b is #f and (void) is 0 values.


sorawee
2020-4-2 16:22:02

Though, arguably, no one should use the result returning from when.


soegaard2
2020-4-2 16:25:55

Although it is printer related, the page on void could mention that the value isn’t printed: https://docs.racket-lang.org/reference/void.html


greg
2020-4-2 16:36:20

So to summarize my new understanding: (call-with-values (lambda () (values)) list) is (). Substitute anything other than (values) in that expression, and it will be a non-empty list.


soegaard2
2020-4-2 16:36:57

That sounds right.


greg
2020-4-2 16:39:33

Things like default-print-handler or pretty-printer (some typical values for current-print) do the (void? _) check.


abmclin
2020-4-2 16:51:34

DrRacket can be configured to print #&lt;void&gt;instead of suppressing it; once you do that, you’ll see #&lt;void&gt; everywhere.

My own impression is that (values) meaning no values convention is older than using (void) to mean a non-printed value, but I don’t have any citations to back that up. Over time I’ve gathered that since Racket is primarily an expression-oriented language, having expressions evaluate to no value when they’re embedded in contexts expecting a value create a lot of problems, especially if one is writing macros expanding to expressions within expressions so that lead to the convention of a non-printed value to represent “nothing important to see here”


samth
2020-4-2 16:51:44

there’s extensive discussion about this topic in the r6rs-discuss archives


abmclin
2020-4-2 16:53:01

good to know there’s historical documentation available to dig up


greg
2020-4-2 16:56:01

Is #&lt;void&gt; Racket’s null ? :simple_smile:


mflatt
2020-4-2 16:58:10

Depending on what you are doing, you may want to be working at the level of module code instead of module declarations, in which case get-module-code is the way to go.


greg
2020-4-2 16:58:49

ducks


soegaard2
2020-4-2 16:59:11

chickens


laurent.orseau
2020-4-2 17:14:24

chicken chicken chicken, chicken chicken.


samdphillips
2020-4-2 18:10:45

@greg no we already have a null :stuck_out_tongue:


greg
2020-4-2 18:18:37

uses valuable quarantine time to work on a print-handler that emits things like #&lt;angry void&gt; and #&lt;undefined goose&gt;


soegaard2
2020-4-2 18:21:56

Does it activate the 1st of April?


greg
2020-4-2 18:58:52

Yes, 364 days should be enough QA time to prepare the release


soegaard2
2020-4-2 18:59:46

soegaard2
2020-4-2 19:00:05

A little late, but…



jbclements
2020-4-2 23:48:02

No, that’s not correct. Consider this program:


jbclements
2020-4-2 23:48:10

#lang racket (define (returns-no-values) (values)) (call-with-values (λ () (returns-no-values)) list)


jbclements
2020-4-2 23:53:21

@greg If you want my two cents (you probably don’t): values is a neat idea: let’s generalize the notion of “returning a value” to “returning an unknown number of values”. Oh, look: it’s really neat how this works with continuations! A function that returns multiple values corresponds to a continuation that accepts multiple values. Except that… the overwhelming majority of expressions don’t expect multiple values, so using multiple values (including no values) requires special effort on the part of your caller, so in practice we never use multiple values. This is a bit unfortunate, because there are many situations where we wind up building an ephemeral list or vector just to return two values. I think the elegance of the match between continuation arguments and return values wound up blocking a more pragmatic solution that would allow people to return multiple values without allocation in everyday situations without causing headaches for users. Again, random spewage from me; I’d love to hear what more thoughtful people think.


jbclements
2020-4-2 23:58:21

@soegaard2 many thanks for pointer.


sorawee
2020-4-3 02:46:12

Also consider this program:

(define (loop) (loop)) (call-with-values (λ () (loop)) list)


sorawee
2020-4-3 02:48:37

@jbclements this question is a follow up of https://stackoverflow.com/questions/60962884/stepping-back-in-drracket-stepper which asks how to step to the step before the end. The author actually knows how to step to the end already.


laurent.orseau
2020-4-3 06:26:55

Nice. You could also exit with an exception caught above and return something else