shu--hung
2017-10-15 13:46:46

@ryanc Hi, I sent a pull request to custom-load. The default use-compiled handler will check the existence of a file, so I added that check


ashakdwipeea
2017-10-15 14:16:42

@ashakdwipeea has joined the channel


leif
2017-10-15 15:50:29

@mflatt Is there an equivalent to ctype-scheme->c and ctype-c->scheme in the ffi lib? I see it in '#%foreign, but the docs say that it shouldn’t be used directly.


leif
2017-10-15 15:51:06

For reference, I’m trying to build my own define-cstruct macro, because the existing one doesn’t support versions, which I need.


royall
2017-10-15 16:20:05

From the second page, I think this covers it: (define-macro-cases bf-op [(bf-op ">") #'(gt)] [(bf-op "<") #'(lt)] [(bf-op "+") #'(plus)] [(bf-op "-") #'(minus)] [(bf-op ".") #'(period)] [(bf-op ",") #'(comma)]) (provide bf-op)


mflatt
2017-10-15 16:24:28

@leif Those are not meant to be exposed, and the way that define-cstruct uses ctype-scheme->c and ctype-c->scheme looks like a hack to me. I recommend using cpointer-push-tag! for the C->Scheme part, and use cpointer-has-tag? for the Scheme->C part. The little bit of duplication that you’ll have is better than the hack.


mflatt
2017-10-15 16:29:09

@sanchom A reference to handle originates in the reader, before identifiers have scope, while references to gt, etc., originate in expansion. In other words, it’s roughly that handle is introduced by a ' form, while gt, etc., are introduced by #' forms.


lexi.lambda
2017-10-15 16:30:55

Can someone in here explain why we always write the former of these two programs instead of the latter? #lang racket (require (for-syntax racket/syntax) syntax/parse/define) (define-simple-macro (definer1 x:id) (define-syntax x 42)) (define-simple-macro (consumer1 x:id) #:with value (syntax-local-value #'x) (quote value)) (definer1 foo) (consumer1 foo) (define-simple-macro (definer2 x:id) (define-for-syntax x 42)) (define-simple-macro (consumer2 x:id) #:with value (syntax-local-eval #'x) (quote value)) (definer2 foo) (consumer2 foo) I’ve never fully understood why we use phase 0 transformer bindings to store data that macros have access to instead of just using phase 1 bindings.


mflatt
2017-10-15 16:34:36

@lexi.lambda One possible reason: Since begin-for-syntax doesn’t work in internal-definition contexts, the latter works only at the module level, while the former also works in local contexts.


lexi.lambda
2017-10-15 16:36:08

Ahh, that makes sense. So you can’t have a notion of nested local scopes from different phases.


lexi.lambda
2017-10-15 16:38:26

That means David’s suggestion to use phases as namespaces unfortunately probably won’t work. Let me ask a followup question, then: is there any way for Racket programmers to inject requires that have the same shadowing behavior as bindings imported by the module language? Alternatively, is there any way to adjust how bindings provided by a module language are imported?


lexi.lambda
2017-10-15 16:40:09

Essentially, I have a require transformer unmangle-types-in, and I inject it into every require. That transformer finds all the mangled type imports, unmangles them, and applies the type scope. I can’t do that for types provided by the module language, though, because there are obviously no “module language transformers”.


lexi.lambda
2017-10-15 16:40:57

And if I adjust the reader to transform #lang hackett into (module m hackett (require hackett)), then users are unable to shadow bindings provided by hackett with other requires.


lexi.lambda
2017-10-15 16:41:35

I think this would be a problem even if I were using something like submodules to store bindings instead of a name mangling scheme, but maybe I’m overlooking something.


cfinegan
2017-10-15 17:03:00

How can one write a macro such that it can report the name of procedure which invokes it? I basically want something like:

(define-syntax (foo)
  (syntax-parse stx
    [(_)
      (with-syntax ([invoking-proc (?? get-invoking-proc ??)])
        (syntax/loc stx
          (begin
            (eprintf "foo called from: ~v" invoking-proc)
            (void))))]))

lexi.lambda
2017-10-15 17:04:51

What do you mean “the procedure that invokes it”? Isn’t the procedure that invokes macro transformers just the macroexpander? Or do you want to know something about where the macro is used?


cfinegan
2017-10-15 17:06:11

The context in which the macro is used. Like if I had (define (my-fn) (foo)) then my-fn should printf foo called from "my-fn" as a side effect.


lexi.lambda
2017-10-15 17:06:40

I don’t think you can do that.


lexi.lambda
2017-10-15 17:07:29

You could create your own custom version of define that set up some lexical information that another macro could use. But I don’t think the built-in define does anything like that.


cfinegan
2017-10-15 17:08:28

I thought the contract system could do things like this? I.e. when a contract is broken, it gives you information about whether the blame lies with the function itself, or the context in which it was called. Either way not a huge deal.


lexi.lambda
2017-10-15 17:09:35

I think the contract system does that with define/contract, which has syntactic access to the name, but I think it usually only blames modules.


cfinegan
2017-10-15 17:10:18

Gotcha, thanks for the info.


michael.ballantyne
2017-10-15 19:26:43

@ryanc I take it from the existence of custom-load that racket does not by default behave the way @samth describes? Do you know why racket isn’t more cautious? It seems like the timestamp check shouldn’t be too expensive compared to the rather larger cost of actually loading and instantiating a module.

To be clear, the behavior I’m talking about is the following:

mkdir example; cd example

cat <<EOF >a.rkt
#lang racket
(define x 'old)
(provide x)
EOF

cat <<EOF >b.rkt
#lang racket
(require "a.rkt")
x
EOF

raco make b.rkt

cat <<EOF >a.rkt
#lang racket
(define x 'new)
(provide x)
EOF

# Prints 'old
racket b.rkt

raco make b.rkt

# Prints 'new
racket b.rkt

samth
2017-10-15 19:32:48

I think that what’s happening there is that the compiled version of b.rkt includes the actual symbol


samth
2017-10-15 19:33:23

so fixing this requires that b.rkt be recompiled, even though its zo is not out of date


samth
2017-10-15 19:34:59

what I said earlier remains correct


lexi.lambda
2017-10-15 20:11:59

@mflatt I’m trying to better understand the syntax model behind (module* m #f ....) submodules, since the docs seem a little sparse. Does it make sense for splicing-syntax-parameterize to affect such submodules? If not, why not? Currently, it looks like the implementation of splicing-syntax-parameterize ignores all module* submodules, but it would be convenient for me if it were possible to affect them that way (and, since they inherit bindings around them, it seems like it should theoretically be possible).


mflatt
2017-10-15 20:19:06

@lexi.lambda I think it would make sense for splicing-syntax-parameterize to work with (module* m #f ....), but I’ve never tried


mflatt
2017-10-15 20:19:41

There’s no way, as far as I can see, to import in a way that allows shadowing


lexi.lambda
2017-10-15 20:20:39

Okay, that’s probably enough for me to go on… I just have little idea how syntax parameters actually work, so I didn’t want to try something completely wrong. :)


lexi.lambda
2017-10-15 20:21:26

As for imports, I think the namespace issue is surprisingly hard. :( But I think I might be able to get something that almost works, modulo the issue with import shadowing.


lexi.lambda
2017-10-16 03:26:20
$ cat module-begin.rkt
#lang racket

(require syntax/parse/define)

(define-simple-macro (#%module-begin form ...)
  #'(#%plain-module-begin form ...))

(module* use #f)

$ racket module-begin.rkt
module-begin.rkt:8:0: module*: compiled body was not built with #%module-begin
  in: (module* use #f)

wat


lexi.lambda
2017-10-16 03:29:13

oh, hah—the #' is wrong there. still have no idea what that error message is about…