
trying to make my Racket macro-writing experience a bit saner. I’m defining a simple module lang and was hoping (expand-module/step mod)
would let me expand modules that use DSLs, but getting an error, e.g.
test.rkt #lang racket
(require macro-debugger/stepper)
(expand-module/step "./scratch.rkt")
scratch.rkt #lang racket
(module test racket
(let ([x 1] [y 2]) (or (even? x) (even? y))))
Produces: >derivation-parser: error on token #2: <local-value, #<syntax:/Users/ze/Code/racket/racket/share/pkgs/gui-lib/framework/private/sig.rkt:8:20 number-snip-class^>>

A more general question is how do I debug my #lang DSLs? Say, I prepare a file in such a language as in #lang rogue
(some rogue forms defined in ~/rogue/main.rkt)
Language is defined using syntax/module-reader and the collection is properly linked with raco link rogue
, so Rogue script runs fine. How would go about stepping through its expansions steps? I’m trying to figure if I my transformations use bindings i expect, e.g. the redefined #%app etc. Sadly, the above-mentioned (expand-module/step mod)
didn’t work for me out of the box. How do people debug such things?

One more question is about redefining kernel forms like #%app
and friends in my #lang implementation, something like this
rogue/main.rkt has (provide #%datum
#%top-interaction
#%top
(all-defined-out)
(rename-out [app #%app]
[module-begin #%module-begin]))
(define-syntax (app stx)
... my implentation of #%app)
(define-simple-macro (some-rogue-form pattern)
(f a)) ;; <-- which binding of #%app will be used when this form is expanded inside a file written in #lang rogue? How do I confirm this using Racket tools?
(racket-module reader syntax/module-reader
rogue)

omg Macro Debugger tools are awesome!

re the above #%app binding question syntax object browser in the stepper shows the binding comes from racket/base and not from my (rename-out [app #%app])
, which is a bit confusing. I suspect I misunderstand scoping rules here, i.e. I expect #%app to be dynamically scope inside a file that uses my DSL #lang rogue
when really macros defined in rogue
end up expanding into forms that use lexically bound #%app, that is inside the module defining rogue
the language. Could you guys correct my thinking here please?

The implicit #%app
form in (f a)
takes its context from the open parenthesis. (More precisely, (f a)
is a syntax list and there’s a context attached to the list as a whole, in addition to contexts on the individual f
and a
tokens.) Since the #%app
in the environment of (f a)
is the one from racket/base
, that’s the one used when (f a)
is treated as (#%app f a)
.

ah I think I get it. I’m beginning to wonder how we ever managed to redefine kernel forms like #%app and #%module-begin then. I’ve seen things like this being used
(provide (except-out (all-from-out racket)
lambda
λ
define
eval
require
modulo
remainder
/
#%app)
(rename-out [new-lambda lambda]
[new-lambda λ]
[new-define define]
[divide /]
[myapp #%app]
))

When new-lambda
is used as lambda
in some importing module, the expressions written inside that lambda
will also be from the importing module – and so an open parentheses there will see myapp
instead of #%app
from racket/base
. You may be thinking that the body of anew-lambda
use is treated as being from the new-lambda
place, but it’s not; the body is treated as being from wherever it is written (i.e., lexical scope).

feeling enlightened

thank you Matthew! that really helps

ok, now i need to think a bit harder about what I’m trying to do here

fwiw I’m just amazed at how much introspection macro-debugger/stepper offers. Like I’m no longer blind

@mflatt Just a sanity check, environment variables that are set using putenv
are also going to be set in FFI calls, correct?

Oh wait, no, it uses current-environment-variables, never mind.

If (current-environment-variables)
returns its original value, then putenv
affects OS-level environment variables

That makes sense. Thanks.

So basically don’t change the parameter and it works. Thanks. :slightly_smiling_face:

@ryanc @ben do either of you have more comments on https://github.com/racket/rackunit/pull/59 ?

Does anyone know how to be more specific when requesting an opengl context than just core/compatibility?

Namely, I want core3.3

If I can get it anyway.


@jeapostrophe You might now?

hmm…looks like not. At least not yet. :slightly_smiling_face:

It looks like when you request core, it starts at 4.x and goes down to 3.0

WAIT!!! No. Grr….despite asking for a core context, its still giving me a legacy one. That absolutely should be in the docs.

That, and you should absolutely be able to find out what kind of context you got after the fact.

Hmm…I guess in get-legacy? it says that it is only supported on mac 10.7+ and some linux variants.

But there still doesn’t seem to be a way to check which version you ended up getting once you go it.

@leif I’m no GL expert, but I thought there were GL-level functions that will tell you

There are some.

Namely, glGetString

@mflatt Btw, its the line (force lazy-GLX_ARB_create_context?)
that is causing it to create a compatibility context.

When I comment out that line a compatibility context gets created. (Version 3.3)

You get a *non-*compatibility context when it’s commented out? Neil wrote that code, and I don’t know the right answer in this case, but I’m happy to accept patches from people who do.

leif: it is not common for OpenGL apis to give you the ability to ask for a specific version, because drivers typically don’t support multiple options anyways. OpenGL versions never change the meaning of old stuff (i.e. it is forward compatible) and when you write GLSL you have to specify the version always… so what exactly is the problem that yo

u are trying to solve?

I mean, newer versions do remove deprecated stuff. Although the only instance I can think of this happening in a major way was 3.0 to 3.1

I have a GLSL shader, it is not doing anything fancy, just drawing a quad to the screen, and drawing a texture to that quad.

(aka, its a media player)

The shader is written in GLSL 330

On my mac, I get 3.3 when I ask for the core profile.

But on linux, despite asking for core, I got compatibility. Which corresponded to version OpenGL 3.0, so GLSL 130.

@jeapostrophe ^

Oh, also, glx (which is what the linux opengl bindings use), does let you request a specific version. Of course you are limited to what your hardware can support. :slightly_smiling_face:

@mflatt Kind of. When you request a core profile, Racket’s opengl library tries a few tests to see if its compatible. If it is, and you requested a core profile, it gives you a context using the core profile. However, if it can’t, it ignores what you requested and silently gives you a compatibility context.

The only real way to test after the fact (as far as I can tell), which one you got is using the glGetString function and checking your opengl version.

Anyway, I commented out one of the checks that was failing, to see what would happen, and the opengl context worked just fine. Which makes me think we are potentially checking more stuff than we need to.

(Obviously I haven’t tested that thoroughly yet.)

Anyway, thanks.

leif: 3.0 to later is basically a totally new API, which what the whole core vs compatibility thing is about

it sounds like either something wrong with Racket checking of the version (which you said) or your driver doesn’t really support new stuff, which is common on Linux software implementations

@jeapostrophe yup. Or at least thats when they dropped the fixed pipeline in favor of the shaders from opengl 2. But how would I test if it doesn’t ‘really’ support newer stuff?

Like, I’m able to open up a window, and build and run a GLSL 330 program.