Re: [racket-users] How to delay evaluation of a set! expression

2017-12-21 Thread Deren Dohoda
Vityou,

> even though (class ...) expands into a function where method-list is
defined.

It does not expand into a function where method-list is defined because it
does not expand in that way. The macro "define/method" is called with the
given syntax and the macro operates on that syntax (it's just a procedure
that takes a syntax argument and evaluates to syntax) and where the macro
lives, "method-list" is neither defined nor given as part of use of the
syntax. So the macro introduces it's own "method-list", so something in the
background like "method-list7734", which isn't your "method-list" but since
the macro's own "method-list" doesn't exist, set! doesn't know what to do,
and you get an error. This is a combination of how procedures work and how
hygiene works in macros.

One way to manage this is to make it part of the syntax:
;
(define-syntax (define/method stx)
  (syntax-parse stx
[(_ (name ML arg ...) body)
 #'(begin (define (name arg ...) body)
  (set! ML (cons `(name ,name) ML)))]))

(define (make-person name age)
  (define (obj arg)
(define method-list '())
(define/method (get-name method-list) name)
(second (assq arg method-list)))
  obj)
;
Then it expands as you expect, because it's operating on the syntax you
have given it.

Another way: the macro can be coerced to use an identifier which it doesn't
understand by breaking the hygiene barrier

;
define-syntax (define/method stx)
  (syntax-parse stx
[(_ (name arg ...) body)
 (with-syntax ((ML (datum->syntax stx 'method-list)))
#'(begin (define (name arg ...) body)
 (set! ML (cons `(name ,name) ML]))
;
Now this macro assumes the identifier "method-list" exists in whatever
context the code expands in, which is the behavior you expect.

Normally we don't want to break hygiene. For instance, if a macro's code
introduced some temporaries like "num" or "x" or something, we wouldn't
want those temporaries to shadow or otherwise clobber some innocent
macro-user's own use of these identifiers. When we call a procedure like
"displayln" we don't need to worry that the author of the code used some
name for some local identifier. Since macros are just racket procedures,
too, the same reasoning applies: we don't want to worry that when we call a
macro it might use some name we've already used. In your case, this is your
exact intention, so racket allows you to break this protective mechanism
explicitly.

Deren

-- 
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] How to delay evaluation of a set! expression

2017-12-21 Thread Vityou
That works ok but if I want to define a class macro like this:

(define-syntax (define/method stx)
  (syntax-parse stx
[(_ method-list (name arg ...) body)
#'(begin (define (name arg ...) body)
 (set! method-list (cons `(name ,name) method-list)))]))

(define-syntax (class stx)
  (syntax-parse stx
[(_ (init-args ...) body ...)
 #'(lambda (init-args ...)
 (lambda (arg)
   
   (define method-list '())
   body ...
   (second (assq arg method-list]))

and then use it:

(define person-class (class (name age)
   (define/method method-list (get-name) name)))

racket complains that method-list isn't defined, even though (class ...) 
expands into a function where method-list is defined.

-- 
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] How to delay evaluation of a set! expression

2017-12-21 Thread Deren Dohoda
Hi Vityou,

Racket macros are procedures and like all procedures only have access to
values in their scope. Conceptually, yes, macros replace code with other
code, but how they do this is not like a glorified C preprocessor. One way
to manage this: you can move the definition of the procedure
"define/method" to a place where it knows what "method-list" is.

#lang racket
(require (for-syntax syntax/parse))

(define (make-person name age)
  (define-syntax (define/method stx)
  (syntax-parse stx
[(_ (name arg ...) body)
#'(begin (define (name arg ...) body)
 (set! method-list (cons `(name ,name) method-list)))]))
  (define method-list '())
  (define (obj arg)
(define/method (get-name) name)
(second (assq arg method-list)))
  obj)
;;;
Welcome to DrRacket, version 6.9 [3m].
Language: racket [custom]; memory limit: 8192 MB.
> (((make-person 'phil 12) 'get-name))
'phil

-- 
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] How to delay evaluation of a set! expression

2017-12-21 Thread Vityou
I am trying to make a macro that helps with creating class-like closures.

#lang racket
(require (for-syntax syntax/parse))

(define-syntax (define/method stx)
  (syntax-parse stx
[(_ (name arg ...) body)
#'(begin (define (name arg ...) body)
 (set! method-list (cons `(name ,name) method-list)))]))

(define (make-person name age)
  (define (obj arg)
(define method-list '())
(define/method (get-name) name)
(second (assq arg method-list)))
  obj)

The goal is for all occurrences of (define/method ...) to get replaced with 
a normal define and a key and value added to an existing list.  However, 
racket complains in the macro definition that method-list isn't defined.  I 
thought that macros just replaced code with other code, not evaluated the 
syntax object that should replace something.

(define/method (get-name) name)   -> (define (get-name) name) (set! 
method-list (cons `(get-name ,get-name) method-list))

-- 
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] Re: Confirming when garbage collection runs

2017-12-21 Thread Gustavo Massaccesi
I'm not sure if this is the exact answer to your question, but I hope it helps.

This program shows the content of the two vectors, (i.e.
) but when the first vector is
freed it displays "goodbye" in the middle of the sequence. So you can
see when it was released.

You can modify it to peek what job-queue is doing.

Gustavo

(PS: If you use a "list" instead of a "vector", you will get a weird
result, because the head of the list is released as soon as possible,
but the tail is not released until later.)

;--
#lang racket

; force some randoms garbage collections
(void (thread
   (lambda ()
 (let loop ()
   (sleep (random 1 3))
   (collect-garbage)
   (loop)

; make a will executor to see when something is freed
(define the-executor (make-will-executor))
(void (thread
   (lambda ()
 (let loop ()
   (will-execute the-executor)
   (loop)
(define (remember-to-say-goodbye v)
  (will-register the-executor
 v
 (lambda (x) (display "goodbye"

; display, but wait a moment
(define (display/slow x)
  (sleep .2)
  (display x))

; make a vector that says goodbye when freed
(define (make-polite-vector l v)
  (let ([ret (make-vector l v)])
(remember-to-say-goodbye ret)
ret))

;main program
(void (thread
   (lambda ()
 (for ([x (make-polite-vector 20 0)])
   (display/slow x))
 (for ([x (make-vector 20 1)])
   (display/slow x)

;--


On Wed, Dec 13, 2017 at 3:57 PM, David Storrs  wrote:
> Sorry, bumped 'send' by mistake
>
> Imagine I do this:
>
> (struct fruit (num))
> (define (foo) (make-list 1 (fruit 7)))
> (define (bar) (map (compose add1 fruit-num) (foo)))
>
> (submit-job! (thunk (bar)))
>
> I think that the above is roughly equivalent to doing this:
>
> (thread (thunk (bar) (sleep )))
>
> If I'm understanding things correctly, the structs that were created
> in (foo) will be up for garbage collection when (bar) exits, even
> though the worker thread continues to run.  Is that right?
>
> --
> 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] Racket PPA updated for v6.11

2017-12-21 Thread 'Reuben Thomas' via users-redirect
On 4 November 2017 at 17:43, Asumu Takikawa  wrote:

> Hi everyone,
>
> The Ubuntu PPA has been updated for v6.11. The PPA is available here:
>
>   https://launchpad.net/~plt/+archive/ubuntu/racket
>
> It's currently available for zesty and artful. Builds for xenial and trusty
> should go up later hopefully.


​I still can't see anything for the LTS distros…is there a problem?

-- 
https://rrt.sc3d.org

-- 
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] Formlets: No binding for 'select-input' without selection and values bound to binding:form

2017-12-21 Thread Jay McCarthy
Hi,

I would write this code like this

```
#lang web-server/insta
(require web-server/http/bindings
 web-server/formlets
 web-server/formlets/lib
 web-server/formlets/input)

(struct stop (id name))

(define stops
  (list (stop 1 "Foo")
(stop 2 "Bar")
(stop 3 "Baz")))

(define (start request)
  (render-info-page request))

(define form-formlet
  (formlet
   (#%# (div ,{(multiselect-input
stops
#:multiple? #f
#:attributes '((size "40"))
#:display (lambda (stop) (stop-name stop)))
   . => . stop})
(div ,{(cross (pure (λ (x) (and x #t)))
  (checkbox "" #t))
   . => . use-name-filter?}
 "Name filter "
 ,{(to-string (default #"" (text-input))) . => . name-filter}))
   (values stop use-name-filter? name-filter)))

(define (render-info-page request)
  (printf "request bindings: ~v~n"
  (force (request-bindings/raw-promise request)))
  (define-values (stops use-name-filter? name-filter)
(formlet-process form-formlet request))
  (define stop
(if (pair? stops) (car stops) #f))
  (printf "stop: ~v, use-name-filter?: ~v, name-filter: ~v~n"
  stop use-name-filter? name-filter)
  (define (response-generator embed/url)
(response/xexpr
 `(html
   (head (title "Stop Info"))
   (body (h1 "List of Stops")
 (h2 ,(if stop
(stop-name stop)
"no stop selected"))
 (form ([action ,(embed/url render-info-page)])
   ,@(formlet-display form-formlet)
   (p (input ([type "submit"]
 
  (send/suspend/dispatch response-generator))
```

I will change `select-input` to not error on empty input and instead
return #f, that seems like what is expected.

Jay


On Thu, Dec 21, 2017 at 9:32 AM, Christian <7enderh...@gmail.com> wrote:
> * I have boiled down my problem to the minimal example at the end of the
> post
>
> * Basically, I'm running a formlet form in 'cycles' on itself to filter some
> list data
>
> * on the initial invocation, the bindings in the request are empty, as
> expected:
> request bindings: ()
> stop: #f, use-name-filter?: #f, name-filter: #f
>
> * submitting the form without selecting a list item results in the binding
> for the list to be missing (hence a contract violation on parsing by
> formlet-process, which results in default values):
> request bindings: (#(struct:binding:form input_1 ) #(struct:binding:form
> input_2 ))
> stop: #f, use-name-filter?: #f, name-filter: #f
>
> * even when selecting a list item, the other values are not bound to their
> 'control values' (boolean and string), but to the binding:form structs:
> request bindings: (#(struct:binding:form input_0 0) #(struct:binding:form
> input_1 ) #(struct:binding:form input_2 abc))
> stop: #, use-name-filter?: #(struct:binding:form input_1 ),
> name-filter: #(struct:binding:form input_2 abc)
>
> * (the problem is the same with a different handler for the submit button,
> without the form returning to itself)
>
> * Any suggestions on what I most probably misunderstand would be welcome.
>
> Thanks for your consideration,
> Christian
>
> Example:
>
> #lang web-server/insta
>
> (require web-server/http/bindings)
> (require web-server/formlets)
> (require web-server/formlets/input)
>
> (struct stop (id name))
>
> (define stops (list (stop 1 "Foo")
> (stop 2 "Bar")
> (stop 3 "Baz")))
>
> (define (start request)
>   (render-info-page request))
>
> (define form-formlet
>   (formlet
>(#%# (div ,{(select-input stops
>  #:attributes '((size "40"))
>  #:display (lambda (stop)
>  (stop-name stop))) . => . stop})
> (div ,{(checkbox "" #t) . => . use-name-filter?}
>  "Name filter "
>  ,{(text-input) . => . name-filter}))
>(values stop use-name-filter? name-filter)))
>
> (define (render-info-page request)
>   (printf "request bindings: ~a~n" (force (request-bindings/raw-promise
> request)))
>   (define-values (stop use-name-filter? name-filter)
> (with-handlers ([(lambda (e) #t) (lambda (e) (values #f #f #f))])
>   (formlet-process form-formlet request)))
>   (printf "stop: ~a, use-name-filter?: ~a, name-filter: ~a~n" stop
> use-name-filter? name-filter)
>   (define (response-generator embed/url)
> (response/xexpr
>  `(html
>(head (title "Stop Info"))
>(body (h1 "List of Stops")
>  (h2 ,(if stop
>   (stop-name stop)
>   "no stop selected"))
>  (form ([action ,(embed/url render-info-page)])
>,@(formlet-display form-formlet)
>(p (input ([type "submit"]
>  
>   (send/suspend/dispatch response-generator))
>
> --
> You receiv

Re: [racket-users] OS X: DrRacket leaking windows?

2017-12-21 Thread Greg Hendershott
Trying older things -- Racket 6.7 on macOS 10.11.6 -- I see only a hint of this.

I do see the white rectangle (to the right of "MB") get left behind on
the desktop when the window is shrunk. But:

- I have to drag the window _up_ (not to the left).

- I see only _one_ such "dropping" (not a trail of them).

- It disappears when I release the trackpad a.k.a. mouse button (the
desktop is clean once the resize completes).

I definitely don't get the full "ooh is this some DrR advent calendar
easter egg" effect in your PNG.

-- 
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] Formlets: No binding for 'select-input' without selection and values bound to binding:form

2017-12-21 Thread Christian
* I have boiled down my problem to the minimal example at the end of the 
post

* Basically, I'm running a formlet form in 'cycles' on itself to filter 
some list data

* on the initial invocation, the bindings in the request are empty, as 
expected:
request bindings: ()
stop: #f, use-name-filter?: #f, name-filter: #f

* submitting the form without selecting a list item results in the binding 
for the list to be missing (hence a contract violation on parsing by 
formlet-process, which results in default values):
request bindings: (#(struct:binding:form input_1 ) #(struct:binding:form 
input_2 ))
stop: #f, use-name-filter?: #f, name-filter: #f

* even when selecting a list item, the other values are not bound to their 
'control values' (boolean and string), but to the binding:form structs:
request bindings: (#(struct:binding:form input_0 0) #(struct:binding:form 
input_1 ) #(struct:binding:form input_2 abc))
stop: #, use-name-filter?: #(struct:binding:form input_1 ), 
name-filter: #(struct:binding:form input_2 abc)

* (the problem is the same with a different handler for the submit button, 
without the form returning to itself)

* Any suggestions on what I most probably misunderstand would be welcome.

Thanks for your consideration,
Christian

Example:

#lang web-server/insta

(require web-server/http/bindings)
(require web-server/formlets)
(require web-server/formlets/input)

(struct stop (id name))

(define stops (list (stop 1 "Foo")
(stop 2 "Bar")
(stop 3 "Baz")))

(define (start request)
  (render-info-page request))

(define form-formlet
  (formlet
   (#%# (div ,{(select-input stops
 #:attributes '((size "40"))
 #:display (lambda (stop)
 (stop-name stop))) . => . stop})
(div ,{(checkbox "" #t) . => . use-name-filter?}
 "Name filter "
 ,{(text-input) . => . name-filter}))
   (values stop use-name-filter? name-filter)))

(define (render-info-page request)
  (printf "request bindings: ~a~n" (force (request-bindings/raw-promise 
request)))
  (define-values (stop use-name-filter? name-filter)
(with-handlers ([(lambda (e) #t) (lambda (e) (values #f #f #f))])
  (formlet-process form-formlet request)))
  (printf "stop: ~a, use-name-filter?: ~a, name-filter: ~a~n" stop 
use-name-filter? name-filter)
  (define (response-generator embed/url)
(response/xexpr
 `(html
   (head (title "Stop Info"))
   (body (h1 "List of Stops")
 (h2 ,(if stop
  (stop-name stop)
  "no stop selected"))
 (form ([action ,(embed/url render-info-page)])
   ,@(formlet-display form-formlet)
   (p (input ([type "submit"]
 
  (send/suspend/dispatch response-generator))

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