Re: [racket-users] [racket users] Pollen tag question

2020-10-30 Thread Matthew Butterick


> On Oct 30, 2020, at 1:46 PM, Kevin Forchione  wrote:
> 
> Thanks, Matthew! Understanding dawns. So the padding of lines is relative to 
> the “{“ and not from the beginning of the editor line as I was assuming. How 
> very clever. That makes alignment much easier than I’d thought!  
> 
> Is this mentioned anywhere in the pollen tutorials? I must have missed it.

Yes:

"The Pollen language is a variant of Racket’s own text-processing language, 
called Scribble. Thus, most things that can be done with Scribble syntax can 
also be done with Pollen syntax. For the sake of clarity & brevity, I’ve only 
shown you the highlights here. But if you want the full story, see @ Syntax in 
the Scribble documentation."

https://docs.racket-lang.org/pollen/pollen-command-syntax.html?q=pollen#%28part._.Further_reading%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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/D63442C4-6339-420A-903D-1547BD013E19%40mbtype.com.


Re: [racket-users] [racket users] Pollen tag question

2020-10-30 Thread Matthew Butterick


> On Oct 29, 2020, at 9:04 PM, Kevin Forchione  wrote:
> 
> I’ve noticed that the elements being sent to a pollen tag don’t preserve the 
> spacing when the text spans multiple lines for any space occurring before 
> characters on the subsequent line, although does preserve the spacing between 
> characters on that line.Is thes intentional?



Yes:

"Spaces at the beginning of body lines do not appear in the resulting 
S-expressions, but the column of each line is noticed, and all-space 
indentation strings are added so the result has the same indentation … If the 
first string came from the opening { line, it is not prepended with an 
indentation"

https://docs.racket-lang.org/scribble/reader.html?q=spaces%20newlines#%28part._.Spaces__.Newlines__and_.Indentation%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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/3998A523-1ED7-4446-80F4-A860324FA79C%40mbtype.com.


Re: [racket-users] Font bearing - lining up texts and outlines

2020-07-21 Thread Matthew Butterick
The `fontland` library does not have an official public API but it will give 
you the answer, which is 1446.

#lang racket
(require fontland fontland/ttf-glyph)
(define f (open-font "/System/Library/Fonts/Supplemental/Arial Unicode.ttf"))
;; `layout` uses OpenType positioning & substitution tables to create a glyph 
run,
;; which is a structure with two vectors: a vector of glyphs and a vector of 
glyph positions
;; once we have the glyph we can `glyph-decode` it and inspect its yMax value.
(match (layout f "♖")
  [(glyphrun (vector glyph _ ...) _) (hash-ref (glyph-decode glyph) 'yMax)])



> On 21 Jul 20, at 4:25 AM, Jens Axel Søgaard  wrote:
> 
> It helps to use the correct font...
> 
> It turns out the chess rook is not in "Courier", it is in  "Arial Unicode MS".
> The raw pango functions aren't clever enough to find an alternative font,
> but I think `text` from `pict` is. I am not sure of the details here 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/43A50577-DCC4-49DE-B33E-8CB16A1B2A10%40mbtype.com.


Re: [racket-users] br-parser-tools question

2020-06-08 Thread Matthew Butterick
`br-parser-tools` has some patches needed to make `brag` work, e.g., using the 
srcloc structure. I forked rather than patch the underlying `parser-tools` 
package because I didn't want to destroy the fragile ancient artifact. I fixed 
a few bugs; the others persist. I notice, for example, that your program fails 
to work regardless of whether it uses `br-parser-tools` or `parser-tools`. (I'm 
assuming here you have a good reason to use good old `yacc` and not `brag`, 
which does mostly the same thing, less painfully)

> On 08 Jun 20, at 9:29 PM, Jon Stenerson  wrote:
> 
> Thanks for confirming. I had actually started with the lexer-src-pos version 
> but had other problems like exn:fail:read wanting a list of srclocs and the 
> lexer only having positions. So I switched to lexer-srcpos which fixed the 
> exception but broke the parse. Maybe I should do a conversion between 
> positions and srclocs at some point? Seems awkward.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/AB46325E-0B78-4ACE-82AD-B5F5AFA4F57E%40mbtype.com.


Re: [racket-users] Exception throwing in web-server

2020-05-25 Thread Matthew Butterick
AFAICT this is the intended behavior. To me it is consistent with the usual 
policy: an uncaught error stops the program. If you want the program to keep 
running, then you have to catch the error and make other arrangements. All my 
servlet routes are surrounded by a top-level `with-handlers` block that catches 
`exn:fail?`. If I get an error, I usually a) log it to the remote system, b) 
send an email to myself, and c) send a status 400 response to the browser with 
the error string. But the web server keeps running as usual. 

> On May 25, 2020, at 10:30 AM, Norman Gray  wrote:
> 
> This means that a further possibility is to have an exception handler within 
> the serialiser, and handle exceptions appropriately there (as in 
> my-app/handlers above).  However all this means that a carefully-written 
> servlet _must_ have such handlers, if an inadvertent exception in the 
> serialiser procedure isn't to stall a client.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/D9679928-BF4D-4115-8E28-5D4D6FAC48B9%40mbtype.com.


Re: [racket-users] Starting a language after Beautiful Racket

2020-04-10 Thread Matthew Butterick
Three options:

1) Implement your language in `#lang br` now (and optionally convert to 
`racket/base` later) [1]

2) Import the `br/datum` module into a `#lang racket/base` program to get 
`format-datum` [2]

3) Reimplement `format-datum` your own way. You can see the underlying code by 
right-clicking on `format-datum` in DrRacket and selecting "Open Defining File".

[1] https://beautifulracket.com/appendix/from-br-to-racket-base.html
[2] 
https://docs.racket-lang.org/br/index.html?q=br%2Fdatums#%28mod-path._br%2Fdatum%29

> On Apr 10, 2020, at 9:17 AM, Pratyush Das  wrote:
> 
> A followup question - 
> 
> But this assumes that the br lang is being used(I think because of the 
> format-datum syntax). How do I implement this without using the br lang?
> 
> ...
> (define 
> 
>  src-lines (port->lines 
> 
>  port))
>   (define 
> 
>  src-datums (format-datums 
> 
>  '(handle ~a) src-lines))
> ...
> 
> Is it possible to use modules to just get the format-datums from the br 
> language? 
> 
> 
> On Fri, 10 Apr 2020 at 17:50, Pratyush Das  > wrote:
> I am absolutely new to both Racket and language implementation.
> 
> I read through some portions of Beautiful Racket 
>  and the racket guide 
>  before trying to 
> implement a language on my own and this is what I understand - 
> 
> I created a main.rkt which would be the boot module in my source directory, 
> following the Beautiful Racket master recipe 
> .
> 
> Every language should define and provide a read-syntax function. 
> 
> To make the new language read the source file, read-syntax must be defined 
> something like - 
> (define (read-syntax path port)
> ...)
> 
> Like in Beautiful Racket's wires language implementation 
> , I want to read the source 
> file line by line and wrap it in a macro. 
> Beautiful Racket does it like this - 
>   (define 
> 
>  (read-syntax 
> 
>  path port)
> (define 
> 
>  wire-datums
>   (for/list 
> 
>  ([wire-str (in-lines 
> 
>  port)])
> (format-datum 
> 
>  '(wire ~a) wire-str)))
> 
> But this assumes that the br lang is being used(I think because of the 
> format-datum syntax). How do I implement this without using the br lang?
> 
> Also, am I wrong in any of my assumptions so far?
> 
> 
> 
> -- 
> You received this message because you are subscribed to a topic in the Google 
> Groups "Racket Users" group.
> To unsubscribe from this topic, visit 
> https://groups.google.com/d/topic/racket-users/qEXz8YcAisc/unsubscribe 
> .
> To unsubscribe from this group and all its topics, send an email to 
> racket-users+unsubscr...@googlegroups.com 
> .
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/180aae4b-9e79-43cc-9177-6c917acf0dc8%40googlegroups.com
>  
> .
> 
> 
> -- 
> Pratyush Das(Reik)
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com 
> .
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/CAFzLTskQ70okYZj247VA2rGNWyoW62wCyyu3jqXHtzZdw3aJEg%40mail.gmail.com
>  
> .

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group 

Re: [racket-users] Suggestions for "The Racket Guide"

2020-04-08 Thread Matthew Butterick
I use the same Clipboard.js library on Beautiful Racket to support code 
copying. (I use v.1.5.15, though apparently the lib is now at 2.0.6).

I've not had any problems or complaints. 

One wrinkle in implementation is that you don't want to pass formatted HTML to 
the clipboard. Obviously, what the user wants is the plain code. What I found 
is that I had to put two versions of each code block on the page: one that's 
visible, with all the styling annotations, and one that's plain (though not 
plain text — you still need to observe HTML whitespace and escaping 
conventions) that gets fed to the clipboarding function. I suppose one could go 
the other way, and scrape the formatting markup off the visible code. I have no 
patience for this kind of "software" "engineering".

> On Apr 8, 2020, at 10:45 AM, Greg Trzeciak  wrote:
> 
> I forgot the dependecy used:
>  
> src="http://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.4.2/clipboard.min.js";>
> 
> 
> On Wednesday, April 8, 2020 at 7:24:20 PM UTC+2, Greg Trzeciak wrote:
> Found in an old file of mine:

> On Wednesday, April 8, 2020 at 6:54:37 PM UTC+2, Stephen De Gabrielle wrote:
> That’s a good suggestion! Do you know the relevant JavaScript we can try it 
> out with. Might be an easy PR.


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/ECBD5E41-745F-4081-826A-F7A26D92C761%40mbtype.com.


Re: [racket-users] racket/draw: how to extract the path from a font% object?

2020-04-02 Thread Matthew Butterick
The thorny issue that `fontconfig` handles is mapping from a high-level 
specification of a font (e.g., family, weight, slant) — that is, how a user 
would typically specify a font — to an actual font file on disk. 

The shortcoming with font filenames is that they don't reliably tell you 
anything about the font inside. So `fontconfig` digs out metadata from the file 
itself (IIUC) and uses this to guess which font file best suits your wishes. 
(Also, Racket ships with `fontconfig`, so it’s guaranteed to be available.)

Most of `fontland` is esoteric nonsense, but for the benefit of future list 
spelunkers, here's how I used `fontconfig` (badly, perhaps) to solve this 
problem:

https://github.com/mbutterick/fontland/blob/master/fontland/font-path.rkt


> On Apr 1, 2020, at 8:14 PM, David Storrs  wrote:
> 
> I knocked together a very minimal pure-Racket library for this so you
> don't have to FFI.  It won't give you all the bells and whistles, but
> it should be a good starting point.
> 
> https://pkgd.racket-lang.org/pkgn/package/font-finder
> 
> Docs:   https://github.com/dstorrs/font-finder/blob/master/README.md
> 
> Newly arrived on a package server near you.
> 
> ...where I note there is a newly-created package named 'fontland' that
> was put up by Matthew and probably does all this and more.  Doh.
> 
> Well, hopefully this helps a little bit.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/4D36EF85-1278-42CF-AEAF-86C8822FF064%40mbtype.com.


Re: [racket-users] racket/draw: how to extract the path from a font% object?

2020-04-01 Thread Matthew Butterick
The answer is you can't, through pure Racket, because Racket delegates the 
nitty-gritty of font-file resolution to external font-handling libraries.

It is possible, however, to call into the `fontconfig` library via the FFI and 
make it do the heavy lifting of 1) scanning font directories to amass a list of 
possible fonts and then 2) finding a match for a certain query pattern, say a 
family name.



> On Mar 31, 2020, at 4:52 PM, Matthew Butterick  wrote:
> 
> IIUC every `font%` object must correspond to a particular font file on disk.
> 
> If so, given a `font%` object, how do I extract the path to that file?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/C28B01B3-4772-4AA4-899C-78DADE7B8B2A%40mbtype.com.


[racket-users] racket/draw: how to extract the path from a font% object?

2020-03-31 Thread Matthew Butterick
IIUC every `font%` object must correspond to a particular font file on disk.

If so, given a `font%` object, how do I extract the path to that file?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/39ABE79E-4319-4B75-8BB4-B93694F7E203%40mbtype.com.


Re: [racket-users] how to adapt BC code for Racket CS?

2020-02-25 Thread Matthew Butterick


> On Feb 25, 2020, at 7:05 AM, Matthew Flatt  wrote:
> 
> * CS has a single heap with a single-threaded, stop-the-world GC ---
>   so allocation and GC easily become a bottleneck.
> 
>   If GHC's experience is any guide, making the GC itself multithreaded
>   may address much of this problem.
> 
> Locks on shared system data structures may also be a significant
> obstacle to CPU utilization with places in CS, but I'm not sure.



FWIW some quick timings on a Pollen render of practicaltypography.com. Though 
extra cores have diminishing net returns under Racket BC, the returns are still 
positive. Under Racket CS, by contrast, net performance degrades with more than 
4 cores.

Racket BC

single core
real4m21.191s
user3m37.940s
sys 0m42.388s

parallel @ 2 cores
real2m46.235s
user4m22.160s
sys 0m56.270s

parallel @ 3 cores
real1m54.134s
user4m10.330s
sys 0m54.533s

parallel @ 4 cores
real1m43.055s
user4m46.933s
sys 1m5.948s

parallel @ 6 cores
real1m34.783s
user6m8.522s
sys 1m32.125s

parallel @ 8 cores
real1m18.137s
user6m24.778s
sys 1m38.617s

parallel @ 12 cores
real1m14.924s
user8m30.239s
sys 2m14.671s

Racket CS   

single core 
real5m1.422s
user4m16.300s   
sys 0m44.253s   

parallel @ 2 cores  
real3m25.016s   
user4m45.385s   
sys 0m54.634s   

parallel @ 3 cores
real2m52.780s
user4m57.951s
sys 1m3.184s

parallel @ 4 cores  
real2m42.471s   
user5m22.796s   
sys 1m17.889s   

parallel @ 6 cores
real2m44.513s
user6m26.700s
sys 1m54.549s

parallel @ 8 cores  
real2m56.782s   
user8m4.029s
sys 2m58.554s   

parallel @ 12 cores 
real3m2.116s
user9m34.846s   
sys 5m5.443s



-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/3D11BBCF-B0FE-473B-8997-09B7CB60D761%40mbtype.com.


Re: [racket-users] how to adapt BC code for Racket CS?

2020-02-25 Thread Matthew Butterick
What can you say about places & parallelism under CS vs. BC? This is one area 
that I find CS to reliably underperform BC (by about a factor of 2). Place 
creation seems slower under CS. More interestingly however, the utilization of 
multiple cores seems inefficient. For instance, when I run a full parallel 
Pollen render under BC, my cores jump to 90-100% and stay there. Fans speed up, 
struggling to eject the heat of this awesome computation. Whereas under CS, the 
cores saunter along in a more leisurely range of about 40-50% (which would 
itself account for the 2x perf difference).


> On Feb 23, 2020, at 4:58 AM, Matthew Flatt  wrote:
> 
>> 2) With Racket BC, I've generally found that the JIT optimizes my code 
>> better 
>> than I do. So I write the simplest code and ignore the details. Is that less 
>> true with CS? Should I be thinking more about manual tuning?
> 
> You should treat Racket BC and CS the same in this 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/4B757A48-F10F-43F3-BECC-9E40A7416448%40mbtype.com.


[racket-users] how to adapt BC code for Racket CS?

2020-02-22 Thread Matthew Butterick
Of the convergence of Racket BC and CS performance, Matthew Flatt wrote: [1]

> development to date has been aimed at making Racket CS match the performance 
> of Racket BC on a code base that was developed and tuned for Racket BC, and 
> that obviously gives Racket BC an advantage. For example, Racket BC makes 
> dormant code relatively cheap, so Racket libraries generate a lot of code. 
> Future Racket libraries will likely shift to take advantage of Racket CS’s 
> cheaper function calls and dramatically cheaper continuations.

1) As a package maintainer with zero exposure to Chez Scheme, how do I start to 
optimize for Racket CS? Are there certain patterns and idioms from BC that 
should be systematically eradicated? For instance, how would I "take advantage 
of ... cheaper function calls"? 

2) With Racket BC, I've generally found that the JIT optimizes my code better 
than I do. So I write the simplest code and ignore the details. Is that less 
true with CS? Should I be thinking more about manual tuning?

3) Lurking here, I gather, is the bugaboo that even though core Racket runs on 
CS, the existing base libraries are optimized for BC. Is it considered 
important to optimize these for CS, in order to get the most benefit from the 
switch? How can Racket developers contribute to this?

4) Building both BC and CS is easy (thank you). What would be the most reliable 
technique for doing performance comparisons as one refactors code? Is it as 
simple as running `raco test ···` and `racocs test ···` in succession?




[1] https://blog.racket-lang.org/2020/02/racket-on-chez-status.html

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/12D39EEF-E58B-476F-8159-78F97E340FE1%40mbtype.com.


Re: [racket-users] Web server + authentication

2020-01-22 Thread Matthew Butterick
I concur on Postmark. For 2+ yrs I've used it with the Racket web server for 
mbtype.com . I pass the server settings to 
`smtp-send-message` from `net/smtp 
`.


> On 22 Jan 20, at 3:00 AM, Bogdan Popa  wrote:
> 
> I like using Postmark[0] for this.  Their free plan lets you send up to
> 100 e-mails a month, their paid plans come at a reasonable price and
> they have helpful docs and validators to help you set up SPF, DMARC and
> DKIM.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/9CBD358C-6A8A-4203-A395-61AF69D44C65%40mbtype.com.


[racket-users] perplexed by macro-expansion behavior near #%module-begin

2020-01-13 Thread Matthew Butterick
Below, the two modules `test1` and `test2` use the same expander `exp` and 
otherwise differ only in the presence of the string "foo" as the second datum 
in `test2`. 

The syntax objects passed to #%module-begin are more different than that, 
however: the syntax passed to the first is 

#'(#%module-begin 'mac-result)

wheras the second gets: 

#'(#%module-begin (mac 42) "foo")

Thus my question: why is `mac` getting expanded at different times based on the 
presence of "foo"?


;;;
#lang racket

(module exp racket
  (provide #%datum mac (rename-out [mb #%module-begin]))

  (define-syntax-rule (mac x) 'mac-result)

  (define-syntax (mb stx)
(println (syntax->datum stx))
(syntax-case stx ()
  [(_ . EXPRS)
   #'(#%module-begin . EXPRS)])) )

(module test1 (submod ".." exp)
  (mac 42))
(require 'test1)
;; '(#%module-begin 'mac-result)

(module test2 (submod ".." exp)
  (mac 42) "foo")
(require 'test2)
;; '(#%module-begin (mac 42) "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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/C0F76736-B28C-4F64-A1AA-D2B2EFD34BF8%40mbtype.com.


Re: [racket-users] Limiting consecutive identical elements with match

2019-12-04 Thread Matthew Butterick

> On Dec 4, 2019, at 3:26 PM, 'Joel Dueck' via Racket Users 
>  wrote:
> 
> I like the trick of using list* to match _ on any number of trailing 
> elements. The grammar given in the docs doesn't seem to include it; I'm 
> curious by what rule is it "allowed" as a pattern?

It's a synonym for the `list-rest` match pattern.



-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/B5F3E54D-B800-481D-8FE3-A03C6B4F565E%40mbtype.com.


Re: [racket-users] Limiting consecutive identical elements with match

2019-12-04 Thread Matthew Butterick

> On Dec 4, 2019, at 2:39 PM, 'Joel Dueck' via Racket Users 
>  wrote:
> 
> So it seems easy to match "at least N identical elements".
> But is there a method for matching "no more than N identical elements"?

?


#lang racket
(require rackunit)

(define (super-cool? lst)
  (match lst
[(and (list* _ ... a a _)
  (not (list* _ ... a a a _))) #t]
[_ #f]))

(check-true (super-cool? '(1 1 4)))
(check-false (super-cool? '(1 1 1 4)))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/1734093C-0C39-4289-9747-41CAFB35851F%40mbtype.com.


Re: [racket-users] xml library clarification - "" symbol parsing

2019-11-21 Thread Matthew Butterick

> On Nov 21, 2019, at 9:51 AM, Kira  wrote:
> 
> I tested sxml. And it is producer rigth (for me) output.
> 
> I feel that this is wrong behavior. Because this  symbols is direct 
> part of one and whole element content. And must be read as "\"test qoute\"".
> 
> Can please someone explain reasoning under such behaivor, and can we change 
> it? Perhaps it is important for some other racket libs?
> It is just totally contrintuitive for me. And creating a huge problems with 
> even simple XML parsing. (I am basically battling XML lib all day already to 
> do most simple tasks)



If you want string elements to be concatenated where possible, you can do that 
after you parse:

#lang racket
(require xml txexpr rackunit)
(check-equal?
 (let loop ([x (string->xexpr "testtest 
qoute")])
   (match x
 [(txexpr tag attrs elements) (txexpr tag attrs (loop elements))]
 [(list (? string? strs) ..1 xs ...) (cons (string-join strs "") (loop xs))]
 [(list xs ...) (map loop xs)]
 [x x]))
 '(ROOT (A (B1 "test") (B2 "\"test qoute\""


But AFAIK there is nothing in the XML spec that requires XML to be parsed in 
your preferred style. So it is not "wrong behavior". 

Moreover, if you are writing code that treats '(tag "a" "b") and '(tag "ab") as 
semantically distinct, that's a code smell, because as XML, they're equivalent:

#lang racket
(require xml rackunit)
(check-equal? "ab" (xexpr->string '(tag "a" "b")))
(check-equal? "ab" (xexpr->string '(tag "ab")))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/04CAA36E-F8D8-479D-9509-28A2970DB445%40mbtype.com.


Re: [racket-users] Efficient idiom for converting key-set of a hash-map into a hash-set

2019-10-26 Thread Matthew Butterick

> On Oct 25, 2019, at 7:28 AM, Thomas Dickerson 
>  wrote:
> 
> For reasons that are unclear to me, hash-keys and dict-keys both return a 
> list? instead of a set?(frankly, this seems like a bug in the API...).


A dict doesn't guarantee unique keys. So `dict-keys` returns a list, not a set. 

#lang racket
(require racket/dict)
(define kvs '((a 1) (a 2)))
(dict? kvs) ; #t
(dict-keys kvs) ; '(a a)

Why does `hash-keys` also return a list? For consistency, I suppose, because 
every hash is a dict.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/0D154CA9-581E-48DB-8C32-EA37A7A25112%40mbtype.com.


Re: [racket-users] Rhombus project plan

2019-10-03 Thread Matthew Butterick
Fantastic! In these confusing times, this fills my mind with warmth and 
optimism.


> On Oct 2, 2019, at 12:27 PM, Matthew Flatt  wrote:
> 
> Rhombus is about building on the good parts of Racket and advancing the
> frontier of Racket-style language-oriented programming. A significant
> part of the experiment is trying a surface syntax other than
> parenthesized prefix notation. Another part is simplifying and
> generalizing elements of `#lang racket`, such as its data structures
> for streams and binding with integrated and extensible
> pattern-matching. While some of these goals could be pursued
> independently, taking them together offers opportunities to make the
> whole language fit together better.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/26232E44-3619-4751-9230-4B3544C8A81B%40mbtype.com.


Re: [racket-users] Can someone help me understand why my tokenizer (made with Brag) doesn't work?

2019-09-23 Thread Matthew Butterick
> 
> On 23 Sep 19, at 9:10 PM, Cistian Alejandro Alvarado Vázquez 
>  wrote:
> 
> Can anyone help me understand how my tokenizer should work? I'm truly truly 
> lost and reading the documentation has only added to my confusion! 

What your parser parses is a sequence of tokens. If you don't pass the parser 
all the tokens that the grammar expects, then the parse can never succeed. 

For instance, the problem with this lexer:

(lexer  
["select" lexeme]
[whitespace (token lexeme #:skip? #t)]   
[any-char (next-token)]))

Is that it only produces one token, "select". Since your parser uses more than 
just the token "select": 

#lang brag
select: /"select" fields /"from" source joins* filters*
fields: @field (/"," @field)*
field : WORD
source: WORD
joins : join* 
join  : "join" source "on" "(" condition ")"
filters   : "where" condition ("and" | "or" condition)*
condition : field | INTEGER "=" field | INTEGER

The parse can never succeed.

Likewise, your revised lexer:

(lexer
   [whitespace (token lexeme #:skip? #t)]
   ["select" lexeme]
   [(:seq alphabetic) (token 'WORD lexeme)]))

Will only emit two kinds of tokens: "select" and a WORD token containing a 
single letter as its lexeme. (Do you see why?) Also not what you want.

I can't write your whole tokenizer. But as a start, you probably want to match 
each of your reserved keywords as a whole token, e.g. —

[(:or "select" "from" "join" "on" "where" "and") lexeme]

If you want other sequences of characters to be captured as WORD tokens, your 
pattern needs to be a quantified pattern:

[(:+ alphabetic) (token 'WORD lexeme)]



-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/A1CAD400-5675-4540-87EE-F154417AC549%40mbtype.com.


Re: [racket-users] Is it possible to sell commercial use rights to an open source Racket package?

2019-08-27 Thread Matthew Butterick


> On 27 Aug 19, at 9:27 AM, Sam Tobin-Hochstadt  wrote:
> 
> 4. The interpretation of the LGPL as it relates to Racket that appears
> on the download page is our (the Racket leadership) interepretation,
> not the SFCs. None of us are lawyers, but that remains our
> interpretation.

So Racket's licensing is, or is not, supervised by an actual lawyer? In the 
past, I've gathered that Racket management has consulted with a lawyer on 
certain issues. But your comment suggests that maybe this isn't so. Or at least 
not for licensing.


> 3. The license of Racket has not changed as a result of joining the SFC.

> 6. The relicensing is something we hope to complete, but as the SFC is
> now the fiscal sponsor of the Racket project they are working to make
> sure it's done to their standards, which may require more time.

These statements seem somewhat at odds — how should they be reconciled? Do you 
mean that if & when the relicensing is completed, Racket's licensing will be 
thereafter be supervised by the SFC and its lawyers (because the relicensing 
needs to be "done to their standards")? As I understand it, though SFC's 
term-of-art legal designation is "fiscal sponsor", their relationship with 
member projects encompasses more than just fiscal matters. [1]

[1] https://sfconservancy.org/about/ 



-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/B646E784-09E6-4A5E-9744-22B37DC566C2%40mbtype.com.


Re: [racket-users] Is it possible to sell commercial use rights to an open source Racket package?

2019-08-23 Thread Matthew Butterick
Bradley Kuhn, director of the SFC, has explained why FLOSS projects don't need 
CLAs, along with some underlying legal truths about FLOSS contributions. [1] 

[1] https://sfconservancy.org/blog/2014/jun/09/do-not-need-cla/ 



> On 23 Aug 19, at 12:29 PM, Alexis King  wrote:
> 
> Maybe so, but that is, in fact, why I sent the email. I was hoping you could 
> clue me in as to what I was missing. (Maybe it’s unfair of me to ask you for 
> free legal analysis, but I don’t feel like it’s all that unreasonable to ask 
> for just a little clarification here.)
> 

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/D77638C7-BF30-4E03-9F57-4090C061DB05%40mbtype.com.


Re: [racket-users] Is it possible to sell commercial use rights to an open source Racket package?

2019-08-23 Thread Matthew Butterick
You're omitting some key facts. So no, I don't agree with your legal analysis. 

But the underlying point remains: there is unnecessary murkiness around 
Racket's licensing status. 


> On 23 Aug 19, at 11:24 AM, Alexis King  wrote:
> 
> AFAIK, copyright of the Racket codebase is not the Racket core team’s to 
> give. Racket has no CLA, so its copyright belongs to all of the individual 
> contributors, core team members or not. If the Racket core team did own the 
> copyright, the relicensing effort would have amounted to little more than a 
> decision. But as-is, whether the SFC takes ownership of copyrights held by 
> the core team or not is irrelevant, as any individual Racket contributor 
> could choose to enforce the terms of the license for their contributions 
> should they desire. But I’m sure you knew all that already—you’re the 
> lawyer—so I’m curious what you know that I don’t.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/5AC224B1-ED3B-4083-A165-FEB9AB9A701A%40mbtype.com.


Re: [racket-users] Is it possible to sell commercial use rights to an open source Racket package?

2019-08-23 Thread Matthew Butterick

> On Aug 23, 2019, at 6:24 AM, Sage Gerard  wrote:
> 
> Has someone tried to release an open source Racket project under a license 
> that enforces paid commercial use of that project? Light Googling suggests 
> this would be antithetical to the LGPL if not open source in general, but  
> https://download.racket-lang.org/license.html 
>  says "the Racket license does 
> not restrict you at all."



I am a lawyer, and I remain mostly mystified about Racket's licensing / IP 
ownership status since it joined Software Freedom Conservancy in June 2018. 

In some cases, SFC takes ownership of trademarks and copyrights [1] which means 
that in terms of license interpretation & enforcement, assumedly the buck would 
now stop with them. 

Did SFC do so in this case? No idea. Before the switch, Karen Sandler from SFC 
circulated [2] a template agreement [3] but AFAIK the actual agreement that 
Racket's core team signed, and the details thereof, has never been shared with 
the community. (Can it? Should it? Not my call. Or did I miss it?)

Furthermore, the original SFC/Racket press release mentioned a "newly formed 
Project Leadership Committee" [4] — there's never been any mention of who's on 
this committee, or whether their responsibilities involve licensing. 

Lingering elsewhere: the relicensing project that commenced more than 2.5 years 
ago [5] — not clear whether under the SFC this effort is alive, dead, or what. 
Of course, Galaxy's Edge took 3 yrs to build, so maybe I'm being unreasonably 
impatient. 

(BTW though I do not redistribute Racket, there's often a certain amount of 
modified Racket code in packages I maintain, therefore the limitations on 
Racket code also limit the licensing of my packages. Other things being equal 
I'd rather use a license more liberal than the LGPL.)


[1] https://sfconservancy.org/about/ 
[2] https://groups.google.com/d/msg/racket-dev/QeYN6uZBWBc/qAbUb_mWBwAJ
[3] https://sfconservancy.org/projects/apply/ConservancyFSATemplate.pdf 

[4] https://sfconservancy.org/news/2018/jun/12/racketjoins/ 

[5] https://github.com/racket/racket/issues/1570 


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/11A6C2ED-604A-4904-9A3E-AE5305A5450A%40mbtype.com.


Re: [racket-users] Using the top level to fix unbound identifier

2019-08-13 Thread Matthew Butterick

> On 13 Aug 19, at 7:03 PM, Jonathan Simpson  wrote:
> 
> In the following magic code, a new function(called a named query in magic) 
> tga-image is defined and later used inside the definition of the function 
> test-scope. The issue is that tga-image is an unbound identifier in 
> test-scope. If tga-image is used outside of a function there isn't a problem 
> because the syntax object passed to use has the binding. What I would like to 
> do is define tga-image at the top level.




You might consider the technique described here, including the 
`find-unique-var-ids` function:

https://beautifulracket.com/basic-2/variables-and-input.html 


Since you're using `brag`, you can wrap your future identifiers in, say, an 
`id` rule that you splice away in the grammar. So your parse tree ends up the 
same, but now that `id` rule leaves a residue as a syntax property. 

Then, as part of your `#%module-begin` prep work, you can use this property to 
pull out the identifiers and write them into the top level of your new module 
as `define` expressions (with dummy values, that would get replaced later with 
`set!`). 

There may be a way of accomplishing the same thing more elegantly with syntax 
lifts and captures. Like the lost city of El Dorado, I searched for this 
beauty, but expired on the jungle floor before discovering it. Since then, 
however, many people smarter than me have seen that page, so by Cunningham's 
Law, if there were a better method, I probably would've been told by now. 




-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/DC4EE1B4-5164-43CB-89D8-E750F15B1A68%40mbtype.com.


Re: [racket-users] Code generation options for a self-made compiler

2019-08-12 Thread Matthew Butterick
+ use the `raco-commands` key in "info.rkt" to create new `raco myprog ···` 
commands

+ use `racket/cmdline` to parse the input options to these commands.




> On 12 Aug 19, at 7:34 AM, Dmitry Pavlov  wrote:
> 
> With C, everyone is happy with macros and built-in options, e. g.
> 
> gcc -O3 -DREAL=double -DDATABASE=POSTGRES prog.c
> 
> 
> The best idea for Rackey I have so far is to use good old environment 
> varibles, e. g.
> 
> REAL=double BACKEND=Racket raco make myprog.mylang
> 
> But it has its obvious drawbacks. What do I do 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/952086D8-F4D1-4CDD-AB4F-1367295B9F87%40mbtype.com.


Re: [racket-users] on reducing barriers in the Racket community

2019-07-25 Thread Matthew Butterick
Mr. Atlas, since this seems to be only your second contribution to the 
racket-users list (the first was yesterday) I'm reluctant to impute much weight 
to your views, since I can't verify that there's a sincere human behind them. 

In any case, I can agree with you on the value of education. But the idea that 
lowering barriers is equivalent to "ruining community", "lying to people", and 
"insult[ing] people who are already in the project" — no, I don't agree, and 
those ideas are inconsistent with everything I've learned about how Racket 
operates.


> On Jul 25, 2019, at 8:58 AM, Atlas Atlas  wrote:
> 
> 1. To increase inclusiveness of some group of people, you educate people from 
> this group on the subject of lisp racket computer science etc.
> 2. By lowering "barriers" you just welcome someone who doesn't care for the 
> project and ruining community from inside.
> 3. By making a show about what project is NOT, you lying to people you want 
> to attract, and insult people who are already in the project.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/1B7D03BF-DB5F-4A1C-83EE-93E0A21CA76C%40mbtype.com.


Re: [racket-users] Message in the meantime?

2019-07-24 Thread Matthew Butterick

> On Jul 24, 2019, at 1:41 PM, Matthew Flatt  wrote:
> 
> it seems difficult to make switching syntax automatic and pervasive. I
> think there would end up being a lot of overhead to maintaining
> documentation and tools that can reliably toggle between notations.


Support for alternative notation in the documentation system is a missing piece 
in Racket's LOP tooling:

1) We can make languages with alternative (= non-S-expression) notation.

2) We can integrate these languages with DrRacket pretty nicely, through 
automatic means (e.g., propagation of source locations) and manual (e.g., the 
`get-info` function)

3) But we can't document these languages in Scribble using their native 
notation. That is, primary forms like `defproc` assume that the language uses 
S-expressions. 

Examples: `#lang datalog` [1] and `#lang lindenmayer` [2].

[1] https://docs.racket-lang.org/datalog/Tutorial.html?q=datalog 

[2] 
https://docs.racket-lang.org/lindenmayer/Simplified_Lindenmayer_System_Language.html?q=lindenmayer
 



-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/90F502CB-6004-40B7-8A15-3E787C67FFF3%40mbtype.com.


[racket-users] on reducing barriers in the Racket community

2019-07-21 Thread Matthew Butterick
I'm not a member of Racket management. But I spend a lot of time using & 
promoting Racket. Most recently, I taught the Beautiful Racket Workshop as part 
of Racket Week 2019. 

I care a lot about Racket — the technology, but especially the human community 
that makes it possible.

I've heard from a few people that events before, during, or after Racket Week 
left them questioning Racket's commitment to making everyone feel welcome. And 
to be honest, it wasn't the first time. 

This saddens me. It's not consistent with my own values. It's not what I want 
Racket to stand for. I want everyone to feel welcome, wanted, and valued. 

In a nearby thread, Matthew Flatt talked about the importance of "reducing 
barriers" in a technical sense. But it matters in a community sense too, of 
course. 

If Racket is putting up social barriers — even unwittingly — that are 
frustrating newcomers (or existing members) then we ought to be able to hear 
this with an open mind & heart, and make adjustments. This is our duty as 
empathetic, moral members of a community.

I'm not sure what I can do to improve this situation. I'm open to suggestions. 
I can at least offer the following (I would rather risk looking foolish than 
doing nothing):


1) If you've had an experience where the Racket community made you feel less 
than totally welcomed, I invite you to add it to this thread, or contact me 
privately. If you want details of your story shared, in some anonymized way, I 
can do that. 

I recognize the irony of making this offer on the racket-users mailing list — 
those who've had a bad experience are likely long gone. But I also know there 
are people here who, like me, want to help make Racket better, even on rough 
days.


2) Gently, I suggest that we work together to reduce the volatility of these 
conversations. I know that some feel that these matters are better handled away 
from the racket-users list. But this is counterproductive: it amounts to saying 
that we should feel free to harvest the benefits of Racket-the-technology while 
avoiding obligations to Racket-the-community. As a matter of logic and ethics, 
I can't see how they are divisible. 


3) Today, I'm a reasonably well-adjusted adult (or at least my dog thinks so). 
But a long time ago, I was a fat and dorky and smart kid. For years, I was 
physically and verbally bullied at school. It was relentless and terrifying. 
But as was true for a lot of kids like me during that era, computers were a 
refuge. They never judged me. They rewarded my curiosity. 

I mention this not to put my experience on a footing with anyone else's. But it 
reminds me that while our contributions to Racket may be public, what Racket 
MEANS to each of us is necessarily private. Right now, there are people in our 
community for whom Racket is a bright spot in difficult times. If you haven't 
been there yet — you will.

To my mind, discussing these matters openly is about preserving the paramount 
virtue of a community based on sharing knowledge: to accept everyone just as 
they are. When we're falling short in this regard, we shouldn't avoid these 
facts, lest we make a virtue of ignorance. Or if we can't do this, and people 
bypass Racket in preference to other communities, then we'll have no one to 
blame but ourselves.

With much gratitude to everyone who makes Racket possible.


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/8964B1F7-C0A5-44BA-AFE3-FF87E038F3CE%40mbtype.com.


[racket-users] Conservancy policy vs. Racket policy

2019-07-15 Thread Matthew Butterick
[forked from "The case, and a proposal, for elegant syntax in #lang racket2"]

> On 07 15 19, at 10:55 AM, Matthias Felleisen  wrote:
> 
> the word “diversity” is inherently political. It is designed as a wedge, a 
> tool to separate people into groups and then from each other. It is used as a 
> kudgel by one side of the political spectrum to relentlessly hit the other 
> side. It was bad enough to have been told that there were too many 
> “cis-gendered white males” at RacketCon. 



For those who weren't there: the comment about "cis-gendered white males" [1] 
was made from the stage by RacketCon 2019 speaker Bradley Kuhn, president of 
the Software Freedom Conservancy, which now oversees Racket. Bradley was 
invited to speak about "Conservancy and Racket: What We Can Do Together".

I enjoyed Bradley's talk. But I'm now unclear about the policy relationship 
between Conservancy & Racket. 

IIUC, as a Conservancy project, Conservancy's policies are now necessarily 
Racket's policies, even if that wasn't the case before. This seems clearly 
spelled out in the fiscal-sponsorship agreement Racket executed (which was 
shared with this list last year) — that Racket is "subject at all times to the 
direction and control of Conservancy’s Board of Directors". [2]


> I do not wish to see this mailing list turn into another political echo 
> chamber, because then I have to remove myself from it and the public Racket 
> community. If people wish to discuss the politics of diversity in the Racket 
> community, please create a Facebook group and go there. 

Stepping gingerly here, it does seem that Bradley Kuhn and Conservancy intend 
that some notion of "diversity" becomes an explicit part of Racket's outward 
policy orientation (and not, say, relegated to a private Facebook group). He 
said so at RacketCon. [1]

For this reason Matthias, I'm not clear whether you're speaking for yourself in 
this case (as you sometimes do) or for Racket management (as you sometimes do). 
Are you saying that on a personal level, it's not your favorite aspect of the 
Conservancy relationship? Or are you saying that Racket, as a Conservancy 
project, is repudiating part of Conservancy's policy platform?

[1] https://youtu.be/xSjk2PdQm5k?t=17682
[2] https://sfconservancy.org/projects/apply/ConservancyFSATemplate.pdf 


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/D8CA91DC-6680-42B0-AECB-93755604C25A%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Racket plugin access the path of a file

2019-06-25 Thread Matthew Butterick
In your `get-info` function for your #lang, if `ip` is the input port passed as 
the first argument to `get-info`, then you can get the current document 
filename like so:

(send (object-name ip) get-filename)

And pass it as an argument to your button function.


> On Jun 25, 2019, at 1:10 PM, Kshitij Sachan  wrote:
> 
> I'm trying to make a language-specific toolbar button that when clicked 
> prints the path of the file the button is clicked from. I've been able to set 
> up the button, but how I don't know how to access the path of the current 
> file.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/1D594ACA-0406-4C54-A7EF-0BAB3AB9F9AE%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] managing competing access to filesystem within places

2019-06-22 Thread Matthew Butterick


> On 06 22 19, at 6:14 AM, Robby Findler  wrote:
> 
> One thing you can do, when the place-specific communication takes
> multiple steps is to, like you did in the first example, put the
> channels into a hash, but then on each iteration of the loop, pull all
> of them out and put them into a giant select that takes the relevant
> step forward for that specific piece of the communication

Not sure what you mean by "giant select" — ought that be "giant sync"? But as 
for "sequential access to some shared state" — In this toy example, maybe more 
along the lines of your suggestion, the server makes a random sequence of 
workers and triggers the workers in turn, so none of them are ever working at 
the same time. (So they could, in principle, all be writing to a single file.) 

I can imagine a more nuanced version involving each worker chekcing out sets of 
files, and the server permitting progress by more than one worker at a time, so 
long as the file sets didn't overlap.


#lang racket
(require racket/place racket/dict)
(provide main)

(define (main)
  (define server-p
(place sch
   (define wp-dict (place-channel-get sch))
   (let loop ()
 (define wp-dict-shuffled (shuffle wp-dict))
 (displayln (format "order: ~a" (dict-keys wp-dict-shuffled)))
 (for ([(widx wp) (in-dict wp-dict-shuffled)])
   (displayln (format "server: start ~a" widx))
   (place-channel-put wp widx)
   (apply sync (dict-values wp-dict)))
 (loop
 
  (define worker-ps
(for/list ([i (in-range (processor-count))])
  (place wch
 (let loop ()
   (define widx (place-channel-get wch))
   (sleep 0.2)
   (displayln (format "worker ~a: done" widx))
   (place-channel-put wch 'done)
   (loop)

  (place-channel-put server-p (for/list ([(wp widx) (in-indexed worker-ps)])
(cons widx wp)))
  
  (for-each place-wait worker-ps))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/54475D15-78B1-4F3A-A06C-35739DFCBC57%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] managing competing access to filesystem within places

2019-06-21 Thread Matthew Butterick


> On 06 15 19, at 8:31 AM, Robby Findler  wrote:
> 
> A standard way to work with this is to send a channel over in the
> first communication and then the communication that's specific to that
> initial request happens on that channel. The precise way you set this
> up depends on what invariants of the communication you want. Like, you
> can create a new thread and just do all the communication there


And here's a threaded version, which I agree is neater, because by closing over 
each worker channel, the threads make other channel-tracking housekeeping 
unnecessary.

#lang racket
(require racket/place)
(provide main)

(define (main)
  (define loopback-p
(place lch
   (let loop ()
 (define wp (place-channel-get lch))
 (thread (λ () (let loop ()
 (place-channel-put wp (place-channel-get wp))
 (loop
 (loop
 
  (define worker-ps
(for/list ([i (in-range (processor-count))])
  (place wch
 (let make-request ([count 1])
   (define countout (place-channel-put/get wch count))
   (displayln (format "worker request ~a:~a got response ~a:~a ~a"
  0 count 0 countout
  (if (eq? count countout) "" "### fail")))
   (make-request (add1 count))
  
  (for ([worker-p (in-list worker-ps)])
(place-channel-put loopback-p worker-p))
  
  (map place-wait worker-ps))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/A5055051-898C-46F9-82C6-BD0A50AC4D20%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] managing competing access to filesystem within places

2019-06-21 Thread Matthew Butterick

> On Jun 15, 2019, at 8:31 AM, Robby Findler  wrote:
> 
> A standard way to work with this is to send a channel over in the
> first communication and then the communication that's specific to that
> initial request happens on that channel.


This is probably the crudest possible implementation of your suggestion, but 
this version avoids mismatched requests & responses. The `loopback-p` makes a 
table of the worker channels at the outset. After that, as it gets requests, it 
dispatches the response directly to the worker that issued the request.

(I'm not asking you to review this code, I'm just posting this for curious 
people of the future.)


#lang racket
(require racket/place)
(provide main)

(define (main)
  (define loopback-p
(place ch
   (let ([chs (make-hasheq)])
 (let loop ()
   (match (place-channel-get ch)
 [(list wpidx (? place-channel? wp))
  (hash-set! chs wpidx wp)
  (place-channel-put wp 'ack)]
 [(list wpidx count)
  (place-channel-put (hash-ref chs wpidx) (list wpidx count))])
   (loop)
 
  (define worker-ps
(for/list ([i (in-range (processor-count))])
  (place ch
 (match-define (list loopback-p wpidx wp) 
(place-channel-get ch))
 (place-channel-put loopback-p (list wpidx wp))
 (place-channel-get ch) ; wait for 'ack
 (let make-request ([count 1])
   (place-channel-put loopback-p (list wpidx count))
   (match-define (list wpidxout countout)
 (place-channel-get ch))
   (displayln (format "worker request ~a:~a got response 
~a:~a ~a"
  wpidx count wpidxout countout
  (if (and (eq? wpidx wpidxout) (eq? 
count countout)) "" "### fail")))
   (sleep (* 0.01 (add1 wpidx))) ; multiplier makes workers 
go at different speeds
   (make-request (add1 count))
  
  (for ([(wp wpidx) (in-indexed worker-ps)])
   (place-channel-put wp (list loopback-p wpidx wp)))
  (map place-wait worker-ps))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/14FF4C4B-CE93-4B10-B496-B678DA74B4F4%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Re: Git-Backed Racket Packages, git archive

2019-06-17 Thread Matthew Butterick

> On Jun 17, 2019, at 10:23 AM, Eric Eide  wrote:
> 
> Communicate with users.  I want to put the appropriate git hash into the 
> output
> of my program (Xsmith-based random program generators) so that I can attempt 
> to
> reproduce the output, if necessary.

Once upon a time I tried to do the same for Pollen and couldn't sort it out. 
AFAICT the git hash isn't generated until the commit is made. Instead, I ended 
up adding a git push hook that writes a timestamp into a "ts.rktd" file as part 
of the commit. Then when Pollen is installed, that timestamp can be baked into 
the version number as a "build number". [1] So it is not the git hash, but it 
still identifies a particular commit. I'm sure this offends common decency, but 
it has indeed been useful for pinpointing user problems.

[1] https://docs.racket-lang.org/pollen/version-notes.html 



-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/1C6BFA1E-612A-498D-A92D-75F0B880F019%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] managing competing access to filesystem within places

2019-06-15 Thread Matthew Butterick


> On Jun 15, 2019, at 8:31 AM, Robby Findler  wrote:
> 
> Place channels are asynchronous, not syncronous (i.e. you don't have
> two-way rendez-vous). So the call to put returns immediately in
> `loopback-p` before the other end receives the result. And now the
> next iteration of the loop's get is in parallel to the put from the
> previous iteration's.


Are place channels "Buffered Asynchronous Channels"? [1] Or just a similar 
idea? The `place` docs describe place channels as "endpoints for a two-way 
buffered communication" and "asychronous" [2] but there is no link to BAC, 
which makes me think they are different. But reading your description of the 
behavior of place channels with `sync` and `handle-evt`, now I'm not sure.


[1] 
https://docs.racket-lang.org/guide/concurrency.html?q=channels#%28part._.Buffered_.Asynchronous_.Channels%29
 


[2] 
https://docs.racket-lang.org/reference/places.html?q=places#%28tech._place._channel%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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/C4E43B34-A41D-4A0D-8FC1-D5E0BF377D34%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] managing competing access to filesystem within places

2019-06-15 Thread Matthew Butterick

> On Jun 14, 2019, at 8:15 PM, Matthew Butterick  wrote:
> 
> But even after approving a lock request from a certain rendering place, the 
> lock server would end up with repeat lock requests from there.


BTW here's a minimal example showing the puzzling message-garbling behavior 
between places.

Here, instead of a lock server, I just have a loopback server. What I expect is 
that each worker sends a request number, and the loopback immediately echoes 
this number back as a response, so the numbers will always match. 

But that's not what happens. At first, the response numbers match the requests. 
But then they start coming back mismatched. The error rate increases as the 
`sleep` value decreases, for instance:

worker request 1:46 got response 1:46 
worker request 0:90 got response 0:90 
worker request 0:91 got response 2:31 ### fail
worker request 2:31 got response 0:91 ### fail
worker request 7:12 got response 7:12 
worker request 1:47 got response 1:47 
worker request 4:19 got response 0:92 ### fail
worker request 0:92 got response 4:19 ### fail
worker request 5:16 got response 5:16 
worker request 0:93 got response 0:93 

The garbling happens in a predictable way: every request is answered, but a 
closely occurring set of requests and responses will be mismatched among 
themselves. By adjusting the `sleep` value, it's easy to create a flow rate of 
messages where almost all of them are garbled.



#lang racket
(provide main)

(define (main)
  (define loopback-p
(place ch
   (let loop ()
 (place-channel-put ch (place-channel-get ch))
 (loop
 
  (define worker-ps
(for/list ([i (in-range (processor-count))])
  (place ch
 (match-define (list loopback-p wpidx) (place-channel-get ch))
 (let make-request ([count 1])
   (match-define (list wpidxout countout)
 (place-channel-put/get loopback-p (list wpidx count)))
   (displayln (format "worker request ~a:~a got response ~a:~a ~a"
  wpidx count wpidxout countout
  (if (and (eq? wpidx wpidxout) (eq? count 
countout)) "" "### fail")))
   (sleep (* 0.01 (add1 wpidx))) ; multiplier makes workers go at 
different speeds
   (make-request (add1 count))
  
  (for ([(wp wpidx) (in-indexed worker-ps)])
(place-channel-put wp (list loopback-p wpidx)))
  (map place-wait worker-ps))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/1A3D2E52-1DDA-40FC-B8F7-816B6E9EFF70%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] managing competing access to filesystem within places

2019-06-14 Thread Matthew Butterick


> On Jun 14, 2019, at 4:34 PM, Matthew Flatt  wrote:
> 
> Sometimes, staying out of the error-triggering space is unavoidable,
> and the possible errors are well enough defined by all filesystems, so
> retrying is a workable solution. If you really have to be in that
> space, then retry an arbitrary number of times, perhaps with an
> exponential backoff (i.e., double the delay between retries).

OK, thanks for the encouragement. After more experimentation I got the 
lock-server idea to work (meaning, my parallel renders now complete without 
errors, which was not true before).

For the benefit of future generations, two complications tripped me up, the 
first I understand, the second I don't, but maybe someday:

1) At first I had each rendering place issue its lock requests file by file. 
This didn't work because each place needed to lock a set of files, and the 
individual lock / unlock requests could end up interleaved in the lock server, 
with strange results (some locked / some unlocked). So I bundled each set of 
files into a "lock transaction" which I passed in a single place message, then 
all of them would get locked or unlocked as a group.

2) I set up each rendering place to repeatedly ask for a lock until it was 
approved. But even after approving a lock request from a certain rendering 
place, the lock server would end up with repeat lock requests from there. To 
fix this, I needed to create a third response for the lock server, which was 
"dude you already have a lock".

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/BCC26E32-FFF6-40ED-92F9-98C70895E227%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] managing competing access to filesystem within places

2019-06-14 Thread Matthew Butterick



> On Jun 13, 2019, at 6:43 PM, Matthew Flatt  wrote:
> 
> 
> Oh, don't do that. Unreliable workarounds to concurrency problems
> really do come back to bite you later.

To ask the second dumbest possible question, what error-recovery policies are 
reliable under concurrency? (Put another way, what guarantees exist about 
errors under concurrency? E.g. can we trust that all errors will trigger an 
exception?)

And the dumbest possible: if there are no such policies, then how can you ever 
be certain the code works?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/07C94517-FA0B-46A7-949D-0AB3179A2F70%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] managing competing access to filesystem within places

2019-06-13 Thread Matthew Butterick

> On Jun 13, 2019, at 10:04 AM, Matthew Flatt  wrote:
> 
> I recommend a lock-serving place in Pollen to manage concurrency for
> parallel rendering. Don't let multiple places try to read and/or write
> to the same file, and don't try to use filesystem locks.


Thanks for the suggestion. I see what you mean. Locking the source file being 
rendered did reduce the filesystem errors ... 

... but it didn't eliminate them. The wrinkle is that in the typical Pollen 
project, many (or even all) these source files may transitively rely on writing 
the same template file, e.g., "template.html.p". I could lock that file too, 
but then other renders that rely on it would be blocked, which would tend to 
relinearize the job.

As an alternative to file locking, I tried having each rendering place attempt 
the render three times with a short delay in between. On the idea that a 
temporary filesystem error is likely to resolve by the third try, and a 
permanent failure (e.g., a problem with the source file itself) will not, and 
can be raised as a "real" error. 

Maybe there is a secretly perncious aspect to this muddle-through-it technique, 
though it does avoid the relinearization problem.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/982C42C2-CC6A-4DB1-8168-D6803A9D502A%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] managing competing access to filesystem within places

2019-06-13 Thread Matthew Butterick
To Pollen, I've recently added a parallel-rendering facility with places, in 
emulation of how Racket docs are rendered in parallel.

But it doesn't quite work — I get intermittent / inconsistent errors from the 
filesystem (for instance, certain files that should exist do not, or certain 
files that shouldn't exist, do)

My intuition about places is weak. But it seems to me that Scribble renders are 
largely independent (= happening in separate folders on the filesystem). 
Whereas within a Pollen project, the rendered sources are often relying on 
shared files (for instance, a "template.html"). So there is more direct 
competition for use of certain files, which perhaps is Bad News.

Is there a rule of thumb for how to manage these conflicts? For instance, is it 
better to just avoid having places try to read or write from the same files? Is 
there some filesystem-blocking technique that can be used to make sure reads & 
writes don't collide? 

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/2A49317F-F4C8-4EF2-B144-E8846571DD7F%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] `fontconfig` through the FFI: best practice?

2019-06-11 Thread Matthew Butterick
If I want to call functions in the `fontconfig` library through the FFI, 

should I be relying on the incantations in "cairo-lib.rkt"?  [1] 

Or are those somehow specific to the `racket/draw` system? 

Why does the `fontconfig-lib` definition there include libraries that are not 
`libfontconfig`? 

Does the "Racket-specific patch to Fontconfig" need to be used always?

So far I've gotten some Fontconfig code to work on Racket 7.1 @ Mojave but it 
failed on 7.1 @ Sierra. So there is some platform-specific magic I'm missing. 

[1] 
https://github.com/racket/draw/blob/6ada7d8abdc664b4b4b42c6e2a7a3703d3794f9e/draw-lib/racket/draw/unsafe/cairo-lib.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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/54B670E7-D324-4EDB-92A1-E269CBBAA92A%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Trouble writing unhygienic macro

2019-05-28 Thread Matthew Butterick

> On May 28, 2019, at 7:11 AM, Jonathan Simpson  wrote:
> 
> Both the function definition and function calls are created by similar 
> looking macros which pass strings as the function name. I've now taken steps 
> to break hygiene in the defining macro, but the calling macro just converts 
> the string to a symbol. It's invocation looks something like this:
> 
> (query
>(line (offset 0) (type "use") "tga-image"))
>  
> Perhaps they aren't referring to the same binding. Maybe I need a 
> datum->syntax in this macro as well. I don't have access to the code at the 
> moment, so I can't try it, but does this make sense?
> 
> If this is the case then I can probably fix it by modifying the other macro 
> as well, but modifying the lexer to emit symbols instead of strings seems 
> like the best approach.


Here's an example of two macros that both make an identifier out of 
"tga-image": the first defines a function called `tga-image`, and the second 
calls it. Notice that the same syntax-context-switching fandango is needed in 
both cases to ensure that both `tga-image` ids are placed inside the same 
syntax context, so that the first one binds the second. (As someone pointed out 
earlier, you could also use `format-id` for this, which is shorthand for the 
same operation)


#lang racket

(define-syntax (definer-macro stx)
  (syntax-case stx ()
[(_ magic-name)
 (with-syntax ([name (datum->syntax #'magic-name (string->symbol 
(syntax->datum #'magic-name)))])
   #'(define (name x) x))]))

(definer-macro "tga-image")

(define-syntax (caller-macro stx)
  (syntax-case stx ()
[(_ magic-name arg)
 (with-syntax ([name (datum->syntax #'magic-name (string->symbol 
(syntax->datum #'magic-name)))])
   #'(name arg))]))

(caller-macro "tga-image" 42)

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/2787D491-F179-49DB-8ECB-8302F2D5EF1E%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] how do you read, manipulate, debug scope sets?

2019-05-06 Thread Matthew Butterick

> On May 6, 2019, at 7:53 AM, zeRusski  wrote:
> 
> Are there any tutorials that show you how to use things documented in Syntax
> Transformers chapter of the Reference?
> 
> How do you debug these scope games?

I agree there is something of a gap in the Racket docs / tooling, because 
scopes are a relatively recent addition to the macro expander. You might  want 
to take a look at the `scope-operations` and `debug-scopes` packages.

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


[2] https://docs.racket-lang.org/debug-scopes/index.html 


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


Re: [racket-users] Module not updating on the package server?

2019-05-01 Thread Matthew Butterick


> On Apr 30, 2019, at 12:18 PM, David Storrs  wrote:
> 
> I just pushed an update to the test-more module.  On the package server it 
> was marked as 'New!' and was up to the latest commit, but the build status 
> was 'fails'.  The compilation report is from April 18.  I thought I'd take a 
> second chance, so I pushed another update, but no joy.  Is there any way for 
> me to make this update or could one of our wonderful maintainers kick the 
> server for me?
> 


Patience is a virtue. Across the months and years I have noticed increasingly 
longer lag times (now measured in hours) between when the daily build occurs 
for a package and when the build report has propagated to the `pkg-build` 
server & documentation has propagated to the `docs` server.  (Even though, as 
others have pointed out, the record on `pkgs` itself usually notices commits 
within a few minutes.)

I don't know for sure, but I take this to be a consequence of the overall daily 
build taking longer than it used to, because there are more packages. Which is 
a good thing.

I don't know if `pkgs.racket-lang.org ` was meant 
to be a package-discovery tool for end users. I imagine not, because we have 
the beautiful Scribble documentation system, which is where the worthwhile 
user-facing information about a package lives. Whereas the package server has 
records largely of interest to package developers and other machines.

-- 
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 do I clear this FFI-related build error?

2019-04-25 Thread Matthew Butterick

> On Apr 25, 2019, at 9:35 AM, Matthew Flatt  wrote:
> 
> Assuming that you're using
> 
>  https://github.com/greghendershott/travis-racket 
> 
> 
> then I think "install-racket.sh" has to change so that you have the
> option to add "-natipkg" between "linux" and ".sh" in a download URL.

Thanks. This works on 7.1 and 7.2. I can live with that.

FWIW:

1) HEAD and HEADCS don't work — they rely on the snapshot servers (Northwestern 
and Utah, respectively), which apparently (?) do not have "natipkg" builds (??)

2) 6.12 and 7.0 install the "natipkg" build, but then `raco pkg install` fails 
with an SSL error. This seems to be a recapitulation of an existing bug [1] (I 
tried the fix suggested by Ryan Culpepper [2], running `export 
SSL_CERT_DIR=/etc/ssl/certs/`, but this did not help).

[1] https://github.com/racket/racket/issues/2184 


[2] https://github.com/racket/racket/issues/2184#issuecomment-428579036 


-- 
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 do I clear this FFI-related build error?

2019-04-25 Thread Matthew Butterick

> On Apr 25, 2019, at 8:54 AM, Matthew Flatt  wrote:
> 
> You can use the "natipkg" Racket build to get Harfbuzz included for
> testing, and that's what the pkg-build server does. Just beware that
> users of the package may have to install/update Harfbuzz on their
> machines.

OK. Sorry to be a moron, but in this case I am. How do I make Travis use the 
"natipkg" Racket build? If there is a .travis.yml that I can study to start my 
cargo cult, fair enough.

-- 
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 do I clear this FFI-related build error?

2019-04-25 Thread Matthew Butterick

> On Apr 23, 2019, at 2:45 PM, Matthew Flatt  wrote:
> 
> At Tue, 23 Apr 2019 23:39:04 +0200, Ryan Culpepper wrote:
>> It looks like natipkg Racket includes libharfbuzz.so.0, not 
>> libharfbuzz.so.1 (see [1]). So try changing the unix line to
>> 
>> [(unix) (ffi-lib "libharfbuzz" '("0" ""))]
>> 
>> instead.
> 
> Right.
> 
> Just to elaborate a little, there is no "libharfbuzz.so.1", so by using
> '("1" "") you end up picking up "libharfbuzz.so" from the OS instead of
> the "libharfbuzz.so.0" natipkg build, and the pkg-build OS is old.


Yes, that advice cleared the error on the Racket package server. 

But now it fails on Travis with a similar error (I know you are not Travis 
support, but let's pretend Travis represents an arbitrary Linux user who might 
use this package):

ffi-obj: couldn't get "hb_buffer_add_codepoints" from "libharfbuzz.so.0" 
(/usr/lib/x86_64-linux-gnu/libharfbuzz.so.0: undefined symbol: 
hb_buffer_add_codepoints)

IIUC, even though I'm now invoking "libharfbuzz.so.0" explicitly, in this case 
the Travis server OS has its own "libharfbuzz.so.0" that is conflicting with 
the one furnished by Racket.

So is there a way to be even more specific about which "libharfbuzz.so.0" I 
load with `define-runtime-lib`?



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


[racket-users] how do I clear this FFI-related build error?

2019-04-23 Thread Matthew Butterick
Some code relies on the `harfbuzz` library, like so:

(define-runtime-lib harfbuzz-lib
  [(unix) (ffi-lib "libharfbuzz" '("1" ""))]
  [(macosx) (ffi-lib "libharfbuzz.0.dylib")]
  [(windows) (ffi-lib "libharfbuzz-0.dll")])


Though this works on my Mac machines, the doc server throws an error: [1]

raco setup:   ffi-obj: couldn't get "hb_buffer_add_codepoints" from 
"libharfbuzz.so" (/usr/lib/x86_64-linux-gnu/libharfbuzz.so: undefined symbol: 
hb_buffer_add_codepoints) 

The `hb_buffer_add_codepoints` function was added in Harfbuzz 0.9.31, but 
according to Racket's readme, it ships with Harfbuzz 1.7.6 [2]

Judging by the Harfbuzz path in the error message, I wonder if I'm 
inadvertently invoking some local copy of Harfbuzz (which is out of date) 
rather than the one that ships with Racket (which isn't). But if so, I don't 
know how to change the `define-runtime-lib` incantation to make it work. 


[1] 
https://pkg-build.racket-lang.org/server/built/fail/quad.txt 


[2] 
https://github.com/racket/racket/blob/709258d88c879c2489a977e85d34f77d760a0008/racket/src/native-libs/README.txt
 


-- 
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] Inline tests for library and corresponding lang result in a loading cycle

2019-04-19 Thread Matthew Butterick


> On Apr 19, 2019, at 1:52 PM, zeRusski  wrote:
> 
> Made me curious. Maybe I'm dense, but do you suggest that I delete 
> foo/bar/lang and add this to foo/bar/main.rkt
> 
> (module reader syntax/module-reader
>   foo/bar/main)
> 
> If I do that though #lang foo/bar no longer works, compiler keeps looking for 
> lang/reader.rkt there, but #lang foo/bar/main does work. In that scenario how 
> do I get my preferred foo/bar language back?


If you want to invoke the language as `#lang foo/bar` then you would put this 
`reader` submodule in "foo/bar.rkt". This would make "foo/bar/lang/reader.rkt" 
obsolete.

-- 
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] Inline tests for library and corresponding lang result in a loading cycle

2019-04-19 Thread Matthew Butterick

> On Apr 19, 2019, at 11:01 AM, zeRusski  wrote:

> One hypothesis I have is that the (module lang-test foo/bar ...) doesn't 
> resolve
> to the language but rather to the foo/bar.rkt


Right. "if the unquoted path contains no /, then require automatically adds a 
"/main" to the reference". [1] Otherwise it doesn't.

[1] 
https://docs.racket-lang.org/guide/module-basics.html?q=main.rkt#%28tech._collection%29
 



> 2. Why does the above report a cycle? How do I reason about it, better still 
> how
>do I query the resolver, reflect and debug?

This also reports a cycle:

;;; bar.rkt
#lang racket
(module foo "bar.rkt")

I don't know exactly why. I'd suppose it's part of some compile-time sanity 
check on submodules.


> 1. How would you write your tests in the situation like this when most of the 
> work
>happens in the library but you also allow using it as #lang? I'd like to 
> keep
>both kinds of tests local to the library, so I can run them as I code. Or 
> at
>least be able to run tests that only test the lib and corresponding 
> language.


Given the above, it seems impossible to invoke a language from within the 
module that implements it. 

Still, I'm not sure why you'd want to do this. #langs are naturally invoked 
from other files. Arguably, it's wise to make this part of the testing. (For 
instance, paths are something that can work correctly when invoking the 
language "locally", but turn out to be broken from afar.) 

I've gotten in the habit of putting my #lang tests in a separate collection (= 
just a neighboring directory, if your package is set up as 'multi) so that the 
test files can invoke the #lang the same way a user would.

PS the `lang/reader.rkt` fandango is no longer necessary in modern Racket; if 
you like, you can use a `reader` submodule in your primary language file.

-- 
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 setup the #%module-begin form with the type-expander lib or #lang typed/racket ?

2019-04-15 Thread Matthew Butterick
`read-syntax` is special, because its job is to convert the surface notation of 
a #lang into S-expressions. So whatever is happening in `read-syntax` is 
happening during compile time, even if we're using functions rather than 
macros. In general, the reader is the most idiosyncratic part of the #lang 
processing pipeline (though perhaps this stands to reason, as surface notations 
are likewise idiosyncratic)


> On Apr 15, 2019, at 2:59 PM, Raoul Schorer  wrote:
> 
> However, I am confused because my lexer (using parser-tools) and pre-expander 
> are defined as standard functions. So in fact, they execute only once at run 
> time, at the difference of a language implemented only with macros which 
> would then have a clear compile time/run time distinction. I would have 
> expected that writing a racket DSL would involve doing almost everything with 
> macros, so is this way of doing things suboptimal?

-- 
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 setup the #%module-begin form with the type-expander lib or #lang typed/racket ?

2019-04-15 Thread Matthew Butterick


> On Apr 12, 2019, at 6:00 PM, Raoul Schorer  wrote:
> 
> Is there a way to achieve expansion to typed/racket from my custom language, 
> please?


With the caveat that I'm probably overlooking some wrinkle pertaining to Typed 
Racket — in general, the language of the expander module doesn't need to be 
same as the language of the `#%module-begin`. I have used this pattern before 
successfully. I don't know if this solves your problem in the large. But it 
makes your toy example work.


;; expander.rkt
#lang racket
(require (prefix-in tr: (only-in typed/racket #%module-begin)))
(provide (rename-out [module-begin/j #%module-begin]))
(define-syntax (module-begin/j stx)
  (syntax-case stx ()
[(_ a) #`(tr:#%module-begin 2)]))

-- 
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] Is it necessary to print after expansion?

2019-04-08 Thread Matthew Butterick

> On Apr 7, 2019, at 9:54 PM, Raoul Schorer  wrote:
> 
> Thanks, indeed it does work.
> Although if I am not mistaken, I did not see mention of 
> (current-print)
> 
> in "Beautiful Racket" or in the doc tutorial on writing languages. Do I have 
> a special case, or is it routinely used but not mentioned? Is it because I 
> did not provide a 
> #%top-interaction
> 
> form for my language yet?


Every expression at the top level of a module is treated as if it had 
`current-print` wrapped around it. Therefore, in the `funstacker` tutorial in 
Beautiful Racket [1], it's not actually necessary to call `display`. 

Still, because I'm writing for people new to Racket, I think it's wiser to 
promote a habit of explicitly calling an output function. Why? Because as you 
move code around, you may be surprised when something stops printing (because 
it's no longer at the top level). For instance, new Racketeers might be 
confused as to why the output of this program:

#lang racket
1
(begin
  2
  3)
(let ()
  4
  5)

is this (4 is not printed):

1
2
3
5

Whereas it's more obvious that this program:

#lang racket

(displayln 1)

(begin
  (displayln 2)
  (displayln 3))

(let ()
  (displayln 4)
  (displayln 5))

Produces this:

1
2
3
4
5

Beyond that, I do very little with output in Beautiful Racket, so it's simpler 
to just use `display` for the few instances (instead of detouring to explain 
the nuances of `current-print` etc.)


[1] https://beautifulracket.com/funstacker/source-listing.html 


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


Re: [racket-users] Pattern: reusing the same name in macro-generated definitions

2019-04-05 Thread Matthew Butterick

> On Apr 5, 2019, at 3:23 AM, zeRusski  wrote:
> 
> Now about that error in the docs:

I was skeptical, but I think you're right:

"More generally, we can define binding based on subsets: A reference’s binding 
is found as one whose set of scopes is a subset of the reference’s own scopes 
(in addition to having the same symbolic name)."

https://www.cs.utah.edu/plt/publications/popl16-f.pdf 


PS I didn't really get scopes until I saw Matthew Flatt's visual explanation 
using colors to represent scopes:

https://www.youtube.com/watch?v=ABWLveMNdzg 


-- 
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] Generics: delegate to a parent

2019-03-22 Thread Matthew Butterick


> On Mar 21, 2019, at 9:55 AM, Kees-Jochem Wehrmeijer  wrote:
> 
> It does? That sounds interesting. Do you have an example of that, or could 
> you point me to some docs? I thought object methods were called with send or 
> send-generic. 

Yes, you can attach generic interfaces to classes. Technique described here:

https://groups.google.com/d/msg/racket-users/uKPauoZvZQo/uey0a66HBgAJ 



> On Mar 22, 2019, at 3:34 AM, zeRusski  wrote:
> 
> TBH I've been avoiding Racket object system since my needs are typically 
> limited and don't call for full blown OOP. I only casually looked at what its 
> capable of, I guess may need to revisit. I was rather hoping for something as 
> simple as structs and generics a-la Emacs Lisp. Superficially Racket structs 
> appear to be like those in Emacs Lisp and Clojure, but now that I'm using 
> them more I'm starting to doubt that. They feel lower level (although quite 
> rich) - the kind of cloth you use to build everything else.


My understanding is that Racket structs are comparatively more foundational 
(e.g., "_all_ values in Racket are structs" [2]), but for that reason, are 
comparatively more rigid. 

Furthermore, "classes and objects are implemented in terms of structure types." 
[3] So even though I am typically an OOP resister, I've come to think of 
Racket's class system as a friendlier way of working with Racket structs.

[2] https://groups.google.com/d/msg/racket-users/7rKKh088zEg/EeuJ3VbSBQAJ 


[3] https://docs.racket-lang.org/guide/define-struct.html 


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


Re: [racket-users] Generics: delegate to a parent

2019-03-20 Thread Matthew Butterick


> On Mar 20, 2019, at 7:09 AM, zeRusski  wrote:
> 
> Both implement the same generic interface. Far as I can tell dispatch will 
> choose marlin's implementation on that kind of instance. Is there a way for 
> me to delegate to fish's method from inside marlin's method with the same 
> name? I can introduce a level of indirection and extract fish's 
> implementation into a function that I could call from marlin's method but 
> that feels wrong somehow. 

I wouldn't say wrong — but I've found that the object system (which also 
cooperates with generics) is more convenient for describing these relationships.

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


Re: [racket-users] How to fix typos in documentation?

2019-03-08 Thread Matthew Butterick
Perhaps this would be good material for a CONTRIBUTING.md at the top level of 
the repo, where it would be more likely to be found by future contributors. 
GitHub will automatically show a link to the file at arguably appropriate 
times. [1]

[1] https://github.blog/2012-09-17-contributing-guidelines/

> On Mar 8, 2019, at 8:44 AM, Marc Kaufmann  wrote:
> 
> Let me (ab)use this thread to add some more details on how to submit pull 
> requests (PR) on GitHub to racket using the GitHub web interface for other 
> noobs - which includes myself in another month or two. Ideally I would write 
> this up elsewhere to help with onboarding, but that won't happen soon, so 
> here we go. We are talking ELI5 (Explain Like I'm 5) level explanations, so 
> this will be painfully obvious to the vast majority (although it would be 
> good for someone who knows what they are doing to correct whatever kludgy 
> workflow I've come up with). I copy most of the steps from Paulo earlier, but 
> add some that I still had to figure 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] raise an exception in a generator

2019-02-20 Thread Matthew Butterick

> On Feb 20, 2019, at 4:29 PM, Kees-Jochem Wehrmeijer  wrote:
> 
> With your define/ideal-world form, is there a way to test whether something 
> was created using that form? E.g. by generating a predicate like ideal-world? 
> That way I can make sure with a contract that my function gets passed an 
> ideal-world generator.

Yes, you could define an impersonator property and then wrap your generator 
with `impersonate-procedure`:



#lang racket
(require (except-in racket/generator yield)
 (prefix-in gen: (only-in racket/generator yield))
 racket/stxparam)

(define-syntax-parameter yield (make-rename-transformer #'gen:yield))

(define-syntax (yield* stx)
  (syntax-case stx ()
[(_ . vals)
 #'(call-with-values (thunk (gen:yield . vals))
 (case-lambda
   [() (void)]
   [(v) (if (exn? v)
(raise v)
v)]
   [vs vs]))]))

(define-values (ideal-world-gen-prop ideal-world-gen? _)
  (make-impersonator-property 'ideal-world-gen))

(define-syntax (define/ideal-world stx)
  (syntax-case stx ()
[(_ ID . BODY)
 #'(define ID
 (impersonate-procedure
  (syntax-parameterize ([yield (make-rename-transformer #'yield*)])
. BODY)
  #f ideal-world-gen-prop #t))]))

(define/ideal-world mygenerator
  (generator ()
 (with-handlers ([exn? (lambda (e) (yield 42))])
   (yield 1)
   (yield 2)
   (yield 3

(mygenerator) ; 1
(mygenerator (exn:fail "Welp" (current-continuation-marks))) ; 42
(generator? mygenerator) ; #t
(ideal-world-gen? mygenerator) ; #t

-- 
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] raise an exception in a generator

2019-02-20 Thread Matthew Butterick

> On Feb 20, 2019, at 8:47 AM, Kees-Jochem Wehrmeijer  wrote:
> 
> While this scheme works, it silently breaks if a user accidentally calls 
> (yield) instead of ((yield)). It might not be a big deal, but in an ideal 
> world I'd only allow the 'correct' way.


You can make a new `define` form where `yield` means something different:


#lang racket
(require (except-in racket/generator yield)
 (prefix-in gen: (only-in racket/generator yield))
 racket/stxparam)

(define-syntax-parameter yield (λ (stx) #'"error: `yield` not parameterized"))

(define-syntax (yield* stx)
  (syntax-case stx ()
[(_ . vals)
 #'(call-with-values (thunk (gen:yield . vals))
 (case-lambda
   [() (void)]
   [(v) (if (exn? v)
(raise v)
v)]
   [vs vs]))]))

(define-syntax (define/ideal-world stx)
  (syntax-case stx ()
[(_ ID . BODY)
 #'(define ID
 (syntax-parameterize ([yield (make-rename-transformer #'yield*)])
   . BODY))]))

(define/ideal-world mygenerator (generator ()
   (with-handlers ([exn? (lambda (e) 
(yield 42))])
 (yield 1)
 (yield 2)
 (yield 3
(mygenerator)

(mygenerator (exn:fail "Welp" (current-continuation-marks)))

-- 
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] Bending use of include-template to my needs (or, macro results as macro arguments)

2019-02-19 Thread Matthew Butterick

> On Feb 19, 2019, at 2:33 PM, Brian Adkins  wrote:
> 
> Awesome - that did the trick. I'm confused as to why it helped to inject STR 
> into the lexical context - it ends up being just a string, and it was working 
> fine with respect to loading the template. I would think the fix would be to 
> inject include-template into the lexical context. I suppose it must have 
> something to do with how the include-template macro is dealing with that 
> argument. 

When `with-syntax` finds a datum (like a string) on the right side of a 
pattern-binding expression, it silently coerces it to a syntax object with the 
macro-definition scope attached (which in this case, was not the right scope).

Ordinarily you wouldn't want to move `include-template` into the lexical 
context of the calling site, because you're relying on retaining the binding it 
has at the macro-definition site.

-- 
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] Bending use of include-template to my needs (or, macro results as macro arguments)

2019-02-19 Thread Matthew Butterick


> On Feb 19, 2019, at 1:28 PM, Brian Adkins  wrote:
> 
> Oops - I spoke too soon. It appears the lexical context is unavailable to the 
> template when include-template is used in this manner. 


Ah right, one has to inject STR into the same lexical context, like so:


#lang racket
(require web-server/templates)

(define-syntax (include-template/named stx)
  (syntax-case stx ()
[(_ NAME)
 (with-syntax ([STR (datum->syntax #'NAME (string-append 
"../views/authentication/" (symbol->string (syntax-e #'NAME)) ".html"))]) 
   #'(include-template STR))]))

(define (login request)
  (include-template/named login))

-- 
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] Bending use of include-template to my needs (or, macro results as macro arguments)

2019-02-19 Thread Matthew Butterick

> On Feb 19, 2019, at 8:25 AM, Brian Adkins  wrote:
> 
> But, I'm guessing that the include-template macro is unable to consume the 
> output of my view macro. Is there anything I can do to get (view login) to be 
> expanded prior to when include-template needs it?

Wrap `include-template` with your own macro that generates the string you want?

#lang racket
(require web-server/templates)

(define-syntax (include-template/named stx)
  (syntax-case stx ()
[(_ NAME)
 (with-syntax ([STR (string-append "../views/authentication/" 
(symbol->string (syntax-e #'NAME)) ".html")]) 
   #'(include-template STR))]))

(define (login request)
  (include-template/named login))

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


Re: [racket-users] Racket Week’s website looks strange now that the registration is open

2019-02-01 Thread Matthew Butterick
This morning, I thought to myself "well, I probably have a couple days to fix 
that counter before someone notices ..." ;)

Registration will be open soon.


> On Feb 1, 2019, at 8:51 AM, 'Leandro Facchinetti' via Racket Users 
>  wrote:
> 
> See https://con.racket-lang.org/2019/ 
> 
> The counter is negative and incrementing.

-- 
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] sxml vs xexpr frustrations

2019-01-31 Thread Matthew Butterick
Stability is narrower than maintainability, which includes the idea of "can the 
software be improved to suit current needs". 

For instance: I'd be willing to look into adding SXML conversion functions to 
my `txexpr` package if you'd find them useful. But when I try to read Oleg's 
spec for SXML, it's gone. 

Yes, it's true that the Racket XML library doesn't support namespaces. I 
imagine part of the issue is that XML belongs to a stack (incl SAX, XPath, 
XSLT) that was never much loved to begin with, and once you've done it the 
Racket Way, feels even more like dragging rocks uphill. On Jupiter.

To be fair, I use xexprs mostly to generate HTML, not XML, so these 
shortcomings aren't bothersome. Those who cannot forgo namespaces will stick 
with SXML.


> On Jan 31, 2019, at 9:39 AM, Christopher Lemmer Webber 
>  wrote:
> 
> Is xexprs really maintained either?  At any rate, not all software needs
> very active maintenance; sxml seems to be fairly stable.  Maybe you
> disagree. :)
> 
> At any rate, I don't think xexprs support namespaces, which sxml has
> tooling for, which is one important thing.

-- 
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] sxml vs xexpr frustrations

2019-01-31 Thread Matthew Butterick
I (ab)use xexprs for Pollen because they're used in the Racket web server, and 
because at the time, SXML seemed largely abandoned — no traffic on its mailing 
list [1] and today, even Oleg's SXML page is a 404. [2] 

I wouldn't try to pry SXML from anyone's fingers. But dragging around 
open-source software abandoned by its owner tends to incite conditions of 
madness. (Insert your favorite 80s typesetting system here.)

[1] https://sourceforge.net/p/ssax/mailman/ssax-sxml/
[2] http://pobox.com/~oleg/ftp/Scheme/SXML.html

> On Jan 30, 2019, at 10:27 AM, Christopher Lemmer Webber 
>  wrote:
> 
> IMO, it makes more sense to have sxml be the "right" one, since it has
> wider user outside of just Racket, and there are some much nicer tools
> available for it:
> 
>  https://docs.racket-lang.org/sxml-intro/index.html#%28part._.Tools%29 
> 
> 
> (That, and I find the @ property syntax a bit easier to follow, but that
> barely matters.)

-- 
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] [help?] Using match-define to generate lists of fields from a struct

2019-01-17 Thread Matthew Butterick

> On Jan 17, 2019, at 2:39 PM, David Storrs  wrote:
> 
> it would be nice to be able to do some slicing and dicing in the
> parsing pattern as opposed to doing it manually afterwards.  Is there
> a way to do it?




#lang racket
(struct spec (type mode) #:transparent) ; cf 'cipher-spec' in crypto module
(define s (spec "aes" "cbc"))

(define-values (type mode cipher-descriptor)
  (match s
[(struct* spec ([type (app string->symbol type)]
[mode (app  string->symbol mode)]))
 (values type mode (list type mode))]))

type ; 'aes
mode ; 'cbc
cipher-descriptor ; '(aes cbc)

-- 
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: ugly spacing due to missing SIntrapara

2019-01-14 Thread Matthew Butterick
I believe the `defthing` tags need an empty {} after them.


> On Jan 13, 2019, at 11:51 PM, Sorawee Porncharoenwase 
>  wrote:
> 
> This seems to be a known and expected output, however. According to 
> https://docs.racket-lang.org/demo-manual-m2/Definition_Blocks.html: 
> 
> 
> Since no explanation flow is attached to the above defform use, there’s no 
> SIntrapara block around the table (just a ).
> 
> The question is, when is this ever a desired output? It seems objectively 
> ugly and confusing in all use cases. 

-- 
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] triggering servlet on GET parameters

2019-01-06 Thread Matthew Butterick
Don't know if it would be an instructive example, but the Pollen project server 
[1], though not intended for production use, is a self-contained HTTP server 
that handles dynamic generation of HTML (it even works with Scribble files), 
which sounds similar to what you're trying to do.

Jesse Alama's book Server: Racket [2] is an excellent resource. Among many 
other things, I learned that you can invent arbitrary HTTP methods beyond GET 
and POST, thereby avoiding encoding conventions like "?action=edit". Instead, 
you can just have an HTTP method called EDIT.

It's possible to use the Racket web server "behind" Apache, so that Apache 
handles the static file serving, and Racket handles computation. [3] 

[1] 
https://github.com/mbutterick/pollen/blob/master/pollen/private/project-server.rkt

[2] https://serverracket.com/

[3] 
http://docs.racket-lang.org/web-server-internal/Troubleshooting_and_Tips.html?q=apache#%28part._.How_do_.I_use_.Apache_with_the_.Racket_.Web_.Server_%29

> On Jan 6, 2019, at 7:33 AM, Stephen De Gabrielle  
> wrote:
> 
> Do you think web-server/dispatch is the right approach?
> 
> My design is; 
> 
> GET http(s)://server/ 
> -> serve static file at specified path
> GET http(s)://server/?action=edit 
> -> serve edit page servlet that retrieves scribble source
> GET http(s)://server/ 
> -> serve edit page adding parameters ?action=edit or maybe new
> POST http(s)://server/   
> -> update scribble source file,  generate target html file in 
> #:server-root-path and redirect to target html file at 
> http(s)://server/https://groups.google.com/d/optout.


Re: [racket-users] Help debugging a custom language read/expansion error

2018-12-30 Thread Matthew Butterick


> On Dec 30, 2018, at 8:41 PM, Jonathan Simpson  wrote:
> 
> I'm doing #1, so I think #2 is the explanation. 'type' is a function 
> available in expander.rkt so the literal will only match that binding. The 
> same is true for 'offset'. Both need to be provided. 'test' is not bound to 
> anything because the macro uses 'compare' as the equivalent function, so 
> 'compare' doesn't need to be provided.
> 
> So I think it all makes sense. Thank you.


PS. This behavior with literals in syntax patterns is specific to 
`syntax-rules` and `syntax-case`. If you switch to `syntax-parse`, you can use 
its `#:datum-literals` option or its `~datum` pattern form to match raw datums 
without bindings.

-- 
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] Help debugging a custom language read/expansion error

2018-12-30 Thread Matthew Butterick
> On Dec 30, 2018, at 3:13 PM, Jonathan Simpson  wrote:
> 
> Adding a '(provide type)' in expander.rkt (where 'line' is defined) gets me 
> past this error. Strangely, providing 'compare' or 'offset' doesn't seem to 
> be necessary. I'm interested in any theories as to why this might be the case.

Without seeing "reader.rkt" or "expander.rkt" — I'd guess that:

1) `read-syntax` isn't stripping all bindings from its parse tree before 
returning it. Though this isn't mandatory, it's a wise practice to avoid 
mysterious binding problems like this one. (Use `strip-context` in 
`syntax/strip-context`.)

and 

2) your list of literals in the `line` macro is stricter than you intend. Macro 
literals match by datum AND binding, not merely by datum. So if you say 
`(offset type test message)`, and you have `type` defined outside the macro, 
then the literal will only match uses of that particular binding of `type`. 
This is why `(provide type)` seems to fix the problem — you're injecting the 
binding the macro pattern wants into the source environment. Again, though 
Racket won't forbid you from managing bindings this way, it can become a 
tangled web.

-- 
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] hackernews

2018-12-27 Thread Matthew Butterick
According to Brendan Eich, "The good parts of [JavaScript] go back to Scheme 
and Self" [1] combined with "a lot of stupid". [2]

[1] 
https://www.jwz.org/blog/2010/10/every-day-i-learn-something-new-and-stupid/#comment-1089
 


[2] 
http://www.jwz.org/blog/2010/10/every-day-i-learn-something-new-and-stupid/#comment-1020


> On Dec 27, 2018, at 8:24 AM, Brett Gilio  wrote:
> 
> 
> Hendrik Boom writes:
> 
>> On Wed, Dec 26, 2018 at 09:51:17AM -0500, Neil Van Dyke wrote:
>>> 
>> 
>> I seem to remember hearing that Scheme was one of the 
>> inspirations for Python.  That and another language.
>> 
>> -- hendrik
> 
> That other language is Dylan, which is also inspired by Scheme.



-- 
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] hackernews

2018-12-26 Thread Matthew Butterick
I agree that success stories are helpful. I'll go one better — I think it would 
be great to have a section of the main Racket website devoted to these stories 
that show who uses Racket and how / why (inside & outside academia). This could 
be done in an interview-style format, like Jesse Alama's recent book about 
language-making in Racket [1]. Photos also. I would be happy to contribute 
design & layout if a sufficiently motivated collaborator — you, Neil? — wanted 
to conduct the interviews & gather the material.

I find the idea of doing language advocacy *on* Hacker News (or Stack Overflow, 
or Quora, etc.) to be weird. Not because I'm a curmudgeon. But rather because 
it's inherently low-leverage, and misses a lot of the people who are 
persuadable.

[1] https://languagemakers.net/anthropology/


> On Dec 26, 2018, at 6:51 AM, Neil Van Dyke  wrote:
> 
> I want to see more people making a living working with/on Racket (outside of 
> professorships, and grad student slave stipends), and I think that means a 
> lot more companies using it for substantial projects, and I suspect the best 
> bet is startups who can choose their tools (and are funded as gambles), and I 
> suspect the best bet for that is getting HN startup success stories like: "we 
> got to launch and ___ funding round, with Racket, because DSLs, and Racket is 
> the best for that".  Then other HN people will see a success story, a couple 
> might be inspired to think about DSLs for their own startup idea, and then 
> somehow this becomes RACKET EXPONENTIAL EXPLOSION.  Or at least more people 
> making a living working with/on 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.


Re: [racket-users] Re: Using Racket behind proxy

2018-12-12 Thread Matthew Butterick

> On Dec 10, 2018, at 11:21 AM, making-a-racket  wrote:
> 
> Does anyone know if Racket is hard-coded to use git://?  


The URL that Racket uses to install a package is whatever the developer has 
listed on the package server — some begin with git://, some with https://, some 
with http://. Moreover, even if the package you want is not associated with a 
git:// URL, it may depend on other packages that are.

-- 
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 disallow certain characters in identifiers?

2018-12-10 Thread Matthew Butterick

> On Dec 9, 2018, at 8:20 PM, default.kra...@gmail.com wrote:

> Is there an easy way to disallow certain characters in identifiers? I 
> realized it's not just dots I want to disallow, but also operators like + 
> which might be interpreted as infix in certain contexts.

Roughly, I imagine you'd want to 

1) grab the input to `#%module-begin`, which is a tree-shaped syntax object
2) flatten it
3) search the list for forbidden identifiers (using `identifier?` and whatever 
patterns are forbidden)
4) report errors, or 
5) if none, complete `#%module-begin` as usual.

Like so:

;; "kapu.rkt"

#lang racket
(require (for-syntax racket/list))
(provide (except-out (all-from-out racket) #%module-begin)
 (rename-out [mb #%module-begin]))

(define-syntax (mb stx)
  (syntax-case stx ()
[(_ . EXPRS)
 (let ()
   (for ([id (in-list (filter identifier?
  (flatten
   (let loop ([stx #'EXPRS])
 (define maybe-stxs (syntax->list stx))
 (if maybe-stxs (map loop maybe-stxs) 
stx)]
 #:when (regexp-match #rx"\\.|\\+" (format "~a" (syntax->datum 
id
(raise-syntax-error 'mylang "invalid identifier name" 
(syntax->datum id)))
   #'(#%module-begin . EXPRS))]))


;; "test.rkt"
#lang s-exp "kapu.rkt"

(define foobar 42)
(define foo.bar 42)
(define foo+bar 42)

> mylang: invalid identifier name in: foo.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.


[racket-users] wrapping C datatypes

2018-11-28 Thread Matthew Butterick
To call my C rusty would be an insult to rust. I'm trying to write an FFI 
wrapper for certain datatypes in the Harfbuzz library:

struct hb_language_impl_t {
  const char s[1];
};
typedef const struct hb_language_impl_t *hb_language_t;


Is this the right interpretation?

(define _one-char-array (make-array-type _char 1))
(define-cstruct _hb_language_impl_t
  ([s _one-char-array]))
(define _hb_language_t _hb_language_impl_t-pointer)

-- 
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] Obtain use-site source information

2018-11-21 Thread Matthew Butterick


> On Nov 21, 2018, at 6:44 PM, Shu-Hung You 
>  wrote:

>> (PS ignore "at L ..." — apparently `gensym` in RacketCS is broken.)

Correction: it's not broken. I overlooked the fact that `gensym` is allowed to 
produce symbols that print the same way, though sometimes it does 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] Obtain use-site source information

2018-11-21 Thread Matthew Butterick
(PS ignore "at L ..." — apparently `gensym` in RacketCS is broken.)

> ;; Result: 
> ;; "at L (unsaved-editor:24.3) ; #f #f"
> ;; "at L (unsaved-editor:25.3) ; #f #f"
> ;; "at L (unsaved-editor:26.0) ; #f #f"
> ;; "at L (unsaved-editor:27.0) ; #f #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] Obtain use-site source information

2018-11-21 Thread Matthew Butterick

> On Nov 21, 2018, at 12:44 PM, Shu-Hung You 
>  wrote:
> 
> It works, but it would be better if (X 'USE) can log information about
> its uses at B and C in addition to the source location A for debugging
> purpose. If I don't want to change the implementation of USE, is there
> a way for X to obtain the source information of B and C?

Stash it in a syntax property?

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

(define log-error format)
(define void values)
(define vector values)

(define-syntax (X stx0)
  (syntax-parse stx0
[(_ stx)
 (define label (gensym 'L))
 (define outer-stx (syntax-property stx0 'outer-stx))
 #`(log-error "at ~a (~a) ; ~a ~a"
 '#,label
 (quote-srcloc-string #,(or outer-stx #'stx))
 '#,(current-module-declare-name)
 '#,(current-module-declare-source))]))


(define-syntax (USE stx)
  #`(void (vector #,(syntax-property #'(X 'USE) 'outer-stx stx ;; A

(X (or 'here #f))
(X 'there)
(USE) ;; B
(USE) ;; C


;; Result: 
;; "at L (unsaved-editor:24.3) ; #f #f"
;; "at L (unsaved-editor:25.3) ; #f #f"
;; "at L (unsaved-editor:26.0) ; #f #f"
;; "at L (unsaved-editor:27.0) ; #f #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] Destructuring a list in (for ...)

2018-11-21 Thread Matthew Butterick

> On Nov 21, 2018, at 9:30 AM, Brian Adkins  wrote:
> 
> Thanks guys. I think I can live with:
> 
> (for ([(i j) (in-dict '(("a" . 1) ("b" . 20)))])
>  (display (list i j)))
> 
> I suppose I could also write something analogous to in-dict that would do 
> what I want. Maybe in-tuple ?


Or perhaps:

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

(define-syntax (match-for stx)
  (syntax-case stx ()
[(_ ([PAT SEQ] ...) . BODY)
 (with-syntax ([(TEMP ...) (map (λ (stx) (generate-temporary)) 
(syntax->list #'(PAT ...)))])
   #'(for ([TEMP SEQ] ...)
  (match-let ([PAT TEMP] ...)
. BODY)))]))

(match-for ([(list i j) '(("a" 1) ("b" 20))])
   (display (list i j)))

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


Re: [racket-users] Racket-on-Chez snapshot builds

2018-11-19 Thread Matthew Butterick


> On Nov 19, 2018, at 2:06 PM, Matthew Flatt  wrote:
> 
> Although Racket-on-Chez is not yet ready to replace the existing
> implementation of Racket for most purposes, it should generally work
> now --- and it might even be useful for some purposes. Many, many
> details have to be right for Racket-on-Chez to assemble itself into a
> snapshot distribution, so this is a significant milestone.

Thank you for the all your effort & hard work to get Racket-on-Chez this far.

This week, I've gone over to using the Racket-on-Chez snapshots exclusively. 
They are stable & fast enough for everything I do with Racket. There are bugs, 
of course, though so far all small. And Matthew has been fixing them as fast as 
I can file them. 

For that matter, if you've ever wondered "what can I do to improve 
Racket-on-Chez, without being a 1337 h4x0r?" I suggest that you also use the 
snapshots and file bugs. Because that will make Racket-on-Chez better, sooner, 
for everyone.

One tip, if you haven't used the snapshots before (I hadn't): I've switched to 
installing my own packages in "--scope user" rather than "--scope 
installation". This keeps the packages out of the snapshot folder, so the 
snapshot can be easily replaced without disturbing the rest. 

To infinity and beyond.

-- 
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] Is there a way to eval a custom language from inside a module... without instantiating modules multiple times?

2018-11-16 Thread Matthew Butterick
You've mentioned that you want to "define a custom language" and evaluate it. 
But so far I don't see any sign that you're using Racket's dedicated facilities 
for doing this (especially `#%module-begin` and `module`). If this is a 
deliberate choice, carry on. If not, consider investigating them, because they 
streamline the very chores you're finding painful.


> On Nov 16, 2018, at 10:43 AM, Andrew Wilcox  wrote:
> 
> What I want to do is rather simple (I hope): define a custom language in a 
> module such as example.rkt, and then be able to eval that language.
> 
> Is there a way to do 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] How to eval a custom language from inside a module?

2018-11-12 Thread Matthew Butterick

> On Nov 12, 2018, at 2:11 PM, Andrew Wilcox  wrote:
> 
> How about providing eval-example from a module?
> 
> ; eval-example.rkt
> #lang racket
> 
> (provide eval-example)
> 
> (define example-namespace (make-base-empty-namespace))
> 
> (parameterize ((current-namespace example-namespace))
>   (namespace-require "example.rkt"))
> 
> (define (eval-example code)
>   (parameterize ((current-namespace example-namespace))
> (eval code)))
> 
> The problem here is that namespace-require is a procedure and so resolves 
> "example.rkt" at run time, not at compile time like require would do.  Thus 
> "example.rkt" is resolved relative to the current working directory of the 
> running program, not relative to the directory containing eval-example.rkt as 
> would happen using a require.


Perhaps you seek a runtime path?

; eval-example.rkt
#lang racket

(provide eval-example)

(require racket/runtime-path)
(define-runtime-path example "example.rkt")

(define example-namespace (make-base-empty-namespace))

(parameterize ((current-namespace example-namespace))
  (namespace-require example))

(define (eval-example code)
  (parameterize ((current-namespace example-namespace))
(eval code)))



-- 
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 make a cartesian supergenerator?

2018-10-21 Thread Matthew Butterick

> On Oct 21, 2018, at 3:49 PM, Jay McCarthy  wrote:
> 
> I think the best strategy would be to convert the generator to a
> sequence and then the sequence to a stream, then write a stream
> cartesian product. The stream will cache the results of the generator.



Nice.



#lang racket 
(require racket/generator rackunit) 

(define (make-cartesian-generator gens)
  (generator ()
 (define gstreams (for/list ([gen (in-list gens)])
  (for/stream ([sol (in-producer gen 
(void))]) 
  sol))) 
 (let loop ([gstreams gstreams][acc empty])
   (if (null? gstreams)
   (yield (reverse acc))
   (for ([arg (in-stream (car gstreams))])
(loop (cdr gstreams) (cons arg acc)))

(define g1 (generator () (yield 1) (yield 2) (void))) 
(define g2 (generator () (yield 'a) (println 'only-prints-once) (yield 'b) 
(void)))

(check-equal? 
 (for/list ([gs (in-producer (make-cartesian-generator (list g1 g2)) (void))]) 
   gs) 
 '((1 a) (1 b) (2 a) (2 b)))

-- 
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 make a cartesian supergenerator?

2018-10-21 Thread Matthew Butterick
I suppose just putting in a hash isn't too bad. 

#lang racket
(require racket/generator rackunit)

(define/contract (make-cartesian-generator gens)
  ((listof generator?) . -> . generator?)
  (generator ()
 (define solcache (make-hasheqv))
 (let loop ([gens gens][genidx 0][sols empty])
   (cond
 [(empty? gens) (yield (reverse sols))]
 [else 
  (match-define (cons gen rest) gens)
  (cond
[(eq? (generator-state gen) 'done)
 (for ([sol (in-list (reverse (hash-ref solcache genidx)))])
   (loop rest (add1 genidx) (cons sol sols)))]
[else
 (for ([sol (in-producer gen (void))])
   (hash-update! solcache genidx (λ (vals) (cons sol vals)) 
null)
   (loop rest (add1 genidx) (cons sol sols)))])]

(define g1 (generator () (yield 1) (yield 2) (void)))
(define g2 (generator () (yield 'a) (yield 'b) (void)))

(check-equal? 
 (for/list ([gs (in-producer (make-cartesian-generator (list g1 g2)) (void))])
   gs)
 '((1 a) (1 b) (2 a) (2 b)))

-- 
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 make a cartesian supergenerator?

2018-10-21 Thread Matthew Butterick
The sample below tries to make a "cartesian supergenerator" that takes several 
smaller generators and combines them into a larger generator that yields 
cartesian combinations of the results.

This works on the first pass (when the result of g1=1). But when the result of 
g1=2, the g2 generator is already spent, and produces no more values.

Of course, it would be possible to precache the results of each generator into 
a list and then combine those cartesian-style. But that would defeat the 
laziness of the evaluation. (Assume the individual generators conduct expensive 
operations.) The ultimate idea is to do as little work as possible, but then 
having done it, avoid repeating it. (This could be the mantra of my entire 
programming career.)



#lang racket
(require racket/generator rackunit)

(define/contract (make-cartesian-generator gens)
  ((listof generator?) . -> . generator?)
  (generator ()
 (let loop ([gens gens][sols empty])
   (cond
 [(empty? gens) (yield (reverse sols))]
 [else (match-define (cons gen rest) gens)
   (for ([sol (in-producer gen (void))])
 (loop rest (cons sol sols)))]

(define g1 (generator () (yield 1) (yield 2) (void)))
(define g2 (generator () (yield 'a) (yield 'b) (void)))

(check-equal? 
 (for/list ([gs (in-producer (make-cartesian-generator (list g1 g2)) (void))])
   gs)
 '((1 a) (1 b) (2 a) (2 b)))

-- 
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] arbitrary currying at run time?

2018-10-12 Thread Matthew Butterick
I know about `curry` and `curryr`, of course. But is there a way to accomplish 
arbitrary currying at run time (not just at the ends of the argument list)? (Or 
is it called partial application?)

Let's suppose we have `f`:

(define f (λ (a b c d) (+ a b c d)))
(f 1 2 3 4) ; 10

And we want to reduce the arity of `f` by supplying 1 as the first arugment and 
3 as the third. Maybe we write this like so:

(define g (reduce-arity f '(1 b 3 d)))

Where the '(1 b 3 d) notation matches the arity of `f`, and denotes "use 1 for 
the first argument, 3 for the third argument, and then leave the other two 
arguments alone." (This is not ideal notation because it precludes the use of 
symbols as applied value, but let's leave that aside.)

So `g` would end up as a 2-arity function:

(define g (λ (b d) (f 1 b 3 d))
(g 2 4) ; 10


I came up with the idea below, but it seems brutal, even by my standards.


#lang racket
(require rackunit)

(define (reduce-arity proc pattern)
  (unless (= (length pattern) (procedure-arity proc))
(raise-argument-error 'reduce-arity (format "list of length ~a, same as 
procedure arity" (procedure-arity proc)) pattern))
  (define reduced-arity-name (string->symbol (format "reduced-arity-~a" 
(object-name proc
  (define-values (id-names vals) (partition symbol? pattern))
  (define new-arity (length id-names))
  (procedure-rename
   (λ xs
 (unless (= (length xs) new-arity)
   (apply raise-arity-error reduced-arity-name new-arity xs))
 (apply proc (for/fold ([acc empty]
[xs xs]
[vals vals]
#:result (reverse acc))
   ([pat-item (in-list pattern)])
   (if (symbol? pat-item)
   (values (cons (car xs) acc) (cdr xs) vals)
   (values (cons (car vals) acc) xs (cdr vals))
   reduced-arity-name))

(define f (λ (a b c d) (+ a b c d)))
(define g (reduce-arity f '(1 b 3 d)))
(check-equal? (f 1 2 3 4) (g 2 4))

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


Re: [racket-users] [Racket Users] Macros and literals question

2018-09-17 Thread Matthew Butterick

> On Sep 17, 2018, at 11:57 AM, Kevin Forchione  wrote:
> 
> In a nutshell I’m working with some hash tables whose keys are symbol and 
> whose values may be other keys or values such as identifiers, and I got a bit 
> tired of quoting all my symbols for functions and decided to use some macros 
> when working with the tables.

OK. Yes, in general you need a macro to convert something like `(id bar)` to 
`(other-id 'bar)`, because otherwise the naked `bar` is treated as an 
identifier (and therefore as usual needs a binding, or the program won't run). 
For even more notational convenience, you might also look at the `read-cdot` 
parameter and `#%dot` identifier, which can expand `table.key` to something 
like `(hash-ref table 'key)`.

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


Re: [racket-users] [Racket Users] Macros and literals question

2018-09-17 Thread Matthew Butterick

> On Sep 17, 2018, at 10:21 AM, Kevin Forchione  wrote:
> 
> That seems to be the nature of macros, and I’m not sure what the solution to 
> that paradox is, apart from perhaps building a symbol/function hash table as 
> part of a define. Presumably Racke does something like that for eva & 
> namespaces, but I’m surprised there isn’t a symbol->procedure function. 


I take a question as I find it, even if its necessity is not clear to me ;) It 
seems a teeny bit possible that you're moving against the grain of how 
identifiers & bindings usually work, and thus certain aspects seem more 
complicated than they need to. 

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


Re: [racket-users] [Racket Users] Macros and literals question

2018-09-16 Thread Matthew Butterick

> On Sep 16, 2018, at 2:13 PM, Kevin Forchione  > wrote:
> 
> Thanks! That’s just what I wanted. Is there a way in Racket to determine if a 
> quoted symbol has an associated procedure? 



#lang racket
(require rackunit)

(define-syntax (bound-to-proc? stx)
  (syntax-case stx ()
[(_ 'x)
 (and (identifier? #'x) (identifier-binding #'x))
 #'(procedure? x)]
[_ #'#f]))

(define bound-to-proc +)
(define not-bound-to-proc 42)

(check-true (bound-to-proc? 'bound-to-proc))
(check-false (bound-to-proc? 'not-bound-to-proc))

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


Re: [racket-users] using `define-runtime-path` inside macros

2018-08-31 Thread Matthew Butterick

> On Aug 31, 2018, at 4:14 PM, Alex Harsanyi  wrote:
> 
> Thanks for this solution, it works.  While I understand what is being done, I 
> do not understand why it is necessary

>From the docs:

"The path is normally computed by taking a relative path result from expr and 
adding it to a path for the enclosing file ... If the expression has no source 
module, the syntax-source location associated with the form is used" [1]

IOW when you wrap `define-runtime-path` in a macro, the "syntax-source location 
associated with the form" becomes that of the macro-definition site. In this 
case, we are overriding this behavior by building the path manually with the 
`syntax-source` we prefer (namely, that of the calling site)


[1] 
http://docs.racket-lang.org/reference/Filesystem.html#(form._((lib._racket%2Fruntime-path..rkt)._define-runtime-path))
 




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


Re: [racket-users] using `define-runtime-path` inside macros

2018-08-31 Thread Matthew Butterick

> On Aug 31, 2018, at 3:25 AM, Alex Harsanyi  wrote:
> 
> Is there a way to write this macro such that the runtime path is defined
> relative to the location of the file that uses `define-sql-statement`?


One option, using `syntax-source` to get the starting directory:


#lang racket
(require racket/runtime-path db (for-syntax racket/base))

(define-syntax (define-sql-statement stx)
  (syntax-case stx ()
[(_ name path)
 (let-values ([(dir fn _) (split-path (syntax-source stx))])
   (with-syntax ([dir (or dir 'same)])
 #'(begin
 (define-runtime-path rpath (build-path dir path))
 (define name
   (let ([vq #f])
 (lambda ()
   (unless vq
 (let ([s (call-with-input-file rpath port->string)])
   (set! vq (virtual-statement (lambda (_) s)
   vq))]))

(provide define-sql-statement)

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


Re: [racket-users] why do these port ops behave differently?

2018-08-26 Thread Matthew Butterick

> On Aug 26, 2018, at 6:48 PM, Philip McGrath  wrote:
> 
> `read-syntax` has two optional arguments: `(test read-syntax)` is effectively 
> calling `(read-syntax (open-input-string "str"))`, which is equivalent to 
> `(read-syntax (open-input-string "str") (current-input-port))`.



Yes of course. Sorry, temporarily lost my mind.

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


Re: [racket-users] Racket koans module language bug

2018-08-26 Thread Matthew Butterick

> On Aug 26, 2018, at 5:15 PM, Sage Gerard  wrote:
> 
> The intent is to reject code with blanks, and to treat code without blanks as 
> Racket code that still might not compile


There's more than one way to go about it, of course. It could be simpler to 
make a wrapper around the usual `read-syntax` and inspect the individual syntax 
objects as they pass by:


;; "racket-koans-lang.rkt"

#lang racket
(require syntax/strip-context rackunit)
(provide #%module-begin (except-out (all-from-out racket) read-syntax)
 (rename-out [koan-read-syntax read-syntax])
 (all-from-out rackunit))

(define (koan-read-syntax path ip)
  (define stxs (parameterize ([current-input-port ip])
 (for/list ([stx (in-port read-syntax)])
   (when (memq '_ (flatten (syntax->datum stx)))
 (raise-syntax-error 'koans "blanks detected" stx))
   stx)))
  (strip-context
   (with-syntax ([(STX ...) stxs])
 #'(module _ "racket-koans-lang.rkt"
 STX ...

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


[racket-users] why do these port ops behave differently?

2018-08-26 Thread Matthew Butterick
With `read`, both `for/list` expressions evaluate the same way.

With `read-syntax`, the first `for/list` works as expected, but the second 
doesn't: it ignores the port argument and waits for something to happen on 
standard input.

;;;

#lang racket
(require rackunit)

(define str "42 foo \"bar\"")

(define (test proc)  
  (check-equal?
   (parameterize ([current-input-port (open-input-string str)])
 (for/list ([stx (in-port proc)])
   stx))
   (for/list ([stx (in-port proc (open-input-string str))])
 stx)))

(test read)
(test read-syntax)

-- 
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] Do I need macros to flag unbound identifiers as failing unit tests?

2018-08-11 Thread Matthew Butterick

> On Aug 11, 2018, at 9:00 AM, Sage Gerard  wrote:
> 
> I'm starting to think writing these kind of exercises in a friendly way is 
> only possible with macros, but before I go that far, is it possible for me to 
> catch a module-level unbound identifier error and print a rackunit failure 
> outright without distracting the student?
> 
> I'd appreciate feedback on the design here too, since I have to pick a 
> direction to handle this kind of problem project-wide.

Perhaps consider making a little `racket/koan` language for your exercises that 
includes some extra conveniences. For instance, one way to address your unbound 
identifiers is to redefine `#%top` as shown below. But you could move that into 
`racket/koan`.


#lang racket/base

(require rackunit)

(require (for-syntax racket/base))
(define-syntax (#%top stx)
  (syntax-case stx ()
[(_ . id) (not (identifier-binding #'id)) #'(λ _ (format "unbound 
identifier: ~a" 'id))]
[(_ . id) #'id]))

;; Produce a single struct that passes all assertions.
(let ([p "?"])
  (check-pred racketeer? p)
  (check-pred programmer? p)
  (check-pred struct? p)
  (check-pred procedure? set-programmer-salary!)
  (check-equal? (programmer-confusion-level p) 10)
  (check-equal? (racketeer-desire-for-racket-jobs p) 9001))

-- 
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] Announcing Event-lang

2018-05-22 Thread Matthew Butterick
I'm sure I'm not the only one who would like to see these (and other examples 
you have handy) added to your `event-lang` docs.


> On May 22, 2018, at 7:29 AM, Eric Griffis  wrote:
> 
> Here's a variety of small examples.

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


[racket-users] why doesn't this macro produce an "identifier already defined" error?

2018-05-21 Thread Matthew Butterick
I must be missing something obvious. But I've developed short-term macro 
blindness.

The idea is that the `foo` identifier is packaged into the call to `submac` as 
a syntax property.

When I retrieve this property from inside `mac`, it returns the expected 
'module-foo value.

But when I retrieve this property from inside `submac`, it creates a new 
nonconflicting variable. This confuses me: what I expect is that `submac` 
should try to bind the same identifier, producing an error.




#lang racket

(define foo 'module-foo)

(define-syntax (mac stx)
  (syntax-case stx ()
[(_ SUBMAC)
 (with-syntax ([SUBMAC (syntax-property #'SUBMAC 'foo-id #'foo)])
   #`(begin (displayln (format "module foo = ~a" #,(syntax-property 
#'SUBMAC 'foo-id)))
SUBMAC))]))

(define-syntax (submac stx)
  (syntax-case stx ()
[(_)
 (with-syntax ([FOO-ID (syntax-property stx 'foo-id)])
   #`(begin
   (define FOO-ID 'submac-foo)
   (displayln (format "submac foo = ~a" FOO-ID]))

(mac (submac)) ; why not an "identifier already defined" error?

-- 
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 handle circular 'requires'

2018-05-14 Thread Matthew Butterick
To add to your pile of options, because you said "certain error conditions": 
perhaps you might `raise` an exception in the db code that gets caught by the 
network code (using `with-handlers`). In this way the dependency only runs one 
direction (network module imports db module) but the db module can still 
propagate messages to the network module (by going "backward" through the 
existing calling chain with an exception, rather than "forward" by calling into 
the db module). 

Here is a toy example of a `db` module that keeps kicking back an exception to 
a `network` module until it gets zero, no circularity needed:

#lang racket

(module db racket
  (provide f)
  (define (f val)
(if (zero? val)
'finally-a-zero!
(raise val

(module network racket
  (require (submod ".." db))
  (let loop ([maybe-err-int #f])
(with-handlers ([integer? loop])
  (when maybe-err-int
(displayln (number->string maybe-err-int)))
  (f (random 10)

(require 'network)


> On May 14, 2018, at 10:28 AM, David Storrs  wrote:
> 
> This worked fine until now, but I've gotten to a point where they're
> circular -- the network code needs to receive the chunk and then
> forward it to the DB code, but if certain error conditions come up
> then the DB code needs to tell the network code to re-request the
> data.
> 
> There's various ways I could work around this (simplest being to put
> all the functions in one file), but I'm wondering if there's a
> recommended way?  C would solve this with a .h file.  Perl would solve
> it with function prototypes (or simply be able to sort it out without
> intervention).  What is the preferred Racket way, or am I simply not
> thinking about it correctly?

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


  1   2   3   4   >