Re: [racket-users] Scribble: tables and figures with captions and numbering?

2017-07-07 Thread Dupéron Georges
Scribble has a low-level mechanisms for handling “numberers”, which aim to 
solve the the same problem as LaTeX's counters.

http://docs.racket-lang.org/scribble/core.html#%28tech._numberer%29

Alternatively, MathJax natively supports numbering equations: 
http://docs.mathjax.org/en/latest/tex.html#automatic-equation-numbering .

I'll try to see if I can integrate one of these mechanisms in scribble-math at 
some point (don't hold your breath, I'm too busy right now so it will wait a 
bit).

Follow this GitHub issue for updates: 
https://github.com/jsmaniac/scribble-math/issues/6

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Scribble: is there a way to refer to a section by its number in HTML?

2017-06-22 Thread Dupéron Georges
My apologies, the code I just posted was missing a `reverse`. Here's the fixed 
version:

@(define (sec-number→string tag #:doc [doc #f])
   (delayed-element
(λ (the-renderer the-part the-resolve-info)
  (define sec-tag (make-section-tag tag #:doc doc))
  (define resolved-sec-tag (resolve-get the-part the-resolve-info sec-tag))
  (if resolved-sec-tag
  (let ()
(unless (and (vector? resolved-sec-tag)
 (>= (vector-length resolved-sec-tag) 3))
  (error (format (string-append
  "Resolved section tag was not a"
  " vector of more than 3 elements: ~a")
   resolved-sec-tag)))
(define sec-number (vector-ref resolved-sec-tag 2))
(unless (list? sec-number)
  (error "Third element of a resolved section tag was not a list."))
(if (= (length sec-number) 1)
(format "Chapter ~a" (car sec-number))
(format "Section ~a" (string-join (map number->string
   (reverse sec-number))
  "."
  (elem #:style (style "badlink" '())
tag " #:doc " (format "~s" doc
(λ ()
  "Section ??")
(λ ()
  "Section ??")))

@(define (sec-number-ref tag #:doc [doc #f])
   (seclink tag #:doc doc (sec-number→string tag #:doc doc)))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Scribble: is there a way to refer to a section by its number in HTML?

2017-06-22 Thread Dupéron Georges
Thanks a lot!

I was able to build an @sec-number-ref function. Here it is below. Matthew, 
since this is not a copy-paste of your code, I hope you won't see any problems 
if I place this in the public domain / CC0 license?

@(define (sec-number→string tag #:doc [doc #f])
   (delayed-element
(λ (the-renderer the-part the-resolve-info)
  (define sec-tag (make-section-tag tag #:doc doc))
  (define resolved-sec-tag (resolve-get the-part the-resolve-info sec-tag))
  (if resolved-sec-tag
  (let ()
(unless (and (vector? resolved-sec-tag)
 (>= (vector-length resolved-sec-tag) 3))
  (error (format (string-append
  "Resolved section tag was not a"
  " vector of more than 3 elements: ~a")
   resolved-sec-tag)))
(define sec-number (vector-ref resolved-sec-tag 2))
(unless (list? sec-number)
  (error "Third element of a resolved section tag was not a list."))
(if (= (length sec-number) 1)
(format "Chapter ~a" (car sec-number))
(format "Section ~a" (string-join (map number->string
   sec-number)
  "."
  (elem #:style (style "badlink" '())
tag " #:doc " (format "~s" doc
(λ ()
  "Section ??")
(λ ()
  "Section ??")))

@(define (sec-number-ref tag #:doc [doc #f])
   (seclink tag #:doc doc (sec-number→string tag #:doc doc)))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Indentation of for-clauses

2017-06-15 Thread Dupéron Georges
Le mardi 13 juin 2017 23:49:23 UTC+2, Alex Knauth a écrit :
> I'm imagining the existing DrRacket indentation rules would be expressed as:
> 
> […]

This seems like a nice concise notation, although it is a bit cryptic at first 
sight :) .

I'm not quite sure if if covers the following case (where y should be aligned 
with x).

(f #:kw x
y
   #:more …)


As a side remark, I have been pleasantly impressed by JetBrain's Meta 
Programmin System [1]'s ability to nicely lay out uses of "macros" (or rather, 
graphical language elements), and more generally the fact that in principle, 
when using a "macro", one can make use of contextual features (auto-complete 
being the main one, but more should be possible).

Achieving this with Racket (without putting snip% graphical objects in the 
code) seems more difficult, because in order to know which macro an identifier 
is bound to, the whole file must be macro-expanded until that point. 
Conversely, I think that with JetBrains MPS the binding is known statically 
from the moment it is inserted into the code.

I wonder if, in a hypothetical future, the best route for Racket to support 
contextual enhancements which can be customised by a macro or function (syntax 
highlighting, indentation, tooltips/blueboxes, auto-completion, macro-specific 
tools), would be to:

* go towards structured editing (which is what MPS relies on), as a lot of the 
infrastructure is already there with snip%, and something like lexi-lambda's 
idea of a syntax/parse/gui could make this relatively painless;
* or to define "lightweight" front-ends to macros, which only perform enough 
expansion that the desired information can be extracted (similarly to how the 
syntax highlighter returned by a language's get-info is a dumbed down / 
optimised version of the parser),
* or if we should follow the approach taken for blueboxes, and cache the 
desired information.
* or something else.

This is ostensibly just a thought experiment, as going towards structured 
editing would be a non-trivial change for Racket.

Cheers,
Georges

[1] : https://www.jetbrains.com/mps/

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Scribble: is there a way to refer to a section by its number in HTML?

2017-06-08 Thread Dupéron Georges
Generally it is nice to get the actual section title printed when using 
@secref["mysection"]. However, in some cases it is a bit awkwards:

Chapter State of the art presents related work. Chapter Implementation explains 
in detail how this library is implemented. etc.

I'd rather have something as follows, with the whole "Chapter 2" and "Chapter 
3" being hyperlinks:

Chapter 2 presents related work. Chapter 3 explains in detail how this library 
is implemented. etc.

I can do this easily with @seclink, but I need to hardcode the chapter and 
section numbers. Is there an easy way to access them and automatically inject 
the chapter/section number (e.g. in Scribble's resolution phase)?

Thanks,
Georges Dupéron

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-07 Thread Dupéron Georges
Le dimanche 7 mai 2017 23:14:17 UTC+2, Daniel Prager a écrit :
> Thanks for the explanation on 2. Pragmatically, it's just another contributor 
> to the cost of contract checking.

I suppose you meant point 3, instead of point 2? The thread I linked to 
indicates that with ->d, the double-checking does not occur. Although the docs 
mention ->d is left only for backward compatibility, it is still available.

> On 1, I'm (naïvely) baffled as to why the contract should regard an optional 
> argument as unsupplied when it comes from the default rather than an explicit 
> passing. 

#lang racket
(define my-contract
  (->i () ([x (>=/c 1)]) [result real?]
   #:post (x result) (>= result (sqr x

(define (my-sqr [y 10]) (* y y))
(define (my-cub [z 20]) (* z z z))

(define/contract my-sqr-contracted my-contract my-sqr)
(define/contract my-cub-contracted my-contract my-cub)

Contracts are values. In the example above, the default value for the first 
optional argument (named x in the contract) is not the same for the first and 
second functions (10 and 20 respectively).

To emphasise the separation between the contract and the functions, I used 
different variable names in the contract (x) and the functions (y and z, 
respectively). I also defined the functions separately, so that when the 
contract is attached, the function's source is not syntactically within 
define/contract (the functions could even be defined in another module).

I'm not sure it is even possible to access the default value for an argument 
once the function is created. If it is possible (but I doubt it), then the 
contract could extract the default expression (which could refer to a global 
mutable value) when a check occurs. It would be nice indeed if this magic 
occurred, but it seems non-trivial to implement.

Furthermore, an poorly designed contract could incorrectly pre-compute the 
default expression, and pass it to the function (e.g. pass 11 instead of 10, 
due to a bug in the contract implementation). The simple fact that this is 
technically possible to make it impossible for the contract generated by ->i to 
be a chaperone, instead it would have to be an impersonator.

You can easily enough define a leaky abstraction with a macro which copies the 
default expression in the contract and in the function signature (but this 
would cause multiple evaluations). I tired to think about caching the value, 
but can't find a way to do so without breaking the blame mechanism (e.g. by 
wrapping the function, the inner one with the contract + mandatory arguments, 
and the outer one with optional arguments + no contract).

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-07 Thread Dupéron Georges
Le dimanche 7 mai 2017 07:27:08 UTC+2, Daniel Prager a écrit :
> 1. Default argument goes missing from post-condition, leading to an
> unexpected error ...

You should use unsupplied-arg? . But I couldn't find a way to get the default 
value from the contract. I would guess that the problem is that the contract 
can be specified separately from the function, and the function itself knows 
the default argument's value. In the general case, extracting the default 
argument's value (without running the default expression multiple times) might 
be tricky.

> 2. contract-exercise seems to miss explicit #pre-conditions ...

This does look like a real (pun intended) problem.

> 3. post-conditions appear to be called twice ...

With the code below, the post-condition only gets called once:

#lang racket

(define/contract (real-sqrt x)
  (->i ([x real?])
   #:pre (x)
   (>= x 0)
   [result any/c]
   #:post (result)
   (begin (displayln result) (>= result 0)))
  (sqrt x))

(real-sqrt 1)

With this code, however, the contract does get called twice:

#lang racket

(define/contract (real-sqrt x)
  (->i ([x real?])
   #:pre (x)
   (>= x 0)
   [result (λ (result) (displayln result) (>= result 0))]
   #:post (result) #t)
  (sqrt x))

(real-sqrt 1)

See this very interesting thread on the mailing list for a detailed discussion 
about this 
https://groups.google.com/forum/#!searchin/racket-users/contract$20twice%7Csort:relevance/racket-users/SUzcozdPh6Q/bjgEjTyQEAAJ
 .

Short story: if one of the arguments is a function, and a dependent #:pre, 
#:post, argument or result contract calls that function, you want it to be 
protected. The contract therefore needs to be applied to the argument before it 
is passed to the other dependent clause, and is applied again when actually 
calling the function.

> Finally, some timings.

Thanks for taking the time to test this out :) .

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-06 Thread Dupéron Georges
Le dimanche 7 mai 2017 00:27:36 UTC+2, Daniel Prager a écrit :
> Thanks Georges
> 
> It looks suggestive, but I'm struggling to follow the details of 
> with-contract / blame-id. An example of use would be very helpful in the docs!

This gives "blaming: (region unsafe-factorial)" instead of "blaming: (function 
unsafe-factorial)". Aside from this slight leak, the messages are identical. 
Supposing this code is correct (I never used with-contract before), if you 
clean it up a bit and add an example to the docs, I'm sure a PR would be 
welcome :) .

#lang racket
(define-syntax-rule (define/tight (fn args ...)
  ctc
  body ...)
  (begin
(define (fn args ...) (fn/impl args ...))
(with-contract fn
   ([fn/impl ctc])
   #:freevar fn ctc
   (define (fn/impl args ...)
 body ...

(define/tight [unsafe-factorial n]
  (-> (and/c integer? (>=/c 0)) (and/c integer? (>=/c 0)))
  (if (zero? n) 
  1
  (* n (unsafe-factorial (- n 10)
(unsafe-factorial 5)

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-06 Thread Dupéron Georges
Le samedi 6 mai 2017 23:38:29 UTC+2, Daniel Prager a écrit :
> Although I understand why my macro does this
>
> unsafe-factorial: contract violation
> ...
>   blaming: (function fn/impl)
> ...
>   at: unsaved-editor:13.15
>
>
> Ideally I would prefer one which blames unsafe-factorial
>
> unsafe-factorial: contract violation
> ...
>   blaming: (function unsafe-factorial)
> ...
>   at: unsaved-editor:13.15
>
>
> i.e. it's leaking an auxillary introduced by the macro (fn/impl) into the
> message & Dr Racket. It seems that the line-number refers to the line that
> defines unsafe-factorial, though, which looks right.

Perhaps with-contract's `blame-id` can help?

http://docs.racket-lang.org/reference/attaching-contracts-to-values.html#%28form._%28%28lib._racket%2Fcontract%2Fregion..rkt%29._with-contract%29%29

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-05 Thread Dupéron Georges
Le vendredi 5 mai 2017 16:36:49 UTC+2, Matthias Felleisen a écrit :
> I think that developers should write contracts and use them during testing 
> and deployment in the same way. I did this decades ago for embedded realtime 
> software and we’d be all better off if we did so. 

I agree that I always feel uneasy about turning off contracts. But sometimes 
performance is a problem.

How would you therefore recommend checking the invariant that the recursive 
function's output is a list of integers, then (as a simple example)?

1. (define/contract (foo input) (-> blah (listof integer?)) …)

  This has a O(n²) cost. I'd consider this bad programming. It's not about 
small speed improvements, it's about making an application unusable altogether 
(the SMS app on my phone has a O(n²) somewhere, with n the number of texts 
sent. After a few thousands, it takes 30s to send a text, so it is effectively 
unusable).

2. (provide (contract-out [foo (-> blah (listof integer?))])) + regular define

  This has a O(n) cost, but does not perform any check during recursive calls. 
If the function is a case-lambda with many cases (which happens often in one 
form or another in macro implementations), it's then hard to guess which case 
is the culprit. One then has to resort to printf-debugging and throw-away 
sanity checks inserted during the debugging session and removed afterwards.

3. (define/contract (foo input) (-> blah (or/c (cons/c integer? any/c) null?)) 
…)

  This has a O(n) cost, and checks recursive calls, but it relies on the fact 
that the implementation of foo prepends elements to the result one at a time. 
If the implementation is changed so that at one point is prepends two elements, 
the contract fails to properly check the result.

Ideally, there would be a way to attach to a value a witness that a given 
contract was checked against it:

4. (define/contract (foo input) (-> blah (listof integer?)) …)
  where the contract check stops when it encounters an already-checked value.

In my current academic project (a typed variant of Nanopass), I'm using a 
hybrid approach: types enforce "simple" invariants. More complex structural 
invariants (acyclicity, well-scopedness, backward "parent" pointers in the AST 
which indeed point to the correct parent, and so on) are checked at run-time, 
since they cannot be expressed using Typed Racket's type system alone. Once 
such an invariant is checked, a phantom type is used on the value's type to 
indicate that the value was safely checked against a given invariant.

This allows compile-time verification that a call to a transformation pass 
gives a value which was properly checked, and also reduces the need for 
performing the same checks against the AST too often (passing the same AST to 
two or more analysis passes needs only one check).

I'm unaware of mechanisms which would allow annotating list elements or syntax 
objects in Racket, which would allow solution 4 to work. If it was possible to 
have chaperone contracts on pairs, it would be possible to wrap the checked 
output values with a no-op "witness" chaperone, and check for the presence of 
the chaperone. Alternatively, the contract system could maintain a cache of 
recently-checked values (like equal? does) e.g. using a weak hash table.

Of course, the best solution is to use types, but until Typed Racket becomes 
versatile enough to write macro implementations, and until Typed Racket gains 
dependent types, so that a wide range of expressive properties can be encoded, 
what would you recommend?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-05 Thread Dupéron Georges
Le vendredi 5 mai 2017 15:24:40 UTC+2, Matthias Felleisen a écrit :
> See 
> https://docs.racket-lang.org/style/Units_of_Code.html#%28part._.Modules_and_their_.Interfaces%29

That's a very interesting document, thanks for the reference. Would you suggest 
that, in this spirit, types for functions are moved to the top of the file with 
the provide forms, instead of being specified alongside each function?

> > On this topic, I have sometimes written recursive functions with expensive 
> > contracts (when recursing down a list, a contract on the whole list will 
> > have a total cost of O(n²)).
> 
> 2. I consider this a horrible idea and I made sure define/contract does not 
> do so. If you feel that unsure about recursive functions, I recommend using 
> types. They help you avoid typos at that level. 

I'm using types wherever possible. Unfortunately, TR does not (yet) mix well 
with contracts (but I'm aware that there is a pending PR for this). More 
importantly, Typed Racket cannot be used to write macro implementations, for 
several reasons:

* Lack of immutable values at the type level (this means that values with type 
Syntax can in principle contain mutable values, which break occurrence typing)

* syntax/parse (and possibly syntax/case) have not been ported to Typed Racket.

I did in the past a couple of experiments to use Typed Racket to implement 
macros, but the results were unsatisfactory. My best attempt so far, 
tr-immutable/typed-syntax (still unstable and undocumented) requires "unsafe" 
mutable syntax values to be converted to a "safe" representation, and converted 
back after executing the macro.

When writing complex compile-time transformations, I felt the need to check the 
input and output of every recursion step, to catch the exact point at which an 
error occurs.

I'm genuinely unsure which aspect of this idea you find horrible?

* Is it because the contract is specified along the function, with 
define/contract-out, instead of being written alongside the provide forms? If 
so, separating the contract from the function definition, using a form similar 
to TR's (: name type), would allow the contract to be specified next to the 
provide form, but still have it applied to recursive function calls during 
debugging.

* Is it because turning off the contract for recursive calls would lower the 
safety (i.e. the swim vest analogy)? In my case, the contract on the result was 
strong enough to catch the error anyway, and the goal was only to catch 
incorrect results as soon as possible, instead of waiting until they cross the 
module boundary and are returned to the original caller, so that it is easier 
to locate the exact source of the error.

* Is it because of something else that I missed?

In conclusion, I do agree that types are a much better option, and I do use 
them wherever possible. Unfortunately, there are some cases where types cannot 
be used (yet), and in those cases I'd like to get as much help as I can from 
contracts when debugging, without imposing a horrendous cost during normal 
development (which does not mean tossing all safety aside, but rather allow 
errors to be caught at module boundaries instead of detecting them nearly 
immediately). These goals do not seem insane to me, and I'm 100% open to 
suggestions on how to achieve this :) .

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-04 Thread Dupéron Georges
Le vendredi 5 mai 2017 02:30:50 UTC+2, Ben Greenman a écrit :
> With a `define/contract-out` macro?
> 
> But I'd rather not have a macro like this in the contract library.
> I prefer reading code with all the "provide" statements at the top of the 
> file.

Since provide transformers are executed in two passes (the second one being 
after the expansion of the rest of the file, IIRC), I thought about writing 
define/contract-out so that it saves the contract, but does not implicitly 
provide the identifier.

That way, if the identifier is provided, the "saved" contract is attached to it.

Types in Typed Racket work a bit like this: the type is defined or inferred 
alongside the function definition, but is also provided. The implementation 
mechanism is a bit more complex though (it relies on a submodule to store the 
types).

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-04 Thread Dupéron Georges
Le jeudi 4 mai 2017 03:00:10 UTC+2, Daniel Prager a écrit :
> On the subject of turning down contracts for performance and then being 
> bitten, believe me, I hear you: my preference is to have the maximum checking 
> I can afford. But when I'm really writing stringent post-conditions (or 
> invariants) they can get *really* expensive, negatively impacting on user 
> experience, which takes us into the land of pragmatic trade-offs. 
> 
> If I don't have a way to turn them off I'm either not going to write them at 
> all or comment them out, and then regret not using them on smaller test 
> scenarios.

On this topic, I have sometimes written recursive functions with expensive 
contracts (when recursing down a list, a contract on the whole list will have a 
total cost of O(n²)).

Using (provide (contract-out …)) is of course the right solution for the final 
version, but during debugging, the extra checks at each recursion step can help 
pinpoint bugs more easily.

In these cases, instead of turning off the contract checks altogether, it would 
be nice to have a way to disable the define/contract and turn it into a 
contract-out, using a single parameter (perhaps a per-file syntax parameter?).

I'm not sure what would be the best syntax and implementation strategy for 
this, though.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] How to improve compile times?

2017-04-28 Thread Dupéron Georges
> > * Alex Harsanyi's start-up time is due to run-time (phase 0) initialisation 
> > code in the required libraries, including things like (define v 
> > costly-expression), which look like they could be saved as constants, but 
> > actually involve running the expression.
> 
> I actively try to avoid this case and I believe the program has little or no 
> such code anymore.  However, even when I removed such cases, it did not seem 
> to make much difference.  Racket code actually runs fast.

Just a quick clarification: I meant that such initialisation code may be 
present in the libraries that you require, not in your own code (and so you do 
not have much control over this, unless you start modifying the libraries).

> > * If Alex Harsanyi's code uses dynamic-require or eval, the phase 1 
> > initialisation code of the required libraries is executed when eval or 
> > dynamic-require are first invoked.
> 
> The code does not use any of those things.  Also, apart from 3 macros dealing 
> with baking in some API KEYS at compile time, there are no uses of 
> `define-syntax` and friends.

Again, there could be some use of eval within library code, or in code 
generated by library macros, even if there is no direct use of eval in your 
code.

Nice application, by the way :)

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] How to improve compile times?

2017-04-27 Thread Dupéron Georges
Thank you Matthew for the explanation.

If I understand correctly,

* Alex Harsanyi's start-up time is due to run-time (phase 0) initialisation 
code in the required libraries, including things like (define v 
costly-expression), which look like they could be saved as constants, but 
actually involve running the expression.

* If Alex Harsanyi's code uses dynamic-require or eval, the phase 1 
initialisation code of the required libraries is executed when eval or 
dynamic-require are first invoked.

* The size of the bytecode does matter (and switching to Chez scheme's run-time 
could hopefully improve that)

Concerning the definition of a macro:

;; a.rkt
#lang racket
(require "b.rkt")
v

;; b.rkt
#lang racket
(require "c.rkt")
(provide v)
(define v (foo))

;; c.rkt
#lang racket
(provide foo)
(require racket/function)
(define-syntax foo (curry (λ (v stx)
(displayln v)
#'1)
  (begin (displayln "XX")
 (string-append "c" "c"

* The "cc" is printed when compiling b.rkt, but not when running a.rkt, nor 
when compiling a.rkt.

* The curry and string-append are executed when compiling c.rkt, when c.rkt is 
instantiated because it is required by b.rkt, and another fresh instantiation 
of c.rkt is done when it is transitively required by a.rkt. This can be seen by 
running raco make c.rkt; raco make b.rkt; raco make a.rkt, and observing that 
XX is printed each time.

* When executing racket a.rkt, no XX is printed unless eval is called at 
run-time at some point.

My conclusions, in terms of performance hints are that:

* It is safe to put code within the body of a transformer function (bound to a 
macro).

* Code outside of transformer functions (to define compile-time constants, or 
the curry in the example above) has a cost when compiling all files which 
transitively require that module. It also has a one-time run-time cost if/when 
eval, dynamic-require or something similar is used.

* The bytecode size has an impact too.

* It is therefore better to avoid requiring too many modules if they are not 
needed.



It would be nice to find a way to detect what code gets executed when a module 
is required, at the various meta-levels. Maybe running raco cover on an empty 
file containing only (require some-module) could help?



I'm not sure how submodules fit in this picture (the main concerns being the 
test submodule, and the doc submodule for literate programs).

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: #:grammar and #:contracts of scribble

2017-04-26 Thread Dupéron Georges
Hi,

This sounds like a nice enhancement.

You might want to request this at https://github.com/racket/scribble/issues .

Aside from the implementation difficulty (the code for defform and friends is 
large, handles many edge cases, and feels a bit like spaghetti code), one of 
the main concerns would be how this change would affect existing scribble 
documentation: if the alignment pushes text into the right margin when it was 
nicely fitting within the main content column, this might be a concern (I do 
not remember if the contracts have auto-wrap, if so this problem would not 
arise).

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] How to improve compile times?

2017-04-26 Thread Dupéron Georges
Hi all!

Some of my libraries take a while to load: just adding a (require mylib) to an 
empty #lang racket/base file bumps the compile time from 0.5s to 1.5s, even if 
no bindings from the library are used. After experimenting a bit, it seems that 
the overhead is mainly due to other modules which are transitively required 
(typed/racket, syntax/parse, …).

Assuming that all the files except the main one are already byte-compiled with 
raco make, what are the factors which affect compile times when a library is 
(possibly transitively) required? Note that we're talking about milliseconds 
here, but when a lot of modules are required, these can add up.

1. Number of bindings directly provided?
2. Number of bindings provided by transitively-required modules (including 
those which are not re-provided, and are not in the main file's namespace)
3. Number of files which are transitively required?
4. Size of the fully expanded code (or size of the bytecode)?
5. Compile-time operations, e.g. within a begin-for-syntax in a 
(transitively-)required module?
6. When a module is required at several meta-levels, does it affect the compile 
time significantly, or is it roughly the same cost than requiring it only once?
7. Something else?

Point 5 seems to matter, as compiling a.rkt still prints "Hello" even if b.rkt 
is already compiled:

a.rkt:
#lang racket/base
(require "b.rkt")

b.rkt:
#lang racket/base
(require (for-syntax racket/base))
(begin-for-syntax (displayln "Hello"))

However, I'm not sure what operations can cause compile-time code to be run in 
this situation. My (possibly incorrect) understanding is that macros are 
executed only once (when expanding the code), but the code to the 
right-hand-side of a (define-syntax foo costly-operation), and the code within 
a (begin-for-syntax …) will both be run each time the module is required.

What I would like is to learn a few "good practices" and gotchas concerning 
compile-time performance.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Re: How to work on a package from a released version of Racket?

2017-04-09 Thread Dupéron Georges
I thought raco pkg update was unable to turn a catalog-package into a
locally-installed package, but I might have tried it at the time
within the directory itself, instead of cd-ing one level up like you
said.

Thanks for the tip!

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: Algol

2017-04-09 Thread Dupéron Georges
As you say, it works with "#lang algol60", but I can't find "Algol60" in the 
language selection dialog on DrRacket 6.9.0.1, only R5RS, "Pretty big Scheme" 
and "ProfessorJ" (which I installed manually).

Which version are you using? Which version were you using when it used to 
work?This may help others diagnose your issue.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: How to work on a package from a released version of Racket?

2017-04-09 Thread Dupéron Georges
I hope that there's a better way, however what I ended up doing was this:

1) Install a "Minimal Racket" from 
http://download.racket-lang.org/releases/6.8/ (scroll down a bit to see these 
versions).

2) cd path/to/my-clone-of-plot/; raco pkg install

3) raco pkg install main-distribution

If you want to later replace an existing package with your local copy, you can 
then do:

2b) raco pkg remove --force the-package ### you can stop it with Ctrl+C after a 
couple of lines of output

2c) cd path/to/my-clone-of-other-package/; raco pkg install

When updating (e.g. after installing the upcoming 6.9), install a new "minimal 
racket 6.9", then run:

4) raco setup --clean ### fails on my machine because it tries to remove 
read-only files in the "minimal racket" installation directory. I run it a 
couple of times just to be sure, and ignore the failures.

5) raco setup -j 1
6) raco setup -j 1 --avoid-main
7) raco setup -j 1 --doc-index

I use -j 1 in the commands above to avoid Out-Of-Memory errors on systems 
without "much" RAM, as parallel builds use more RAM, and a few of my packages 
stress Typed/Racket at compile-time, which in turn uses lots of memory.

Hopefully someone will drop by and suggest better alternatives to my 
suggestions of using Ctrl+C and ignoring errors :) .

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: empty lines in a grammer of defform of scribble

2017-03-28 Thread Dupéron Georges
Le lundi 27 mars 2017 22:36:43 UTC+2, jos.koot a écrit :
> When I use #:grammar in a defform,
> the rules of the grammer are separated by empty lines.
> 
> I would like to avoid these empty lines.
> Is it possible?

I haven't seen a built-in mechanism to control this. Generally speaking, the 
tools for documenting bindings are somewhat inflexible, if your use case falls 
out of the existing options. This leaves you with three possibilities:

1) Copy the source code of the @defform macro, and patch it to your needs
2) Add an option to control this in the mainstream scribble, and hope/wait for 
your Pull Request to be accepted
3) Call the current, official @defform macro, and patch the result.

Solution 1 is future-proof, but your implementation and the official one may 
drift apart, yielding slight inconsistencies in the rendered output.

Solution 2 sounds better, although I wonder how many quick-fixes like this one 
@defform and similar macros can bear, given that they are already a maze of 
particularly complex code, with lots of special-casing.

Solution 3 is the simplest, but is also more brittle, as you depend on the 
output of @defform staying roughly the same.

Here's a quick and dirty implementation of solution 3, note that if you intend 
to use this in production, you should try to make the match pattern a bit more 
robust (i.e. a bit more general, in several cases I assume single-element 
lists, and any change in the implementation of @defform is likely to break this 
code).

#lang scribble/manual
@(require scribble/manual
  scribble/core
  racket/match
  racket/list)
@(define (defform-remove-empty-lines the-defform)
   (match the-defform
 [(box-splice
   (list
before ...
(nested-flow nf-style
 (list
  (table t-style
 (list other ...
   (list
(table (style "specgrammar" tspec-style)
   (list lines ...)))
   more ...
after ...))
  (define without-empty-lines
;; an empty lines is a sequence of five empty columns:
(remove* (list
  (list
   (paragraph (style #f '(omitable)) (element #f (list (element 
'tt '(nbsp)
   (paragraph (style #f '(omitable)) (element #f (list (element 
'tt '(nbsp)
   (paragraph (style #f '(omitable)) (element #f (list (element 
'tt '(nbsp)
   (paragraph (style #f '(omitable)) (element #f (list (element 
'tt '(nbsp)
   (paragraph (style #f '(omitable)) (element #f (list (element 
'tt '(nbsp)))
 lines))
  (box-splice
   (append
before
(list (nested-flow nf-style
   (list
(table t-style
   (append other
   (list (list
  (table (style "specgrammar" 
tspec-style)
 without-empty-lines)))
   more)
after))]))

@defform-remove-empty-lines[
 @defform[(foo bar baz quux)
  #:grammar ([bar (code:line xxx)
  (code:line yyy)]
 [baz (code:line zzz)
  (code:line ttt)]
 [quux (code:line aaa)
  (code:line bbb)])]{
  Blah blah lots of text.}]

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] syntax-parse: using expr/c with ~optional

2017-03-22 Thread Dupéron Georges
> (prefix 6 5 4) raises the same error as before, and the definition of 
> prefix/parse complains "syntax-parse: duplicate attribute in: tail".

This is because ~or behaves differently under ellipses, and nested ~or are just 
inlined. Your code for prefix/parse is therefore equivalent to (~or alt1 (~seq 
#:tail) (~and (~seq) (~parse tail #'null))) ...

To make a ~or pattern behave as a normal ~or, and not as a list of 
possibly-repeated elements, you can wrap it with a dummy ~and, i.e. writing 
(~or alt1 alt2 (~and (~or foo bar)) alt4) ... instead of (~or alt1 alt2 (~or 
foo bar) alt4) ...

I like to define a (~either . pats) pattern expander which aliases to (~and 
(~or . pats)), for better readability [1] .

In your case, since you want to limit it to a single occurrence anyway, you can 
simply wrap the inner ~or with ~once, as follows:

#lang racket
(require (for-syntax syntax/parse))
(define-syntax (prefix/parse stx)
  (syntax-parse stx
[(_ (~or (~seq nat:exact-nonnegative-integer)
 (~once (~or (~seq #:tail tail)
 (~and (~seq) (~parse tail #'null)
...)
 #:declare tail (expr/c #'(listof natural-number/c))
 #'(list* nat ... tail.c)]))


The issue with this solution, however, is that it allows the empty sequence 
(~seq) to be matched as part of a ellipsis-head pattern. This means that the 
(~seq) could match anywhere, and, save for the ~once, could match an infinite 
amount of times without consuming any element. To prevent such issues, 
syntax/parse guards against this, and you will get the following error:

syntax-parse: an ellipsis-head pattern matched an empty sequence

The simplest solution I can see is to re-bind the tail attribute to a real 
pattern variable, safe in the knowledge that the tail attribute is never #f, 
thanks to the #:defaults (note that if you nest uses of ~optional, e.g. 
(~optional (~seq (~seq a (~optional b #:defaults ([b c]))) ...)), then I think 
this is not true anymore, you'd have to provide #:defaults for the outer 
~optional too.

I'll use #:with here, but you could equally use a {~parse pvar-tail #'tail) in 
the pattern, somewhere after the (~or . pats) ...:

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

(define-syntax (prefix/parse stx)
  (syntax-parse stx
[(_ (~or (~seq nat:exact-nonnegative-integer)
 (~optional (~seq #:tail tail)
#:defaults ([tail #'null])))
...)
 #:with pvar-tail #'tail
 #:declare pvar-tail (expr/c #'(listof natural-number/c))
 #'(list* nat ... pvar-tail.c)]))

(prefix/parse 1 2 3)
(prefix/parse 1 2 3 #:tail 42) ;; contract violation, as expected.


It would probably be possible to abstract this using my 
extensible-parser-specifications library [2] which defines a ~seq-no-order 
similar to the one by Alexander Knauth, but allows some "post" operations which 
are executed after matching the whole sequence. I would recommend against it, 
however, as my library has severe limitations, and could really use a redesign 
(which might need some changes in syntax/parse itself, as achieving these 
"post" operations required a few hacks).

Alternatively, it would make sense to fix #:declare so that it handles 
gracefully #f values. Could you file an issue for this so that it is not 
forgotten?

[1]: 
http://docs.racket-lang.org/phc-toolkit/syntax-parse_helpers.html#%28form._%28%28submod._%28lib._phc-toolkit%2Fsyntax-parse..rkt%29._typed%29._~7eeither%29%29
[2]: http://docs.racket-lang.org/extensible-parser-specifications/

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] packages with separate -lib -test and -doc [Was: Package layout in docs]

2017-02-03 Thread Dupéron Georges
Hi Neil,

I'm starting a new thread to avoid hijacking the "Package layout in docs" 
thread.

Le mardi 31 janvier 2017 20:25:31 UTC+1, Neil Van Dyke a écrit :
> Greg Trzeciak wrote on 01/31/2017 01:24 PM:
> > Speaking of packages - there seems to be a trend recently in racket 
> > packages to create separate packages for main, lib, doc, test, etc. This 
> > causes an artificial inflation in available packages and IMHO may cause 
> > some confusion for newcomers as instead of finding eg. "PackageX" we now 
> > get the following instead:
> 
> I agree with Greg that this looks like people are going out of their way 
> to make clutter.  I don't think that ever should have been encouraged.

I have two such packages which are split in pkg/lib/test/doc. In both cases, it 
was not my desire, but rather a constraint.

In the first case, the whole package was taking too long to build on pkg-build, 
and that package (as well as those depending on it) were therefore marked as 
failing to build. There's a hard 20 minutes limit on pkg-build, it is not a 
very fast machine (Travis builds the package *and* all its dependencies in 
about 15 minutes), and performance varies from build to build, due to the 
server's load I guess — it sometimes takes several minutes more than usual, and 
having builds randomly fail every time I push a change or one of the 
dependencies is changed is not acceptable.

In the second case, I was referring in the documentation to uses of the 
package: "this package is used for example to build 
@racketmodname[package-bar]". Unfortunately, this creates a cyclic dependency 
(foo's doc depends on bar's doc, and bar depends on foo). The pkg-build server 
and raco pkg can handle cyclic dependencies, I think, but all the packages part 
of the cycle have to be built at the same time on pkg-build (within the 20 
minutes time frame). In order to avoid timeouts in the future, and in order to 
avoid having this messy cyclic dependency, I chose to split out the 
documentation.

In both cases, I'd rather avoid doing so. If there was a way to increase the 
timeout on pkg-build, and if there was a way to refer to a module with 
@racketmodname[] only if it is installed (a "weak" documentation reference, if 
you will), then I would not have needed to split these two packages (a painful 
operation which I really would have preferred to avoid). The first point 
(timeout) has been discussed several times, so I remain hopeful that at some 
point in the future the timeout becomes configurable. The second point seems 
more like an edge case, and I'm not sure it is actually a good idea, and I'm 
not sure scribble has the right primitives to do this (knowing that if a 
weakly-referred-to module name or defproc is installed, the documentation for 
the referring package needs to be rebuilt).

Simply grouping together the packages in the catalog seems like a good idea to 
me, as there will always be some reasons to need to do this.

Cheers,
-- 
Georges Dupéron

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Confused about syntax properties

2017-02-03 Thread Dupéron Georges
Le vendredi 3 février 2017 11:28:47 UTC+1, Laurent Orseau a écrit :
> I see. So basically all #% things are extension points?
> The list for the racket language:
> 
> http://docs.racket-lang.org/search/index.html?q=%23%25%20L%3Aracket 

I think #% just means "low-level".
* #%declare,  #%expression, #%require, #%provide and #%variable-reference are 
built-in forms with special meanings, and it does not really make sense to 
override them.
* #lang racket/base overrides #%app, and re-provides the original as 
#%plain-app, so it is just an alias for the #%app from the '#%kernel. The same 
goes for #%plain-lambda.
* #%app, #%datum, #%module-begin, #%top and #%top-interaction are extension 
points (for function calls, self-quoting data, handling the body of the entire 
module, unbound variables and REPL interactions, respectively)
* I'm not 100% sure if #%stratified-body, #%plain-module-begin and 
#%printing-module-begin can be overridden in a useful way or not.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Confused about syntax properties

2017-02-03 Thread Dupéron Georges
Le vendredi 3 février 2017 10:56:10 UTC+1, Laurent Orseau a écrit :
> Btw, with "Macro Hiding: Disabled" we can see that after foo is turned into 
> #'1 (printed '1' in the macro stepper), then the 1 is 'tagged' with (#%datum 
> . 1) and then right after that turned into (quote 1). Is the tagging step 
> necessary for numbers?

Yes, self-quoting values like numbers, vectors, booleans, strings etc. are 
wrapped with (#%datum).

This is an extension point which allows languages to decide what to do with 
such values. For example, a language could disallow the use of some kinds of 
data, by making #%datum throw an error. This could also be used to treat the 
contents of vectors as expressions, so that (let ([x 1]) #(x x x)) produces #(1 
1 1).

Similar extension points are #%top, which is wrapped around unbound variables, 
and #%app, which is prepended to all function calls.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Confused about syntax properties

2017-02-02 Thread Dupéron Georges
PS: a nice example to try in the macro stepper, to see the evaluation order:

#lang racket
(define-syntax (foo stx) #'1)
(define-syntax (bar stx) #'foo)

(let ()
  bar
  (let ()
bar
(let ()
  bar
  bar)
(#%expression bar)
bar)
  (+ bar bar)
  bar)

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Confused about syntax properties

2017-02-02 Thread Dupéron Georges
Le lundi 30 janvier 2017 06:25:29 UTC+1, Matias Eyzaguirre a écrit :
> Nice, thanks! I wasn’t aware of that. so macros are expanded in the order 
> that the reader reads them, not in so called evaluation order.

>From experience, the order is outside-in, each form after the preceding one 
>(except when a macro produces a begin form, in which case the contents of the 
>begin are spliced, and handled one by one). The contents of let-values forms 
>are initially skipped, and expanded after every form in the outer let has been 
>expanded enough to determine that it is not a definition. This means that 
>within the body of a let (or of a module, I think), forms are expanded until 
>the first element is not a macro anymore (e.g. a function application with 
>#%app, an expression with #%expression, or a datum), as any remaining macro 
>could potentially expand to a definition.

Add to that a few exceptions, like things lifted with 
syntax-local-lift-expression or syntax-local-lift-module-end-declaration, and 
explicit expansion with local-expand.

I wonder if there's a definitive reference in the docs about this? I'd enjoy 
reading about how the built-in forms behave, and what mechanisms may influence 
the order of expansion (#%expression, local-expand, maybe some others?).

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Package layout in docs

2017-01-30 Thread Dupéron Georges
Le lundi 30 janvier 2017 22:13:57 UTC+1, Matthew Butterick a écrit :
> Recently we added a Racket logo to the upper right of the public doc pages. 
> We could do something where this logo changed depending on whether the 
> package belonged to core or community or whatever. Then we wouldn't need to 
> actually cleave the docs into two websites (which IMO is counterproductive). 

I agree with Matthew Butterick that splitting the docs into two websites would 
be counterproductive. As a user, I don't want to have to remember whether this 
package happens to be in main-distribution or not, and look up one website or 
the other. The same applies when searching for a functionality: I would rather 
avoid having to search on two different websites.

The logo idea seems like a nice compromise.

Another possibility would be to change the packages so that they display 
somewhere below the title "Part of the community package foo", "Part of the 
main Racket distribution" or "Part of the minimal Racket distribution". As far 
as I can tell, this would require cooperation from the packages (modifying the 
scribble files), unless Scribble forcefully inserts the text (like the "v.6.8" 
above the title).

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: Dynamic-require a compile-time identifier?

2017-01-21 Thread Dupéron Georges
I was going to suggest `dynamic-require-for-syntax`, but it seems to do exactly 
the same thing as `dynamic-require`, i.e. give the value of a phase-0 provided 
identifier. Is this normal?

The `eval` trick is a good idea, I would say. From the couple of times I have 
used dynamic-require, I have felt that it was pretty limited concerning 
shifting phases.

The thing I found to be the most difficult is to extract the phase 1 value 
bound to a macro via define-syntax. Following your `eval` idea, I managed to do 
that using 3D syntax. I suppose it's safe, as the 3D syntax object is created 
on the fly during `eval` and promptly discarded, therefore it should never need 
to be marshalled into a compiled file.

(eval #'(begin
   (module m racket/base
 (require (for-syntax racket/base) "x.rkt")
 (provide (for-syntax x-val))
 (define-syntax (get-val stx)
   (syntax-case stx ()
 [(_ name)
  #`(define-for-syntax name #,(syntax-local-value #'x))]))
 (get-val x-val))
   (require (for-meta -1 'm))
   x-val))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] How to watch the filesystem

2017-01-20 Thread Dupéron Georges
Le vendredi 20 janvier 2017 19:47:11 UTC+1, David K. Storrs a écrit :
> I see that I can get the event telling me that something changed.  As
> far as I can tell the event contains no information about *what*
> changed, it simply alerts that *something* changed.  Likewise, the
> monitor is only for the directory that I point it at, not for the
> subdirectories.

There *should* be a way to know what changed, at least in Linux as inotify 
allows this IIRC. Someone already wrote an FFI wrapper for inotify, hopefully 
it suits your needs (if it does, it would be cool to send a Pull Request to 
turn the repo in a Racket package, so that it can be put on 
pkgn.racket-lang.org):

https://github.com/samdphillips/racket-inotify

As for monitoring subdirectories, unfortunately (and surprisingly) this is not 
possible with inotify on Linux. From the man page:

Inotify monitoring of directories is not recursive: to monitor
subdirectories under a directory, additional watches must be created.

Fortunately, this should be easy enough to do in Racket, thanks to the 
wonderful in-directory:

(define (watch-recursively d)
(for ([subnode (in-sequences (in-value d) (in-directory d))])
  (when (directory-exists? subnode) ;; filter out files
(watch-the-directory subnode)))

This might take a while (and use up some resources) when watching a large 
directory :-( .

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: parameterize during compile

2017-01-20 Thread Dupéron Georges
Hi Dan,

Try with this:

main.rkt:

#lang racket
(require racket/stxparam "macro.rkt" "param.rkt")
(syntax-parameterize ([dirs 123])
  (mymacro))

macro.rkt:

#lang racket
(require racket/stxparam "param.rkt")
(provide mymacro)
(define-syntax (mymacro stx)
  #`(printf "dirs was ~a\n" #,(syntax-parameter-value #'dirs)))

param.rkt:

#lang racket
(require racket/stxparam)
(provide dirs)
(define-syntax-parameter dirs #f)


If you want the parameter's value to be effective during the require itself, 
like this:

(splicing-syntax-parameterize ([dirs 123])
  (require "myfile.rkt"))

then I do not know of an easy solution. You can set a compile-time variable to 
a mutable box, and set! that box, but it has some shortcomings:
1) when the file reading from the box is first compiled, the box has its 
default value
2) changes to the value are no longer scoped (every set-box! overwrites the 
value, so transitive requires might not see the value you expected if there are 
several calls to set-box!).

Here's the code for that:

main.rkt

#lang racket
(require racket/stxparam
 racket/splicing
 "param.rkt")

(begin-for-syntax
  (set-box! dirs 123))
(require "myfile.rkt")

myfile.rkt:

#lang racket
(require racket/stxparam
 "w3.rkt")
(begin-for-syntax
  (printf "dirs is ~a\n" dirs))


param.rkt:

#lang racket
(require racket/stxparam)
(provide (for-syntax dirs))
(define-for-syntax dirs (box #f))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] hello, where can I find the distribution 6.7.0.3.

2017-01-04 Thread Dupéron Georges
I don't think the old "minor" versions are kept, only the last few as Stephen 
pointed out.

As can be checked in the git log for 
https://github.com/racket/racket/blame/master/pkgs/base/info.rkt, the version 
number was bumped away from 6.7.0.3 in commit d7b18e7, so you could try 
checking out the previous commit (5e94a90) and compiling that. Racket isn't 
very difficult to compile under Linux, never tried on Windows, so good luck :) !

PS: Don't forget to report that new bug if you haven't already, sometimes they 
are fixed within hours.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] [ANN] Tools for debugging scope problems (for unhygienic macros)

2017-01-03 Thread Dupéron Georges
Hi all!



TL;DR: if you're struggling when debugging scopes, I wrote a couple of 
utilities to help: (+scopes stx) shows the scopes in a readable manner, 
(print-full-scopes) gives a summary of these scopes, and (make-named-scope 
string-or-symbol) creates a fresh scope annotated with a name, to track it more 
easily in the macro stepper or in (print-full-scopes). Docs here:

http://docs.racket-lang.org/debug-scopes/



When developing unhygienic macros, it frequently occurs that an extra, unwanted 
scope is present on one part of the output: In the macro's result, one might 
expect two identifiers to bind one another, but they won't because of that 
extra scope.

The reasons for this occurring are rare, but varied:
* Using a macro which forgets to remove the use-site scope (with 
syntax-local-identifier-as-binding) from an identifier which ends up in a 
binding position. Most of the time this is not a problem, but in a few corner 
cases this can be a problem.
* Template metafunctions (from syntax/parse/experimental/template) flip their 
own mark on the output, but don't provide a way to cancel that mark (i.e. they 
are forcefully hygienic in a way).
* Voluntarily applying a (make-syntax-introducer) in one place, and mistakenly 
forgetting to apply it in the other
* And so on.

While the fix for these problem is often trivial (flip the right scope in the 
right place), finding the source of the error can be a difficult endeavour.

A few things could be changed to help debugging:
* The snip% that shows up when a syntax object is display-ed shows a wealth of 
information about the syntax object and its subparts, but not the scopes 
present on them.
* The macro-debugger/syntax-browser does show this information, but can only be 
called from phase 0 (rendering difficult attempts to inspect syntax objects in 
the middle of the execution of a transformer function)
* The macro stepper is a bit cumbersome to use for this purpose: you have to 
click on the two identifiers one after another, and compare the (potentially 
long) list of scopes. Also, it rarely crashes, but according to Murphy's law 
will only do so when you're debugging the hardest issue ;-)
* The scopes as printed by syntax-debug-info and the macro debugger are 6-digit 
numbers which are difficult to compare at a glance
* These numbers say nothing about which macro introduced which scope — names 
would be a bliss, but alas (make-syntax-introducer) does not accept an optional 
name argument, and the auto-generated macro and use-site scopes are not 
annotated with the macro's name.

I wrote a small package, https://pkgd.racket-lang.org/pkgn/package/debug-scopes 
, which helps with the last two issues:

* The (+scopes stx) function returns a string, where each identifier is adorned 
with the scopes it has, using a succinct notation for ranges of scopes, which 
is practical for comparing the sets of scopes on two identifiers at a glance 
(see the docs for more details).
* The (print-full-scopes) function prints a table making the correspondance 
between that succinct notation and the traditional syntax-debug-info notation
* The (make-named-scope string-or-symbol) function creates a fresh scope like 
(make-syntax-introducer), but annotates it with a name. It is based on a hack: 
it creates a module with that name on the fly, extracts the module scope, and 
discards the module. This works because module scopes are annotated with their 
name in the macro debugger, unlike other kinds of scopes. This hack is likely 
slow, but if someday (make-syntax-introducer) supports an optional name, we'll 
rely on that instead.
* As an experimental feature, (require debug-scopes/named-scopes/override) 
overrides define-syntax and syntax-local-introduce, so that the implicit macro 
scope bears the name of the macro (it does not affect the use-site scope, as 
that one is handled specially by definition contexts). This feature might 
behave badly with other for-syntax functions which use the non-overridden 
version of syntax-local-introduce, so use with care.

I hope this can help others while debugging scope-related issues, which I found 
to be the most difficult aspect of unhygienic macro development.

Happy new year!
Georges Dupéron

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: Fix Ctr+F search on the new website?

2016-12-29 Thread Dupéron Georges
Good catch!

I looked this up a bit, unfortunately it seems that there is no reliable way to 
detect when the browser's search feature is started, let alone know where the 
results are and which one is currently highlighted.

None of the options available is entirely satisfactory:
* Use JavaScript to detect when Ctrl+F, "/" and similar search keys are 
pressed, shortly followed by a loss of focus as described in [1]. When this 
happens, force all the boxes to be visible. As said in [1], this won't work 
when the search function is invoked via the menu, or with non-standard search 
keys
* Use display:none instead of or in addition to opacity:0. This will make the 
text non-searchable, which kinda solves the "invisible text found" issue, but 
is not really what we want. It would also most likely prevent the text from 
being read by screen readers, which is bad on the accessibility side.
* Change the design to always show the text, at least with a 30% opacity or 
something (like is done for the source code boxes).
* Use the CSS below to make the text's color a transparent one, instead of 
having the whole box transparent. It seems that both Chromium and Firefox 
highlight text with the color rgba(0,0,0,0), see the attached screenshots. It 
doesn't show up the whole text where the match was found, but at least it's 
very clear where one should put the mouse to see the full text, instead of 
playing whack-a-mole

.feature > .inner a {
color:rgba(0,0,0,0);
transition: color 0.3s ease, background 0.3s ease;
}

.feature > .inner {
opacity: 1; /* was 0 */
color:rgba(0,0,0,0);
background:rgba(255,255,255,0);
transition: color 0.3s ease, background 0.3s ease;
}

.feature:hover > .inner a {
color:rgb(6, 121, 167);
transition: color 0.3s ease;
}

.feature:hover > .inner {
color:black;
background:rgba(255,255,255,1);
transition: color 0.3s ease, background 0.3s ease;
}

It might however be unwise to rely on that behaviour. An alternative would be 
to use opaque white text (and transition it to opaque black on hover), and in 
the non-hovered state put the image *on top* of the white text (so that the 
text doesn't leave white artefacts on the picture), using an empty :after 
pseudo-element or a :before + a z-index. Aligning the :before or :after element 
properly turns out to be a pain, though (especially since the title line does 
need the image as a "real" background, and only the "main" part of the box need 
the image atop the white text when unhovered, but below the text when hovered).


[1] http://stackoverflow.com/a/6680403/324969

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: New website design feedback

2016-12-27 Thread Dupéron Georges
One small point: I think it was good in the old site to have a link to the 
documentation right at the top, where now there are just "Packages" and 
"Download". We have great documentation (with a great design, thanks to 
Matthew!), better put it forward :)

> 2. Greyed out code snippets - I am not a fan of too much greyed out text or 
> code. It causes unnecessary eye strain. If this has to stay maybe make it not 
> AS GREY as it is right now.

I second that, and the drawings for the first 6 boxes could probably be darker 
too, I find them a bit hard on the eye. Also, I didn't notice the [click for 
more] text at first, maybe make it stand out a bit more?

Finally, is the new design accessible? I think the opacity:0 should still allow 
screen readers to process the hidden text without "hovering", but I'm not 100% 
sure.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] mirror.racket-lang.org seems down, and, 301 or 302?

2016-12-27 Thread Dupéron Georges
Greg, maybe you could push a commit to travis-racket, changing the URL to the 
currently-working one, and revert that after the maintenance?

That way the repos which fetch travis-racket on the fly would still build while 
mirror.racket-lang.org is down.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: Issue with the catalog (package removed and re-added does not appear)

2016-12-18 Thread Dupéron Georges
Actually, it seems I simply can't add any new package (neither 
pkgn.racket-lang.org nor from pkgs.racket-lang.org).

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Issue with the catalog (package removed and re-added does not appear)

2016-12-16 Thread Dupéron Georges
Hi all!

I tried adding a "version exception" earlier, which partially failed (rendering 
that package unusable on version in question, with the error "cannot use empty 
checksum for Git repostory package source").

As a last ressort, I tried removing the package and re-adding it, but now 
although it's listed on pkgn.racket-lang.org, it is missing from the catalog 
and doesn't seem to get re-added :-(

I tried re-adding the package both from pkgd.racket-lang.org and 
pkgs.racket-lang.org without success.

Can someone help me sort this out?

Thanks! 

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] syntax-property lost across module boundary (WAS: format-id doesn't preserve preserved?-edness of syntax-property?)

2016-12-15 Thread Dupéron Georges
Le jeudi 15 décembre 2016 00:48:13 UTC+1, Alexis King a écrit :
> without much issue, modulo an issue I asked about on this mailing
> list a month or two back

Here's (what I suspect is) the thread Alexis mentions, for those who feel 
curious: https://groups.google.com/forum/#!topic/racket-users/TGax2h8dVxs 
(Identifier equality of identifiers stashed in preserved syntax properties).

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Extracting the body of a fully-expanded module (with submodules)

2016-12-15 Thread Dupéron Georges
Thanks Matthew!

Your solution seems to work fine, the trampoline idea is a very neat trick. I 
like how it's safe to use require and begin because the continue macro returns 
fully-expanded syntax which won't be affected by the code injected around (for 
some reason I thought it was necessary to only inject fully-expanded forms like 
#%require, but that assumption was wrong).

I'd like to read more about the shifting of "relative" module references, is 
there anything in the docs about it (I vaguely remember seeing something, but 
couldn't find it again)?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Extracting the body of a fully-expanded module (with submodules)

2016-12-14 Thread Dupéron Georges
Hello!

This is a follow-up to the excellent answer by Alex Knauth on StackOverflow 
here: http://stackoverflow.com/a/38032107/324969 and this mailing-list thread: 
https://groups.google.com/forum/#!topic/racket-users/sS-pUUGp9o4

I'm trying to write a module meta-language mylang, which accepts a second 
language to which is passes the modified body, such that:

(module foo mylang typed/racket body)

is equivalent to:

(module foo typed/racket transformed-body)

The real-world goal is to transform the fully-expanded body (e.g. add a 
submodule, like the "doc" module added by scribble/lp2).

Alex came up with the implementation below. It puts the body into a dummy 
module, fully expands it, and extracts the (#%plain-module-begin . mod-body), 
patching it to require the user-provided lang. This works very well in all 
cases except when the body contains submodules.

In that case, I get an "require: namespace mismatch; reference to a module that 
is not available" error.

I'm rather clueless about how to solve that problem. I tried using local-expand 
with a 'module-begin context, but it then complains that x is unbound when the 
user-supplied language is typed/racket, and the error seems to be related to 
the submodules generated by TR.

Any suggestions?
Georges Dupéron




#lang racket

;; The language definition
(module mylang racket
  (provide (rename-out [-#%module-begin #%module-begin]))
  (define-syntax (-#%module-begin stx)
(syntax-case stx ()
  [(_ lng . rest)
   (with-syntax ([#%module-begin (datum->syntax #f '#%module-begin)])
 ;; put the code in a module form, and fully expand that module
 (define mod-stx
   (local-expand
#'(module ignored lng (#%module-begin . rest))
'top-level
(list)))
 ;; pattern-match on the #%plain-module-begin form to insert a require
 (syntax-case mod-stx (module #%plain-module-begin)
   [(module _ lng (#%plain-module-begin . mod-body))
#`(#%plain-module-begin
(#%require lng)
.
#,((make-syntax-introducer) #'mod-body))]))])))

;; A module using that language
(module foo (submod ".." mylang) typed/racket/base
  (module a-submod typed/racket/base
(define x 1)
(provide x))
  (require 'a-submod)
  (ann (+ x 1) Number))
(require 'foo)

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Re: Language-provided bindings and arrows in DrRacket

2016-12-04 Thread Dupéron Georges
I think I found a solution which allows me to inject the (#%require lng) 
without causing conflicts with other required module: applying an extra scope 
to the whole body makes the other (require) forms more specific, and they can 
shadow bindings imported by (#%require lng).

Here is the modified "MyLang.rkt":

#lang racket
(provide (rename-out [my-module-begin #%module-begin]))
(define-syntax (my-module-begin stx)
  (syntax-case stx ()
[(_ real-lang body)
 (syntax-case (local-expand #'(module m real-lang body) 'top-level (list)) 
()
   [(module nm lng (#%plain-module-begin . body2))
#`(#%plain-module-begin
 (#%require lng)
 . #,((make-syntax-introducer) #'body2))])]))

And here's an example file using it:

(module m "MyLang.rkt"
  ;; delegates to this language:
  typed/racket/base
  ;; body:
  (begin
(require racket/set)
(displayln ;; arrow successfully drawn to typed/racket/base
 (set  ;; arrow successfully drawn to racket/set
  "Hello"

Without the extra scope, I would get this error because racket/set shadows 
these bindings imported by typed/racket/base:

module: identifier already imported from a different source in:
  for/set
  racket/set
  typed/racket/base

My problem seems solved, but if this extra-scope trick has some unwanted 
consequences, I would definitely want to hear about them!

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Re: Language-provided bindings and arrows in DrRacket

2016-12-04 Thread Dupéron Georges
Le dimanche 4 décembre 2016 04:18:44 UTC+1, Robby Findler a écrit :
> The fully expanded form of the original program doesn't have a require
> that brings in displayln?

Indeed, if I use (#%require lng) the arrows get drawn.

However, the body can require libraries which shadow some of the 
language-provided bindings, e.g. (require type-expander) shadows some of the 
bindings imported by #lang typed/racket. I therefore use (#%require (only lng)) 
to make sure the lng module is available, without creating potential conflicts 
with other required modules.

I was hoping there would be some trick similar to disappeared-use and 
disappeared-bindings that would help me solve this problem. I suppose I could 
apply a 'disappeared-binding property to the "racket/base" on the second line, 
using a list containing every binding imported by the "module language".

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: Language-provided bindings and arrows in DrRacket

2016-12-03 Thread Dupéron Georges
I made a copy-paste mistake, the replacement for the last line of "MyLang.rkt" 
should use "body2" instead of "body":

#'(#%plain-module-begin (module nm lng (#%plain-module-begin . body2)))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Language-provided bindings and arrows in DrRacket

2016-12-03 Thread Dupéron Georges
I'm writing a meta-language (a small extension of scribble/lp2), which 
delegates to a second language. I am using the neat trick suggested to me by 
Alex Knauth [1], but I have trouble getting the arrows to be drawn in DrRacket 
for language "built-ins".

A boiled down version of the language file "MyLang.rkt" follows:

#lang racket
(provide (rename-out [my-module-begin #%module-begin]))
(define-syntax (my-module-begin stx)
  (syntax-case stx ()
[(_ real-lang body)
 (syntax-case (local-expand #'(module m real-lang body) 'top-level (list)) 
()
   [(module nm lng (#%plain-module-begin . body2))
#'(#%plain-module-begin
;; use (only lng) to avoid conflicts with other require
(#%require (only lng))
. body2)])]))

It is used by "m.rkt":

(module m "MyLang.rkt" ;; MyLang acts as a meta-language
  racket/base  ;; which delegates to this language
  (displayln "Hello")) ;; using this body

The problem I have is that "displayln" is highlighted with a blue-green 
background in DrRacket, indicating that it is provided by the module's 
language, but there is no arrow drawn from the "racket/base" just above.

If I change the last line of "MyLang.rkt" to put the fully-expanded module as a 
submodule (instead of merely extracting the contents of the 
#%plain-module-begin), then the arrow gets drawn:

#'(#%plain-module-begin (module nm lng (#%plain-module-begin . body)))

What conditions must be met for the arrow to be drawn?

[1] http://stackoverflow.com/a/38032107/324969

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: Reducing Program Startup Time

2016-12-03 Thread Dupéron Georges
A few ideas:

1) Loading a lot of modules can be slow. You are already avoiding that by using 
racket/base and racket/gui/base, so that's good, but it already takes me 0.5s 
just to require these :-( . I don't know it there is much to do about this.
2) Your main.rkt might be doing a some lengthy initialisation work. Try 
inserting a displayln right at the beginning, to see if there is a long delay 
between that and the moment when the window pops up.
3) Of course use raco make or raco exe (from your README I gather that's 
already the case).

Try also comparing with the start-up time of the simplest GUI application you 
can think of, e.g.

#lang racket/base
(require racket/gui/base racket/class)
(define f (new frame% [label ""] [width 100] [height 100]))
(send f show #t)

Hopefully someone else with more knowledge about racket/gui and/or optimisation 
will give better recommendations.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] degenerate performance in syntax-parse

2016-10-26 Thread Dupéron Georges
> The only issue is converting our mountain of code that uses the old syntax 
> (more than 40,000 lines, if you can believe it).

I would suggest keeping the old syntax too via {~or #:blend {~and blend-stx 
blend}}, but making it log a warning when (attribute blend-stx) is true, 
printing (syntax-source blend-stx) and (syntax-line blend-stx) and 
(syntax-column blend-stx).

That will make it way easier to convert your old source. With a good backup and 
a daring mood, you could even feed that to sed to make the change automatically 
:) .

There was a talk by Jack Firth at racket-con about the idea of integrating 
warnings to macros, and automatically suggesting or applying fixes. This seems 
to be a good use-case for the idea.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: Redex: macro expanding to a side-condition clause

2016-10-26 Thread Dupéron Georges
Be aware that `expand-all-judgment-form-expanders` does what it says on the 
tin: if the `(define-judgment-form …)` contains something that should in 
principle shadow the expander, e.g. something equivalent to `(let ([where/not 
(λ (x) 42)]) (where/not 'blah))`, then the `expand-all-judgment-form-expanders` 
will still blindly expand the inner `where`.

In other words, it does a substitution on the whole syntax tree, and does not 
recognise any sort of binding form in any special way.

A better implementation of the "new" `define-judgment-form` I wrote in my 
previous e-mail would selectively expand judgment form expanders in the 
appropriate places, and detect shadowing instead of uniformly substituting all 
occurrences within the whole syntax tree.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: Redex: macro expanding to a side-condition clause

2016-10-25 Thread Dupéron Georges
Sam, would something like this work for you?

I'm using the generic-syntax-expanders library to easily define expanders 
(sorts of macros) which are expanded within uses of a wrapper of 
define-judgment-form.



#lang racket

(require (rename-in redex
[define-judgment-form orig:define-judgment-form])
 generic-syntax-expanders)

(define-language L
  (E number (+ E E)))

(define-expander-type judgment-form)
(define-syntax (define-judgment-form stx)
  (syntax-case (expand-all-judgment-form-expanders stx) ()
[(self . rest)
 (with-syntax ([new-self (datum->syntax #'here
'orig:define-judgment-form
#'self
#'self)])
   (datum->syntax #'here
  `(,#'new-self . ,#'rest)
  stx
  stx))]))

(define-judgment-form-expander where/not
  (λ (stx)
(syntax-case stx ()
  [(_ pat tm)
   #'(side-condition ,(not (redex-match? L pat (term tm])))

(define-judgment-form L
  #:mode (j I)
  [(where/not number E)
   -
   (j E)])

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: Planet package murphy/protobuf for Protocol Buffers

2016-10-14 Thread Dupéron Georges
Maybe it's in /Users/dstorrs/Library/Racket/bin, or something like this?

otherwise, this command shoul hopefully show the file's path if it is on your 
system:

find / -name protoc-gen-racket

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: FUSE filesystem package

2016-10-12 Thread Dupéron Georges
This is great! Thumbs up, and thanks for writing this library. I have a couple 
of filesystems in my "TODO" list, hopefully this package will motivate me to 
actually write them one of these days :) .

A nice feature would be some simpler API for creating filesystems which work by 
virtually moving or changing the attributes of (or concatenating + splitting, 
or otherwise transforming) files stored in an existing directory. This is a 
common use case in FUSE, I believe.

PS: is the documentation for use-once/c somewhere?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: Properly annotating disappeared uses/bindings for substituted identifiers

2016-10-12 Thread Dupéron Georges
My experience with check-syntax is that several conditions have to be met:

* The identifiers must have the correct source locations (actually, you can 
make arrows point to weird places by faking the source locations)
* The properties must be present high enough in the AST. For example, if you 
put a 'sub-range-binders property on the "name" in "(define name value)", it 
won't work, instead the property should be present on the "(define name value)" 
syntax object itself, not on one of its subparts
* The planets must align.

At a first glance, I think in your case the problem is with the second 
condition, so you should "lift" all those properties out onto the topmost 
syntax object (they probably can be present at a lower point, but why bother?).

There's a with-disappeared-uses + record-disappeared-uses utility [1], and I 
wrote my own with-sub-range-binders + record-sub-range-binders! [2]. I also 
threw in a with-arrows form which combine both with-xxx forms.

Unfortunately, there is nothing for disappeared-bindings (yet). You can 
copy-paste and adjust my sub-range-binders code [3] and adjust it (permission 
granted to use whatever licence your project uses).

Georges

[1] 
http://docs.racket-lang.org/reference/syntax-util.html#%28form._%28%28lib._racket%2Fsyntax..rkt%29._with-disappeared-uses%29%29

[2] 
http://docs.racket-lang.org/phc-toolkit/phc-toolkit-format-id-record.html#%28form._%28%28lib._phc-toolkit%2Funtyped-only%2Fformat-id-record..rkt%29._with-sub-range-binders%29%29

[3] 
https://github.com/jsmaniac/phc-toolkit/blob/master/untyped-only/format-id-record.rkt

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Scribble: how to use #:tag-prefix and have @elemref work within the Table Of Contents?

2016-10-02 Thread Dupéron Georges
Thanks a lot for the fixes, Matthew!

The workaround was not too much of a problem to set up in the end (the elemref 
were generated by a macro in my case, so I just had to use make-link-element + 
the global variable instead of elemref). I'll probably get rid of it once a new 
version with your fixes ships out.

For what it's worth, I sometimes find it difficult to guess what the complete 
tag with prefixes should be, e.g. in the example above I expected the tag to be

`(elem (prefixable (lib "test-tag-prefix/scribblings/sub.scrbl")
   "foo"))

but the tag actually is:

`(elem (prefixable "(lib test-tag-prefix/scribblings/test-tag-prefix.scrbl)"
   "(lib test-tag-prefix/scribblings/sub.scrbl)"
   "foo"))

I found an awful hack to make scribble print the list of all tags for a package:
1) First install the package as a locally linked package (i.e. using "cd 
/path/to/the-pkg/; raco pkg install" with no arguments)
2) Uninstall the package, using "raco pkg remove the-pkg". This removes the 
package link, but does not clear Scribble's cache containing all the tags in 
all the documentation
3) Re-install the package from git instead of linking it from the local copy 
(make sure the git repo is up-to-date with the local copy), using "raco pkg 
install https://github.com/user/the-pkg.git;. When Scribble renders the 
documentation for this second copy of the package, it still has not cleaned the 
cache of tags, and therefore generates an error message for every single tag 
present in the package, complaining that it is a duplicate.
4) Scribble will continue to print the error messages each time a package is 
recompiled with "raco setup --pkgs some-package". To get rid of them, run: 
"raco setup; raco setup --avoid-main; raco setup --doc-index". If at some point 
all the links on the documentation's start page turn red, fear not (this 
happened to me) and run these three commands again a couple of times, they 
should fix it.

Hopefully I have overlooked some function in the documentation which prints all 
the tags within a package or document (an equivalent of module->exports for 
tags, if you will) and someone will point it out, but until then this hack may 
be useful to others :) .

Regards,
Georges

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: Scribble: how to use #:tag-prefix and have @elemref work within the Table Of Contents?

2016-09-30 Thread Dupéron Georges
Le vendredi 30 septembre 2016 14:30:05 UTC+2, Dupéron Georges a écrit :
> Is there a better way to automatically generate this tag?
> I can store the document tags within a global variable and cons them
> everywhere I'm inserting an @elemref in the Table Of Contents, but it
> seems a bit of a hack.

I meant "store the document tags within a global variable and prepend them", 
not "cons them", obviously.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Scribble: how to use #:tag-prefix and have @elemref work within the Table Of Contents?

2016-09-30 Thread Dupéron Georges
I have two simple scribble files. The first one simply includes the second:



#lang scribble/manual
@title{test-tag-prefix}
@include-section{sub.scrbl}



And the second one uses #:tag-prefix, and inserts an @elemref in the TOC:



#lang scribble/manual
@title[#:tag-prefix '(lib "test-tag-prefix/scribblings/sub.scrbl")]{sub}
@(require scribble/struct)
@(make-toc-element #f
   (list (elemtag '(prefixable "foo") "foo-tag"))
   (list (elemref '(prefixable "foo") "foo-ref-in-toc")))
@(elemref '(prefixable "foo") "foo-ref-in-part")



The @elemref within the document works fine, but the @elemref in the Table Of 
Contents is shown in red and is not a hyperlink, see the attached screenshot.

If I remove the #:tag-prefix, everything works fine. Also, the second file on 
its own works fine (but it ignores the #:tag-prefix). I tried creating the 
appropriate taglet:



(elemref '(prefixable "(lib test-tag-prefix/scribblings/test-tag-prefix.scrbl)"
  "(lib test-tag-prefix/scribblings/sub.scrbl)"
  "foo")
 "foo-ref-in-toc")



but elemref rejects it (I think the contract on elemref is wrong, it should 
accept a taglet, not a tag). Directly calling make-link-element worked, though:



(make-link-element
 #f
 (decode-content (list "foo-ref-in-toc"))
 `(elem (prefixable "(lib test-tag-prefix/scribblings/test-tag-prefix.scrbl)"
"(lib test-tag-prefix/scribblings/sub.scrbl)"
"foo")))



Is there a better way to automatically generate this tag? I can store the 
document tags within a global variable and cons them everywhere I'm inserting 
an @elemref in the Table Of Contents, but it seems a bit of a hack.

Thanks,
Georges

--

For experimentation, I uploaded a minimal package containing the two files at 
https://github.com/jsmaniac/test-tag-prefix/tree/master/scribblings and the 
package can be installed using:

raco pkg install https://github.com/jsmaniac/test-tag-prefix.git

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] udelim package -- more parens than you can shake a stick at

2016-09-25 Thread Dupéron Georges
If I understand you well, the intended use of your nested delimiters can be 
more or less described as syntactic sugar for #reader, with auto-detection of 
where the string ends:

(filter foo? 
(python-ish-list-comprehend 
 «thing for x in sqlish(«select * from foo») where some_pred(x)»))

could be rewritten as:

(filter foo? 
#reader"python-ish-list-comprehend.rkt" thing for x in 
#reader"sqlish.rkt" select * from foo where 
some_pred(x)

-- 
Georges

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: udelim package -- more parens than you can shake a stick at

2016-09-24 Thread Dupéron Georges
Le samedi 24 septembre 2016 18:46:07 UTC+2, William G Hatch a écrit :
> Udelim is a library for adding extra parens and string delimiters to
> your language.

I can't tell how ecstatic I am about this :) . I have been wanting to add new 
parenthesis shapes for a while, but never found the time to look seriously into 
it, so thank you a lot for writing this! I was thinking about using the white 
brackets ⟦⟧, braces ⦃⦄ and parentheses ⦅⦆ are commonly used for describing 
semantics, for example.

I also like the idea of nestable string delimiters, although I rarely have use 
for it.

One note about the docs: when you write:

(open-input-string
  "«this is a string with nested «string delimiters.»  No \n escape 
interpreting.»")

the "\n" is already escaped by the "…" fed into open-input-string I think, so 
what udelim parses in that example is a raw newline, not the \ character 
followed by the n character.

Scribble supports "element transformers" which allow to change how an 
identifier is printed. Unfortunately, when the identifier appears in the first 
position of a form (like the #% wrappers), only the identifier itself can get 
styled, not the whole form. I added a few days ago a quick hack to my unstable 
scribble-enhanced library to add catch-alls which can re-style any identifier 
matching a given pattern. The hack [1] should also work for whole forms 
(untested, though), so that in scribble or scribble/lp2, @racketblock[(a ⟦b⟧ 
c)] would be properly typeset.

Georges

[1] The hack in scribble-enhanced 
https://github.com/jsmaniac/scribble-enhanced/blob/master/racket.rkt#L1012
[2] Example using the hack to nicely typeset identifiers with numeric 
superscripts like String³, which means "three strings in a row" for the xlist 
type expander 
https://github.com/jsmaniac/xlist/blob/master/scribble-enhanced.rkt

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] equal? and recursive data structures

2016-09-13 Thread Dupéron Georges
Le mardi 13 septembre 2016 16:30:39 UTC+2, Robby Findler a écrit :
> http://www.cs.indiana.edu/~dyb/pubs/equal.pdf

Thanks a lot for the reference, I was looking for that.

If I understand well, equal? first tries a fast algorithm which does not take 
cycles into account, and after a certain level of recursion, it switches to a 
slower algorithm which checks for the presence of cycles (and it then 
alternates between these two algorithms, so long as there are no cycles).

I'm therefore guessing the default value for k₀ must be about 25 for Racket's 
implementation.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] equal? and recursive data structures

2016-09-13 Thread Dupéron Georges
I'm writing a prop:equal+hash for a recursive data structure, and I noticed 
that it takes several comparisons of pairs of values which are eq? before 
equal? realises that there is a cycle, and stops.

Below is the code for the trivial case, where the implementation of equality 
just calls itself on the same values.

#lang racket

(struct s ()
  #:property prop:equal+hash
  (list (λ (a b r) (display ".") (r a b))
(λ (a r) (display "!") (r a))
(λ (a r) (display "!") (r a

(equal? (s) (s)) ;; => prints 26 "."
(equal-hash-code (s)) ;; => prints 128 "!"
(equal-secondary-hash-code (s)) ;; => prints 128 "!"

Why doesn't it stop immediately after the first cycle?

Also, where do these magical numbers (26 and 128) come from? I grepped the C 
source, but couldn't find anything relevant. The numbers 26 and 128 seem to be 
independent of the equality function, so it does not sound like a change of 
behaviour once the stack overflows, for example.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Order of reduction rules in Redex

2016-09-06 Thread Dupéron Georges
Le mardi 6 septembre 2016 20:39:37 UTC+2, Sam Caldwell a écrit :
> I'm not sure what it is you want. Do you want the reduction relation to be 
> deterministic? If so then you need to decide which order is the "right" one.
> 
> You can do this by adding a "lifted-less expression" to your grammar

Thanks a lot, Sam, this works like a charm!

I wanted the relation order to be deterministic indeed, but I wasn't sure if it 
was the appropriate solution, or if this was an XY problem that needed a 
completely different approach.

Regards,
Georges Dupéron

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Order of reduction rules in Redex

2016-09-06 Thread Dupéron Georges
Hi all!

I'm trying out redex, and I defined a simple language with (define v e) 
statements. I also defined an extended language, which allows expressions to be 
(lifted v' e'). A (lifted v' e') expression is replaced by v', and a definition 
(define v' e') is lifted to the top-level, just before the current statement.

I tried to define a reduction from the simple+lifted language to the simple 
language. It makes the lifted definitions bubble up until they reach the 
top-level, and inserts them before their containing statement.

Unfortunately, my reduction is ambiguous: when reducing the program (define 
result (+ (lifted x 1) (lifted y 2))), both lifted definitions can bubble up 
first and be inserted before the other. Therefore, apply-reduction-relation* 
returns two valid results:

(begin (define x 1) (define y 2) (define result (+ x y)))
(begin (define y 2) (define x 1) (define result (+ x y)))

How can I avoid this problem?

See the attached file or http://pasterack.org/pastes/44574 for the full code.

Thanks!
Georges Dupéron

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


lifted-experiment.rkt
Description: Binary data


[racket-users] Re: DrRacket says #%module-begin not a module

2016-09-03 Thread Dupéron Georges
Le dimanche 4 septembre 2016 01:44:01 UTC+2, David K. Storrs a écrit :
> Welcome to DrRacket, version 6.6 [3m].
> Language: R5RS [custom]; memory limit: 128 MB.

It seems that DrRacket is configured to use the R5RS language. Using the 
bottom-left menu (or Ctrl+L), select "The Racket language Use #lang at the 
beginning of the program to specify the dialect to use…".

I can reproduce your error message if the R5RS language is used instead.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: How to adjust an expansion-time parameter in a dynamic-require?

2016-09-02 Thread Dupéron Georges
Le vendredi 2 septembre 2016 12:32:52 UTC+2, Jack Firth a écrit :
> However, (parameterize ([param tool-func]) (dynamic-require mod-path)) 
> doesn't seem to work because the parameter is being set for the runtime phase 
> rather than the expansion time phase.

Here's a solution, which also allows the mod-path to return a value, but it 
must do so at compile-time (I think the run-time is not even executed).

param.rkt:

#lang racket
(provide foo)
(define foo (make-parameter #f))



mod-path.rkt:

#lang racket
(require (for-meta 1 "param.rkt"))
(provide (for-syntax return-value))
(define-for-syntax return-value `("here's my report: " (foo is ,(foo
(provide (for-syntax varref))
(define-for-syntax varref (#%variable-reference))



tool.rkt:

#lang racket
(require (for-meta 1 "param.rkt"))
(define run-time-param-value (+ 40 2))
(define run-time-module-name (string-append "mod" "-path.rkt"))
(define result
  (eval #`(begin
(define-syntax (trampoline _stx)
  (parameterize ([foo #,run-time-param-value])
(define ns
  (eval '(begin
   (require (for-template #,run-time-module-name))
   (variable-reference->namespace varref
#`#,(namespace-variable-value 'varref #f #f ns)))
(define varref-0 (trampoline))
(define ns-0 (variable-reference->namespace varref-0))
(parameterize ([current-namespace ns-0])
  (namespace-variable-value 'return-value)
result





After our discussion on IRC:

> …
> @notjack: IIUC, your tool expands 'mod, and wants to access the syntax 
> properties of the expanded code?
>  yup, exactly
> …

it seems something like this would be more suited to your purposes:

mod-path.rkt:

#lang racket
(define-syntax (mod-stx stx)
  (syntax-property #'42
   'my-prop 123))
(mod-stx)



tool.rkt:

#lang racket
(define (traverse stx)
  (when (and (syntax? stx) (syntax-property stx 'my-prop))
(displayln (syntax-property stx 'my-prop)))
  (cond
[(syntax? stx) (traverse (syntax-e stx))]
[(list? stx) (map traverse stx)]
[(pair? stx) (traverse (car stx))
 (traverse (cdr stx))]
[(vector? stx) (traverse (vector->list stx))]
[(prefab-struct-key stx) (traverse (struct->vector stx))])
  (void))
 
(traverse
 (parameterize ([read-accept-lang #t]
[current-namespace (make-base-namespace)])
   (expand-syntax
(namespace-syntax-introduce
 (read-syntax "tool.rkt" (open-input-file "tool.rkt"))
;; => 123
;;123

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] [ANN] A type-expander library for Typed/Racket

2016-08-27 Thread Dupéron Georges
Le samedi 27 août 2016 03:54:00 UTC+2, Anthony Carrico a écrit :
> On 08/26/2016 11:10 AM, Matthias Felleisen wrote:
> Likewise. Can you say something for us lurkers about the use cases? Do
> you think it is workable to have an identifier act as a type expander,
> match expander, normal macro and identifier macro?

Think about a struct defined using `(struct s ([field : type] …))`. The 
identifier `s` has a special meaning when used as a type or a match pattern, 
can be called as a function, or used as an identifier whose value is a 
function, e.g. in `(map s '(vals …) '(more-vals …))`.

I'm currently developing an Algebraic Data Types library [1] similar to the one 
by Andrew Kent [2], but with the following features:

* Structure types work like prefab structs, but with field names: two structure 
types in two different files are identical if they have the same field names 
and field types (without the need to declare them beforehand).

* Constructor tags work like symbols: two constructor types in two different 
files are identical if they have the same tag name and content type (without 
the need to declare them beforehand).

* The same constructor can belong to two distinct variant types, i.e. variants 
are just unions of constructors. In contrast, most implementations allow a 
constructor to be present in only a single variant.

With the multi-id library, I can define the `s1` structure as a type-expander, 
match-expander, macro and identifier macro, so that the code at [2] works. I 
included the whole file at the end of this message.

It is similarly possible to define a constructor `c` as a type-expander, 
match-expander, macro and identifier macro, so that you can write:

(match (ann (c 1 2 3) (c Number Number Number))
  [(c x y z) (+ x y z)])

Note that the phc-adt package isn't quite ready yet, it should be reasonably 
stable in a week or so.

[1] : https://github.com/jsmaniac/phc-adt.git
[2] : https://github.com/andmkent/datatype.git
[3] : 
https://github.com/jsmaniac/phc-adt/blob/master/test/mailing-list-example/example.rkt






#lang typed/racket
;; phc-adt sets registers some information in its support files when it
;; encounters new structure types, so this file has to be compiled twice
;; in DrRacket (not on the command-line). The first compilation will fail,
;; it is normal and expected (but it should soon give a better error message)
(require type-expander multi-id phc-adt typed/rackunit)
(adt-init)

;; This internally does
;; (define-multi-id s1
;;   #:type-expander  (λ (stx) …)
;;   #:match-expander (λ (stx) …)
;;   #:call   (λ (stx) …)
;;   #:id (λ (stx) …))
(define-structure s1 [a : Number] [b : String])

;; The "structure" identifier is also a multi-id, for on-the-fly usage of a
;; structure as a type, match pattern, constructor function or instance creation

(: foo (→ (U
   ;; type-expander: s1
   s1
   ;; type-expander: (structure [field : type] …)
   (structure [a : Number] [c : Symbol]))
  Number))
(define (foo s)
  (match s
;; match-expander: (s1 pat ...)
[(s1 (? number? the-a) the-b) (+ the-a (string-length the-b))]
;; match-expander: (structure field-name …)
[(structure a c) (+ a (string-length (symbol->string c)))]))

(define instances
  (append
   ;; identifier macro: s1, to pretend it's a function
   (map s1
(range 5)
'("x" "xx" "xxx" "" "x"))
   ;; macro: (s1 args …), to pretend it's a function call
   (list (s1 42 "Why does six times nine equal forty two?"))
   ;; macro: (structure [field : type] …), produces a bulder function
   (map (structure [a : Number] [c : Symbol])
(reverse (range 5))
'(x xx xxx  x))
   ;; macro: (structure [field value] …) or (structure [field : type value]),
   ;; produces an instance
   (list (structure [a pi] [c 'three-fourteen]

(check-equal? (map foo instances)
  (append '(1 3 5 7 9)
  '(82)
  '(5 5 5 5 5)
  '(17.141592653589793)))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] How would a library express indentation rules? [was: DrRacket's auto-indentation outside DrRacket?]

2016-08-25 Thread Dupéron Georges
I'm starting a new discussion topic, so as not to crowd
https://groups.google.com/forum/#!topic/racket-users/4SnwpX6gYqk .

2016-08-26 0:32 GMT+02:00 Alex Knauth :
> How would a library express indentation rules? Would indentation rules
meant for s-expression languages be useful in at-exp or sweet-exp notations?

Below are some ideas, but I'm definitely sure something better can be
achieved.
TL;DR: we could specify the indentation of each s-expression with respect
to another preceding s-expression (but not necessarily the one just
before), and indicating if it should be indented by 0, 2 or 4 spaces.



>From what I've seen, lisps and schemes have a few indentation styles for a
given line:

Indent a bit, with respect to the beginning of the enclosing s-expression:

(define ;; indent = 0
  a ;; indent += small
  1)

Indent a a lot (twice as much?), with respect to the beginning of the
enclosing s-expression.

(λ ;; indent = 0
(args) ;; indent += big
  body);; indent += small, with respect to line 1

Indent the as much as the first argument of the enclosing form.

(displayln datum
   output-port)

Indent as much as the first s-expression on the previous line (this is
basically just `begin` specifying a +small indentation for all of
sub-expressions):

(begin
  (define x 1) (define y 2) ;; indent = 2
  (displayln (+ x y)))  ;; indent += 0

Has anyone seen another kind of indentation? Reader extensions like #' and
dotted pairs may need some extra thought.

I think the cases above can be generalized to: “Indent this s-expression so
that it aligns with that other preceding s-expression (exactly | plus a
small indent of 2 spaces | plus a large indent of 4 spaces)“. It allows
some less common indentation styles:

The code
(some-macro #:kw #:kw-one-arg arg1 #:kw-trhee-args argA argB argC)
may specify the following indentation styles:
#:kw => +small, w.r.t some-macro
#:kw-one-arg => exactly, w.r.t #:kw
arg1 => +small, w.r.t #:kw-one-arg
#:kw-three-args => exactly, w.r.t #:kw (or w.r.t #:kw-one-arg)
argA => +small, w.r.t #:kw-three-args
argB => exactly, w.r.t argA
argC => exactly, w.r.t argA
which gives the following indentations, depending on where the newlines are:
(some-macro #:kw #:kw-one-arg arg1 #:kw-three-args argA argB argC)
(some-macro #:kw
#:kw-one-arg arg1
#:kw-three-args argA argB argC)
(some-macro #:kw
#:kw-one-arg
  arg1
#:kw-three-args
  argA argB
  argC)
(some-macro
  #:kw
  #:kw-one-arg
arg1
  #:kw-three-args argA argB
  argC)

Given a caml-style let-in macro, the code
(let (x . y) z = (values (cons 1 2) 3) t = 4 in body)
may specify the following indentation styles:
(x . y) => +big, w.r.t let
z => exactly, w.r.t (x . y)
= => exactly w.r.t (x . y)
t =>  exactly w.r.t (x . y)
=  => exactly w.r.t (x . y)
4 =>  exactly w.r.t (x . y)
in => exactly w.r.t let
body => +small w.r.t let
which gives the following indentations, depending on where the newlines are:
(let (x . y) z = (values (cons 1 2) 3) t = 4 in body)
(let
(x . y) z = (values (cons 1 2) 3)
t = 4
 in
   body)
(let
(x . y) z = (values (cons 1 2) 3)
t = 4 in
   body)
(let (x . y) z = (values (cons 1 2) 3)
 t = 4
 in body)
(let (x . y) z = (values (cons 1 2) 3) t = 4 in
  body)

I'm not used to sweet-exp, so I cannot say much about it, but the rules
above seem to translate naturally to at-exp in most cases, but not all:
@some-macro[#:kw #:kw-one-arg arg1 #:kw-three-args argA argB argC]
@some-macro[#:kw
#:kw-one-arg arg1
#:kw-three-args argA argB argC]
@some-macro[#:kw
#:kw-one-arg
  arg1
#:kw-three-args
  argA argB
  argC]
@some-macro[
  #:kw
  #:kw-one-arg
arg1
  #:kw-three-args argA argB
  argC]
bonus: if the [ appears first on its line, it uses the indentation of the
following token, and shifts everyting until ] by 1 space:
@some-macro
  [#:kw
   #:kw-one-arg
 arg1
   #:kw-three-args argA argB]
things are do not look so good when using {} for the last argument:
@some-macro
  [#:kw
   #:kw-one-arg
 arg1
   #:kw-three-args argA argB]{
   argC}

@let[(x . y) z = (values (cons 1 2) 3) t = 4 in body]
@let[
(x . y) z = (values (cons 1 2) 3)
t = 4
 in
   body]
This one looks a bit weird too (because the "[" bracket is opened on the
second line):
@let
[(x . y) z = (values (cons 1 2) 3)
 t = 4 in
   body]
Where should the closing brace "}" be positioned ?

Re: [racket-users] Re: DrRacket's auto-indentation outside DrRacket?

2016-08-25 Thread Dupéron Georges
Le vendredi 26 août 2016 00:02:13 UTC+2, Matthias Felleisen a écrit :
> The specification has to come with feature and/or the language, not the tool. 
> How would Emacs know about it? Or Notepad? Every editor — and every tool in 
> the tool chain — must know what indentation means if it may touch it. 

I agree, it is unfortunate that for a language's get-info to respond to the 
`'drracket:indentation` it has to manipulate racket:text<%> among other things.

This could however be achieved (without popping a GUI) by an emacs mode 
communicating with Racket. If macros were allowed to specify how they are 
indented, the editor would need to run some racket code at some point, anyway 
(to expand the macro). It is already necessary to run some racket code to parse 
the surface syntax of the file, and know what parts are strings, what parts are 
identifiers etc. (the same file with #lang scribble and #lang racket won't 
indent in the same way, obviously).

I'm not sure if using racket:text<%> is that much of a concern in the end, 
though: any editor plugin could spawn a racket process, create an instance of 
racket:text<%> and communicate with it to get the indentation of any line it 
wants. The overhead does not seem that high, and it does not require a 
full-blown gui (the GTK libraries might be needed, but not a suitable display).

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Re: DrRacket's auto-indentation outside DrRacket?

2016-08-25 Thread Dupéron Georges
Le jeudi 25 août 2016 23:47:21 UTC+2, Matthias Felleisen a écrit :
> If Travis re-indented my benchmarks/samples every time I commit one, I would 
> be rather unhappy. 

I think that's what David meant by "A way to represent indentation 
specifications for new syntactic forms": the idea would be to include in the 
repository a list of define-style, lambda-style, begin-style and for/fold-style 
keywords, so that the build knows how to indent project-specific and 
library-specific identifiers.

> I would like us to wait until languages can choose an indentation style per 
> construct. 

If I understood well, I think this can already be done with 
'drracket:indentation to override drracket's indentation function (and with a 
bit of luck, Robby's script already takes that into account).

I didn't know this had been used in practice, but surprisingly (for me) 
github's search for `drracket:indentation` turned up several repositories:
* https://github.com/mbutterick/beautiful-racket
* scribble seems to use it
* a few other random repos

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: DrRacket's auto-indentation outside DrRacket?

2016-08-25 Thread Dupéron Georges
I'll add a few relevant and less relevant references:

This discussion [1] is about extending drracket's built-in indenter, using 
`drracket:indentation` [2]. The #lang's get-info function should accept that 
symbol as a key, and return an indentation function.

To access the default indentation by drracket, it seems you could call 
`compute-racket-amount-to-indent` [3]. It accepts an optional argument 
`get-head-sexp-type` which should be a function mapping identifiers to one of 
#f 'lambda 'define 'begin 'for/fold 'other, where #f means that it will use the 
built-in list.

There was some discussion in [1] and in this mailing-list discussion [4] about 
the future possibility of using syntax properties or a similar mechanism to 
allow macros and other identifiers to specify their indentation.

 [1] https://github.com/racket/drracket/issues/60
 [2] 
http://docs.racket-lang.org/tools/adding-languages.html#%28idx._%28gentag._17._%28lib._scribblings%2Ftools%2Ftools..scrbl%29%29%29
 [3] 
http://docs.racket-lang.org/framework/Racket.html#%28meth._%28%28%28lib._framework%2Fmain..rkt%29._racket~3atext~3c~25~3e%29._compute-racket-amount-to-indent%29%29
 [4] https://groups.google.com/forum/#!msg/racket-users/mTXshH6eal0/u-OySmuuCwAJ

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] [ANN] A type-expander library for Typed/Racket

2016-08-24 Thread Dupéron Georges
Based on Asumu's work on type expanders 
(https://github.com/racket/racket/compare/master...takikawa:tr-type-expander), 
I have written a library which adds support for type expanders in typed/racket. 
Type expanders are to types what match expanders are to match patterns. A type 
expander is a special macro which can appear wherever a type would normally be 
expected, and must expand to a type.

The library is written using literate programming, with (a variant of) 
scribble/lp2. The annotated source code is available here:
http://docs.racket-lang.org/type-expander.hl/
and the documentation here:
http://docs.racket-lang.org/type-expander/

This library comes along with the multi-id library 
(http://docs.racket-lang.org/multi-id/, literate source: 
http://docs.racket-lang.org/multi-id.hl/), which allows easy definition of an 
identifier which acts as a type expander, match expander, normal macro and 
identifier macro. It can be used to define new datatypes, where a single 
identifier represents the type, match clause, literal
instance as in (foo-datatype 1 2 3), and constructor function as in (map 
foo-datatype …).

The type-expander library is in beta status:
* It works well and I have been using it for a while without issues.
* The API should not change significantly in the future.
* However, there are many typed/racket primitives which are not
  overloaded yet, as noted in the documentation (patches are welcome).
* Also, a couple of features are missing (patches are welcome again):
   * The special form `Let`, which acts like `let-syntax` for types,
 is only partially implemented.
   * The special form `(Λ (stx) . body)`, which acts as an anonymous
 type expander, is not implemented at all.
   * There is no syntax-local-type-introduce.

Any feedback is appreciated! :)

Regards,
Georges Dupéron

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: linespacing in scribble with superscripts

2016-08-23 Thread Dupéron Georges
Le jeudi 18 août 2016 22:21:37 UTC+2, jos.koot a écrit :
> #lang scribble/manual
> bla blah blah@(linebreak)
> blah blah bla @superscript{blah blah bah}@(linebreak)
> bla blah blah
> 
> the linespacing between the first 2 lines is larger
> than between the last 2 lines.

I suppose you are talking about the HTML output, as LaTeX (used for the PDF 
output) handles this correctly, unless you start stacking many superscripts, as 
you noted.

I used a quick hack to collapse the element's vertical height in HTML, with 
`margin-top` and `margin-bottom` set to an arbitrary, large, negative value, 
and `display: inline-block;` so that the margin is taken into account.

Unfortunately, scribble doesn't apply a CSS class to superscript elements, and 
instead it uses some hard-coded `style="…"` attribute on the element. I 
therefore suggest overriding the `superscript` function with your own 
definition. The code below renders as the attached screenshot, and allows you 
to use the `@original-superscript{…}` if you need.

#lang scribble/manual

@(require scribble/core
  scribble/html-properties
  scribble/latex-properties
  (only-in scribble/manual
   [superscript original-superscript]))
@(define thin-superscript-css
   (string->bytes/utf-8 #

[racket-users] Re: Problems with modules and with raco

2016-08-13 Thread Dupéron Georges
Le vendredi 12 août 2016 14:53:35 UTC+2, rumpz a écrit :
> It's like it marked down somewhere that those structs refer to the definition 
> of "word" in webapp/words.rkt, and not the one in webapp2/words.rkt

This sounds to me like it is using the old bytecode files, since the original 
files haven't changed. Does removing the compiled/ directory fix this issue?

Le vendredi 12 août 2016 14:53:35 UTC+2, rumpz a écrit :
> (define-namespace-anchor a)
> (define ns (namespace-anchor->namespace a))
> 
> …
> 
> If I compile app.rkt with "raco exe app.rkt" and "raco distribute appdir app"
> and I move the "appdir" directory to another system, when I run ./app it 
> crashes with this error:
> 
> default-load-handler: cannot open module file
>   module path: #

What exactly are you doing with the namespace-anchor? Usually, 
`dynamic-require` and friends play poorly with compilation (since they require 
modules at run-time, the compiler can't easily know statically what files to 
include etc.).

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Macro expanding to #'(begin) lacks arrows in DrRacket

2016-08-03 Thread Dupéron Georges
I have two files, `a.rkt` and `b.rkt`:

;; a.rkt
#lang racket
(provide foo)
(define-syntax (foo stx)
  ;; Do some compile-time side effects here…
  #'(begin))

;; b.rkt
#lang racket
(require "a.rkt")
(foo)

The `foo` macro defined in `a.rkt` does some side effects, and expands to 
`(begin)`. When `b.rkt` is opened in DrRacket, there is no arrow drawn from 
`foo` to the require clause, and the require clause is marked as unused (red 
background when hovering it.

How can I get the arrow from `foo` to "a.rkt", while keeping the same semantics?

* If I change `foo` so that it expands to `(begin-for-syntax)`, then the arrow 
is correctly shown, but the macro can't be used in expression contexts.

* If I change `foo` so that it expands to `(void)`, then the arrow is correctly 
shown, but it changes the semantics (whether # values are displayed or 
not during execution depends on the language)

* The only solution I found is to change `foo` so that it expands to `(define 
dummy (void))`. Since the macro is hygienic, the `dummy` definition is 
inaccessible. It does feel a bit clunky though, is there a better solution?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: get the contract of a (or any) function - or find matching functions

2016-07-31 Thread Dupéron Georges
Le samedi 16 juillet 2016 09:20:33 UTC+2, mattap...@gmail.com a écrit :
> I wonder if there's a way to get the contract of functions in the libraries?
> 
> PS. I'm trying to find target functions in the namespace that'll 'match' the 
> values I have (i.e. that can 'work with' the values I have). Any guidance on 
> an easier or different approach are greatly welcome.

Maybe the info contained in `blueboxes.rktd` can help?

I suspect that in most cases, this info would be extracted from @defproc[…] 
calls in the docs. This means the declaration shown in the blue boxes is not 
completely free-form, although @defproc[…] does not check that actual contracts 
are given (it does not even check that the identifiers are bound, for that 
matter).

If you run the contract functions as specified in `blueboxes.rktd` to check the 
values against them, then it would be nicer to do so in a sandbox, as the 
function could 1) have side-effects and 2) in some cases would not even be a 
contract.

Georges Dupéron

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] (make-syntax-delta-introducer a b) and (m-s-d-i b a) have scopes in common

2016-07-31 Thread Dupéron Georges
In the following code, (make-syntax-delta-introducer a b) and 
(make-syntax-delta-introducer b a) have scopes in common (#(8979 module) and 
#(8980 module m 0)), which are part of both inputs. The docs do not mention 
that some scopes present in both `a` and `b` can be part of the resulting 
introducer too. What is causing this behaviour?

#lang racket

(define-syntax (foo stx1)
  (syntax-case stx1 ()
[(_ name)
 #`(define-syntax (name stx2)
 (let* ([a (datum->syntax (quote-syntax #,stx1) 'x)]
[b (datum->syntax (quote-syntax #,(syntax-local-introduce 
stx1)) 'y)]
[delta-a-b (make-syntax-delta-introducer a b)]
[delta-b-a (make-syntax-delta-introducer b a)])
   (display "a   ") (displayln (hash-ref (syntax-debug-info a) 
'context))
   (display "b   ") (displayln (hash-ref (syntax-debug-info b) 
'context))
   (display "delta a b   ") (displayln (hash-ref (syntax-debug-info 
(delta-a-b (datum->syntax #f 'x) 'add)) 'context))
   (display "delta b a   ") (displayln (hash-ref (syntax-debug-info 
(delta-b-a (datum->syntax #f 'x) 'add)) 'context))
   #'(void)))]))

(foo bar)
(bar)

=>

a   (#(8979 module) #(8980 module m 0) #(8993 use-site))
b   (#(8979 module) #(8980 module m 0) #(8992 macro))
delta a b   (#(8979 module) #(8980 module m 0) #(8993 use-site))
delta b a   (#(8979 module) #(8980 module m 0) #(8992 macro))



It seems that `make-syntax-delta-introducer` reliably gives an introducer 
encapsulating the set of scopes `a - b` only if `b` is the empty set. Based on 
this, I wrote the following function, which seems reliably produce an 
introducer for `a - b`:

(define (scopes-delta a b)
  (let* ([+a (make-syntax-delta-introducer (datum->syntax a 'first)
   (datum->syntax #f 'none))]
 [+b (make-syntax-delta-introducer (datum->syntax b 'second)
   (datum->syntax #f 'none))]
 [a-b (+b (+a (datum->syntax #f 'none)
  'add)
  'remove)])
(make-syntax-delta-introducer a-b
  (datum->syntax #f 'none

Georges Dupéron

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.