
While building racket I saw these lines go past:

Downloading repository <git://github.com/RenaissanceBug/racket-cookies?path=net-cookies>
Downloading repository <github://github.com/stamourv/optimization-coach/master>
Downloading repository <git://github.com/racket/option-contract?path=option-contract>

Although nothing seemed to fail, I find the use of github://
strange. Was this a typo or is it actually allowed these days?

@pocmatos Not newly-allowed. More like earlier-allowed — it’s deprecated. See next to last bullet under Package Sources here: https://docs.racket-lang.org/pkg/Package_Concepts.html#%28part._concept~3asource%29

Thanks @greg

I am seeing a strange behaviour with sync
and handle-evt
for place synchronization with an alarm to deal with a timeout. The problem is that the timeout is never triggered. I am doing a simplified (sync (handle-evt (alarm-evt (+ (current-inexact-milliseconds) (* timeout 1000)))
(lambda (_) (printf "timeout~n")))
(handle-evt ...))
I assume, there’s nothing obviously wrong with doing this right?

Annoyingly this simple example works out of the box in drracket. sigh

@pocmatos Hmm. - Does it work because it’s running under DrRacket — or because it’s a simpler example? - What happens if (handle-evt ...)
is never-evt
?

(I haven’t used places, for real. So I am just trying to be your “rubber duck”.)

@greg well, it’s because it’s a simple example. With never-evt
also works. Trying to reproduce this with a larger but manageable example. My suspicion is that it has to do with how place channels interact with handle-evt
.

Thanks! :slightly_smiling_face:

Also, the places I create are all computationally heavy… but I am not sure that can influence the behaviour of the original place.

@pocmatos Does it work if you try something like sync/timeout
and test for #f
? (To maybe rule out the handle-evt
aspect.)

humm, good idea. will give it a try.

Well at least rule out the (handle-evt (alarm-evt ...))
composition.

sync/timeout
is not what I expected because the timeout sets a timeout on the synchronization. In my application synchronization happens very rapidly due to messages being sent back and forth so timeout is never triggered. Maybe I can change the structure to test it anyway.

ok… just crashed drracket :disappointed:

how can I go to the inside of a submodule in DrRacket or Racket REPL?

oh, I shouldn’t have quoted the module path

@greg finally found out the problem. :slightly_smiling_face: Not racket! Issue with how I was dealing with message passing between places. alarm was being triggered but my print was buffered and not displayed so I thought the event was just not being handled. I assumed a printf ending in ~n
would flush the buffer but that was not the case. I needed (flush-output)
. Did manage to crash DrRacket in the process though.

@pocmatos Ah! BTW you could do this globally with (file-stream-buffer-mode (current-output-port) 'none)

Or 'line
maybe in your case.

is there any library that implements rackjure function literals? only that part. i only use the threading macro and that

@greg Awesome, thanks for pointing that out!

and theres the threading package now

there are like 3

@cosmez Yes, @alexknauth has a pkg for just that, IIRC.


as Greg mentions, Alex has http://docs.racket-lang.org/afl/index.html, but I’ll also plug my take http://docs.racket-lang.org/curly-fn/index.html

Oh, cool.

@lexi.lambda and @alexknauth create so many good packages I can’t keep up :smile:

I think I beat Alex to the punch on this one, but I’m not sure :)

thanks a bunch :slightly_smiling_face:

He’d been helping fix a bug or two in rackjure fn lits, around the same time, I think

In hindsight rackjure
could/should be mostly just a meta pkg that re-provides things like afl and threading, now that those exist.

I already did that with threading, but maybe could take it further now.

Or not. I don’t think many people use rackjure for realz.

if youre coming from clojure, is nice to have it.

I use curly-fn
liberally.

Hmm, it’s occurring to me, now, that I rarely seem to use anonymous functions, lately. I wonder why. It’s mostly not intentional. I mean, I do prefer for/list
et al to map
. And I do sometimes just define
a function with a name because I like how that reads, when using it. So it’s a little on purpose. But mostly that’s not it. I wonder why, is there something else about the code I’m writing lately. Hmmm.

theyre good when youre prototyping. and youre not used to the for idiom

right now i have to see the documentation everytime i have to use one of the for alternatives

@mflatt I feel less confident about asking this question than I normally do, since I really don’t known if this behavior is a bug or my own misunderstanding, but I’m trying to figure out why this program behaves the way it does. It seems to only cause a problem when split out over three separate files, but they’re short: ;; ns.rkt
#lang racket
(require (for-syntax racket
syntax/parse/define)
syntax/parse/define)
(provide (for-syntax type-namespace-introduce)
begin-for-type)
(begin-for-syntax
(define-simple-macro (define-type-introducer type-introducer:id)
#:with scopeless-id (datum->syntax #f 'introducer-id)
#:with type-id ((make-syntax-introducer #t) #'scopeless-id)
(define type-introducer (make-syntax-delta-introducer #'type-id #'scopeless-id)))
(define-type-introducer type-introducer)
(define (type-namespace-introduce stx)
(type-introducer stx 'add)))
(define-syntax-parser begin-for-type
[(_ form ...)
#:with [form* ...] (map type-namespace-introduce (attribute form))
(syntax/loc this-syntax
(begin form* ...))])
;; p.rkt
#lang racket
(require syntax/parse/define
"ns.rkt")
(provide foo)
(begin-for-type
(define-syntax Foo 'type))
(define-simple-macro (get-typed-value x:id)
#:with val (syntax-local-value (type-namespace-introduce #'x))
(quote val))
(define-simple-macro (foo)
(get-typed-value Foo))
;; u.rkt
#lang racket
(require "p.rkt")
(foo)
Running racket u.rkt
without compiling any of the modules successfully compiles and prints 'type
, but attempting to compile the modules with raco make u.rkt
produces an unbound identifier error. I don’t understand why. Is this a bug?

Compiling just ns.rkt
and then running racket u.rkt
also doesn’t trigger the issue, but compiling p.rkt
and then running racket u.rkt
does.

I use fancy-app
so much it feels painful to write code without it. But I don’t use anything else for anonymous functions (like currying) because by that point I find a named definition much clearer.

That’s pretty subtle. The short answer is that you’re exposing the gensym
-like nature of scopes. The “ns.rkt” module is carefully set up to embed the relevant scope in a syntax object, so every instantiation of “ns.rkt” will get the same scope. But “p.rkt” also attaches the scope to a syntax object (although indirectly, in the identifer-to-definition mapping). When those two modules are separately unmarshaled, you get two different scopes It’s the same as if you embed the result of one gensym
call into two different compiled expressions and then read the expressions individually, so that the gensym
ed symbol is created twice. I’m not immediately sure of how to do what you want to do. It seems like the kind of thing that submodules are for, but I can imagine why a submodule might not work in this case.

Possibly, the solution is to arrange for a separate type-introducer
in every module that uses define-type-introducer

That makes sense, though it’s rather unfortunate. I’m not sure what the right thing to do is, either. I’ve been thinking about potential workarounds, but I haven’t been able to come up with any. At first, I thought it wouldn’t be important for the namespace scopes to span multiple modules, but I’ve realized lately that it (unfortunately) actually is.

@michael.ballantyne This reminds me of what you were doing with scope-based, textually interleaved namespaces. Is it the same?

The reason it’s necessary for the scope to be consistent across modules stems from the problem I actually ran into before reducing the issue to this minimal test case. Namely, I had a macro written in one module that expands to a form like (instance (forall [x] (Show x) => (Show (Maybe x))) ....)
, and the instance
knows that things like forall
and Show
should be bound in the type namespace. But until the macro is expanded, that information isn’t known.

In the existing Hackett implementation, I use a syntax/parse
pattern transformer named ~type
that is used to annotate pieces of syntax that should be interpreted in the right namespace, which is really the API I want. It makes sense from the mental model of a macro-writer. It just doesn’t work, due to the way the scopes can end up inconsistent, as demonstrated in this example.

I thought the make-syntax-delta-introducer
trick would be enough to fix the scopes across instantiations, and I guess it is, as you say. But also as you say, the way scopes are unmarshalled means the “same” scope is not necessary actually the same after being stuffed in bytecode, if that scope ends up being embedded in multiple modules. :(

I’m not clear on why type-namespace-introduce
can’t be a macro that triggers a module-local type-namespace-introduce
definition (once per module) and replaces itself with a call to the module-local one.

The problem is that the use of type-namespace-introduce
might be in a different module from the syntax it gets called upon, in which case that won’t work. I compressed the code in my reproduction into just three modules, but my actual problem involved six! Specifically, imagine if the foo
macro and the Foo
type were defined in a different module from the get-typed-value
macro.

In more practical terms, imagine the instance
macro for defining typeclass instances is defined in one module, and it calls type-namespace-introduce
on a piece of input syntax. But a macro that expands into an instance
form is defined in a separate module, and it references bindings in scope in that separate module (which, if I understand your suggestion properly, would use a distinct type namespace scope, and therefore the scope introduced by the instance
macro wouldn’t be the right one).

I imagine that anything that calls type-namespace-introduce
would also need to be module-local, so use the same localizing strategy for get-typed-value
– or, probably more simply, pass the right type-namespace-introduce
to it. That way, it would never the case that type-namespace-introduce
or (effectively) get-typed-value
is from a different module.

I’m not sure I’m mapping things right to instance
, but it feels like this is one of those problems that is solved by one more level of indirection

Unless I’m misunderstanding you, I don’t think it’s possible to implement a namespace abstraction if users are required to either only reference locally-defined macros or to thread type-namespace-introduce
around manually when they write macros.

That is to say that this is not code that is exclusively internal to Hackett; it also exists as part of the API to users of Hackett writing their own macros that expand into Hackett forms.

If it helps at all, I can point to the actual code on GitHub in a branch of Hackett that ran into this problem. I just figured that probably wouldn’t be very helpful to someone unfamiliar with the codebase (that is, everyone except me).

Ok – I’ll look tomorrow.

Yes, no rush. It’s late. :) It’s also not exactly urgent.

On the other hand, while it definitely isn’t urgent, it’s also something I do need to fix to make Hackett work (or abandon separate type/value namespaces entirely), and I don’t currently have a workaround or even a path to a solution in the expander (unlike some other things I’ve bumped into that I can deal with myself).