[racket-users] New lightweight termios package: rktermios

2020-09-21 Thread Dominik Pantůček
Hello Racketeers,

as I learned that it is not possible to use the ansi package under CS,
because the C extensions do not work under CS, I decided to put together
a minimalistic termios wrapper using only Racket code.

It provides the bare minimum to set the terminal to "raw" mode and
should work under any POSIX system (tested on Linux and NetBSD). Usage
is VERY simple[1].

The ansi package can be patched immediately to use it and therefore work
under CS and charterm can be probably be patched as well - meaning it
will no longer rely on `stty' for this functionality.

The termios package uses similar approach but tries to implement all
termios capabilities which means it has to compile at least the
constants from termios headers. The same applies for serial package. It
might be possible to generate a .rkt file with those constants from the
header files during package build - but I didn't investigate that yet.

Any feedback is, of course, welcome. And all the ideas mentioned are
only suggestions.


Cheers,
Dominik

[1] https://docs.racket-lang.org/rktermios/index.html

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/756b73f6-919e-fef2-b81c-7ad19fa1378c%40trustica.cz.


Re: [racket-users] Package index

2020-09-21 Thread Dominik Pantůček
Hi,

I confirm the issue. I am already a registered user but adding a new
package fails with:

Proxy Error

The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request GET /pkgn/package/rktermios.

Reason: Error reading from remote server

Apache/2.4.7 (Ubuntu) Server at pkgd.racket-lang.org Port 443


Can anyone, please, look into it?


Cheers,
Dominik

On 19. 09. 20 18:01, Griffin Byatt wrote:
> Hi all,
> 
> I’ve been unable to register on the package index for the last two days. 
> Entering my email address for a registration code results in an error and 
> stack trace.
> 
> Can anyone confirm that this also happens for them? 
> 
> Thanks,
> Griffin
> 

-- 
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/2e36ecd1-a5cd-f018-40df-4dc5be46ba7c%40trustica.cz.


Re: [racket-users] Scribbling hexadecimal values

2020-09-19 Thread Dominik Pantůček
Hi Eric,

thank you. Actually I was already using unsyntax for putting the default
values in optional arguments list and didn't recognize that I can use
anything from the scribble API at that point. Now the formatting of
default values is simple and yields expected results. In my case:

(()
   ((argb #,(racketvalfont (format "#x~x" (arithmetic-shift alpha-max
24))

This is really cool.

However, for the contract part, I think the only solution would be
adding a parameter that would change the behavior of
proc-doc-transformer and proc-doc/names transformer or more generally
add support to *defproc's do-one' arg-contracts handling code.

This basically goes down to racketblock0 rendering of numbers.

I am afraid that this needs some with more experience with scribble
internals to implement. I think that adding parameter to configure the
rendering of numbers inside define-code-like forms will be rather easy.
But how to parameterize in provide block and not mess with any of those
proc-doc*transformer code is currently beyond my understanding.

I would appreciate any hints though.


Cheers,
Dominik

On 19. 09. 20 3:40, Eric Griffis wrote:
> Hi Dominik,
> 
> If you put the hex number in a string, many of the formatting functions
> in the Scribble manual, section 4.2.1.4 will work:
> 
>   (proc-doc/names
>    name
>    (->* () (integer?) void?)
>    (()
>     ((argument #,(racketvalfont "#x1f"
>    @{ some description }))
> 
> Eric
> 
> 
> On Fri, Sep 18, 2020 at 2:23 PM Dominik Pantůček
> mailto:dominik.pantu...@trustica.cz>> wrote:
> 
> Hello Racketeers,
> 
> I am struggling to make scribble typeset default values in
> proc-doc/names in hexadecimal. An example would be:
> 
> (proc-doc/names
>   name
>   (->* () (integer?) void?)
>   (()
>    ((argument #x1f)))
>   @{ some description }) ; yes, at-exp reader
> 
> The same applies to values in nested contracts of ->* - like (integer-in
> 0 #x1f).
> 
> Of course #,(~a "~x" #x1f) will produce the string with appropriate
> contents - but enclosed in parentheses which does not help much. Also it
> is not just a matter of typesetting because the provide form really
> contracts the procedure being provided and the actual values should
> actually be present.
> 
> I would love to see some documentation-stage parameter where I could
> just (parameterize ((numbers-as-hexadecimal #t)) (integer-in ...) ...)
> and it would keep the values as they are for contract purposes and
> render them hexadecimal. Of course, this is quite specific - more
> generic solution is probably more appropriate, this is just to explain
> the problem I am trying to solve.
> 
> 
> Cheers,
> Dominik
> 
> -- 
> 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
> <mailto:racket-users%2bunsubscr...@googlegroups.com>.
> To view this discussion on the web visit
> 
> https://groups.google.com/d/msgid/racket-users/aca5b2ab-36b6-98c6-0747-9d5447ae9766%40trustica.cz.
> 

-- 
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/23557632-fe68-567e-3a2e-c9abf6df5779%40trustica.cz.


[racket-users] Scribbling hexadecimal values

2020-09-18 Thread Dominik Pantůček
Hello Racketeers,

I am struggling to make scribble typeset default values in
proc-doc/names in hexadecimal. An example would be:

(proc-doc/names
  name
  (->* () (integer?) void?)
  (()
   ((argument #x1f)))
  @{ some description }) ; yes, at-exp reader

The same applies to values in nested contracts of ->* - like (integer-in
0 #x1f).

Of course #,(~a "~x" #x1f) will produce the string with appropriate
contents - but enclosed in parentheses which does not help much. Also it
is not just a matter of typesetting because the provide form really
contracts the procedure being provided and the actual values should
actually be present.

I would love to see some documentation-stage parameter where I could
just (parameterize ((numbers-as-hexadecimal #t)) (integer-in ...) ...)
and it would keep the values as they are for contract purposes and
render them hexadecimal. Of course, this is quite specific - more
generic solution is probably more appropriate, this is just to explain
the problem I am trying to solve.


Cheers,
Dominik

-- 
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/aca5b2ab-36b6-98c6-0747-9d5447ae9766%40trustica.cz.


Re: [racket-users] new racket-lang.org website

2020-08-25 Thread Dominik Pantůček



On 26. 08. 20 0:09, Robby Findler wrote:
> I've put a version that uses 550 pixels as a cutoff here, in case that
> the 1080 really was
> 540: https://users.cs.northwestern.edu/~robby/tmp/Web/www/

This is displayed correctly using any browser on the S61 now. So
probably it is the case of those 540 "pixels". Great job! (Not just the
fix, the whole new website, actually).


Dominik

> 
> Robby
> 
> 
> On Tue, Aug 25, 2020 at 5:06 PM Robby Findler  <mailto:ro...@cs.northwestern.edu>> wrote:
> 
> Thanks Dominik. Currently the site uses the predicate "less than 460
> pixels wide?" to determine if it should switch to single-column /
> phone mode. That seemed to work for the 3-4 phones (narrow) and
> tablets (wide) that I tried but I'm certainly not well versed in
> these kinds of things. The specific expression it uses is here:
> 
>   
> https://github.com/racket/racket-lang-org/blob/master/www/css/styles.css.pp#L543
> 
> (and then a bit further down is the negated version of that same
> predicate). 
> 
> If you (or anyone!) has advice on how to improve this, that'd be
> welcome.
> 
> It may be that the right approach is to adjust the font sizes, as
> 1080x1920 sounds really wide. Is it possible that's a retina-style
> display and the logical number is actually 540 wide? Maybe that's a
> better cutoff for switching?
> 
> Robby
> 
> 
> On Tue, Aug 25, 2020 at 3:45 PM Dominik Pantůček
> mailto:dominik.pantu...@trustica.cz>>
> wrote:
> 
> On 25. 08. 20 22:35, Laurent wrote:
> 
> > Or maybe Dominik checked something like "Always display the
> desktop
> 
> > version for this site"? (FWIW it displays nicely on a
> 2,280x1,080 pixels
> 
> > phone screen)
> 
> 
> 
> I wish that was the case. The screenshot comes from Lightning
> browser,
> 
> however I get the same result from Chrome (default on my Cat S61
> Phone)
> 
> and mobile Firefox too.
> 
> 
> 
> It's 1080x1920 with default Android 9 as shipped by the
> manufacturer.
> 
> Actually I am using this device for testing our mobile apps (yes
> ...).
> 
> 
> 
> Of course, changing the orientation to landscape makes it
> display the
> 
> desktop version correctly.
> 
> 
> 
> Sadly, I can only help by reporting as much information as possible.
> 
> 
> 
> 
> 
> Dominik
> 
> 
> 
> >
> 
> > On Tue, Aug 25, 2020 at 9:13 PM Robby Findler
> mailto:ro...@cs.northwestern.edu>
> 
> > <mailto:ro...@cs.northwestern.edu
> <mailto:ro...@cs.northwestern.edu>>> wrote:
> 
> >
> 
> >     It looks like your phone has enough pixels width wise that
> the site
> 
> >     thinks it is a normal machine (albeit uncomfortably
> narrow). If
> 
> >     things are slightly narrower you'll see the site changes. I am
> 
> >     attaching two screenshots from my phone. 
> 
> >
> 
> >     Robby 
> 
> >
> 
> >
> 
> >
> 
> >
> 
> >
> 
> >     On Tue, Aug 25, 2020 at 2:59 PM Dominik Pantůček
> 
> >      <mailto:dominik.pantu...@trustica.cz>
> <mailto:dominik.pantu...@trustica.cz
> <mailto:dominik.pantu...@trustica.cz>>>
> 
> >     wrote:
> 
> >
> 
> >         Hi,
> 
> >
> 
> >         apparently the new design is not very mobile-friendly
> as can be
> 
> >         seen on the attached screenshot. If somebody has the
> skills and
> 
> >         time, this should probably be fixed soon.
> 
> >
> 
> >         D.
> 
> >
> 
> >
> 
> >         On August 25, 2020 7:51:40 PM GMT+02:00, Robby Findler
> 
> >          <mailto:ro...@cs.northwestern.edu>
> <mailto:ro...@cs.northwestern.edu
> <mailto:ro...@cs.northwestern.edu>>>
> 
> >         wrote:
> 
> >
> 
> >
> 
> >
> 
> >             Hi all: as you may know if you follo

Re: [racket-users] new racket-lang.org website

2020-08-25 Thread Dominik Pantůček
On 25. 08. 20 22:35, Laurent wrote:
> Or maybe Dominik checked something like "Always display the desktop
> version for this site"? (FWIW it displays nicely on a 2,280x1,080 pixels
> phone screen)

I wish that was the case. The screenshot comes from Lightning browser,
however I get the same result from Chrome (default on my Cat S61 Phone)
and mobile Firefox too.

It's 1080x1920 with default Android 9 as shipped by the manufacturer.
Actually I am using this device for testing our mobile apps (yes ...).

Of course, changing the orientation to landscape makes it display the
desktop version correctly.

Sadly, I can only help by reporting as much information as possible.


Dominik

> 
> On Tue, Aug 25, 2020 at 9:13 PM Robby Findler  <mailto:ro...@cs.northwestern.edu>> wrote:
> 
> It looks like your phone has enough pixels width wise that the site
> thinks it is a normal machine (albeit uncomfortably narrow). If
> things are slightly narrower you'll see the site changes. I am
> attaching two screenshots from my phone. 
> 
> Robby 
> 
> 
> 
> 
> 
> On Tue, Aug 25, 2020 at 2:59 PM Dominik Pantůček
> mailto:dominik.pantu...@trustica.cz>>
> wrote:
> 
> Hi,
> 
> apparently the new design is not very mobile-friendly as can be
> seen on the attached screenshot. If somebody has the skills and
> time, this should probably be fixed soon.
> 
> D.
> 
> 
> On August 25, 2020 7:51:40 PM GMT+02:00, Robby Findler
> mailto:ro...@cs.northwestern.edu>>
> wrote:
> 
> 
> 
> Hi all: as you may know if you follow dev@, we've been
> revising the website. The new version went live last night;
> please have a look: https://www.racket-lang.org/
> 
> A big Thank You to Matthew Butterick for the previous design
> which, as you can tell, inspired the current visual design.
> 
> Matthew, Robby, Sam, Jay, John, and Matthias
> 
> 
> 
> 
> 
> 
> -- 
> Sent from my Android device with K-9 Mail. Please excuse my brevity.
> 
> 
> 
> 
> 
> 
> 
> 
> -- 
> 
> 
> 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
> <mailto:racket-users+unsubscr...@googlegroups.com>.
> 
> 
> To view this discussion on the web visit
> 
> https://groups.google.com/d/msgid/racket-users/1FFB85C8-D1E3-4E72-8A1D-8DD38FE5FF05%40trustica.cz
> 
> <https://groups.google.com/d/msgid/racket-users/1FFB85C8-D1E3-4E72-8A1D-8DD38FE5FF05%40trustica.cz?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
> <mailto:racket-users+unsubscr...@googlegroups.com>.
> To view this discussion on the web visit
> 
> https://groups.google.com/d/msgid/racket-users/CAL3TdONGCQyDnCRt42t%2B-KnOBq8XZmU71%2BTUxwkC%3Dw9TJsMb3w%40mail.gmail.com
> 
> <https://groups.google.com/d/msgid/racket-users/CAL3TdONGCQyDnCRt42t%2B-KnOBq8XZmU71%2BTUxwkC%3Dw9TJsMb3w%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
> <mailto:racket-users+unsubscr...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/CABNTSaEfeHBnQkb_%3Dq2E2t6%3DD3_PEcMrN7cbSXCZza%3DXjFVfvA%40mail.gmail.com
> <https://groups.google.com/d/msgid/racket-users/CABNTSaEfeHBnQkb_%3Dq2E2t6%3DD3_PEcMrN7cbSXCZza%3DXjFVfvA%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/07d6669c-8b59-766d-c527-19a8e862246b%40trustica.cz.


Re: [racket-users] trying to use futures for some calculations

2020-06-17 Thread Dominik Pantůček
Hi Alex,

I finally got to investigate the issue in depth. And there are two major
problems blocking your implementation from running the futures in parallel.

1) Allocations of boxed flonums. I tried to get rid of those by
allocating "scratchpad" flvectors and mapping everything onto them. The
future scheduling started to look different, however there are many
allocations because of your loops in functions cp3-futures and
evaluate-cost.

I didn't finish the work though, because I noticed another strange
thing. The Typed Racket code in the lambda function returned by spline
(your mmax-fn argument) blocks almost entirely the parallel execution on
... type checks.

2) All those =, < and friends just block it.

So how to fix this? Well, it is relatively easy albeit quite a lot of
manual work.

(I am looking only at the cp3-futures function when talking about
possible improvements).

* Change the all the for loops for let loop forms and use preallocated
flvectors to hold all the values.
* Switch to racket/unsafe/ops for everything inside futures (this is not
necessary, but takes away a few possible surprises)
* Restructuralize the way you split the work into 30 futures and just
use a binary tree of futures as suggested earlier.
* Use racket/unsafe/ops from regular racket to implement the spline
interpolation. I would also move the coefficients into one huge flvector
and forgot about lists at all. This is very specific workload.

And do not worry about GCs. Once you get rid of all allocations inside
futures, the GCs will disappear.

Also bear in mind that my suggestions are rather low level. By following
them you will get the algorithm to scale over multiple cores if you
really need it. Just remember it will be at a huge cost to readability.
You can slightly mitigate this by some refactoring and custom syntax,
but that is even more work and I would really consider whether you need
the parallelism for a computation that takes a few seconds anyway.

Of course, if you plan to use your algorithm for much bigger data set,
this is the way to go (including the custom syntax).


Cheers,
Dominik

On 17. 06. 20 10:50, Alex Harsanyi wrote:
> 
> I am trying to speed up an algorithm using futures, but I am getting
> some unexpected results (and no real speed improvements), and I was
> wondering if someone more experienced could have a look a the code and
> tell me what am I doing wrong.
> 
> I put up the code in this repository:
> https://github.com/alex-hhh/cp3-exeriments, unfortunately it is the
> simplest meaningful example that I can come up with.  Most of the
> functions, however are just support functions and there are six
> implementation of the same algorithm.
> 
> Basically, the problem I am trying to solve is to fit a model to
> existing data and this is done by evaluating 2.5 million combinations of
> parameters.  My best, non-futures based, algorithm can do this in about
> 3 seconds (8 seconds in DrRacket).
> 
> Given that each of this 2.5 million combination is completely
> independent from the others, they could all be done in parallel.  Given
> this, I "sliced" the combinations into 30 groups and tried to perform
> each "slice" in its own future and select the best among the 30 results
> produced by these futures.
> 
> Unfortunately, while the futures versions of the algorithm produce the
> correct result, the algorithm runs at the same speed as the non-futures
> version.  My `processor-count` returns 8, so I would expect at least
> some level of parallelism.
> 
> As a first step, I tried using `would-be-future`, to see if it reported
> any operations which might block, but nothing was printed out.
> 
> I also tried using the futures visualized, and I found the following:
> 
> * the code appears to be blocking on primitive operations, such as +, -,
> < etc.
> * I suspect these operations are inside the code generated by the `for`
> loops, so I am not sure how to remove them without making the code even
> more difficult to read.
> * there seems to be a lot more time spent in the garbage collector when
> running the futures visualizer than without it (DrRacket runs with
> unlimited memory)
> 
> So I am wondering if someone who is more familiar with futures can look
> at the code and provide some hints about what can be done to make this
> code run in parallel (or if it cannot, I would like to understand why).
> 
> This is already a long message, so I will not add further details here,
> but the repository at https://github.com/alex-hhh/cp3-exeriments has an
> explanation of what every function does, and I am happy to provide
> further clarifications if needed.
> 
> Thanks,
> 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
> .
> To view this discussion on the web visit

Re: [racket-users] Re: trying to use futures for some calculations

2020-06-17 Thread Dominik Pantůček
I've looked at it only briefly (it's the end of the semester and grading
is due soon).

> 
> 
> I would *love* to be proven wrong on this, but I think it's rare to
> be able to get decent parallelization in practice using futures. You
> may have better results using places, but it will depend on how the
> amount of processing for a unit compares to the overhead of
> communicating with the places i.e. you may get better results with 2
> places than with 8 due to place communication overhead. In your
> case, if it's easy for the places to input their own sets of
> parameters, then the place overhead may be small since I think each
> place would simply need to communicate its best value.
> 

This is not even remotely true, I am using futures to get 100%
utilization on all cores available. The current situation is that it
takes quite some effort to leverage futures to get there.

A few generic remarks first. Arbitrary partitioning does not work well
with futures. I always partition the work based on the processor-count
with something like:

(define futures-depth (make-parameter (inexact->exact (ceiling (log
(processor-count) 2)

(define-syntax (define-futurized stx)
  (syntax-case stx ()
((_ (proc start end) body ...)
 #'(begin
 (define max-depth (futures-depth))
 (define (proc start end (depth 0))
   (cond ((fx< depth max-depth)
  (define mid (fx+ start (fxrshift (fx- end start) 1)))
  (let ((f (future
(λ ()
  (proc start mid (fx+ depth 1))
(proc mid end (fx+ depth 1))
(touch f)))
 (else
  body ...)))

Of course all those fx+, fx- and fx< must be unsafe versions from
racket/unsafe/ops.

Second problem is the allocation of flonums. The inner part of the loop
looks like even with flonums inlining it triggers the allocator more
than often. With CS just forget about this before the inlined flonums
are merged. In the meantime, you can drop the for/fold and use flvector
to store and accumulate whatever you need. Using futures-vizualizer is a
good start.

I'll look into it later this week. But generally you need to stick to
unsafe ops and avoid the allocator.

> 
> 
> While this may be true, it is also the case that the design of futures
> is such that incremental work on the primitives turns into incremental
> ability to parallelize programs. So while it is likely to be more work
> today, it may also be the case that people putting effort in to help
> their own programs will help us turn the corner here. Perhaps this is a
> place where an interested contributor can help us out a lot!

It is on the list :)


Dominik

-- 
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/16fc95cf-5e46-50b6-2d9d-0e336ff1be37%40trustica.cz.


[racket-users] Possible bug in vector-cas!

2020-05-30 Thread Dominik Pantůček
Hello Racketeers,

it didn't take long before I hit another strange behavior when
extensively using futures. The setup is relatively simple: I am
processing a large fxvector/flvector and I am processing it on a
line-by-line basis (the vectors themselves are width*height in nature).
To avoid races I setup a (make-vector height #f) to serve as a vector of
locks. Locking is simple:

(let lloop ()
  (when (not (vector-cas! locks y #f #t))
(lloop)))

.. do something ...

(vector-set! locks y #f)

Of course, the code in question is in 8 futures on my CPU and they are
scheduled in parallel pretty consistently.

Most of the time it works fine, but sometimes it just hangs with
multiple CPU cores being utilized at 100% (I assume they are in the
busy-wait "lloop").

The problem is I cannot isolate a minimal working example from that. The
code in question is about 3000 LoC and the issue expresses itself only
in about 1 in 30 times just after the program has started. The GUI
thread is running and there are lots of flonum operations and lots of
thrown away flonum results (meaning GC gets triggered quite often).

Also I cannot trigger the same issue with unsafe-vector*-cas! - I'll
look into the differences in the source.

I see this with latest Racket 3m.

Any suggestions how to approach finding the source of the problem are -
as always - very welcome.


Cheers,
Dominik

-- 
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/0e6de88c-1d39-38fa-ea69-2043c4f4071b%40trustica.cz.


Re: [racket-users] Hunting a possible fsemaphore-post/wait bug

2020-05-24 Thread Dominik Pantůček


On 24. 05. 20 3:38, Matthew Flatt wrote:
> At Sat, 23 May 2020 18:51:23 +0200, Dominik Pantůček wrote:
>> But that is just where the issue is showing up. The real question is how
>> the counter gets decremented twice (given that fsemaphores should be
>> futures-safe).
> 
> I found a configuration that triggered the bug often enough on my
> machine. Yes, it was a dumb mistake in the implementation of
> fsemaphores. In your example, it wasn't so much that the counter
> fsemaphore was decremented twice, but that the lock fsemaphore could go
> negative --- so it didn't actually lock.
> 
> I've pushed a repair.

Thank you for the repair (and good idea with the test case).

> 
> 
> FWIW, after looking at this example more, I see why it's still not
> enough in principle to make a thread that waits on the result of
> `do-start-workers` or to run `do-start-workers` after the enqueue
> loops. The `start-workers` function can run a dequeue loop after
> starting a future to do the same, and before touching that future. So,
> the dependencies aren't as linear as I thought before.
> 
> If your real code looks anything like this, consider using a CAS
> operation, like `box-cas!`, instead of an fsemaphore as lock for the
> queue. The queue's use of an fsemaphore for counting and signaling
> seems fine, though.
> 

Yes, the real code is a binary tree of futures. However each future
performs a lot of fixnum/flonum operations.

At first I was surprised that you are basically suggesting using
spinlocks (busy-wait loops) instead of futex-backed (at least on Linux)
fsemaphores. That is a waste of CPU time... But yes, CAS-based locking
outperforms fsemaphores locking and distributes the work way more
evenly. Now when I see it in action and look at the source it kind of
makes sense as the spinlock does not need to wait long and does not
cause any re-scheduling (which is the reason why I get so uneven counts
with fsemaphore-based locking).

> In any case, the example worked well to expose the fsemaphore bug.
> 

Probably expect to see more in the future :)



Dominik

-- 
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/9fdcb07a-a596-fc84-5529-4517f6b8b1fd%40trustica.cz.


Re: [racket-users] Hunting a possible fsemaphore-post/wait bug

2020-05-23 Thread Dominik Pantůček


On 23. 05. 20 19:24, Matthew Flatt wrote:
> I'm not sure this is the problem that you're seeing, but I see a
> problem with the example. It boils down to the fact that futures do not
> provide concurrency.
> 
> That may sound like a surprising claim, because the whole point of
> futures is to run multiple things at a time. But futures merely offer
> best-effort parallelism; they do not provide any guarantee of
> concurrency.

It might be surprising as well - but that is exactly the reason I am
using futures for this task. Up until now I always built a data set and
then have setup a futures tree to process that data set - possibly in
parallel. But with no assumptions about whether it will happen in parallel.

What I am trying to achieve now is to allow the futures scheduling start
speculatively working on the data set while it is being created. And
yes, I don't want to make any assumptions about it actually starting or
even being run in parallel. I just want to provide the futures runtime
with the best setup, so it can also do the best.

Using os-threads with explicit scheduling is something I want to
investigate as well - but generally I do not see why this shouldn't work
as expected (with the great advantage that it can fallback on
program-level single-thread and not OS-run threads interleaved on the
same core transparent to the program).

> 
> As a consequence, trying to treat an fsemaphore as a lock can go wrong.
> If a future manages to take an fsemaphore lock, but the future is not
> demanded by the main thread --- or in a chain of future demands that
> are demanded by the main thread --- then nothing obliges the future to
> continue running; it can hold the lock forever.

Duly noted. I'll look into that possibility. But honestly, I've never
encountered such behavior.

> 
> (I put the blame on femspahores. Adding fsemaphores to the future
> system was something like adding mutation to a purely functional
> language. The addition makes certain things possible, but it also
> breaks local reasoning that the original design was supposed to
> enable.)

I understand and - another surprise - I agree. The example is very
"imperative", but that is really bare-bones example of the problem.

> 
> In your example program, I see
> 
>  (define workers (do-start-workers))
>  (displayln "started")
>  (for ((i 1))
>(mfqueue-enqueue! mfq 1))
> 
> where `do-start-workers` creates a chain of futures, but there's no
> `touch` on the root future while the loop calls `mfqueue-enqueue!`.
> Therefore, the loop can block on an fsemaphore because some future has
> taken the lock but stopped running for whatever reason.
> 
> In this case, adding `(thread (lambda () (touch workers)))` before the
> loop after "started" might fix the example. In other words, you can use
> the `thread` concurrency construct in combination with the `future`
> parallelism construct to ensure progress. I think this will work
> because all futures in the program end up in a linear dependency chain.
> If there were a tree of dependencies, then I think you'd need a
> `thread` for each `future` to make sure that every future has an active
> demand.

The same thing happens if I (do-start-workers) after filling the queue
using mfqueue-enqueue!.

> 
> If you're seeing a deadlock at the `(touch workers)`, though, my
> explanation doesn't cover what you're seeing. I haven't managed to
> trigger the deadlock myself.

Should I open an issue at github and provide the gdb backtraces?

Btw, none of this behaviour is seen with Racket CS (so far) and the
observed futures scheduling is speculative very aggresively with CS
variant (which is definitely what I want).

I am running 3m v7.7.0.6 compiled from sources on Ubuntu 20.04 if that
helps.



And (as usual) - thank you very much!

Dominik

-- 
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/393d7b45-38bb-8384-a34c-7bacbd517424%40trustica.cz.


[racket-users] Hunting a possible fsemaphore-post/wait bug

2020-05-23 Thread Dominik Pantůček
Hello again with futures!

I started working on futures-based workers and got quickly stuck with a
dead-lock I think does not originate in my code (although it is two
semaphores, 8 futures, so I'll refrain from strong opinions here).

I implemented a very simple futures-friendly queue using mutable pairs
and created a minimal-deadlocking-example[1]. I am running racket 3m
7.7.0.4 which includes fixes for the futures-related bugs I discovered
recently.

Sometimes the code just runs fine and shows the numbers of worker
iterations performed in different futures (as traced by the 'fid'
argument). But sometimes it locks in a state where there is one last
number in the queue (0 - zero) and yet the fsemaphore-count for the
count fsemaphore returns 0. Which means the semaphore was decremented
twice somewhere. The code is really VERY simple and I do not see a
race-condition within the code, that would allow any code path to
decrement the fsema-count fsemaphore twice once the worker future
receives 0.

I am able to reproduce the behavior with racket3m running under gdb and
get the stack traces for all the threads pretty consistently. The
deadlock is apparently at:

  2Thread 0x77fca700 (LWP 46368) "mfqueue.rkt"
futex_wait_cancelable (private=, expected=0,
futex_word=0x559d8e78) at ../sysdeps/nptl/futex-internal.h:183

But that is just where the issue is showing up. The real question is how
the counter gets decremented twice (given that fsemaphores should be
futures-safe).

Any hints would be VERY appreciated!


Cheers,
Dominik

[1] http://pasterack.org/pastes/28883

-- 
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/5dcf1260-e8bf-d719-adab-5a0fd9378075%40trustica.cz.


Re: [racket-users] Cross-building Racket applications for 64bit Windows on Linux

2020-05-23 Thread Dominik Pantůček
I'll try with 3m. I am a bit skeptical here - as the resulting
program.exe is about 150M when properly build and apparently has to
include a lots of native DLLs. But reading the documentation (again)
makes me think that generally it should work.

Technically the byte-code should be platform-independent for 3m and then
it is just a matter of pre-prending the right binary and packing-in the
libraries. I will definitely look into that.


Thank you!

Dominik

On 23. 05. 20 18:38, Matthew Flatt wrote:
> Thinking about this a little more, I don't think all the pieces are in
> place for CS. At least, I don't remember setting up all the pieces...
> 
> The extra piece needed for Racket CS is a Chez Scheme cross-compiler
> that runs on Linux but produces machine code for Windows. That can be
> done --- and it is done, because our distributions for Windows are
> built on Linux (without wine). But I don't think the cross compilers
> are stashed anywhere right now, and we'll need to offer NxM cross
> compilers for N host systems and M target systems.
> 
> So, if building on a Linux target for Windows works for BC (which is a
> different question than trying to run BC on wine), then we can start
> thinking about how to fill in the last NxM pieces for CS.
> 
> At Sat, 23 May 2020 10:25:31 -0600, Matthew Flatt wrote:
>> Have you already tried using `raco exe` on Linux (i.e., using Racket
>> for Linux) but generating Windows executables?
>>
>>   https://docs.racket-lang.org/raco/cross-system.html
>>
>>
>> Note that the "tarball" distributions at places like
>>
>>https://download.racket-lang.org/releases/7.7/
>>
>> can be handy for setting up a .
>>
>>
>> At Sat, 23 May 2020 17:39:58 +0200, Dominik Pantůček wrote:
>>> Hello Racketeers,
>>>
>>> although I am developing Racket applications on Linux, our customers are
>>> usually running Windows. The good thing about Racket (and racket/gui
>>> especially) is that it requires virtually no OS-specific code for many -
>>> even non-trivial - tasks. However it is not that straightforward to
>>> produce binaries for different target platform.
>>>
>>> Since last summer, we have been successfully using wine and Racket
>>> Windows builds to create 32bit binaries. However with Racket BC it was
>>> impossible to make it work with 64bit Windows builds. This is still the
>>> case even with latest snapshots and latest wine bundled with Ubuntu 20.04.
>>>
>>> It turns out, that Racket CS works flawlessly under wine - including
>>> raco.exe exe. And with the latest patches[1] (thanks Matthew and
>>> DaLynX), it is possible to produce working 64bit Windows binaries from
>>> Racket programs on Linux using wine.
>>>
>>> As my work is heavily CPU- and memory-bound, the 32bit address space
>>> limit was quite a limit.
>>>
>>> However, once we tried to embed the build process into our
>>> (Gitlab-based) CI/CD, we failed miserably. Combining wine and Racket
>>> windows builds (7.7.0.6 snapshots from University of Utah) turned out to
>>> be a terrible nightmare under Docker.
>>>
>>> On my workstation, it is absolutely straightforward:
>>>
>>> rm -fr ~/.wine # Do not try this without backing up, if you need it
>>> wine racket-7.7.0.6-x86_64-win32-cs.exe
>>>
>>> Now just click next next next with the installer and you are ready.
>>> Building a 64bit Windows binary is just a matter of single:
>>>
>>> wine ~/.wine/drive_c/Program\ Files/Racket-7.7.0.6/raco.exe exe --gui
>>> --embed-dlls program.rkt
>>>
>>> Of course, any packages needed have to be installed using raco.exe pkg
>>> in the same wine prefix.
>>>
>>> But when you take the ~/.wine prefix and try to run it under docker,
>>> nothing works at all and tracing what is happening is extremely
>>> difficult with very cryptic results.
>>>
>>> We ruled out X11 dependency - raco.exe works just fine after I `unset
>>> DISPLAY` on my workstation. And the results in Docker are no different
>>> with Xvfb installed and running. We got to a point where the raco.exe
>>> actually starts as a process under wine in Docker and it silently fails
>>> upon startup.
>>>
>>> Any ideas where to look and what to test? I strongly assume Racket is
>>> not the root cause of the problem here, but rather the combination of
>>> wine under Docker. However, Racket sometimes uses an OS-specific
>>> trickery so I am sort of hoping that the described behav

[racket-users] Cross-building Racket applications for 64bit Windows on Linux

2020-05-23 Thread Dominik Pantůček
Hello Racketeers,

although I am developing Racket applications on Linux, our customers are
usually running Windows. The good thing about Racket (and racket/gui
especially) is that it requires virtually no OS-specific code for many -
even non-trivial - tasks. However it is not that straightforward to
produce binaries for different target platform.

Since last summer, we have been successfully using wine and Racket
Windows builds to create 32bit binaries. However with Racket BC it was
impossible to make it work with 64bit Windows builds. This is still the
case even with latest snapshots and latest wine bundled with Ubuntu 20.04.

It turns out, that Racket CS works flawlessly under wine - including
raco.exe exe. And with the latest patches[1] (thanks Matthew and
DaLynX), it is possible to produce working 64bit Windows binaries from
Racket programs on Linux using wine.

As my work is heavily CPU- and memory-bound, the 32bit address space
limit was quite a limit.

However, once we tried to embed the build process into our
(Gitlab-based) CI/CD, we failed miserably. Combining wine and Racket
windows builds (7.7.0.6 snapshots from University of Utah) turned out to
be a terrible nightmare under Docker.

On my workstation, it is absolutely straightforward:

rm -fr ~/.wine # Do not try this without backing up, if you need it
wine racket-7.7.0.6-x86_64-win32-cs.exe

Now just click next next next with the installer and you are ready.
Building a 64bit Windows binary is just a matter of single:

wine ~/.wine/drive_c/Program\ Files/Racket-7.7.0.6/raco.exe exe --gui
--embed-dlls program.rkt

Of course, any packages needed have to be installed using raco.exe pkg
in the same wine prefix.

But when you take the ~/.wine prefix and try to run it under docker,
nothing works at all and tracing what is happening is extremely
difficult with very cryptic results.

We ruled out X11 dependency - raco.exe works just fine after I `unset
DISPLAY` on my workstation. And the results in Docker are no different
with Xvfb installed and running. We got to a point where the raco.exe
actually starts as a process under wine in Docker and it silently fails
upon startup.

Any ideas where to look and what to test? I strongly assume Racket is
not the root cause of the problem here, but rather the combination of
wine under Docker. However, Racket sometimes uses an OS-specific
trickery so I am sort of hoping that the described behavior rings a bell
for someone :)


Cheers,
Dominik

[1]
https://github.com/racket/racket/commit/61cefe693a047e22ca44752eafb9eb9e2e65409f

-- 
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/6cd41db0-a1f1-916a-edaf-20d9d0597f68%40trustica.cz.


[racket-users] JIT and futures on aarch64

2020-05-16 Thread Dominik Pantůček
Hello fellow racketeers,

after pushing futures on x86 and x86_64 to their limits (and helping
fixing two bugs), I turned my focus on ARM. Apparently everything should
work with 32bit arm without any hurdles (I am going to test that later
today), however on aarch64 (64bit arm), there is no JIT and therefore no
futures.

A quick look at the implementation hints that being stuck with forked
GNU Lightning 1.2 is the major problem here. Apparently latest versions
of Lightning support aarch64.

I am willing to invest some time into porting that, but the question is
how much work is needed. Also - is it relevant for CS variant? (I would
guess not). And of course, how to do the actual porting - it seems to me
the Racket's port is more than just a few minor changes. Maybe porting
only the aarch64 part might be a reasonable way to go?

Any suggestions would be really appreciated.


Cheers,
Dominik

-- 
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/8e43f493-df5d-e6bb-e7f5-c8bc67dd891c%40trustica.cz.


Re: [racket-users] Another futures-related bug hunt

2020-05-09 Thread Dominik Pantůček

Hello,



I'll add a lock at lines 1092-1096 of "newgc.c", and we'll see if that
helps.


should I open the issue or will you do it? (Speaking of race conditions...).

I'll re-run the tests with the lock once it is in the repo - sometimes 
it takes hours for this bug to exhibit and with 8 HTs the process in 
question consumes slightly more than 500% of CPU time - which means the 
computer sounds it's going to take off and fly. I'll keep it up and 
running overnight again.



And thank you for the explanation, digging in Racket internals has a 
very varying degree of difficulty :)



Cheers,
Dominik

--
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/606315e6-edd3-1ab5-48b2-770b6fd79893%40trustica.cz.


Re: [racket-users] Another futures-related bug hunt

2020-05-08 Thread Dominik Pantůček

Hello,



The most useful information here is likely to be a stack trace from
each OS-level thread at the point where the application is stuck.



would this be enough to open an issue for that?

(gdb) info threads
  Id   Target IdFrame
* 1Thread 0x77c1b300 (LWP 19075) "tut22.rkt" 
mark_backpointers (gc=gc@entry=0x559d10c0) at 
../../../racket/gc2/newgc.c:4078
  2Thread 0x77fcb700 (LWP 19076) "tut22.rkt" 
futex_wait_cancelable (private=, expected=0, 
futex_word=0x559d7d78)

at ../sysdeps/unix/sysv/linux/futex-internal.h:80
  3Thread 0x7fffe65a6700 (LWP 19077) "gmain" 
0x77d34c2f in __GI___poll (fds=0x55b82520, nfds=2, 
timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
  4Thread 0x7fffe5da5700 (LWP 19078) "gdbus" 
0x77d34c2f in __GI___poll (fds=0x55b94ce0, nfds=3, 
timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
  7Thread 0x7fffd77fe700 (LWP 19082) "dconf worker" 
0x77d34c2f in __GI___poll (fds=0x55e9e5e0, nfds=1, 
timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
  8Thread 0x7fffe40d4800 (LWP 19083) "tut22.rkt" 
futex_wait_cancelable (private=, expected=0, 
futex_word=0x559c499c)

at ../sysdeps/unix/sysv/linux/futex-internal.h:80
  9Thread 0x7fffd4602800 (LWP 19084) "tut22.rkt" 
futex_wait_cancelable (private=, expected=0, 
futex_word=0x559c499c)

at ../sysdeps/unix/sysv/linux/futex-internal.h:80
  10   Thread 0x7fffd4586800 (LWP 19085) "tut22.rkt" 
futex_wait_cancelable (private=, expected=0, 
futex_word=0x559c499c)

at ../sysdeps/unix/sysv/linux/futex-internal.h:80
  11   Thread 0x7fffd450a800 (LWP 19086) "tut22.rkt" 
futex_wait_cancelable (private=, expected=0, 
futex_word=0x559c499c)

at ../sysdeps/unix/sysv/linux/futex-internal.h:80
  12   Thread 0x7fffd448e800 (LWP 19087) "tut22.rkt" 
futex_wait_cancelable (private=, expected=0, 
futex_word=0x559c499c)

at ../sysdeps/unix/sysv/linux/futex-internal.h:80
  13   Thread 0x7fffd4412800 (LWP 19088) "tut22.rkt" 
futex_wait_cancelable (private=, expected=0, 
futex_word=0x559c499c)

at ../sysdeps/unix/sysv/linux/futex-internal.h:80
  14   Thread 0x7fffd4396800 (LWP 19089) "tut22.rkt" 
futex_wait_cancelable (private=, expected=0, 
futex_word=0x559c499c)

at ../sysdeps/unix/sysv/linux/futex-internal.h:80
  15   Thread 0x7fffd431a800 (LWP 19090) "tut22.rkt" 
futex_wait_cancelable (private=, expected=0, 
futex_word=0x559c499c)

at ../sysdeps/unix/sysv/linux/futex-internal.h:80
  16   Thread 0x765b2800 (LWP 21691) "tut22.rkt" 
futex_wait_cancelable (private=, expected=0, 
futex_word=0x559c4998)

at ../sysdeps/unix/sysv/linux/futex-internal.h:80
(gdb) bt
#0  0x557f5064 in mark_backpointers (gc=gc@entry=0x559d10c0) 
at ../../../racket/gc2/newgc.c:4078
#1  0x557edb2b in garbage_collect (gc=gc@entry=0x559d10c0, 
force_full=force_full@entry=0, no_full=no_full@entry=0, 
switching_master=switching_master@entry=0, lmi=lmi@entry=0x0)

at ../../../racket/gc2/newgc.c:5646
#2  0x557f0ff2 in collect_now (nomajor=, 
major=, gc=) at 
../../../racket/gc2/newgc.c:875
#3  0x557f0ff2 in collect_now (gc=0x559d10c0, major=0, 
nomajor=0) at ../../../racket/gc2/newgc.c:855
#4  0x557f9124 in allocate_slowpath (newptr=, 
allocate_size=, gc=) at 
../../../racket/gc2/newgc.c:1607
#5  0x557f9124 in allocate (type=1, request_size=out>) at ../../../racket/gc2/newgc.c:1671
#6  0x557f9124 in allocate (type=, 
request_size=) at ../../../racket/gc2/newgc.c:1636
#7  0x557f9124 in GC_malloc_atomic (s=) at 
../../../racket/gc2/newgc.c:1792
#8  0x557f9124 in GC_malloc_atomic (s=) at 
../../../racket/gc2/newgc.c:1792
#9  0x55605406 in prepare_retry_alloc (p2=, 
p=) at ../../../racket/gc2/../src/jitalloc.c:47
#10 0x55605406 in ts_prepare_retry_alloc (p=, 
p2=) at ../../../racket/gc2/../src/jitalloc.c:73

#11 0x77fbe62b in  ()
#12 0x in  ()
(gdb) thread 2
[Switching to thread 2 (Thread 0x77fcb700 (LWP 19076))]
#0  futex_wait_cancelable (private=, expected=0, 
futex_word=0x559d7d78) at ../sysdeps/unix/sysv/linux/futex-internal.h:80

80  ../sysdeps/unix/sysv/linux/futex-internal.h: No such file or directory.
(gdb) bt
#0  0x77e202c6 in futex_wait_cancelable (private=out>, expected=0, futex_word=0x559d7d78) at 
../sysdeps/unix/sysv/linux/futex-internal.h:80
#1  0x77e202c6 in __pthread_cond_wait_common (abstime=0x0, 
clockid=0, mutex=0x559d7d28, cond=0x559d7d50) at 
pthread_cond_wait.c:508
#2  0x77e202c6 in __pthread_cond_wait 
(cond=cond@entry=0x559d7d50, mutex=mutex@entry=0x559d7d28) at 
pthread_cond_wait.c:638
#3  0x557209fe in green_thread_timer 
(data=data@entry=0x559d7d10) at ../../../racket/gc2/../src/port.c:6659
#4  0x556bb8be in mzrt_thread_stub (data=0x559d7dc0) at 

Re: [racket-users] Another futures-related bug hunt

2020-05-08 Thread Dominik Pantůček

Hello,

On 08. 05. 20 14:27, Matthew Flatt wrote:

At Fri, 8 May 2020 09:34:32 +0200, Dominik Pantůček wrote:

Apart from obvious strace (after freeze) and gdb (before/after freeze)
debugging to find possible sources of this bug, is there even a remote
possibility of getting any clue how can this happen based on the
information gathered so far? My thought go along the lines:

* flonums are boxed - but for some operations they may be immediate
* apparently it is a busy-wait loop in RTT, otherwise 100% CPU usage is
impossible with this workload
* unsafe ops are always suspicious, but again, the problem shows up even
when I switch to the safe versions - it just takes longer time
* which means, the most probable cause is a race condition


The most useful information here is likely to be a stack trace from
each OS-level thread at the point where the application is stuck.

That could potentially tell us, for example, that it's a problem with
synchronization for a GC (where one of the OS threads that run futures
doesn't cooperate for some reason) or a problem with a the main thread
performing some specific work on a future thread's behalf.



I am using the build from master branch with the patch for #3145 and 
cannot make it run under gdb:


$ gdb ../racket-lang/racket/racket/bin/racket
GNU gdb (Ubuntu 8.3-0ubuntu1) 8.3
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ../racket-lang/racket/racket/bin/racket...
(No debugging symbols found in ../racket-lang/racket/racket/bin/racket)
(gdb) run
Starting program: 
/home/joe/Projects/Programming/racket-lang/racket/racket/bin/racket

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Welcome to Racket v7.7.0.4.
[New Thread 0x77fcb700 (LWP 6410)]

Thread 1 "racket" received signal SIGSEGV, Segmentation fault.
0x555e14fe in scheme_gmp_tls_unload ()
(gdb)

The same happens for the binary with debug symbols:

 gdb ../racket-lang/racket/racket/src/build/racket/racket3m
GNU gdb (Ubuntu 8.3-0ubuntu1) 8.3
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from 
../racket-lang/racket/racket/src/build/racket/racket3m...

(gdb) run
Starting program: 
/home/joe/Projects/Programming/racket-lang/racket/racket/src/build/racket/racket3m 


[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Welcome to Racket v7.7.0.4.
[New Thread 0x77fcb700 (LWP 6422)]

Thread 1 "racket3m" received signal SIGSEGV, Segmentation fault.
scheme_gmp_tls_unload (s=0x76114480, data=0x0) at 
../../../racket/gc2/../src/gmp/gmp.c:5822

5822  s[0] = 0;
(gdb)

I am running Ubuntu 19.10's default gdb:

$ gdb --version
GNU gdb (Ubuntu 8.3-0ubuntu1) 8.3

I assume gmp is used for bignum implementation (didn't check yet), so it 
might be relevant as well:


ii  libgmp-dev:amd64   2:6.1.2+dfsg-4 
  amd64Multiprecision arithmetic library 
developers tools
ii  libgmp10:amd64 2:6.1.2+dfsg-4 
  amd64Multiprecision arithmetic library
ii  libgmp10:i386  2:6.1.2+dfsg-4 
  i386 Multiprecision arithmetic library
ii  libgmpxx4ldbl:amd642:6.1.2+dfsg-4 
  amd64Multiprecision arithmetic library (C++ 
bindings)
ii  python-gmpy:amd64 

[racket-users] Another futures-related bug hunt

2020-05-08 Thread Dominik Pantůček

Hello fellow Racketeers,

my spare-time out-of-curiosity venture into using HPR (High-Performance 
Racket) for creating a software 3D rendering pipeline seems to be 
pushing the futures into rough edges.


The scenario is sort of "usual":

* 7 futures + 1 in RTT that form a binary tree
* GUI thread running

But this time, the futures perform not only data-heavy fixnums 
operations, but flonums operations as well.


Something along the lines of 2560x1440 fixnums and the same number of 
flonums is being handled in 8 threads effectively (give or take some 
optimizations that slightly lower the 1440 height usually).


The code in question is relatively short - say 60 lines of code - 
however it does not make much sense without the remaining 2k lines :)


If the operation runs without futures in RTT, nothing happens. But under 
a heavy load and VERY varying amount of time (seconds to hours), it 
completely freezes with:


* 1 CPU being used at 100% (top/htop shows)
* Does not handle socket operations (X11 WM message for closing the window)
* Does not respond to keyboard (or via kill) SIGINT
* Can only be forcibly stopped by SIGKILL (or similar) or forcefully 
closing the window from WM which sort of gets handled probably in the 
lower-level parts of GDK completely without Racket runtime intervention 
(just prints Killed and the exit code is 137)


Based on these observations I can only conclude that it is the RTT that 
gets stuck - but that is only the native thread perspective. From Racket 
thread perspective, it can be either the "main" application thread that 
is in (thread-wait) for the thread that performs the futures stuff and 
it can also be the GUI thread which is created with parameterizing the 
eventspace (that is just some trickery to allow me to send breaks when I 
receive window close event).


Apart from obvious strace (after freeze) and gdb (before/after freeze) 
debugging to find possible sources of this bug, is there even a remote 
possibility of getting any clue how can this happen based on the 
information gathered so far? My thought go along the lines:


* flonums are boxed - but for some operations they may be immediate
* apparently it is a busy-wait loop in RTT, otherwise 100% CPU usage is 
impossible with this workload
* unsafe ops are always suspicious, but again, the problem shows up even 
when I switch to the safe versions - it just takes longer time

* which means, the most probable cause is a race condition

And that is basically all I can tell right now.

Of course, any suggestions would be really welcome.

Cheers,
Dominik

P.S.: I am really curious, what will I find when I finally put 
fsemaphores into the mix...





--
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/ca40f468-53c7-6fd2-4e7f-0d963e931a60%40trustica.cz.


Re: [racket-users] Futures + threads SIGSEGV

2020-05-02 Thread Dominik Pantůček
Hi Sam,

On 02. 05. 20 14:26, Sam Tobin-Hochstadt wrote:
> I successfully reproduced this on the first try, which is good. Here's
> my debugging advice (I'm also looking at it):
> 
> 1. To use a binary with debugging symbols, use
> `racket/src/build/racket/racket3m` from the checkout of the Racket
> repository that you built.
> 2. When running racket in GDB, there are lots of segfaults because of
> the GC; you'll want to use `handle SIGSEGV nostop noprint`
> 3. It may not work for this situation because of parallelism, but if
> you can reproduce the bug using `rr` [1] it will be almost infinitely
> easier to find and fix.

thanks for the hints and also thanks for opening the Github issue for
that. I'll try to post my results (if any) there.

> 
> I'm also curious about your experience with Racket CS and futures.
> It's unlikely to have the _same_ bugs, but it would be good to find
> the ones there are. :)

This is going to be a really hard one. With all the tricks I learned
during past weeks, I get almost 400 frames per second with my experiment
using 3m and unsafe operations. Without unsafe operations it goes down
to 300 and without unsafe operations and with the de-optimized flip
function as shown in the example + set-argb-pixels, I am at about 50 fps
(that is presumably a completely "safe" version without relying on my
bounds and type checking).

With CS, I am unable to get quickly working anything else than the
de-optimized version with set-argb-pixels and I am at about 5 fps. Also,
the thread scheduling is "interesting" at best. I am postponing the work
on that - I sort of assume, that it can take another few weeks to
understand how to properly use all the fixnum/flonum related stuff with CS.


Thanks again!
Dominik


> 
> [1] https://rr-project.org
> 
> On Sat, May 2, 2020 at 7:56 AM Dominik Pantůček
>  wrote:
>>
>> Hello fellow Racketeers,
>>
>> during my research into how Racket can be used as generic software
>> rendering platform, I've hit some limits of Racket's (native) thread
>> handling. Once I started getting SIGSEGVs, I strongly suspected I am
>> doing too much unsafe operations - and to be honest, that was true.
>> There was one off-by-one memory access :).
>>
>> But that was easy to resolve - I just switched to safe/contracted
>> versions of everything and found and fixed the bug. But I still got
>> occasional SIGSEGV. So I dug even deeper (during last two months I've
>> read most of the JIT inlining code) than before and noticed that the
>> crashes disappear when I refrain from calling bytes-set! in parallel
>> using futures.
>>
>> So I started creating a minimal-crashing-example. At first, I failed
>> miserably. Just filling a byte array over and over again, I was unable
>> to reproduce the crash. But then I realized, that in my application,
>> threads come to play and that might be the case. And suddenly, creating
>> MCE was really easy:
>>
>> Create new eventspace using parameterize/make-eventspace, put the actual
>> code in application thread (thread ...) and make the main thread wait
>> for this application thread using thread-wait. Before starting the
>> application thread, I create a simple window, bitmap and a canvas, that
>> I keep redrawing using refresh-now after each iteration. Funny thing is,
>> now it keeps crashing even without actually modifying the bitmap in
>> question. All I need to do is to mess with some byte array in 8 threads.
>> Sometimes it takes a minute on my computer before it crashes, sometimes
>> it needs more, but it eventually crashes pretty consistently.
>>
>> And it is just 60 lines of code:
>>
>> #lang racket/gui
>>
>> (require racket/future racket/fixnum racket/cmdline)
>>
>> (define width 800)
>> (define height 600)
>>
>> (define framebuffer (make-fxvector (* width height)))
>> (define pixels (make-bytes (* width height 4)))
>>
>> (define max-depth 0)
>>
>> (command-line
>>  #:once-each
>>  (("-d" "--depth") d "Futures binary partitioning depth" (set! max-depth
>> (string->number d
>>
>> (file-stream-buffer-mode (current-output-port) 'none)
>>
>> (parameterize ((current-eventspace (make-eventspace)))
>>   (define win (new frame%
>>(label "test")
>>(width width)
>>(height height)))
>>   (define bmp (make-bitmap width height))
>>   (define canvas (new canvas%
>>   (parent win)
>>   (paint-callback
>>(λ (c dc)
>>  

Re: [racket-users] Futures + threads SIGSEGV

2020-05-02 Thread Dominik Pantůček
Hi Dex,

On 02. 05. 20 14:10, Dexter Lagan wrote:
> Hello,
> 
>   I’ve been getting inconsistent results as well. A while ago I made a
> benchmark based on a parallel spectral norm computation. The benchmark
> works fine on Windows on most systems and uses all cores, but crashes
> randomly on other systems. I haven’t been able to figure out why. On
> Linux it doesn’t seem to use more than one core. I’d be interested to
> know if this is related. Here’s the benchmark code :
> 
> https://github.com/DexterLagan/benchmark

Beware that (processor-count) returns the number of HT-cores, so your
v1.3 is actually requesting twice the number of threads as there are
HTs. At least on Linux this is the case (checked right now).

Interesting idea... 16 threads:

$ time racket crash.rkt -d 4
SIGSEGV MAPERR si_code 1 fault on addr (nil)
Aborted (core dumped)

real6m37,579s
user32m55,192s
sys 0m35,124s

So that is consistent to what I see.

Have you tried using future-visualizer[1] for checking why it uses only
single CPU thread? Last summer I spent quite some time with it to help
me find the right futures usage patterns that actually enable the
speculative computation in parallel. Usually if your code is too deep
and keeps allocating "something" each frame, it goes back to the runtime
thread for each allocation.


Cheers,
Dominik

[1] https://docs.racket-lang.org/future-visualizer/index.html

> 
> Dex
> 
>> On May 2, 2020, at 1:56 PM, Dominik Pantůček
>>  wrote:
>>
>> Hello fellow Racketeers,
>>
>> during my research into how Racket can be used as generic software
>> rendering platform, I've hit some limits of Racket's (native) thread
>> handling. Once I started getting SIGSEGVs, I strongly suspected I am
>> doing too much unsafe operations - and to be honest, that was true.
>> There was one off-by-one memory access :).
>>
>> But that was easy to resolve - I just switched to safe/contracted
>> versions of everything and found and fixed the bug. But I still got
>> occasional SIGSEGV. So I dug even deeper (during last two months I've
>> read most of the JIT inlining code) than before and noticed that the
>> crashes disappear when I refrain from calling bytes-set! in parallel
>> using futures.
>>
>> So I started creating a minimal-crashing-example. At first, I failed
>> miserably. Just filling a byte array over and over again, I was unable
>> to reproduce the crash. But then I realized, that in my application,
>> threads come to play and that might be the case. And suddenly, creating
>> MCE was really easy:
>>
>> Create new eventspace using parameterize/make-eventspace, put the actual
>> code in application thread (thread ...) and make the main thread wait
>> for this application thread using thread-wait. Before starting the
>> application thread, I create a simple window, bitmap and a canvas, that
>> I keep redrawing using refresh-now after each iteration. Funny thing is,
>> now it keeps crashing even without actually modifying the bitmap in
>> question. All I need to do is to mess with some byte array in 8 threads.
>> Sometimes it takes a minute on my computer before it crashes, sometimes
>> it needs more, but it eventually crashes pretty consistently.
>>
>> And it is just 60 lines of code:
>>
>> #lang racket/gui
>>
>> (require racket/future racket/fixnum racket/cmdline)
>>
>> (define width 800)
>> (define height 600)
>>
>> (define framebuffer (make-fxvector (* width height)))
>> (define pixels (make-bytes (* width height 4)))
>>
>> (define max-depth 0)
>>
>> (command-line
>> #:once-each
>> (("-d" "--depth") d "Futures binary partitioning depth" (set! max-depth
>> (string->number d
>>
>> (file-stream-buffer-mode (current-output-port) 'none)
>>
>> (parameterize ((current-eventspace (make-eventspace)))
>>  (define win (new frame%
>>   (label "test")
>>   (width width)
>>   (height height)))
>>  (define bmp (make-bitmap width height))
>>  (define canvas (new canvas%
>>  (parent win)
>>  (paint-callback
>>   (λ (c dc)
>> (send dc draw-bitmap bmp 0 0)))
>>  ))
>>
>>  (define (single-run)
>>    (define (do-bflip start end (depth 0))
>>  (cond ((fx< depth max-depth)
>> (define cnt (fx- end start))
>> (define cnt2 (fxrshift cnt 1))
>> (define mid (fx+ start cnt2))
>>   

[racket-users] Futures + threads SIGSEGV

2020-05-02 Thread Dominik Pantůček
Hello fellow Racketeers,

during my research into how Racket can be used as generic software
rendering platform, I've hit some limits of Racket's (native) thread
handling. Once I started getting SIGSEGVs, I strongly suspected I am
doing too much unsafe operations - and to be honest, that was true.
There was one off-by-one memory access :).

But that was easy to resolve - I just switched to safe/contracted
versions of everything and found and fixed the bug. But I still got
occasional SIGSEGV. So I dug even deeper (during last two months I've
read most of the JIT inlining code) than before and noticed that the
crashes disappear when I refrain from calling bytes-set! in parallel
using futures.

So I started creating a minimal-crashing-example. At first, I failed
miserably. Just filling a byte array over and over again, I was unable
to reproduce the crash. But then I realized, that in my application,
threads come to play and that might be the case. And suddenly, creating
MCE was really easy:

Create new eventspace using parameterize/make-eventspace, put the actual
code in application thread (thread ...) and make the main thread wait
for this application thread using thread-wait. Before starting the
application thread, I create a simple window, bitmap and a canvas, that
I keep redrawing using refresh-now after each iteration. Funny thing is,
now it keeps crashing even without actually modifying the bitmap in
question. All I need to do is to mess with some byte array in 8 threads.
Sometimes it takes a minute on my computer before it crashes, sometimes
it needs more, but it eventually crashes pretty consistently.

And it is just 60 lines of code:

#lang racket/gui

(require racket/future racket/fixnum racket/cmdline)

(define width 800)
(define height 600)

(define framebuffer (make-fxvector (* width height)))
(define pixels (make-bytes (* width height 4)))

(define max-depth 0)

(command-line
 #:once-each
 (("-d" "--depth") d "Futures binary partitioning depth" (set! max-depth
(string->number d

(file-stream-buffer-mode (current-output-port) 'none)

(parameterize ((current-eventspace (make-eventspace)))
  (define win (new frame%
   (label "test")
   (width width)
   (height height)))
  (define bmp (make-bitmap width height))
  (define canvas (new canvas%
  (parent win)
  (paint-callback
   (λ (c dc)
 (send dc draw-bitmap bmp 0 0)))
  ))

  (define (single-run)
(define (do-bflip start end (depth 0))
  (cond ((fx< depth max-depth)
 (define cnt (fx- end start))
 (define cnt2 (fxrshift cnt 1))
 (define mid (fx+ start cnt2))
 (let ((f (future
   (λ ()
 (do-bflip start mid (fx+ depth 1))
   (do-bflip mid end (fx+ depth 1))
   (touch f)))
(else
 (for ((i (in-range start end)))
   (define c (fxvector-ref framebuffer i))
   (bytes-set! pixels (+ (* i 4) 0) #xff)
   (bytes-set! pixels (+ (* i 4) 1) (fxand (fxrshift c 16)
#xff))
   (bytes-set! pixels (+ (* i 4) 2) (fxand (fxrshift c 8) #xff))
   (bytes-set! pixels (+ (* i 4) 3) (fxand c #xff))
(do-bflip 0 (* width height))
(send canvas refresh-now))
(send win show #t)

  (define appthread
(thread
 (λ ()
   (let loop ()
 (single-run)
 (loop)
  (thread-wait appthread))

Note: the code is deliberately de-optimized to highlight the problem.
Not even mentioning CPU cache coherence here

Running this from command-line, I can adjust the number of threads.
Running with 8 threads:

$ time racket crash.rkt -d 3
SIGSEGV MAPERR si_code 1 fault on addr (nil)
Aborted (core dumped)

real1m18,162s
user7m11,936s
sys 0m3,832s
$ time racket crash.rkt -d 3
SIGSEGV MAPERR si_code 1 fault on addr (nil)
Aborted (core dumped)

real3m44,005s
user20m10,920s
sys 0m11,702s
$ time racket crash.rkt -d 3
SIGSEGV MAPERR si_code 1 fault on addr (nil)
Aborted (core dumped)

real2m1,650s
user10m58,392s
sys 0m6,445s
$ time racket crash.rkt -d 3
SIGSEGV MAPERR si_code 1 fault on addr (nil)
Aborted (core dumped)

real8m8,666s
user45m52,359s
sys 0m25,184s
$

With 4 threads it didn't crash even after quite some time:

$ time racket crash.rkt -d 2
^Cuser break
  context...:
   "crash.rkt": [running body]
   temp35_0
   for-loop
   run-module-instance!
   perform-require!

real20m18,706s
user61m38,546s
sys 0m22,719s
$


I'll re-run the 4-thread test overnight.

What would be the best approach to debugging this issue? I assume I'll
load the racket binary in gdb and see the stack traces at the moment of
the crash, but that won't reveal the source of the problem (judging
based on my previous experience of debugging heavily multi-threaded

Re: [racket-users] Rhombus project plan

2020-04-29 Thread Dominik Pantůček
Hi,

I can't leave this without reaction...

> 
>   To the point: what would make Racket2 the ultimate tool (for me):
> 
>   * Performance. Faster startup times, shorter execution times in
> general. Optionally, a ‘lite’ version of Racket that compiles
> directly to no-deps binaries, bypassing the JIT altogether, would be
> a game-changer. As far as high levels languages with functional
> concepts and metaprogramming facilities that compiles to tiny, fast
> bins, Nim comes dangerously close, but it’s not a Lisp, and it’s not
> Racket.

They say that Racket is slow. I would like to know who are "they".

Racket can be surprising. For example - our GUI application on RPi has a
start-up time of 24s... But when we compile it using `raco exe`, it goes
down under 2s including some hardware setup the program does. Usually
the slow startup times are caused by not using compiled byte-code.

As I have mentioned a few times on this list, I am working on a side
project right now which pushes Racket to its limits and let's say that
the results might look impossible to many people. Full 3D rendering
pipeline in pure Racket with no external libraries (no OpenGL, no SDL,
just pure Racket) which can run at 60fps FullHD kind of beats the
argument "Racket is slow". Racket can be REALLY fast. But you need to
know how to achieve that (think contract boundaries, unsafe ops guarded
by other mechanisms, ultimate parallelism support - yes, once you grasp
futures to their full extent, you will see what performance gains you
get virtually for free... see my sorting package[1])

>   * Production-quality, modern and fast GUI facilities. I’ll take
> properly documented, complete Qt bindings. Racket/GUI is great for
> internal tools, but it quickly becomes slow, tedious and limited for
> more complex client-facing UIs.

My experience is quite contrary to that. In the last three years we were
forced to develop a few GUI tools used by our customers and there are no
complains only against the tools using racket/gui. Yes, it is far from
perfect - but it is the only thing that really behaves consistently
across all three platforms we need to support (Linux, Mac, and ...
Windows). Python+Qt and go+Qt are absolutely insupportable without a
long list of per-platform/per-widget hacks. It might be that we are just
hitting corner cases (actually that's pretty probably), yet with Racket
there were no such hurdles.

>   * One complete, commercial-grade Web framework, inspired from Symphony
> or Laravel. Security and ease of use first, continuations later.

And this is the part that made me actually hit the "Reply List" button.
The good thing about mentioned PHP frameworks is only that anyone can
start producing something with them without any prior experience. So
right now we are encountering vulnerable and unmaintainable code
anywhere we bump into some 3rd party "web application" we are hired to
audit. With Racket - the entry barrier is really high, I agree. I
actually spent many days getting through it - but once you pass the
barrier, it really helps you write applications where you can focus on
the actual functionality and let the libraries do the rest for you. And
securing such application is almost trivial task. Yes, I have hit some
corner cases here as well, but if you follow for example Bogdan's
work[2][3], you'll see that there are solutions readily available. It is
just necessary to read the docs and understand how the whole thing works.

>   * Better documentation: Racket docs are aesthetically very pleasing,
> complete and detailed. However some parts are still very obscure and
> lacking simple examples (if only the part about Continuations
> included just one basic example, such as a ‘return’ implementation,
> on the very first page. If only the Macros documentation started
> with define-simple-macro and a few very basic, practical examples.
> Instead we’re greeted with pattern-based macros, which although very
> powerful, are very hard to comprehend for newcomers).

I am not sure whether it is the best thing to start with
define-simple-macro (if anything, I'd start with define-syntax-rule),
but yes, more examples are always useful. Just write them and send a
pull request to appropriate repository - I was pleasantly surprised when
I first did this. All the Racketeers are super helpful when it comes to
incorporating any improvements. (Thanks Ben!)

> 
> 
>   I am well aware that what I’m wishing for isn’t necessarily compatible
> with Racket’s intended public’s needs (comp-sci teachers and students?
> That’s the impression I’m getting). But Racket is the most advanced
> general purpose programming tool I’ve ever seen. Wouldn’t it be a shame
> if it was limited to academic use?

As far as I can tell, it is definitely limited to academic use. Although
I prepare support materials for my students with Racket, I actually
teach Clojure - so for me, Racket is tool mostly for my 

Re: [racket-users] Question about generating urls with dispatch-rules from imported modules

2020-04-26 Thread Dominik Pantůček
Hello,

just a quick and dirty hack I use to get the best of default
dispatch-... for my use-case when dispatching API requests:

(define-for-syntax (dispatch-api-case-helper stx)
  (syntax-parse stx
(((method:id (path+args:expr ...) proc:id) rest ...)
   #`((("api" path+args ...) #:method #,(symbol->string
(syntax->datum #'method)) proc)
  #,@(dispatch-api-case-helper #'(rest ...
(((else proc:id))
 #'((else proc)))
(()
 #'(

(define-syntax (dispatch-api-case stx)
  (syntax-parse stx
((_ rest ...)
 #`(dispatch-case
#,@(dispatch-api-case-helper #'(rest ...))

(define dispatch-api-request-real
  (dispatch-api-case
   (get ("number" (number-arg)) api-number-test)
   (get ("ping") api-ping)
   (post ("auth") auth-login)
   (delete ("auth") auth-logout)
   (put ("auth") auth-passwd)
   (get ("auth" "info") auth-user-info)
   (get ("partners") partners-list)
   (get ("partners" (string-arg)) partner-detail)
   (get ("partners" (string-arg) "payments") partner-payments)
   (get ("partners" (string-arg) "debt") partner-debt)
   (get ("debts") partners-debts)
   (get ("partners" (string-arg) "history") partner-debt-history)
   (get ("invoices" "issued") invoices-issued-list)
   (get ("invoices" "issued" (string-arg)) invoice-info)
   (post ("notes") notes-add)
   (else api-404)))

Not very general, but maybe you'll find that useful (especially if the
(string-arg) and similar can make your life easier like it was the case
for me.

When I needed a url-generation function in earlier project, I basically
did the same with more syntax mess around, that used either set! or
parameter from different module to store the dispatch-url -generated
procedure.

Basically it is about customized version of dispatch-rules that does the
dispatch-case and dispatch-url independently and provides the results by
different means.


Cheers,
Dominik

On 26. 04. 20 17:26, Yury Bulka wrote:
> Meanwhile here's my attempt at doing a koyo-like url generation with a
> wrapper around web-server/dispatch's url-generating function:
> 
> (define-values (app-dispatch app-url)
>   (dispatch-rules  ; the standard one
>[...]))
> 
> (define (app-url/names route-name . args)
>   ;; define a mapping between symbolic names and handlers
>   (define route-names
> (hash 'item-list item-list-view
>   'item-detail item-detail-view))
>   (apply app-url (hash-ref route-names route-name) args))
> 
> And then I can store the function in a parameter that is used by the
> templates.
> 
> It is of course not a general solution (for instance, the rules in
> dispatch-rules and the route-names can go out of sync if one forgets to
> update either of them) and they are not dynamic.
> 
> But for an ultra-minimalistic application this might do when you don't
> feel like adding a new external dependency.
> 
> --
> Yury Bulka
> https://mamot.fr/@setthemfree
> #NotOnFacebook
> 
> 
> 
> Yury Bulka  writes:
> 
>> Thank you for sharing this!
>>
>> I'm wondering, if this is a common use case, maybe it is worth adding to
>> web-server/dispatch in some form?
>>
>> Or, if not, maybe we can extend the documentation to include some hints
>> on how to approach this otherwise?
>>
>> It is great to have powerful libraries outside the main distribution,
>> but the main distribution is the place where newcomers like me are going
>> to look first.
> 

-- 
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/304869ce-9ab8-0255-50ca-de7b7db0788d%40trustica.cz.


Re: [racket-users] Retro 3D maze with Pict?

2020-04-19 Thread Dominik Pantůček
Hi,

On 19. 04. 20 11:42, Aidan Gauland wrote:
> Would it be feasible to use Pict to create a very simplistic rendering
> of a first-person perspective of a 2D maze, in the style of Scarab of Ra
>  for the old
> B Macs?
> 

I've created more than a few experiments like this using dc<%> backed by
canvas% or bitmap%. For such simple game like you mention, it will work
like a charm. However it is not the fastest approach - I remember
rendering a Rubik's cube last year for the students[1] and on Linux it
ran fluently, on Mac it ran at 2 frames per second for no apparent
reason. Probably the Cairo back-end is just really slow there.

I would assume Pict is on-par with dc<%>-based approach (in the end that
is what renders the rasterized image).

Funnily enough, I am working on a graphics side project right now and I
have a working 3D rendering pipeline completely in Racket which works
surprisingly fast even on 2560x1440. I plan to publish a series of
articles about that. No OpenGL, no compiled C code, only Racket trickery.

Or you can use ASCII (as seen on RacketFest 2020)...


Cheers,
Dominik

[1]
https://trustica.cz/en/2019/05/16/teaching-cryptography-rubiks-cube-diffusion/

-- 
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/45b3a36c-f95a-69ac-92e1-5d1b2951dec4%40trustica.cz.


Re: [racket-users] Unfinished S-Expressions in scribbled code blocks

2020-04-12 Thread Dominik Pantůček
Nope, even with eval:alts and eval:result(s) I cannot produce the
results I want.

Btw, I am subscribed to the list.


Cheers,
Dominik

On 12. 04. 20 17:22, Sage Gerard wrote:
> Does scribble/examples offer what you need?
> 
> 
> 
>  Original Message 
> On Apr 12, 2020, 4:23 AM, Dominik Pantůček <
> dominik.pantu...@trustica.cz> wrote:
> 
> 
> Hello fellow Racketeers,
> 
> I've started a small side project and as a part of that I want to write
> some articles interspersed with code. Scribble was a natural choice for
> that task.
> 
> So I started with #lang scribble/manual as usual and after writing some
> text, I tried to do something like the following:
> 
> 
> #lang scribble/manual
> 
> ... and here are the requires:
> 
> @racketblock{
> (require
> }
> 
> .. with the first one being this and we need that for 
> 
> @racketblock{
> (only-in ffi/unsafe ptr-set! _uint32)
> }
> 
> ...
> 
> 
> Of course it renders the racketblocks as string, silly me. So I go for
> @racketblock[] but that - in @-syntax translates to S-expressions with
> "(require" (without the quotes) definitely not being a valid
> S-expression. And therefore scribble cannot handle it.
> 
> Looking at [1] leaves me with an impression that it is not possible to
> typeset parts of racket code in scribble. Only valid S-expressions (and
> the #lang line, of course).
> 
> Using scribble/lp2 I can get closer to my wanted result, but really it
> just works around the issue by forming valid S-expressions and expanding
> chunks inside those.
> 
> What is the proper way of typesetting (in scribble) parts of racket code
> which do not form complete S-expression?
> 
> And yes, I know this is rather strange requirement, but in this
> particular case, I am pretty sure, I want to work with parts of
> S-expressions without balanced parentheses. (Although the minimal
> example definitely does not answer "why").
> 
> I assume I must have overlooked something, of course.
> 
> Cheers,
> Dominik
> 
> [1] https://docs.racket-lang.org/scribble/scribble_manual_code.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/d4473bd1-5b9c-b658-2989-df0a143d7ae9%40trustica.cz.
> 
> -- 
> 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
> <mailto:racket-users+unsubscr...@googlegroups.com>.
> To view this discussion on the web visit
> 
> https://groups.google.com/d/msgid/racket-users/kB7sQQDkefoEq86xajF1QifjjY-cWMqDfbxhD08dN2NqNBNnRn-8u6HX7lOA_JFhClSvgMhJdHxpI9MdEaB3oOpOQHEKNRFn1KCSexM86bg%3D%40sagegerard.com
> 
> <https://groups.google.com/d/msgid/racket-users/kB7sQQDkefoEq86xajF1QifjjY-cWMqDfbxhD08dN2NqNBNnRn-8u6HX7lOA_JFhClSvgMhJdHxpI9MdEaB3oOpOQHEKNRFn1KCSexM86bg%3D%40sagegerard.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/977981fa-97c1-15ac-fcae-84cbb5330e4e%40trustica.cz.


[racket-users] Unfinished S-Expressions in scribbled code blocks

2020-04-12 Thread Dominik Pantůček
Hello fellow Racketeers,

I've started a small side project and as a part of that I want to write
some articles interspersed with code. Scribble was a natural choice for
that task.

So I started with #lang scribble/manual as usual and after writing some
text, I tried to do something like the following:


#lang scribble/manual

... and here are the requires:

@racketblock{
(require
}

.. with the first one being this and we need that for 

@racketblock{
 (only-in ffi/unsafe ptr-set! _uint32)
}

...


Of course it renders the racketblocks as string, silly me. So I go for
@racketblock[] but that - in @-syntax translates to S-expressions with
"(require" (without the quotes) definitely not being a valid
S-expression. And therefore scribble cannot handle it.

Looking at [1] leaves me with an impression that it is not possible to
typeset parts of racket code in scribble. Only valid S-expressions (and
the #lang line, of course).

Using scribble/lp2 I can get closer to my wanted result, but really it
just works around the issue by forming valid S-expressions and expanding
chunks inside those.

What is the proper way of typesetting (in scribble) parts of racket code
which do not form complete S-expression?

And yes, I know this is rather strange requirement, but in this
particular case, I am pretty sure, I want to work with parts of
S-expressions without balanced parentheses. (Although the minimal
example definitely does not answer "why").

I assume I must have overlooked something, of course.


Cheers,
Dominik


[1] https://docs.racket-lang.org/scribble/scribble_manual_code.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/d4473bd1-5b9c-b658-2989-df0a143d7ae9%40trustica.cz.


Re: [racket-users] Proxying websockets via web-server

2020-01-12 Thread Dominik Pantůček
Sigh... I forgot to reply to the list... Here we go:

I want a single HTTP server like serve/servlet (or similar) that handles
all requests by the standard dispatcher/c logic - ideally using
dispatch/servlet with dispatch-case to specify the mapping. And for one
specific URL path "/sockjs-node", I need it to be able to do the
websocket HTTP 101 protocol switch.

The React.js application in the browser just communicates using HTTP and
if you run its minimal node.js server with "npm start" its HTTP
implementation contains the selective websocket URL path and it works. I
just need a way to proxy this, as my Racket backend is the HTTP server.
For static data I produce response/full with that data, for API calls,
it is response/jsexpr and for this websocket endpoint, I would like to
run copy-port and be done with it - after the protocol switch, that is.

>From what I read about rfc6455 package, it cannot be used with the
web-server package. I'll dive into the source later today.

Actually I can live without that, yet I was curious as it provides a
convenient way to reload the frontend after source changes in its code
(that is the Javascript part). For production builds, a plain
serve/servlet does all the job required.


Dominik

On 11. 01. 20 3:18, Jay McCarthy wrote:
> I don't completely understand what you want to do. Is there a reason
> you can't use the WebSocket implementation ---
> https://docs.racket-lang.org/rfc6455/index.html --- and then use
> normal inter-Racket communication like channels and stuff to work with
> the rest of your Web application?
> 
> Jay
> 
> --
> Jay McCarthy
> Associate Professor @ CS @ UMass Lowell
> http://jeapostrophe.github.io
> Vincit qui se vincit.
> 
> On Thu, Jan 9, 2020 at 5:23 PM Dominik Pantůček
>  wrote:
>>
>> Hello everyone,
>>
>> I am working on an application that uses React.js[1] for front-end and
>> Racket as HTTP back-end server.
>>
>> For production builds, the Javascript part is compiled using "npm build"
>> which generates a directory full of HTML and Javascript files which are
>> then included in the Racket application during syntax stage as an
>> immutable hash. For development builds, the Racket application runs "npm
>> start" in the front-end source directory and proxies all non-backend
>> requests to the managed node.js server.
>>
>> When run in the development setup (that is with the node.js secondary
>> HTTP server), the proxying using serve/servlet and simple dispatch-case
>> works like a charm - each servlet uses http-sendrecv to get the data
>> from the secondary HTTP server and returns it as appropriate response body.
>>
>> But the reason for this setup is that React.js can automatically reload
>> the webpage, if any of the source files change. To do this trick, it
>> uses an url "/sockjs-node". The browser sends GET request for this
>> resource and the node.js server responds with "HTTP/1.1 101 Switching
>> Protocols" like in [2].
>>
>> Apparently, to make this work, I need to establish a bi-directional
>> connection after the 101 response code. This is impossible with
>> serve/servlet. I have done some experiments with plain (serve #:dispatch
>> ...) and just cannot make it work all at once. With connection-i-port
>> and connection-o-port it should be (relatively) easy to implement. But
>> the documentation is virtually nonexistent and browsing the
>> web-server/private/ sources is a bit tricky if I do not know what I am
>> looking for.
>>
>> If anyone can give me a hint how a proper setup for websocket
>> implementation should look like, I would really appreciate it. Of
>> course, I also want to use the dispatch-case with plain requests as it
>> automates most of the real work I need to perform there.
>>
>>
>>
>> Cheers,
>> Dominik
>>
>> [1] https://reactjs.org/
>> [2] https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake
>>
>> --
>> 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/a3834699-4ed6-f337-1409-9f175636c087%40trustica.cz.
> 

-- 
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/8222caa5-0104-a0b4-2e08-53ec731ac2bb%40trustica.cz.


[racket-users] Proxying websockets via web-server

2020-01-09 Thread Dominik Pantůček
Hello everyone,

I am working on an application that uses React.js[1] for front-end and
Racket as HTTP back-end server.

For production builds, the Javascript part is compiled using "npm build"
which generates a directory full of HTML and Javascript files which are
then included in the Racket application during syntax stage as an
immutable hash. For development builds, the Racket application runs "npm
start" in the front-end source directory and proxies all non-backend
requests to the managed node.js server.

When run in the development setup (that is with the node.js secondary
HTTP server), the proxying using serve/servlet and simple dispatch-case
works like a charm - each servlet uses http-sendrecv to get the data
from the secondary HTTP server and returns it as appropriate response body.

But the reason for this setup is that React.js can automatically reload
the webpage, if any of the source files change. To do this trick, it
uses an url "/sockjs-node". The browser sends GET request for this
resource and the node.js server responds with "HTTP/1.1 101 Switching
Protocols" like in [2].

Apparently, to make this work, I need to establish a bi-directional
connection after the 101 response code. This is impossible with
serve/servlet. I have done some experiments with plain (serve #:dispatch
...) and just cannot make it work all at once. With connection-i-port
and connection-o-port it should be (relatively) easy to implement. But
the documentation is virtually nonexistent and browsing the
web-server/private/ sources is a bit tricky if I do not know what I am
looking for.

If anyone can give me a hint how a proper setup for websocket
implementation should look like, I would really appreciate it. Of
course, I also want to use the dispatch-case with plain requests as it
automates most of the real work I need to perform there.



Cheers,
Dominik

[1] https://reactjs.org/
[2] https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake

-- 
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/a3834699-4ed6-f337-1409-9f175636c087%40trustica.cz.


Re: [racket-users] Re: Inadvertedly requiring racket/unsafe/ops

2019-12-23 Thread Dominik Pantůček
Hello all,

a short followup on the issue.

I opened a PR[1] and Sam raised an interesting question:

(require (filtered-in
   (λ (name)
  (and (regexp-match #rx"^unsafe-fx" name)
   (regexp-replace #rx"unsafe-" name "")))
   racket/unsafe/ops))

ensures that only unsafe-fx... bindings get required as fx... bindings
and no other bindings from racket/unsafe/ops are. However, the following:

(require (filtered-in
   (λ (name) (regexp-replace #rx"unsafe-fx" name ""))
   racket/unsafe/ops))

does the same trick of not shadowing for example vector-ref with
unsafe-vector-ref - which also solves the problem I encountered and
therefore it might be better suited (as it is a smaller change).

To be honest - both solutions are OK. My personal preference for not
polluting the current namespace with all those unsafe-... bindings is
mostly irrelevant here. Can anyone using racket/unsafe/ops share their
thoughts here?

Also please note that the same applies to flonums and extflonums - which
do not mention the unsafe-... option in the documentation at all. I am
inclined to think that this might be good to fix as well.


Cheers,
Dominik

[1] https://github.com/racket/racket/pull/2975

On 15. 12. 19 11:13, Dominik Pantůček wrote:
> Hi,
> 
> On 15. 12. 19 2:57, Jack Firth wrote:
>> I think that documentation fix is a good idea.
> 
> I'll submit a PR to appropriate repository later on.
> 
>> More broadly, it seems awkward that all of the unsafe ops for 
>> different data types are combined together into a single module. I 
>> would instead expect there to be modules like racket/fixnum/unsafe, 
>> racket/struct/unsafe, racket/vector/unsafe, etc. But I've never used 
>> the unsafe ops before, maybe those who have can chime in?
> 
> it's not that easy as it is really about the "ops" part. For example if
> you need (make-fxvector ...), you still need to require it using
> (only-in racket/fixnum make-fxvector) as there is no racket/unsafe/ops
> equivalent (which is really NOT surprising).
> 
> And also splitting the racket/unsafe/ops into more modules might break a
> thing or two as it has been this way for quite some time. Also it is
> nice - if you are in need of heavy optimizations - to see the list of
> unsafe ops in one place.
> 
> 
> Cheers,
> Dominik
> 
>>
>> On Saturday, December 14, 2019 at 1:03:14 PM UTC-8, Dominik Pantůček 
>> wrote:
>>
>> Hello,
>>
>> the documentation at 
>> https://docs.racket-lang.org/reference/fixnums.html 
>> <https://docs.racket-lang.org/reference/fixnums.html> is misleading 
>> at best. If you - as I did - use the suggested approach of requiring 
>> optimized (and unsafe) fx... operations from racket/unsafe/ops with:
>>
>> (require (filtered-in (λ (name) (regexp-replace #rx"unsafe-" name 
>> "")) racket/unsafe/ops))
>>
>> You end up using _all_ symbols from racket/unsafe/ops. All of them 
>> are - of course - uncontracted. Which means that if you issue for 
>> example vector-ref on something that is not a vector, it can crash 
>> the runtime without any apparent reason - instead of just throwing
>> an exception as one would expect.
>>
>> A simple documentation fix should probably go along the lines:
>>
>> (require racket/require (filtered-in (λ (name) (and (regexp-match 
>> #rx"^unsafe-fx" name) (regexp-replace #rx"unsafe-" name ""))) 
>> racket/unsafe/ops))
>>
>> Or is it just me running into corner cases with optimized Racket 
>> code?
>>
>>
>> Cheers, Dominik
>>
>> -- 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 
>> <mailto:racket-users+unsubscr...@googlegroups.com>. To view this 
>> discussion on the web visit 
>> https://groups.google.com/d/msgid/racket-users/c118c47e-fccd-4fab-b252-7a24afe6eef1%40googlegroups.com
>>
>>
>>
>>
>>
> <https://groups.google.com/d/msgid/racket-users/c118c47e-fccd-4fab-b252-7a24afe6eef1%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/5769cec9-3bb5-4e2f-ba64-23910ab91da9%40trustica.cz.


Re: [racket-users] ffi-lib and scribble/srcdoc

2019-12-23 Thread Dominik Pantůček
Hi,

On 23. 12. 19 15:29, Sam Tobin-Hochstadt wrote:
> What you're seeing is that `scribble/srcdoc` looks for the _binding_
> of `->` from `racket/contract` which is being shadowed by the version
> of `->` from `ffi/unsafe`. I would do something like this:
> 
> #lang racket
> (require (rename-in ffi/unsafe [-> -->]) scribble/srcdoc)
> (provide
>   (proc-doc/names
> a-struct?
> (-> any/c boolean?)
> (a)
> ("Returns true if a is a-struct")))
> (struct a-struct (b))
> 
> and then use `-->` in ffi declarations.

that is exactly what I was looking for. All the "unsafe" parts can get
really "unsafe" during any stage though ...


Thank you!
Dominik

-- 
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/390de732-d2a7-343a-e36f-d693a1da8cc4%40trustica.cz.


[racket-users] ffi-lib and scribble/srcdoc

2019-12-23 Thread Dominik Pantůček
Hello,

apart from parallel sorting and working with unsafe ops, I stumbled upon
a very strange behavior using ffi-lib:

-->8--
#lang racket
(require scribble/srcdoc)
(provide
  (proc-doc/names
a-struct?
(-> any/c boolean?)
(a)
("Returns true if a is a-struct")))
(struct a-struct (b))
->8-

Running this works without a glitch:

$ racket test1.rkt
$

But if we require ffi/unsafe, something bad happens:

-->8--
#lang racket
(require ffi/unsafe scribble/srcdoc)
(provide
  (proc-doc/names
a-struct?
(-> any/c boolean?)
(a)
("Returns true if a is a-struct")))
(struct a-struct (b))
->8-

$ racket test2.rkt
test2.rkt:8:4: proc-doc/names: unsupported procedure contract form (no
argument names)
  at: (-> any/c boolean?)
  in: (proc-doc/names a-struct? (-> any/c boolean?) (a) ("Returns true
if a is a-struct"))
  location...:
   test2.rkt:8:4
  context...:
   do-raise-syntax-error
   /usr/share/racket/pkgs/scribble-lib/scribble/srcdoc.rkt:342:2:
proc-doc/names-transformer
   /usr/share/racket/pkgs/scribble-lib/scribble/srcdoc.rkt:127:24
   /usr/share/racket/pkgs/scribble-lib/scribble/srcdoc.rkt:124:0:
do-provide/doc
   /usr/share/racket/collects/racket/provide-transform.rkt:63:2:
pre-expand-export
   /usr/share/racket/collects/racket/private/reqprov.rkt:708:2: provide
   apply-transformer-in-context
   apply-transformer52
   dispatch-transformer41
   do-local-expand50
   /usr/share/racket/collects/syntax/wrap-modbeg.rkt:46:4:
do-wrapping-module-begin
   apply-transformer-in-context
   apply-transformer52
   dispatch-transformer41
   loop
   finish
   ...
$

I assume that ffi/unsafe somehow re-defines -> and it does it in a very
srcdoc-incompatible way. Did anyone spot the same behavior? Can it be
fixed? That is without rewriting the whole ffi/unsafe library.

I am using a simple workaround to scribble my libraries with ffi/unsafe
requires:

->8-
#lang racket
(require
 ffi/unsafe
 scribble/srcdoc)
(provide
  (proc-doc/names
a-struct?
(->* (any/c) () boolean?)
((a) ())
("Returns true if a is a-struct")))
(struct a-struct (b))
->8-

But it is kind of strange to use (-> any/c boolean?) contract for
predicate in one module and (->* (any/c) () boolean?) in another one.

It sort of feels like the problem with requiring unsafe-vector-ref
without knowing. Although this is also "without knowing", it at least
exhibits itself at the syntax stage (and not at run-time).



Cheers,
Dominik

-- 
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/2ac9a533-4325-53da-6855-01bd07da81a3%40trustica.cz.


Re: [racket-users] Re: Inadvertedly requiring racket/unsafe/ops

2019-12-15 Thread Dominik Pantůček
Hi,

On 15. 12. 19 2:57, Jack Firth wrote:
> I think that documentation fix is a good idea.

I'll submit a PR to appropriate repository later on.

> More broadly, it seems awkward that all of the unsafe ops for 
> different data types are combined together into a single module. I 
> would instead expect there to be modules like racket/fixnum/unsafe, 
> racket/struct/unsafe, racket/vector/unsafe, etc. But I've never used 
> the unsafe ops before, maybe those who have can chime in?

it's not that easy as it is really about the "ops" part. For example if
you need (make-fxvector ...), you still need to require it using
(only-in racket/fixnum make-fxvector) as there is no racket/unsafe/ops
equivalent (which is really NOT surprising).

And also splitting the racket/unsafe/ops into more modules might break a
thing or two as it has been this way for quite some time. Also it is
nice - if you are in need of heavy optimizations - to see the list of
unsafe ops in one place.


Cheers,
Dominik

> 
> On Saturday, December 14, 2019 at 1:03:14 PM UTC-8, Dominik Pantůček 
> wrote:
> 
> Hello,
> 
> the documentation at 
> https://docs.racket-lang.org/reference/fixnums.html 
> <https://docs.racket-lang.org/reference/fixnums.html> is misleading 
> at best. If you - as I did - use the suggested approach of requiring 
> optimized (and unsafe) fx... operations from racket/unsafe/ops with:
> 
> (require (filtered-in (λ (name) (regexp-replace #rx"unsafe-" name 
> "")) racket/unsafe/ops))
> 
> You end up using _all_ symbols from racket/unsafe/ops. All of them 
> are - of course - uncontracted. Which means that if you issue for 
> example vector-ref on something that is not a vector, it can crash 
> the runtime without any apparent reason - instead of just throwing
> an exception as one would expect.
> 
> A simple documentation fix should probably go along the lines:
> 
> (require racket/require (filtered-in (λ (name) (and (regexp-match 
> #rx"^unsafe-fx" name) (regexp-replace #rx"unsafe-" name ""))) 
> racket/unsafe/ops))
> 
> Or is it just me running into corner cases with optimized Racket 
> code?
> 
> 
> Cheers, Dominik
> 
> -- 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 
> <mailto:racket-users+unsubscr...@googlegroups.com>. To view this 
> discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/c118c47e-fccd-4fab-b252-7a24afe6eef1%40googlegroups.com
>
>
>
>
> 
<https://groups.google.com/d/msgid/racket-users/c118c47e-fccd-4fab-b252-7a24afe6eef1%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/4185c1c1-7e2b-ea02-a9c5-03231cb112c2%40trustica.cz.


[racket-users] Inadvertedly requiring racket/unsafe/ops

2019-12-14 Thread Dominik Pantůček
Hello,

the documentation at https://docs.racket-lang.org/reference/fixnums.html
is misleading at best. If you - as I did - use the suggested approach of
requiring optimized (and unsafe) fx... operations from racket/unsafe/ops
with:

(require (filtered-in
  (λ (name) (regexp-replace #rx"unsafe-" name ""))
  racket/unsafe/ops))

You end up using _all_ symbols from racket/unsafe/ops. All of them are -
of course - uncontracted. Which means that if you issue for example
vector-ref on something that is not a vector, it can crash the runtime
without any apparent reason - instead of just throwing an exception as
one would expect.

A simple documentation fix should probably go along the lines:

(require racket/require
 (filtered-in
  (λ (name)
(and (regexp-match #rx"^unsafe-fx" name)
 (regexp-replace #rx"unsafe-" name "")))
   racket/unsafe/ops))

Or is it just me running into corner cases with optimized Racket code?


Cheers,
Dominik

-- 
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/1262b01a-5e9c-180e-d02a-b2e331c1f3cc%40trustica.cz.


[racket-users] futures-sort update

2019-12-07 Thread Dominik Pantůček
Hello Racketeers,

I am continuing my work on cleaning up our private source code and
publishing it as a part of my futures-sort[1] package. Current state of
the package is:

- configurable parallelism depth
- in-place parallel merge-sort of both vector and fxvector
- parallel merge-sort with results going to a freshly allocated vector
- support for calling a custom progress reporting function for all variants

The only missing piece to put this on par with vector-sort is probably
the support for start and end indices and the #:key argument (which we
are internally using). I am not entirely sure if key-caching is feasible
though.

Apart from that and some documentation improvements (mainly for the
progress reporting feature), it is basically complete. In the future I'd
like to investigate possible speedups by providing optimized code paths
for "small" ranges starting with 3 element ranges.

I would appreciate any suggestions and/or feature requests.

Btw, this is production code we are using to speed up tome tasks both on
Linux and Windows.

If you want to benchmark it, beware: it is necessary to first sort some
large dummy vector to ensure that JIT kicks in (1000 elements is enough
with 7.5 on my i7 running Linux).

Also I am curious about what is necessary to get the package to a higher
ring. There will be no backwards-incompatible changes from now.

Any suggestions are - of course - welcome.


Cheers,
Dominik


[1] https://pkgs.racket-lang.org/package/futures-sort

-- 
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/eeb76294-4057-3226-9cab-a4e9c62afa03%40trustica.cz.


Re: [racket-users] Vector length and indices contracts

2019-12-04 Thread Dominik Pantůček



On 04. 12. 19 20:21, Matthew Flatt wrote:
> I think it makes sense to refine the contract to guarantee a fixnum
> result for `vector-length`.
> 
> This fact is currently documented in `unsafe-vetcor-length`, because
> that's the layer where it has seemed sensible to talk about fixnums in
> the past, but that's not where anyone would think to look. Meanwhile,
> the contract for unsafe operation doesn't specify a nonnegative fixnum
> as it should.
> 
> At Wed, 4 Dec 2019 14:07:47 -0500, George Neuner wrote:
>>
>>
>> It would be more correct to use  (and/c fixnum? (or/c zero? positive?)) 
>> to explicitly limit the value.

My impression is - so far - that (and/c fixnum? (or/c zero? positive?))
or (and/c fixnum? exact-nonnegative-integer?) should be the right way to
go with vector-length.

What about all the vector-ref, -set! and basically all indices
contracts? That should probably be the same.

Also updating the contracts for unsafe-vector-* seems reasonable to me.


Dominik

-- 
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/f54df855-6ffd-4979-0f58-2126c80f577d%40trustica.cz.


[racket-users] Vector lenght and indices contracts

2019-12-04 Thread Dominik Pantůček
Hello,

looking at vector-length[1] documentation, it returns
(exact-nonnegative-integer?). However, as far as I can tell, it returns
(fixnum?). Also for subsequent contracts in the vector's documentation
all indices are assumed to be (exact-nonnegative-integer?) but usually
it is impossible on given platform to use anything larger than (fixnum?)
in reality.

For example on 64bit platforms the (fixnum?) could store numbers from (-
(expt 2 62)) to (sub1 (expt 2 62)). Vector slots cannot be smaller than
64bits (machine-dependent pointers) which means 8 bytes = 3 bits of
address. Given 64bit (VERY theoretical) size of the address space, this
leaves the possibility of storing a single vector with (expt 2 61)
elements into the memory.

If I did not overlook anything, the contracts could be safely changed to
(fixnum?).

And yes, I found this issue while cleaning up my futures-sort[2] package
discussed a few months ago here. If I assume
(exact-nonnegative-integer?), I need to manually check for (fixnum?).
Even though it - given the information above - does not really make much
sense.


Should I open a PR?


Cheers,
Dominik


[1]
https://docs.racket-lang.org/reference/vectors.html#(def._((quote._~23~25kernel)._vector-length))
[2] https://docs.racket-lang.org/futures-sort/index.html

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/e9ea30ad-5563-fe1a-688c-73fe47b51e68%40trustica.cz.


Re: [racket-users] question re downloading a PDF file

2019-11-24 Thread Dominik Pantůček
Hi,

On 24. 11. 19 13:01, Tim Hanson wrote:
> hi,
> 
> I need to fetch a number of PDF documents and wrote a bit of racket to make 
> it easier. The part that "downloads" is this:
> 
> (let ([content 
>((compose port->string get-pure-port string->url) (url-for-doc 
> year doc-name))])
>   (let ([out (open-output-file full-path-of-file-to-write #:mode 'text)])
> (write-string content out)
> (close-output-port out)

as far as I can tell the PDF is not a string - rather it is bytes. I
would try port->bytes and write-bytes in your case.


Cheers,
Dominik

-- 
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/cb06a85a-1840-f8c0-111f-9b5af21910f7%40trustica.cz.


Re: [racket-users] Re: Parallel merge-sort leveraging futures

2019-10-10 Thread Dominik Pantůček
Hello,

thanks everyone for helping me putting this into a reasonable shape.

My short-term plans with futures-sort are currently to check how various
construct could be improved (or'ing of touched futures is really just a
quick hack for example). Also I'd like to investigate why it didn't work
for me when I used the futures example in documentation[1] - that is to
perform one half of the computation in current context and then touch
future with the other half.

Feature-wise I'd like to implement a version that returns a fresh
vector. However I want to avoid any unnecessary copying so I want ot use
similar approach as with swapping/keeping for cnt=1 or 2. With this
ready it should be a faster drop-in replacement for all (fx)vector
sorting functions. I am not sure if similar approach is viable for lists.

And yes, it needs real tests. However I am not sure what kind of
reproducible tests to add there. Especially that the parallelism may not
be available on given platform. Maybe creating reasonably small vector
of random numbers with static seed and force two "parallel" futures no
matter what is available?

Also today I published on our company blog[2] (no need to follow this
link) some benchmarking results obtained on ThinkPad x280[3] (4 cores, 8
HT) and on a VM running on  Intel Xeon with 16 cores / 32 HT with 16
VCPUs assigned to the VM[4]. I measured 10 runs for each N where N was
n*2^18 for n in 1 to 255 which covers the range from 0 to 2^24 or
roughly 16M.

All times are measured using time-apply and the resulting data set was
processed with Gnuplot and empirical data were fitted using
f(x)=a*n*log2(n).

A few interesting remarks - once we reach the HTs (and not just cores),
the memory starts to be a real bottleneck. Hence the small difference
between depth=2 and depth=3 on i7.

Also for depth=3 and depth=4 sometimes Racket just hung and I had to
restart the tests. I will try to create a minimal working example where
futures can block indefinitely. Does anyone have similar experience for
example with pmapf?


Cheers,
Dominik


[1]
https://docs.racket-lang.org/guide/parallelism.html#%28part._effective-futures%29
[2]
https://trustica.cz/en/2019/10/10/parallel-merge-sort-leveraging-futures-in-racket/
[3]
https://trustica.cz/wp-content/uploads/2019/10/futures-sort-telperion.png
[4] https://trustica.cz/wp-content/uploads/2019/10/futures-sort-builder.png

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/f9bdae48-d027-9ed4-0cc3-e97f230a7b21%40trustica.cz.


Re: [racket-users] Re: Parallel merge-sort leveraging futures

2019-10-08 Thread Dominik Pantůček
Hi,

On 08. 10. 19 6:58, Sam Tobin-Hochstadt wrote:
> I've submitted a pull request fixing those errors and supporting
> running in serial mode.

thank you for that, it's already fixed. I am actually pulling this from
our internal git repository and I imported older info.rkt into the
Github one.

For the contracts - now it is void? instead of suggested any/c. The
functions are modeled like vector-sort! - which returns #.

Btw, is it necessary to bump the version on pkgd.racket-lang.org in
order to get it updated? When I `raco install' the package from its
directory, it works fine now. When I use the github repository using
plain `raco pkg install futures-sort' it still uses the old version.
Just removing and re-installing does not change anything.

> 
> One thing I notice is that it's substantially faster than
> `vector-sort!` even when run in serial mode on traditional Racket (but
> not on Racket CS), so perhaps this should be integrated (or there are
> improvements that we can adopt).

We mostly discussed that with Jens Axel on #racket - main advantage at
the lowest level is the usage of fixnums for everything. This however
means that the vector's size to be sorted must be `fixnum?'. Which I
think is always the case on all supported architectures (addressable
memory and such).

> 
> Alex, just to clarify a couple things about futures: they block when
> performing operations that are either sensitive to the current
> continuation or need single-threaded access to the runtime. Vector
> operations, as you see in Dominik's code, are not in this category.
> Mutable hash table operations are blocking. Here's some numbers with
> performance on sorting a vector with random fixnums using this package
> on a 4 core machine with hyperthreading, "classic" is `vector-sort!`.
> Note that the futures-sort library creates 2^k futures.
> 
> k: 0
> cpu time: 3402 real time: 3399 gc time: 45
> k: 1
> cpu time: 3487 real time: 1834 gc time: 46
> k: 2
> cpu time: 3581 real time: 1097 gc time: 69
> k: 4
> cpu time: 5745 real time: 1014 gc time: 69
> k: 8
> cpu time: 5742 real time: 992 gc time: 45
> k: 16
> cpu time: 8111 real time: 2189 gc time: 279
> 'classic
> cpu time: 4390 real time: 4388 gc time: 98
> 
> Here are similar numbers for Racket CS:
> 
> k: 0
> cpu time: 2960 real time: 2960 gc time: 33
> k: 1
> cpu time: 3021 real time: 1594 gc time: 33
> k: 2
> cpu time: 3462 real time: 1154 gc time: 36
> k: 4
> cpu time: 4381 real time: 929 gc time: 36
> k: 8
> cpu time: 4406 real time: 889 gc time: 34
> k: 16
> cpu time: 7124 real time: 1655 gc time: 440
> 'classic
> cpu time: 2749 real time: 2749 gc time: 51

Is there a package for these benchmarks? I created some benchmarks based
on sorting vectors of varying size from 1 to 2^27 elements. It would be
really nice to test this on a number of systems to get some empirical
data here. The GC can sometimes surprise (me, at least). My benchmarks
used (current-inexact-milliseconds) before and after each run which is
not something very exact. I'll post some graphs on our company blog on
Thursday probably.

Thank you Sam and Alex!


Cheers,
Dominik

-- 
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/7409b25d-8638-36ff-4c2e-7253da5ab672%40trustica.cz.


[racket-users] Parallel merge-sort leveraging futures

2019-10-07 Thread Dominik Pantůček
Hello,

over the course of past few months I have been tasked with solving a
(real-world) problem of sorting the sums of all possible combinations of
numbers. Some boring accounting stuff revolving around invoices. As the
total number of combinations is 2^N where N is the number of source
numbers, this task got "interesting" once there were more than 24
numbers - that is on my laptop with:

model name  : Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz

4 cores, 8 hyper-threads and 16GB RAM.

Long story short, I had to implement a custom merge-sort for fxvectors
and managed to leverage futures for fully parallel execution. Now in
some spare time, I slightly polished the code and released it as
"futures-sort" package.

The source code is available on GitHub[1] and it is already in Racket
package index[2].

The package provides four sorting functions - two for vector? and two
for fxvector?. There are two variants of each, one with progress
reporting and one without. For the original task I needed to show
progress using racket/gui gauge% and it might be helpful for others
(it's just a callback that gets current and total number of merges
performed regularly).

I would really appreciate any feedback regarding the naming conventions,
code style and generally anything else.

Yes, the tests are not there (yet).

The same algorithm without futures runs on par with Racket's default
sorting routines (tested for sets upto 2^30 - only 16G of memory here)
and for fixnums it is even (very slightly but consistently) faster than
vector-sort alone. With parallelism using futures it runs roughly N
times faster where N is the number reported by (processor-count).

I have already some benchmark results available and once I get more data
I am more than happy to share it as well.

The parallelism is configurable as parameter.

And yes, all of this can be seen in the documentation which is included
but I still have to look into how to build it - I was sort of assuming
this works automatically based on what I see for example in
scribble-math[3][4]. Any help with getting this right is also more than
welcome.


Lastly - thanks go out to Jens Axel Søgaard for pointing out that
fixnums and fxvectors might help (and why) and also to other helpful
folks on #racket at Freenode.


Cheers,
Dominik


[1] https://github.com/dzoep/futures-sort
[2] https://pkgd.racket-lang.org/pkgn/package/futures-sort
[3] https://docs.racket-lang.org/scribble-math/index.html
[4] https://pkgd.racket-lang.org/pkgn/package/scribble-math

-- 
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/bdddfd14-7e06-28e7-91c0-67a2403f5629%40trustica.cz.


Re: [racket-users] scribble/srcdoc raised exception fix and class-doc syntax form

2019-09-27 Thread Dominik Pantůček
Hi,

On 25. 09. 19 19:43, Dominik Pantůček wrote:
> 
> On 25. 09. 19 19:32, Ben Greenman wrote:
>>> Should I include a brief documentation in
>>> scribble-doc/scribblings/scribble/srcdoc.scrbl within the same PR as well?
>>
>> Yes!
> 
> Btw, looking at the struct-doc and struct*-doc descriptions maybe I
> should actually provide class-doc and class*-doc forms. The former for
> documenting classes without interfaces and the latter with interfaces
> list. The underlying defclass omits interfaces in the generated
> documentation if the interfaces list is empty (which is something the
> transformer can do for class-doc then). This way it would strictly
> follow the difference between class and class* forms.
> 

it's there as PR#213.

However, I have no clue what @history[#:added ...] should be attached to
the scribblings. The git tags are the same as for Racket releases and
the version from scribble-lib/info.rkt is 1.29. I can guess 1.30 might
be fine, but I'd rather get this confirmed.


Cheers,
Dominik

-- 
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/8a3e1925-8c63-ef00-ce6e-c27da19eea8b%40trustica.cz.


Re: [racket-users] scribble/srcdoc raised exception fix and class-doc syntax form

2019-09-25 Thread Dominik Pantůček


On 25. 09. 19 19:32, Ben Greenman wrote:
>> Should I include a brief documentation in
>> scribble-doc/scribblings/scribble/srcdoc.scrbl within the same PR as well?
> 
> Yes!

Btw, looking at the struct-doc and struct*-doc descriptions maybe I
should actually provide class-doc and class*-doc forms. The former for
documenting classes without interfaces and the latter with interfaces
list. The underlying defclass omits interfaces in the generated
documentation if the interfaces list is empty (which is something the
transformer can do for class-doc then). This way it would strictly
follow the difference between class and class* forms.

> 
> And if there are tests for scribble/srcdoc, it'd be good to add some
> for `class-doc` before merging
> 

There are tests only for proc-doc-transformer and
proc-doc/names-transformer. All other forms are without any tests (which
sort of makes sense).


Dominik
P.S.: Btw, I am subscribed to the list ...

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/e4f4f4db-2484-472f-78f2-89690771057f%40trustica.cz.


Re: [racket-users] scribble/srcdoc raised exception fix and class-doc syntax form

2019-09-25 Thread Dominik Pantůček
Hi,

thank you for the quick response.

On 25. 09. 19 17:11, Ben Greenman wrote:
> These changes look great. Can you open a pull request for the
> racket/scribble repo?
> 

opened PR#212.


> It looks like:
> - `class?` would be a better contract than `any/c`

Definitely makes sense, as the result is contract-out. I will change that.

> - maybe `defmethod`, `this-obj', and others should be required, in
> case the `pre-flow` needs them

Adding at least defconstructor and defmethod is definitely a good idea
(those are used heavily within defclass anyway). Although I've rarely
used this-obj so far, it looks like a very good idea indeed, so I will
add these three symbols into require value.

> 
>> 
>> It does not handle the maybe-link keyword argument as I am not using it
>> and I didn't dive into where it is used in order to test it.
> 
> That seems fine because `thing-doc` doesn't provide a maybe-link to
> `defthing` either.
> 

I see. So let's just forget about it right now then.

I will clean it up and create another PR for it.

Should I include a brief documentation in
scribble-doc/scribblings/scribble/srcdoc.scrbl within the same PR as well?


Cheers,
Dominik

-- 
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/faf46d5a-6f88-e82c-3600-b55b03a9f95d%40trustica.cz.


[racket-users] scribble/srcdoc raised exception fix and class-doc syntax form

2019-09-25 Thread Dominik Pantůček
Hello,

as a heavy user of scribble/srcdoc I've always missed a defclass provide
form equivalent. Therefore I wanted to implement my own. I decided to
use thing-doc as a starting point and noticed that it raises misleading
message if id is not an identifier. Minimal working example follows.

 MWE: test.rkt 
#lang racket
(require scribble/srcdoc)
(provide (thing-doc 5 number? "Just a number."))
 MWE: test.scrbl 
#lang scribble/manual
@(require scribble/extract)
@include-extracted["test.rkt"]


Running scribble --pdf test.scrbl produces:

test.rkt:4:12: parameter/doc: expected an identifier
  at: 5
  in: (thing-doc 5 number? "Just a number.")
  location...:
   test.rkt:4:12
  context...:

Looking at the sources file scribble-lib/srcdoc.rkt, the line 580 lists
the wrong exception identifier. A patch against current master follows:


diff --git a/scribble-lib/scribble/srcdoc.rkt
b/scribble-lib/scribble/srcdoc.rkt
index ee977a16..e9dd3311 100644
--- a/scribble-lib/scribble/srcdoc.rkt
+++ b/scribble-lib/scribble/srcdoc.rkt
@@ -577,7 +577,7 @@
   [(_ id contract desc)
(begin
  (unless (identifier? #'id)
-   (raise-syntax-error 'parameter/doc
+   (raise-syntax-error 'thing-doc
"expected an identifier"
stx
#'id))


Also I implemented a simple defclass wrapper as a provide form named
class-doc:

 class-doc syntax form 
(define-provide/doc-transformer class-doc
  (lambda (stx)
(syntax-case stx ()
  [(_ id super (intf-id ...) pre-flow)
   (begin
 (unless (identifier? #'id)
   (raise-syntax-error 'class-doc
   "expected an identifier"
   stx
   #'id))
 (unless (identifier? #'super)
   (raise-syntax-error 'class-doc
   "expected super class identifier"
   stx
   #'id))
 (values
  #'[id any/c] ; contract not used?
  #'(defclass id super (intf-id ...) . pre-flow)
  #'((only-in scribble/manual defclass))
  #'id))])))


It does not handle the maybe-link keyword argument as I am not using it
and I didn't dive into where it is used in order to test it.

 maybe-link =   
|   #:link-target? link-target?-expr

I would appreciate any feedback and/or improvement suggestions.

Is there a chance this new provide form can be merged into
scribble-lib/srcdoc.rkt in the future or is it better to create a
separate package for it?


Cheers,
Dominik

-- 
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/99cc1ba0-19f3-717b-b089-6cd6aa948144%40trustica.cz.