Many thanks @greg . I am using racket-mode version , Just to be sure, I deleted racket-mode and reinstalled. I’m now wondering if the problem is that I am using emacs 27.1; if I understand the NEWS file correctly, there were some changes in the way that emacs handles images.
I will copy this to the GitHub thread, and do some more digging.
Hello there, I’m trying to debug a language module. How can I print out the macro expanded result before the code get evaluate?
A language module written by you or someone else?
raco expand
@soegaard2 Written by me.
Or the macro stepper
I just want to print out the fully expanded result.
Is accessing parallel lists like (list-ref l2 (index-of l1 v))
idiomatic? If not, what is?
@joshibharathiramana it really depends what you’re doing, but why are you searching in l1, and why are the lists parallel? it’s hard to answer without knowing that.
@samth I was reading <https://docs.racket-lang.org/guide/lambda.html?q=closure#%28part._lambda-keywords%29|Declaring keyword arguments section> in The Racket Guide which has the example (define (trace-wrap f)
(make-keyword-procedure
(lambda (kws kw-args . rest)
(printf "Called with ~s ~s ~s\n" kws kw-args rest)
(keyword-apply f kws kw-args rest))))
So it got me thinking how one would access things in kw-args
. Is there any idiomatic code I can look at that uses keyword arguments?
(on a side note, isn’t it bad practice to shadow names like rest
? Wouldn’t it be better if the example used something like rest-args
instead?)
I don’t think it’s bad practice to shadow rest
When you use keyword arguments you typically don’t have to deal with lists of arguments at all. make-keyword-procedure
is very rarely needed.
But usually if you had something like that you’d need to process all the keywords and arguments, and thus I’d use something like map
over both lists, or a for
loop that iterated over both lists.
why/when would I want to use values
instead of just returning a list of results?
A list requires at least N (for the length of the list) memory allocations, whereas values
just passes the values back.
There are downsides to values
though in that procedures that use values
don’t compose as well as ones that return single values.
@samdphillips > A list requires at least N (for the length of the list) memory allocations, whereas values
just passes the values back. when a procedure returns N values, won’t they have to be allocated somewhere in memory? Why is it that a N-list would be worse?
What I mean is, consider (define (why-values x y)
(values (* x x) (+ y y)))
(define (list-instead x y)
`(,(* x x) ,(+ y y)))
Now > (why-values 3 4)
9
8
> (list-instead 3 4)
'(9 8)
Both why-values
and list-instead
need to allocate memory for both the results, correct?
I think it’s the case that, yes, the return values must be allocated in both cases, however, when using a list
, the list itself has to be allocated, whereas, when using values
, no additional data structure is being allocated to hold the results, instead, they get passed along directly. (please correct me if I’m wrong)
That’s right.
Thank you! Follow up question - is there an example that shows something that is elegant to do with vaules
but ugly with list
?
Here’s one: (define-values (a b) (let/cc k (let loop () ... some code here ... (k 1 2))))
passing multiple arguments to the continuation is just returning multiple values
Wow, that’s really neat
Probably the multiple value function I find the handiest is quotient/remainder
because 99% of the time you need the separate values and deconstructing a list in that case would be annoying.
> The https://docs.racket-lang.org/reference/case.html#%28form._%28%28lib._racket%2Fprivate%2Fmore-scheme..rkt%29._case%29%29\|case form can dispatch to the correct clause in _O_(log N) time for _N_ datums. From Racket Guide <https://docs.racket-lang.org/guide/case.html?q=closure#tocview_1:~:text=The%20case%20form%20can%20dispatch%20to%20the%20correct%20clause%20in%20O(log%20N)%20time%20for%20N%20datums.|Simple Dispatch : case> can someone give a high level description of how Racket does this in O(log N)? I was expecting it to take O(N), I find O(log N) both impressive and surprising.
My guess would be that a case
form is compiled into some sort of jump table.
Oh, that’s much more sophisticated than I implied :sweat_smile:
Is there an efficiency difference between letrec
and the other let
forms?
@soegaard2 thank you for linking the paper, it is very well written :smiley:
Another great paper, thanks, @soegaard2!