greg
2021-11-22 13:36:43

Ugh that sound frustrating. :frowning: Thank you for pursuing it so doggedly!


greg
2021-11-22 13:40:16

The last pair of screenshots is interesting — how it starts midway through the racket.


greg
2021-11-22 13:42:06

Unfortunately. I don’t have any quick theories of the bug. And I’m up to my eyeballs in some other issues atm. But I want to capture your report/research in a GitHub issue so it doesn’t get lost. So I’ll do some copy/paste for now….



laurent.orseau
2021-11-22 13:59:48

Is there a way for a message% to receive a mouse event? I tried overriding on-subwindow-event without success. Is it related to the fact that a message% can’t have the focus, and on-traverse-char does not forward key events to them? (It seems different to me though)


greg
2021-11-22 14:00:50

@badkins What version of Racket are you using?


spdegabrielle
2021-11-22 14:02:27

Does it pass events straight to the underlying container?


laurent.orseau
2021-11-22 14:03:08

A button% in the same panel does receive clicks (left or right) when overriding the aforementioned method


laurent.orseau
2021-11-22 14:03:53

(but I would like a message% because there’s not button-like border and I want to customize the behaviour)


spdegabrielle
2021-11-22 14:09:01

I seem to remember something about controls that don’t handle events(unlike button) passing them to the parent object. I’m not sure where in the docs - I could be wrong. And I’m not sure how to determine the position/area of the child message% obj.


laurent.orseau
2021-11-22 14:11:25

Looks like I can cheat, by enclosing the message% into a dedicated panel%, and overriding the event methods works for the latter


laurent.orseau
2021-11-22 14:11:35

It’s weird though


badkins
2021-11-22 14:33:32

Welcome to Racket v8.2.0.8 [cs].


jjsimpso
2021-11-22 14:35:56

That is exactly what I did for my app. I used a subclass of horizontal-panel% to handle the events.


cperivol
2021-11-22 17:40:19

I am trying to define a macro that shortens the definition of an generic method:

(define-syntax (const-method stx) (syntax-parse stx [(_ method:id) #:with args (datum->syntax stx (for/list [(i (in-range (procedure-arity method))] (string->symbol (format "arg~a" i))) #'(define (method args ...) 'constant-value)]))


cperivol
2021-11-22 17:41:01

There are probably other problems with this but the main one is that it doesn’t let me use a pattern variable outside a template


soegaard2
2021-11-22 17:42:07

This (procedure-arity method) should probably be (procedure-arity #'method).


soegaard2
2021-11-22 17:43:38

But from method:id we know that method is an identifier, so (procedure-arity #'method) doesn’t work, since procedure-arity expects a function.


cperivol
2021-11-22 17:44:58

right… so how do I get arity of the function corresponding to method?


soegaard2
2021-11-22 17:46:08

I don’t know how generic methods are implemented. But maybe a method definition also stores some information at compile time that can be used?



cperivol
2021-11-22 17:48:44

I was trying to implement this https://docs.racket-lang.org/reference/struct-generics.html but it looks like its the same thing right?


sorawee
2021-11-22 17:53:43

It may be helpful to provide a concrete usage of the macro, and what you think it should expand to.


soegaard2
2021-11-22 17:54:16

It’s not the same thing. One is for objects and the second is for structures.

The docs on define-generics say: Defines the following names, plus any specified by keyword options. gen:id as a transformer binding for the static information about a new generic interface; So at compile time, you’ll need to lookup the information in gen:id. I think the information is stored as one of the structs mentioned at the end in that section of the documentation.


cperivol
2021-11-22 17:58:58

ok lets forget about structs for a minute because I can’t get it to work even for normal functions:

(define-syntax (macro-arity stx) (syntax-parse stx [(_ fn:id) #:with args (datum->syntax stx (procedure-arity #'fn)) #'args]))


cperivol
2021-11-22 18:00:16

calling (expand (macro-arity +)) sais #%app: missing procedure expression


sorawee
2021-11-22 18:00:36

What do you want (macro-arity +) to expand to?


sorawee
2021-11-22 18:01:18

(FWIW, it probably should be (expand #'(macro-arity +)))


cperivol
2021-11-22 18:01:27

ideally (arity-at-least 0)


sorawee
2021-11-22 18:02:28

Why do you need a macro for that? Can’t you just use procedure-arity?


cperivol
2021-11-22 18:02:53

I need to use that information to build the expansion of another macro


cperivol
2021-11-22 18:03:09

in particular I want to build a function that has the same arity as the one provided


sorawee
2021-11-22 18:04:05

I see. IIUC, this is not possible with procedure-arity. The information is only available at run-time.


sorawee
2021-11-22 18:04:38

What you can do is, you can create your own variant of define that records its arity at compile-time, and then extract it later.


cperivol
2021-11-22 18:06:21

ok, I can live with that. What would be the RightWay of recording compile time information?


cperivol
2021-11-22 18:08:03

Also, side-question, how could you tell that procedure-arity doesn’t read compile-time information?


cperivol
2021-11-22 18:19:35

it is sligtly surprising to me that the arity is not known at compile time since the racket compiler should be able to produce efficient code based on that information..


sorawee
2021-11-22 18:19:55

Something like this:

#lang racket (require syntax/parse/define) (begin-for-syntax (struct fun-info (arity proc) #:property prop:procedure (λ (si stx) (syntax-parse stx [x:id (fun-info-proc si)] [(_ args ...) #:with p (fun-info-proc si) #'(p args ...)])))) (define-syntax-parse-rule (fun name (xs ...) body ...+) #:with arity (length (attribute xs)) (begin (define (the-function xs ...) body ...) (define-syntax name (fun-info 'arity #'the-function)))) (define-syntax (find-arity stx) (syntax-parse stx [(_ x:id) (printf "~a has arity ~a\n" (syntax->datum #'x) (fun-info-arity (syntax-local-value #'x))) #'(void)])) (fun test (a b) (+ a b)) (test 1 2) (define f test) (f 5 6) (find-arity test)


sorawee
2021-11-22 18:20:20

IIUC, the arity is inferred later in the Chez Scheme level. But it’s not known at the macro expansion level


cperivol
2021-11-22 18:21:05

thanks very much for putting in the time!


soegaard2
2021-11-22 18:21:33

At compile time, what should the compiler do when it sees: (define f (if (random 1) list cons)


soegaard2
2021-11-22 18:22:31

The point is that the value of which you would like to know the arity hasn’t been computed yet. That’s why the arity is known at runtime and not at compile time.


soegaard2
2021-11-22 18:22:56

Sometimes the compiler might have a chance, but not in general.


cperivol
2021-11-22 18:23:19

good point


cperivol
2021-11-22 18:23:56

in my case I would like the macro to fail when something like that happens


soegaard2
2021-11-22 18:24:46

Dybvig and others have a series of papers on “flow analysis” which has the goal of determining that type of information at compile time. It’s not as easy as it looks at first sight.


cperivol
2021-11-22 18:25:23

I am realising that…


soegaard2
2021-11-22 18:25:31

I think, sorawee’s suggestion is the best practical solution.


soegaard2
2021-11-22 18:26:00

Unless … define/generics saves the same information somewhere.