
@lexi.lambda But if you provide at phase 0, then require the file at phase 1, in the end you get a phase 1 binding, right?

You get the value of the phase 0 binding of the providing module in the phase 1 of the requiring module.

Ok, so I didn’t check the (struct-out)
macro in details, but I guess it expands to a (provide the-struct (for-syntax the-struct))
because in most of my code, I get the phase 1 struct binding (struct-infos) without having to specify the phase when providing.

Yup, I think that’s what struct-out
expands to.

:+1:

actually, no

I think the-struct
is defined with define-syntax
, not define-for-syntax

So (provide the-struct)
would actually be enough.

ooh, it’s already a phase 1 binding then

No, the struct name is bound at phase 0 to a phase–1 value. All macros are like that. That’s what define-syntax
does, as opposed to define
and define-for-syntax
.

What kinds of things would you want a Racket linter to catch? Asking for a friend1.

@ryanc Wow, I’m having a hard time trying to understand that. Does it mean the phase–1 value will be executed so that the phase 0 binding gets a value? I don’t really get the difference between define-syntax
and define-for-syntax
.

@popa.bogdanp Looks interesting. What do you mean by “shadowed identifiers”?

(define x 1)
(define (f x)
x)
the x
inside f
shadows the one outside it

so the tool catches this case and a couple others similar to it and displays a warning

this is as opposed to a re-bound identifier like
(define x 1)
(define x 2)
in which case it displays an error

you can see some examples in this folder:
https://github.com/Bogdanp/konmari/tree/master/tests/lint
the .out files contain the command line output resulting from linting their .rkt counterparts

Would (let ([x 1]) (let ([x 2]) x)) also give a warning?

Right now, yes, though I am planning to add an exemption for that case in particular

Would macro generated shadowing also give warnings?

Shadowings in macro code would yield warnings for shadowed bindings at that phase level (this is yet to be done though), but not bindings generated by macro code, unfortunately.

This is because I want to avoid expanding the linted code.

I would say fortunately :slightly_smiling_face:

If you are looking for ideas - I think there were a thread at some point on the mailing list.

Thanks! I think I found the thread. https://groups.google.com/forum/#!searchin/racket-users/linting%7Csort:date/racket-users/GQkv71Uq3cI/VaPIL92wAgAJ

Yes. There is also an older thread were Eli points to: http://tmp.barzilay.org/code-ayatollah.rkt

(from 2012)

Sweet. I’ll take a look at that as well.

titled “Style mistakes (was: static variables question)”

Thanks. I found it in the old archive

Also, @jbclements had a tool called “no-brainer” a long time ago that maybe could be found

but a quick google finds only broken links

Oh, I think it didn’t make the jump from planet. Let me see…

Yes, the source is all still on planet: http://planet.racket-lang.org/display.ss?package=no-brainer.plt&owner=clements

Cool! I’ll take a peek at that as well. Thanks

@jerome.martin.dev | form | bind-phase | value-phase | use at 0 | use at 1 | |————————-|————|————-|—————————————————|————————————————| | (define x e) | 0 | 0 | x
gets value of e
| N/A | | (define-syntax x e) | 0 | 1 | (x 1 2 3)
macro call e
transformer function | (syntax-local-value #'x)
gets value of e
| | (define-for-syntax x e) | 1 | 1 | N/A | x
gets value of e
|

Or maybe an image will show it better

The bind-phase
is the phase x
is bound at, so its the phase where x
can be used without #'
syntax-quotes. For define
that’s just x
returning the value of e
, and for define-syntax
that’s x
being a macro call: both are phase 0 references

If thread-a calls place-channel-put/get and thread-b also calls place-channel-put/get at the “same time”, then is is possible that the response intended for thread-a ends up in thread-b? I’m assuming no, but I want to be sure.

My use case is I have a place that performs password hashing and hash verification using the FFI. The hasher’s config values are set fairly high so using it on the main place would completely block my web server when someone logs in. The loop inside of the hasher place is basically:
(forever
(match (place-channel-get ch)
[... (place-channel-put response)]))

Do I have to tag requests and responses with message ids and come up with a somewhat-complicated dispatching system, or can I rely on place-channel-put/get to do the right thing with respect to my use case here?

@popa.bogdanp are they calling this on different channels?

They are all using the same place channel

(define hasher-place-ch
(dynamic-place hasher-path 'main))
(define/contract (hash-password s)
(-> string? string?)
(place-channel-put/get hasher-place-ch (list 'hash s)))
(define/contract (hash-matches? s h)
(-> string? string? boolean?)
(place-channel-put/get hasher-place-ch (list 'verify s h)))

eseentially, all threads would be calling this code

So I’m imagining a case where two users attempt to login at the same time, off of two separate threads on the main place, each of them would issue a request to the hasher place and wait on a response. Getting their responses mixed would obviously not be desirable :smile:

is the hasher concurrent?

No. It takes a message off the channel, puts a response back and then recurs

Then I think your code is correct but I’m not certain, @mflatt would be able to say for sure

I the mean time I think I’ll wrap the two functions inside a call-with-semaphore
just to be safe. Thanks @samth

I’m a little confused about the difference between a module and a package in Racket. I thought that I had it straight after reading the post on Modules, Packages, and Collections on the Racket blog. But, for example, if I search the docs for data-frame, the top result returned is “data-frame module.” Why does search not return “data-frame package”?

data-frame
is a module, and that module is in package that happens to also be named data-frame

That does seem like a problem. The place-channel-put/get
function is just a place-channel-put
followed by a place-channel-get
, so the replies could get crossed if two threads call hash-password or
hash-matches?` at the same time.

Ah, okay, my understanding of module was too narrow. Thanks.

Understood. Thank you!
I’ve wrapped the two functions in a call-with-semaphore
for now and I’ll eventually morph that into a pool of hasher places if necessary.
I’m not too worried about the time it takes for a login request to process and this fixes my immediate issue of someone spamming login requests being able to negatively impact the performance of my server for everybody else.

probably-naive question: is there a way to get fprintf to pad outputs (e.g., so that “1” and “11" take up the same amount of space and you get “1 ” and “11" or something). I’m guessing no but checking

I found some libraries that do something like this, leading me to guess it’s not built in :slightly_smiling_face:

Would you expect (begin-for-syntax (println 1))
to output 1, 2, or 3 1
s? https://github.com/greghendershott/racket-mode/issues/379

The answer is here: https://github.com/racket/drracket/issues/278
If I disable debugging in DrRacket, the number of 1
decreases from 3 to 2.

I guess I’m convinced that this is not a bug, though I still don’t think it makes sense.

Dr Racket gives you 50% more 1
s than Racket Mode. That is pretty embarrassing. Clearly I need to work harder.

Nice!!

That’s what I needed. I didn’t mean specifically fprintf
but just fprintf
and friends :slightly_smiling_face:

@krismicinski also take a look at ~r
if you’re formatting numbers

The command raco pkg new
defaults your package’s license to LGPL, presumably to follow Racket’s LGPL. However, there’s a plan for Racket to move away from LGPL (https://github.com/racket/racket/issues/1570), so…. I don’t know.