gknauth
2021-2-23 14:06:09

I forgot the name of the site where Racket gists can be run…


soegaard2
2021-2-23 14:06:53

pasterack


gknauth
2021-2-23 14:29:56

Thanks @soegaard2!


yilin.wei10
2021-2-23 21:21:23

Is this for internal or external structs?


jestarray
2021-2-23 22:20:00

unsure what you mean by extermal/"internal", as in the standard library?


jestarray
2021-2-23 22:21:04

it works for nearly all functions


badkins
2021-2-24 01:21:37

Is (void) really a procedure call, or does the compiler replace it with nothing? I would like to collect some (potentially expensive) statistics sometimes, and at other times the forms that update the stats would be no-ops. So, it seems I’ll need a macro that expands to essentially nothing.


badkins
2021-2-24 01:22:22

This is in a speed-sensitive portion of the program, so I’d prefer there to be absolutely zero effect when not in stats gathering mode.


badkins
2021-2-24 01:27:52

https://stackoverflow.com/questions/40082458/can-a-racket-macro-expand-to-nothing (void) or (begin) is suggested. I’d just considered (begin) before googling that.


samdphillips
2021-2-24 01:29:03

I was thinking (begin)


samdphillips
2021-2-24 01:29:12

#lang racket/base (require (for-syntax racket/base)) (begin-for-syntax (define debug? #f)) (define-syntax (do-the-thing stx) (if debug? #'(println "doing the thing") #'(begin))) (do-the-thing)


samdphillips
2021-2-24 01:30:14

But I think in an expression context it may error?


sorawee
2021-2-24 01:31:17

(void) is a procedure call. Macro expansion doesn’t do anything special with it. However, partial evaluator (cp0) can optimize away (void) in specific situations


sorawee
2021-2-24 01:32:17

On the other hand, begin is a form, so macro expander will do something with it.


sorawee
2021-2-24 01:34:48

Yep, it would be an error to write (begin) in an expression context.


badkins
2021-2-24 01:35:15

In my particular case, I suppose I could expand to just about any cheap value, e.g. #f since the expression will be ignored. This is for my chess engine which necessitates coding in a mutating style in many places. It’s been fun, but man, do I appreciate functional programming even more after this experience :)


badkins
2021-2-24 01:36:24

(begin) probably makes the most sense, and hopefully the compiler will realize (begin) doesn’t add any value and will optimize it away.


sorawee
2021-2-24 01:37:06

cp0 is really aggressive. Putting (void) or #f in a uselessly probably will have the same effect: they get optimized away


badkins
2021-2-24 01:37:40

Yes, but I need to be sure, as in “take off and nuke ’em from space” sure :)


badkins
2021-2-24 01:38:41

“sure” as in no function call is made - I don’t care as much about an unused value


sorawee
2021-2-24 01:39:35

If you use Racket CS, try

#lang racket (provide f) (define (f x) (void) (void) (void) (void) (void) (void) (void) (void) #f (+ x 1))


sorawee
2021-2-24 01:39:53

and run PLT_LINKLET_SHOW_CP0=1 racket filename.rkt


sorawee
2021-2-24 01:40:09

The resulting program after cp0 is:

(lambda (instance-variable-reference .get-syntax-literal!1 .set-transformer!2 f3) (letrec ([f (lambda (x_1) (#2%+ x_1 1))]) (variable-set!/define f3 f 'consistent)))


badkins
2021-2-24 01:40:52

Cool :)


samdphillips
2021-2-24 01:47:19

Other magic compiler environment variables: https://docs.racket-lang.org/reference/compiler.html