bedeke
2020-8-28 07:23:59

I think it’s intended. At least it is in line with what I would expect if function, or parametric would give a result that is +nan.0. I would find it weird if there was a line between (–1 0) and (1 0). (plot (function (λ (x) (flsqrt (- (flabs (fl x)) 1))) -2 2))


bedeke
2020-8-28 07:24:25

(then again, I’m biased in this discussion)


alexharsanyi
2020-8-28 07:34:27

Yes, I suspect this was added to support the function and parametric renderers. And it is fine for the functions passed to these renderers to return +nan.0 or +/-inf.0 and plot should handle that. The question is whether lines should do that as well, or rather, whether it is documented behavior for lines. The fact that function is internally implemented in terms of lines is an implementation detail, not a documented API.

I am not suggesting that we change the behavior, just that we don’t document it. That is: • you can plot functions which return +nan.0 or +/-inf.0 , and this behavior will be guaranteed to work in the future • using +nan.0 values in the lines renderer works now, but you should not rely on it. Than again, if using +nan.0 values for lines is in wide use already, we might as well document lines as well and put a comment in the code where the “magic” happens to make it explicit, so we make sure we don’t break it.


bedeke
2020-8-28 07:40:25

I don’t mind removing it from the documentation. I would expect lines to continue functioning this way, but when it doesn’t, as you said, just use lines twice.


laurent.orseau
2020-8-28 07:59:13

@sorawee Can we view the invocation of the continuation from call/ec as unstacking the call stack until reaching the same context as the call/ec site? And call/cc as copying the state as you say? @343519265 Do you happen to have a link to a comparison by any chance?


343519265
2020-8-28 08:12:56

@laurent.orseau#lang racket/base (collect-garbage) (time (for ([_ (in-range 10000000)]) (call/cc (λ (k) (+ 1 (k 0)))))) ;cpu time: 487 real time: 487 gc time: 7

(collect-garbage) (time (for ([_ (in-range 10000000)]) (call/ec (λ (k) (+ 1 (k 0))))))

;cpu time: 794 real time: 794 gc time: 13


laurent.orseau
2020-8-28 08:19:39

Thanks! Do you happen to have BC on the same machine too? :)


343519265
2020-8-28 08:21:34

No, because in cs I think this is understandable, because call/cc is simply chez call/cc + a few things, while call/ec needs to touch metacontinuation frames additionally


laurent.orseau
2020-8-28 08:22:29

Do you mean that Chez doesn’t have call/ec?


343519265
2020-8-28 08:32:39

probably call/ec is better when we have plenty of prompts in stack, but i think it is rare.


343519265
2020-8-28 08:35:59

chez has call/1cc which is efficient for escape, but it seems racketcs didn’t make use of it.


laurent.orseau
2020-8-28 08:37:29

Can’t call/ec be implemented in terms of call/1cc then?


343519265
2020-8-28 08:56:12

for chez call/ec can be implemented as call/1cc plus dynamic extent checking, but for racket, probably marks, prompts and threads make it complicated. I am not sure


laurent.orseau
2020-8-28 09:07:19

Oh I see, bummer


notjack
2020-8-28 09:37:21

you could make plot log a debug level message whenever +nan.0 is used with lines and then build and test every package and any large apps you know of, that might give you a sense of how widespread its use is.


alexharsanyi
2020-8-28 11:19:09

The issue is that the documentation for two new renderers now mentions this behavior explicitely, and the question is whether to keep that in the documentation (and therefore making this feature official) or to leave it out. It is not an essential feature for the renderers themselves either…


bedeke
2020-8-28 11:29:17

Just for reference, this “feature” is part of the plot-device, and not so much of lines etc. But I think there are valid alternatives to get the same result, so I will take it out of the documentation.


samth
2020-8-28 11:49:02

Also, chez’s call/cc is fast so the optimizations make less difference


laurent.orseau
2020-8-28 11:59:24

Right. Does that mean that let/cc is now recommended for simple escape continuations instead of let/ec?


samth
2020-8-28 13:08:35

I think you should still use the same thing if you don’t need full continuations


laurent.orseau
2020-8-28 13:15:53

to make the intent clearer you mean?


samth
2020-8-28 13:16:24

And it’s faster on BC and it may be faster on CS


greg
2020-8-28 13:32:14

As a first approximation how about there being a new parameter for the error display handler to consult. The parameter is something like a list of module paths to ignore (if an error’s srcloc matches that modpath).


greg
2020-8-28 13:32:31

And it defaults to something like “modpaths from ‘main-distribution’”?


greg
2020-8-28 13:33:17

Letting a user configure this — or a tool that helps a certain kind of user — might be useful. Similar to why it’s handy to configure logger output.


samth
2020-8-28 13:33:19

I don’t think “main-distribution” is the right thing here — “inside the runtime system” seems more likely


greg
2020-8-28 13:34:03

OK yes I’m not sure the right default, I’m sure you’re right about htat.


greg
2020-8-28 13:34:53

I guess I’m just pointing out the obvious that this is similar to logger output, or to macro-hiding in the step expander. In that, what is good to ignore, depends.


samth
2020-8-28 13:35:14

both on general grounds, that “main-distribution” is not intended to be special, and that errors inside plot or pict are not really different from inside other libraries


samth
2020-8-28 13:35:24

but yes, I agree with the general point about hiding


greg
2020-8-28 13:38:49

It’s really just that, between “beginner” and “core Racket developer”, there are some useful degrees of hiding. Even for the same person, depending on what they’re working on.


sorawee
2020-8-28 14:42:57

I can imagine both function and lines compile to line-internal, which allow NaN, but lines does not.


mflatt
2020-8-28 19:36:14

For now, I’ve made the easy change of just dropping builtin functions from the trace (disable filtering by setting PLT_SHOW_BUILTIN_CONTEXT), and we can see whether that’s better or worse.


cris2000.espinoza677
2020-8-29 03:22:41

hello again, i was trying to make a list in a more lispy way while trying to make a list out of tokens given by a lexer from <https://docs.racket-lang.org/br-parser-tools/Lexers.html?q=br-parser-tools|Parser Tools> . i came up with something, that was close to what i remember seeing in the internet. but i realized that it maybe doesn’t count as tail-call recursion, so it probably wouldn’t get optimized? i know in this case i can replace it with for/list or for/fold maybe. but i want to know if there’s a correct way to write this. (define (tokens-&gt;list next-token) (let loop ([r (next-token)]) (cond [(not (void? (position-token-token r))) (cons (position-token-token r) (loop (next-token)))] [else (cons r '())]))) you can see cons is receiving a loop call as its second argument.


sorawee
2020-8-29 03:25:00

I think the worry about non tail recursion is usually exaggerated. Racket has a “deep stack” feature which allows you to recur however deep as long as there’s enough memory, so what you are doing is perfectly fine.


jcoo092
2020-8-29 03:26:08

I seem to recall that a while ago someone investigated tail-recursive and non-tail-recursive versions of some function, and found that the non-tail one ran faster, without them ever hitting memory problems.


cris2000.espinoza677
2020-8-29 03:28:05

ok thank you for the information! once again~


cris2000.espinoza677
2020-8-29 03:28:52

although i was curious if there was a lispy way that was standard for doing accumulation.