Re: [racket-users] Standardizing the threading macro and organizing packages

2016-02-12 Thread Brian Adkins
On Sunday, January 31, 2016 at 1:05:17 PM UTC-5, Alexis King wrote:
> > On Jan 29, 2016, at 21:55, Brian Adkins wrote:
> > 
> > Was any consensus reached on this? I've been working through some exercises 
> > in Racket that a friend is implementing in Elixir, and I just came across a 
> > "method chaining" situation. I ended up simply writing a wrapper function, 
> > but using a version of ~> would've been nice.
> 
> Yes, actually, there was. The “threading” package was the result, and
> you can find the documentation here[1]. I believe rackjure’s threading
> implementation now also uses this package, so at least some level of
> standardization has been reached.

Awesome! I just tried it out, and it works great:

(define (score word)
  (apply + (~> word
   string-trim
   string-downcase
   string->list
   (map (curry hash-ref points) _

(define (word-count str)
  (~> str
  string-downcase
  (string-split #px"[^a-z]+")
  (foldl (λ (word hsh) (hash-update hsh word add1 0))
 (make-immutable-hash)
 _)))

> If you want Clojure-style threading macros, the threading package is
> probably your best bet. Of course, that might not actually be what you
> want: consider also looking at the different ~> from the point-free
> package, which is actually a higher-order function. When paired with a
> shorthand function package (which didn’t ever get standardized), it can
> be a little more powerful (and just as concise) than a dumb macro.

I'll check this out later.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2016-01-31 Thread Alexis King
> On Jan 29, 2016, at 21:55, Brian Adkins  wrote:
> 
> Was any consensus reached on this? I've been working through some exercises 
> in Racket that a friend is implementing in Elixir, and I just came across a 
> "method chaining" situation. I ended up simply writing a wrapper function, 
> but using a version of ~> would've been nice.

Yes, actually, there was. The “threading” package was the result, and
you can find the documentation here[1]. I believe rackjure’s threading
implementation now also uses this package, so at least some level of
standardization has been reached.

If you want Clojure-style threading macros, the threading package is
probably your best bet. Of course, that might not actually be what you
want: consider also looking at the different ~> from the point-free
package, which is actually a higher-order function. When paired with a
shorthand function package (which didn’t ever get standardized), it can
be a little more powerful (and just as concise) than a dumb macro.

> On Jan 31, 2016, at 05:58, Greg Trzeciak  wrote:
> 
> With Refinements being currently added 
> (http://andmkent.com/blog/2015/07/06/stop-2015-talk-adding-practical-dependent-types-to-typed-racket/):
> 1. Is the argument of using ~> no longer valid since refinements also use it.
> 2. Is adding refinements going to cause some conflicts with the existing 
> threading implementations?

I would say no. I’m not sure if the refinement syntax is set in stone,
and even if it is, the name of this particular macro has a relatively
long history in the Racket world, so it doesn’t make much sense to
change it now. In the event that the two are used together and do,
indeed, collide, then Racket’s ample namespace management tools are easy
enough to use to resolve the conflict.

[1]: http://pkg-build.racket-lang.org/doc/threading/index.html

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2016-01-29 Thread Brian Adkins
On Wednesday, October 7, 2015 at 11:18:41 PM UTC-4, Sam Tobin-Hochstadt wrote:
> A few thoughts:
> 
> 1. This is a great idea -- one of the reasons that I think Racket has
> avoided lots of little dialects despite syntactic flexibility is
> standardizing the community on one thing. I'm glad you're continuing
> this.
> 
> 2. When we've standardized on this sort of thing in the core, the
> primary way we arranged it is writing things on mailing lists, so I
> hope that works just as well here.
> 
> 3. I agree with Jay's point about `data` and such, but I don't think
> this fits in any existing category. I'm skeptical of a grab-back
> `util` collection, though, so I think just putting this in it's own
> collection makes the most sense. If we eventually have more things
> like this, then we should come up with a category.
> 
> Sam

Was any consensus reached on this? I've been working through some exercises in 
Racket that a friend is implementing in Elixir, and I just came across a 
"method chaining" situation. I ended up simply writing a wrapper function, but 
using a version of ~> would've been nice.

The commit is here:

https://github.com/lojic/exercism-racket/commit/5d2d24c240d7157204c473ea98d2e4990bb9e4ca

Lines 29-34 on the left compared to using a wrapper function in lines 35-39 on 
the right.


> On Wed, Oct 7, 2015 at 11:09 PM, Alexis King  wrote:
> > While in St. Louis, I had a brief conversation with Jay, Alex, and Jack 
> > about how we all happen to have our own implementation of Clojure’s 
> > threading macro. That macro is called -> in Clojure, but I believe Greg’s 
> > rackjure library set the Racket standard of calling it ~>, since the arrow 
> > is already used by contracts and types (and the FFI, too, for that matter). 
> > I have no idea how many implementations of this macro exist in the wild, 
> > but 5 is already far too many.
> >
> > Duplication is an uncomfortably common problem in Lispy circles, but 
> > fragmentation is never a good thing, so I’m interested in trying to create 
> > a standard implementation. It is my understanding that Racket has mostly 
> > avoided this problem by traditionally absorbing common libraries into the 
> > core, but I also understand there’s been a push to reverse this trend by 
> > spinning these things off into packages. I plan to extract my 
> > implementation of ~> and all its associated friends (I have a lot of them) 
> > into their own package, but I’d also like to ask some questions first.
> >
> > First of all, do any people object to this idea in principle? Is this too 
> > trivial of a thing to try and standardize? Assuming that’s not the case, 
> > I’ve been wondering what collection to put these in. Currently, Racket 
> > packages tend to use their own collections, which is even recommended by 
> > the documentation. However, Jay recently brought to my attention that 
> > perhaps this isn’t the best way to organize things: it might be better to 
> > extend existing collections with new modules. For example, he suggested I 
> > move my collections library to data/collection, which would imply that the 
> > lens library should be moved to data/lens. I actually like this idea quite 
> > a bit, especially for packages that are more mature.
> >
> > This prompts the question asking where a set of utility macros actually 
> > belong. They don’t belong in data/, certainly, and they don’t belong in 
> > syntax/, since that collection deals with handling syntax objects 
> > themselves. Would it be good to create a util/ collection and place this in 
> > util/threading? Or would these be better in their own, separate collection?
> >
> > The danger of departing from the one-to-one correlation with package names, 
> > of course, is the possibility of dramatically increasing the potential for 
> > conflicts. Personally, I think that grouping collections logically might be 
> > a good thing, but maybe it isn’t worth the risk? I’m interested in hearing 
> > people’s thoughts.
> >
> > Thanks,
> > Alexis
> >
> > --
> > You received this message because you are subscribed to the Google Groups 
> > "Racket Users" group.
> > To unsubscribe from this group and stop receiving emails from it, send an 
> > email to racket-users+unsubscr...@googlegroups.com.
> > For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Robby Findler
In addition to agreeing with you and Sam here Alexis, I would like to
point out another thing that has worked well for Racket in design
situations such as these: benevolent despotism.

That is, the person in charge of the design is expected to fully and
deeply understand what they have designed and to seriously consider
others suggestions but ultimately not get bogged down in directions
that would prevent having something that works well on a reasonable
time-scale.

Robby



On Wed, Oct 7, 2015 at 10:18 PM, Sam Tobin-Hochstadt
 wrote:
> A few thoughts:
>
> 1. This is a great idea -- one of the reasons that I think Racket has
> avoided lots of little dialects despite syntactic flexibility is
> standardizing the community on one thing. I'm glad you're continuing
> this.
>
> 2. When we've standardized on this sort of thing in the core, the
> primary way we arranged it is writing things on mailing lists, so I
> hope that works just as well here.
>
> 3. I agree with Jay's point about `data` and such, but I don't think
> this fits in any existing category. I'm skeptical of a grab-back
> `util` collection, though, so I think just putting this in it's own
> collection makes the most sense. If we eventually have more things
> like this, then we should come up with a category.
>
> Sam
>
> On Wed, Oct 7, 2015 at 11:09 PM, Alexis King  wrote:
>> While in St. Louis, I had a brief conversation with Jay, Alex, and Jack 
>> about how we all happen to have our own implementation of Clojure’s 
>> threading macro. That macro is called -> in Clojure, but I believe Greg’s 
>> rackjure library set the Racket standard of calling it ~>, since the arrow 
>> is already used by contracts and types (and the FFI, too, for that matter). 
>> I have no idea how many implementations of this macro exist in the wild, but 
>> 5 is already far too many.
>>
>> Duplication is an uncomfortably common problem in Lispy circles, but 
>> fragmentation is never a good thing, so I’m interested in trying to create a 
>> standard implementation. It is my understanding that Racket has mostly 
>> avoided this problem by traditionally absorbing common libraries into the 
>> core, but I also understand there’s been a push to reverse this trend by 
>> spinning these things off into packages. I plan to extract my implementation 
>> of ~> and all its associated friends (I have a lot of them) into their own 
>> package, but I’d also like to ask some questions first.
>>
>> First of all, do any people object to this idea in principle? Is this too 
>> trivial of a thing to try and standardize? Assuming that’s not the case, 
>> I’ve been wondering what collection to put these in. Currently, Racket 
>> packages tend to use their own collections, which is even recommended by the 
>> documentation. However, Jay recently brought to my attention that perhaps 
>> this isn’t the best way to organize things: it might be better to extend 
>> existing collections with new modules. For example, he suggested I move my 
>> collections library to data/collection, which would imply that the lens 
>> library should be moved to data/lens. I actually like this idea quite a bit, 
>> especially for packages that are more mature.
>>
>> This prompts the question asking where a set of utility macros actually 
>> belong. They don’t belong in data/, certainly, and they don’t belong in 
>> syntax/, since that collection deals with handling syntax objects 
>> themselves. Would it be good to create a util/ collection and place this in 
>> util/threading? Or would these be better in their own, separate collection?
>>
>> The danger of departing from the one-to-one correlation with package names, 
>> of course, is the possibility of dramatically increasing the potential for 
>> conflicts. Personally, I think that grouping collections logically might be 
>> a good thing, but maybe it isn’t worth the risk? I’m interested in hearing 
>> people’s thoughts.
>>
>> Thanks,
>> Alexis
>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "Racket Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to racket-users+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Greg Hendershott
On Thu, Oct 8, 2015 at 10:56 AM, Greg Hendershott
 wrote:
> - If you do want a Clojure style threading _macro_, rackjure's is the
> best implementation now AFAIK. I say that with no ego because that's
> mostly thanks to help from people like Sam and Christoffer Sawicki.
> Among other things, it's careful to expand using the correct #%app
> (you can use it w/o using #lang rackjure). It could easily be its own
> package, now, if that makes more sense.

Hmm that makes it sound like I want to keep "owning" this. But
actually, if someone else would prefer to own it, I'm fine with that!
I'd change rackjure to use that other package.

If that other package even needs it, I'd offer the same sort of help
and PRs that people like Sam and Chris gave me.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Greg Hendershott
Why Rackjure

- rackjure is something I started casually, didn't expect it would
ever get 100 stars. On the other hand, I suspect nearly all of those
stars are "huh, interesting". Not "I actually use this". :)

- I have no emotional investment in it. Just feel an obligation to
support it for whoever may actually be using it.

- Also there's probably some value in a realistic example of how to do
some Clojure idioms in Racket? It's another path to Racket. Also,
"Racket is a programming-language programming language".


How Rackjure

- I'd be OK to see rackjure evolve (devolve?) toward a package that
mostly just re-provides other, more granular packages.

- If you do want a Clojure style threading _macro_, rackjure's is the
best implementation now AFAIK. I say that with no ego because that's
mostly thanks to help from people like Sam and Christoffer Sawicki.
Among other things, it's careful to expand using the correct #%app
(you can use it w/o using #lang rackjure). It could easily be its own
package, now, if that makes more sense.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Alexis King
I decided to release my threading implementation as the “threading” package. 
The documentation is here:
http://pkg-build.racket-lang.org/doc/threading/index.html

I’m okay with this because I wanted to pull them out of my utils package, 
anyway, and they’re nice to have, even if we come up with a better solution 
later. I think thrush and thrush+ from point-free might be nice to have in 
racket/function, but point-free is a good package for them, otherwise.

> On Oct 8, 2015, at 5:17 AM, Robby Findler  wrote:
> 

> In addition to agreeing with you and Sam here Alexis, I would like to
> point out another thing that has worked well for Racket in design
> situations such as these: benevolent despotism.

I appreciate the value of this, certainly, but it doesn’t help much if the 
“standard” version is just another implementation that nobody agrees on, since 
that won’t really help the fragmentation much at all.

> On Oct 8, 2015, at 7:56 AM, Greg Hendershott  
> wrote:
> 
> If you do want a Clojure style threading _macro_, rackjure's is the
> best implementation now AFAIK. I say that with no ego because that's
> mostly thanks to help from people like Sam and Christoffer Sawicki.
> Among other things, it's careful to expand using the correct #%app
> (you can use it w/o using #lang rackjure). It could easily be its own
> package, now, if that makes more sense.

I’d be interested to hear what fanciness rackjure’s threading macros provide! 
It would be nice to incorporate those into my package, since I’m sure there are 
a few things I’m missing. Expanding to the right #%app is one of those things, 
to start. My implementation also does some fanciness that Clojure’s does not, 
such as allowing arbitrary position for the arguments, but it would be nice to 
combine the best of them both.

The question about function reader syntax packages is still outstanding. I get 
the sense that those aren’t terribly commonly used... but then I also get the 
sense that packages are very reluctant to depend on anything but the core. Does 
anyone even really use these packages besides their authors?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Alex Knauth
You don't think
(define-simple-macro (-> var:id expr:expr ...+)
  (let* ([var expr] ...) var))

Is better?

It's more powerful, because it allows placeholders to be arbitrarily nested 
within the expressions.
Also, it allows the user to supply their own identifier to use as a placeholder 
instead of _, so it doesn't run into the problems of substituting an expression 
in a place you didn't want it, for instance if you had another ~> expression 
nested within in.

Because of those two things, it allows pieces of a program to be put together 
easily, without worrying about whether it will do some weird thing like insert 
an ~> expression into another ~> expression and end up with a compile-time 
infinite loop. 

It's also much simpler to keep in your head.

> On Oct 8, 2015, at 1:01 PM, Alexis King  wrote:
> 
> I decided to release my threading implementation as the “threading” package. 
> The documentation is here:
> http://pkg-build.racket-lang.org/doc/threading/index.html
> 
> I’m okay with this because I wanted to pull them out of my utils package, 
> anyway, and they’re nice to have, even if we come up with a better solution 
> later. I think thrush and thrush+ from point-free might be nice to have in 
> racket/function, but point-free is a good package for them, otherwise.
> 
>> On Oct 8, 2015, at 5:17 AM, Robby Findler  
>> wrote:
>> 
> 
>> In addition to agreeing with you and Sam here Alexis, I would like to
>> point out another thing that has worked well for Racket in design
>> situations such as these: benevolent despotism.
> 
> I appreciate the value of this, certainly, but it doesn’t help much if the 
> “standard” version is just another implementation that nobody agrees on, 
> since that won’t really help the fragmentation much at all.
> 
>> On Oct 8, 2015, at 7:56 AM, Greg Hendershott  
>> wrote:
>> 
>> If you do want a Clojure style threading _macro_, rackjure's is the
>> best implementation now AFAIK. I say that with no ego because that's
>> mostly thanks to help from people like Sam and Christoffer Sawicki.
>> Among other things, it's careful to expand using the correct #%app
>> (you can use it w/o using #lang rackjure). It could easily be its own
>> package, now, if that makes more sense.
> 
> I’d be interested to hear what fanciness rackjure’s threading macros provide! 
> It would be nice to incorporate those into my package, since I’m sure there 
> are a few things I’m missing. Expanding to the right #%app is one of those 
> things, to start. My implementation also does some fanciness that Clojure’s 
> does not, such as allowing arbitrary position for the arguments, but it would 
> be nice to combine the best of them both.
> 
> The question about function reader syntax packages is still outstanding. I 
> get the sense that those aren’t terribly commonly used... but then I also get 
> the sense that packages are very reluctant to depend on anything but the 
> core. Does anyone even really use these packages besides their authors?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Alex Knauth

> On Oct 8, 2015, at 2:27 PM, Alexis King  wrote:
> 
> 
>> On Oct 8, 2015, at 11:08 AM, Alex Knauth  wrote:
>> 
>> You don't think
>> (define-simple-macro (-> var:id expr:expr ...+)
>>  (let* ([var expr] ...) var))
>> 
>> Is better?
> 
> No, actually I, I don’t. Threading macros are a convenience, just like 
> anonymous functions. I’d rather keep them simple and easy to use than add 
> another term that needs to be provided 100% of the time that I’ll only take 
> advantage of 5% of the time.

One big thing that I find convenient is the ability to treat everything as an 
expression with sub-expressions. This is convenient because it allows me to 
move expressions around, combine them, and substitute them in whatever ways I 
want, and nothing unexpected happens. My macro and Jack Firth's function both 
allow that. 

> As for compile-time infinite loops: I can’t imagine how that could possibly 
> occur, but if you can demonstrate such a problem, that sounds like a bug.

Your implementation avoids this, and so does the current rackjure 
implementation, but I think at one point the rackjure implementation did this:
'(~>> a b (~>> c d))
'(~>> (~>> a b) (~>> c d))
'(~>> c d (~>> a b))
'(~>> (~> c d) (~>> a b))
'(~>> a b (~> c d)) ; back where we started

This confused me. The rules of recursion made sense, but the expansion didn't 
make sense because the subexpressions weren't subexpressions, but templates.

> As for simpler to keep in your head: [citation needed]. The original 
> threading macro is a simple macro that unwinds nested function application. 
> Implementation aside, I find that the most intuitive way to visualize 
> it—introducing binding makes that more complicated, not less.

Introducing binding makes it about expressions that make sense with lexical 
scope, as opposed to templates that stuff will get inserted into. 


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Alexis King
> On Oct 8, 2015, at 1:34 PM, Jay McCarthy  wrote:
> 
> FWIW, I find my threading macro to be very powerful, pretty clear when
> used complicatingly, and at about power-level 9,000:
> 
> https://github.com/jeapostrophe/exp/blob/master/threading-arrow.rkt

I have to agree with Jack and Alex here: I find that a little terrifying, and I 
would not want to need to understand any code that used it.

> My opinion is to include something like this in remix along with some
> nice syntax for cut (what ignorant people call "function literals".)

I admit I can’t really disagree with this point. I’m mostly just interested in 
what syntax you have in mind.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Jay McCarthy
FWIW, I find my threading macro to be very powerful, pretty clear when
used complicatingly, and at about power-level 9,000:

https://github.com/jeapostrophe/exp/blob/master/threading-arrow.rkt

My opinion is to include something like this in remix along with some
nice syntax for cut (what ignorant people call "function literals".)
Probably by replacing the (<> 1) in my ~> with _ and _.1 and by
writing cut as λ.(+ $.0 $.2) using _, λ, and $ as dot transformers.

Jay

On Thu, Oct 8, 2015 at 4:18 PM, Jack Firth  wrote:
> I agree about using the function form for flexibility. (Alliteration!) The
> macro form should be optimized for simple cases, because macros by nature
> are less flexible. If you have a complex case, write actual functions.
> You'll spend less time wrangling the syntax system that way.
>
> On Thu, Oct 8, 2015 at 1:16 PM, Alexis King  wrote:
>>
>> > My macro and Jack Firth's function both allow that.
>>
>>
>> Sounds like the solution is to go with a function instead of a macro then.
>> If you want that flexibility, I don’t think there’s any reason to stick with
>> a macro, anyway. The point-free package is very nice.
>>
>> Alexis
>
>



-- 
Jay McCarthy
http://jeapostrophe.github.io

   "Wherefore, be not weary in well-doing,
  for ye are laying the foundation of a great work.
And out of small things proceedeth that which is great."
  - D 64:33

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Alex Knauth

> On Oct 8, 2015, at 4:48 PM, Jay McCarthy  wrote:

> A key thing that Remix has is buttery C-like syntax for infix dots. So
> you can write r.ul.x and it might be the same as (posn-x (rectangle-ul
> r)) if `r` were bound to a "dot transformer" that looked for .ul and
> so on.


(Off topic)
Sounds a bit like my postfix-dot-notation package
http://pkg-build.racket-lang.org/doc/postfix-dot-notation/index.html 

Except that this forces you to write r.post-x.rectangle-ul instead of r.x.ul.


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Jay McCarthy
On Thu, Oct 8, 2015 at 6:23 PM, Alexis King  wrote:
>> On Oct 8, 2015, at 1:34 PM, Jay McCarthy  wrote:
>>
>> FWIW, I find my threading macro to be very powerful, pretty clear when
>> used complicatingly, and at about power-level 9,000:
>>
>> https://github.com/jeapostrophe/exp/blob/master/threading-arrow.rkt
>
> I have to agree with Jack and Alex here: I find that a little terrifying, and 
> I would not want to need to understand any code that used it.

I'm inspired by your terror.

>> My opinion is to include something like this in remix along with some
>> nice syntax for cut (what ignorant people call "function literals".)
>
> I admit I can’t really disagree with this point. I’m mostly just interested 
> in what syntax you have in mind.

The idea would be to make it like super cut, but with . to give it
that delicious C-like crunchy topping

https://github.com/jeapostrophe/exp/blob/master/scut.ss

So,

λ.(+ $ 1) => (λ (x) (+ x 1)
λ.(+ $.0 $.1) => (λ (x y) (+ x y))
λ.(+ $.x 1) => (λ (#:x x) (+ x 1)
λ.(+ $.x $8) => (λ (#:x x a0 a1 a2 a3 a4 a5 a6 a7 a8) (+ x a8)
λ.(apply + $.0 $.…) => (λ (x . args) (apply + x args))

-- 
Jay McCarthy
http://jeapostrophe.github.io

   "Wherefore, be not weary in well-doing,
  for ye are laying the foundation of a great work.
And out of small things proceedeth that which is great."
  - D 64:33

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Jack Firth
I agree about using the function form for flexibility. (Alliteration!) The
macro form should be optimized for simple cases, because macros by nature
are less flexible. If you have a complex case, write actual functions.
You'll spend less time wrangling the syntax system that way.

On Thu, Oct 8, 2015 at 1:16 PM, Alexis King  wrote:

> > My macro and Jack Firth's function both allow that.
>
>
> Sounds like the solution is to go with a function instead of a macro then.
> If you want that flexibility, I don’t think there’s any reason to stick
> with a macro, anyway. The point-free package is very nice.
>
> Alexis

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Sam Tobin-Hochstadt
On Thu, Oct 8, 2015 at 6:48 PM, Jay McCarthy  wrote:
>
>>> My opinion is to include something like this in remix along with some
>>> nice syntax for cut (what ignorant people call "function literals".)
>>
>> I admit I can’t really disagree with this point. I’m mostly just interested 
>> in what syntax you have in mind.
>
> The idea would be to make it like super cut, but with . to give it
> that delicious C-like crunchy topping
>
> https://github.com/jeapostrophe/exp/blob/master/scut.ss
>
> So,
>
> λ.(+ $ 1) => (λ (x) (+ x 1)
> λ.(+ $.0 $.1) => (λ (x y) (+ x y))
> λ.(+ $.x 1) => (λ (#:x x) (+ x 1)
> λ.(+ $.x $8) => (λ (#:x x a0 a1 a2 a3 a4 a5 a6 a7 a8) (+ x a8)
> λ.(apply + $.0 $.…) => (λ (x . args) (apply + x args))

Perhaps unsurprisingly, since this is what I implemented in fancy-app,
I think that once you're numbering things, the whole enterprise has
gone off the rails.

Either (+ _ _) [1] should mean (lambda (x) (+ x x)) or (lambda (x y)
(+ x y)) or a syntax error, but when you need to get fancier, named
function arguments are a great thing.

[1] Or whatever preferred syntax we settle on.

Sam

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Alex Knauth

> On Oct 8, 2015, at 4:51 PM, Jack Firth  wrote:
> 
> Looking at that one, I'm against back-referencing N clauses with (<> n). I 
> find it very difficult to read, and it strikes me as particularly fragile if 
> you're inserting or removing steps into the flow as you edit it. 

> Trying to count back steps (especially if they're not formatted to all be one 
> per line) is mental juggling I don't want to do, and it muddies my thought 
> process. If I really want to go to that effort to avoid naming things, I'll 
> use currying and point free composition operations.

+1
I agree completely.

> On Thu, Oct 8, 2015 at 1:34 PM, Jay McCarthy  > wrote:
> FWIW, I find my threading macro to be very powerful, pretty clear when
> used complicatingly, and at about power-level 9,000:
> 
> https://github.com/jeapostrophe/exp/blob/master/threading-arrow.rkt 
> 
> 
> My opinion is to include something like this in remix along with some
> nice syntax for cut (what ignorant people call "function literals".)
> Probably by replacing the (<> 1) in my ~> with _ and _.1 and by
> writing cut as λ.(+ $.0 $.2) using _, λ, and $ as dot transformers.
> 
> Jay

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Jack Firth
The more I think about it, the more I realize I really dislike specifying
the position of arguments in these anonymous function syntaxes. For
instance I would prefer this:

(λ (x y) (/ y x))

To this:

λ.(/ $.1 $.0)

In the common case, you won't need to flip any argument orders around. In
that case the numbering is just noise that gets tuned down relative to the
expression structure. In the uncommon case, because of the common case I
might not notice it when reading the code and could critically misread the
order of an anonymous function's arguments. In addition, when shuffling the
positions around I find it much easier to think in terms of actual
bindings, as with the first example, than in terms of positions, as in the
second example. What if I need to change argument order or insert an
argument? Now I have to tweak the numbers used in the *structure* of the
function, rather than just messing with the declaration of bindings for the
function.

This is why I like fancy-app. Once you throw out specifying positions, you
don't need that syntactic overhead in the common cases. You're left with
just structure:

(define halve (/ _ 2))

Ideally fancy app would do keyword arguments and rest arguments, perhaps
rest arguments as (+ . _). I think it handles keyword args (never tried)
but I don't know if it does rest args.

On Thu, Oct 8, 2015 at 3:48 PM, Jay McCarthy  wrote:

> On Thu, Oct 8, 2015 at 6:23 PM, Alexis King  wrote:
> >> On Oct 8, 2015, at 1:34 PM, Jay McCarthy 
> wrote:
> >>
> >> FWIW, I find my threading macro to be very powerful, pretty clear when
> >> used complicatingly, and at about power-level 9,000:
> >>
> >> https://github.com/jeapostrophe/exp/blob/master/threading-arrow.rkt
> >
> > I have to agree with Jack and Alex here: I find that a little
> terrifying, and I would not want to need to understand any code that used
> it.
>
> I'm inspired by your terror.
>
> >> My opinion is to include something like this in remix along with some
> >> nice syntax for cut (what ignorant people call "function literals".)
> >
> > I admit I can’t really disagree with this point. I’m mostly just
> interested in what syntax you have in mind.
>
> The idea would be to make it like super cut, but with . to give it
> that delicious C-like crunchy topping
>
> https://github.com/jeapostrophe/exp/blob/master/scut.ss
>
> So,
>
> λ.(+ $ 1) => (λ (x) (+ x 1)
> λ.(+ $.0 $.1) => (λ (x y) (+ x y))
> λ.(+ $.x 1) => (λ (#:x x) (+ x 1)
> λ.(+ $.x $8) => (λ (#:x x a0 a1 a2 a3 a4 a5 a6 a7 a8) (+ x a8)
> λ.(apply + $.0 $.…) => (λ (x . args) (apply + x args))
>
> --
> Jay McCarthy
> http://jeapostrophe.github.io
>
>"Wherefore, be not weary in well-doing,
>   for ye are laying the foundation of a great work.
> And out of small things proceedeth that which is great."
>   - D 64:33
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Alexis King
> My macro and Jack Firth's function both allow that.


Sounds like the solution is to go with a function instead of a macro then. If 
you want that flexibility, I don’t think there’s any reason to stick with a 
macro, anyway. The point-free package is very nice.

Alexis

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Greg Hendershott
> Quick! Should (~>> (~>> a b) (~>> c d)) be equal to (~>> (b a) (~>> c d)) ?

Well, I wouldn't want to write or read code like that. If I'm using a
threading macro, at all, it's to reduce nesting, and emphasize the
"flat", "pipeline" quality of some computations. As a result I'm not
eager to write or read nested threading macros. :)

Honestly I hardly use threading macros anymore. I used them a fair
amount in Frog, but that's a relatively "pipeline-ish" app, with lots
of "take X and run it through this series of transformations". Most of
my projects don't really have that quality, or at least I haven't
found it as helpful to express them that way.


As for a threading macro being faster than a thrush function: Although
it is, instead how I'd put it is that it's "not slower than"
traditional nested applications. For example you can "de-nest"
existing code and not worry that you also made it slower. Because it's
expanding to the same nested applications. It's just expressed in a
flat postfix syntax. IFF doing so actually makes it easier to read and
maintain, is what I ask myself these days.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Alexis King

> On Oct 8, 2015, at 11:08 AM, Alex Knauth  wrote:
> 
> You don't think
> (define-simple-macro (-> var:id expr:expr ...+)
>   (let* ([var expr] ...) var))
> 
> Is better?

No, actually I, I don’t. Threading macros are a convenience, just like 
anonymous functions. I’d rather keep them simple and easy to use than add 
another term that needs to be provided 100% of the time that I’ll only take 
advantage of 5% of the time.

As for compile-time infinite loops: I can’t imagine how that could possibly 
occur, but if you can demonstrate such a problem, that sounds like a bug.

As for simpler to keep in your head: [citation needed]. The original threading 
macro is a simple macro that unwinds nested function application. 
Implementation aside, I find that the most intuitive way to visualize 
it—introducing binding makes that more complicated, not less.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-08 Thread Alex Knauth

> On Oct 8, 2015, at 2:27 PM, Alexis King  wrote:
> 
> The original threading macro is a simple macro that unwinds nested function 
> application. Implementation aside, I find that the most intuitive way to 
> visualize it—introducing binding makes that more complicated, not less.

An ~> expression has a start expression followed by a series of templates. 

But at least the start expression is an expression, so it should be able to be 
replaced with what it equals.

Quick! Should (~>> (~>> a b) (~>> c d)) be equal to (~>> (b a) (~>> c d)) ?

Uh, wait, ahh! My intuition says yes ?

Nope.

One expands to (d c (b a)), and the other expands to (b a (d c)).

Quick! Can you tell which one expands to which? 

I can't unless I actually evaluate expand-once a bunch of times.

If I were implementing this, I would make sure that (~>> some-expr 
some-template ...) was always equal to
(let ([x some-expr])
  (~>> x some-template ...))

I'm pretty sure there's some technical term for being able to do this, but I 
can't think of it.

Apply that rule recursively to all the intermediate steps, and
(let* ([x some-expr]
   [x (subst x some-template)]
   ...)
  x)


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-07 Thread Sam Tobin-Hochstadt
A few thoughts:

1. This is a great idea -- one of the reasons that I think Racket has
avoided lots of little dialects despite syntactic flexibility is
standardizing the community on one thing. I'm glad you're continuing
this.

2. When we've standardized on this sort of thing in the core, the
primary way we arranged it is writing things on mailing lists, so I
hope that works just as well here.

3. I agree with Jay's point about `data` and such, but I don't think
this fits in any existing category. I'm skeptical of a grab-back
`util` collection, though, so I think just putting this in it's own
collection makes the most sense. If we eventually have more things
like this, then we should come up with a category.

Sam

On Wed, Oct 7, 2015 at 11:09 PM, Alexis King  wrote:
> While in St. Louis, I had a brief conversation with Jay, Alex, and Jack about 
> how we all happen to have our own implementation of Clojure’s threading 
> macro. That macro is called -> in Clojure, but I believe Greg’s rackjure 
> library set the Racket standard of calling it ~>, since the arrow is already 
> used by contracts and types (and the FFI, too, for that matter). I have no 
> idea how many implementations of this macro exist in the wild, but 5 is 
> already far too many.
>
> Duplication is an uncomfortably common problem in Lispy circles, but 
> fragmentation is never a good thing, so I’m interested in trying to create a 
> standard implementation. It is my understanding that Racket has mostly 
> avoided this problem by traditionally absorbing common libraries into the 
> core, but I also understand there’s been a push to reverse this trend by 
> spinning these things off into packages. I plan to extract my implementation 
> of ~> and all its associated friends (I have a lot of them) into their own 
> package, but I’d also like to ask some questions first.
>
> First of all, do any people object to this idea in principle? Is this too 
> trivial of a thing to try and standardize? Assuming that’s not the case, I’ve 
> been wondering what collection to put these in. Currently, Racket packages 
> tend to use their own collections, which is even recommended by the 
> documentation. However, Jay recently brought to my attention that perhaps 
> this isn’t the best way to organize things: it might be better to extend 
> existing collections with new modules. For example, he suggested I move my 
> collections library to data/collection, which would imply that the lens 
> library should be moved to data/lens. I actually like this idea quite a bit, 
> especially for packages that are more mature.
>
> This prompts the question asking where a set of utility macros actually 
> belong. They don’t belong in data/, certainly, and they don’t belong in 
> syntax/, since that collection deals with handling syntax objects themselves. 
> Would it be good to create a util/ collection and place this in 
> util/threading? Or would these be better in their own, separate collection?
>
> The danger of departing from the one-to-one correlation with package names, 
> of course, is the possibility of dramatically increasing the potential for 
> conflicts. Personally, I think that grouping collections logically might be a 
> good thing, but maybe it isn’t worth the risk? I’m interested in hearing 
> people’s thoughts.
>
> Thanks,
> Alexis
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Standardizing the threading macro and organizing packages

2015-10-07 Thread Alexis King
While in St. Louis, I had a brief conversation with Jay, Alex, and Jack about 
how we all happen to have our own implementation of Clojure’s threading macro. 
That macro is called -> in Clojure, but I believe Greg’s rackjure library set 
the Racket standard of calling it ~>, since the arrow is already used by 
contracts and types (and the FFI, too, for that matter). I have no idea how 
many implementations of this macro exist in the wild, but 5 is already far too 
many.

Duplication is an uncomfortably common problem in Lispy circles, but 
fragmentation is never a good thing, so I’m interested in trying to create a 
standard implementation. It is my understanding that Racket has mostly avoided 
this problem by traditionally absorbing common libraries into the core, but I 
also understand there’s been a push to reverse this trend by spinning these 
things off into packages. I plan to extract my implementation of ~> and all its 
associated friends (I have a lot of them) into their own package, but I’d also 
like to ask some questions first.

First of all, do any people object to this idea in principle? Is this too 
trivial of a thing to try and standardize? Assuming that’s not the case, I’ve 
been wondering what collection to put these in. Currently, Racket packages tend 
to use their own collections, which is even recommended by the documentation. 
However, Jay recently brought to my attention that perhaps this isn’t the best 
way to organize things: it might be better to extend existing collections with 
new modules. For example, he suggested I move my collections library to 
data/collection, which would imply that the lens library should be moved to 
data/lens. I actually like this idea quite a bit, especially for packages that 
are more mature.

This prompts the question asking where a set of utility macros actually belong. 
They don’t belong in data/, certainly, and they don’t belong in syntax/, since 
that collection deals with handling syntax objects themselves. Would it be good 
to create a util/ collection and place this in util/threading? Or would these 
be better in their own, separate collection?

The danger of departing from the one-to-one correlation with package names, of 
course, is the possibility of dramatically increasing the potential for 
conflicts. Personally, I think that grouping collections logically might be a 
good thing, but maybe it isn’t worth the risk? I’m interested in hearing 
people’s thoughts.

Thanks,
Alexis

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-07 Thread Alexis King
> If this isn't going to be added to the core (and I don't think it should), 
> then there would need to be some work done on exposure and making sure 
> everyone who wants this functionality knows "look here first and only roll 
> your own if this isn't specific enough”.

This is a good point, and it’s one that I’ve considered. I’m not entirely sure 
what the solution is. The “rings” system in the package manager seems like a 
potential attempt to account for this, but that system is, as of now, unused. 
Clojure has a “Clojure contrib” project, which pulls certain user-created 
packages into the clojure GitHub org, but I’m not sure that’s really much of a 
helpful (or scalable) approach.

> As for the actual package, I'm a strong proponent of a non-macro version 
> that's just the reverse of compose, mostly because it plays very nicely with 
> anonymous macro functions like fancy-app. I'm a bit biased as that's the one 
> I made in my point-free package however. Macro versions are nice too, but I 
> prefer the flexibility of an actual function for most purposes.

I kind of agree with this, even if it isn’t really idiomatic Racket. With good 
lambda shorthand, this is really just as good as any threading macro I’ve seen, 
and it’s more flexible at that. In practice, I haven’t found that added 
flexibility all that important in Racket code, but it is conceptually nicer.

The obvious argument against this is “it’s slow!”, which is true currently. The 
macro version is quite a bit faster than the higher-order function, for obvious 
reasons. That said, I tend to err on the side of conceptual cleanliness over 
speed, and it’s hard to argue using a macro where a function would do.

The real argument is that, well, Racket *doesn’t* have built-in function 
shorthand. Perhaps we should be discussing that package zoo instead? The 
versions I know off the top of my head are:

- fancy-app — Sam’s. Implemented as a module by exporting a customized
  #%app that works at expansion-time.
- rackjure  — Greg’s. Implemented as a full language. Works at read-time
  using readtable dispatch macros with a prefix.
- afl   — Alex’s. Implemented as a meta-language. Works at read-time
  using readtable dispatch macros with a prefix.
- curly-fn  — Mine. Implemented as a meta-language. Works at read-time using
  readtable dispatch macros and curly braces.

(If I’m missing any, please let me know.)

While rackjure is quite cool, it’s much more than just anonymous functions and 
it isn’t composable, so I consider that out. I know fancy-app is somewhat 
appealing because it doesn’t need to be implemented at read-time, but I find 
that it doesn’t have a very strong visual sigil that clues me into the fact 
that something is a lambda expression, not an application. I think the uniform 
syntax works against readability here.

So, in my highly subjective opinion, that leaves afl and curly-fn. I think it 
goes without saying which one I prefer, but I’ll be the first to admit that the 
differences are minor. The only semantic difference is that curly-fn doubles as 
a shorthand for `curry` when no argument placeholders are provided, which I 
think is a nice feature, but it could also be easily added to afl.

I think that summarizes another case in which we have lots of libraries that do 
the same thing in slightly different ways. This example, however, is different: 
it is something that quite likely *should* be in the core. This might be the 
best argument for afl, given that it would be the most seamless to add in a 
backwards-compatible way, but this is probably another thing to hold off until 
racket2, anyway. Until that happens, what are people’s thoughts on this batch 
of conflicting libraries?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Standardizing the threading macro and organizing packages

2015-10-07 Thread Alex Knauth
To clarify this, I think the function version is better because it's more 
powerful and more general, not just because it's convenient.
A macro constrains you to the syntax, but a function can be used in many 
different ways.

Similarly for the macro, allowing the user to specify the identifier to use as 
a placeholder allows -> expressions to be nested within other ->, meaning 
pieces can be fit together much more nicely. That's one thing functions do that 
these shorthand macros tend to leave aside.

> On Oct 8, 2015, at 12:34 AM, Alex Knauth  wrote:
> 
> 
>> On Oct 8, 2015, at 12:02 AM, Jack Firth > > wrote:
> 
>> As for the actual package, I'm a strong proponent of a non-macro version 
>> that's just the reverse of compose, mostly because it plays very nicely with 
>> anonymous macro functions like fancy-app. I'm a bit biased as that's the one 
>> I made in my point-free package however. Macro versions are nice too, but I 
>> prefer the flexibility of an actual function for most purposes.
> 
> 
> +1
> I like the function version better too, as long as I'm also using a good 
> library (such as afl or fancy-app) for concise anonymous functions.
> 
> But for more complicated expressions, especially involving nesting, what I 
> really want is something like this:
> 
> (-> x ; declares that x is the equivalent of _ or <>
>   1
>   (add1 x)
>   (number->string x 2)
>   (string-append x "1")
>   (string->number x 10))
> 
> This is especially helpful when the xs are more deeply nested within the 
> expressions.
> 
> Which can be defined easily like this:
> (define-simple-macro (-> var:id expr:expr ...+)
>   (let* ([var expr] ...) var))
> 
> The some-> version is almost as simple:
> (define-simple-macro (some-> var:id expr0:expr expr:expr ...)
>   (let* ([var expr0] [var (and var expr)] ...) var))
> 
> I actually got this idea from Matthias Felleisen, from this email on the list:
> https://groups.google.com/forum/#!msg/racket-users/Um0_anlD8r4/1r-GFejV_HYJ 
> 
> Which was rewritten to use let* instead of set! here:
> https://groups.google.com/forum/#!msg/racket-users/Um0_anlD8r4/cpW0Bp-GMpUJ 
> 
> 
> I think it would be useful to provide both the function and the macro, 
> without trying to conflate the two.


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.