zenspider
2017-10-25 15:34:31

@samth it I’d soooo small! Making me sad.


samth
2017-10-25 15:42:25

@zenspider ?


zenspider
2017-10-25 15:45:00

@samth just being wistful… This conference used to be huge. I worry it won’t have the impact it used to have.


chrisg
2017-10-25 16:42:33

@chrisg has joined the channel


chrisg
2017-10-25 16:50:37

So I’m using Racket for a class and discovered this, if I do (require 2htdp/planetcute) and then (list heart heart), the REPL only shows one image (the heart isn’t repeated), though interestingly if I ask for the length of that same list, it’s 2


chrisg
2017-10-25 16:51:30

Any idea if that’s expected behavior? Easy enough to tell my class to ignore the fact that the repl isn’t printing out the expected list so it’s not a big deal, just thought I’d bring it up


samth
2017-10-25 16:55:57

@chrisg that’s definitely a bug


chrisg
2017-10-25 17:00:12

Thanks @samth, I’ll report it as such :thumbsup:


zenspider
2017-10-25 17:24:18

@samth I just did Chris Granger’s “how long does it take to make a counting button” example… Even learning enough of racket/gui it only took me 3–4 minutes… but is there something I can have represented in the repl that could do the same thing? I had to have a [parent frame] thingy to make this demo work and would just like to have a thing drop into the repl w/ some state.


samth
2017-10-25 17:25:33

@zenspider I don’t think there’s a really easy way to add a button to the repl, but I know very little racket/gui programming


zenspider
2017-10-25 17:25:50

looks like button-snip% would be close if it weren’t backed by an image


zenspider
2017-10-25 17:26:13

oh! text-button-snip%


zenspider
2017-10-25 17:27:57

hrm. nope :confused:


jason_gregory
2017-10-25 17:59:34

@jason_gregory has joined the channel


apg
2017-10-25 18:17:35

I’m trying to wrap my head around units and how to think about them. They seem mostly prevalent in gui code written in the pre-Racket days (PLT Games, Slideshow, etc), but they seem like a pretty powerful construct for building other applications and structuring libraries around.


apg
2017-10-25 18:19:08

As an example, @lexi.lambda’s envy project seems like a natural fit. envy could produce a signature, and the environment parsing could produce a unit that matches the signature for use everywhere.


apg
2017-10-25 18:19:43

but, in testing, you could provide a “mocked” unit…


apg
2017-10-25 18:20:46

but, based on my peering into slideshow’s code, it seems like units “infect” — I’m not sure if that’s just the style of slideshow’s codebase, or a practical “limitation” of working with them. Is my understanding accurate?


apg
2017-10-25 18:22:21

And, finally: does it make sense to think of a unit as a “parameterizable, reinvokable” module?


mflatt
2017-10-25 18:30:29

@apg Yes, a parameterizable, reinvokable module is definitely the right idea. A unit cannot import or export macros, although macros can be “exported” in unit signatures. Yes, units tend infect if you want to parameterize in interesting ways, and the overhead of doing that is why they’re not used as pervasively as we originally imagined. Units are still a decent option for dealing with mutual dependencies, since units allow cycles in the dependency graph, and modules don’t. Units can also be good for parameterization, but lambda turns out to be enough more often than not.


apg
2017-10-25 18:36:54

@mflatt thanks for the explanation! the other analogy I thought of is simply a class. but, that’s more squinty.


apg
2017-10-25 18:44:21

what if units were extended to support a notion of calling intosend in class terms, such that they could be linked without affecting local bindings (which is where I think the “infectiousness” stems from)?


apg
2017-10-25 18:45:43

so for every exportable you could write the equivalent of (unit@ some-function-in-sig) ?


apg
2017-10-25 18:48:11

to call the some-function-in-sig without binding it in your current module’s namespace


apg
2017-10-25 18:48:48

sort of a dynamic “fluid” import of sorts


mflatt
2017-10-25 18:48:52

You can use (let () (define-values/invoke-unit ....) ....) to do that kind of thing.


apg
2017-10-25 18:49:37

hmm.. does invoking the unit cost a lot though?


mflatt
2017-10-25 18:51:04

It costs some, similar to calling a function that contains definitions in its body. If you want a single instance that acts like an object, then you could certainly implement that macro. There’s a compile-time API to inspect signatures.


apg
2017-10-25 18:51:47

yeah, i guess the thing I want is temporary, or fluid “linkage”


apg
2017-10-25 18:52:44

if the unit performs some sort of expensive computation, invoking it multiple times to call a single function from it (like, with the define-values/invoke-unit) seems costly


apg
2017-10-25 18:53:37

where as, an already invoked unit that wasn’t linked (if such a thing is possible) provides this sort of first class object that I can “tap” into when needed only.


apg
2017-10-25 18:53:45

but, i guess i could just use a class for that, too.


apg
2017-10-25 18:54:23

does any of this make sense?


apg
2017-10-25 18:55:33

with the advantage that these things can be parameterized and customized effectively.


apg
2017-10-25 18:55:41

(e.g. a plugin system or something)


mflatt
2017-10-25 18:59:44

Yes, that all make sense, including the idea that you might just use a class (possibly under a lambda)


apg
2017-10-25 19:01:55

is there an easy way in racket/class classes to enforce a thing implements an interface, in the same way a unit is checked against a signature?


apg
2017-10-25 19:13:30

I guess as a final point, maybe the best idea is a macro, like you suggested (and I’m just catching up to), that invokes a unit, captures and saves off it’s exports into a first class thing (e.g. a struct) that can get the dynamic linkage I’m searching for, without the cost of reinvoking the unit each time.


apg
2017-10-25 19:18:09

maybe a struct with a prop:procedure that ties it all together. :thinking_face:


apg
2017-10-25 19:18:17

thanks again, @mflatt


greg
2017-10-25 19:36:54

@apg If you want runtime linkage another idea is to start with dynamic-require, and build up from that that?


greg
2017-10-25 19:37:19

Let’s say, the plugin interface requires plugins to provide functions named start do and finish — or provide a struct or class named the-interface.


greg
2017-10-25 19:37:35

On the consuming side your app could store the dynamic-required result(s) in var(s) wrapped in contract(s) if you wish.


greg
2017-10-25 19:38:31

(Maybe I didn’t follow the discussion well. Just wanted to point out that dynamic-require is a thing. Maybe too low-level for what you’re trying to do.)


apg
2017-10-25 19:44:55

@greg I’m not, yet, trying to do anything. Just exploring what units are (and are not) good for.


apg
2017-10-25 19:45:45

dynamic-require sounds worth exploring, though I’m not sure it gets at the ability to “mock” things like in my example with envy.


apg
2017-10-25 19:45:54

maybe.


apg
2017-10-25 19:53:27

hmmm, yeah, I guess other than the signature aspect of it, @greg, this could work the same way.


apg
2017-10-25 19:54:11

you still get the separation of namespaces that are important in this theoretical use case. worth considering, for sure.


apg
2017-10-25 23:06:02

does anyone have context on neil van dyke’s “uri-old” package?


apg
2017-10-25 23:06:17

is it called “uri-old” because there’s a new thing? or something else?


apg
2017-10-25 23:07:10

oh. nevermind. it’s “old and obsolete, but nevertheless still in use.”


apg
2017-10-25 23:11:55

I ask, mostly, because I’m curious why net/url doesn’t provide a #url"<http://blargh>" reader like uri-old does.


lexi.lambda
2017-10-25 23:43:14

@mflatt Do you have any intuition around whether or not it would be possible to make splicing-syntax-parameterize used in a 'module-begin context apply to declarations lifted with syntax-local-lift-module-begin-declaration? It seems like it would be necessary to force expansion using local-expand, but that seems like it would be okay in a 'module-begin context, since the expander is going to recursively expand the module, anyway. Does that make sense, or am I speaking nonsense?


mflatt
2017-10-26 00:46:24

@lexi.lambda Do you mean local-expand/capture-lifts? It sounds like that could work.


lexi.lambda
2017-10-26 00:47:09

I just mean local-expand… my understanding is local-expand/capture-lifts is only for syntax-local-lift-expression. I want to make this work for something that uses syntax-local-lift-module-end-declaration.


mflatt
2017-10-26 00:48:01

Oh, I see. I’m less optimistic about that.


lexi.lambda
2017-10-26 00:48:43

I’ve hacked something together since I asked the question, and it passes the tests I wrote. However, it doesn’t seem to be working in my “real” problem, so I’m not sure what’s going on.


lexi.lambda
2017-10-26 00:49:22

I did observe that calling local-expand with 'module-begin as the context seems to, indeed, capture things lifted by syntax-local-lift-module-end-declaration.


lexi.lambda
2017-10-26 00:52:29

mflatt
2017-10-26 00:53:30

My guess is that expansion for 'module-begin either goes too far or a partial doesn’t go far enough to expose all of the relevant lifts, but maybe it can be made to work


lexi.lambda
2017-10-26 00:55:25

When in a 'module-begin context, after the initial introduction of #%module-begin, doesn’t the expander recursively expand the module, anyway? There’s no more partial expansion at that point, right?


mflatt
2017-10-26 00:56:41

Yes, but I was thinking that you need something to be partial to add the parameterization. But maybe I haven’t given it enough thought, and I can look more tomorrow


lexi.lambda
2017-10-26 00:57:30

Okay. My naïve attempt just bound the identifiers in a first-class definition context, then called (local-expand stx 'module-begin '() ctx).


lexi.lambda
2017-10-26 01:00:28

The main reason I’m trying this, for what it’s worth, is to avoid needing to reimplement module+ for Hackett. I started by trying to ditch syntax parameters entirely and just use phase 1 parameters, but I don’t think that interacts with submodules properly, an issue I stumbled into before.


lexi.lambda
2017-10-26 01:01:25

So it seems like binding the right identifiers and forcing recursive expansion should work alright, even if it’s a little roundabout. But it isn’t working, so I’m trying to figure out why.


lexi.lambda
2017-10-26 01:23:39

@mflatt Here’s a reduced program I’ve managed to come up with that completely perplexes me: #lang racket (require syntax/parse/define) (define-syntax x #f) (define-simple-macro (print-shadower!) #:do [(println (syntax-local-value (syntax-local-get-shadower #'x)))] (void)) (define-simple-macro (expand-and-shadow form ...) #:do [(define ctx (syntax-local-make-definition-context)) (syntax-local-bind-syntaxes (list (syntax-local-introduce (syntax-local-get-shadower #'x))) #'#t ctx)] #:with result (local-expand #'(#%plain-module-begin form ...) 'module-begin '() ctx) #:do [(println (syntax-&gt;datum #'result))] result) (module* a #f (expand-and-shadow (print-shadower!))) (module* b #f (expand-and-shadow (define y (print-shadower!)))) Here’s the output: #t '(#%plain-module-begin (#%app void)) #f '(#%plain-module-begin (define-values (y) (#%app void))) Why does the second example print #f?


lexi.lambda
2017-10-26 01:23:57

I think I must not understand how first-class definition contexts work.


lexi.lambda
2017-10-26 01:24:43

Also, excitingly, it seems that using syntax-local-make-definition-context in a 'module-begin context produces an internal expander error on racket7.


lexi.lambda
2017-10-26 01:32:05

Here’s an even simpler test case: #lang racket (require syntax/parse/define) (define-simple-macro (bind-and-expand x:id form ...) #:do [(define ctx (syntax-local-make-definition-context)) (syntax-local-bind-syntaxes (list #'x) #'(λ (stx) (println stx) #'(void)) ctx)] #:with result (local-expand #'(#%plain-module-begin form ...) 'module-begin '() ctx) #:do [(writeln (syntax-&gt;datum #'result))] result) (module* a #f (bind-and-expand x x)) (module* b #f (bind-and-expand x (define y x))) The first module* declaration compiles fine, but the second produces an identifier-used-out-of-context error.


lexi.lambda
2017-10-26 01:39:40

This weirdness really does seem potentially specific to 'module-begin because I can’t get similar behavior with other expansion contexts, and the fact that it crashes the new expander seems like reason to believe it’s doing something strange.


notjack
2017-10-26 04:34:05

I have Many Opinions about both this and uris in general