hoshom
2019-2-21 10:01:35

If I have types like these: (struct Foo ([x : Number])) (struct Bar ([f : Foo])) (struct SubFoo1 Foo ()) (struct SubFoo2 Foo ()) (struct SubFoo3 Foo ()) What would be a type definition that accepts Bar only if Bar-f is of type SubFoo2?


hoshom
2019-2-21 10:01:44

I’m basically trying to translate some code from contracts to types


hoshom
2019-2-21 10:05:10

I mean I understand I could say (struct Bar (X) ([f : X])) and then be able to say : (Bar SubFoo2) or something similar, but I want Bar-f to only be subtypes of Foo and not just any type


samth
2019-2-21 12:41:49

@hoshom what you suggest there is exactly what I would do


Bot messages not yet supported
samth
2019-2-21 15:54:55

@pocmatos related to your gccjit code, you might be interested in https://github.com/rjnw/sham which could presumably have a libgccjit backend


pocmatos
2019-2-21 16:02:13

@samth thanks I took a peek at it last year and thought it was mostly a set of llvm bindings but I see it’s more than that. I like the idea of the sham language. And implementing a backend for that language using gccjit sounds definitely feasible? is rjnw one of your phd students?


samth
2019-2-21 16:13:23

Yes, he is


samth
2019-2-21 16:14:00

I also think you should see if the llvm jit that already works there can do what you need


bill_temps
2019-2-21 16:26:28

@bkovitz I’m not an expert in this area, but I see similarities between SQL and map-reduce. SQL seems to have some odd restrictions on applying functions to sets of data. I couldn’t make a clean SQL implementation of the “square top 2” example unless I cheated by constraining the arguments to be non-negative. What struck me particularly was the use of take and sort (which also reminded me of APL).


pocmatos
2019-2-21 17:07:15

thanks @samth i will take a more in-depth look at his code then. :slightly_smiling_face:


oldsin
2019-2-21 17:41:42

Do you prefer using shorthand style, like

(define (eat something)
  (printf "~a is delicious!\n" something))

over the explicit λ style, like

(define eat
  (lambda (something)
    (printf "~a is delicious!\n" something)))

in Racket? I came from Scheme, been using the `explicit lambda’ style for a rather long time, but found the style guide https://docs.racket-lang.org/style/Choosing_the_Right_Construct.html?q=style seems to encourage the use of the former style.


lexi.lambda
2019-2-21 17:46:04

Ubiquitous, unambiguous shorthand is usually better. Even Scheme wouldn’t have the former style at all if it intended you to write the latter.


lexi.lambda
2019-2-21 17:46:32

Being taught to religiously write the latter is helpful to teach first-class functions, but it has few benefits for the working programmer.


notjack
2019-2-21 17:46:53

@oldsin the first style, by far. Introduces less indentation and makes the declaration of a function and its arguments line up visually with uses of the function, like f(x) and f(3).


lexi.lambda
2019-2-21 17:48:55

The define/use symmetry is a good point! It’s always aesthetically pleasing when that sort of thing happens.


lexi.lambda
2019-2-21 17:49:31

I am fond of similar symmetries in pattern-matching implementations.


bkovitz
2019-2-21 17:49:46

@bill_temps (or anyone else reading), what I’m most wondering if the SQL-ish style is typical, “first-resort” pure-functional programming—and especially, if I’ve cultivated a good or bad habit by looking at things that way. I still wonder if it’s all that readable, and it bothers me that it tends to produce a lot of unnecessary dynamic memory allocation, especially lists that are quickly consumed.


oldsin
2019-2-21 17:51:23

@notjack @lexi.lambda Got it. Cheers!


notjack
2019-2-21 17:59:56

@bkovitz I think that SQL-ish style is fairly typical, and I think it’s a good approach. The two main drawbacks I see to it are:

  • The memory allocation problem, which you already mentioned. This can be fixed with better approaches to streaming data transformations that don’t require you to make a bunch of temporary collections (clojure’s transducers, java 8’s stream API, python’s generators / generator comprehension, haskell’s laziness, etc.)
  • It’s often written “inside-out and backwards”, e.g. (apply + (map square (take (sort xs >) 2))) instead of xs.sort(>).take(2).map(square).apply(+). That’s a purely notational problem though and can be fixed with things like threading macros: (~> xs (sort _ >) (take _ 2) (map square _) (apply + _)).

bkovitz
2019-2-21 18:04:12

@notjack Thanks—it helps a lot to get confirmation or correction from people with more experience. Indeed I liked the threading macros when I was programming in Clojure, for just that reason: they made a lot of code quite readable that otherwise would have been a mess. Hmm, that’s an interesting variation on the threading macro…


notjack
2019-2-21 18:04:59

ah yeah I should clarify that I prefer to use something that isn’t technically what folks usually call the threading macro


notjack
2019-2-21 18:05:43

I like to define (~> x f ...) as a regular function that takes a single argument and a list of functions, and then I combine that with the fancy-app package which lets you write anonymous functions using underscores


notjack
2019-2-21 18:05:53

e.g. add1 is the same as (+ _ 1)


bkovitz
2019-2-21 18:06:40

@notjack Say, when I’ve looked through Racket code (admittedly not a huge amount), I haven’t seen real-life use of a ~> macro. Is there any particular reason why it isn’t common practice in the Racket world, beyond not already being standard? Are there other common ways to avoid the inside-out problem?


notjack
2019-2-21 18:08:20

@bkovitz I think it’s not common practice only because it’s not in the standard libraries shipped with racket out of the box, so you have to find a package implementing it. And there’s multiple packages implementing it so you have to choose one. People underestimate how much effort that is.


bkovitz
2019-2-21 18:09:18

Yep, it’s very easy to underestimate the paradox of choice.


notjack
2019-2-21 18:09:33

especially when different people have different choices but need to share a codebase


notjack
2019-2-21 18:10:07

like, I’m the only one I know who prefers the plain-function-plus-fancy-app approach


bkovitz
2019-2-21 18:10:38

@notjack Say, you’re Jack Firth, aren’t you? I just watched your talk about expect on YouTube a couple days ago, and I’m sold. Is there any way to use expect with Typed Racket?


notjack
2019-2-21 18:11:17

@bkovitz yup that’s me!


notjack
2019-2-21 18:13:27

I think using expect with TR might be doable with require/typed, or it might require something more complicated. The tricky part is that expectations are parametric - there should be some way to say that expect/proc has the type (-> (Expectation A) (-> A B) (Expectation B)).


notjack
2019-2-21 18:14:55

If you come up with something that works using require/typed, feel free to send a PR to the expect repo that adds an expect/typed module that just imports stuff using require/typed and then exports it


bkovitz
2019-2-21 18:18:17

I just recently moved about 1,000 lines of code to Typed Racket and found that it went pretty swimmingly and the result is better, clearer code that I can now modify with confidence. But I was disappointed to find that unit-testing doesn’t yet seem to work well with it. For example, check-equal? in typed/rackunit doesn’t report the line number of the failure. The error messages from expect are fantastic—but, it looks like I’ll have to add some require/typed code. OK, I’ll be more than happy to make that my first contribution to Racket, and no doubt I’ll learn some good stuff from it, too.


notjack
2019-2-21 18:20:09

some of the rackunit-TR issues are known and have been partially worked on: https://github.com/racket/rackunit/issues


notjack
2019-2-21 18:21:05

the rackunit codebase is a little hairy, but if you feel up to working on the unit-testing story in TR that might be a more effective place to contribute than expect - a lot more people use plain rackunit than expect


bkovitz
2019-2-21 18:21:15

Ah, thanks, now skimming through the issues…


bkovitz
2019-2-21 18:22:29

Thanks for the suggestion. Does the line number get lost in rackunit because of the optimizations that TR does?


notjack
2019-2-21 18:23:36

nah, it’s not even because of some TR-specific thing - it’s just that the typed versions of the check-equal?/ check-pred / etc. macros don’t properly preserve source locations


notjack
2019-2-21 18:23:53

I think @samth wrote a PR to fix this


samth
2019-2-21 18:24:04

yes, but it broke some stuff so wasn’t merged


bkovitz
2019-2-21 18:24:07

OIC



notjack
2019-2-21 18:24:37

@samth wait it did? :o


samth
2019-2-21 18:24:38

getting that to work generally would be nice


samth
2019-2-21 18:24:42

I think that’s why


bkovitz
2019-2-21 18:28:09

OK, that looks like it will take some work. I’m balancing “getting something to work right now” vs. reading up on and learning more Racket. When I next get to the 2nd of those two phases, I’ll have a go at making a require/typed wrapper around expect; that might be easier.


samth
2019-2-21 20:39:14

@mbutterick my guess is that it’s the https redirect + 6.0 not supporting something in modern https


notjack
2019-2-21 20:41:29

how many years old is 6.0 now?


oldsin
2019-2-21 20:43:13

Another question on style: as racket/list provides first second third, etc., to manipulate list, when do you use car cdr cadr caddr? Use them in a `mixed style’?


samth
2019-2-21 20:44:13

I use car, cdr, cadr and try to avoid anything beyond that


notjack
2019-2-21 20:44:22

@oldsin I’d recommend never using car / cdr / etc, if possible


notjack
2019-2-21 20:44:38

they’re virtually unreadable


alexknauth
2019-2-21 20:44:46

car, cdr, etc. are confusing for beginners, and me


alexknauth
2019-2-21 20:45:10

first, rest, second, etc. are a lot more readable


soegaard2
2019-2-21 20:45:15

If you have a data structure built using pairs that doesn’t represent a list, then car and cdr makes sense.


notjack
2019-2-21 20:45:33

true


soegaard2
2019-2-21 20:45:35

Otherwise first, second, rest signals you are working on a list.


notjack
2019-2-21 20:45:53

I think it’s a bad idea in general to make data structures out of raw pairs


diego
2019-2-21 20:46:39

I also prefer first, rest etc. I always have to think twice to remember what car and cdr represent (despite learning them decades ago)


daniel
2019-2-21 20:46:50

They’re not unfamiliar to someone who’s used Lisp for a while. One advantage is that they can be combined, as in caddr. Not very intuitive, no. Are there equivalent combining functions with first, last, et al.?


oldsin
2019-2-21 20:46:55

This thing really confuses me as, when you start as racket/base instead of racket, you do not own first second third things.


notjack
2019-2-21 20:47:22

Even once you’ve memorized them, they’re still no more descriptive names than random keyboard mashing


alexknauth
2019-2-21 20:50:25

I wish there was a language in between racket/base and racket, that was just basically racket/base + racket/list and racket/match.


jjwiseman
2019-2-21 20:50:43

they become their own concepts, if you use them enough. but mostly i feel like they’re left over from a time before fast & easy structs


jjwiseman
2019-2-21 20:51:19

i’m still a racket beginner, so… why don’t you want to just use racket?


notjack
2019-2-21 20:51:48

it’s huge


johnstonskj
2019-2-21 20:52:13

as a relative newcomer, I do tend to use both and for the reasons above, when I am manipulating pairs I use car/cdr and when I am manipulating lists I use first/second etc. I find it does make the code more readable because it is more intentional.


notjack
2019-2-21 20:52:41

which means slow load times and (more dangerously) higher chance of external libraries providing stuff that conflicts with the exports of racket


notjack
2019-2-21 20:54:45

less of an issue for #lang racket than for (require racket) because required identifiers can shadow identifiers imported from a #lang


notjack
2019-2-21 20:56:52

tangentially, what do you think of extending #lang reprovide to make it easier to make whole languages that just modify the exports of other languages? I’ve wanted that on several occasions


pierre
2019-2-21 20:58:19

curious as why this is an ssl error when the url is http just above


alexknauth
2019-2-21 20:59:44

You mean a kind of “reprovide-as-language” thing?


alexknauth
2019-2-21 21:00:38

If I wanted to define, say, #lang agile as s-exp M where M provides everything from racket/base, racket/list, and racket/match?


oldsin
2019-2-21 21:00:43

Here is a thing: if car cadr is really harder to understand, especially for newbies, then maybe first second are good alternatives. But what about cons? I haven’t seen any alternate names of cons.


alexknauth
2019-2-21 21:01:52

I guess it would have to be constrained to “reprovide-as-s-exp-language”


notjack
2019-2-21 21:03:16

@oldsin Honestly I’d prefer this:

  • pair Constructor for pairs, e.g. (pair 1 2)
  • pair? Predicate for pairs
  • pair-first, pair-second Accessors for pairs

notjack
2019-2-21 21:03:27

Yes that


alexknauth
2019-2-21 21:05:24

Okay. I could call it #lang reprovide/as-s-exp-language, and have it generate the reprovides + a reader submodule equal to… what? (module reader syntax/module-reader ???)


alexknauth
2019-2-21 21:05:34

What do I put in the ??? hole?


alexknauth
2019-2-21 21:06:40

Normally you would put a path to a module in a collection, but what if the current file isn’t installed within a collection?


oldsin
2019-2-21 21:06:47

Reminds me of typed/racket :racket-flat:


alexknauth
2019-2-21 21:07:54

A relative path to the current module won’t work, because once someone uses it, that path will be relative to their usage file, not to the definition file…


oldsin
2019-2-21 21:09:10

Really learned from your ways. Thank you guys.


alexknauth
2019-2-21 21:15:44

Would define-runtime-path help?


jaz
2019-2-21 21:32:55

I’d even just take racket/match.


alexknauth
2019-2-21 21:35:35

This doesn’t seem to work: (define-runtime-module-path self (submod "."))


notjack
2019-2-21 21:37:27

Oh right, this isn’t possible because readers emit module syntax objects that directly say what their language is :(


alexknauth
2019-2-21 21:38:20

The syntax/macro-lang language deals with this problem by forcing the user to specify the path to the current file as an absolute collection path…


notjack
2019-2-21 21:38:42

The reader of the wrapper language could be a wrapper function around the reader of the wrapped language. The wrapper reader could then postprocess the syntax object emitted by the wrapped reader and change the module’s declared language


notjack
2019-2-21 21:38:51

Would that work?


alexknauth
2019-2-21 21:39:45

If we were speaking I would tell you to say it again, slower this time.


alexknauth
2019-2-21 21:40:47

The wrapper function does what? Takes a module syntax-object and returns a module syntax-object?


notjack
2019-2-21 21:40:53

I’m not sure what I’m saying either


alexknauth
2019-2-21 21:41:12

Takes a “read” function and returns a “read” function?


alexknauth
2019-2-21 21:42:27

Wait, are you proposing a way that this could work with non-s-expression languages?


notjack
2019-2-21 21:44:22

All langs have a reader function right? The thing that the reader submodule is supposed to provide? It accepts a port and some other arguments and returns a syntax object for a module, like (module #f implementation-language). Is that all mostly correct?


alexknauth
2019-2-21 21:46:17

Yes. However, we can’t create a new implemnation-language on the fly


notjack
2019-2-21 21:48:28

brb, getting laptop so I can write examples


alexknauth
2019-2-21 21:49:47

Wait I just had an idea. It doesn’t work in the Racket module system but what if you could write something like: (module A (module B racket (provide (all-from-out racket))) (+ 1 2))


alexknauth
2019-2-21 21:50:51

The language of the module A is B, and B is defined on-the-fly


alexknauth
2019-2-21 21:52:02

If we had that, I think we could do the reader wrapper that wraps a wrapped reader, or whatever you said


notjack
2019-2-21 21:52:47

ah yes I caught up to your thought process and now see what you mean about how to specify the path to the current file


notjack
2019-2-21 21:53:47

I think embedding modules in there would not be good because it ties together the expansion process of the two modules - we definitely want a weaker link between the two than that


alexknauth
2019-2-21 21:55:03

Hey, does anyone have any thoughts about defining module-languages “on-the-fly” like this: (module A (module B racket (provide (all-from-out racket))) (+ 1 2)) Where the module A has language B, and the module B has language racket?


notjack
2019-2-21 21:58:22

I’m imagining something like this: #lang reprovide example/foo example/bar #:reader-from example/foo …would be equivalent to this: #lang racket/base (reprovide example/foo example/bar) (module reader racket/base (require (prefix-in base: (submod example/foo reader))) (provide read-syntax) (define (read-syntax ...) (define mod-stx (base:read-syntax ...)) (replace-language-module-path-in-module-syntax mod-stx absolute/path/to/file/containing/reprovide/code)))


notjack
2019-2-21 21:58:35

but I don’t know how to figure out that absolute/path/to/file/containing/reprovide/code bit


notjack
2019-2-21 21:59:00

and yes, I think this should work for non-s-expression languages


notjack
2019-2-21 21:59:32

I would know exactly how this should work if module paths were just URIs. That would make everything here much simpler.


alexknauth
2019-2-21 22:00:23

What if the example/foo language produces multiple different module-languages in different situations?


notjack
2019-2-21 22:01:05

you mean like metalanguages? like at-exp?


mflatt
2019-2-21 22:01:28

We recently changed http to redirect to https, so that’s why the SSL error. Also, it looks like Racket before v6.1.1 used SLL 2/3 by default (which is now disabled and changed to TLS), which is probably why v6.0 fails.


alexknauth
2019-2-21 22:01:31

As in sometimes #lang example/foo produces (module name example/foo/1 ...), and other times #lang example/foo produces (module name example/foo/2 ...)


alexknauth
2019-2-21 22:02:43

That includes at-exp, and I think it also includes pl (a language that Eli Barzilay made for a class), and I could imagine a language similar in spirit to pollen that did this too


mflatt
2019-2-21 22:03:42

And v6.0 didn’t have PLT_PKG_SSL_NO_VERIFY, yet… so I don’t have a workaround at the moment.


alexknauth
2019-2-21 22:06:00

It should be roughly equivalent to: (module B racket (provide (all-from-out racket))) (module A B (+ 1 2)) Except that B probably shouldn’t be visible outside.


notjack
2019-2-21 22:06:04

couple of thoughts:

  • maybe it would work if the user supplied a function to transform the source language module path instead of just overwriting it
  • or maybe it’s enough to just support replacing a fixed finite set of languages
  • when this pattern occurs outside metalanguages like at-exp, how is the choice of language usually made in practice? one of a few fixed possible languages? something more elaborate? I could see pollen doing this to figure out a file path programmatically or something
  • does this use case even make sense for a reprovide-like thing? When would you be reproviding a metalanguage? I just think of reproviding as a way to bundle together a few simple modules to make another simple module - I’d never try to use reprovide to define a modified version of a metalanguage

soegaard2
2019-2-21 22:07:43

alexknauth
2019-2-21 22:09:16

I guess the difference between your thinking and my thinking is this: - You’re thinking of the module-language and the reader as more separate. You can extend the module-language without messing with the reader too much. - I’m thinking of the module-language dependent on the reader. The reader determines which module-language to use at read-time.


notjack
2019-2-21 22:10:35

Right


alexknauth
2019-2-21 22:14:54

In order to wrap a #lang language to include an extra binding, you either need to: - determine the reader yourself separate from the #lang that you’re wrapping, and then wrap the module-language - or, wrap only the reader, and not the module-language


alexknauth
2019-2-21 22:16:31

Having (module _ (module _ racket stuff ...) stuff ...) would allow you to wrap the module-language as part of wrapping the reader


notjack
2019-2-21 22:19:09

It would, but other ideas would also work and I think it’s really not a good idea to treat modules as anonymous entities. It’s important that modules have names, and that those names are unambiguous and serializable. This property lets you separately read, expand, and compile modules.


notjack
2019-2-21 22:19:26

Modules are definitely not lambdas


alexknauth
2019-2-21 22:19:55

Lambdas allow expressions to “depend” on values that don’t come syntactically with them


notjack
2019-2-21 22:20:19

Yes. So do links to named resources.


alexknauth
2019-2-21 22:20:28

But the module-language-can-be-a-module-expression thing does not allow that


alexknauth
2019-2-21 22:21:12

As in there’s something that would make lambdas hard, which does not apply to module-language-can-be-a-module-expression. module-lanugage-can-be-a-module-expression is not hard in the way lambdas would be


notjack
2019-2-21 22:23:28

Keep in mind cacheability is a really important property to preserve here. In your example, the module expression containing the reprovides to perform must be copied and pasted into every single client module. That makes caching that work much harder (not impossible, but complex caching is often implemented wrong and its nearly impossible to test).


alexknauth
2019-2-21 22:23:47

The module A depends on B, yes, but B is right there. The compiler can just compile B first.


notjack
2019-2-21 22:24:30

Yes. But you don’t have just module A. You have hundreds of modules using this reproviding language. And each client module will get a copy of B pasted into it.


alexknauth
2019-2-21 22:25:15

Yes, but that’s necessary if the module-languages produced by the reader are all different


notjack
2019-2-21 22:26:35

which I don’t think happens all that often, and definitely wouldn’t in the use cases of #lang agile and your request for a language that’s just racket/base + racket/list +racket/match.


notjack
2019-2-21 22:26:51

I think languages like that would be 90% of the use cases


alexknauth
2019-2-21 22:28:04

If I can’t do it for arbitrary readers producing arbitrary modules, then I’ll do it only for s-exp readers. Which is still 90% of the use cases


notjack
2019-2-21 22:28:17

I’d do it for scribble/manual pretty often


notjack
2019-2-21 22:28:33

That’s a non-s-exp reader that doesn’t produce arbitrary modules (I think)


mflatt
2019-2-21 22:31:44

This change certainly affects v6.0 users who try to install packages from the default configured catalog, which is an even smaller group than v6.0 users generally. I’m not sure it’s reason enough to turn the global HTTP->HTTPS forwarding back off, but it’s a point in that direction.


sorawee
2019-2-21 22:37:53

@mflatt I’m trying to use free-identifier=? to test if an id refers to another id from another file. It works perfectly before expand-syntax, but after I expand-syntax somehow the function returns #f. Do you know a solution to this?


sorawee
2019-2-21 22:43:01

To demonstrate:

;; a.rkt

#lang racket

(define a 1)

a
;; compile.rkt

#lang racket

(define my-a #f)
(define my-b #f)

(define (annotate stx)
  (let ([stx (expand-syntax stx)])
    (println (syntax->datum stx))
    (syntax-case stx ()
      [(module _ _ (mb _ (define-vals (b) _) (app _ (lam () a) _)))
       (set! my-a #'a)
       (set! my-b #'b)]
      [_ (void)])
    stx))

(define orig (current-compile))
(current-compile
 (lambda (e immediate-eval?)
   (orig (annotate
          (if (syntax? e)
              e
              (namespace-syntax-introduce
               (datum->syntax #f e))))
         immediate-eval?)))

(dynamic-require "a.rkt" #f)

(println my-a)
(println my-b)

(free-identifier=? my-a my-b)

This returns #t.

But if now I have:

;; a.rkt
#lang racket

(require "b.rkt")

a
;; b.rkt
#lang racket

(provide a)
(define a 42)
;; compile.rkt

...
      [(module _ _ (mb _ _ (define-vals (a) _)))
       (set! my-b #'a)]
      [(module _ _ (mb _ _ (app _ (lam () a) _)))
       (set! my-a #'a)]
...

now it returns #f.


mflatt
2019-2-21 22:44:57

We’ve turned off HTTP->HTTPS for now. Part of the idea is to check whether that fixes the package server, as you have suggested.


sorawee
2019-2-21 22:47:08

I also test the scenario where I have two submodules in a file, and that one works as expected. The only case that it doesn’t work is when they are in different files


mflatt
2019-2-21 22:48:58

From the module system’s perspective, those are not the same binding. The one in “b.rkt”’s expansion is “in the current module”. The one in “a.rkt”’s expansion is “from a module b.rkt relative to the current module”. There’s nothing that ties one module’s “current module” to the other module’s “b.rkt relative to the current module”. When you have submodules, there is something that ties them together, since they’re at once relative to the enclosing module.


mflatt
2019-2-21 22:51:06

For the multi-module case, you could use identifier-binding and related tools to inspect binding information and impose rules about the relationship of “current modules”s, but I don’t know whether that’s the right direction for your purposes.


sorawee
2019-2-21 22:51:55

I see. Let me try identifier-binding then. Thank you very much for your help :slightly_smiling_face:


notjack
2019-2-21 23:08:29

This was a fantastic read, thank you


alexknauth
2019-2-21 23:47:11

Is there a way to generate a module-path, like define-runtime-path, that points to the current module?


alexknauth
2019-2-21 23:47:29

I tried (define-runtime-module-path self (submod "."))


alexknauth
2019-2-21 23:47:41

but that gave me an error about a cycle in the loading path


mflatt
2019-2-21 23:48:27

(variable-reference->module-path-index (#%variable-reference))?


notjack
2019-2-21 23:48:40

is this for the reader submodule reprovide problem?


notjack
2019-2-21 23:49:13

@mflatt can a module path index go in the module-path part of a top-level module expression? like (module foo <mpi> body ...)


mflatt
2019-2-21 23:49:37

No, it can’t


notjack
2019-2-21 23:51:06

@mflatt what can? context: alex and I were discussing how to make something like #lang reprovide that generates a read-syntax procedure that returns a module syntax object pointing to the reprovide module


alexknauth
2019-2-21 23:51:20

Can the result of (require syntax/modresolve) (resolve-module-path-index (variable-reference->module-path-index (#%variable-reference))) go there?


alexknauth
2019-2-21 23:59:54

In other words, does the following make sense, or sound completely wrong? #lang racket/base (provide (all-from-out racket/base)) (require syntax/modresolve) ;(define-runtime-module-path self-module-path (submod ".")) (define self-module-path (resolve-module-path-index (variable-reference->module-path-index (#%variable-reference)))) (module* self-module-path #f (provide self-module-path)) (module* reader syntax/module-reader #:language self-module-path (require (submod ".." self-module-path)))


greg
2019-2-22 00:01:56

@sorawee I don’t know if it would be helpful — or even if it’s a good example to follow — but I’ve done some things with identifier-binding to support visit-definition in racket-mode. There are some edge cases like identifiers that are both contract-out and rename-out. AFAICT in such cases identifier-binding can tell you the id came from a module, but not necessarily the original id. For that you have to walk the syntax. This may not matter for what you’re doing but just a heads-up. https://github.com/greghendershott/racket-mode/blob/master/racket/find.rkt


sorawee
2019-2-22 00:03:15

Thank you!!!


mflatt
2019-2-22 00:12:48

I’m not sure I follow, but maybe you want to use #:language with a 5-argument procedure, where the second argument to the procedure is how the reader module was referenced. Then, you can build on that reference to access a module relative to the reader module.


alexknauth
2019-2-22 00:19:18

Oh, so I could take (submod stuff stuff reader) and extract just (submod stuff stuff)


alexknauth
2019-2-22 00:21:50

Though I supposed one disadvantage of that is that someone could reprovide the read and read-syntax functions from a different module, and then that “how the reader module was referenced” argument might be different


alexknauth
2019-2-22 00:53:46

I’ve finished making the s-exp-only version on a branch here: https://github.com/AlexKnauth/reprovide-lang/tree/as-s-exp-language


daniel
2019-2-22 01:59:23

That was probably the best explanation of why LOP is significant. Well done, sir!


mflatt
2019-2-22 02:32:25

@mbutterick Do you need v6.0 support, or would supporting/testing only v6.2 and later be ok?


abbyrjones72
2019-2-22 07:17:03

Thank you for this link. Reading it now.