[racket-users] Trouble with recursive lambda macros, using Y combinator

2016-09-10 Thread Vasily Rybakov
Hi!

I'm learning Racket and I stumpbled into a couple of problems with macros.

I tried to make macros that implements recursive lambda, but not the classic 
one (that uses letre), but the one that uses Y combinator.

So it should work like this:

(recursion fact (n)
(if (zero? n)
1
(* n (fact (sub1 n)

transforms into

((lambda (x) (x x))
(lambda (fact)
  (lambda (n)
 (if (zero? n) 1 (* n ((fact fact) (sub1 n)))

which produces recursive anonymous function to compute factorial.

So I wrote this macros:

(define-syntax recursion
  (syntax-rules ()
[(_ label (args ...) body ...)
 ((lambda (x) (x x))
  (lambda (label)
(lambda (args ...)
  (substitute-term label (label label) body) ...)))]))

(substitute-term) macros is helper macros to substitute one piece of code with 
another, here its fist version:

(define-syntax (substitute-term stx)
  (syntax-case stx ()
[(_ term-from term-to body)
   (cond
 [(null? (syntax-e #'body)) #'(void)]
 [(list? (syntax-e #'body)) #`#,(map (lambda (x) (append (syntax-e 
#'(substitute-term term-from term-to)) (if (list? x) x (list x (syntax-e 
#'body))]
 [else (if (equal? (syntax-e #'body) (syntax-e #'term-from)) #'term-to 
#'body)])]))

>(substitute-term - + (- 1 2))
3

This works. But

>(substitute-term and or (and #t #f))
or: bad syntax in: or

Macro stepper shows that it expands into

(or (substitute-term and or #t) (substitute-term and or #f))

And after this step is "bad syntax" error. I couldn't figure why is this and 
how to fix it. It raises "bad syntax" errors with all special forms for some 
reason. Can somebody explain to me -- why? And how to fix it?

Then I tried rewrite (substitute-term) macro:

(define-syntax (substitute-term-2 stx)
  (syntax-case stx ()
[(substitute-term term-from term-to body)
 (datum->syntax stx (for-substitute-term (syntax->datum #'term-from) 
(syntax->datum #'term-to) (syntax->datum #'body)))]))

It uses helper function (define-for-syntax) which do all the work:

(define-for-syntax (for-substitute-term term-from term-to expr)
  (cond
[(null? expr) (void)]
[(list? expr) (map (lambda (x) (apply for-substitute-term (list term-from 
term-to x))) expr)]
[else (if (equal? expr term-from) term-to expr)]))

>(substitute-term-2 and or (and #t #f))
#t

Hurray! But if I use it in my (recursion) macro:

(define-syntax recursion-2
  (syntax-rules ()
[(_ label (args ...) body ...)
 ((lambda (x) (x x))
  (lambda (label)
(lambda (args ...)
  (substitute-term-2 label (label label) body) ...)))]))

>((recursion-2 fact (n)
(if (zero? n)
1
(* n (fact (sub1 n) 5)
n: unbound identifier in module
  context...:
  other binding...: in: n

Although macro stepper shows that it expands into

((lambda (x) (x x))
 (lambda (fact)
   (lambda (n)
 (substitute-term-2
  fact
  (fact fact)
  (if (zero? n) 1 (* n (fact (sub1 n

Which if entered in interaction area works as intended. I understand that 
binding for n is lost when I invoke (substitute-term-2) macro on body. But I 
couldn't find in documentation -- why? And how to fix it?

I would be grateful, if somebody explained to me what's wrong with my first and 
my second attempts and how to fix them. Thanks!

-- 
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] Image Transparency Detection

2016-09-10 Thread Lehi Toskin
On Saturday, September 10, 2016 at 5:45:43 AM UTC-7, Matthew Flatt wrote:
> I think that means information about the source stream's alpha channel
> really is not available through the current interface. A pull request
> to add that would be welcome.

I've been looking through bitmap%'s definition and I can't seem to find what I 
would need to change to make it work how I expect. Ah, well, I guess I'll just 
have to manage without the alpha channel detection.

Thanks for the help, Matthew.

-- 
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] Using the base language’s get-info function with make-meta-reader

2016-09-10 Thread Alex Knauth

> On Sep 8, 2016, at 4:36 PM, Alexis King  wrote:
> 
> Alright, I’m finally taking a look at this (and looping the users
> list back in). I think, unfortunately, your (Alex’s) change isn’t
> quite sufficient: having access to the get-info function isn’t
> enough. The read and read-syntax functions need access to the lambda
> returned by the base language’s get-info procedure, not the wrapper
> function that accepts an input port.

That still shouldn't be a problem with my attempted version. If the 
`convert-lang` function has access to the old `read-syntax` and the old 
`get-info` functions (the ones that the base language `provide`s), then it can 
return a `read-syntax` function that applies the old `get-info` function to the 
proper arguments to give you what you want.

> I just tried my hand at this, and I managed to get a hacky solution
> working. I’ve put my version in a gist here:
> 
> https://gist.github.com/lexi-lambda/12b3c23d58937ce66fff03be2adb6e99
> 
> The above code is almost identical to make-meta-reader from
> syntax/module-reader, but the read-fn function is altered to pass
> both the underlying read or read-syntax function AND the result of
> -get-info to the convert-read function. You can see this on line
> 65 of the above gist.
> 
> The interface is still pretty bad, since it requires that users of
> the function accept both arguments, so I’d want to clean it up a
> lot before putting it in a package somewhere. I don’t have any
> immediate plans to do that yet, though, so somebody might find some
> use for this code in the meantime. I’ve successfully used this code
> to implement a language extension that uses the result of a base
> language’s get-info function to direct how reading should work.
> 
> Alexis
> 
>> On Sep 6, 2016, at 9:19 PM, Alex Knauth  wrote:
>> 
>> I have no idea whether this works or not; it's completely untested. I took 
>> the existing implementation of make-meta-reader and tried to manipulate it 
>> into something that allowed one `convert-lang` function to convert the 
>> `read`, `read-syntax`, and `get-info` functions together, with each able to 
>> reference the base-language's versions of the others. I might have made some 
>> mistakes confusing the get-info function with the function that get-info 
>> returns, things like that. I have no idea how many of those kinds of errors 
>> I might have made.
> 

-- 
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] Image Transparency Detection

2016-09-10 Thread Matthew Flatt
At Sat, 10 Sep 2016 01:10:53 -0700 (PDT), Lehi Toskin wrote:
> On Friday, September 9, 2016 at 7:45:32 PM UTC-7, Matthew Flatt wrote:
> > You could use 'unknown/mask, which should create a mask bitmap only if
> > the source stream has an alpha channel, but at the expense of parsing
> > the file an extra time.
> 
> Running `(read-bitmap img 'unknown/mask)` produces a bitmap with a
> mask, but the problem I'm seeing is that every image, no matter the
> type, will return a mask. Images that have no alpha channel (I tested
> several jpegs and pngs) will produce an all-black bitmap of the same
> size as the image.

Ah, ok. I was going more by the docs than by memory or looking at the
code (so I think the docs are misleading, and I'll adjust them).

I think that means information about the source stream's alpha channel
really is not available through the current interface. A pull request
to add that would be welcome.

-- 
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] Image Transparency Detection

2016-09-10 Thread Lehi Toskin
On Friday, September 9, 2016 at 7:45:32 PM UTC-7, Matthew Flatt wrote:
> You could use 'unknown/mask, which should create a mask bitmap only if
> the source stream has an alpha channel, but at the expense of parsing
> the file an extra time.

Running `(read-bitmap img 'unknown/mask)` produces a bitmap with a mask, but 
the problem I'm seeing is that every image, no matter the type, will return a 
mask. Images that have no alpha channel (I tested several jpegs and pngs) will 
produce an all-black bitmap of the same size as the image. It works as expected 
with images that do have alpha channels, however.

Testing it with

(define bmp (make-object bitmap% 50 50))
(send bmp load-file path-to-img 'unknown/mask)

will produce a bitmap that when running `get-loaded-mask`, always returns #f.

-- 
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.