[racket-users] Re: “If you could have a wish granted, what would you like to see next in Racket?”

2020-07-25 Thread Marc Kaufmann
1. More how-to guides/good practice guides and discussions of some Racket 
specific features: continuations (especially for the web); Typed Racket; 
parameters/dynamic scope. Maybe macros, but I don't use them, so can't 
comment on whether I'd miss how-tos for it. I like "the 4 types of 
documentation" (https://documentation.divio.com/), and think Racket does 
great on reference, well on tutorials, and when one knows where to look for 
also often on 'discussion' - but how-to's are too sparse for me, so I end 
up with stupid code for situations that feel fairly standard.

2. I am interested in using Racket for symbolic maths/simulations/etc and 
Rosette seems to provide one big useful block. It would be great to have 
support for numerics in Racket, probably by integrating well with the 
Python/R/Julia universe of packages. There is no point in rebuilding much 
of it from scratch, it seems too huge, but it would be nice to use Racket's 
features in a way that integrates nicely with the numerics. Julia 
apparently has a good macro system, but I would be surprised if it was on 
par with Racket's macro and type system, but who knows?

On Friday, July 24, 2020 at 8:46:55 PM UTC+2, wanp...@gmail.com wrote:
>
> Faster load time and less memory consumption.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/a1c43716-7d94-4cb0-a502-881861258bbfo%40googlegroups.com.


Re: [racket-users] Gradual Typed Racket?

2020-04-17 Thread Marc Kaufmann
Fantastic, thanks for the clarification Ben. I'll start using it to see
what it does, as I have a few functions that occasionally throw errors
through contracts - which I should call 'blame' - yet I can't figure out
much from it.

On Fri, Apr 17, 2020 at 6:09 PM Ben Greenman 
wrote:

> On 4/17/20, Sorawee Porncharoenwase  wrote:
> >>
> >> My understanding is that contract-out only provides protection against
> >> inappropriate calls from clients *outside* the module, whereas
> >> define/contract enforces the contract against everyone, including things
> >> inside the module.  Do I have that right?
> >>
> >
> > I think that's correct. Note though that the implication is that
> > define/contract could produce a much more expensive code, especially for
> > recursive function, since it will need to check against the contract for
> > every iteration.
> >
> >
> >> On a related topic, I don't understand the concept of positive and
> >> negative blame.  Can someone fill me in?
> >>
> >
> > I always forget which is positive and negative, so I won't use the terms
> > here (and too lazy to lookup). But roughly, suppose you attach a function
> > contract (-> number? string?) to a function value, then there are mainly
> > two ways things could go wrong.
> >
> > 1. Client uses the function incorrectly by calling it with non-number.
> > 2. The function itself returns a non-string.
> >
> > A blame would indicate whose party is at fault when a contract is
> > violated--caller or the function itself.
>
> 1 = negative = the client that uses the value
> 2 = positive = the code that made the value
>
> But unless you're using `contract` directly, you don't need to know
> these words to benefit from contracts.
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Racket Users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/racket-users/VA_ufNV6J24/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/CAFUu9R5vabY64_HZRWv1zNoyuEd7K5p8i8jfVN0JB1reufYEPw%40mail.gmail.com
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO7Yo%2BL-T5JnxKB74-OPNce3On0YY%3DujHLR7L%2B1Ch%2Bqz1w%40mail.gmail.com.


Re: [racket-users] Gradual Typed Racket?

2020-04-17 Thread Marc Kaufmann
Hi Ben,

you wrote (snip):

For contracts, though, (provide (contract-out ...)) gives better error 
> messages than define/contract. 
>

In what sense is this the case, and where can I read more about the 
differences, as well as how to improve errors of contracts? Is it related 
to this part of the documentation of `contract-out` 
(https://docs.racket-lang.org/reference/attaching-contracts-to-values.html#%28form._%28%28lib._racket%2Fcontract%2Fbase..rkt%29._contract-out%29%29)
 
- which I admittedly don't understand:

"The implementation of contract-out 

 
uses syntax-property 

 
to attach properties to the code it generates that records the syntax of 
the contracts in the fully expanded program. Specifically, the symbol '
provide/contract-original-contract is bound to vectors of two elements, the 
exported identifier and a syntax object for the expression that produces 
the contract controlling the export."

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/a046c971-8207-4486-bfb3-723a5d7d0446%40googlegroups.com.


Re: [racket-users] Switch off type checking via typed/racket/no-check fails on typed big-bang

2020-04-01 Thread Marc Kaufmann
Thanks Ben.

On Tue, Mar 31, 2020 at 4:41 AM Ben Greenman 
wrote:

> On 3/25/20, Marc Kaufmann  wrote:
> > Hi,
> >
> > I am trying to switch off type checking on a file so that I can prototype
> > faster without the wait for the type checker. However, my code also uses
> > typed/2htdp/universe and typed/2htdp/image, and I get an error on
> > `big-bang`:
> >
> >> Type Checker: Macro big-bang from typed module used in untyped code in:
> > (big-bang ...
> >
> > So, is there a to run the program without running the type checker?
>
> No, you'll need a hack-around to avoid the macro issue.
>
> This macro+use might be safe, but in general TR can't be sure that
> expanding a macro won't break the typed module.
>
> > Relatedly, is there a way of reloading a *typed* racket file in the REPL
> (I
> > can't get it to work with ,reload-require which just chokes somehow).
>
> I don't know about this
>
>
Do you know why it is difficult to get working - as in, whether it's worth
investigating? My workflow with Typed Racket requires far too many restarts
of the REPL. I am just wondering what a saner workflow would look like that
still allows for some quick and (typed) dirty prototyping.

Cheers,
Marc


> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Racket Users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/racket-users/40cX2FYaECs/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/CAFUu9R5WDyc2RaR0kH4P%3DGUKVdsP-M7%3DF4R%3DfQiZsMRY4Gd1cg%40mail.gmail.com
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO4YoYv_gw4xTpbK4w_nd1vmARV-tsSiGe3GFO%3D2VX--Qw%40mail.gmail.com.


Re: [racket-users] How to find source file loaded by/relevant for (require )?

2020-03-29 Thread Marc Kaufmann
Awesome, that looks like the right thing.

Thanks,
Marc

On Fri, Mar 27, 2020 at 10:08 AM Alexis King  wrote:

> I recommend Ryan Culpepper’s whereis package:
> https://docs.racket-lang.org/whereis/index.html It provides both a
> programmatic interface and a raco command.
>
> Alexis
>
> On Mar 27, 2020, at 03:56, Marc Kaufmann 
> wrote:
>
> Hi,
>
> I am trying to set up vim such that it jumps to the correct source file
> when I see a `(require some-module)`. With packages that I have installed
> myself, I have managed to do so (80% solution), since they get installed in
> $HOME/.racket//pkgs. However, I can't quite figure out where all
> the things are. Some are in
> /usr/share/racket/pkgs/-lib/, but
> others like racket/match seem to be in /usr/share/racket/collects/... . Are
> there any other places for the core modules?
>
> Rather than me trying to do something error-prone, is there a Racket
> function that I can call on  that returns the right path on my
> machine? That way I don't write stupid error-prone regexes.
>
> Cheers,
> Marc
>
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO6QwV0N_jqsxHrnS5E0%2BXdcyBvFTy%3DPVLWxyz74T2EJXA%40mail.gmail.com.


[racket-users] How to find source file loaded by/relevant for (require )?

2020-03-27 Thread Marc Kaufmann
Hi,

I am trying to set up vim such that it jumps to the correct source file 
when I see a `(require some-module)`. With packages that I have installed 
myself, I have managed to do so (80% solution), since they get installed in 
$HOME/.racket//pkgs. However, I can't quite figure out where all 
the things are. Some are in 
/usr/share/racket/pkgs/-lib/, but 
others like racket/match seem to be in /usr/share/racket/collects/... . Are 
there any other places for the core modules?

Rather than me trying to do something error-prone, is there a Racket 
function that I can call on  that returns the right path on my 
machine? That way I don't write stupid error-prone regexes.

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/2f82bba5-bf2b-4e1e-8d45-5e49b27a3713%40googlegroups.com.


[racket-users] Switch off type checking via typed/racket/no-check fails on typed big-bang

2020-03-25 Thread Marc Kaufmann
Hi,

I am trying to switch off type checking on a file so that I can prototype 
faster without the wait for the type checker. However, my code also uses 
typed/2htdp/universe and typed/2htdp/image, and I get an error on 
`big-bang`:

> Type Checker: Macro big-bang from typed module used in untyped code in: 
(big-bang ...

So, is there a to run the program without running the type checker? 
Relatedly, is there a way of reloading a *typed* racket file in the REPL (I 
can't get it to work with ,reload-require which just chokes somehow). 

I could hack around this by having the big-bang be in an untyped submodule 
- but doing this only so that I can have a faster developing loop (I will 
already have to switch between #lang typed/racket and #lang 
typed/racket/no-check enough) seems a bit dodgy.

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/650c64c5-370e-4bc6-855c-5e6745ef53e8%40googlegroups.com.


Re: [racket-users] Types for formlets

2020-03-09 Thread Marc Kaufmann
 the
> multiple-return-values case.) Because of the way `cross` is implemented,
> there is a great deal of function composition, which could mean many, many
> crossings of the typed–untyped boundary with contract enforcement costs.
>
> An approach I might consider would be re-implementing the core
> combinators—essentially this module
> <https://github.com/racket/web-server/blob/master/web-server-lib/web-server/formlets/unsafe/lib.rkt>—in
> Typed Racket and writing a typed version of the `formlet` macro that
> expands to them. You could still use the library formlets by importing them
> with `require/typed` at some concrete type.
>
> I'm happy to talk more if you're interested.
>
> -Philip
>
> On Mon, Feb 24, 2020 at 10:28 AM Marc Kaufmann 
> wrote:
>
>> Hi all,
>>
>> I wonder what the best way is to integrate formlets into typed programs.
>> I simply `require/typed` formlet-display  as type (-> Any Any), which is
>> not illuminating, but the display part is rarely the problem.
>>
>> formlet-process is tricky. The earliest point at which I 'know' the type
>> of processing a given formlet is directly when formlet-process is called,
>> so that's the best time to start typing to get most of the types checked.
>> Ideally I would do something like:
>>
>> (define s-formlet
>>   (formlet (div (label "Enter a string:")
>> ,{=> input-string a-string})
>>[a-string : String]))
>>
>> and be done with it. Of course I cannot type it this way. One solution is
>> to define
>>
>> (define (s-formlet-process a-formlet a-request)
>>   (formlet-process a-formlet a-request))
>>
>> provide it, and then require it with the correct type in the next file.
>> That's sort of what I am doing right now, but it requires quite a bit of
>> boiler-plate everywhere. The problem is that I don't see how I would even
>> start typing s-formlet itself, since (I think) it is a macro that changes
>> how formlet-process deals with it, so I don't even know where to start
>> typing any of it. When I expand formlet-process in the macro stepper, it
>> turns into the application of some idY11 with something lifted (none of
>> which I understand), and I don't see how I would make the type of
>> (formlet-process a-formlet ...) dependent on which formlet it is that I am
>> processing.
>>
>> One idea I had is to define my-formlet-process which takes the name as a
>> symbol, rather than as an id, and uses different type signatures depending
>> on the symbol, using case->:
>>
>> #lang racket
>>
>> ;; UNTYPED
>> (define (my-formlet-process name req)
>>   (cond [(eq? name 'integer-formlet) (formlet-process integer-formlet
>> req)]
>> [(eq? name 'string-formlet) (formlet-process string-formlet
>> req)]
>> ...
>>
>> and then require/typed this via (case-> (-> 'integer-formlet Integer) (->
>> 'string-formlet String)). This cuts down on having to define all the
>> intermediaries, and puts all the types for formlets in one place. It still
>> feels more tedious than it has to be, but it is probably not trivial to
>> make this much easier.
>>
>> Any thoughts on if the above is an OK if not best practice, or ideas for
>> improvements? I guess using types with some rather sophisticated macros may
>> in general be a little tricky - any pointers to other places on how to do
>> this and how to figure out how to type it are appreciated.
>>
>> Cheers,
>> Marc
>>
>> --
>> 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.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/racket-users/6241af3c-4b2d-43a5-a76a-2a14b02bc153%40googlegroups.com
>> <https://groups.google.com/d/msgid/racket-users/6241af3c-4b2d-43a5-a76a-2a14b02bc153%40googlegroups.com?utm_medium=email_source=footer>
>> .
>>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO7tNK3AmJ2n_4C8aBmU%3D%2B2HznvdQ2d_9bmW2%2BhMYaTYPQ%40mail.gmail.com.


[racket-users] Types for formlets

2020-02-24 Thread Marc Kaufmann
Hi all,

I wonder what the best way is to integrate formlets into typed programs. I 
simply `require/typed` formlet-display  as type (-> Any Any), which is not 
illuminating, but the display part is rarely the problem.

formlet-process is tricky. The earliest point at which I 'know' the type of 
processing a given formlet is directly when formlet-process is called, so 
that's the best time to start typing to get most of the types checked. 
Ideally I would do something like:

(define s-formlet 
  (formlet (div (label "Enter a string:")
,{=> input-string a-string})
   [a-string : String]))

and be done with it. Of course I cannot type it this way. One solution is 
to define

(define (s-formlet-process a-formlet a-request)
  (formlet-process a-formlet a-request))

provide it, and then require it with the correct type in the next file. 
That's sort of what I am doing right now, but it requires quite a bit of 
boiler-plate everywhere. The problem is that I don't see how I would even 
start typing s-formlet itself, since (I think) it is a macro that changes 
how formlet-process deals with it, so I don't even know where to start 
typing any of it. When I expand formlet-process in the macro stepper, it 
turns into the application of some idY11 with something lifted (none of 
which I understand), and I don't see how I would make the type of 
(formlet-process a-formlet ...) dependent on which formlet it is that I am 
processing. 

One idea I had is to define my-formlet-process which takes the name as a 
symbol, rather than as an id, and uses different type signatures depending 
on the symbol, using case->:

#lang racket

;; UNTYPED
(define (my-formlet-process name req)
  (cond [(eq? name 'integer-formlet) (formlet-process integer-formlet req)]
[(eq? name 'string-formlet) (formlet-process string-formlet 
req)]
...

and then require/typed this via (case-> (-> 'integer-formlet Integer) (-> 
'string-formlet String)). This cuts down on having to define all the 
intermediaries, and puts all the types for formlets in one place. It still 
feels more tedious than it has to be, but it is probably not trivial to 
make this much easier.

Any thoughts on if the above is an OK if not best practice, or ideas for 
improvements? I guess using types with some rather sophisticated macros may 
in general be a little tricky - any pointers to other places on how to do 
this and how to figure out how to type it are appreciated.

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/6241af3c-4b2d-43a5-a76a-2a14b02bc153%40googlegroups.com.


Re: [racket-users] TR dependent types cannot check equality of symbols

2020-02-24 Thread Marc Kaufmann
Very nice, adding 

(: get-user-var (case-> ...))

indeed does the trick. So I can use `case->` to do overloading (if that's 
what it is called), by defining different functions for different type 
signatures, and then put them together into a single function via a cond. 
E.g.:

(: int-add (-> Integer Integer Integer))
(define (int-add x y)
  (+ x y))

(: string-add (-> String String String))
(define (string-add x y)
  (string-append x y))

(: int-string-add (case-> 
(-> Integer Integer Integer)
(-> String String String)))
(define (int-string-add x y)
  (cond [(integer? x) (int-add x y)]
[(string? x) (string-add x y)]
[else
  (error "Not a string or int" x)]))

I am wondering if there is a way to avoid the final definition of 
`int-string-add`, by simply defining the same function twice (or more) with 
different type signatures, and then when I call the function, which code 
gets called depends on the type signature? I would be surprised if this 
existed in Typed Racket right now, but it would be neat and good to know if 
there is a more idiomatic/built-in way than what I do above, ie just write:

(: special-add (-> Integer Integer Integer))
(define-special (special-add x y)
  (+ x y))

(: special-add (-> String String String))
(define-special (special-add x y)
  (string-append x y))

I guess it would be pretty hard, since the type signature has to be coupled 
more tightly to a specific function than TR requires right now, i.e. I'd 
have to write (define-special (special-add [x : String] [y : String]) to 
make the link explicit. Anyway, if it's not possible right now, totally 
fine.
   
Regarding refinement types for symbols, I have no idea how useful it would 
be, as the only example I came up with was the above one, which I think is 
better dealt with in a different way.

Cheers,
Marc

On Sunday, February 23, 2020 at 6:33:33 PM UTC+1, Ben Greenman wrote:
>
> Try this case-> type instead: 
>
>   (case-> 
> (-> Integer 'name Symbol) 
> (-> Integer 'age Integer) 
> (-> Integer Symbol (U Symbol Integer))) 
>
>
> I don't know what it would take to add refinements for symbols, but 
> that might be useful. Andrew Kent's dissertation may have some 
> pointers: 
>
> https://pnwamk.github.io/docs/dissertation.pdf 
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/98151240-f930-4dee-a8de-45f8ce6797ac%40googlegroups.com.


[racket-users] TR dependent types cannot check equality of symbols

2020-02-22 Thread Marc Kaufmann
Hi, 

I worked my way through the blog posts on refinement types 
(https://blog.racket-lang.org/2017/11/adding-refinement-types.html) and 
through the docs 
(https://docs.racket-lang.org/ts-reference/Experimental_Features.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fbase-types-extra..rkt%29._.Refine%29%29).
 
The problem I wanted to solve is as follows: I have some code that gets 
values from a hash that can be Integers or Symbols, but I sometimes need to 
know that the returned value is exactly an integer in order to use it. 
Currently my code uses lots of `(if (number? x) ...)` to deal with this, 
but I was wondering if I could use refinement types to do the same, since I 
know which columns are of which types.

It turns out that I can solve the problem by rewriting my code to use 
hashes that return a struct `person`, and the fields of the struct are easy 
to type check via `(person-age ...)` and `(person-name ...)` -- but I am 
still wondering if this kind of dependent typing is possible with typed 
racket right now or not.

Below is the code, which does *not* type check, it says: "terms in linear 
constraints must be integers, got Symbol for var". I thought that from the 
docs one could also use `id`s in the proposition constraints, but I guess 
by id it means the id of some argument, not the id of a variable? Is there 
a way to make this code work such that my function `get-user-var` always 
returns *either* type Integer *or* type Symbol, but not both - and hence 
the code would type check? The last line won't type check if I get rid of 
the refinement, since then the type is clearly (U Integer Symbol).


#lang typed/racket

(struct person ([name : Symbol] [age : Integer]) #:transparent)

(define bob (person 'bob 15))
(define sally (person 'sally 30))

(: people (HashTable Integer person))
(define people (hash 1 bob 
 2 sally))

(: get-user-var (-> ([uid : Integer] 
[var : Symbol])
(Refine [res : (U Symbol Integer)]
(if  (= var 'age)
  (: res Integer)
  (: res Symbol)
(define (get-user-var uid var)
  (cond [(eq? var 'name) (person-name (hash-ref people uid))]
[(eq? var 'age) (person-age (hash-ref people uid))]
[else
  (error "No such variable: " var)]))

(get-user-var 1 'age)
(get-user-var 1 'name)
(add1 (get-user-var 1 'age))

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/98636cef-0f0c-42bb-bb87-af2824355175%40googlegroups.com.


Re: [racket-users] How do I just run the type checker?

2020-02-21 Thread Marc Kaufmann
Fantastic, that's what I was looking for, thanks.

Marc

On Friday, February 21, 2020 at 6:27:23 PM UTC+1, Sam Tobin-Hochstadt wrote:
>
> If you compile the file with `raco make server.rkt` then it will run 
> the type checker as part of compilation. Furthermore, it will run 
> faster the next time since it won't have to re-compile. 
>
> Sam 
>
> On Fri, Feb 21, 2020 at 12:13 PM Marc Kaufmann 
> > wrote: 
> > 
> > Hi, 
> > 
> > the way I currently check my web server is by simply running `racket 
> server.rkt` on the command line. However, this also launches the server, 
> which I usually do want to, but not always. So is there a way to run just 
> the type checker -- plus all the compile-time stuff that needs to happen 
> for this -- without anything else? The best I have managed is to put the 
> most time-consuming commands that I run into `(module+ main ...)`, but that 
> still does more than than just run the type checker. 
> > 
> > Secondly, is it possible to somehow speed up subsequent type checks by 
> caching something before? 
> > 
> > Cheers, 
> > Marc 
> > 
> > -- 
> > 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...@googlegroups.com . 
> > To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/b8922e9a-524f-4c2d-b716-c857914e7107%40googlegroups.com.
>  
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/92d2cf1b-da1b-4d7f-89ce-8429d07ee9e9%40googlegroups.com.


[racket-users] Re: xrepl ,require-reloadable and ,require

2020-02-21 Thread Marc Kaufmann
Hi,

I'm hitting the same issue again, except that now that I use Typed Racket, 
and after I do the 

> ,rr "code.rkt"
> ,r "code.rkt"

dance, if I `provide` a new function in code.rkt, then it complains that it 
is missing type for the identifier, and says that I should consider using 
`require/typed` to import it. But code.rkt is #lang typed/racket, and I 
don't want to specify every type again! 

So 

1. how can I get Typed Racket to reload a file (I started it with `racket 
-I typed/racket`)
2. is there a way to avoid the Step 1: > ,rr "code.rkt" Step 2: > ,r 
"code.rkt" dance even for standard Racket?

Or what workflow do people use to reload files quickly (that does not 
depend on Emacs/Racket-mode)?

Cheers,
Marc
On Tuesday, October 8, 2019 at 1:32:20 PM UTC+2, Marc Kaufmann wrote:
>
> Hi,
>
> according to the docs (
> https://docs.racket-lang.org/xrepl/index.html#%28xrepl._require-reloadable%29)
>  
> I would have assumed that when I do 
>
> > ,require-reloadable "code.rkt"
>
> that I can use whatever "code.rkt" provides, the same way as when I do
>
> > ,require "code.rkt"
>
> However, when I do just the ,require-reloadable I have to follow it up 
> with a simple ,require for the provides to be available. Example: if code 
> has (provide my-function), then I have (where ,rr is the short-form for 
> ,require-reloadable and ,r for ,require):
>
> > ,rr "code.rkt"
> > (my-function args)
> ; my-function: undefined;
> ...
> > ,r "code.rkt"
> > (my-function args)
> ; Works fine, and seems like I can reload it afterwards
>
> Is this how it should be - and if so, why? Might be worth pointing out in 
> the docs if this behavior is expected, as I kept closing and restarting the 
> repl to reload my changes since I couldn't get ,require-reloadable to work.
>
> Cheers,
> Marc
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/13ef69a3-cf22-40b5-8b74-5a3c30b815d2%40googlegroups.com.


[racket-users] How do I just run the type checker?

2020-02-21 Thread Marc Kaufmann
Hi,

the way I currently check my web server is by simply running `racket 
server.rkt` on the command line. However, this also launches the server, 
which I usually do want to, but not always. So is there a way to run just 
the type checker -- plus all the compile-time stuff that needs to happen 
for this -- without anything else? The best I have managed is to put the 
most time-consuming commands that I run into `(module+ main ...)`, but that 
still does more than than just run the type checker. 

Secondly, is it possible to somehow speed up subsequent type checks by 
caching something before?

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/b8922e9a-524f-4c2d-b716-c857914e7107%40googlegroups.com.


Re: [racket-users] Change error message of web server continuations from "Sorry, this page has expired. Please go back."

2019-12-23 Thread Marc Kaufmann
Yeah, I realized that after George's message.

I also now searched the Github for the message and found this:

```
#:manager
[manager
(make-threshold-LRU-manager
(lambda (request)
(response/xexpr
`(html (head (title "Page Has Expired."))
(body (p "Sorry, this page has expired. Please go back.")
(* 128 1024 1024))]
```

It seems this calls the serve/servlet not with the argument #f, but with
the error message I find. Presumably this serve/servlet gets called by
default, since I changed nothing yet get that error message? At least I
have finally figured out what I need configuring.

Link to search:
https://github.com/racket/racket/search?q=serve%2Fservlet_q=serve%2Fservlet

Thanks everybody, that was quite helpful.

Cheers,
Marc

On Mon, Dec 23, 2019 at 3:28 PM Sam Tobin-Hochstadt 
wrote:

> The default is documented here:
>
> https://docs.racket-lang.org/web-server/run.html?q=serve%2Fservlet#%28def._%28%28lib._web-server%2Fservlet-env..rkt%29._serve%2Fservlet%29%29
> as the default value for the `#:manager` argument.
>
> The default handler is `#f`, which produces the behavior you see. You
> can provide a different `request? -> response?` function instead.
>
> On Mon, Dec 23, 2019 at 6:55 AM Marc Kaufmann 
> wrote:
> >
> > In order to do everything as I do now - where I have been blissfully
> unaware of the managers - I do
> >
> > ```
> > (define the-manager-with-threshold (make-threshold-LRU-manager
> what-is-this-instance-expiration-handler? (* 512 1024 1024)))
> >
> > (serve/servlet start ...  ... #:manager
> the-manager-with-threshold)
> > ```
> > and this would set the threshold to roughly 512 MB, rather than 130MB?
> By the way, where does it say that the default is 130MB?
> >
> > Can I set the instance-expiration-manager to #f and that is the place
> where it generates the 'Sorry, this page link has expired' error? So I
> could provide a more meaningful error message there? Or better not, since
> it does more work behind the scenes?
> >
> > Cheers,
> > Marc
> >
> > On Sun, Dec 22, 2019 at 9:58 PM Philip McGrath 
> wrote:
> >>
> >> You can probably use `make-threshold-LRU-manager` with a much higher
> memory threshold than the default from `serve/servlet`, which is about 130
> MB. The manager will start expiring continuations at that threshold even if
> you have lots of RAM available.
> >>
> >> -Philip
> >>
> >> On Sat, Dec 21, 2019 at 3:31 PM George Neuner 
> wrote:
> >>>
> >>>
> >>> On 12/21/2019 4:38 AM, Marc Kaufmann wrote:
> >>>
> >>>
> >>>> Did you perhaps change the continuation manager - or its setup?
> >>>>
> https://docs.racket-lang.org/web-server/servlet.html?q=ffi#%28part._managers%29
> >>>>
> >>>
> >>> No, not really. I simply import send/suspend/dispatch etc and use them
> without doing anything in particular. I am requiring them within
> typed/racket if that matters via require/typed. So I have no idea where to
> configure the continuation manager - I don't even know where the current
> one is.
> >>>
> >>>
> >>> If you started from serve/servlet - and didn't specify differently -
> then you are using the default LRU continuation manager.   If the load
> spikes, it will drop saved continuations to get memory use back under
> control.
> >>>
> >>>
> https://docs.racket-lang.org/web-server/run.html?q=serve%2Fservlet#%28def._%28%28lib._web-server%2Fservlet-env..rkt%29._serve%2Fservlet%29%29
> >>>
> https://docs.racket-lang.org/web-server/servlet.html#%28def._%28%28lib._web-server%2Fmanagers%2Flru..rkt%29._make-threshold-.L.R.U-manager%29%29
> >>>
> >>>
> >>> You can specify to use a different manager (including a custom one) in
> the call to serve/servlet.
> >>>
> >>>
> >>> George
> >>>
> >>> --
> >>> 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.
> >>> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/f974666a-3e1a-3cd8-d371-09e9a283a157%40comcast.net
> .
> >
> > --
> > 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.
> > To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/CAD7_NO7G%3DY_Q48_pfTYknpPCrfULRL3-yoCzqMVH0at372P0Uw%40mail.gmail.com
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO4hU2%3D_kUCQVuDXccS-xGLpfjkyOOmuBHcWfPsS3Drrbw%40mail.gmail.com.


Re: [racket-users] Change error message of web server continuations from "Sorry, this page has expired. Please go back."

2019-12-23 Thread Marc Kaufmann
Of course. I read this line of the docs:

#:manager manager

but not this one:

manager   :   manager?
<https://docs.racket-lang.org/web-server/servlet.html?q=serve%2Fservlet#%28def._%28%28lib._web-server%2Fmanagers%2Fmanager..rkt%29._manager~3f%29%29>
  =   (make-threshold-LRU-manager
<https://docs.racket-lang.org/web-server/servlet.html?q=serve%2Fservlet#%28def._%28%28lib._web-server%2Fmanagers%2Flru..rkt%29._make-threshold-.L.R.U-manager%29%29>
 #f (*
<https://docs.racket-lang.org/reference/generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2A%29%29>
 128 1024 1024))


which comes a page later given how many arguments serve/servlet has. I
still haven't internalized how to read the documentation properly. Seems to
suggest the default handler is #f, so that should be OK to do.

It also means that it didn't help much that I increased the current RAM on
my server. Good to know.

On Mon, Dec 23, 2019 at 1:24 PM George Neuner  wrote:

>
> On 12/23/2019 6:54 AM, Marc Kaufmann wrote:
> > By the way, where does it say that the default is 130MB?
>
> In the docs for serve/servlet.
>
> > Can I set the instance-expiration-manager to #f and that is the place
> > where it generates the 'Sorry, this page link has expired' error? So I
> > could provide a more meaningful error message there? Or better not,
> > since it does more work behind the scenes?
>
> I don't know if you can set the handler to #f.  But you can replace it.
>
> George
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO4GmcT7NS7H6Cgo%3D686vSNzcpdEAS80eTkq8Rg9DVDbmQ%40mail.gmail.com.


Re: [racket-users] Change error message of web server continuations from "Sorry, this page has expired. Please go back."

2019-12-23 Thread Marc Kaufmann
In order to do everything as I do now - where I have been blissfully
unaware of the managers - I do

```
(define the-manager-with-threshold (make-threshold-LRU-manager
what-is-this-instance-expiration-handler? (* 512 1024 1024)))

(serve/servlet start ...  ... #:manager
the-manager-with-threshold)
```
and this would set the threshold to roughly 512 MB, rather than 130MB? By
the way, where does it say that the default is 130MB?

Can I set the instance-expiration-manager to #f and that is the place where
it generates the 'Sorry, this page link has expired' error? So I could
provide a more meaningful error message there? Or better not, since it does
more work behind the scenes?

Cheers,
Marc

On Sun, Dec 22, 2019 at 9:58 PM Philip McGrath 
wrote:

> You can probably use `make-threshold-LRU-manager
> <https://docs.racket-lang.org/web-server/servlet.html?q=file-box#%28def._%28%28lib._web-server%2Fmanagers%2Flru..rkt%29._make-threshold-.L.R.U-manager%29%29>`
> with a much higher memory threshold than the default from `serve/servlet`,
> which is about 130 MB. The manager will start expiring continuations at
> that threshold even if you have lots of RAM available.
>
> -Philip
>
> On Sat, Dec 21, 2019 at 3:31 PM George Neuner 
> wrote:
>
>>
>> On 12/21/2019 4:38 AM, Marc Kaufmann wrote:
>>
>>
>> Did you perhaps change the continuation manager - or its setup?
>>>
>>> https://docs.racket-lang.org/web-server/servlet.html?q=ffi#%28part._managers%29
>>>
>>>
>> No, not really. I simply import send/suspend/dispatch etc and use them
>> without doing anything in particular. I am requiring them within
>> typed/racket if that matters via require/typed. So I have no idea where to
>> configure the continuation manager - I don't even know where the current
>> one is.
>>
>>
>> If you started from serve/servlet - and didn't specify differently - then
>> you are using the default LRU continuation manager.   If the load spikes,
>> it will drop saved continuations to get memory use back under control.
>>
>>-
>>
>> https://docs.racket-lang.org/web-server/run.html?q=serve%2Fservlet#%28def._%28%28lib._web-server%2Fservlet-env..rkt%29._serve%2Fservlet%29%29
>>-
>>
>> https://docs.racket-lang.org/web-server/servlet.html#%28def._%28%28lib._web-server%2Fmanagers%2Flru..rkt%29._make-threshold-.L.R.U-manager%29%29
>>
>>
>> You can specify to use a different manager (including a custom one) in
>> the call to serve/servlet.
>>
>>
>> George
>>
>> --
>> 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.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/racket-users/f974666a-3e1a-3cd8-d371-09e9a283a157%40comcast.net
>> <https://groups.google.com/d/msgid/racket-users/f974666a-3e1a-3cd8-d371-09e9a283a157%40comcast.net?utm_medium=email_source=footer>
>> .
>>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO7G%3DY_Q48_pfTYknpPCrfULRL3-yoCzqMVH0at372P0Uw%40mail.gmail.com.


Re: [racket-users] Can I somehow connect to and update values in a specific hash table used by a running web server?

2019-12-22 Thread Marc Kaufmann
Thanks George and Matt, those look great.

I think I'll try to implement your version later George, as the
syntax-parse makes me sure I'll screw up. However it looks like a really
nice way to contain what can be changed/updated, while adding things
flexibly to it. And it should be possible to combine with Matt's idea of
running it only on a second servlet that is on a separate port (to avoid
the 'you can only do this on /update-values').

Cheers,
Marc


On Sun, Dec 22, 2019 at 3:25 AM Matt Jadud  wrote:

> My off-list thought (which was largely because I wasn't sure it would even
> work) was to run a second web server on another port that was bound to
> localhost. Then, SSH onto the localhost when needed, and squirt values into
> the locally bound webserver as needed. Depending on the server config
> (e.g., you're the only one on it) would make this reasonably secure. (If
> someone got onto your host, you probably aren't worrying about the hash
> table of parameters...)
>
> Cheers,
> Matt
>
> #lang racket
> (require web-server/dispatch
>  web-server/servlet
>  web-server/servlet-env)
>
> (define posts (make-hash))
>
> (define (list-posts req)
>   (response/xexpr
>`(html
>  (body
>   ,@(for/list ([(k v) posts])
>   `(p ,(format "[~a] ~a" k v)))
>
>
> (define (review-post req key)
>   (hash-ref posts key))
>
> (define-values (blog-dispatch blog-url)
> (dispatch-rules
>  [("") list-posts]
>  [("posts" (string-arg)) review-post]
>  [else list-posts]))
>
> (define (add-key req k v)
>   (hash-set! posts k v)
>   (response/xexpr `(html (body ,(format "Added '~a' -> '~a'" k v
>   )
>
> (define (get-key req k)
>   (response/xexpr `(html (body ,(format "Found '~a'"   (hash-ref posts k
> false)
>   )
>
> (define-values (tweaker url)
>   (dispatch-rules
>[("set" (string-arg) (string-arg)) add-key]
>[("get" (string-arg)) get-key]))
>
> (thread (λ ()
>   (serve/servlet blog-dispatch
>  #:servlet-path ""
>  #:servlet-regexp #rx""
>  #:port 8080
>  #:listen-ip "0.0.0.0")))
> (thread (λ ()
>   (serve/servlet tweaker
>  #:servlet-path ""
>  #:servlet-regexp #rx""
>  #:port 9090
>  #:listen-ip "127.0.0.1")))
>
>
> On Sat, Dec 21, 2019 at 4:13 PM George Neuner 
> wrote:
>
>>
>> On 12/21/2019 4:44 AM, Marc Kaufmann wrote:
>>
>> one useful feature of the Django web framework is that it is easy to
>> access the database and change it on the fly. I am not using a DB, but a
>> hash inside of Racket for various reasons. I understand that it would be
>> easy to connect to a database in any language, and getting the hash is a
>> different beast - but I am wondering if there is an easy way such that I
>> could tell the racket web server via a command line or REPL interaction
>> "(update-user uid key-name new-value)" or some such.
>>
>> Is that easily possible? (And very secondarily: Is this a stupid idea?
>> But even if it is, it's what I am under time pressure to get working, as a
>> proper solution ain't gonna happen in time.)
>>
>>
>> Running a REPL inside your program is fairly easy but not terribly safe.
>> E.g., you can dedicate a thread to reading a network port and executing
>> whatever code fragments you send.  But you need to take precautions,
>> limiting what it is allowed to do, and who can access it, so unauthorized
>> users can't screw up your program.
>>
>> In my apps I make hot tweak settings available through a secured web
>> interface.  The "variables" are functions exported from my configuration
>> module (similar to the way parameters work).
>>
>> (define-syntax getter/setter!
>>   (syntax-rules ()
>> ((getter/setter!)
>>  ; -- start template
>>
>>  (let [(var null)]
>>(lambda x
>>  (cond
>>([null? x] var)
>>([pair? x] (set! var (car x)))
>>(else (error))
>>))
>>)
>>
>>  ; -- end template
>>  )))
>>
>> (define some-config-var (getter/setter!))
>>
>>
>> Then  *(some-config-var )*  changes the value, and
>> *(some-config-var)*  gets the current value.
>>
>> It's simplistic, but it works well.  I haven't r

[racket-users] Can I somehow connect to and update values in a specific hash table used by a running web server?

2019-12-21 Thread Marc Kaufmann
Hi all,

one useful feature of the Django web framework is that it is easy to access 
the database and change it on the fly. I am not using a DB, but a hash 
inside of Racket for various reasons. I understand that it would be easy to 
connect to a database in any language, and getting the hash is a different 
beast - but I am wondering if there is an easy way such that I could tell 
the racket web server via a command line or REPL interaction "(update-user 
uid key-name new-value)" or some such.

Is that easily possible? (And very secondarily: Is this a stupid idea? But 
even if it is, it's what I am under time pressure to get working, as a 
proper solution ain't gonna happen in time.)

I guess I could add some function to the server that gets called via a 
specific url that writes to some file, which I then edit manually (or via 
the REPL) and which gets read in again. A bit cumbersome, but I've done 
worse.

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/9f011618-8351-43f1-9eda-49f3ef966b4b%40googlegroups.com.


Re: [racket-users] Change error message of web server continuations from "Sorry, this page has expired. Please go back."

2019-12-21 Thread Marc Kaufmann


> Did you perhaps change the continuation manager - or its setup? 
>
> https://docs.racket-lang.org/web-server/servlet.html?q=ffi#%28part._managers%29
>  
>
>
No, not really. I simply import send/suspend/dispatch etc and use them 
without doing anything in particular. I am requiring them within 
typed/racket if that matters via require/typed. So I have no idea where to 
configure the continuation manager - I don't even know where the current 
one is.

Cheers,
Marc

As to where to put your message: you can install a custom "expiration" 
> handler in the continuation manager.  Unfortunately I haven't done this 
> in a very long time, so I can't guide you through it.  Perhaps someone 
> (Jay?) knows exactly what to do. 
>
> George 
>
>
 

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/ebf3d85d-c1e6-4de0-9b97-b1150eb1843f%40googlegroups.com.


[racket-users] Change error message of web server continuations from "Sorry, this page has expired. Please go back."

2019-12-20 Thread Marc Kaufmann
Hi all,

reading a past thread started by me, I realize that I should have learned 
how to implement Philip's advice on using stateless continuations, but well 
I didn't. So I still use vanilla `send/suspend/dispatch` and hence my users 
hit the "Sorry, this page has expired. Please go back." The quick fix is to 
tell them that they should go to page xyz.com. But I don't know how I can 
easily change this error message to add a link. Anyone?

I'm about to leave for travel or else I would have done some digging around.

Cheers,
Marc

PS: For some reason I keep hitting these errors faster than in the past - 
as in, within a few minutes. Any idea why that might be and how to increase 
the time? I can crank up the RAM of the machine too, anything that cuts 
down on developer time really. I'll be back in the new year to actually fix 
this, but not now.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/31aed0b4-c9df-4ccb-9e10-92df3dd3952c%40googlegroups.com.


Re: [racket-users] Typed Racket: 'Unable to protect opaque value passed as `Any`' with interesting behavior

2019-12-16 Thread Marc Kaufmann
Follow up on this: Is there a way to resolve this type of issue when I 
import typed code in a non-typed place? I did hit the same issue today, 
roughly as follows: the typed code uses an opaque type for `Time` (using 
predicate `time?`), and the function `my-function` has return type `Any`, 
and can return various types, including opaque type `Time`. 

However when the non-typed code tries to display the time objects in a 
response, it blows up with the "any-wrap/c: Unable to protect opaque value 
passed as `Any`" error. I now think that I understand why this happens (the 
untyped code can't look at the 'interesting' value of the time object, or 
the contract can't in any case). Is there some way of getting this to work, 
given that I have opaque types? 

I got it working after typing the whole previously untyped file, but I 
might hit this issue again with another file that I really don't know how 
to type (it has formlets in it). Do I have to change the return value of 
the function? Write a wrapper function that does the type checking inside 
of the typed module? Are there any best practices?

Cheers,
Marc

On Wednesday, December 11, 2019 at 5:05:08 PM UTC+1, Marc Kaufmann wrote:
>
> Thanks. Yes, I realized that the two gave the same answer, but for 
> debugging I tried to see if it was different. I think I now see where I am 
> thinking about this in the wrong way. I thought `(U A B)` means 'it is 
> either of type A or of type B', with the implication that it picks the more 
> stringent one when possible. When there are two separate types A and B, 
> this is innocuous enough, I think. What you are saying is that when typed 
> racket sees `(U response Any)`, it transforms it (via some macro applied 
> before doing type checking?) into `Any`. I thought it would leave `(U 
> response Any)` around and always check against both, which is why I 
> switched the order to see if that happened. 
>
> A trivial and obvious answer to something that stumped me for quite a 
> while. Good illustration of 
>
> “It's not what we don't know that hurts. It's what we know that ain't so.”
>
> Cheers,
> Marc
>
> On Wednesday, December 11, 2019 at 4:27:03 PM UTC+1, Sam Tobin-Hochstadt 
> wrote:
>>
>> First, (U Any response) is the same as (U response Any) which is the 
>> same as Any -- Any includes all other types and thus includes 
>> response. 
>>
>> Second, f4 really is breaking the contract -- the contract Any turns 
>> into says: don't try to pass through any "interesting" values, or if 
>> you do, the other side isn't allowed to look at them. You passed a 
>> "response" which is an interesting value (not a number or suchlike) 
>> and the web server actually did something with it. The REPL doesn't 
>> give you this error because in a typed module the REPL is also typed. 
>>
>> The problem is fundamentally that when you using Any in an annotation, 
>> you're explicitly asking Typed Racket to throw away information. 
>> Unfortunately, when you throw away that information for something that 
>> you provide to untyped parts of your program, you've thrown away the 
>> information Typed Racket needed to generate a more useful contract. So 
>> instead, Typed Racket generates the best contract it can, which is as 
>> described above. 
>>
>> Sam 
>>
>> On Wed, Dec 11, 2019 at 8:31 AM Marc Kaufmann  
>> wrote: 
>> > 
>> > Hello, 
>> > 
>> > I have one file called `type-test.rkt` with the following (notice that 
>> I discovered that there is a typed version of the web-server/http module, 
>> which solves another of my issues): 
>> > 
>> > ``` 
>> > #lang typed/racket 
>> > 
>> > (require (only-in typed/web-server/http response/xexpr response)) 
>> > 
>> > (provide f1 f2 f3 f4) 
>> > 
>> > (: f1 (-> response)) 
>> > (define (f1) 
>> >   (define x '(body (h1 "Try it"))) 
>> >   (: resp response) 
>> >   (define resp (response/xexpr x)) 
>> >   resp) 
>> > 
>> > (: f2 (-> (U response Any))) 
>> > (define (f2) 
>> >   (define x '(body (h1 "Try it"))) 
>> >   (: resp response) 
>> >   (define resp (response/xexpr x)) 
>> >   resp) 
>> > 
>> > (: f3 (-> (U response Number))) 
>> > (define (f3) 
>> >   (define x '(body (h1 "Try it"))) 
>> >   (: resp response) 
>> >   (define resp (response/xexpr x)) 
>> >   resp) 
>> > 
>> > (: f4 (-> (U Any response))) 
>> > (define (f4) 
>> >   (define x '(body (h1 "Try it"))) 
>

Re: [racket-users] How to use dates (especially gregor) with Typed Racket?

2019-12-11 Thread Marc Kaufmann


On Saturday, December 7, 2019 at 3:04:25 PM UTC+1, Ben Greenman wrote:
>
> On 12/7/19, Marc Kaufmann > wrote: 
> > Thanks Ben and Jon, that did the trick. 
> > 
> > I realized when following the code that the structure wasn't exported - 
> but 
> > 
> > I didn't know how to work around that. I now also checked the 
> > documentation, and the only thing I found on opaque types is 
> > 
> https://docs.racket-lang.org/ts-reference/special-forms.html?q=opaque#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._require%2Ftyped%29%29.
>  
>
> > 
> > What it says about opaque types is: 
> > 
> > "Opaque types must be required lexically before they are used." 
>
> The docs says a little more --- there are 4 sentences that come right 
> before this one. 
>
> I think those sentences would be better off with: 
> 1. a link to `make-predicate` 
> 2. and English words at the start & end of each sentence 
>
> Let me know if you have other suggestions 
>

So here is the paragraph:

> The fourth case defines a new type t. pred, imported from module m, is a 
predicate for this type. The type is defined as precisely those values to 
which pred produces #t. pred must have type (Any -> Boolean). Opaque types 
must be required lexically before they are used.


When I came to the documentation, I was skimming, in part because I didn't 
know whether this would be helpful or not. I am not a fan of the "The 
first/second/... case..." when there are many cases and I can no longer see 
what the cases were - and in fact I miscounted the rows, so I thought this 
applied to something else for a while. Or rather, I like it, but only if it 
is 


"The fourth case defines a new *opaque* type t. ..."


When I got to the last sentence starting with 'Opaque types...', I had to 
think again to realize this is the fourth case talked about - even though 
no one at any point talked about opaque types, so I was wondering where I'd 
missed them.


Second sentence "This type t is defined via the predicate `pred`, imported 
from module m. More precisely, it is defined as precisely ... . 

>
> > followed by an example that is even now non-trivial for me to parse and 
> > figure out. (I started going down the rabbit hole when the `->` was not 
> > used in the first position of the definition, nor written as `. -> .` 
> Turns 
> > out types can be defined via infix notation, which is nice but 
> unexpected.) 
>
> The docs for -> show the infix notation. 
>

Yeah, I followed that and therefore realized that it was infix notation. 
Just to explain why I said it, even though I do *not* think that this 
particular instance should get changed: The point I was making is that for 
someone like me who doesn't live and breathe Racket, any extra layer of 
abstraction that isn't the same everywhere is extra cognitive load. Imagine 
me replacing every few words by a French word. I guess the fact that Racket 
contracts and Typed Racket don't use exactly the same notation is just a 
(very minor) nuisance. And I realize that it is incredibly hard to write 
helpful and clear documentation, so I'm not saying that I'd do a better job.

I only very recently started to be able to read and understand the Racket 
reference, while before I skipped all the arrow bits (and hence 
higher-order functions) and used the examples to reverse-engineer what form 
the arguments must take. That means that often I can't figure out what I 
need from the reference even when it's there. 


> Is the example still difficult to figure out? We could replace it, but 
> I'm not sure what could be better 
>
>
I think what I'd suggest is to add an example with #:opaque to the Typed 
Racket Guide, part 6 
(https://docs.racket-lang.org/ts-guide/typed-untyped-interaction.html). 

(if want to stop using infix notation here, then the other uses on the 
> same page need to change too) 
>
>
No, I think it's fine. 

> 
> > So there are two questions: 
> > 
> > 1. What does #:opaque do? 
> > 2. How could I have found that out by searching - or essentially the way 
> to 
> > 
> > do it was "Email the list". If the latter, that's fine, the email list 
> is 
> > very helpful and it would be good to add some additional explanation of 
> > opaque types to the documentation of `require-typed`, and possibly even 
> to 
> > the typed racket reference. Probably the part talking about typed-racket 
> > untyped racket interaction. 
> > 
> > Let me try answering my first question: #:opaque defines a new type via 
> a 
> > predicate function -- here `time?` -- that is being imported (can I use 
> it 
> > without require-typed? I guess there would be no po

Re: [racket-users] Typed Racket: 'Unable to protect opaque value passed as `Any`' with interesting behavior

2019-12-11 Thread Marc Kaufmann
Thanks. Yes, I realized that the two gave the same answer, but for 
debugging I tried to see if it was different. I think I now see where I am 
thinking about this in the wrong way. I thought `(U A B)` means 'it is 
either of type A or of type B', with the implication that it picks the more 
stringent one when possible. When there are two separate types A and B, 
this is innocuous enough, I think. What you are saying is that when typed 
racket sees `(U response Any)`, it transforms it (via some macro applied 
before doing type checking?) into `Any`. I thought it would leave `(U 
response Any)` around and always check against both, which is why I 
switched the order to see if that happened. 

A trivial and obvious answer to something that stumped me for quite a 
while. Good illustration of 

“It's not what we don't know that hurts. It's what we know that ain't so.”

Cheers,
Marc

On Wednesday, December 11, 2019 at 4:27:03 PM UTC+1, Sam Tobin-Hochstadt 
wrote:
>
> First, (U Any response) is the same as (U response Any) which is the 
> same as Any -- Any includes all other types and thus includes 
> response. 
>
> Second, f4 really is breaking the contract -- the contract Any turns 
> into says: don't try to pass through any "interesting" values, or if 
> you do, the other side isn't allowed to look at them. You passed a 
> "response" which is an interesting value (not a number or suchlike) 
> and the web server actually did something with it. The REPL doesn't 
> give you this error because in a typed module the REPL is also typed. 
>
> The problem is fundamentally that when you using Any in an annotation, 
> you're explicitly asking Typed Racket to throw away information. 
> Unfortunately, when you throw away that information for something that 
> you provide to untyped parts of your program, you've thrown away the 
> information Typed Racket needed to generate a more useful contract. So 
> instead, Typed Racket generates the best contract it can, which is as 
> described above. 
>
> Sam 
>
> On Wed, Dec 11, 2019 at 8:31 AM Marc Kaufmann  > wrote: 
> > 
> > Hello, 
> > 
> > I have one file called `type-test.rkt` with the following (notice that I 
> discovered that there is a typed version of the web-server/http module, 
> which solves another of my issues): 
> > 
> > ``` 
> > #lang typed/racket 
> > 
> > (require (only-in typed/web-server/http response/xexpr response)) 
> > 
> > (provide f1 f2 f3 f4) 
> > 
> > (: f1 (-> response)) 
> > (define (f1) 
> >   (define x '(body (h1 "Try it"))) 
> >   (: resp response) 
> >   (define resp (response/xexpr x)) 
> >   resp) 
> > 
> > (: f2 (-> (U response Any))) 
> > (define (f2) 
> >   (define x '(body (h1 "Try it"))) 
> >   (: resp response) 
> >   (define resp (response/xexpr x)) 
> >   resp) 
> > 
> > (: f3 (-> (U response Number))) 
> > (define (f3) 
> >   (define x '(body (h1 "Try it"))) 
> >   (: resp response) 
> >   (define resp (response/xexpr x)) 
> >   resp) 
> > 
> > (: f4 (-> (U Any response))) 
> > (define (f4) 
> >   (define x '(body (h1 "Try it"))) 
> >   (: resp response) 
> >   (define resp (response/xexpr x)) 
> >   resp) 
> > ``` 
> > 
> > Then I have another *untyped* file for a servlet: 
> > 
> > ``` 
> > #lang racket 
> > 
> > (require "type-test.rkt" 
> >  web-server/servlet 
> >  web-server/servlet-env) 
> > 
> > (define (start req) 
> >   (f1) 
> >   ; (f2) 
> >   ; (f3) 
> >   ; (f4) 
> >   ) 
> > 
> > (serve/servlet start 
> >#:servlet-regexp #rx"" 
> >#:launch-browser? #false 
> >#:port 8080) 
> > ``` 
> > 
> > Notice that I am telling all the f* functions that `resp` is of type 
> `response`. Yet, when I run the server with `start` using `f1` through `f4` 
> I get the following results: 
> > 
> > (f1): All good 
> > (f2): Error, see below. Unable to protect opaque value passed as `Any` 
> > (f3): All good 
> > (f4): Error, see below. 
> > 
> > The error is: 
> > 
> > ``` 
> > 
> > f4: broke its own contract 
> >   any-wrap/c: Unable to protect opaque value passed as `Any` 
> >   value: # 
> >   in: the range of 
> >   (-> Any) 
> > 
> > ``` 
> > 
> > First, I couldn't figure out how to replicate this in the REPL, and had 
> to use the server to get the result. But I was able to figure out at the 
&g

[racket-users] Using typed racket with web server continuations `(send/suspend/dispatch ...)`

2019-12-11 Thread Marc Kaufmann
Hi,

if possible, I'd like to use web server continuations with 
`(send/suspend/dispatch...)`. However, currently I need to return something 
of type `response?`, but when send/suspend/dispatch (and friends) don't 
return a response - they send it to the client and return `Any` (or other 
types). 

The question is: is this even possible to get working when my servlet 
expects a response back? And if not, is there some clever way to make it 
work anyway - typing things differently? I think that I won't go down the 
road of using different types, since sometimes I want to use a function 
that returns a response directly, rather than via web continuations.

The cod so far: 

```{module that creates the response}
#lang typed/racket

(require typed/web-server/http)
(define-type EmbedURL (-> (-> request Any) String))
(define-type ResponseMaker (-> EmbedURL response))

(require/typed web-server/servlet
   [send/suspend/dispatch (-> ResponseMaker Any)])

(define continuation-servlet
  (λ (req)
 (: response-generator ResponseMaker)
 (define (response-generator embed/url)
   (response/wrap-xexpr
 #:title text
 #:wrap-body? #t
 #:xexpr `(body (h1 ,text)
,(if when-done
   (next-button (λ () (when-done (state-response 
'next 'display-page)))
embed/url)
   '(p "Thanks and goodbye"))
)))
 (send/suspend/dispatch response-generator

```

which gets called elsewhere in a non-typed module via 
`(continuation-servlet req)`, which has the wrong type. I could simply 
claim that the returned type is response (it's thrown away anyway, I 
think), but that seems wrong at the conceptual level. 

Thanks for any pointers as to how to make this work - or why not to try to 
make it work.

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/58a6be81-2d68-4f3f-a621-cc01888db011%40googlegroups.com.


[racket-users] Re: Typed Racket: 'Unable to protect opaque value passed as `Any`' with interesting behavior

2019-12-11 Thread Marc Kaufmann
And I forgot: What is the cryptic error message 'any-wrap/c: Unable to 
protect opaque value passed as `Any`' telling me? That response is opaque 
and ... what?

Cheers,
Marc

On Wednesday, December 11, 2019 at 2:31:37 PM UTC+1, Marc Kaufmann wrote:
>
> Hello,
>
> I have one file called `type-test.rkt` with the following (notice that I 
> discovered that there is a typed version of the web-server/http module, 
> which solves another of my issues):
>
> ```
> #lang typed/racket
>
> (require (only-in typed/web-server/http response/xexpr response))
>
> (provide f1 f2 f3 f4)
>
> (: f1 (-> response))
> (define (f1)
>   (define x '(body (h1 "Try it")))
>   (: resp response)
>   (define resp (response/xexpr x))
>   resp)
>
> (: f2 (-> (U response Any)))
> (define (f2)
>   (define x '(body (h1 "Try it")))
>   (: resp response)
>   (define resp (response/xexpr x))
>   resp)
>
> (: f3 (-> (U response Number)))
> (define (f3)
>   (define x '(body (h1 "Try it")))
>   (: resp response)
>   (define resp (response/xexpr x))
>   resp)
>
> (: f4 (-> (U Any response)))
> (define (f4)
>   (define x '(body (h1 "Try it")))
>   (: resp response)
>   (define resp (response/xexpr x))
>   resp)
> ```
>
> Then I have another *untyped* file for a servlet:
>
> ```
> #lang racket
>
> (require "type-test.rkt"
>  web-server/servlet
>  web-server/servlet-env)
>
> (define (start req)
>   (f1)
>   ; (f2)
>   ; (f3)
>   ; (f4)
>   )
>
> (serve/servlet start
>#:servlet-regexp #rx""
>#:launch-browser? #false
>#:port 8080)
> ```
>
> Notice that I am telling all the f* functions that `resp` is of type 
> `response`. Yet, when I run the server with `start` using `f1` through `f4` 
> I get the following results:
>
> (f1): All good
> (f2): Error, see below. Unable to protect opaque value passed as `Any` 
> (f3): All good 
> (f4): Error, see below.
>
> The error is:
>
> ```
>
> f4: broke its own contract
>   any-wrap/c: Unable to protect opaque value passed as `Any`
>   value: #
>   in: the range of
>   (-> Any)
>
> ```
>
> First, I couldn't figure out how to replicate this in the REPL, and had to 
> use the server to get the result. But I was able to figure out at the REPL 
> that (f2) and (f4) return something of type `Any`, for some unknown reason. 
> Clearly TR is smart enough to figure out that `resp` is not a Number, but a 
> response, but then when I allow it to return both a type `response` and 
> `Any`, it says that it's return value is `Any`. Why? Every function that 
> can take `Any` can take `response`, and every function that expects 
> response is now going to blow up (as now happens). 
>
> At the REPL, I didn't manage to get this behavior, probably because 
> `serve/servlet` has contracts around it's arguments. Thus:
>
> - I pass all the typed racket tests
> - I nonetheless return something of type `Any` (which is really guaranteed 
> to be of type response, and I am already annotating, so this surprises me)
> - When this hits the contract, it complains and tells me that f4 broke its 
> own contract, which seems false, but this may be one of those 'Contract 
> blaming is hard' moments
>
> Long story short: Why do (f2) and (f4) return something of type `Any` 
> rather than `response`? What is the logic for doing this and what use case 
> am I missing where this is a feature (or maybe it's just hard to get right, 
> but this seems vastly easier than other things Typed Racket does).
>
> And yes, I should probably just use typed/web-server/servlet and friends 
> (not sure if everything is covered, but probably) - but I discovered the 
> typed/** modules only while trying to fix this. And the issue will come up 
> with other non-typed modules or when/if I try to created typed versions of 
> some module. 
>
> Cheers,
> Marc
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/5ea67f27-ddc1-412c-bb8e-dd049172b641%40googlegroups.com.


[racket-users] Typed Racket: 'Unable to protect opaque value passed as `Any`' with interesting behavior

2019-12-11 Thread Marc Kaufmann
Hello,

I have one file called `type-test.rkt` with the following (notice that I 
discovered that there is a typed version of the web-server/http module, 
which solves another of my issues):

```
#lang typed/racket

(require (only-in typed/web-server/http response/xexpr response))

(provide f1 f2 f3 f4)

(: f1 (-> response))
(define (f1)
  (define x '(body (h1 "Try it")))
  (: resp response)
  (define resp (response/xexpr x))
  resp)

(: f2 (-> (U response Any)))
(define (f2)
  (define x '(body (h1 "Try it")))
  (: resp response)
  (define resp (response/xexpr x))
  resp)

(: f3 (-> (U response Number)))
(define (f3)
  (define x '(body (h1 "Try it")))
  (: resp response)
  (define resp (response/xexpr x))
  resp)

(: f4 (-> (U Any response)))
(define (f4)
  (define x '(body (h1 "Try it")))
  (: resp response)
  (define resp (response/xexpr x))
  resp)
```

Then I have another *untyped* file for a servlet:

```
#lang racket

(require "type-test.rkt"
 web-server/servlet
 web-server/servlet-env)

(define (start req)
  (f1)
  ; (f2)
  ; (f3)
  ; (f4)
  )

(serve/servlet start
   #:servlet-regexp #rx""
   #:launch-browser? #false
   #:port 8080)
```

Notice that I am telling all the f* functions that `resp` is of type 
`response`. Yet, when I run the server with `start` using `f1` through `f4` 
I get the following results:

(f1): All good
(f2): Error, see below. Unable to protect opaque value passed as `Any` 
(f3): All good 
(f4): Error, see below.

The error is:

```

f4: broke its own contract
  any-wrap/c: Unable to protect opaque value passed as `Any`
  value: #
  in: the range of
  (-> Any)

```

First, I couldn't figure out how to replicate this in the REPL, and had to 
use the server to get the result. But I was able to figure out at the REPL 
that (f2) and (f4) return something of type `Any`, for some unknown reason. 
Clearly TR is smart enough to figure out that `resp` is not a Number, but a 
response, but then when I allow it to return both a type `response` and 
`Any`, it says that it's return value is `Any`. Why? Every function that 
can take `Any` can take `response`, and every function that expects 
response is now going to blow up (as now happens). 

At the REPL, I didn't manage to get this behavior, probably because 
`serve/servlet` has contracts around it's arguments. Thus:

- I pass all the typed racket tests
- I nonetheless return something of type `Any` (which is really guaranteed 
to be of type response, and I am already annotating, so this surprises me)
- When this hits the contract, it complains and tells me that f4 broke its 
own contract, which seems false, but this may be one of those 'Contract 
blaming is hard' moments

Long story short: Why do (f2) and (f4) return something of type `Any` 
rather than `response`? What is the logic for doing this and what use case 
am I missing where this is a feature (or maybe it's just hard to get right, 
but this seems vastly easier than other things Typed Racket does).

And yes, I should probably just use typed/web-server/servlet and friends 
(not sure if everything is covered, but probably) - but I discovered the 
typed/** modules only while trying to fix this. And the issue will come up 
with other non-typed modules or when/if I try to created typed versions of 
some module. 

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/777af0ca-0b1f-474a-bd9f-8a9786e2a5c1%40googlegroups.com.


[racket-users] How can I tell Typed Racket that xexpressions are xexpressions?

2019-12-10 Thread Marc Kaufmann
Welcome to this week's edition of "Confusing myself with Typed Racket".*

I want to import `response/xexpr-wrap` -- a version of `response/xexpr` 
that does some additional styling -- in a typed/racket file. So thanks to 
Ben and Jon in another thread, I now do

```
(require/typed xml [#:opaque Xexpr xexpr?])
(require/typed "tools.rkt" [#:opaque Response response?] 
[response/xexpr-wrap (-> Xexpr Response)])

(define x '(body (h1 "Not so Hello world")))
(response/xexpr-wrap x)
```

And this does not work. I get the error

```
expected: Xexpr
given: (List 'body (List 'h1 String))
```

even though it passes the `(xexpr? x)` passes, returning #t. I was somewhat 
surprised by this, but I guess the issue is that opaque types can only work 
at runtime on code from non-typed modules. However, since I pass `x` as an 
argument in my file, the type checker wants to type check it now, rather 
than putting contracts around the arguments passed into 
`response/xexpr-wrap`. 

If this is the case, is it possible to use opaque types to type check 
arguments into functions required from non-typed modules? Well, I can 
probably hack my way around this: I write a non-typed function in 
`tools.rkt` called `this-is-an-xexpr` which I require/typed with `(-> Any 
Xexpr)`, which if I understand things correctly should put run-time 
contracts around that function, but type check. (See below, I went and 
checked whether this worked, and it does.) A less hacky way would be to be 
less lazy and define an Xexpr type via `define-type Xexpr (U String Symbol 
(Listof ...)...)` and so on. This is probably what I'll do, but I wanted to 
know what is going on anyway.

If it is not the case, what is going on that makes this not work?

Despite having found a way to make this work, I'd like to know if there is 
a non-hacky way, whether I understand correctly why my naive approach 
failed, and what the (or a) recommended way of doing this is. 

Cheers - until next time.

Marc

EDIT LATER: Hah, my hack works! 

```{tools.rkt}
#lang racket

(provide make-xexpr ...)
(define (make-xexpr xexpr)
  xexpr)
```

and then in my typed file:

```
#lang typed/racket

(require/typed "tools.rkt" 
  [#:opaque Response response?]
  [#:opaque Xexpr xexpr?]
  [make-xexpr (-> Any Xexpr)]
  [response/wrap-xexpr (-> Xexpr Response)])

(define x '(body (h1 "Not so Hello world")))
(response/wrap-xexpr (make-xexpr x))
```

and this works. Nice, in an ugly kind of way.

*: Despite said confusion, ever since I got past the initial hump of using 
Typed Racket, it's been really useful though as it catches a substantial 
fraction of my bugs that would require sprinkling lots of printfairy dust 
to find and fix.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/0e428a87-095a-48fc-a31a-b393f4672642%40googlegroups.com.


Re: [racket-users] How to use dates (especially gregor) with Typed Racket?

2019-12-07 Thread Marc Kaufmann
I meant `require/typed` obviously, not `require-typed`.

On Saturday, December 7, 2019 at 11:17:00 AM UTC+1, Marc Kaufmann wrote:
>
> Thanks Ben and Jon, that did the trick. 
>
> I realized when following the code that the structure wasn't exported - 
> but I didn't know how to work around that. I now also checked the 
> documentation, and the only thing I found on opaque types is 
> https://docs.racket-lang.org/ts-reference/special-forms.html?q=opaque#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._require%2Ftyped%29%29.
>  
> What it says about opaque types is:
>
> "Opaque types must be required lexically before they are used."
>
> followed by an example that is even now non-trivial for me to parse and 
> figure out. (I started going down the rabbit hole when the `->` was not 
> used in the first position of the definition, nor written as `. -> .` Turns 
> out types can be defined via infix notation, which is nice but unexpected.)
>
> So there are two questions: 
>
> 1. What does #:opaque do?
> 2. How could I have found that out by searching - or essentially the way 
> to do it was "Email the list". If the latter, that's fine, the email list 
> is very helpful and it would be good to add some additional explanation of 
> opaque types to the documentation of `require-typed`, and possibly even to 
> the typed racket reference. Probably the part talking about typed-racket 
> untyped racket interaction.
>
> Let me try answering my first question: #:opaque defines a new type via a 
> predicate function -- here `time?` -- that is being imported (can I use it 
> without require-typed? I guess there would be no point, but I haven't 
> thought this through). This is not based on the usual type constructors 
> using other types, but based on whether a thing returns `#true` when passed 
> to the predicate, in my case `time?`. I assume this means that the type is 
> verified via contracts, so if I do this a lot I should expect some run-time 
> performance hits (if I call this function a bunch, which isn't an issue in 
> my case).
>
> Cheers,
> Marc
>
> On Wednesday, December 4, 2019 at 6:26:47 PM UTC+1, Jon Zeppieri wrote:
>>
>> On Tue, Dec 3, 2019 at 8:55 PM Ben Greenman  
>> wrote: 
>> > 
>> > The error is because gregor/time doesn't export a struct. But 
>> > nevermind that, because you're probably best off with an opaque type: 
>> > 
>> > ``` 
>> > #lang typed/racket 
>> > 
>> > (require/typed gregor/time 
>> >   [#:opaque Time time?] 
>> >   [time (->* [Integer] [Integer Integer Integer] Time)] 
>> >   [time->iso8601 (-> Time String)]) 
>> > 
>> > (require/typed gregor 
>> >   [current-time (->* [] [#:tz String] Time)]) 
>> > 
>> > (time->iso8601 (current-time)) 
>> > ;; "21:04:25.687808105" 
>> > ``` 
>>
>> Also, most operations on the date/time data structures are generic, 
>> which makes it a bit more complicated to use with typed racket. The 
>> generic predicates, like `time-provider?`, should probably map to 
>> union types, like so (though people like Ben, who are more savvy about 
>> typed racket, might have other ideas): 
>>
>> ``` 
>> #lang typed/racket 
>>
>> (require/typed gregor/time 
>>[#:opaque Time time?] 
>>[time (->* [Integer] [Integer Integer Integer] Time)] 
>>[time->iso8601 (-> Time String)]) 
>>
>> (require/typed gregor 
>>[#:opaque Datetime datetime?] 
>>[datetime (->* [Integer] [Integer Integer Integer 
>> Integer Integer Integer] Datetime)]) 
>>
>> (define-type Time-Provider (U Time Datetime)) 
>>
>> (require/typed gregor 
>>[current-time (->* [] [#:tz String] Time)] 
>>[->hours (-> Time-Provider Integer)]) 
>>
>> (time->iso8601 (current-time)) 
>> (->hours (current-time)) 
>> ``` 
>>
>> Also, if you want to be more specific with your types: 
>> ``` 
>> #lang typed/racket #:with-refinements 
>>
>> (define-type Hour (Refine [n : Integer] (and (>= n 0) (< n 24 
>> (define-type Minute (Refine [n : Integer] (and (>= n 0) (< n 60 
>> (define-type Second (Refine [n : Integer] (and (>= n 0) (< n 60 
>> (define-type Nanosecond (Refine [n : Integer] (and (>= n 0) (< n 
>> 10 
>>
>> (require/typed 
>>  gregor/time 
>>  [#:opaque Time time?] 
>>  [time (->* [Hour] [Minute Second Nanosecond] Time)]) 
>> ``` 
>> ... though this might make the proof obligations too onerous, 
>> depending on how you're using the library. 
>>
>> - Jon 
>>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/10a47274-6a9c-4cc6-b554-05a286531f9f%40googlegroups.com.


Re: [racket-users] How to use dates (especially gregor) with Typed Racket?

2019-12-07 Thread Marc Kaufmann
Thanks Ben and Jon, that did the trick. 

I realized when following the code that the structure wasn't exported - but 
I didn't know how to work around that. I now also checked the 
documentation, and the only thing I found on opaque types is 
https://docs.racket-lang.org/ts-reference/special-forms.html?q=opaque#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._require%2Ftyped%29%29.
 
What it says about opaque types is:

"Opaque types must be required lexically before they are used."

followed by an example that is even now non-trivial for me to parse and 
figure out. (I started going down the rabbit hole when the `->` was not 
used in the first position of the definition, nor written as `. -> .` Turns 
out types can be defined via infix notation, which is nice but unexpected.)

So there are two questions: 

1. What does #:opaque do?
2. How could I have found that out by searching - or essentially the way to 
do it was "Email the list". If the latter, that's fine, the email list is 
very helpful and it would be good to add some additional explanation of 
opaque types to the documentation of `require-typed`, and possibly even to 
the typed racket reference. Probably the part talking about typed-racket 
untyped racket interaction.

Let me try answering my first question: #:opaque defines a new type via a 
predicate function -- here `time?` -- that is being imported (can I use it 
without require-typed? I guess there would be no point, but I haven't 
thought this through). This is not based on the usual type constructors 
using other types, but based on whether a thing returns `#true` when passed 
to the predicate, in my case `time?`. I assume this means that the type is 
verified via contracts, so if I do this a lot I should expect some run-time 
performance hits (if I call this function a bunch, which isn't an issue in 
my case).

Cheers,
Marc

On Wednesday, December 4, 2019 at 6:26:47 PM UTC+1, Jon Zeppieri wrote:
>
> On Tue, Dec 3, 2019 at 8:55 PM Ben Greenman  > wrote: 
> > 
> > The error is because gregor/time doesn't export a struct. But 
> > nevermind that, because you're probably best off with an opaque type: 
> > 
> > ``` 
> > #lang typed/racket 
> > 
> > (require/typed gregor/time 
> >   [#:opaque Time time?] 
> >   [time (->* [Integer] [Integer Integer Integer] Time)] 
> >   [time->iso8601 (-> Time String)]) 
> > 
> > (require/typed gregor 
> >   [current-time (->* [] [#:tz String] Time)]) 
> > 
> > (time->iso8601 (current-time)) 
> > ;; "21:04:25.687808105" 
> > ``` 
>
> Also, most operations on the date/time data structures are generic, 
> which makes it a bit more complicated to use with typed racket. The 
> generic predicates, like `time-provider?`, should probably map to 
> union types, like so (though people like Ben, who are more savvy about 
> typed racket, might have other ideas): 
>
> ``` 
> #lang typed/racket 
>
> (require/typed gregor/time 
>[#:opaque Time time?] 
>[time (->* [Integer] [Integer Integer Integer] Time)] 
>[time->iso8601 (-> Time String)]) 
>
> (require/typed gregor 
>[#:opaque Datetime datetime?] 
>[datetime (->* [Integer] [Integer Integer Integer 
> Integer Integer Integer] Datetime)]) 
>
> (define-type Time-Provider (U Time Datetime)) 
>
> (require/typed gregor 
>[current-time (->* [] [#:tz String] Time)] 
>[->hours (-> Time-Provider Integer)]) 
>
> (time->iso8601 (current-time)) 
> (->hours (current-time)) 
> ``` 
>
> Also, if you want to be more specific with your types: 
> ``` 
> #lang typed/racket #:with-refinements 
>
> (define-type Hour (Refine [n : Integer] (and (>= n 0) (< n 24 
> (define-type Minute (Refine [n : Integer] (and (>= n 0) (< n 60 
> (define-type Second (Refine [n : Integer] (and (>= n 0) (< n 60 
> (define-type Nanosecond (Refine [n : Integer] (and (>= n 0) (< n 
> 10 
>
> (require/typed 
>  gregor/time 
>  [#:opaque Time time?] 
>  [time (->* [Hour] [Minute Second Nanosecond] Time)]) 
> ``` 
> ... though this might make the proof obligations too onerous, 
> depending on how you're using the library. 
>
> - Jon 
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/41fc9b03-81e0-4062-b7da-253d7348ce29%40googlegroups.com.


[racket-users] How to use dates (especially gregor) with Typed Racket?

2019-12-03 Thread Marc Kaufmann
Hi,

this is hopefully easier, but I can't figure out how to `(require/typed 
gregor)` inside a typed racket file. Here are my failed attempts (I want 
time to work, hence I try to import gregor/time):

```
#lang typed/racket

; Try to get time struct from gregor/time
(require/typed gregor/time
   [#:struct time ([hour : Integer] 
   [minute : Integer]
   [second : Integer]
   [nanosecond : Integer])])

; This just checks that the time structure isn't in gregor
(require/typed gregor
   [#:struct time ([hour : Integer] 
   [minute : Integer]
   [second : Integer]
   [nanosecond : Integer])]
   [current-time (->* () (#:tz String) time)])
```

These fail with errors of the kind 

"
only-in: identifier `struct:time' not included in nested require spec
at: gregor
in: (only-in gregor struct:time (time time2))
"

So, maybe I am wrong to think that time is a struct. But when I print one 
in the REPL, it says #, which I thought would mean it's a struct.

My next step was to check the type of it in the REPL with typed racket... 
but that doesn't work since requiring gregor in a REPL with typed/racket 
leads to the same errors (obviously, since how would it know anything 
more...). 

Hence, I fire up DrRacket, following the trail to the definition of the 
time structure and I find that the structure itself is never provided out, 
but only used to define the function `time?` and others. But that makes me 
wonder: how can I define the type for time so that I can use gregor inside 
typed/racket if I can't import the structure (which in my understanding 
defines the type of time)? I can't figure out what thing `(current-time)` 
is, apparently  `(struct Time (hms ns) ...)` but I don't see any contracts 
on hms or ns to figure out what they are... but even if I did, would I 
define my own structure `(struct my-time ([hms : HMS] [ns : NS])` and use 
that? 

Cheers,
Marc

PS: If any Vim users our there can tell me how to jump to definitions of 
required libraries I'd be ever so happy.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/fddb26f2-31d9-4228-b44f-73ea30d98220%40googlegroups.com.


Re: [racket-users] Typed Racket needs annotation to realize (Mutable-HashTable Symbol Symbol) is of a more general type

2019-11-06 Thread Marc Kaufmann
Thanks Alexis, I now see why the subtyping doesn't work and why mutability
is the issue. So when using mutable data structures, I really have to use
the largest possible type everywhere or add annotations or similar - making
types on immutable data more flexible. That's interesting.

Thanks for pointing out the REPL tools for looking at types Ben, I'll check
those out.

I've now worked around having to put annotations everywhere by making some
custom constructors with type signatures. That obviously requires direct
annotations still, but at least my code isn't sprinkled with `(ann
(make-hash ...) DB)` anymore, instead it has `(make-db ...)`.

Maybe I missed this (subtle, to me) point in the documentation, but somehow
highlighting the issue of mutability and subtyping may be worth it. In
https://docs.racket-lang.org/ts-guide/more.html, the docs mention the need
to annotate mutable data, but this seems somewhat different from the "It's
mutable, so you need to annotate", especially as the problem was lack of
precision, rather than overly conservative type inference. I would suggest
adding it as a point 5, or a variation of point 4, using Alexis' example
with `(f v)` as to why it fails.

Cheers,
Marc

On Wed, Nov 6, 2019 at 2:05 PM Ben Greenman 
wrote:

> On 11/6/19, Marc Kaufmann  wrote:
> > I assumed it was something to do with mutability, but I don't understand
> > what you mean when you say there is a two-way channel. The reference in
> > typed racket (
> >
> https://docs.racket-lang.org/ts-reference/type-ref.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fbase-types..rkt%29._.Hash.Table%29%29
> )
> > says this:
> >
> > ```
> >
> > (HashTable
> > <
> https://docs.racket-lang.org/ts-reference/type-ref.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fbase-types..rkt%29._.Hash.Table%29%29
> >
> >  k v)
> >
> > is the type of a mutable or immutable hash table
> > <
> https://docs.racket-lang.org/reference/hashtables.html#%28tech._hash._table%29
> >
> > with key type k and value type v.
> > Example:
> >
> >> (make-hash
> > <
> https://docs.racket-lang.org/reference/hashtables.html#%28def._%28%28quote._~23~25kernel%29._make-hash%29%29
> >
> >  '((a . 1) (b . 2)))
> >
> > - : (HashTable Symbol Integer) [more precisely: (Mutable-HashTable Symbol
> > Integer)]
> >
> > '#hash((a . 1) (b . 2))
> >
> > ```
> >
> > That suggests to me that HashTable includes both Mutatable-HashTable and
> > Immutable-HashTable. The example given even states that the HashTable
> > Symbol Integer is more precisely of Mutable-HashTable Symbol Integer
> type -
> > does that *not* mean that (Mutable-HashTable Symbol Integer) is a subtype
> > of (HashTable Symbol Integer) in the reference example?
>
> Right --- (Mutable-HashTable Symbol Integer) is a subtype of
> (HashTable Symbol Integer).
>
> > I now tried to redefine DB as Mutable-HashTable to avoid this issue, but
> > that doesn't work either. It still doesn't accept `(make-hash (list (cons
> > 'study-type study-type)))` as something of type DB. How is
> > (Mutable-HashTable Symbol Symbol) not a subtype of DB, which is
> > (Mutable-HashTable DBKey (U DB DBValue)), and DBKey is (U Symbol ...
> ;other
> > stuff) and same for DBValue?
>
> See Alexis's reply.
>
> For a small example,  (Mutable-HashTable Symbol Symbol) is NOT a
> subtype of (Mutable-HashTable Symbol (U Symbol String))
>
> ```
> #lang typed/racket/base
>
> (define-type (M-HT A B) (Mutable-HashTable A B))
>
> (define (f (x : (M-HT Symbol (U Symbol String
>   (void))
>
> (define h : (M-HT Symbol Symbol)
>   (make-hash '((A . X
>
> (f h) ;; type error
> ```
>
> > You wrote that make-hash is of type `(Listof (Pairof Symbol Symbol))`. Is
> > there a way to expand and print the type of something in terms of
> primitive
> > types (well, or maybe step through one layer of abstraction) so that I
> > could play around with some toy examples to get a sense of what types are
> > returned? I am clearly confused by what type `make-hash` returns and what
> > `hash-ref` expects.
>
> The blue boxes in Dr. Racket might help. There are also a few tools
> for looking at types in the REPL:
>
> https://docs.racket-lang.org/ts-reference/Exploring_Types.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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO7MNPVctku-mZQddNO5PXEwy1Wv6CDL4vxVZ3iQMoQ%3Dtw%40mail.gmail.com.


Re: [racket-users] Typed Racket needs annotation to realize (Mutable-HashTable Symbol Symbol) is of a more general type

2019-11-05 Thread Marc Kaufmann
I assumed it was something to do with mutability, but I don't understand
what you mean when you say there is a two-way channel. The reference in
typed racket (
https://docs.racket-lang.org/ts-reference/type-ref.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fbase-types..rkt%29._.Hash.Table%29%29)
says this:

```

(HashTable
<https://docs.racket-lang.org/ts-reference/type-ref.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fbase-types..rkt%29._.Hash.Table%29%29>
 k v)

is the type of a mutable or immutable hash table
<https://docs.racket-lang.org/reference/hashtables.html#%28tech._hash._table%29>
with key type k and value type v.
Example:

> (make-hash
<https://docs.racket-lang.org/reference/hashtables.html#%28def._%28%28quote._~23~25kernel%29._make-hash%29%29>
 '((a . 1) (b . 2)))

- : (HashTable Symbol Integer) [more precisely: (Mutable-HashTable Symbol
Integer)]

'#hash((a . 1) (b . 2))

```

That suggests to me that HashTable includes both Mutatable-HashTable and
Immutable-HashTable. The example given even states that the HashTable
Symbol Integer is more precisely of Mutable-HashTable Symbol Integer type -
does that *not* mean that (Mutable-HashTable Symbol Integer) is a subtype
of (HashTable Symbol Integer) in the reference example?

I now tried to redefine DB as Mutable-HashTable to avoid this issue, but
that doesn't work either. It still doesn't accept `(make-hash (list (cons
'study-type study-type)))` as something of type DB. How is
(Mutable-HashTable Symbol Symbol) not a subtype of DB, which is
(Mutable-HashTable DBKey (U DB DBValue)), and DBKey is (U Symbol ... ;other
stuff) and same for DBValue?

You wrote that make-hash is of type `(Listof (Pairof Symbol Symbol))`. Is
there a way to expand and print the type of something in terms of primitive
types (well, or maybe step through one layer of abstraction) so that I
could play around with some toy examples to get a sense of what types are
returned? I am clearly confused by what type `make-hash` returns and what
`hash-ref` expects.

Cheers,
Marc


On Tue, Nov 5, 2019 at 3:22 PM Sam Tobin-Hochstadt 
wrote:

> The problem is that the `DB` type is _not_ a super-type of
> `(Mutable-HashTable Symbol Symbol)`, because mutable data structures
> are two way communications channels. If you used an immutable hash,
> that's a one-way communication and you would have the expected result.
>
> However, the change you made fixed the problem because it changes the
> type that `make-hash` picks to create the hash table. The argument to
> `make-hash` has the type `(Listof (Pairof Symbol Symbol))` which _is_
> a sub-type of `(Listof (Pairof DBKey (U DB DBValue)))`.
>
> Sam
>
>
> On Tue, Nov 5, 2019 at 6:39 AM Marc Kaufmann 
> wrote:
> >
> > Hi,
> >
> > in order to put some discipline on my code (and formalize to myself what
> I'm passing around), I started using typed racket. I have definitely hit my
> share of gotchas that make me scratch my head, but I kind of start to
> understand how things work and adding `(ann this-is ThatType)` annotations.
> >
> > However, I have the following piece of code:
> >
> > ```
> > (: register-study-session! (-> Number Symbol Void))
> > (define (register-study-session! sid study-type)
> >   (unless (hash-has-key? (db-table 'studies) sid)
> > (hash-set! (db-table 'studies)
> >sid
> >(make-hash (list (cons 'study-type study-type))
> > ```
> >
> > then I get the following error:
> >
> > ```
> > exploration.rkt:139:4: Type Checker: Polymorphic function `hash-set!'
> could not be applied to arguments:
> > Argument 1:
> >   Expected: (HashTable a b)
> >   Given:DB
> > Argument 2:
> >   Expected: a
> >   Given:Number
> > Argument 3:
> >   Expected: b
> >   Given:(Mutable-HashTable Symbol Symbol)
> > ```
> >
> > The DB type is as follows:
> >
> > ```
> > (define-type DBKey (U Symbol Number))
> > (define-type DBValue (U Symbol Number Boolean Char))
> > (define-type DB (HashTable DBKey (U DB DBValue)))
> > ```
> >
> > However when I annotate this with an (ann ...) around the make-hash, it
> works:
> >
> > ```
> > (: register-study-session! (-> Number Symbol Void))
> > (define (register-study-session! sid study-type)
> >   (unless (hash-has-key? (db-table 'studies) sid)
> > (hash-set! (db-table 'studies)
> >sid
> >(ann (make-hash (list (cons 'study-type study-type)))
> DB ;; ONLY THIS LINE CHANGED
> > ```
> >
> > I don't understand why this leads to it passing, since it said that it
> thought the DB earlier was a mutable hash of type Symbol to Symbol, wh

[racket-users] Typed Racket needs annotation to realize (Mutable-HashTable Symbol Symbol) is of a more general type

2019-11-05 Thread Marc Kaufmann
Hi,

in order to put some discipline on my code (and formalize to myself what 
I'm passing around), I started using typed racket. I have definitely hit my 
share of gotchas that make me scratch my head, but I kind of start to 
understand how things work and adding `(ann this-is ThatType)` annotations.

However, I have the following piece of code:

```
(: register-study-session! (-> Number Symbol Void))
(define (register-study-session! sid study-type)
  (unless (hash-has-key? (db-table 'studies) sid)
(hash-set! (db-table 'studies) 
   sid 
   (make-hash (list (cons 'study-type study-type))
```

then I get the following error:

```
exploration.rkt:139:4: Type Checker: Polymorphic function `hash-set!' could 
not be applied to 
arguments:  
 

Argument 
1:  

  

  Expected: (HashTable a 
b)  

  

  Given:
DB  

   

Argument 
2:  

  

  Expected: 
a   

   

  Given:
Number  

   

Argument 
3:  

  

  Expected: 
b   

   

  Given:(Mutable-HashTable Symbol Symbol)  
``` 

   

 
The DB type is as follows:

```
(define-type DBKey (U Symbol Number))
(define-type DBValue (U Symbol Number Boolean Char))
(define-type DB (HashTable DBKey (U DB DBValue)))
```

However when I annotate this with an (ann ...) around the make-hash, it 
works:

```
(: register-study-session! (-> Number Symbol Void))
(define (register-study-session! sid study-type)
  (unless (hash-has-key? (db-table 'studies) sid)
(hash-set! (db-table 'studies) 
   sid 
   (ann (make-hash (list (cons 'study-type study-type))) DB 
;; ONLY THIS LINE CHANGED
```   

I don't understand why this leads to it passing, since it said that it 
thought the DB earlier was a mutable hash of type Symbol to Symbol, which I 
would have thought is of type DB (which is any hashtable). So why does the 
type checker complain at first - or maybe why does it pass later?

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/6b08ac58-5c85-45ad-9fb7-dd367254e015%40googlegroups.com.


Re: [racket-users] Re: General ways and concrete examples of approaching web dev

2019-10-09 Thread Marc Kaufmann
> I think part of your problem it is that you are integrating/conflating
> what are purely implementation issues - such as whether to pass state
> via continuations vs storing it in DBMS - with higher level design
> issues like whether to use MVC vs some other equivalent architecture.

Yep, I agree, and I actually know it - but that doesn't help me know what I
shouldn't and what I should conflate. This thread has helped somewhat. If
you know of any in-depth resource/book (whether modern web dev or old '80s
MVC) that might help, I'd appreciate it.

> On the subject of database development, your best bet for reducing
> effort is to invest in a database modeling tool.

You don't happen to have a free/cheap (Linux compatible) one to try out? I
found 10 lists with 'best 6/10/33 db modeling tools', which is 5/9/32 tools
too many...

For now I'll have to roll my own due to deadlines, but I'll have a look.
And see, I didn't even know such things existed (and am still not quite
sure what part of the work they are for, but we'll see).

Cheers,
Marc

On Wed, Oct 9, 2019 at 9:30 AM George Neuner  wrote:

>
> Rearranged a bit for continuity ...
>
>
> On Tue, 8 Oct 2019 19:44:55 +0200, Marc Kaufmann
>  wrote:
>
> >Thanks for the response to a rather general question. I'll definitely have
> >a look at your code for Racket stories, which is live now if I see
> >correctly. Nice!
> >
> >I guess one concrete thing that I find surprisingly hard in my code is to
> >get rid of the number of times I repeat the structure of the data:
> >
> >1. write the SQL code to create the database
> >2. write the interface in Racket that deals with the database directly
> >(transform into Racket values, but it's still in the same groups)
> >3. write functions that need to know about this structure, because they
> >extract the information from part 2, but different fields for different
> uses
> >4. write the view that - quite often - looks like a subset of the database
> >and in my case calls functions from part 3, which again repeats huge parts
> >of what is in part 1
> >
> >So if I have a user with 5 fields I am interested in, I find that if I
> >change part of my database schema, I usually update 3 (or more) places,
> >which tells me that I didn't get the abstractions right. (And I haven't
> >added tests, or else I'm sure I'd have another layer or 2 of repetition.)
> >  :
> >
> >My guess is that I don't grok MVC, and therefore end up with all these
> >repetitions ...
>
> It remains to be seen whether you really understand what MVC is about
> ... but repetition unfortunately is a major issue with it, as it is
> with many other application design patterns.
>
> In general, embracing MVC as a design philosophy won't reduce your
> work at all - in fact it likely will increase it.  MVC does nothing
> whatsoever to reduce the application's unique processing - it only
> addresses ways to structure the application.  But usually it will
> produce a program that is more modular and clearer to understand.
> [But your observations about maintenance are quite valid.]
>
>
> One of the issues I have with MVC is the way it typically is
> presented: data flow in the tutorials tends to be exaggerated and
> overly complicated, and the explanation typically revolves around DBMS
> and graphical UIs that simply aren't relevant to it.
>
> As a design pattern, MVC dates from the 1960s, from the era of CRT
> display/edit form-based applications.  The View and Controller
> historically were integrated, and the "Model" was a memory cache of
> one or more data records.
> [Relational DBMS didn't exist in the 60's, but there were many
> varieties of file based record systems.  Dedicated DBMS software based
> on network/graph and hierarchical models appeared in the 70's, and
> then relational models appeared in the 80's.]
>
> Obviously MVC can be - and has been - generalized to separate the
> various concerns, divorce the "Model" from its "data record" origins,
> and to allow more complex communication/control patterns.  But the
> modern notion of MVC has become so interwoven with DBMS, graphical
> UIs, event handling, reactive programming and web services that people
> learning about it often have a hard time figuring out what it really
> means and how to use it effectively for their own programs.
>
> MVC is simple when you understand what it was designed for originally.
>
>
> Then there is the proliferation of simplistic MVC object "frameworks".
> These typically address DBMS backing storage for the Model and little
> or nothing else.  Trying to use them for rapid application development
> too often results in your applicat

Re: [racket-users] General ways and concrete examples of approaching web dev

2019-10-08 Thread Marc Kaufmann
Thanks for the response to a rather general question. I'll definitely have
a look at your code for Racket stories, which is live now if I see
correctly. Nice!

I guess one concrete thing that I find surprisingly hard in my code is to
get rid of the number of times I repeat the structure of the data:

1. write the SQL code to create the database
2. write the interface in Racket that deals with the database directly
(transform into Racket values, but it's still in the same groups)
3. write functions that need to know about this structure, because they
extract the information from part 2, but different fields for different uses
4. write the view that - quite often - looks like a subset of the database
and in my case calls functions from part 3, which again repeats huge parts
of what is in part 1

So if I have a user with 5 fields I am interested in, I find that if I
change part of my database schema, I usually update 3 (or more) places,
which tells me that I didn't get the abstractions right. (And I haven't
added tests, or else I'm sure I'd have another layer or 2 of repetition.)
The continuation passing style actually suits my use cases much better than
storing state in the database -- except that I need to be able later on to
recreate the path a user took, in order to figure out what happened, so I
have to store it in an easy-to-interpret way in the database.

My guess is that I don't grok MVC, and therefore end up with all these
repetitions, so I'll have a look at your web site -- although part of the
reason I don't grok it may be that most beginner resources have websites
that are less stateful than what I do, which is much more like a game with
many action nodes and randomization. I should probably have a look at Realm
of Racket and see if I can't port the big-bang ideas to the web server.

Thanks for the reply and the tutorial, I'll have a look.

Cheers,
Marc

On Mon, Sep 30, 2019 at 2:48 PM Jens Axel Søgaard 
wrote:

> Hi Marc,
>
> Den tir. 24. sep. 2019 kl. 21.28 skrev Marc Kaufmann <
> marc.kaufman...@gmail.com>:
>
>> TL;DR: What are some patterns/approaches for web sites for which Racket
>> is particularly suited *and* for which you can point at decently written up
>> examples in Racket or other languages that share such features?
>>
>
> A big question on which I will punt.
>
>
>> Much longer me:
>>
>> I spent much of summer implementing online web sites with quite a bit of
>> state (do step 1; if answer a do step 2, if answer b do step 3; keep
>> forking, randomize some things in between). The first website I did in
>> Django, because 2 years ago when I rolled my own in Racket, I ended up with
>> an unmaintainable mess of code that had sql and sexpr sprinkled across all
>> types of files, and I didn't dare touch anything anymore. Now I learned
>> that I am perfectly capable of writing an unmaintainable mess of code in
>> Python too. Hence the second such web site (all are used for economic
>> experiments, think surveys with a lot of randomization and if/then logic)
>> is again back to Racket.
>>
>> The thing is that, while I know about MVC and grok it better after having
>> spent time with Django, I am often at a loss to figure out where to draw
>> boundaries in Racket. This is true for Django too, but there are so many
>> examples out there, that it is easier to figure out what belongs where, and
>> Django forces you to put some things in the models (more or less) and
>> others in the views. And all the standard stuff - forms, simple SQL - has
>> obvious ways of doing it. There are some things I dislike about it, but
>> these are some positives.
>>
>> Now that I am back in Racket land, and at least partially get what
>> continuations do (thanks to primarily Philip, George, Jesse, Bogdan and
>> Matthew B's writings and answers on this list over the years), my code is
>> vastly better than 2 years ago. Yet, I still feel that it is pretty bad,
>> and I see loads of duplications that I do, sometimes due to lack of time to
>> refactor, but just as often because I have no clue how to refactor it in a
>> way that will not make it ridiculously fine-tuned to my current purpose.
>>
>> So, my question is this: what approches (if you like big ponderous words,
>> what paradigms) and patterns are there to write web sites, and are you
>> aware of examples that highlight them *concretely* in code in a way that
>> the send/suspend/dispatch is described in the "Continue: ..." tutorial?
>> Here are approaches that I know of:
>>
>> - MVC: Django and Rails for instance, easy to find examples. Usually
>> object oriented it seems, but it's sort of what I do in Racket as well.
>> - Single-Page Apps: I never implemented

[racket-users] xrepl ,require-reloadable and ,require

2019-10-08 Thread Marc Kaufmann
Hi,

according to the docs 
(https://docs.racket-lang.org/xrepl/index.html#%28xrepl._require-reloadable%29) 
I would have assumed that when I do 

> ,require-reloadable "code.rkt"

that I can use whatever "code.rkt" provides, the same way as when I do

> ,require "code.rkt"

However, when I do just the ,require-reloadable I have to follow it up with 
a simple ,require for the provides to be available. Example: if code has 
(provide my-function), then I have (where ,rr is the short-form for 
,require-reloadable and ,r for ,require):

> ,rr "code.rkt"
> (my-function args)
; my-function: undefined;
...
> ,r "code.rkt"
> (my-function args)
; Works fine, and seems like I can reload it afterwards

Is this how it should be - and if so, why? Might be worth pointing out in 
the docs if this behavior is expected, as I kept closing and restarting the 
repl to reload my changes since I couldn't get ,require-reloadable to work.

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/74ff9ef8-c66d-4e8c-9595-2bd40e30f761%40googlegroups.com.


[racket-users] Does Racket have something similar to IPython.embed() for debugging?

2019-10-04 Thread Marc Kaufmann
Hi,

a friend who uses Python mentioned that how he debugs is via `embed()`, 
which launches an IPython console at the point it is called with all the 
variables that exist at that point being defined, so you can inspect a 
bunch without sprinkling prints everywhere.

```{python}
from IPython import embed

a = 30
b = 20
embed() # At this point an IPython console will pop up and one can check 
the values of `a` and `b`, then type `exit()` to continue
c = 10
d = 0
embed() 
```

I was wondering if Racket has something similar? Sometimes it's not that 
useful since I have to figure out the point where things break, but at 
other times, it might be quite useful.

Additionally, I came across this tread on racket-users from 2015: 

https://groups.google.com/forum/#!searchin/racket-users/inspect$20variable%7Csort:date/racket-users/Jzg7cYCH-GY/nciHFLZkBAAJ

Are there any more up-to-date resources on how to debug in Racket? Thanks 
to vim-slime my debugging is already faster (all you emacs people are 
probably way ahead thanks to Greg's racket-mode), but it's still incredibly 
clunky and slow. (Of course if I used tests and contracts more liberally, 
things might be different... but hey, debugging can't be avoided, tests and 
contracts can.)

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/cd2b9453-e26d-4b80-bbd8-e3a0ec43f06d%40googlegroups.com.


Re: [racket-users] Testing Servlets: exceptions not raised/passed through; how to pass extra arguments to tested servlet

2019-09-26 Thread Marc Kaufmann
Ah yes, that's right. I did somehow (without really thinking about it,
admittedly) think that the exception would get returned with the response.
I did not realize that test-servlet sets up a server.

So for testing the functions, I just create the right requests and do a
check-* test. That should also work to see if dispatch-rules calls the
correct routes, right? Or does that require something from a running server
that I don't realize?

I'll probably need some time before I figure out which type of testing
belongs where, hopefully I'll get to it this weekend.

On Thu, Sep 26, 2019 at 1:22 PM Jay McCarthy  wrote:

> On Thu, Sep 26, 2019 at 5:46 AM Marc Kaufmann 
> wrote:
> >
> > Thanks for clearing this up. If I understand correctly, the following
> happens:
> >
> > - the servlet raises an exception
> > - this is caught by the default exception handler
> > - it prints the traceback and exception message to standard output which
> I see (and which made me realize an exception had been raised), and it
> passes the response to the servlet-tester. However, the exception didn't
> bubble up to check-not-exn
> >
> > Since I can't turn off the exception handling of the servlets, I have to
> look at the output to find that an exception was thrown. Could I pass a
> different exception-handler to the test-servlet, which would return
> something easier (and more robust) to check whether an exception was thrown
> or not? Or should I bundle the servlet into a lambda for this, and have an
> exception-handler in that lambda that simply outputs "exception-raised" or
> some such? Otherwise I can of course parse the output, but that seems a
> little more error-prone.
>
> I think you're thinking about this wrong. It is not that can't "turn
> off the exception handling" or that "the exception didn't bubble up".
> If you go to pkgs.racket-lang.org and there's an exception in the code
> on the server, do you expect the Racket exception to be thrown to
> Google Chrome where a `with-handlers` can catch it? Of course not.
> `make-servlet-tester` is literally a network client. It starts up a
> hidden server and connects to it.
>
> So, you need to ask what it is that you are trying to test...
>
> If you want to know if a certain Racket function throws an exception,
> then just test that function directly and use `check-not-exn`. That's
> what Rackunit, chk, and other libraries are for. In this case, you are
> testing a Racket function for its behavior: so you ask "Racket"
> questions, like "Are exceptions thrown?".
>
> If you want to know if your servlet returns certain pages, then use
> `make-servlet-tester` to inspect the pages that get generated. In this
> case, you are testing a Web app for its behavior: so you ask "Web"
> questions, like "Is the background of the page purple?".
>
> 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO5FYHcx-z0PVV2Nz7k%3DuRYrTUar5Fb3cDs657cJDWxa%3Dg%40mail.gmail.com.


Re: [racket-users] Testing Servlets: exceptions not raised/passed through; how to pass extra arguments to tested servlet

2019-09-26 Thread Marc Kaufmann
Thanks for clearing this up. If I understand correctly, the following
happens:

- the servlet raises an exception
- this is caught by the default exception handler
- it prints the traceback and exception message to standard output which I
see (and which made me realize an exception had been raised), and it passes
the response to the servlet-tester. However, the exception didn't bubble up
to check-not-exn

Since I can't turn off the exception handling of the servlets, I have to
look at the output to find that an exception was thrown. Could I pass a
different exception-handler to the test-servlet, which would return
something easier (and more robust) to check whether an exception was thrown
or not? Or should I bundle the servlet into a lambda for this, and have an
exception-handler in that lambda that simply outputs "exception-raised" or
some such? Otherwise I can of course parse the output, but that seems a
little more error-prone.

Thanks

On Wed, Sep 25, 2019 at 4:29 PM Jay McCarthy  wrote:

> The output of `make-servlet-tester` returns the HTTP response object that
> the servlet returns. `make-servlet-tester` really makes a HTTP connection
> to your servlet and is checking the actual result that you sent back. If
> the servlet throws an exception, then probably you have the default
> exception handler which turns that into an HTML display. That HTML display
> would be returned and thus, there was no exception. In other words, it is
> not a sufficient test of what you want to check that no exception is
> thrown, you want to make sure a desirable page is returned.
>
> Jay
>
> --
> Jay McCarthy
> Associate Professor @ CS @ UMass Lowell
> http://jeapostrophe.github.io
> Vincit qui se vincit.
>
>
> On Tue, Sep 24, 2019 at 9:34 AM Marc Kaufmann 
> wrote:
>
>> Hi all,
>>
>> I have gone through https://docs.racket-lang.org/web-server/test.html to
>> finally stop manually checking whether I didn't introduce new bugs in one
>> of my servlets. I think that I have figured out most of the wrinkles for
>> this, except one.
>>
>> I run my tests via `raco test server.rkt`, and server.rkt has the
>> following structure:
>>
>> (require web-server/test web-server/servlet ...)
>>
>> (define (start request)
>>   (define-values (top-dispatch top-urls)
>> (dispatch-rules
>>   [("") home]
>>   [("login") #:method (or "post" "get") log-in]
>>   [("mp") #:method (or "post" "get") mp]
>>   ...
>>   ))
>>
>>   (top-dispatch request))
>>
>> (module+ main
>>   (serve/servlet start ...))
>>
>> (module+ test
>>
>>   (define (test-start-servlet)
>>
>> (define experiment-servlet-tester
>>   (make-servlet-tester start))
>>
>> ; Test all the routes. This only tests that they don't raise
>> exceptions
>> (define routes
>>   (list
>> '()   ; Tests "/"
>> '("/login")
>> '("/mp")
>> ))
>>
>> (for ([route routes])
>>   (check-not-exn (λ () (apply experiment-servlet-tester route
>>
>> (define matrix-servlet-tester
>>   (make-servlet-tester (λ (req)
>>   (matrix req #:h (hash 'mturk-id
>> "TESTER")
>>
>> (matrix-servlet-tester)
>>
>> (displayln "All pages render without exception"))
>>
>>   (test-start-servlet))
>>
>>
>> The meat of what is going on is in the test module at the end. I create a
>> servlet-tester for the start servlet, which uses a dispatcher, and since I
>> have a bunch of routes I go through them in a for-loop. However, even
>> though the "/login" route throws an exception, the (test-start-servlet)
>> code is happily marching on, checks the "/mp" route, and then prints "All
>> pages render without exception". And raco test tells me that all the tests
>> are passing!
>>
>> How do I know that there is an exn? Because it prints the following right
>> before the test results:
>>
>> Servlet (@ /372d34a3-df04-478f-8d84-94fb212725c2) exception:
>> >: contract violation
>>   expected: real?
>>   given: #
>>   argument position: 1st
>>   other arguments...:
>>0
>>
>>
>> So, what is going on here? Clearly test-servet does some exception
>> catching in between, yet it still prints it to the screen? How can I test
>> for this, since I want to know how many and which pages blow up?
>>
&g

[racket-users] General ways and concrete examples of approaching web dev

2019-09-24 Thread Marc Kaufmann
Hi all,

TL;DR: What are some patterns/approaches for web sites for which Racket is 
particularly suited *and* for which you can point at decently written up 
examples in Racket or other languages that share such features?

Much longer me:

I spent much of summer implementing online web sites with quite a bit of 
state (do step 1; if answer a do step 2, if answer b do step 3; keep 
forking, randomize some things in between). The first website I did in 
Django, because 2 years ago when I rolled my own in Racket, I ended up with 
an unmaintainable mess of code that had sql and sexpr sprinkled across all 
types of files, and I didn't dare touch anything anymore. Now I learned 
that I am perfectly capable of writing an unmaintainable mess of code in 
Python too. Hence the second such web site (all are used for economic 
experiments, think surveys with a lot of randomization and if/then logic) 
is again back to Racket. 

The thing is that, while I know about MVC and grok it better after having 
spent time with Django, I am often at a loss to figure out where to draw 
boundaries in Racket. This is true for Django too, but there are so many 
examples out there, that it is easier to figure out what belongs where, and 
Django forces you to put some things in the models (more or less) and 
others in the views. And all the standard stuff - forms, simple SQL - has 
obvious ways of doing it. There are some things I dislike about it, but 
these are some positives.

Now that I am back in Racket land, and at least partially get what 
continuations do (thanks to primarily Philip, George, Jesse, Bogdan and 
Matthew B's writings and answers on this list over the years), my code is 
vastly better than 2 years ago. Yet, I still feel that it is pretty bad, 
and I see loads of duplications that I do, sometimes due to lack of time to 
refactor, but just as often because I have no clue how to refactor it in a 
way that will not make it ridiculously fine-tuned to my current purpose.

So, my question is this: what approches (if you like big ponderous words, 
what paradigms) and patterns are there to write web sites, and are you 
aware of examples that highlight them *concretely* in code in a way that 
the send/suspend/dispatch is described in the "Continue: ..." tutorial? 
Here are approaches that I know of:

- MVC: Django and Rails for instance, easy to find examples. Usually object 
oriented it seems, but it's sort of what I do in Racket as well.
- Single-Page Apps: I never implemented one, but my sense was that you can 
do MVC with it too, and it's more about whether you use JS to do things 
asynchronously. I may be wrong and there might be more to it.
- Continuation style: What "Continue" does, and again it's not really an 
alternative to MVC, but more how you implement it (or other things). I 
still struggle a lot with doing this well, as there are few descriptions of 
it that go beyond "Continue". When I google, it brings up essentially the 
Racket crowd and something called Seaside (I had never heard of it)
- Microservices (I do not get what it is, if it even is one thing)

So what are examples in Racket or Racket-like languages (semantics, not 
syntax, so it doesn't have to look Lispy if it is functional or uses 
continuations or whatever features of Racket) that I could use to guide how 
I *could* structure my web site in a given way? Django isn't that great a 
fit since it has a pretty heavy ORM, and does lots of magic behind the 
scenes on objects, which is not trivial to map to the functional style of 
Racket. 

I don't know whether these are related to it, but half (all?) of my 
struggles come from trying to manage the state people are in and ending up 
passing around biggish objects, or adding 2 or more boolean fields per page 
to the database and calling the database on every new page.

I understand that this is not the most well-formed question on this email 
list and it's likely I am asking the wrong question, so I am very open to 
being told "What you should be asking is ... " (such as, this is not about 
web stuff, but ...).

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/3375bd01-2fe5-4c9a-b926-d8b272010b74%40googlegroups.com.


[racket-users] Testing Servlets: exceptions not raised/passed through; how to pass extra arguments to tested servlet

2019-09-24 Thread Marc Kaufmann
Hi all,

I have gone through https://docs.racket-lang.org/web-server/test.html to 
finally stop manually checking whether I didn't introduce new bugs in one 
of my servlets. I think that I have figured out most of the wrinkles for 
this, except one. 

I run my tests via `raco test server.rkt`, and server.rkt has the following 
structure:

(require web-server/test web-server/servlet ...)

(define (start request)
  (define-values (top-dispatch top-urls)
(dispatch-rules
  [("") home]
  [("login") #:method (or "post" "get") log-in]
  [("mp") #:method (or "post" "get") mp]
  ...
  ))

  (top-dispatch request))

(module+ main
  (serve/servlet start ...))

(module+ test
 
  (define (test-start-servlet)

(define experiment-servlet-tester
  (make-servlet-tester start))

; Test all the routes. This only tests that they don't raise exceptions
(define routes 
  (list 
'()   ; Tests "/"
'("/login")
'("/mp")
))

(for ([route routes])
  (check-not-exn (λ () (apply experiment-servlet-tester route

(define matrix-servlet-tester
  (make-servlet-tester (λ (req)
  (matrix req #:h (hash 'mturk-id "TESTER")

(matrix-servlet-tester)

(displayln "All pages render without exception"))

  (test-start-servlet))


The meat of what is going on is in the test module at the end. I create a 
servlet-tester for the start servlet, which uses a dispatcher, and since I 
have a bunch of routes I go through them in a for-loop. However, even 
though the "/login" route throws an exception, the (test-start-servlet) 
code is happily marching on, checks the "/mp" route, and then prints "All 
pages render without exception". And raco test tells me that all the tests 
are passing!

How do I know that there is an exn? Because it prints the following right 
before the test results:

Servlet (@ /372d34a3-df04-478f-8d84-94fb212725c2) exception:
>: contract violation
  expected: real?
  given: #
  argument position: 1st
  other arguments...:
   0


So, what is going on here? Clearly test-servet does some exception catching 
in between, yet it still prints it to the screen? How can I test for this, 
since I want to know how many and which pages blow up?

Also, when I want to test matrix at the end, I have to pass it an extra 
argument. Is it the right way of passing in the argument by defining a new 
servlet where I set the argument to some fixed value, as I do above via: 

(define matrix-servlet-tester
  (make-servlet-tester (λ (req)
  (matrix req #:h (hash 'mturk-id "TESTER")

It seems to work, but I am wondering if I can pass arguments directly to 
`make-servlet-tester`, but I couldn't figure out how.

Thanks,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/a7ae5893-5bdd-4b3f-924a-42e4936d2a68%40googlegroups.com.


Re: [racket-users] How to disable back button in web application

2019-09-21 Thread Marc Kaufmann
I haven't had the time to test it, but I am wondering if  calling
(clear-continuations-table!) which send/forward does will delete all
continuations, even those of other users. So suddenly links that other
users want to use will also get wiped out. I probably won't have time to
test today, but will check later. (I actually don't know how
clear-continuations-table! could delete only continuations of the current
user, since it can't know about users - so my guess is that this will not
work.)

On Sat, Sep 21, 2019 at 10:05 AM Marc Kaufmann 
wrote:

> Could I use the send/forward to essentially disable forms if I use as the
> `action` attribute on the form an (embed-url ...), which will no longer
> work later on? This will probably through an error if people do the 'Go
> back, resubmit' cycle, but I don't mind throwing an error on that, rather
> than gracefully failing. I'm not going to win any design contests that way,
> but solve a problem without dealing with any database interactions.
>
> On Fri, Sep 20, 2019 at 2:03 PM Jens Axel Søgaard 
> wrote:
>
>> Den fre. 20. sep. 2019 kl. 13.51 skrev Marc Kaufmann <
>> marc.kaufman...@gmail.com>:
>>
>>> Thanks Jens, yes the send/forward seems to at least address a few of the
>>> cases that I have - not sure if it disallows the forms unless I use
>>> continuations in the forms (right now I am not, mostly just sending the
>>> request to the current URL. I'll have to see.
>>>
>>> Yes, I worked through and read the Continue tutorial a few times and use
>>> redirect/get to work around the double submit error. But -- I think -- the
>>> redirect/get only avoids something like refreshing the page from leading to
>>> a new submit, although I may be wrong. I thought I used it in some places
>>> where I was able to go back and resubmit. I should double check, since I am
>>> not using redirect/get everywhere, so that may be the issue.
>>>
>>
>> Yes, the redirect trick only prevents the same data (as the result of a
>> "submit" action) being sent twice.
>> If the user goes back to the form, fills in the form again and the click
>> submit again, a new set
>> of data is sent.
>>
>> If you need to prevent the same form being filled in twice, you could
>> associate a key as
>> a hidden form value (say the md5 of a counter) and keep track in a
>> database of which keys
>> have already been used.
>>
>> To prevent the key table from getting too large, you can flip it around:
>> keep the non-used keys in the
>> database, then on submission remove the key. If you also store the age of
>> the key, you can
>> from time to time delete old keys.
>>
>> /Jens Axel
>>
>>
>>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO5WnvJ3FKVofUohEW4hvY4TnOMFW4KuJaZ7CsA9S%2Bc27w%40mail.gmail.com.


Re: [racket-users] How to disable back button in web application

2019-09-21 Thread Marc Kaufmann
Could I use the send/forward to essentially disable forms if I use as the
`action` attribute on the form an (embed-url ...), which will no longer
work later on? This will probably through an error if people do the 'Go
back, resubmit' cycle, but I don't mind throwing an error on that, rather
than gracefully failing. I'm not going to win any design contests that way,
but solve a problem without dealing with any database interactions.

On Fri, Sep 20, 2019 at 2:03 PM Jens Axel Søgaard 
wrote:

> Den fre. 20. sep. 2019 kl. 13.51 skrev Marc Kaufmann <
> marc.kaufman...@gmail.com>:
>
>> Thanks Jens, yes the send/forward seems to at least address a few of the
>> cases that I have - not sure if it disallows the forms unless I use
>> continuations in the forms (right now I am not, mostly just sending the
>> request to the current URL. I'll have to see.
>>
>> Yes, I worked through and read the Continue tutorial a few times and use
>> redirect/get to work around the double submit error. But -- I think -- the
>> redirect/get only avoids something like refreshing the page from leading to
>> a new submit, although I may be wrong. I thought I used it in some places
>> where I was able to go back and resubmit. I should double check, since I am
>> not using redirect/get everywhere, so that may be the issue.
>>
>
> Yes, the redirect trick only prevents the same data (as the result of a
> "submit" action) being sent twice.
> If the user goes back to the form, fills in the form again and the click
> submit again, a new set
> of data is sent.
>
> If you need to prevent the same form being filled in twice, you could
> associate a key as
> a hidden form value (say the md5 of a counter) and keep track in a
> database of which keys
> have already been used.
>
> To prevent the key table from getting too large, you can flip it around:
> keep the non-used keys in the
> database, then on submission remove the key. If you also store the age of
> the key, you can
> from time to time delete old keys.
>
> /Jens Axel
>
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO5-Cz0HNMCa78rDRyRgRyNbW1C2GdFOEg-eSaSyX1XiKA%40mail.gmail.com.


Re: [racket-users] How to disable back button in web application

2019-09-20 Thread Marc Kaufmann
Thanks Jens, yes the send/forward seems to at least address a few of the
cases that I have - not sure if it disallows the forms unless I use
continuations in the forms (right now I am not, mostly just sending the
request to the current URL. I'll have to see.

Yes, I worked through and read the Continue tutorial a few times and use
redirect/get to work around the double submit error. But -- I think -- the
redirect/get only avoids something like refreshing the page from leading to
a new submit, although I may be wrong. I thought I used it in some places
where I was able to go back and resubmit. I should double check, since I am
not using redirect/get everywhere, so that may be the issue.

Cheers,
Marc

On Fri, Sep 20, 2019 at 1:38 PM Stephen De Gabrielle <
spdegabrie...@gmail.com> wrote:

> Maybe also relevant
>
>
> https://docs.racket-lang.org/continue/index.html#%28part._.The_.Double_.Submit_.Error%29
>
> The whole Continue tutorial is worth the time spent.
>
> s.
>
>
> On Fri, Sep 20, 2019 at 12:32 PM Jens Axel Søgaard 
> wrote:
>
>> Is `send/forward` what you need?
>>
>> Den fre. 20. sep. 2019 kl. 11.43 skrev Marc Kaufmann <
>> marc.kaufman...@gmail.com>:
>>
>>> Hi all,
>>>
>>> disclaimer: I am guessing that my current design simply doesn't allow me
>>> (easily) what I want, but there may be a solution I am unaware of.
>>>
>>> In my Racket-powered website I want to disable the back button or keep
>>> people from using the back button to resubmit (with different data) a
>>> previous form or hit a link that is an embedded continuation to a function
>>> that should not be called twice.
>>>
>>> One way I can do this is to set some variable in the database when the
>>> form is submitted or one of several links clicked on a page and check
>>> whether it already is set and disallow new submits (or some such). However,
>>> I want to do this in many places and don't want to sprinkle all my code and
>>> database with names that I can't track. I tried to achieve this by defining
>>> a new variable in the request itself that I set to #false initially and
>>> then set! to true when any link is hit -- but this fails if a person comes
>>> back, refreshes the page and clicks the link, since this creates a new
>>> instance of the variable.
>>>
>>> Qualtrics surveys have this feature, but the way they implement it is (I
>>> think) by being single-page apps where the 'Next' button loads the new page
>>> content via an Ajax call. I don't see how to turn my current website into
>>> that without substantial rewrites.
>>>
>>> Cheers,
>>> Marc
>>>
>>> --
>>> 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.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/racket-users/7e356eb4-e886-4f9c-90cd-0db658d14a91%40googlegroups.com
>>> <https://groups.google.com/d/msgid/racket-users/7e356eb4-e886-4f9c-90cd-0db658d14a91%40googlegroups.com?utm_medium=email_source=footer>
>>> .
>>>
>>
>>
>> --
>> --
>> Jens Axel Søgaard
>>
>> --
>> 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.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/racket-users/CABefVgzmMJMrqjAF4JXJU7txX9hU5HWBrfREP915j8ggi%3Dmt5w%40mail.gmail.com
>> <https://groups.google.com/d/msgid/racket-users/CABefVgzmMJMrqjAF4JXJU7txX9hU5HWBrfREP915j8ggi%3Dmt5w%40mail.gmail.com?utm_medium=email_source=footer>
>> .
>>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO6daWvM0Qy4dPMgNsuyfUD990xtKJNEv7WiwNniYUYwXw%40mail.gmail.com.


[racket-users] How to disable back button in web application

2019-09-20 Thread Marc Kaufmann
Hi all,

disclaimer: I am guessing that my current design simply doesn't allow me 
(easily) what I want, but there may be a solution I am unaware of. 

In my Racket-powered website I want to disable the back button or keep 
people from using the back button to resubmit (with different data) a 
previous form or hit a link that is an embedded continuation to a function 
that should not be called twice. 

One way I can do this is to set some variable in the database when the form 
is submitted or one of several links clicked on a page and check whether it 
already is set and disallow new submits (or some such). However, I want to 
do this in many places and don't want to sprinkle all my code and database 
with names that I can't track. I tried to achieve this by defining a new 
variable in the request itself that I set to #false initially and then set! 
to true when any link is hit -- but this fails if a person comes back, 
refreshes the page and clicks the link, since this creates a new instance 
of the variable. 

Qualtrics surveys have this feature, but the way they implement it is (I 
think) by being single-page apps where the 'Next' button loads the new page 
content via an Ajax call. I don't see how to turn my current website into 
that without substantial rewrites. 

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/7e356eb4-e886-4f9c-90cd-0db658d14a91%40googlegroups.com.


Re: [racket-users] What is a (the?) way to track requirements for a web or app with Racket?

2019-09-16 Thread Marc Kaufmann
So the easiest to do is to create such an info.rkt file and call `raco pkg
install app-name/` -- and that should work even if I don't do the `raco
exe` and `raco distribute`?

On Mon, Sep 16, 2019 at 11:04 AM Bogdan Popa  wrote:

>
> Marc Kaufmann writes:
>
> > this is surely answered somewhere, but I have not made much progress. If
> > you know python, what I want to do is essentially
> >
> > $ pip install requirements.txt
> >
>
> Although it's not exactly the same thing, I use `info.rkt'[1][2]
> (similar to `setup.py') for this purpose and each one of
> my web apps is its own package.
>
> Here's an example of what that ends up looking like:
>
>
> https://github.com/Bogdanp/koyo/blob/master/koyo-lib/blueprints/standard/app-name-here/info.rkt
>
> and
>
>
> https://github.com/Bogdanp/koyo/tree/master/koyo-lib/blueprints/standard#first-time-setup
>
> For deployment, I leverage `raco exe' and `raco distribute' to create
> self-contained distributions that I can ship to my server.
>
> [1]: https://docs.racket-lang.org/pkg/metadata.html
> [2]: https://docs.racket-lang.org/raco/setup-info.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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO5C%3DtuQr0%2BgS5mVe8cjNDr-9bg2KxR7203kwCtdqphodQ%40mail.gmail.com.


[racket-users] What is a (the?) way to track requirements for a web or app with Racket?

2019-09-16 Thread Marc Kaufmann
Hi,

this is surely answered somewhere, but I have not made much progress. If 
you know python, what I want to do is essentially 

$ pip install requirements.txt

where requirements.txt has a list (one per line) of packages and their 
versions to install (usually installed into a virtual environment). I am 
pretty certain that I can do this with raco setup or raco pkg or raco ... 
but I can't figure out how to do it. Essentially I want to avoid having to 
run 

raco pkg install forms
raco pkg install ...
raco pkg install ...

which is what I currently do. What is the most vanilla way of doing this? 
Most of the threads I found were about bundling whole apps or packages, 
which I would think is different from what I want, although I am not sure. 
I guess I could do this via Ansible, which is how I do most of these 
things, but it seems there should be a better way (and Ansible won't know 
if something is already installed or not, just dumbly run the command).

Also, if anyone knows of a good blog/tutorial on this kind of 
sysadmin/devops/deploy side of things in Racket, I'd love to know about it. 

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/087f5a89-321a-40ac-adc9-3d7a59f2db71%40googlegroups.com.


Re: [racket-users] vi-mode for racket cli

2019-09-13 Thread Marc Kaufmann
Since I had to look up this thread again, I wanted to mention that there is 
a way to avoid downloading readline-gpl. By default, the repl uses 
editline, which also has a way of switching on vi (or emacs) modes. Just 
edit/create the ~/.editrc file:

bind -v
bind "jj" vi-command-mode

and you have vi-mode with jj letting you escape into command mode.

On Monday, April 15, 2019 at 10:55:04 AM UTC+2, Marc Kaufmann wrote:
>
> Fantastic, that was faster and easier than I thought! So nice to not 
> constantly mess up all my commands any more... A good start to a new week. 
> :-)
>
> Cheers,
> Marc
>
>
> Ha, thanks. I should have searched the docs for readline, not for vi-mode 
>> and vi mode. I'll let you know how it goes.
>>
>> Marc
>>
>> On Mon, Apr 15, 2019 at 10:30 AM Tom Gillespie <...> wrote:
>>
>>> I'm not sure if this will fix your vi-mode issues, but here is some info 
>>> on the readline situation. You should be able to get readline support by 
>>> installing readline-gpl via `raco pkg install readline-gpl` (as the name 
>>> suggests it was removed from core racket due to gpl compatibility 
>>> concerns).  Some additional info in the docs 
>>> <https://docs.racket-lang.org/readline/index.html>, with an additional 
>>> note that `racket -il xrepl` is another way to start racket with readline 
>>> support (once you have readline-gpl installed). Best!
>>> Tom
>>>
>>>
>>> On Mon, Apr 15, 2019 at 1:20 AM Marc Kaufmann <> wrote:
>>>
>>>> Hi all,
>>>>
>>>> I use vi-mode in the cli and in all the repls that use readline. 
>>>> Racket's repl does not use readline for reading. Is there a way to get 
>>>> vi-mode going anyway, either by wrapping readline around first or 
>>>> something 
>>>> else? And if it's possible, would this require switching off something 
>>>> else 
>>>> that is really important to have in the REPL?
>>>>
>>>> I hope someone else figured this one out before.
>>>>
>>>> Cheers,
>>>> Marc
>>>>
>>>> -- 
>>>> 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/510e3caf-256b-400f-bfce-c74093930aff%40googlegroups.com.


[racket-users] Amazon Mechanical Turk library/package in racket

2019-09-11 Thread Marc Kaufmann
Hi all,

I was wondering if there is a Racket library that makes it easy to 
interface with Amazon's Mechanical Turk interface 
(https://docs.aws.amazon.com/AWSMechTurk/latest/AWSMturkAPI/Welcome.html) 
and if anyone has some code lying around on how to do so? I know that there 
is the aws package by Greg, but I couldn't figure out if it also makes it 
easier to do the MTurk stuff or not. Since this involves payments, I don't 
want to do much experimentation to see if it works.

If not, no worries - I think that I solved it by doing it in R the last 
time round, which was not too painful. 

Cheers,
Marc

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/b70d0e44-191a-423b-a200-82a31a44a713%40googlegroups.com.


Re: [racket-users] vi-mode for racket cli

2019-04-15 Thread Marc Kaufmann
Fantastic, that was faster and easier than I thought! So nice to not
constantly mess up all my commands any more... A good start to a new week.
:-)

Cheers,
Marc

On Mon, Apr 15, 2019 at 10:51 AM Marc Kaufmann 
wrote:

> Ha, thanks. I should have searched the docs for readline, not for vi-mode
> and vi mode. I'll let you know how it goes.
>
> Marc
>
> On Mon, Apr 15, 2019 at 10:30 AM Tom Gillespie  wrote:
>
>> I'm not sure if this will fix your vi-mode issues, but here is some info
>> on the readline situation. You should be able to get readline support by
>> installing readline-gpl via `raco pkg install readline-gpl` (as the name
>> suggests it was removed from core racket due to gpl compatibility
>> concerns).  Some additional info in the docs
>> <https://docs.racket-lang.org/readline/index.html>, with an additional
>> note that `racket -il xrepl` is another way to start racket with readline
>> support (once you have readline-gpl installed). Best!
>> Tom
>>
>>
>> On Mon, Apr 15, 2019 at 1:20 AM Marc Kaufmann 
>> wrote:
>>
>>> Hi all,
>>>
>>> I use vi-mode in the cli and in all the repls that use readline.
>>> Racket's repl does not use readline for reading. Is there a way to get
>>> vi-mode going anyway, either by wrapping readline around first or something
>>> else? And if it's possible, would this require switching off something else
>>> that is really important to have in the REPL?
>>>
>>> I hope someone else figured this one out before.
>>>
>>> Cheers,
>>> Marc
>>>
>>> --
>>> 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] vi-mode for racket cli

2019-04-15 Thread Marc Kaufmann
Ha, thanks. I should have searched the docs for readline, not for vi-mode
and vi mode. I'll let you know how it goes.

Marc

On Mon, Apr 15, 2019 at 10:30 AM Tom Gillespie  wrote:

> I'm not sure if this will fix your vi-mode issues, but here is some info
> on the readline situation. You should be able to get readline support by
> installing readline-gpl via `raco pkg install readline-gpl` (as the name
> suggests it was removed from core racket due to gpl compatibility
> concerns).  Some additional info in the docs
> <https://docs.racket-lang.org/readline/index.html>, with an additional
> note that `racket -il xrepl` is another way to start racket with readline
> support (once you have readline-gpl installed). Best!
> Tom
>
>
> On Mon, Apr 15, 2019 at 1:20 AM Marc Kaufmann 
> wrote:
>
>> Hi all,
>>
>> I use vi-mode in the cli and in all the repls that use readline. Racket's
>> repl does not use readline for reading. Is there a way to get vi-mode going
>> anyway, either by wrapping readline around first or something else? And if
>> it's possible, would this require switching off something else that is
>> really important to have in the REPL?
>>
>> I hope someone else figured this one out before.
>>
>> Cheers,
>> Marc
>>
>> --
>> 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] vi-mode for racket cli

2019-04-15 Thread Marc Kaufmann
Hi all,

I use vi-mode in the cli and in all the repls that use readline. Racket's 
repl does not use readline for reading. Is there a way to get vi-mode going 
anyway, either by wrapping readline around first or something else? And if 
it's possible, would this require switching off something else that is 
really important to have in the REPL?

I hope someone else figured this one out before.

Cheers,
Marc

-- 
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] Struct subtype with default/fixed value of super-type

2019-03-18 Thread Marc Kaufmann
While I did know that I could define my own, I was going to do it while
providing-out another function make-fish and make-shark, but it's nice to
know that this allows me to locally define make-fish, while it looks to the
outside like (fish ...).

Thanks to including sufficient numbers of mundane bugs in my code (all
well-maintained in version control, for quick deployment on docker), I
rarely get to worry about phases - it just isn't where the highest gains
are. :-)

On Mon, Mar 18, 2019 at 2:46 PM Jérôme Martin 
wrote:

> Once you discover that the default constructor for a struct is just a
> simple procedure that was generated for you, it's not that big of deal to
> just make your own and export it like this:
>
> (provide
>   (except-out (struct-out fish) fish)
>   (rename-out (make-fish fish)))
>
> All the code relying on it will still work.
> Except I guess if you pass through different phase levels, it becomes a
> bit more complicated because you have a syntax attached at compile-time to
> the identifier. But that's another issue.
> Correct me if I'm wrong.
>
> On Monday, March 18, 2019 at 2:11:46 PM UTC+1, Marc Kaufmann wrote:
>>
>> Yes, I saw that, the problem is that I want to be able to set a
>> (potentially different) default value for the sub-type shark than for the
>> sub-type guppy. So if I set the value to 'big for all `fish`, then I can't
>> do that. Essentially, I'd need an #:auto for every sub-type, but the #:auto
>> refers to a parent/super field.
>>
>> I'll just run with defining a custom constructor.
>>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Racket Users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/racket-users/TthsE0FZDB0/unsubscribe.
> To unsubscribe from this group and all its topics, 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] Struct subtype with default/fixed value of super-type

2019-03-18 Thread Marc Kaufmann
Yes, I saw that, the problem is that I want to be able to set a
(potentially different) default value for the sub-type shark than for the
sub-type guppy. So if I set the value to 'big for all `fish`, then I can't
do that. Essentially, I'd need an #:auto for every sub-type, but the #:auto
refers to a parent/super field.

I'll just run with defining a custom constructor.

On Sat, Mar 16, 2019 at 8:24 AM Luis Sanjuán 
wrote:

> Maybe #:auto/#:auto-value is what you want:
>
> ```
> (struct fish (name [size #:auto])
>   #:auto-value 'big
>   #:transparent)
> (struct shark fish (scares-people?) #:transparent)
>
> (define white-shark (shark "The big white" #t))
> ```
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Racket Users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/racket-users/TthsE0FZDB0/unsubscribe.
> To unsubscribe from this group and all its topics, 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] How to launch image display from racket REPL?

2019-03-16 Thread Marc Kaufmann
Yep, that works. 

How could I have googled this or found this solution? Or did you simply 
know this before? I tried for 15 minutes without success, trying 'display 
image repl' and variations on it (canvas, cli, repl).

On Saturday, March 16, 2019 at 3:59:02 PM UTC+1, Philip McGrath wrote:
>
> Here's one way:
>
> Welcome to Racket v7.2.
> > (require 2htdp/image racket/gui/base (only-in pict show-pict))
> > (show-pict (empty-scene 100 100))
>
> (The require of racket/gui/base seems to be needed for side-effect only, 
> to prevent a "racket/gui/base is not available" error. That seems like it 
> might be a bug.)
>
> -Philip
>
>
> On Sat, Mar 16, 2019 at 10:48 AM Marc Kaufmann  > wrote:
>
>> Hi, 
>>
>> I am playing around with big-bang in 2htdp/universe and images in 
>> 2htdp/image. When I launch big-bang from racket on the cli (not DrRacket), 
>> it does somehow call a window and display the images with my render 
>> function. However, when I want to test the render functions, I want to run 
>> them separately in the cli, but can't figure out how to display images 
>> there. All I get is:
>>
>> > (require 2htdp/image)
>> > (empty-scene 100 100)
>> > (object:image% ...)
>>
>> How do I open a window from the repl on which I either continuously 
>> render again and again, or for each image a new such window is opened? How 
>> does big-bang do it - that is maybe the way I should do it too?
>>
>> Thanks,
>> Marc
>>
>> -- 
>> 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...@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] How to launch image display from racket REPL?

2019-03-16 Thread Marc Kaufmann
Hi, 

I am playing around with big-bang in 2htdp/universe and images in 
2htdp/image. When I launch big-bang from racket on the cli (not DrRacket), 
it does somehow call a window and display the images with my render 
function. However, when I want to test the render functions, I want to run 
them separately in the cli, but can't figure out how to display images 
there. All I get is:

> (require 2htdp/image)
> (empty-scene 100 100)
> (object:image% ...)

How do I open a window from the repl on which I either continuously render 
again and again, or for each image a new such window is opened? How does 
big-bang do it - that is maybe the way I should do it too?

Thanks,
Marc

-- 
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] Struct subtype with default/fixed value of super-type

2019-03-15 Thread Marc Kaufmann
Hi all,

suppose I have a struct `(struct fish (size name) #:transparent)` and a 
sub-type `(struct shark fish (scares-people?) #:transparent)`. What if I 
want all sharks to have size 'large by default whenever I create one, so 
that I create them via:

(define white-shark (shark "The big white" #t))

rather than 

(define white-shark (shark 'big "The big white" #t))

Is that possible to do, other than defining my own wrapper? If it is not 
possible with the current structures, I guess it would be bad practice to 
overwrite the `shark` constructor, and rather create a `my-shark` 
constructor to avoid (hypothetical) reader of my code wouldn't get confused.

Best,
Marc

-- 
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 fix typos in documentation?

2019-03-09 Thread Marc Kaufmann
I agree with Greg that such a feature would be neat - so it's great that
Ben and Kieran are on it already. (Thanks!)

The CONTRIBUTING.md is a good idea (and I David's version). The 'Edit on
Github' button would solve the first stumbling block I hit, while the
contribution.md file helps later in the process.

Cheers,
Marc

On Fri, Mar 8, 2019 at 10:55 PM Ben Greenman 
wrote:

> On 3/8/19, David Storrs  wrote:
> > On Fri, Mar 8, 2019 at 3:13 PM Greg Hendershott <
> greghendersh...@gmail.com>
> > wrote:
> >
> >> I have a dumb question. Why can't doc pages have links whose label is
> >> something like "Want to improve the docs?", and the URL goes directly
> >> to the appropriate .scrbl file on GitHub?
> >>
> >
> > I asked about this a year or so ago and the consensus was that it was
> > impractically difficult given the number of tuits that were available at
> > the time.  IIRC, it would have required significant changes to the
> > documentation generation system.  Perhaps I'm misremembering, or perhaps
> > that's changed?
>
> Here's a Scribble issue about adding links to the doc pages:
>
> https://github.com/racket/scribble/issues/76
>
>
> And here's a Scribble branch that Kieran Hardy and I started (at
> RacketCon 2017) to add the links:
>
> https://github.com/bennn/scribble/commits/view-source
>
> Next month I'll try to turn the branch into a pull request. If someone
> wants to take the lead this month, feel free.
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Racket Users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/racket-users/J8ylMGGGr-8/unsubscribe.
> To unsubscribe from this group and all its topics, 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] How to fix typos in documentation?

2019-03-08 Thread Marc Kaufmann
 "Fixes #2518".
- The latter part means that I claim that this fixes issue number 2518.
I believe that GitHub automatically understands this and if my pull request
gets accepted, the issue should automatically be closed.
- I had opened that issue a little earlier, and that's how I found out
from Sam what the correct link/path is.
- Hit "Propose file change"
- On the next page, hit "create pull request"
- Sit back and wait until your PR gets accepted, rejected, or you are asked
for amendments.

Now, suppose that one of the maintainers asks you to change something in
your PR. After bursting into hysterical laughter (or tears, depending on
temperament), you give it a shot:

- Go to the pull requests (https://github.com/racket/racket/pulls) and find
your pull request.
- Choose 'commits' at the top
- Click on the commit (there seem to be 5 different ways of doing this)
- It shows the actual patch/diff/change that your early commit did
- Click the pen (Edit) button to "change this file in the online editor"
- This way your earlier changes from the earlier commit (or commits) are
there
- Fix whatever needs fixing, add commit message and comment, hit 'commit
changes'
- Done (maybe)

Submitting issues:

- So you don't know where the broken link should point to and decide to
open an issue.
- Go to racket/racket, click on 'Issues' at the top, click on 'New Issue'
(green button on the right at the time of writing)
- Add an issue message, e.g. "Broken link in docs"; Github will tell you
that this looks like other issues and ask you to make sure it's not the
same. Check it isn't.
- Get the link to the part of the code that needs fixing. For this, I went
to the file I knew had to be fixed from the earlier search
- I went to
https://github.com/racket/racket/blob/5bb837661c12a9752c6a99f952c0e1b267645b33/pkgs/racket-doc/scribblings/style/testing.scrbl
and clicked on the line number 19 since the typo was in line 19.
- This made a [...] field appear on the left of the line. Click on it,
choose "Copy permalink".
- Paste this permalink into the comment part of the issue that is still
open in another tab. Check via preview that it shows the correct file and
line.
- Write something clear and snappy, e.g. "I found this link and it seems
broken. I don't know where it should point though."
- Hit submit

Quickly log off your computer before anyone can tell you how to fix the
issue yourself! Otherwise, the above at least tells you how you can submit
that PR, another Issue, leading to another PR... turtles all the way down.

Cheers,
Marc

PS: This was so utterly painful to write up. If someone knows of tools to
record workflows online, that would be really nice. Writing isn't really
the right interface to provide this knowledge, but I find videos not that
useful either.

On Thu, Mar 7, 2019 at 2:05 PM Marc Kaufmann 
wrote:

> Ergh, of course I forgot to do that part. Thanks for catching that.
>
> On Thu, Mar 7, 2019 at 1:59 PM Paulo Matos  wrote:
>
>>
>>
>> On 07/03/2019 13:40, Marc Kaufmann wrote:
>> > Thanks Paulo, this is way better than the workflow I used the only other
>> > time I made a PR. The only thing I had to do was choose a branch to
>> > commit to: I chose 'master', mostly because I have no clue what else I
>> > would have chosen. What is the default to contribute to?
>> >
>> > It was in scribblings by the way.
>> >
>>
>> OK, I found you.
>> https://github.com/MarcKaufmann/racket/tree/patch-1
>>
>> As you can see, github created the patch-1 branch correctly and your fix
>> is there. You should see now a button in green saying 'Create New Pull
>> Request'.
>>
>> Then it should show something like:
>>
>> racket/racket master <- MarcKaufmann/racket patch-1
>>
>> on top. Press create pull request and it will create a pull request in
>> racket/racket for master, based on your patch-1 branch changes.
>>
>> I would then expect to see a PR from you here:
>> https://github.com/racket/racket/pulls
>>
>> --
>> Paulo Matos
>>
>

-- 
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 fix typos in documentation?

2019-03-07 Thread Marc Kaufmann
Ergh, of course I forgot to do that part. Thanks for catching that.

On Thu, Mar 7, 2019 at 1:59 PM Paulo Matos  wrote:

>
>
> On 07/03/2019 13:40, Marc Kaufmann wrote:
> > Thanks Paulo, this is way better than the workflow I used the only other
> > time I made a PR. The only thing I had to do was choose a branch to
> > commit to: I chose 'master', mostly because I have no clue what else I
> > would have chosen. What is the default to contribute to?
> >
> > It was in scribblings by the way.
> >
>
> OK, I found you.
> https://github.com/MarcKaufmann/racket/tree/patch-1
>
> As you can see, github created the patch-1 branch correctly and your fix
> is there. You should see now a button in green saying 'Create New Pull
> Request'.
>
> Then it should show something like:
>
> racket/racket master <- MarcKaufmann/racket patch-1
>
> on top. Press create pull request and it will create a pull request in
> racket/racket for master, based on your patch-1 branch changes.
>
> I would then expect to see a PR from you here:
> https://github.com/racket/racket/pulls
>
> --
> Paulo Matos
>

-- 
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 fix typos in documentation?

2019-03-07 Thread Marc Kaufmann
Thanks Paulo, this is way better than the workflow I used the only other
time I made a PR. The only thing I had to do was choose a branch to commit
to: I chose 'master', mostly because I have no clue what else I would have
chosen. What is the default to contribute to?

It was in scribblings by the way.

Cheers,
Marc

On Thu, Mar 7, 2019 at 12:02 PM 'Paulo Matos' via Racket Users <
racket-users@googlegroups.com> wrote:

>
>
> On 07/03/2019 11:55, Marc Kaufmann wrote:
> > Hi,
> >
> > I just came across a typo in the documentation and was about to move on
> > simply because I couldn't be bothered to figure out how/where to change
> > it. I couldn't find the docs in the github repo (I searched for doc, and
> > looked under racket-lang-org without success).
> >
> > Also, is there a guide on best practice for pull requests or
> > contributions, including a "Fork this, do that, push like that, etc"? I
> > have no idea, usually just fork the whole thing, but don't know how to
> > keep it up-to-date. Pointers to Racket-agnostic resources very welcome.
> > Thanks,
> > Marc
> >
> > PS: I am purposefully not saying where the typo is so that I will have
> > to go and fix it, rather than have someone else fix it.
> >
>
> Where the documentation is, depends on where the typo is. Is it in the
> Guide, Reference, somewhere else?
>
> Go to https://github.com/racket/racket
> then search for the typo in the github search box and select 'in this
> repository'.
>
> Found it, great? No? Maybe the docs are somewhere else. Does it belong
> to one of the libraries in pkgs.racket-lang.org? To scribble?
>
> Once you found it, the easiest thing for a typo is to find the file in
> github, then edit straight in github. It will automatically fork the
> project. Then you can edit the file, fixing the typo and commit. Open PR
> straight after that. Someone will come and merge the PR. :) If you need
> step-by-step help feel free to pvt me in Slack.
>
> Enjoy the ultimate pleasure of committing to the racket repo, go get
> that chocolate bar you deserve!
>
> --
> Paulo Matos
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Racket Users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/racket-users/J8ylMGGGr-8/unsubscribe.
> To unsubscribe from this group and all its topics, 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] How to fix typos in documentation?

2019-03-07 Thread Marc Kaufmann
Hi,

I just came across a typo in the documentation and was about to move on 
simply because I couldn't be bothered to figure out how/where to change it. 
I couldn't find the docs in the github repo (I searched for doc, and looked 
under racket-lang-org without success). 

Also, is there a guide on best practice for pull requests or contributions, 
including a "Fork this, do that, push like that, etc"? I have no idea, 
usually just fork the whole thing, but don't know how to keep it 
up-to-date. Pointers to Racket-agnostic resources very welcome.
Thanks,
Marc

PS: I am purposefully not saying where the typo is so that I will have to 
go and fix it, rather than have someone else fix it.

-- 
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 do you make students submit programming assignments online for automatic tests?

2019-02-20 Thread Marc Kaufmann
Hi all,

I will be teaching a course on data analysis in R next year (September), 
and may at some point add some Racketeering to my other courses (maybe), 
and I was wondering how those of you who teach programming classes deal 
with programming assignments. Are there somewhat language-independent 
platforms for having students submit assignments that have to pass a bunch 
of pre-specified tests, or would I need to look at what is available for 
any given platform? Any security issues I should be aware of?

All recommendations welcome,

Marc

-- 
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] web-server/http documentation: "You are unlikely to need to construct a request struct." Why?

2019-02-20 Thread Marc Kaufmann
OK, so there is no reason for me to leave the racket world for that type of
tests. Thanks.

On Wed, Feb 20, 2019 at 4:25 PM Jay McCarthy  wrote:

> On Wed, Feb 20, 2019 at 10:23 AM Marc Kaufmann
>  wrote:
> > I came across this statement regarding structure request in the
> documentation: "You are unlikely to need to construct a request struct."
> (See here.)
> >
> > Why does it say this? I want to generate requests (in one form or
> another) for functional tests of my website. Should I use curl for that?
> And is the rationale something to do with security?
>
> What you want to do is basically the only use case for making
> requests. That's why it says this. Sometime people think that they can
> make request structures and use that with something like
> net/http-client to make a request to a site. That's not what they are
> for.
>
> Jay
>
> --
> -=[ Jay McCarthy   http://jeapostrophe.github.io]=-
> -=[ Associate ProfessorPLT @ CS @ UMass Lowell ]=-
> -=[ Moses 1:33: And worlds without number have I created; ]=-
>

-- 
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] web-server/http documentation: "You are unlikely to need to construct a request struct." Why?

2019-02-20 Thread Marc Kaufmann
Hi all,

I came across this statement regarding structure request in the 
documentation: "You are unlikely to need to construct a request struct." 
(See here 

.)

Why does it say this? I want to generate requests (in one form or another) 
for functional tests of my website. Should I use curl for that? And is the 
rationale something to do with security?

Thanks,
Marc

-- 
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: How To Design Classes text not available?

2019-02-04 Thread Marc Kaufmann
Thanks for that nifty tip for quick bookmarking Neil. 

Quick Searches: 
>
> Name: [SEARCH] DUCKDUCKGO 
> Location: https://start.duckduckgo.com/?q=%s=hb=-2=web 
> Keyword: d 
>
>
For anyone else who might want it (but not quite know how): the way I got 
it going was 

1. Go do some search with the search bar of the website you want, search 
anything you like, e.g. https://web.archive.org/web/*/breakdance
2. Bookmark that link
3. Go find your bookmark in the list of bookmarks (for me the "|||\" sign 
on the right of the search bar)
4. Right-click on the recently added bookmark to get "Properties"
5. Now replace the "breakdance" by %s
6. Add the "a " as keyword

Just adding this as it took me some time googling (well, duckduckgo-ing) 
this (I couldn't figure out how to find 'properties' on bookmarks). It 
works with every website that has a search with URL parameters. 

Cheers,

Marc


Name: [SEARCH] DUCKDUCKGO IMAGES 
> Location: 
> https://start.duckduckgo.com/?q=%s=hb=-2=images=images 
> Keyword: di 
>
> BTW, on the desktop, the browser operation to make new tab (Ctrl-T on my 
> computer), with your new tab page set to blank, is a way to quickly both 
> get a new browser tab without possibly disturbing something else, and to 
> put your GUI text focus on the location bar do your next keystroke 
> starts your Quick Search, autocomplete of your bookmarks, or a 
> URL/domain.  No "new tab" or "search" or "home" page load, no separate 
> search field widget taking up space that could show URL or slowing down 
> the UI, no gratuitous/paid leaking. 
>
> >   (turns out !a goes to amazon, sigh). 
>
> I took away my old "a" Quick Search keyword from Amazon, to give to 
> Archive.org.  Individual users can still have some power over the 
> computation they use. :) 
>
>

-- 
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] side by side; scribble

2019-01-30 Thread Marc Kaufmann
Ah, I misunderstood the synchronization to be about synchronization in time
between source and typeset output, while the question was about
synchronizing two outputs that are typeset from the same source next to
each other. My bad. However, I couldn't find anything on one-vs-two columns
other than the SIGPLAN option @onecolumn. When you say that I need to add
those commands, you mean I should define them in scribble or pass them as
templates for a given output (say two-column output in HTML or Latex)?

I had been wondering if there is something where, side-by-side, you have
the editor to enter scribble on the left, and on the right it updates as I
type (or once I complete a command) scribble's typesetting. Similar to the
(near-automatic) preview on Discourse (
https://blog.discourse.org/2016/12/discourse-new-user-tips-and-tricks/ go
down to "Reply"). I now realize that's not there, but I thought that was
what you meant with the two-columns thing -- and spent 30 minutes figuring
out where that is.

On Wed, Jan 30, 2019 at 2:44 PM Robby Findler 
wrote:

> No it does not require that, if I am understanding you correctly. You just
> need to add the two-column specific commands and use them, as appropriate.
>
> Robby
>
> On Wed, Jan 30, 2019 at 1:57 AM Marc Kaufmann 
> wrote:
>
>> Since you say that it requires dropping to the latex level, does it mean
>> that doing a synchronization of scribble and other output (say, HTML or
>> something else that doesn't require anything from outside scribble and
>> racket) can be done directly? Essentially:
>>
>> ```
>> @title{Synchronize this!}
>>
>> Can you synchronize this @racket[(range 5)]?
>> ```
>>
>> would update to show
>>
>> ```
>> # Synchronize this!
>>
>> Can you synchronize this '(0 1 2 3 4)?
>> ```
>>
>> and it would update it quickly when I change (range 5) to (range 4)? I
>> may have misinterpreted what you said - but if I didn't, then I wasn't
>> aware this was easily doable.
>>
>> Cheers,
>> Marc
>>
>> On Tuesday, January 29, 2019 at 2:01:37 PM UTC+1, Robby Findler wrote:
>>>
>>> In order to do that you'd need to drop down to the latex level and use
>>> a package there to help you. There is information about how to do that
>>> here: http://docs.racket-lang.org/scribble/config.html . Here is a
>>> post about packages you could use:
>>>
>>> https://tex.stackexchange.com/questions/308260/parallel-text-translation-including-the-same-double-parallel-heading-numbering
>>>
>>> hth,
>>> Robby
>>>
>>> On Tue, Jan 29, 2019 at 5:09 AM  wrote:
>>> >
>>> > Can I do a side by side pdf using racket scribble? Imagine you have an
>>> English text and want the Portuguese translation in the opposite column. If
>>> yes, it brings another question, which is, can it be done with synchronized
>>> paragraphs?
>>> >
>>> > --
>>> > 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...@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] side by side; scribble

2019-01-29 Thread Marc Kaufmann
Since you say that it requires dropping to the latex level, does it mean 
that doing a synchronization of scribble and other output (say, HTML or 
something else that doesn't require anything from outside scribble and 
racket) can be done directly? Essentially:

```
@title{Synchronize this!}

Can you synchronize this @racket[(range 5)]?
```

would update to show 

```
# Synchronize this!

Can you synchronize this '(0 1 2 3 4)?
```

and it would update it quickly when I change (range 5) to (range 4)? I may 
have misinterpreted what you said - but if I didn't, then I wasn't aware 
this was easily doable.

Cheers,
Marc

On Tuesday, January 29, 2019 at 2:01:37 PM UTC+1, Robby Findler wrote:
>
> In order to do that you'd need to drop down to the latex level and use 
> a package there to help you. There is information about how to do that 
> here: http://docs.racket-lang.org/scribble/config.html . Here is a 
> post about packages you could use: 
>
> https://tex.stackexchange.com/questions/308260/parallel-text-translation-including-the-same-double-parallel-heading-numbering
>  
>
> hth, 
> Robby 
>
> On Tue, Jan 29, 2019 at 5:09 AM > wrote: 
> > 
> > Can I do a side by side pdf using racket scribble? Imagine you have an 
> English text and want the Portuguese translation in the opposite column. If 
> yes, it brings another question, which is, can it be done with synchronized 
> paragraphs? 
> > 
> > -- 
> > 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...@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] Web server hits "Sorry, this page has expired. Please go back."

2018-10-13 Thread Marc Kaufmann
urce code changes, which is a good thing: the
> potential bugs otherwise would be nightmarish.
>
>
Another problem solved, and together with George's explanation I finally
see what the difference is between the stateful and stateless server.

Is there somewhere a good write-up on a comparison of what is nice about
>> one style vs the other? I am not asking which is better, but examples that
>> highlight how they are different or lead to different solutions or
>> different trade-offs?
>>
>
> There is a gap in the documentation, I think. (Maybe I should try to write
> some more.) I know that I did find reading Jay's papers helpful, even if
> the formal PL parts were over my head:
>

I'd be delighted to read such a write-up, but this already helps a lot.


>- "Automatically RESTful Web Applications: Marking Modular
>Serializable Continuations": https://doi.org/10.1145/1596550.1596594
>- "The Two-State Solution: Native and Serializable Continuations
>Accord":
>https://jeapostrophe.github.io/home/static/oopsla026-mccarthy.pdf
>
> I opened the first link dreading the worst, but it is surprisingly
readable!


> Personally, I had experience with RESTful web programming before I came to
> Racket, and I also started using stateless servlets first. Once it finally
> clicked, stateless servlets/serializable continuations made sense to me,
> and I could see that what `#lang web-server` does automatically is really
> just what I had previously been doing manually and painfully: stuffing all
> of the data needed to continue the interaction into URL query parameters,
> hidden form fields, etc.
>

This! I used to do this all the time and still sometimes do, but recently
replaced it by continuations. (Thanks to Matthew Butterick's write-up on
continuations btw, which made them click for me.) However, I ended up with
n parameters: one for period, one for id, one for phase of the moon, ...
Every time I changed the code or realized I needed one more state variable,
I had to refactor all the instances, until it occurred to me to define a
`struct my-struct and pass that around and then the only place I have to
change it is in the struct when adding new variables. I know, this should
have been obvious, but while trying to figure out how to get the
continuation working, I didn't consciously grasp that all I was doing was
passing state around, the same way that big-bang in HTDP/2e does it. That
was a real missing-the-forest-for-the-trees moment for me.

The benefits of stateless servlets are mostly just the benefits of not
> using server-side state in general. The main disadvantage is that you need
> to ensure data structures that will be serialized as part of the closure
> are serializable. However, while it takes some practice to get a sense of
> this (maybe another opportunity for more documentation), it isn't actually
> a big problem in practice.
>
> -Philip
>
>
Thanks for taking the time to write all of this in detail, I really
appreciate it.

Cheers,
Marc

On Sat, Oct 13, 2018 at 12:18 PM Marc Kaufmann 
> wrote:
>
>>
>> On Sat, Oct 13, 2018 at 5:49 PM George Neuner 
>> wrote:
>>
>>> Hi Marc,
>>>
>>> On 10/13/2018 10:42 AM, Marc Kaufmann wrote:
>>>
>>> Thanks George and Philip.
>>>
>>> George, while I am sure that in some places I allow using continuations
>>> after a delay, that's not what I meant. What I feel is happening (with
>>> little evidence, mind you) is that, when I come back to my website after 3
>>> days and open the homepage, it creates it on the fly with a *new*
>>> continuation (generated now), yet when the link gets called it gives me
>>> this error. I would have thought this continuation is new, yet it seems to
>>> throw the error I am talking about more often when I haven't visited the
>>> site in a while. See below for the servlet I am using currently, I am not
>>> specifying a manager.
>>>
>>>
>>> Which means you are using the default manager. That would explain an old
>>> continuation expiring, but not a new one.
>>>
>>> When the program is operating normally, are you seeing *different*
>>> continuation URLs every time you execute the same send/suspend/... call?
>>> Or are all the URLs for the same send/suspend/... call identical?   IIRC,
>>> the default URL generator includes a nonce, but you can create your own
>>> URLs.
>>>
>>>
>> The urls have different numbers at the end of the form (("k" . "(6 1
>> 8431734)")) if that's what you mean by nonce.
>>
>>>
>>> Philip, thanks, I didn't realize that I had made an active choice. I

Re: [racket-users] Web server hits "Sorry, this page has expired. Please go back."

2018-10-13 Thread Marc Kaufmann
Hi George,

thanks, this is incredibly helpful.

On Sat, Oct 13, 2018 at 9:11 PM George Neuner  wrote:

> Hi Marc,
>
> On 10/13/2018 12:17 PM, Marc Kaufmann wrote:
>
>
> On Sat, Oct 13, 2018 at 5:49 PM George Neuner 
> wrote:
>
>>
>> When the program is operating normally, are you seeing *different*
>> continuation URLs every time you execute the same send/suspend/... call?
>> Or are all the URLs for the same send/suspend/... call identical?   IIRC,
>> the default URL generator includes a nonce, but you can create your own
>> URLs.
>>
>>
> The urls have different numbers at the end of the form (("k" . "(6 1
> 8431734)")) if that's what you mean by nonce.
>
>
> Yes.  A "nonce" is (supposed to be) a single use, never repeated, stamp.
> Obviously the "never repeated" part is impractical with reasonably sized
> numbers (rollover), but the point is to generate a unique value that won't
> be repeated within the expected lifetime of the continuation.
>
>
> I generally use stateful servers myself, because I don't use web
>> continuations.  It's not that I don't like them - it's that I don't often
>> have a need for them that isn't better served by using a database.  I
>> certainly do use continuations in my programming - I just don't use web
>> continuations.  I do think that long duration web continuations are a
>> questionable design ... there are just too many error possibilities in the
>> web environment.  Short-lived continuations?  Up to a few minutes?  Maybe
>> ... but I'd need a good use case to justify them.
>>
>
> To clarify, when you say you use a database you mean when the form gets
> posted, there is some variable in the database (say 'page_number') that
> gets incremented, then after the storing in the database, you check the
> database for the page and see the variable is one larger and you post the
> next page? Whereas with continuations there is nothing in the database that
> I can see and the new page is the continuation, as in (generate-page (+ n
> 1))?
>
>
> Not exactly, although that is a valid use case.  The more concurrent
> users, the more it makes sense to use a database to hold session state.
>
>
> My canon example is a database search engine [my own application area].
> User submits search criteria, and [like Google,etc.] gets back a list of
> results.  But say the user wants the results (no more than) 20 per page and
> there are 1172 results.  Now there are some choices about how to structure
> the ongoing session with the user.
>
> 1) The Racket program can read out all the results [freeing up the DB
> connection], send the 1st page of 20 and include continuation links for the
> additional pages.  But there are 59 pages of results, plus  and
>  where applicable.  Even limiting to, say 10 page links at a time
> [like Google], that means 11 or 12 outstanding continuations kept open on
> this one user session.  AND, no good way to decide when to expire them ...
> the user may go off and examine some result(s) for a while, then come back
> to the list.
>
> Keep in mind that (presumably) there will be some number of concurrent
> users doing similar things.
>
> 2) The Racket program can hold a cursor open on the DB results, use the
> same continuation scheme as above, and read out just a page full of results
> on demand when the user wants them.  This approach has the same
> continuations open, and adds a persistent DB connection, but it shifts the
> load of caching results to the DBMS ... result data passing through the
> Racket program now is transitory and can be GC'd if memory is needed.
>
> 3) results from the initial search are written into a dedicated table in
> the database.  The Racket program uses the same continuation scheme and
> reads out pages of results on demand as in (2).  Now, since each database
> query is self contained, and the user session does not require a persistent
> DB connection, a larger number of users can be serviced with a small(er)
> pool of connections.  As in (2), all the result data is transitory in the
> Racket program, so all that needs to be remembered are the continuations.
>
> 4) results are written into a dedicated table as in (3).  The Racket
> program does NOT use continuations, but rather provides a dedicated result
> fetch function - separate from the search function - and generates page
> URLs which call that function with appropriate arguments.  Now, in addition
> to every DBMS query being self contained, the functions of the Racket
> application also are self contained - there is no persistent session state
> in the Racket program.
>
>
OK, this does give one nice usecase where the di

Re: [racket-users] Web server hits "Sorry, this page has expired. Please go back."

2018-10-13 Thread Marc Kaufmann
On Sat, Oct 13, 2018 at 5:49 PM George Neuner  wrote:

> Hi Marc,
>
> On 10/13/2018 10:42 AM, Marc Kaufmann wrote:
>
> Thanks George and Philip.
>
> George, while I am sure that in some places I allow using continuations
> after a delay, that's not what I meant. What I feel is happening (with
> little evidence, mind you) is that, when I come back to my website after 3
> days and open the homepage, it creates it on the fly with a *new*
> continuation (generated now), yet when the link gets called it gives me
> this error. I would have thought this continuation is new, yet it seems to
> throw the error I am talking about more often when I haven't visited the
> site in a while. See below for the servlet I am using currently, I am not
> specifying a manager.
>
>
> Which means you are using the default manager. That would explain an old
> continuation expiring, but not a new one.
>
> When the program is operating normally, are you seeing *different*
> continuation URLs every time you execute the same send/suspend/... call?
> Or are all the URLs for the same send/suspend/... call identical?   IIRC,
> the default URL generator includes a nonce, but you can create your own
> URLs.
>
>
The urls have different numbers at the end of the form (("k" . "(6 1
8431734)")) if that's what you mean by nonce.

>
> Philip, thanks, I didn't realize that I had made an active choice. I am
> pretty sure I was simply using stateful servlets because the
> send/suspend/dispatch link on "Continue: Web Applications in Racket" links
> to the stateful servlets page, not to the stateless servlets page. If this
> is not best practice, maybe it would be better to link it to the
> send/suspend/dispatch on the stateless server page. You say:
>
> "Stateless servlets avoid this issue by making continuations serializable,
> so they can be saved on the client, in a database, etc."
>
> Does this mean I have to deal with managing them myself?
>
> Practically speaking, since both of you seem to imply that I should use
> stateless servers, how do I do that? I did skim the page on stateless
> servers, but I don't understand who the web server should provide
> interface-version, stuffer, and start to. Do I have to require this file in
> all the *.rkt files that uses send/suspend/dispatch?
>
>
> It's not really a matter of "best practice" ... stateful vs stateless
> mostly is a non-issue unless you have limited memory or you really need web
> continuations to be available long duration: e.g., hours or days.
>
> I generally use stateful servers myself, because I don't use web
> continuations.  It's not that I don't like them - it's that I don't often
> have a need for them that isn't better served by using a database.  I
> certainly do use continuations in my programming - I just don't use web
> continuations.  I do think that long duration web continuations are a
> questionable design ... there are just too many error possibilities in the
> web environment.  Short-lived continuations?  Up to a few minutes?  Maybe
> ... but I'd need a good use case to justify them.
>
>
To clarify, when you say you use a database you mean when the form gets
posted, there is some variable in the database (say 'page_number') that
gets incremented, then after the storing in the database, you check the
database for the page and see the variable is one larger and you post the
next page? Whereas with continuations there is nothing in the database that
I can see and the new page is the continuation, as in (generate-page (+ n
1))?

I have a mixture of both (for no good reason that I couldn't figure out how
to do some parts with continuations after starting with them, due to
wanting to learn how to use them), but realized that if I hit an error and
have to restart the server, all existing users are going to see 'Page
expired' links, which isn't Very Good (TM) even by my standards - or
especially, since I usually do hit bugs that I have to fix after going live.

Is there somewhere a good write-up on a comparison of what is nice about
one style vs the other? I am not asking which is better, but examples that
highlight how they are different or lead to different solutions or
different trade-offs?


> As a practical matter, you can start to go stateless just by substituting
> #lang web-server  for  #lang racket ... odds are that most/all of your
> program will remain the same.  The web-server language enables you to do
> things beyond what a stateful Racket server can do, but you don't need to
> worry about cells and stuffers, etc. until / unless you really need them.
>
>
I'll try that and see what happens. Thanks a lot!

> George
>

Marc

-- 
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] Web server hits "Sorry, this page has expired. Please go back."

2018-10-13 Thread Marc Kaufmann
 #:servlet-regexp #rx""
   #:launch-browser? #f
   #:extra-files-paths (list (build-path "htdocs"))
   #:servlet-responder my-error-responder)

Thanks a lot,
Marc

On Sat, Oct 13, 2018 at 4:10 PM Philip McGrath 
wrote:

> You should only be seeing this issue if you are using stateful servlets,
> as opposed to stateless, RESTful servlets in `#lang web-server`. The first
> question is whether you really need to be doing that—other than as an
> experiment, I never have.
>
> Stateful servlets work by keeping continuation values live in memory.
> Keeping all continuations in memory indefinitely will presumably exhaust
> your available memory eventually (unless you know you have a short-running
> servlet with limited access), but in general there isn't a sound way to
> decide when to free them: this is explained more in the papers. Stateful
> servlets have *managers* (
> http://docs.racket-lang.org/web-server/servlet.html#%28part._managers%29)
> that decide when to free saved continuations, typically using a timeout or
> least-recently-used policy. The error you are reporting is from visiting a
> page that has been freed. So, you probably need to adjust the limits being
> given to your servlet's manager, rather than using the default from
> `serve/servlet` or equivalent.
>
> Stateless servlets avoid this issue by making continuations serializable,
> so they can be saved on the client, in a database, etc.
>
> -Philip
>
>
> On Sat, Oct 13, 2018 at 9:27 AM Marc Kaufmann 
> wrote:
>
>> Hi all,
>>
>> I am running the Racket web server with continuations and I keep getting
>> "Sorry, this page has expired. Please go back." rather sporadically. I
>> can't seem to figure out why and when this happens. I get it more on my
>> local server running on localhost.
>>
>> A few patterns that I believe are true (without having rigorously tested
>> it):
>>
>> - When I don't visit my live server for a while (and hence noone does), I
>> usually get the error immediately and then when I go back and try again it
>> works. Is it possible that it is an issue of something (the continuation
>> URL) not being loaded quickly or having to be generated on the fly? Would a
>> database connection that has expired lead to this? I remember having issues
>> with my database connections going stale (or whatever I'm supposed to call
>> that).
>> - When I refresh a page, I often get it too (although sometimes that
>> fixes the problem?)
>>
>> This is not a crippling issue, but my guess is that I am doing something
>> wrong in how I set up things and eventually I should deal with this.
>>
>> Cheers,
>> Marc
>>
>> --
>> 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] Web server hits "Sorry, this page has expired. Please go back."

2018-10-13 Thread Marc Kaufmann
Hi all,

I am running the Racket web server with continuations and I keep getting 
"Sorry, this page has expired. Please go back." rather sporadically. I 
can't seem to figure out why and when this happens. I get it more on my 
local server running on localhost.

A few patterns that I believe are true (without having rigorously tested 
it):

- When I don't visit my live server for a while (and hence noone does), I 
usually get the error immediately and then when I go back and try again it 
works. Is it possible that it is an issue of something (the continuation 
URL) not being loaded quickly or having to be generated on the fly? Would a 
database connection that has expired lead to this? I remember having issues 
with my database connections going stale (or whatever I'm supposed to call 
that).
- When I refresh a page, I often get it too (although sometimes that fixes 
the problem?)

This is not a crippling issue, but my guess is that I am doing something 
wrong in how I set up things and eventually I should deal with this.

Cheers,
Marc

-- 
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] Re: Using ctags and vim with Racket

2018-09-14 Thread Marc Kaufmann
Thanks Alex, that was it. I thought I had tried it by setting .rkt to be 
interpreted as .scm, but I think that got overridden by vim-racket plugin. 
What I now did is:

ctags --language-force=scheme *.rkt

Cheers,
Marc

On Friday, September 14, 2018 at 12:24:32 AM UTC+2, Alex Harsanyi wrote:
>
>
>
> On Thursday, September 13, 2018 at 10:19:37 PM UTC+8, Marc Kaufmann wrote:
>>
>> Hi all,
>>
>> for the first time I wanted to use ctags today, which generates a bunch 
>> of tags so that one can jump to and from function definitions and the like 
>> in vim. However, the program generates no tags whatsoever for Racket, which 
>> wasn't too surprising.
>>
>> I am using the vim-racket plugin. Does anyone use vim with ctags -- or 
>> vim with any plugin that does a good job of jumping between definitions and 
>> works with Racket?
>>
>
> The likely problem is that ctags does not recognize the .rkt file 
> extension as a scheme file.  You will need to find what command line option 
> to use to map the .rkt file extension to scheme.  For example, in etags 
> (the Emacs equivalent), I use:
>
> find . -name "*.rkt" -print | etags -l scheme -
>
> Alex. 
>
>

-- 
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] Using ctags and vim with Racket

2018-09-13 Thread Marc Kaufmann
Hi all,

for the first time I wanted to use ctags today, which generates a bunch of
tags so that one can jump to and from function definitions and the like in
vim. However, the program generates no tags whatsoever for Racket, which
wasn't too surprising.

I am using the vim-racket plugin. Does anyone use vim with ctags -- or vim
with any plugin that does a good job of jumping between definitions and
works with Racket?

Cheers,
Marc

-- 
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] What does `raco test file.rkt` do by default if no `test` submodule?

2018-09-07 Thread Marc Kaufmann
Thanks Greg and David.

If I use raco test, is the best practice to configure test runs via an 
info.rkt file (I did that when I wanted to exclude files instead of the 
`-x` flag)? Are there any common (best?) practices for racket tests that I 
should be aware of, whether it is purely by convention or because the tools 
tend to work better that way.

David, for now raco test works for my needs, so I'll stick with it. I'll 
keep it in mind though, especially for the feature of printing passing 
tests.

Cheers,
Marc

On Thursday, September 6, 2018 at 5:31:17 PM UTC+2, David K. Storrs wrote:
>
> This isn't a direct answer to your question, but you might want to check 
> out handy/test-more.  Unlike the racket test system it always provides 
> feedback on what tests have run and it will warn you if you did not run the 
> expected number of tests.  It also uses shorter names for the tests and 
> each test returns a useful value so that you can chain tests together or 
> use them in conditionals.  For example:
>
> ;; in test.rkt
> #lang racket
>
> (require handy/test-more)
>
> (when (not (equal? 'windows (is (system-type) 'windows "expected to be 
> running on windows")))
>   (void (is (system-type) 'macosx "it's mac"))
>   )
>
> (test-suite
>  "examples"
>
>  (throws (thunk (raise-arguments-error 'some-func "bad args"))
>  #px"bad args"
>  "threw as expected")
>
>  (lives (thunk (ok 1 "1 is true"))
> "checking truth of 1 did not blow up")
>  )
>
>
>
> ;; at command line (assume you're running on macOS)
> $ racket test.rkt
>
> NOT ok 1 - expected to be running on windows
>   Got:  'macosx
>   Expected: 'windows
> ok 2 - it's mac
>  (START test-suite:  examples)
> ok 3 - threw as expected
> ok 4 - 1 is true
> ok 5 - checking truth of 1 did not blow up
> ok 6 - test-suite completed without throwing uncaught exception
>
> Total tests passed so far: 5
> Total tests failed so far: 1
>  (END test-suite:  examples)
> WARNING: Neither (expect-n-tests N) nor (done-testing) was called.  May 
> not have run all tests.
>
>
>
> There's thorough documentation, although it's in comments instead of in 
> Scribble so you'll need to actually look in the code.  I keep meaning to 
> Scribbleify it but haven't found the tuits.  I also have chosen not to have 
> a handy/main.rkt that would pull in all the pieces of handy, since I feel 
> like it's better to be explicit about what you want.  If people actually 
> started using it and asked for that feature then I'd add it.
>
>
> On Thu, Sep 6, 2018 at 5:46 AM, Marc Kaufmann  > wrote:
>
>> Hi,
>>
>> I am starting to use raco test for testing, and found out that in a file 
>> without (module test ...), it may run some kind of test on the file. But 
>> for some files, raco test reports that it ran a test, for others however no 
>> test is run.
>>
>> Right now I am now adding a (module test racket/base) at the end of files 
>> I have no tests for which leads to 0 tests (as it should). Nonetheless out 
>> of curiosity, I am wondering why raco reports running a test for 
>> `pages.rkt`, but not `tools.rkt`, even though both of them are essentially 
>> defining a bunch of functions and providing them to other files, without 
>> running any code.
>>
>> This made me realize that I don't know how to print out which tests were 
>> run. Is there a way of doing that?
>>
>> Thanks,
>> Marc
>>
>> -- 
>> 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...@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] What does `raco test file.rkt` do by default if no `test` submodule?

2018-09-06 Thread Marc Kaufmann
Hi,

I am starting to use raco test for testing, and found out that in a file 
without (module test ...), it may run some kind of test on the file. But 
for some files, raco test reports that it ran a test, for others however no 
test is run.

Right now I am now adding a (module test racket/base) at the end of files I 
have no tests for which leads to 0 tests (as it should). Nonetheless out of 
curiosity, I am wondering why raco reports running a test for `pages.rkt`, 
but not `tools.rkt`, even though both of them are essentially defining a 
bunch of functions and providing them to other files, without running any 
code.

This made me realize that I don't know how to print out which tests were 
run. Is there a way of doing that?

Thanks,
Marc

-- 
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] European Racketeers and conferences

2017-08-24 Thread Marc Kaufmann
I'm in Hungary, but regularly (3 times or more per year) travelling to 
Germany/Benelux. I am more likely to make a meetup if it falls in an academic 
holiday and is arranged at least 6 months in advance, given that I am unlikely 
to travel that distance for just one meetup (even if it is, admittedly, for the 
second best programming language).

On Thursday, August 24, 2017 at 9:08:33 AM UTC+2, John Berry wrote:
> I live in Finland, and will be giving a talk about Heresy, the language I 
> built in Racket, next weekend at ClojuTRE in Tampere FI.
> 
> 
> It would be interesting to see a Racketeer meetup of some kind. As much as I 
> love the UK though, I'm not sure I would be keen on a meetup there with the 
> way things are going. Too many horror stories about tech people and 
> conference goers getting harassed or deported by UK border security. 
> Apparently they think we're going to sneak in and steal all the good tech 
> jobs. ;)
> 
> 
> On Wed, Aug 23, 2017 at 3:45 PM, Matthew Eric Bassett  
> wrote:
> So there's at least 7 of us around UK/Germany/France/Netherlands that
> 
> are active on the mailing list.  What would we need at a European
> 
> Rackeeteers Meeting to ensure that *at least* all 7 of us would travel
> 
> to it ?
> 
> 
> 
> @Matthias - it'd be fantastic if we could arrange something in London or
> 
> Oxford.  I'm just getting back from Salone this week and wasn't planning
> 
> on making to ICFP, but I'll see if I can help organize something.  Can
> 
> you sure your itinerary ?
> 
> 
> 
> 
> 
> On 08/23/2017 11:13 AM, 'Paulo Matos' via Racket Users wrote:
> 
> >
> 
> >
> 
> > On 22/08/17 16:20, Daniel Brunner wrote:
> 
> >> Hey Matthew,
> 
> >>
> 
> >> I live in Germany and use Racket for teaching students, teaching our
> 
> >> apprentices (dual education system in Germany) and use it "in
> 
> >> production" for some tasks.
> 
> >>
> 
> >
> 
> > In Germany as well - Nuernberg to be precise. I learned Racket back in
> 
> > version 53 - that was something around 1999. On and off for a few years
> 
> > and now I am using in commercially in my own company.
> 
> >
> 
> > Happy to join a European Racket gathering.
> 
> >
> 
> > Paulo Matos
> 
> >
> 
> >> Best wishes,
> 
> >> Daniel
> 
> >>
> 
> >> Am 22.08.2017 um 15:15 schrieb Matthew Eric Bassett:
> 
> >>> Hi all,
> 
> >>>
> 
> >>> Gutted I can't make it to RacketCon this year.  Really glad to see it
> 
> >>> growing.
> 
> >>>
> 
> >>> Question for y'all - how many Racketeers are active on this side of the
> 
> >>> Atlantic?  Enough for a specific get-together over here?  Or are there
> 
> >>> already appropriate venues for that that I'm unaware of (I am already
> 
> >>> familiar with the European lisp symposium)
> 
> >>>
> 
> >>> Best,
> 
> >>>
> 
> >>>
> 
> >>
> 
> >
> 
> 
> 
> 
> 
> --
> 
> Matthew Eric Bassett | http://mebassett.info
> 
> 
> 
> 
> 
> --
> 
> 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...@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] How to build new formlets that allow passing default values (such as hidden)?

2017-08-23 Thread Marc Kaufmann
Hi again,

I am now trying to deal with formlets in a more principled fashion and thus
trying to implement, as Philip suggested, to use `send/formlet` and
`embed-formlet`. After a lot of tinkering, I still haven't figured out how
to actually process the formlet (without having to pass it around) with
embed-formlet. Here is the current example:

(define (debrief request)
  (define test-formlet
(formlet
  (div "Name:" ,{input-string . => . name})
  (list name)))
  (define (response-generator embed/url)
(html-wrapper
  `((h1 "Testing Formlets")
(form ([action ,(embed/url testing)]
   [method "POST"])
  (p "Here is the displayed formlet")
  ;,@(formlet-display test-formlet) ;; THIS WORKS
  ,(embed-formlet embed/url test-formlet)
  (input ([type "submit"]))
  

The above works without `embed-formlet` with the following definition of
`testing`:

  (define (testing request)
(define result (formlet-process test-formlet request))
(html-wrapper
  `((h1 "Result")
(div
  ,(first result)
  (send/suspend/dispatch response-generator))

But it does not work (or I can't figure out how it works) with
embed-formlet. How do I process the formlet, with the requirement that I do
not want to refer explicitly to `test-formlet`? Or is this not possible -
in which case, what does `embed-formlet` do that `formlet-processing`
doesn't? Any working example with embed-formlet is appreciate, even if it
is not the same as mine.

Thanks,
Marc


On Thu, Mar 16, 2017 at 2:11 PM, Marc Kaufmann <marc.kaufman...@gmail.com>
wrote:

> Thanks Philip. I checked out the links, but I fear that it's over my head,
> and that I would almost surely screw it up. For now I'll keep passing the
> parameters.
>
> Cheers,
> Marc
>
> On Tuesday, March 14, 2017 at 3:22:39 PM UTC-4, Philip McGrath wrote:
> > If you want it to be part of the continuation without having to pass it
> around as an argument, check out web cells (http://docs.racket-lang.org/
> web-server/stateless.html?q=web-server%2Flang%2Fwe#%28mod-
> path._web-server%2Flang%2Fweb-cells%29) or web parameters (
> http://docs.racket-lang.org/web-server/stateless.html?q=
> web-server%2Flang%2Fwe#%28mod-path._web-server%2Flang%2Fweb-param%29).
> >
> >
> >
> > -Philip
> >
> >
> >
> > On Tue, Mar 14, 2017 at 1:48 PM, Marc Kaufmann <marc.ka...@gmail.com>
> wrote:
> >
> >
> >
> > Thanks for the detailed answer Philip! Some of it is definitely over my
> head. The reason I don't pass around the id is that I use the html field
> exactly to track the id and wanted to avoid having to pass around the
> argument left and right - and the only ways to pass it on are via forms or
> by sticking it into the requested URL or by using continuations. I will
> give the continuation-style solution a shot though, it's probably cleaner
> to pass the id around as an argument.
> >
> > Cheers,
> > Marc
> >
> >
> >
> >
> >
> > On Tue, Mar 14, 2017 at 1:34 PM, Philip McGrath <
> phi...@philipmcgrath.com> wrote:
> >
> > In this case it will work despite being a hack, because you know that
> your id argument affects only the display stage, not the processing stage:
> however, you can't know in general that this will work for dynamically
> generated formlets, and personally I would therefore be reluctant to rely
> on this, both because it is fragile in terms of changes to your
> implementation of matrix-formlet that you might make later.
> >
> >
> > If you are using native continuations (i.e. not the stateless #lang
> web-server), you can use send/formlet or embed-formlet to deal with this
> correctly and easily. (At a lower level, you could also do something
> like(define-values (xexpr-forest bindings->result i)
> >   ((matrix-formlet "3") 0))
> > to access the low-level rendering, processing function, and next
> allowable input integer directly.)
> >
> >
> > It is a little more tricky in #lang web-server, because your formlet and
> it's generated processing function are plain functions, and thus not
> serializable (see this old thread for discussion: https://groups.
> google.com/d/topic/racket-users/lMYWjodgpmo/discussion). The easy
> work-around is to keep the arguments you need to reproduce your formlet
> around as part of the closure, e.g. by rewriting your matrix-submission
> like this:(define (matrix-submission req id)
> >   (define-values (number-of-ones user-id)
> >   (formlet-process (matrix-formlet id) req))
> >   ...)
> > The alternative is to either recompile the formlet li

Re: [racket-users] Strange (to me) error in 'query-exec for io:read-le-intN

2017-04-05 Thread Marc Kaufmann
Ah, all of this makes a lot more sense now. I assumed that the handles
stayed connected until I close them intentionally. Lots of reading ahead...

Thanks though, at least now I know what is going wrong.

On Wed, Apr 5, 2017 at 4:00 PM, George Neuner <gneun...@comcast.net> wrote:

>
> On 4/5/2017 2:56 PM, David Storrs wrote:
>
>> On Wed, Apr 5, 2017 at 1:39 PM, Marc Kaufmann <marc.kaufman...@gmail.com>
>> wrote:
>> > Thanks David, that makes a little sense also because it often happens
>> after
>> > there has been no activity on the server for a while. If it is a stale
>> > handle, is there something I can do about it?
>>
>> Get a fresh handle instead of re-using an old one.  I don't know what
>> this line does:(define dbc (study-db a-study))   but if it's
>> returning a cached handle then that's your problem.
>>
>> Something like this would work:
>>
>> (define (connect-me)
>>(postgresql-connect #:user "foo"
>>#:database "bar"
>>#:password "baz"
>>#:port 5432
>>))
>>
>> (define dbc (connect-me))
>>
>>
>> (Note that this is illustrative, not necessarily efficient.)
>>
>> Also, you might want to look into virtual connections and connection
>> pools.
>>
>
> In addition to David's excellent suggestion:
>
> Be aware that the server may close an idle connection, and you may get a
> stale handle even from a pool.  Depending on the DBMS you may need to
> enable keep-alives and/or change idle connection timeouts on the server so
> that a pool can keep connections open.
>
> MySQL uses keep-alives by default, but there is a separate idle connection
> timeout.
> see https://dev.mysql.com/doc/refman/5.7/en/server-system-variab
> les.html#sysvar_wait_timeout
>
> George
>
>

-- 
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] Strange (to me) error in 'query-exec for io:read-le-intN

2017-04-05 Thread Marc Kaufmann
Thanks David, that makes a little sense also because it often happens after
there has been no activity on the server for a while. If it is a stale
handle, is there something I can do about it?

I got rid of the string-join, although I think I was using bind params
already -- I did not join strings that were variable, all variables get
passed via "?" in the string itself. It might be because I do
`(number->string (random 100)), which is because it means I don't have
to convert it to strings every time I put it in the webpage.

Cheers,
Marc

On Wed, Apr 5, 2017 at 1:25 PM, David Storrs <david.sto...@gmail.com> wrote:

> I'm guessing here, but these lines:
>
>/usr/share/racket/pkgs/db-lib/db/private/mysql/message.rkt:417:0:
> parse-packet
>/usr/share/racket/pkgs/db-lib/db/private/mysql/connection.rkt:105:4:
> recv* method in connection%
>
> suggest to me that the issue is:
>
> 1) The connection handle is stale or not established
>
> 2) It's failing to make the connection before the initial call is
> made, so it receives something that isn't a packet back (my guess
> would be #f, but that's purely a guess).
>
> 3) The connection then finishes being made so the second call works.
>
>
> The reason it works on localhost is that the DB is instantly available
> with no network latency and your handles are not stale.
>
> As an aside, I would suggest using bind params for your SQL instead of
> assembling it as a string.  It will be faster, might fix your problem,
> and will be substantially more secure depending on where your data is
> coming from.  It will also allow the handle to cache statements for
> future use.  The only change you need is to get rid of the
> string-append:
>
>   (query-exec
> dbc
> "INSERT INTO participant (subscribed, next_matrix,
> completion_code, comprehension_incorrect, comprehension_question)
> VALUES (1, 1, ?, 0, 0)"
> (random 100))
>
>
> Hope this helps,
>
> Dave
>
> On Wed, Apr 5, 2017 at 12:08 PM, Marc Kaufmann
> <marc.kaufman...@gmail.com> wrote:
> > Hi all,
> >
> > I have the following code that occasionally throws an error when called,
> but definitely not always:
> >
> > "
> > (define (study-add-participant! a-study)
> >   (displayln-date)
> >   (define dbc (study-db a-study))
> >   (displayln "Inserting new participant...")
> >   (query-exec
> > dbc
> > (string-join
> >   '(
> > "INSERT INTO participant (subscribed, next_matrix,
> completion_code, comprehension_incorrect, comprehension_question)"
> > "VALUES (1, 1, ?, 0, 0)"))
> > (number->string (random 100)))
> >   (displayln "New participant inserted. Getting id of new
> participant...")
> >   ... ; More stuff
> > "
> >
> > Sometimes I hit the following error, but never if I refresh the page
> that calls 'study-add-participant!, and usually I don't hit the error at
> all.
> >
> > "
> > Servlet (@ /tutorial) exception:
> > io:read-le-intN: internal error;
> >  unexpected eof; got #
> >
> >   context...:
> >/usr/share/racket/collects/db/private/generic/interfaces.rkt:209:0:
> error*9
> >/usr/share/racket/pkgs/db-lib/db/private/mysql/message.rkt:417:0:
> parse-packet
> >/usr/share/racket/pkgs/db-lib/db/private/mysql/connection.rkt:105:4:
> recv* method in connection%
> >.../more-scheme.rkt:261:28
> >/usr/share/racket/collects/db/private/generic/common.rkt:276:13
> >/usr/share/racket/collects/db/private/generic/../../../
> racket/private/more-scheme.rkt:261:28
> >[repeats 1 more time]
> >/usr/share/racket/collects/db/private/generic/functions.rkt:141:0:
> compose-statement
> >/usr/share/racket/collects/db/private/generic/functions.rkt:216:0:
> query-exec
> >/home/marc/mturk/model.rkt:99:0: study-add-participant!
> >/home/marc/mturk/pages.rkt:563:0: tutorial
> >/usr/share/racket/collects/racket/contract/private/arrow-
> higher-order.rkt:342:33
> >[repeats 1 more time]
> >/usr/share/racket/pkgs/web-server-lib/web-server/
> dispatchers/dispatch-servlets.rkt:58:2
> >/usr/share/racket/collects/racket/contract/private/arrow-
> higher-order.rkt:342:33
> >[repeats 1 more time]
> > ...
> > "
> >
> > From the logs, I know that this happens in the query-exec, since I see
> the first `displayln message, but not the second one. What I do not
> understand is how I can hit the message sometimes but not other times? What
&g

[racket-users] Strange (to me) error in 'query-exec for io:read-le-intN

2017-04-05 Thread Marc Kaufmann
Hi all,

I have the following code that occasionally throws an error when called, but 
definitely not always:

"
(define (study-add-participant! a-study)
  (displayln-date)
  (define dbc (study-db a-study))
  (displayln "Inserting new participant...")
  (query-exec
dbc
(string-join
  '(
"INSERT INTO participant (subscribed, next_matrix, 
completion_code, comprehension_incorrect, comprehension_question)"
"VALUES (1, 1, ?, 0, 0)"))
(number->string (random 100)))
  (displayln "New participant inserted. Getting id of new participant...")
  ... ; More stuff
"

Sometimes I hit the following error, but never if I refresh the page that calls 
'study-add-participant!, and usually I don't hit the error at all.

"
Servlet (@ /tutorial) exception:
io:read-le-intN: internal error;
 unexpected eof; got #

  context...:
   /usr/share/racket/collects/db/private/generic/interfaces.rkt:209:0: error*9
   /usr/share/racket/pkgs/db-lib/db/private/mysql/message.rkt:417:0: 
parse-packet
   /usr/share/racket/pkgs/db-lib/db/private/mysql/connection.rkt:105:4: recv* 
method in connection%
   .../more-scheme.rkt:261:28
   /usr/share/racket/collects/db/private/generic/common.rkt:276:13
   
/usr/share/racket/collects/db/private/generic/../../../racket/private/more-scheme.rkt:261:28
   [repeats 1 more time]
   /usr/share/racket/collects/db/private/generic/functions.rkt:141:0: 
compose-statement
   /usr/share/racket/collects/db/private/generic/functions.rkt:216:0: query-exec
   /home/marc/mturk/model.rkt:99:0: study-add-participant!
   /home/marc/mturk/pages.rkt:563:0: tutorial
   
/usr/share/racket/collects/racket/contract/private/arrow-higher-order.rkt:342:33
   [repeats 1 more time]
   
/usr/share/racket/pkgs/web-server-lib/web-server/dispatchers/dispatch-servlets.rkt:58:2
   
/usr/share/racket/collects/racket/contract/private/arrow-higher-order.rkt:342:33
   [repeats 1 more time]
...
"

>From the logs, I know that this happens in the query-exec, since I see the 
>first `displayln message, but not the second one. What I do not understand is 
>how I can hit the message sometimes but not other times? What (hidden?) state 
>is there that is changing and sometimes causes the io:read-le-intN to fail? 

If it helps with diagnosing: 

- The query did not get run successfully on the database.
- The query itself is correct, since it succeeds the second time, and since it 
succeeded yesterday. Thus, it's not that I am addressing a missing database or 
anything.
- I have never yet hit this error when running the code on localhost for 
testing and development. This is on the live server.

I am happy to provide more logs or run commands to figure out what is going on, 
but unfortunately I cannot even replicate the bug reliably (I hit it 4 times so 
far. 

Thanks,
Marc

-- 
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] nginx with Racket web server

2017-04-01 Thread Marc Kaufmann
Ergh... Indeed, that did the trick. Thanks Daniel.

On Sat, Apr 1, 2017 at 5:34 PM, Daniel Brunner <dan...@dbrunner.de> wrote:

> Hi Marc,
>
> I used this setup several times.
>
> Marc Kaufmann <marc.kaufman...@gmail.com> hat am 1. April 2017 um 23:01
> geschrieben:
> location / {
> try_files proxy_pass http:///127.0.0.1:8080;
> }
>
> I think you should omit the "try_files". I think it should read:
>
> location / {
>   proxy_pass http:///127.0.0.1:8080;
> }
>
> Best wishes,
> Daniel
>

-- 
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] nginx with Racket web server

2017-04-01 Thread Marc Kaufmann
Hi all,

this should be simple, but I couldn't get it working, so I am here. I am using 
nginx on my server since I have multiple domains. I am trying to pass all the 
requests to this particular instance to the Racket server, which according to 
the docs works like this for Apache:

RewriteEngine on

RewriteRule ^(.*)$ http://localhost:8080/$1 [P,NE]

According to docs I have found elsewhere, the nginx equivalent of that (without 
the flags at the end, which I have no clue how to do) is:

server {
listen 80;

server_name my-site.com www.my-site.com

location / {
try_files proxy_pass http:///127.0.0.1:8080;
}

My racket server should be listening to localhost at port 8080, since I start 
it as follows:

(serve/servlet start #:log-file (build-path (string-append "logs/" date-string 
"server.logs"))
   #:port 8080
   ;#:listen-ip #f
   #:servlet-path "/"
   #:servlet-regexp #rx""
   #:launch-browser? #t
   #:extra-files-paths (list (build-path "htdocs"))
   #:servlet-responder my-error-responder)

I have tested that the Racket server works when listening on port 80 and to all 
ips (turning off my other domains for that test); nginx also works with plain 
HTML in the folders where it is supposed to look, so at least it's running and 
functional for Wordpress sites. Finally, I don't think the problem is with the 
[P, NE] flags either, since there is no direct redirect. And the NE flag should 
not be a problem for the pages I am testing, since the URL is simply 
my-site.com/home. 

Yet, all I get is nginx's error page. 

Has anyone experience with setting this up and getting it to work - and what 
are the precise configurations in nginx you used?

Thanks,
Marc

-- 
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 store a list (or struct...) in SQL and extract again as original Racket value

2017-03-21 Thread Marc Kaufmann
Thanks, I will give that a try in the future, once I have time to look at
PG database (as I have some experience with Mysql, but none with PG). But
that would be exactly the kind of thing I was looking for.

Cheers,
Marc

On Tue, Mar 21, 2017 at 8:47 PM, George Neuner <gneun...@comcast.net> wrote:

>
> On 3/21/2017 8:36 PM, Marc Kaufmann wrote:
>
> Thanks. But I have to turn it into a string before storing it in the
> database; when I tried to store a serialized list in it (in a VARCHAR
> field), it complained that it expected a string. That's where all the
> trouble came from. The trouble I had was parsing the string back into the
> serialized form, which 'with-input-from-string does (because, I presume, it
> treats the contents of the string as the input, rather than the string
> itself).
>
> Of course, if there is a way to store serialized data directly in the
> database, that would be great - but -- except for arrays in a Postgre
> database -- that doesn't seem to be the case.
>
>
> Serialize produce a list.  You might try storing it as JSON.  Postgresql
> can parse and search JSON values.
>
> https://www.postgresql.org/docs/current/static/datatype-json.html
> https://www.postgresql.org/docs/current/static/functions-json.html
>
>
> George
>

-- 
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 store a list (or struct...) in SQL and extract again as original Racket value

2017-03-21 Thread Marc Kaufmann
Thanks. But I have to turn it into a string before storing it in the
database; when I tried to store a serialized list in it (in a VARCHAR
field), it complained that it expected a string. That's where all the
trouble came from. The trouble I had was parsing the string back into the
serialized form, which 'with-input-from-string does (because, I presume, it
treats the contents of the string as the input, rather than the string
itself).

Of course, if there is a way to store serialized data directly in the
database, that would be great - but -- except for arrays in a Postgre
database -- that doesn't seem to be the case.



On Tue, Mar 21, 2017 at 8:04 PM, Philip McGrath <phi...@philipmcgrath.com>
wrote:

> When you use:
> (write (~a (serialize '((0 1) (1 0 out)
> you are first turning the result of deserialize into a string, then
> writing the string, so read will produce a string.
>
> Your example will work correctly if you drop the ~a and just use:
> (write (serialize '((0 1) (1 0))) out)
>
> If that's less than totally clear, for illustrative purposes, consider the
> following:
> > (serialize '((0 1) (1 0)))
> '((3) 0 () 0 () () (q (0 1) (1 0)))
> > (~a '((3) 0 () 0 () () (q (0 1) (1 0
> "((3) 0 () 0 () () (q (0 1) (1 0)))"
> > (with-output-to-string
>(λ () (write "((3) 0 () 0 () () (q (0 1) (1 0)))")))
> "\"((3) 0 () 0 () () (q (0 1) (1 0)))\""
> > (with-input-from-string "\"((3) 0 () 0 () () (q (0 1) (1 0)))\""
>   read)
> "((3) 0 () 0 () () (q (0 1) (1 0)))"
> > (with-output-to-string
>(λ () (write '((3) 0 () 0 () () (q (0 1) (1 0))
> "((3) 0 () 0 () () (q (0 1) (1 0)))"
> > (with-input-from-string "((3) 0 () 0 () () (q (0 1) (1 0)))"
>   read)
> '((3) 0 () 0 () () (q (0 1) (1 0)))
> > (deserialize '((3) 0 () 0 () () (q (0 1) (1 0
> '((0 1) (1 0))
>
> On Tue, Mar 21, 2017 at 6:53 PM Marc Kaufmann <marc.kaufman...@gmail.com>
> wrote:
>
>> Regarding not using deserialize directly: I may be using deserialize in
>> the wrong way, but the following doesn't work (and I had tried that before
>> posting):
>>
>> > (define-values (in out) (make-pipe))
>> > (write (~a (serialize '((0 1) (1 0)
>> "((3) 0 () 0 () () (q (0 1) (1 0)))"
>> > (write (~a (serialize '((0 1) (1 0 out)
>> > (deserialize (read in))
>> ; car: contract violation
>> ;   expected: pair?
>> ;   given: "((3) 0 () 0 () () (q (0 1) (1 0)))"
>> ; [,bt for context]
>>
>> 'read simply returns a string. On the other hand, using Philip's
>> suggestion works (although I can't say I fully understand the subtleties
>> involved):
>>
>> > (define serialized-string (~a (serialize '((0 1) (1 0)
>> > (with-input-from-string serialized-string (lambda () (deserialize
>> (read
>> '((0 1) (1 0))
>>
>> Regarding pg-array, I thought (from the docs) that it allowed for
>> multi-dimensional arrays, but since I might need a similar functionality
>> for structs and the like, I thought that I should find another solution.
>>
>> Thanks everyone for the quick response.
>>
>> Cheers,
>>
>> Marc
>>
>>
>> On Tue, Mar 21, 2017 at 5:58 PM, George Neuner <gneun...@comcast.net>
>> wrote:
>>
>> On 3/21/2017 5:48 PM, Jon Zeppieri wrote:
>>
>> Ah, except apparently `pg-array` only supports arrays with dimension
>> 1. So... that won't help.
>>
>>
>> I *think* Ryan Culpepper fixed that a long time ago ... though the docs
>> may never have been updated.  I had a workaround at the time and
>> unfortunately I never did go back to verify the fix in later releases.
>>
>> George
>>
>>
>> On 12/18/2014 09:03 PM, George Neuner wrote:
>>
>> Using 6.0.1.   I just painfully discovered that
>>
>>(pg-array->list (list->pg-array (list)))
>>=> ERROR
>>pg-array->list: expected argument of type ;
>> given: (pg-array 0 '() '() '#())
>>
>> The documentation for  list->pg-array  states that it produces an array
>> of dimension 1.  However, if you pass an empty list, you get back an array
>> of dimension zero which you then can't transform back to a list [ except by
>> going straight to the internal vector ].
>>
>> My question is, "shouldn't these conversions be symmetric?"   I
>> understand  an array with no elements is meaningless as an array, but
>> Postgresql (ab)uses arrays as substitutes for lists and sets, so an empty
>> array does have meaning.
>>

Re: [racket-users] How to store a list (or struct...) in SQL and extract again as original Racket value

2017-03-21 Thread Marc Kaufmann
Regarding not using deserialize directly: I may be using deserialize in the
wrong way, but the following doesn't work (and I had tried that before
posting):

> (define-values (in out) (make-pipe))
> (write (~a (serialize '((0 1) (1 0)
"((3) 0 () 0 () () (q (0 1) (1 0)))"
> (write (~a (serialize '((0 1) (1 0 out)
> (deserialize (read in))
; car: contract violation
;   expected: pair?
;   given: "((3) 0 () 0 () () (q (0 1) (1 0)))"
; [,bt for context]

'read simply returns a string. On the other hand, using Philip's suggestion
works (although I can't say I fully understand the subtleties involved):

> (define serialized-string (~a (serialize '((0 1) (1 0)
> (with-input-from-string serialized-string (lambda () (deserialize
(read
'((0 1) (1 0))

Regarding pg-array, I thought (from the docs) that it allowed for
multi-dimensional arrays, but since I might need a similar functionality
for structs and the like, I thought that I should find another solution.

Thanks everyone for the quick response.

Cheers,

Marc


On Tue, Mar 21, 2017 at 5:58 PM, George Neuner  wrote:

> On 3/21/2017 5:48 PM, Jon Zeppieri wrote:
>
> Ah, except apparently `pg-array` only supports arrays with dimension
> 1. So... that won't help.
>
>
> I *think* Ryan Culpepper fixed that a long time ago ... though the docs
> may never have been updated.  I had a workaround at the time and
> unfortunately I never did go back to verify the fix in later releases.
>
> George
>
>
> On 12/18/2014 09:03 PM, George Neuner wrote:
>
> Using 6.0.1.   I just painfully discovered that
>
>(pg-array->list (list->pg-array (list)))
>=> ERROR
>pg-array->list: expected argument of type ;
> given: (pg-array 0 '() '() '#())
>
> The documentation for  list->pg-array  states that it produces an array of
> dimension 1.  However, if you pass an empty list, you get back an array of
> dimension zero which you then can't transform back to a list [ except by
> going straight to the internal vector ].
>
> My question is, "shouldn't these conversions be symmetric?"   I
> understand  an array with no elements is meaningless as an array, but
> Postgresql (ab)uses arrays as substitutes for lists and sets, so an empty
> array does have meaning.
>
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Racket Users" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/racket-users/xAbm8mlPX-w/unsubscribe.
> To unsubscribe from this group and all its topics, 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] How to store a list (or struct...) in SQL and extract again as original Racket value

2017-03-21 Thread Marc Kaufmann
Hi,

I want to store matrices of the following form (but larger) in a database: 

(define m '((0 1) (1 0)))

Currently I manage to store them by turning them into strings first via:

(~a (serialize m)); Or just drop the serialize, but I figured I might benefit 
from it later.

The problem is that I can only get a string out of the database. Obviously I 
could write a parser for this, but it feels a little odd having to write one 
for such a simple, and probably common, task. 

The question I have is whether there is a common best practice for storing such 
things in a database, or whether I should write a parser? And if I should write 
a parser, I presume I should use either Parsack or Megaparsack?

Thanks,
Marc

-- 
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 build new formlets that allow passing default values (such as hidden)?

2017-03-16 Thread Marc Kaufmann
Thanks Philip. I checked out the links, but I fear that it's over my head, and 
that I would almost surely screw it up. For now I'll keep passing the 
parameters.

Cheers,
Marc 

On Tuesday, March 14, 2017 at 3:22:39 PM UTC-4, Philip McGrath wrote:
> If you want it to be part of the continuation without having to pass it 
> around as an argument, check out web cells 
> (http://docs.racket-lang.org/web-server/stateless.html?q=web-server%2Flang%2Fwe#%28mod-path._web-server%2Flang%2Fweb-cells%29)
>  or web parameters 
> (http://docs.racket-lang.org/web-server/stateless.html?q=web-server%2Flang%2Fwe#%28mod-path._web-server%2Flang%2Fweb-param%29).
> 
> 
> 
> -Philip
> 
> 
> 
> On Tue, Mar 14, 2017 at 1:48 PM, Marc Kaufmann <marc.ka...@gmail.com> wrote:
> 
> 
> 
> Thanks for the detailed answer Philip! Some of it is definitely over my head. 
> The reason I don't pass around the id is that I use the html field exactly to 
> track the id and wanted to avoid having to pass around the argument left and 
> right - and the only ways to pass it on are via forms or by sticking it into 
> the requested URL or by using continuations. I will give the 
> continuation-style solution a shot though, it's probably cleaner to pass the 
> id around as an argument.
> 
> Cheers,
> Marc
> 
> 
> 
> 
> 
> On Tue, Mar 14, 2017 at 1:34 PM, Philip McGrath <phi...@philipmcgrath.com> 
> wrote:
> 
> In this case it will work despite being a hack, because you know that your id 
> argument affects only the display stage, not the processing stage: however, 
> you can't know in general that this will work for dynamically generated 
> formlets, and personally I would therefore be reluctant to rely on this, both 
> because it is fragile in terms of changes to your implementation of 
> matrix-formlet that you might make later.
> 
> 
> If you are using native continuations (i.e. not the stateless #lang 
> web-server), you can use send/formlet or embed-formlet to deal with this 
> correctly and easily. (At a lower level, you could also do something 
> like(define-values (xexpr-forest bindings->result i)
>   ((matrix-formlet "3") 0))
> to access the low-level rendering, processing function, and next allowable 
> input integer directly.)
> 
> 
> It is a little more tricky in #lang web-server, because your formlet and it's 
> generated processing function are plain functions, and thus not serializable 
> (see this old thread for discussion: 
> https://groups.google.com/d/topic/racket-users/lMYWjodgpmo/discussion). The 
> easy work-around is to keep the arguments you need to reproduce your formlet 
> around as part of the closure, e.g. by rewriting your matrix-submission like 
> this:(define (matrix-submission req id)
>   (define-values (number-of-ones user-id)
>       (formlet-process (matrix-formlet id) req))
>   ...)
> The alternative is to either recompile the formlet library using #lang 
> web-server/base or to implement your formlet at a low level using 
> serial-lambda and not use any of the library tools.
> 
> 
> In this specific case, though, if you are using this hidden input field just 
> to remember the user id from one request to the next (i.e. you wouldn't ever 
> change it on the client side with JavaScript or something), the best solution 
> is not to put it in the form at all, but have it be part of the continuation. 
> This could also have security advantages, if you cryptographically sign your 
> continuations or store them on the server. If that works for your use case, 
> you could simply write:
> (define matrix-formlet
> 
>   input-string)
> display it with
> (matrix-submission
>  (send/suspend
>   (λ (k-url)
>     (response/xexpr
>      `(html (body (form
>                    ((action "/the-matrix-submitted")
>                     (method "post"))
>                    ,@(formlet-display matrix-formlet)
>                    (input ([type "submit"]
>  user-id)
> and then define matrix-submission as(define (matrix-submission req user-id)
>   (define number-of-ones
>       (formlet-process matrix-formlet req))
>   ...)
> 
> 
> 
> -Philip
> 
> 
> 
> 
> 
> On Tue, Mar 14, 2017 at 12:01 PM, Marc Kaufmann <marc.ka...@gmail.com> wrote:
> 
> 
> Hi,
> 
> 
> 
> I have created a formlet like so:
> 
> 
> 
> (define (matrix-formlet id)
> 
>   (formlet
> 
>         (#%# ,{input-string . => . ones}
> 
>              ,{(to-string (required (hidden id))) . => . user-id}
> 
>                  )
> 
>         (values ones user-id)))
> 
> 
> 
> I display this as follows:
> 
> 
> 
> `(form
&g

Re: [racket-users] Require the same file repeatedly for debugging on command line

2017-03-15 Thread Marc Kaufmann
Ha, very nice. That's exactly what I was looking for - at least it works if
I drop the "#lang racket" at the beginning of the file. If I do include it
and thus, if I understand correctly, make it a module, it somehow does not
seem to load it properly. Short example for file test.rkt:

#lang racket

(define (blob x) 7)

(provide blob)

In xrepl:
> ,rr test.rkt
; reloading "test.rkt"
> blob
; blob: undefined;
;  cannot reference undefined identifier
; [,bt for context]

What am I missing? It does work if I drop the #lang and the `provide.

Marc

On Wed, Mar 15, 2017 at 10:35 AM, Greg Hendershott <
greghendersh...@gmail.com> wrote:

> Have you tried using XREPL -- perhaps its ,enter command or
> ,require-reloadable?
>
>   https://docs.racket-lang.org/xrepl/index.html
>
> On Mon, Mar 13, 2017 at 9:44 PM, Marc Kaufmann
> <marc.kaufman...@gmail.com> wrote:
> > Hi all,
> >
> > while trying to debug, I often change the code in the text file and then
> want to do a (require "file-with-code.rkt") on the command line to test the
> new code. This never works, because I cannot redefine imported modules.
> Thus I always use Dr Racket for this, where I can hit the "Run" button,
> which reruns everything and all is good. Since I prefer to use Vim for
> editing, I was wondering if there is an equivalent of the "Run" button for
> the command line (well, for the require at least)?
> >
> > Thanks,
> > Marc
> >
> > --
> > 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] How to build new formlets that allow passing default values (such as hidden)?

2017-03-14 Thread Marc Kaufmann
Thanks for the detailed answer Philip! Some of it is definitely over my
head. The reason I don't pass around the id is that I use the html field
exactly to track the id and wanted to avoid having to pass around the
argument left and right - and the only ways to pass it on are via forms or
by sticking it into the requested URL or by using continuations. I will
give the continuation-style solution a shot though, it's probably cleaner
to pass the id around as an argument.

Cheers,
Marc

On Tue, Mar 14, 2017 at 1:34 PM, Philip McGrath <phi...@philipmcgrath.com>
wrote:

> In this case it will work despite being a hack, because you know that your
> id argument affects only the display stage, not the processing stage:
> however, you can't know in general that this will work for dynamically
> generated formlets, and personally I would therefore be reluctant to rely
> on this, both because it is fragile in terms of changes to your
> implementation of matrix-formlet that you might make later.
>
> If you are using native continuations (i.e. not the stateless #lang
> web-server), you can use send/formlet or embed-formlet to deal with this
> correctly and easily. (At a lower level, you could also do something like
>
>> (define-values (xexpr-forest bindings->result i)
>>   ((matrix-formlet "3") 0))
>
> to access the low-level rendering, processing function, and next allowable
> input integer directly.)
>
> It is a little more tricky in #lang web-server, because your formlet and
> it's generated processing function are plain functions, and thus not
> serializable (see this old thread for discussion: https://groups.
> google.com/d/topic/racket-users/lMYWjodgpmo/discussion). The easy
> work-around is to keep the arguments you need to reproduce your formlet
> around as part of the closure, e.g. by rewriting your matrix-submission
> like this:
>
>> (define (matrix-submission req id)
>>   (define-values (number-of-ones user-id)
>>   (formlet-process (matrix-formlet id) req))
>>   ...)
>
> The alternative is to either recompile the formlet library using #lang
> web-server/base or to implement your formlet at a low level using
> serial-lambda and not use any of the library tools.
>
> In this specific case, though, if you are using this hidden input field
> just to remember the user id from one request to the next (i.e. you
> wouldn't ever change it on the client side with JavaScript or something),
> the best solution is not to put it in the form at all, but have it be part
> of the continuation. This could also have security advantages, if you
> cryptographically sign your continuations or store them on the server. If
> that works for your use case, you could simply write:
> (define matrix-formlet
>   input-string)
> display it with
>
>> (matrix-submission
>>  (send/suspend
>>   (λ (k-url)
>> (response/xexpr
>>  `(html (body (form
>>((action "/the-matrix-submitted")
>> (method "post"))
>>,@(formlet-display matrix-formlet)
>>(input ([type "submit"]))))
>>  user-id)
>
> and then define matrix-submission as
>
>> (define (matrix-submission req user-id)
>>   (define number-of-ones
>>   (formlet-process matrix-formlet req))
>>   ...)
>
>
> -Philip
>
> On Tue, Mar 14, 2017 at 12:01 PM, Marc Kaufmann <marc.kaufman...@gmail.com
> > wrote:
>
>> Hi,
>>
>> I have created a formlet like so:
>>
>> (define (matrix-formlet id)
>>   (formlet
>> (#%# ,{input-string . => . ones}
>>  ,{(to-string (required (hidden id))) . => . user-id}
>>  )
>> (values ones user-id)))
>>
>> I display this as follows:
>>
>> `(form
>>   ((action "/the-matrix-submitted")
>>(method "post"))
>>  ,@(formlet-display (matrix-formlet user-id))
>>  (input ([type "submit"]
>>
>> and process it like this:
>>
>> (define (matrix-submission req)
>>   (define-values (number-of-ones user-id)
>>  (formlet-process (matrix-formlet "3") req))
>>   ...)
>>
>> While this works, the formlet I use to display and process are not really
>> the same, since they are created on the spot, and created with different
>> parameters. So far it seems to work, but I am worried that this will break
>> down, and clearly this isn't the right way to go about creating
>> parametrizable formlets.
>>
>> The questions are (i) is the above going to work despite being a hack,
>>

Re: [racket-users] Why does 1 count as numeric in xexpr, but 0 does not?

2017-03-14 Thread Marc Kaufmann
Fair enough if that's the specification, even if it is unexpected (to me at 
least). Thanks,

Marc

On Tuesday, March 14, 2017 at 10:41:02 AM UTC-4, Jay McCarthy wrote:
> Hi Marc,
> 
> libxml2 only allows numeric entity references in this range:
> 
> * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
> * | [#x1-#x10]
> 
> Racket doesn't fully respect that, but both disallow 0. I think we
> should match libxml2 and tighten the contract.
> 
> Jay
> 
> -- 
> -=[ Jay McCarthy   http://jeapostrophe.github.io]=-
> -=[ Associate ProfessorPLT @ CS @ UMass Lowell ]=-
> -=[ Moses 1:33: And worlds without number have I created; ]=-

-- 
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 build new formlets that allow passing default values (such as hidden)?

2017-03-14 Thread Marc Kaufmann
Hi,

I have created a formlet like so:

(define (matrix-formlet id)
  (formlet
(#%# ,{input-string . => . ones}
 ,{(to-string (required (hidden id))) . => . user-id}
 )
(values ones user-id)))

I display this as follows:

`(form
  ((action "/the-matrix-submitted")
   (method "post"))
 ,@(formlet-display (matrix-formlet user-id))
 (input ([type "submit"]

and process it like this:

(define (matrix-submission req)
  (define-values (number-of-ones user-id)
 (formlet-process (matrix-formlet "3") req))
  ...)

While this works, the formlet I use to display and process are not really the 
same, since they are created on the spot, and created with different 
parameters. So far it seems to work, but I am worried that this will break 
down, and clearly this isn't the right way to go about creating parametrizable 
formlets. 

The questions are (i) is the above going to work despite being a hack, and (ii) 
is there a correct and easy way to do the same thing?

Cheers,
Marc

-- 
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] Why does 1 count as numeric in xexpr, but 0 does not?

2017-03-14 Thread Marc Kaufmann
I understand that the number 1 is different from the string (although I would 
probably have expected it to be turned into a string before being passed to the 
browser or something, but it doesn't matter for my purposes). What does 
surprise me is that (xexpr->string 1) gives , yet (xexpr->string 0) does not 
give  but throws an error. Is this due to the XML specification, or due to 
the Racket implementation of X-expressions?

Cheers,
Marc



On Monday, March 13, 2017 at 10:32:50 PM UTC-4, Philip McGrath wrote:
> Numbers in x-expressions are interpreted as XML entities, not as the string 
> representation of the number. The value of (xexpr->string '(html 1)), to use 
> your example, is "". The 1 represents the character that 
> Racket would represent as #\u0001, i.e. the value of (integer->char 1). In 
> contrast, (char->integer #\1) produces 49.
> 
> 
> 
> -Philip
> 
> 
> 
> On Mon, Mar 13, 2017 at 8:38 PM, Marc Kaufmann <marc.ka...@gmail.com> wrote:
> Hi,
> 
> 
> 
> I am creating matrices of 0s and 1s that I display in HTML-tables and 
> somewhat surprisingly I found out that 0s are not permissible in 
> X-expressions, while 1s are:
> 
> 
> 
> (require web-server/http)
> 
> 
> 
> (response/xexpr '(html 1)) ; Fine, no trouble.
> 
> (response/xexpr '(html 0)) ; Blow-up.
> 
> 
> 
> The specific violation is the following:
> 
> 
> 
> "response/xexpr: contract violation;
> 
>  Not an Xexpr. Expected a string, symbol, valid numeric entity, comment, 
> processing instruction, or list, given 0"
> 
> 
> 
> After some digging around, it turns out that only numbers that satisfy 
> valid-char? are acceptable, which means "exact-nonnegative-integer whose 
> character interpretation under UTF-8 is from the set ([#x1-#xD7FF] | 
> [#xE000-#xFFFD] | [#x1-#x10]), in accordance with section 2.2 of the 
> XML 1.1 spec."
> 
> 
> 
> First, should 0 really not be accepted? (I am not going to try and figure out 
> the UTF-8 interpretation...) And second, is the reason that negative numbers 
> are not acceptable that they are not under the XML spec above? This took me 
> by surprise and means I have to put number->string in a bunch of places.
> 
> 
> 
> Cheers,
> 
> Marc
> 
> 
> 
> --
> 
> 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...@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] Require the same file repeatedly for debugging on command line

2017-03-13 Thread Marc Kaufmann
Hi all,

while trying to debug, I often change the code in the text file and then want 
to do a (require "file-with-code.rkt") on the command line to test the new 
code. This never works, because I cannot redefine imported modules. Thus I 
always use Dr Racket for this, where I can hit the "Run" button, which reruns 
everything and all is good. Since I prefer to use Vim for editing, I was 
wondering if there is an equivalent of the "Run" button for the command line 
(well, for the require at least)?

Thanks,
Marc

-- 
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] Why does 1 count as numeric in xexpr, but 0 does not?

2017-03-13 Thread Marc Kaufmann
Hi,

I am creating matrices of 0s and 1s that I display in HTML-tables and somewhat 
surprisingly I found out that 0s are not permissible in X-expressions, while 1s 
are:

(require web-server/http)

(response/xexpr '(html 1)) ; Fine, no trouble.
(response/xexpr '(html 0)) ; Blow-up.

The specific violation is the following:

"response/xexpr: contract violation;
 Not an Xexpr. Expected a string, symbol, valid numeric entity, comment, 
processing instruction, or list, given 0"

After some digging around, it turns out that only numbers that satisfy 
valid-char? are acceptable, which means "exact-nonnegative-integer whose 
character interpretation under UTF-8 is from the set ([#x1-#xD7FF] | 
[#xE000-#xFFFD] | [#x1-#x10]), in accordance with section 2.2 of the 
XML 1.1 spec." 

First, should 0 really not be accepted? (I am not going to try and figure out 
the UTF-8 interpretation...) And second, is the reason that negative numbers 
are not acceptable that they are not under the XML spec above? This took me by 
surprise and means I have to put number->string in a bunch of places.

Cheers,
Marc

-- 
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] Re: Plot with text annotation inside the graph

2016-10-16 Thread Marc Kaufmann
Thanks Alex, that does the trick.

On Saturday, October 15, 2016 at 12:58:28 AM UTC-4, Alex Harsanyi wrote:
> You could try using a point-label or a function-label with a point size of 0, 
> like this:
> 
> (plot (list (function-interval sin (lambda (x) 0))
> (function-label (lambda (x) (* (sin x) 0.2)) -1.8 "sin(x)" 
> #:point-size 0))
>   #:x-min -2 #:x-max 2)
> 
> Alex.
> 
> On Saturday, October 15, 2016 at 10:29:07 AM UTC+8, Marc Kaufmann wrote:
> > Hi all,
> > 
> > I am creating some graphs where I want to label various regions as region 
> > A, B, C, and so on. Currently I am doing this by coloring the regions 
> > differently and having the labels in legend: 
> > 
> > (plot-file 
> >   (list 
> > (axes)
> > (function-interval (lambda (x) 0) MD 0 E_x #:label "F")
> > (function-interval 
> >   (lambda (x) (MD E_x)) 
> >   (lambda (x) 0) 
> >   e_x E_x
> >   #:color 4 #:line1-color 4 #:line2-color 4
> >   #:label "G"))
> >   "graph-proof-which-task-completed-2.pdf"
> >   #:x-label "Instantaneous effort"
> >   #:y-label "Marginal Disutility")
> > 
> > This becomes problematic with multiple regions since it is hard to 
> > distinguish the colors (or line styles). Is there a way to place a label 
> > "A" in the region "A"? 
> > 
> > Thanks,
> > 
> > Marc

-- 
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] Plot with text annotation inside the graph

2016-10-14 Thread Marc Kaufmann
Hi all,

I am creating some graphs where I want to label various regions as region A, B, 
C, and so on. Currently I am doing this by coloring the regions differently and 
having the labels in legend: 

(plot-file 
  (list 
(axes)
(function-interval (lambda (x) 0) MD 0 E_x #:label "F")
(function-interval 
  (lambda (x) (MD E_x)) 
  (lambda (x) 0) 
  e_x E_x
  #:color 4 #:line1-color 4 #:line2-color 4
  #:label "G"))
  "graph-proof-which-task-completed-2.pdf"
  #:x-label "Instantaneous effort"
  #:y-label "Marginal Disutility")

This becomes problematic with multiple regions since it is hard to distinguish 
the colors (or line styles). Is there a way to place a label "A" in the region 
"A"? 

Thanks,

Marc

-- 
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] Include link in email: what headers to use?

2016-03-27 Thread Marc Kaufmann
Ah, of course "extra-header ... " means there can be several of them -
which I know, but forgot in this context. On the other hand, I also didn't
realize that "Conten-Type: text/html; charset=iso-8859-1" was a single
header either, so I would still have gotten it wrong.

Works like a charm now, thank.

On Sun, Mar 27, 2016 at 1:42 AM, Jon Zeppieri <zeppi...@gmail.com> wrote:

> The `extra-header` parameter is a rest parameter, so you're supposed to
> pass one string per header, not a single string containing all of them.
> And, if you were going to send them all in a single string, you'd need to
> separate them with an \r\n sequence, not with semicolons. So pass two
> separate strings as the last two arguments:
>
> "Return-Path: <mkaufm...@g.harvard.edu>"
> "Content-Type: text/html; charset=iso-8859-1"
>
> -Jon
>
> On Sun, Mar 27, 2016 at 1:18 AM, Marc Kaufmann <marc.kaufman...@gmail.com>
> wrote:
>
>> Hi all,
>>
>> I am sending out emails with sendmail, and found a PHP thread [1] on the
>> headers one should include in order to be able to use html in the emails -
>> I want this only to make the links look nice, e.g. > href="i-am-long-and-ugly">Pretty.
>>
>> Unfortunately, adding "Return-Path: <mkaufm...@g.harvard.edu>;
>> Content-type: text/html; charset=iso-8859-1;" as the extra-header string to
>> sendmail has absolutely no effect and the html gets simply printed as text.
>>
>> I don't know whether this is due to Racket, sendmail, or the sendmail
>> configuration on my system, so let me know if I should look elsewhere for
>> solutions.
>>
>> Cheers,
>> Marc
>>
>> [1]:
>> http://stackoverflow.com/questions/15711700/php-mail-how-to-put-an-html-link-in-an-email
>>
>> --
>> 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.


  1   2   >