greghendershott / rackjure

Provide a few Clojure-inspired ideas in Racket. Where Racket and Clojure conflict, prefer Racket.
BSD 2-Clause "Simplified" License
236 stars 17 forks source link

~> and ~>> suffer from CLJ-1121 #28

Closed qerub closed 10 years ago

qerub commented 10 years ago

http://dev.clojure.org/jira/browse/CLJ-1121

I'm not sure if it's worth fixing, but wanted to bring it up.

greghendershott commented 10 years ago

Thanks for bringing this up. Interesting. I'll take a look.

greghendershott commented 10 years ago

Only just starting to look at this, but want to point out that http://dev.clojure.org/jira/browse/CLJ-1121 gives this example:

(macroexpand-1 (macroexpand-1 '(-> a b c)))
; =>
(c (-> a b))

saying:

c is now in control if it is a macro, and is now seeing the argument (-> a b) rather than (b a) as would be the case if we had written (c (b a)) originally.

Although Rackjure's ~> requires 3 expansion not 2 to get to that same point, it does get there:

#lang rackjure
(expand-once (expand-once (expand-once #'(~> a b c))))
; =>
#<syntax (c (~> a b))>

So yes, it looks like a similar issue.

I do think I may need some coffee to get riled up about the importance of fixing this. :) To identity an example where it would matter, which I would also like to have for a unit test. If you know of one please let me know. In any case I will undertake a fix.

greghendershott commented 10 years ago

I pushed a commit only to a topic branch, for now. Although it passes my current unit tests, maybe the tests aren't good-enough. There are enough moving parts, that I want to sleep on it.

Also if someone like @samth or @takikawa wanted to eyeball, I'd be grateful. This at the edge of my macrology.


BTW Asumu: Let me know if the last few commits on threading.rkt are of interest to you. Although I know the quote case is N/A for you:

If any of the above, please let me know and I'd be happy to give you a pull request. Or, of course feel free to borrow back -- especially seeing as how you gave me such a huge head start on the initial implementation.

qerub commented 10 years ago

I went off with another implementation approach: https://github.com/qerub/rackjure/commit/4bf950e2a3cac54e27471e1500ec06b243b85d46

I think they missed the occasion to do a left fold in the Clojure implementation. :)

Unfortunately, I based my version on an old checkout lacking a fix for #25, but I'll try to rectify that later.

greghendershott commented 10 years ago

I think they missed the occasion to do a left fold in the Clojure implementation. :)

Although I'm not too hip to Clojure culture, I think I know what you mean. If you write a loop/recur instead of using HOFs, you get your membership card revoked? :)

I went off with another implementation approach: qerub@4bf950e

I really like the way you factored out the duplication. Nice!

Unfortunately, I based my version on an old checkout lacking a fix for #25, but I'll try to rectify that later.

Yes, but I think I see how to do that with your implementation.

qerub commented 10 years ago

Good news! I think I fixed it while keeping the code lean with the help of this darling:

(define ((keep-stxctx f) stx . args)
  (datum->syntax stx (syntax-e (apply f stx args))))

New commit: https://github.com/qerub/rackjure/commit/69c6411fe25e64e4aee2fd71fd942c9b00ae2d33

greghendershott commented 10 years ago

It looks good!

In something like (~> a (~> b (~> c))), my previous commit used the lexical context of the "outermost" ~> or ~>> "all the way down", ensuring the #%app from that context is used. Your commit instead uses the lexical context of a (which is fine, same context) and uses it all the way down, IIUC.

I tried various permutations of default #%app vs. rackjure's applicative dict #%app, and forms that are functions vs. macros. Everything worked as expected.

So my suggestion: Why not make a pull request. We'll let Travis CI double-check whether conveniences like syntax-parser and stx-map are available in the older versions of Racket we're supporting. If it passes, I'll merge.

greghendershott commented 10 years ago

Will the really nice refactoring that you did, pay off even more when you implement some~> and some~>>? ;)

Seriously -- please let me know if you'd like to stay on a roll and do that, or, have me take a crack at it.

qerub commented 10 years ago

Certainly! I already have an implementation lying around somewhere, so let me stay on a roll. :)