Re: [racket-users] package manager woes on Windows 10?

2020-09-10 Thread Philip McGrath
Also, this is happening over encrypted HTTPS: no one is sniffing the
User-Agent header.

My initial attempt to reproduce in the GUI package manager was foiled
because I’d first tried installing at the command line, and the package
manager used a cached copy of the repository. From Shriram’s update
last night, it sounds like the GUI package manager and “raco pkg” are doing
something differently.


-- 
-Philip

-- 
You received this message because you are subscribed to the Google 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/010001747856d1f6-1ebee798-1b06-4633-a897-13e206024129-00%40email.amazonses.com.


Re: [racket-users] locally linked package name doesn't match info collection name

2020-09-09 Thread Philip McGrath
There was a `pkg-name` info.rkt item added in 20672cd
,
but it only seems to be used by `make-dirs-catalog`
.
Maybe it should also be used by "raco pkg install" unless "--name" is given
explicitly?

-Philip


On Wed, Sep 9, 2020 at 9:09 PM Shriram Krishnamurthi 
wrote:

> I'm curious why the Package Manager doesn't also show the collection name
> (or plural)? Wouldn't I need that to trace backwards? "This program in
> #lang foo is behaving oddly, I wonder what foo's source is" — find the
> collection in the PM, trace back to the package, locate the source…?
>
> --
> You received this message because you are subscribed to the Google 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/CAJUf2yQqHiryeTsn8Az2PqWPbXV2YwLxGxtNPK_UEVJyGPcJpw%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/01000174759e0aa8-b30af989-9083-4f74-be9d-d07bc303e11c-00%40email.amazonses.com.


Re: [racket-users] Why is struct/contract so much faster than a guard?

2020-09-02 Thread Philip McGrath
On Wed, Sep 2, 2020 at 3:41 PM Christopher Lemmer Webber <
cweb...@dustycloud.org> wrote:

> Unfortunately I can't use #:methods with struct/contract so I'm stuck
> with the slow one if I want a contract on the struct?
>

For another option (though you may already know this), I'd advocate for
using the `struct` sub-form of `contract-out` and drawing the module
boundary as tightly as needed to make it a sensible boundary for trust,
potentially by using submodules.

Since you mention `#:methods` in particular, you should be aware of some
subtle corners that make it tricky (and potentially expensive at runtime)
to protect  `racket/generic` methods comprehensively with contracts. (Here's
a pointer to some discussions.
) I think just working with
struct-type properties can make sense when you don't really need most of
the features `racket/generic` gives you.

-Philip

-- 
You received this message because you are subscribed to the Google 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/0100017450ed66ea-e1b5b7a3-11cf-416b-bcab-dc314bc692b2-00%40email.amazonses.com.


Re: [racket-users] abstraction suggestion?

2020-08-31 Thread Philip McGrath
In addition (or instead, if this is good enough and less painful), you
could use a compile-time helper function like:

(define-for-syntax (make-mb+ti namespaces-stx
   lang-print-names-stx)
  (define-syntax-class to-run
#:attributes (parsed)
#:literals (TEST)
(pattern (TEST e r ...)
 #:with parsed
 #`(test-output 'e (list 'r ...) #,namespaces-stx))
(pattern e
 #:with parsed
 #`(show-output 'e #,namespaces-stx #,lang-print-names-stx)))
  (values (syntax-parser
#:track-literals
[(_ :to-run ...)
 #'(#%printing-module-begin parsed ...)])
  (syntax-parser
#:track-literals
[(_ . :to-run)
 #'(#%top-interaction . parsed)])))

-Philip


On Mon, Aug 31, 2020 at 1:39 PM Shriram Krishnamurthi 
wrote:

> Oooh, that's pretty clever! A bit painful, but clever!
>
> On Mon, Aug 31, 2020 at 1:32 PM Philip McGrath 
> wrote:
>
>> There might be a better way, but I'd probably make a language for writing
>> this kind of module, in the spirit of `#lang syntax/module-reader`, where
>> its `#%module-begin` would expect the module body to be `> THAT CHANGES>`, similar to the way that the body of `(module reader
>> syntax/module-reader my-language-implementation-module)` is a module name.
>>
>> -Philip
>>
>>
>> On Mon, Aug 31, 2020 at 1:24 PM Hendrik Boom 
>> wrote:
>>
>>> On Mon, Aug 31, 2020 at 10:06:42AM -0700, Shriram Krishnamurthi wrote:
>>> > I'm having some trouble abstracting over this code. Any suggestions?
>>> >
>>> > I have numerous files that follow this boilerplate:
>>> >
>>> > #lang racket
>>> >
>>> > (require )
>>> >
>>> > (provide (rename-out [mod-begin #%module-begin]
>>> >  [ti#%top-interaction]))
>>> >
>>> > (define-values (namespaces lang-print-names)
>>> >   )
>>> >
>>> > (define-syntax (multi-runner stx)
>>> >   (syntax-case stx (TEST)
>>> > [(_ (TEST e r ...))
>>> >  #`(test-output 'e (list 'r ...) namespaces)]
>>> > [(_ e)
>>> >  #`(show-output 'e namespaces lang-print-names)]))
>>> >
>>> > (define-syntax mod-begin
>>> >   (λ (stx)
>>> > (syntax-case stx ()
>>> >   [(_ b ...)
>>> >#'(#%printing-module-begin (multi-runner b) ...)])))
>>> >
>>> > (define-syntax ti
>>> >   (λ (stx)
>>> > (syntax-case stx ()
>>> >   ([_ . e]
>>> >#'(#%top-interaction . (multi-runner e))
>>> >
>>> > I've abstract most of the details into `test-output` and `show-output`
>>> into
>>> > . I would ideally like to move as much of what's left as
>>> > possible into the same file.
>>> >
>>> > The key problem is that the MB and TI depend on `multi-runner`, which
>>> in
>>> > turn depends on `namespaces`, which is a name at run time. As long as
>>> > everything is in the same module, no problem. But when I start to move
>>> the
>>> > boilerplate out…
>>> >
>>> > Concrete suggestions welcome — I've tried several different things
>>> (various
>>> > forms of abstraction, syntax parameters, etc.) without luck.
>>>
>>> Maybe a macro or two?  Perhaps a nonhygienic one?
>>>
>>> -- hendrik
>>>
>>> >
>>> > Thanks,
>>> > Shriram
>>> >
>>> > --
>>> > You received this message because you are subscribed to the Google
>>> 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/362f807e-3561-4be6-8b4d-937776fea36bn%40googlegroups.com
>>> .
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Racket Users" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to racket-users+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/racket-users/20200831172435.6f6oweyhxjux4g5j%40topoi.pooq.com
>>> .
>>>
>> --
>> You received 

Re: [racket-users] abstraction suggestion?

2020-08-31 Thread Philip McGrath
There might be a better way, but I'd probably make a language for writing
this kind of module, in the spirit of `#lang syntax/module-reader`, where
its `#%module-begin` would expect the module body to be ``, similar to the way that the body of `(module reader
syntax/module-reader my-language-implementation-module)` is a module name.

-Philip


On Mon, Aug 31, 2020 at 1:24 PM Hendrik Boom  wrote:

> On Mon, Aug 31, 2020 at 10:06:42AM -0700, Shriram Krishnamurthi wrote:
> > I'm having some trouble abstracting over this code. Any suggestions?
> >
> > I have numerous files that follow this boilerplate:
> >
> > #lang racket
> >
> > (require )
> >
> > (provide (rename-out [mod-begin #%module-begin]
> >  [ti#%top-interaction]))
> >
> > (define-values (namespaces lang-print-names)
> >   )
> >
> > (define-syntax (multi-runner stx)
> >   (syntax-case stx (TEST)
> > [(_ (TEST e r ...))
> >  #`(test-output 'e (list 'r ...) namespaces)]
> > [(_ e)
> >  #`(show-output 'e namespaces lang-print-names)]))
> >
> > (define-syntax mod-begin
> >   (λ (stx)
> > (syntax-case stx ()
> >   [(_ b ...)
> >#'(#%printing-module-begin (multi-runner b) ...)])))
> >
> > (define-syntax ti
> >   (λ (stx)
> > (syntax-case stx ()
> >   ([_ . e]
> >#'(#%top-interaction . (multi-runner e))
> >
> > I've abstract most of the details into `test-output` and `show-output`
> into
> > . I would ideally like to move as much of what's left as
> > possible into the same file.
> >
> > The key problem is that the MB and TI depend on `multi-runner`, which in
> > turn depends on `namespaces`, which is a name at run time. As long as
> > everything is in the same module, no problem. But when I start to move
> the
> > boilerplate out…
> >
> > Concrete suggestions welcome — I've tried several different things
> (various
> > forms of abstraction, syntax parameters, etc.) without luck.
>
> Maybe a macro or two?  Perhaps a nonhygienic one?
>
> -- hendrik
>
> >
> > Thanks,
> > Shriram
> >
> > --
> > You received this message because you are subscribed to the Google
> 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/362f807e-3561-4be6-8b4d-937776fea36bn%40googlegroups.com
> .
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/20200831172435.6f6oweyhxjux4g5j%40topoi.pooq.com
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/010001744593f3c3-1bc786d7-6d32-4e00-ab62-7d3ad7a42359-00%40email.amazonses.com.


Re: [racket-users] lsp server

2020-08-16 Thread Philip McGrath
On Fri, Jul 31, 2020 at 2:46 PM Catonano  wrote:

> I'm playing with a toy project in #Racket
> 
>
I'd like to use the lsp server…
>
how do I connect to it from my Emacs based client ?
>

Just in case by "use the lsp server" you meant "set up Emacs to work on a
Racket project" (rather than working *on* the lsp server or client), the
generally preferred way to edit Racket in Emacs is with Greg Hendershott's
Racket Mode (actually a package with a few major and minor modes):
https://www.racket-mode.com

-Philip

-- 
You received this message because you are subscribed to the Google 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/01000173f78714a6-5170a43f-d553-407e-89e8-db6db26d911e-00%40email.amazonses.com.


Re: [racket-users] Advice wanted about new opengl binding

2020-08-03 Thread Philip McGrath
Is this what you're looking for? https://pkgs.racket-lang.org/package/sgl

-Philip


On Sun, Aug 2, 2020 at 5:51 PM Hendrik Boom  wrote:

> Time to rethink everything before I go further.
>
> So far I've found several opengl bindings.
> There's opengl, documented here:
>https://docs.racket-lang.org/opengl/index.html
> There are sgl and sgl/gl, documented here:
>https://docs.racket-lang.org/sgl/index.html
> and there's a typed opengl hidden with in pict3.
>
> But I cannot find sgl and sgl/gl in the index of packages
> at https://pkgs.racket-lang.org/
>
> Shouldn't they be there?
> Are they there in disguise?
> Abd where should I look for current source code?
> The index is pretty good at identifying source code for other packages.
>
> -- hendrik
>
> --
> You received this message because you are subscribed to the Google 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/20200802215123.iiqik4wpfusarcw4%40topoi.pooq.com
> .
>

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


Re: [racket-users] pictures in code?

2020-08-03 Thread Philip McGrath
On Mon, Aug 3, 2020 at 9:47 AM Hendrik Boom  wrote:

> On Sun, Aug 02, 2020 at 08:58:54PM -0700, Sorawee Porncharoenwase wrote:
> > For DrRacket, it's possible via "Insert > Insert Image". It's been used
> in
> > HtDP. See https://htdp.org/2020-8-1/Book/part_prologue.html
>
> Now that's presumably something that works nicely in the DrRacket editor.
> When DrRacket saves it into a file, it presumably uses some notation that
> won't look like a picture in, say, emacs.
>

Yes, that's all correct. My knowledge isn't very deep here, but to answer
the questions you asked:


> But will it still be recognised as an image if I use Racket to run that
> file?
>

Yes. The only difference is that the default printer (for example) doesn't
know how to print pictures, so you will see some output like:
philip$ racket image-literal.rkt
(object:image% ... ...)
when DrRacket would actually print the image. In principle, this is just
like DrRacket's ability to print `1/3` using barred decimal notation.

Can the image be used as a symbol or a constant or is it some other type
> of object?
>

The idea, as I understand it, is that an image is a self-quoting literal
datum like `42`, `"foo`", `#false`, or `#px"\\d+"`.

What kind of a datum is it? Alexis has explained in your other thread why
that's a difficult question.

Practically, I know that image literals answer `#true` to `image?` from the
`2htdp/image `
library. That's the only way I can remember having worked with them, but I
know they are also some other kinds of things: for example, an image
literal is an instance of (a subclass of) `snip%
` from `racket/gui`.

How is this implemented? My vague understanding is that there's some deep
magic baked into `racket/gui` to support image literals, I think around
`mrlib/image-core` and `mrlib/image-core-wxme`. I know there are some
limitations to this approach (though I don't immediately remember what all
of them are), and there have been some discussions about more general
mechanism for languages to support new kinds of literal data. The most
in-depth work I know of is from Lief's `#lang video `,
where she's experimenting with non-linear video editor literals

.

 Hope this helps.

-Philip

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gYs1L8Zgiapino%3DRVj3%3DX%3DmYm%3DJ_4c50KMDjESmrYC%2Brg%40mail.gmail.com.


Re: [racket-users] Working out which directory the current code was loaded from?

2020-07-27 Thread Philip McGrath
For this particular purpose, you want `define-runtime-path`:
https://docs.racket-lang.org/reference/Filesystem.html#%28part._runtime-path%29

-Philip


On Mon, Jul 27, 2020 at 9:38 PM Peter W A Wood 
wrote:

> I have a short racket program/script that reads a file from the directory
> in which it is stored. The directory structure is something like this:
>
> a/
> b/
> c/
> my-racket.rkt
> my-data-file.txt
>
> I want to be able to run the program from the command line no matter what
> is the current working directory. E.G.:
>
> a> racket b/c/my-racket.rkt
> a/b> racket c/my-racket.rkt
> a/b/c> racket my-racket.rkt
>
> In order to do so, I need to provide the correct path to my-data-file.txt
> depending on from where the script was launched. I haven’t learnt about
> Racket modules yet so I resorted to searching Stack Overflow. I found a
> code snippet that I used which worked:
>
> (define script-dir (path-only (resolved-module-path-name
>   (variable-reference->resolved-module-path
>(#%variable-reference)
>
> Is this the best way to ascertain the directory of the “current module”?
>
> Thanks in advance
>
> Peter
>
>
> --
> You received this message because you are subscribed to the Google 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/92DACE01-60C8-445A-A07E-A4E6A6F5F684%40gmail.com
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAH3z3ga%2B4Lhvg8%3DitgW_aLZ%2B-RbdN%2BAZuPPPeYukD3qRYuPiBw%40mail.gmail.com.


Re: [racket-users] Are Regular Expression classes Unicode aware?

2020-07-09 Thread Philip McGrath
On Thu, Jul 9, 2020 at 10:32 AM Sorawee Porncharoenwase <
sorawee.pw...@gmail.com> wrote:

> Racket REPL doesn’t handle unicode well. If you try (regexp-match?
> #px"^[a-zA-Z]+$" "héllo") in DrRacket, or write it as a program in a file
> and run it, you will find that it does evaluate to #f.
>
See this issue for workarounds, including installing the `readline-gpl`
package: https://github.com/racket/racket/issues/3223

But you may have some other issues: for me, `(regexp-match?
#px"^[a-zA-Z]+$" "h\U+FFC3\U+FFA9llo")` gives an error saying "read-syntax:
no hex digit following `\U`"

For the original question:


> On Thu, Jul 9, 2020 at 7:19 AM Peter W A Wood 
> wrote:
>
>> I was experimenting with regular expressions to try to emulate the Python
>> isalpha() String method.
>>
>
You'd want to benchmark, but, for this purpose, I have a hunch you might
get better performance by using `in-string` with a `for/and` loop (which
can use unsafe operations internally)—probably especially so if you were
content to just test `char-alphabetic?`, which follows Unicode's definition
of "alphabetic" rather that Python's idiosyncratic one. Here's an example:

#lang racket
>
> (module+ test
>   (require rackunit))
>
> (define (char-letter? ch)
>   ;; not the same as `char-alphabetic?`: see
>   ;; https://docs.python.org/3/library/stdtypes.html#str.isalpha
>   (case (char-general-category ch)
> [(lm lt lu ll lo) #t]
> [else #f]))
>
> (define (string-is-alpha? str)
>   (for/and ([ch (in-string str)])
> (char-letter? ch)))
>
> (module+ test
>   (check-true (string-is-alpha? "hello"))
>   (check-false (string-is-alpha? "h1llo"))
>   (check-true (string-is-alpha? "héllo")))
>

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gYfZqGe5hQheAsSxdX8VzAsGYhi61W5ZpmMkkaRb0F%2B5A%40mail.gmail.com.


Re: [racket-users] Re: Andy Wingo's fold

2020-06-25 Thread Philip McGrath
On Sun, Jun 14, 2020 at 2:20 PM Catonano  wrote:

> I'm referring to a paper titled: "A better XML parser through functional
> programming"
>
> by Oleg Kiselyov
>

Ah, I see. I'm not deeply familiar with it myself (I mostly use Racket's
`xml` library), but there is a Racket port of Oleg's SSAX, and the source
code includes extensive comments.

Code: https://github.com/jbclements/sxml
Package documentation (limited): https://docs.racket-lang.org/sxml/

Oleg's website also has some links, though some are broken:
http://okmij.org/ftp/Scheme/xml.html#XML-parser

Hope this helps!

-Philip

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gYHHJ7NHr4%3DNmUBOWHEU6skgBYac3n78OVHn%2BVuB%3D74YQ%40mail.gmail.com.


Re: [racket-users] Re: Andy Wingo's fold

2020-06-12 Thread Philip McGrath
On Fri, Jun 12, 2020 at 2:46 AM Catonano  wrote:

> the original paper Andy Wingo refers to uses Haskell to express this
> operator and I can't read Haskell and I'm not willing to learn
>

I'm confused about what you mean: in the version of "Applications of Fold
to XML Transformation", on Andy Wingo's blog
, all of the
examples are in Scheme. Here is a version of the example from the paper
that will run in Racket—most of the code is just copied and pasted from the
figures:

#lang racket

;; Source: https://wingolog.org/pub/fold-and-xml-transformation.pdf

(module+ test
  (require rackunit)
  (check-equal?
   (cartouche->svg
;; figure 16
'(cartouche (@ (line-color "red")
   (text-height 56))
(para "Warning: Smoking Kills")))
   ;; figure 17
   '(g (rect (@ (fill "none") (stroke "red")
(stroke-width "4")
(width "660") (height "120.0")
(x "0") (y "0")
(ry "20")))
   (text (@ (xml:space "preserve")
(font-size "56")
(font-family "Georgia")
(x "32")
(y "88"))
 (tspan (@ (x "32") (y "88"))
"Warning: Smoking Kills")

;;
-
;;
-

;; for Racket compatibility

(define (atom? v)
  (not (pair? v)))

(struct layout (x y)
  #:constructor-name make-layout
  #:transparent)

;; p. 7
;;   "Figure 20 uses without definition the macro let-params,
;;which binds lexical variables from the parameters list."
;; p. 6
;;   "... representing parameters as a list of association lists.
;;At each descent into a new SXML node, we cons the new parameters
;;onto the list. Lookup proceeds left-to-right in the parameters list,
;;stopping at the first alist in which a parameter is found."
(require syntax/parse/define)
(define-simple-macro (let-params params:expr (name:id ...)
 body:expr ...+)
  (let ([the-params params])
(let ([name (params-ref the-params 'name)]
  ...)
  body ...)))
(define (params-ref params name)
  (or (for*/first ([alist (in-list params)]
   [pr (in-list alist)]
   #:when (eq? name (car pr)))
(cadr pr))
  (raise-argument-error 'params-ref "no binding found for parameter"
"name" name
"params" params)))

;;
-
;;
-


;; figure 7 (part)
(define (assq-ref alist key default)
  (cond ((assq key alist) => cdr)
(else default)))

;; figure 11
(define (fold-values proc list . seeds)
  (if (null? list)
  (apply values seeds)
  (call-with-values
   (lambda ()
 (apply proc (car list) seeds))
   (lambda seeds
 (apply fold-values proc (cdr list)
seeds)

;; figure 12
(define (foldts*-values fdown fup fhere
tree . seeds)
  (if (atom? tree)
  (apply fhere tree seeds)
  (call-with-values
   (lambda () (apply fdown tree seeds))
   (lambda (tree . kseeds)
 (call-with-values
  (lambda ()
(apply fold-values
   (lambda (tree . seeds)
 (apply foldts*-values
fdown fup fhere
tree seeds))
   tree kseeds))
  (lambda kseeds
(apply fup tree
   (append seeds kseeds

;; figure 13, but with fdown replaced by figure 14
(define (post-order bindings tree)
  (define (err . args)
(error "no binding available" args))
  (define (fdown tree bindings pcont ret)
(let ((tail (assq-ref bindings (car tree)
  #f)))
  (cond
((not tail)
 (let ((default (assq-ref bindings
  '*default* err)))
   (values tree bindings default '(
((pair? tail)
 (let ((cont (cdr tail)))
   (case (car tail)
 ((*preorder*)
  (values '() bindings
  (lambda x (reverse x))
  (apply cont tree)))
 ((*macro*)
  (fdown (apply cont tree) bindings
 pcont ret))
 (else
  (let ((new-bindings (append (car tail)
  bindings)))
(values tree new-bindings cont
'()))
(else
 (values tree bindings tail '())
  (define (fup tree bindings cont ret
   kbindings kcont kret)
(values bindings cont
(cons (apply kcont (reverse kret))
  

Re: [racket-users] syntax woe with typed Racket 'let'

2020-06-02 Thread Philip McGrath
On Mon, Jun 1, 2020 at 3:48 PM Sam Tobin-Hochstadt 
wrote:

> (define (f [x : Number] . [y : String *]) : Number (+ x (length y)))
>

 Another way to write this, which I often prefer, is:

> (: f (-> Number String * Number))
> (define (f x . y)
>   (+ x (length y)))
>

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gZqMU8FGcCi6g165QhYsagjSoxkJS%2BXm%2BRi6Lpr2fbN7Q%40mail.gmail.com.


Re: [racket-users] Re: Is it possible to make submodules with private names?

2020-05-23 Thread Philip McGrath
On Sat, May 23, 2020 at 5:04 PM Simon Schlee  wrote:

> I also would find it interesting to have something functor like, in the
> sense of being able to create parameterized module instances.
> My guess is that constructs like that are difficult to optimize and the
> separation between runtime and compile time can become extremely blurry.
> To the point that certain dynamic constructs would cause big chunks of
> code to become ready for compiling at run-time only and at that time an
> interpreter might be faster.
>

In fact, Racket has such a construct, units
. They are first-class
values, with run-time operations to link and invoke them, and they allowing
for cyclic dependencies and multiple instantiations of a given unit.

One of the major design goals of units was support for separate compilation
(units predate `module` in Racket), which may rule them out for Nia's goal
of modules with "optional *compile-time* arguments" per se.

I guess I'm interested in what sorts of things these optional arguments
might be used for: if dealing with the arguments could instead be done at
link- or invoke-time, you might be able to use units to implement this
module system. Regardless, I recommend anyone thinking about implementing a
unit-like system look closely at units first: even when I ultimately ended
up implementing my own unit-like system to meet a specific need (this was
part of my RacketCon talk), my experience with units was very valuable in
doing so.

-Philip

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gY4e%2BsvAQhHrtj21%3DJ2-%2B6GvVDhPpMY0PkiqbjzaNjOsQ%40mail.gmail.com.


Re: [racket-users] trickiness about the order of definitions in GUI code

2020-05-06 Thread Philip McGrath
On Wed, May 6, 2020 at 8:49 PM Jon Zeppieri  wrote:

> It's a bit trickier to define these things in separate files, because
> their definitions refer to each other (though indirectly in this
> case), and the module system does not tolerate cyclic dependencies.
> The most straightforward way to break the cycle would be to take
> advantage of the fact that `table3` and `info-menu-item` each depends
> on `row-edit-menu`, and `info-menu-item` further depends on `table3`,
> but `row-edit-menu` doesn't depend on either. So the dependencies
> aren't really cyclical.
>

When possible, finding ways to avoid cyclic dependencies in the first place
is definitely advisable: even if you can get Racket to understand them,
mere human beings may find them confusing.

But sometimes there really are entanglements between units of code that you
want to logically separate: then, as Alex said, you need an indirection.
For a relatively simple case, a simple solution using familiar constructs
(like `lambda`) is the right choice, but complicated cycles seem to turn up
especially often in complicated, large-scale code.

Rather than designing an ad hoc system of indirection that can handle all
of the complexity,* I suggest using the one that already exists: units
, Racket's original,
first-class (rather than first-order) module system, offer support for
cyclic dependencies. In fact, they are used in the implementation of
Racket's GUI framework to address precisely this problem.

For this example it ends up being a bit contrived (I would probably use
`class` to define a `row-edit-menu%` that takes a table as an
initialization argument), but here's a way of writing it in a single file
using units: I've posted a Gist

showing the division into multiple files, which is straight-forward.

#lang racket/gui
>
> (require qresults-list)
>
> ;; A signatures describes an interface.
>
> (define-signature row-edit-menu^
>   (row-edit-menu))
>
> (define-signature table3^
>   (table3))
>
> (define-signature frame3^ extends table3^
>   (frame3))
>
> ;; A unit that exports a signature must
> ;; implement the definitions it specifies.
>
> ;; Units can also import signatures,
> ;; which allows the body of the unit to
> ;; refer to definitions from the imported signatures.
> ;; Before the unit is invoked,
> ;; it must be linked together with other units
> ;; that that export the signatures it imports,
> ;; which will suply the actual implementations.
>
> ;; Code in the body of the unit is run when the unit is invoked.
>
> (define-unit row-edit-menu@
>   (import table3^)
>   (export row-edit-menu^)
>
>   (define row-edit-menu
> (new popup-menu%))
>
>   (define info-menu-item
> (new menu-item%
>  [label "info"]
>  [parent row-edit-menu]
>  [callback
>   (λ (menu-item event)
> (define num-selected
>   (length (send table3 get-selected-row-indexes)))
> (message-box "Info"
>  (~a "You have selected " num-selected " rows")
>  #f))])))
>
>
> (define-unit table3@
>   (import row-edit-menu^)
>   (export frame3^)
>
>   (init-depend row-edit-menu^)
>
>   (define frame3
> (new frame%
>  [label "myTable 3"]
>  [width 800]
>  [height 600]))
>
>   (define table3
> (new (class qresults-list%
>(super-new))
>  [parent frame3]
>  [pref-tag 'preferences-tag]
>  [selection-type 'multiple]
>  [right-click-menu row-edit-menu])))
>
>
> ;; Invoke the units and introduce the definitions they
> ;; export into this scope:
>
> (define-values/invoke-unit/infer
>   (link row-edit-menu@
> table3@))
>
> ;; Run the demo:
>
> (send table3
>   setup-column-defs
>   (let ([column1
>  (λ (data) (vector-ref data 0))]
> [column2
>  (λ (data) (vector-ref data 1))])
> (list (qcolumn "Column1" column1 column1)
>   (qcolumn "Column2"
>(λ (row)
>  ;; allows a cell to be blank
>  (if (number? (column2 row))
>  (number->string (column2 row))
>  ""))
>column2
>
> (send table3 add-row (vector "R1C1" 10))
> (send table3 add-row (vector "R2C1" 11))
> (send table3 add-row (vector "R3C1" 12))
> (send table3 add-row (vector "R4C1" 13))
>
> (send frame3 show #t)
>

* Even when specific requirements eventually led me to implement my own
system, as I discussed a bit in my RacketCon talk, it helped to have used
units and looked at a bit of their implementation. I still do use units in
other parts of the Digital Ricoeur codebase.

-Philip

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

Re: [racket-users] Matching groups of optional elements

2020-05-04 Thread Philip McGrath
Depending on your requirements, I would consider using `syntax-parse` at
runtime: this is easily written with its `~seq` patterns, and you get nicer
error reporting.

Here's an example—I use syntax classes for clarity, but they aren't
necessary, if you prefer to be more concise:

#lang racket

(require syntax/parse
 rackunit)

(define-splicing-syntax-class person-cols
  (pattern (~seq "Name" "Age" "First" "Last")))

(define-syntax-class csv-header
  (pattern ("RequiredA" "RequiredB" person:person-cols ...)))

(define valid-header?
  (syntax-parser
[:csv-header
 #t]
[_
 #f]))

;; legal column arrangements:
(check-true
 (valid-header? #'("RequiredA" "RequiredB")))
(check-true
 (valid-header? #'("RequiredA" "RequiredB" "Name" "Age" "First" "Last")))
(check-true
 (valid-header?
  #'("RequiredA" "RequiredB" "Name" "Age" "First" "Last" "Name" "Age"
"First" "Last")))

;; illegal:  if an optional group is present, it must have all 4 columns
(check-false
 (valid-header?
  #'("RequiredA" "RequiredB" "Name" "Age" "First" "Last" "Name")))


On Mon, May 4, 2020 at 10:39 PM Michael MacLeod 
wrote:

> I'm not sure this is possible with only using `match` patterns. A
> combination of the `list-rest` and `app` patterns as well as the `in-slice`
> procedure from `racket/sequence` should do the trick, though:
>
> #lang racket
>
> (require racket/match)
>
> (define (collect-optional-vals x)
>   (for/list ([y (in-slice 4 x)])
> y))
>
> (match '(req-a req-b name1 age1 first1 last1 name2 age2 first2 last2)
>   [(list-rest req-a req-b (app collect-optional-vals optional-vals))
>(list req-a req-b optional-vals)])
>
> On Mon, May 4, 2020 at 7:16 PM David Storrs 
> wrote:
>
>> I'm trying to write a parser for a CSV file with optional columns.
>> Simplified version:  There are 2 mandatory columns, after which there can
>> be 0+ 4-column groups describing a person.  Each group has the same column
>> headers.
>>
>> ; legal column arrangements:
>> RequiredA RequiredB
>> RequiredA RequiredB Name Age First Last
>> RequiredA RequiredB Name Age First Last Name Age First Last
>>
>>
>> ; illegal:  if an optional group is present, it must have all 4 columns
>> RequiredA RequiredB Name Age First Last Name
>>
>> I thought I could do this straightforwardly with `match`, but I'm wrong.
>> Can someone point me to the way to write such a match clause?
>>
>>
>> Various failed attempts:
>> (list reqA reqB (opt1 opt2 opt3 opt4) ...)   ; syntax error. matching
>> clauses do not do grouping like this
>> (list reqA reqB (list opt1 opt2 opt3 opt4) ...) ; didn't expect this to
>> work since it would specify an embedded list.  I was right.
>>
>> This one surprised me:
>> (match row
>>   [(list required1 required2 (and opt1 opt2 opt3 opt4) ...)
>>(list opt1 opt2 opt3 opt4)])
>>
>> This distributes the ... over the four items inside the 'and' clause such
>> that each of the 'optionalN' identifiers matches all remaining elements.
>> '(("Name" "Age" "First" "Last")
>> ("Name" "Age" "First" "Last")
>> ("Name" "Age" "First" "Last")
>> ("Name" "Age" "First" "Last"))
>>
>> In hindsight it makes sense -- the 'and' causes it to match the element
>> across all four patterns.  They all match because they are identifiers and
>> therefore match anything.  Then the '...' causes it to do that for all
>> remaining elements, generating lists into each of the identifiers because
>> that's what '...' does.
>>
>> --
>> You received this message because you are subscribed to the Google 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/CAE8gKocCPSgVQG_aMSC%3DQJAmAtxvmCN8vqpwsankKnCJZAOotw%40mail.gmail.com
>> 
>> .
>>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/CACehHmA6Xo87zckX4N8JbXDJVaVob6cp3Dk%2B%3DD3DG80DDgonyQ%40mail.gmail.com
> 
> .
>

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


Re: [racket-users] multiple-value version of in-value

2020-05-04 Thread Philip McGrath
Glad it was useful!

There is a variant `in-value*/expression` that works like your `in-values`:
https://docs.racket-lang.org/adjutor/Stable.html#(form._((lib._adjutor%2Fmain..rkt)._in-value*%2Fexpression))

-Philip


On Mon, May 4, 2020 at 10:12 PM Jos Koot  wrote:

> To Philip McGrath, Hi again
>
>
>
> I modified the clause
>
> ((id ...) (in-value* expr ...))
>
> to the following in-values clause:
>
> ((id ...) (in-values expr))
>
>
>
> where the expr is supposed to return as many values as ids.
>
> I simplified the code such as to avoid syntax-parse,
>
> because I do not (yet) understand all its powerful features.
>
> I prefer writing code I can understand in all details.
>
>  I should study on syntax-parse in due future 
>
>
>
> (define-sequence-syntax in-values
>
> (λ (stx)
>
>   (raise-syntax-error 'in-values
>
>"can only be used in for forms" stx))
>
> (λ (stx)
>
>   (syntax-case stx ()
>
>(((id ...) (_ expr))
>
>   #'((id ...)
>
>  (:do-in
>
>   (((id ...) expr))
>
>   #t () #t () #t #f ()))
>
>
>
> For example:
>
>
>
> (for/first (((a b c) (in-values (values 2 + 3 (b a c)) ; -> 5
>
>
>
> Thanks again, Jos
>
>
>
> *From: *Philip McGrath 
> *Sent: *04 May 2020 17:21
> *To: *Jos Koot 
> *Cc: *us...@racket-lang.org
> *Subject: *Re: [racket-users] multiple-value version of in-value
>
>
>
> My package `adjutor` has a few variants of this, like `in-value*`:
> https://docs.racket-lang.org/adjutor/Stable.html#(part._.Sequence_.Constructors)
>
>
>
> They can all be used as first-class procedures, but that does involve a
> little runtime overhead, so they use `define-sequence-syntax` to cooperate
> directly with `for`-like forms when possible.
>
>
>
> -Philip
>
>
>
>
>
>
>

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gZdxzaUgWqqhM4PzYT%3DozckGrUsaHh8OXFDH74mfEutHg%40mail.gmail.com.


Re: [racket-users] multiple-value version of in-value

2020-05-04 Thread Philip McGrath
My package `adjutor` has a few variants of this, like `in-value*`:
https://docs.racket-lang.org/adjutor/Stable.html#(part._.Sequence_.Constructors)

They can all be used as first-class procedures, but that does involve a
little runtime overhead, so they use `define-sequence-syntax` to cooperate
directly with `for`-like forms when possible.

-Philip


On Mon, May 4, 2020 at 6:28 AM Jos Koot  wrote:

>
>
> Recently I needed a multiple value version of in-value.
>
> Does something like that exist already?
>
> I could not find it, so I made one:
>
>
>
> (define-syntax (in-values stx)
>
> (syntax-case stx ()
>
>   ((_ expr)
>
> #'(make-do-sequence
>
> (λ ()
>
>  (values
>
>   (λ (p) expr)
>
>   (λ (p) #f)
>
>   #t
>
>   (λ (p) p)
>
>   #f
>
>   #f))
>
>
>
> A pity that it is a syntax. It is possible to code it as a procedure, but
> I do not see an elegant way to do that without confusing a list with a
> multiple value.
>
>
>
> I had:
>
>
>
> File drac-plus-sant-is-jordi.rkt
>
>
>
> (define digits '(0 1 2 3 4 5 6 7 8 9))
>
>
>
>   (for*/list
>
>((A (in-list digits)) (digits (in-value (remove A digits)))
>
> (C (in-list digits)) (digits (in-value (remove C digits)))
>
> (D (in-list digits)) (digits (in-value (remove D digits)))
>
> (N (in-list digits)) (digits (in-value (remove N digits)))
>
> (R (in-list digits)) (digits (in-value (remove R digits)))
>
> (S (in-list digits)) (digits (in-value (remove S digits)))
>
> (T (in-list digits))
>
> (DRAC  (in-value (+ (* 1000 D) (* 100 R) (* 10 A) C)))
>
> (SANT  (in-value (+ (* 1000 S) (* 100 A) (* 10 N) T)))
>
> (JØRDI (in-value (+ DRAC SANT))) ...
>
>
>
> With syntax in-values I could simplify it to:
>
>
>
> File drac-plus-sant-is-jordi-with-combi.rkt
>
>
>
>   (for*/list
>
>((combination (in-combinations '(0 1 2 3 4 5 6 7 8 9) 7))
>
> (permutation (in-permutations combination))
>
> ((A C D N R S T) (in-values (apply values permutation)))
>
> (DRAC  (in-value (+ (* 1000 D) (* 100 R) (* 10 A) C)))
>
> (SANT  (in-value (+ (* 1000 S) (* 100 A) (* 10 N) T)))
>
> (JØRDI (in-value (+ DRAC SANT)))
>
> (J (in-value (find-decimal-digit JØRDI 4)))
>
> (Ø (in-value (find-decimal-digit JØRDI 3)))
>
> (I (in-value (find-decimal-digit JØRDI 0))) ...
>
>
>
> See https://github.com/joskoot/drac-sant-jordi for the complete programs.
>
>
>
> Best wishes, Jos
>
> --
> You received this message because you are subscribed to the Google 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/5eafee34.1c69fb81.33cf0.0ce5%40mx.google.com
> 
> .
>

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


Re: [racket-users] Do I misunderstand set! ?

2020-04-23 Thread Philip McGrath
I think you are running into the (very confusing!) issue Ben describes
here: https://groups.google.com/d/msg/racket-users/UD20HadJ9Ec/mDd4x8Y1BwAJ

-Philip


On Thu, Apr 23, 2020 at 5:00 PM Hendrik Boom  wrote:

> extract from code:
>
>   (fprintf anomaly "resEEEulttyope was ~s~n" resulttype)
>   (fprintf anomaly "set resulttyoe to ~s~n" ty)
>  `(set! resulttype ty)
>   (fprintf anomaly "resEEulttyope now ~s~n" resulttype)
>
> Previous creation of resulttype:
>
>   (define resulttype : (Option TType) #f) ; TODO: check there's only one
>
> Output that appeared on the anomaly file:
>
> resEEEulttyope was #f
> set resulttyoe to _void
> resEEulttyope now #f
>
> I stuck the E's in just to make sure these were the statements really
> generating that output.
>
> If I am correct, the set! should have changed the value of resulttype.
> I'm doing thie in typed-racket.
>
> -- hendrik
>
> --
> You received this message because you are subscribed to the Google 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/20200423210026.3iuntiq3jqyjtpmc%40topoi.pooq.com
> .
>

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


Re: [racket-users] Examples of sending HTML email w/ Racket?

2020-04-09 Thread Philip McGrath
I put up an example taken from my code for Digital Ricoeur in response to
an old mailing list thread
. It
is not ready for general-purpose use—in particular, I basically only have
to deal with trusted input—but here it is:
https://github.com/LiberalArtist/multipart-writing-examples

That thread also has some discussion about what a good package might want
to address and some slightly annoying differences between "normal" mime and
"multipart/form-data" used for web forms.

-Philip


On Thu, Apr 9, 2020 at 10:25 AM Matthew Flatt  wrote:

> At Thu, 9 Apr 2020 07:09:21 -0700 (PDT), Brian Adkins wrote:
> > I looked at the net/mime library, but, as the title of the doc page
> > suggests, it seemed to only be about decoding, not creating:
> >
> > https://docs.racket-lang.org/net/mime.html?q=net%2Fmime
>
> Ah, right. I think I've made this mistake before.
>
>
> Encoding is be built into SirMail (very old code):
>
>  https://github.com/mflatt/sirmail/blob/master/sirmail/sendr.rkt#L136
>
> It would make sense to have a better version of this in a package, of
> course.
>
> --
> You received this message because you are subscribed to the Google 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/5e8f303a.1c69fb81.69759.d940SMTPIN_ADDED_MISSING%40gmr-mx.google.com
> .
>

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


Re: [racket-users] Scribble citations for art history dissertation (AJA style)

2020-03-19 Thread Philip McGrath
On Thu, Mar 19, 2020 at 12:40 PM Matthew Flatt  wrote:

> At Thu, 19 Mar 2020 12:38:39 -0400, Christopher Lemmer Webber wrote:
> > I will spend the rest of the day looking at what scriblib's bibliography
> > stuff does in further detail and think about how to accomplish what we
> > need.  It could be that what I do is build a quicker proof of concept
> > that accomplish *Morgan's* needs so we can get her dissertation out the
> > door, and then upon examining that, we can think about how to generalize
> > it for something more universal.  How does that sound?
>
> That sounds like a good plan.
>

For a general solution, I'd take a look at the Citation Style Language (
https://citationstyles.org/), which is an XML language for defining how to
render citations and bibliographies. A major advantage is that it has libre
style definitions for a dizzying variety of house styles, including AJA (
https://github.com/citation-style-language/styles/blob/master/american-journal-of-archaeology.csl),
many of which seem to be maintained by the relevant publishers. It also
integrates with Zotero and its competitors, as well as many other tools.

I'm quite interested in working on this and some related issues as well,
though properly digging into it keeps getting pushed aside by other things.

But I agree that a general solution might be best deferred until after the
dissertation—best wishes, Morgan!

-Philip

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gZ8j0rCO1xNHD7cjcS-6xtKZXU8aesOkP3D5OBou99X4g%40mail.gmail.com.


Re: [racket-users] Types for formlets

2020-02-24 Thread Philip McGrath
Hi Marc,

You're right that there will be some challenges in using formlets in Typed
Racket. The easiest approach will probably be to keep defining formlets in
untyped modules and importing them with `require/typed`, perhaps with
helper functions or macros to eliminate some of the boilerplate.
Pragmatically, you aren't even loosing much type safety here: formlets are
processing raw bytes from the outside world, and there is an inherent
possibility for dynamic failure. Using `require/typed` will enforce with
contracts that the values dynamically coming in have the right types and
raise an exception otherwise.

But you asked about how to type formlets. I don't have a worked-out answer,
but I'll try to point you to some of the implementation details that would
be relevant.

To start, in your example:
(define s-formlet
  (formlet (div (label "Enter a string:")
,{=> input-string a-string})
   [a-string : String]))
the `formlet` form is indeed a macro defined here

(and also here
,
sadly basically by copy and paste, because that seemed easier than properly
abstracting over the shared parts when I added the unsafe version).

The `s-formlet` itself, though, is a normal runtime value, as is
`formlet-process`: my guess is that what you were seeing from the macro
stepper was some of the implementation of enforcing the contract on
`formlet-process`.

The `formlet` syntax is built on a functional layer. This is discussed in
the docs , and in
more detail in the paper
 and a technical report
. (You
may be interested to note that the papers present formlets in a version of
OCaml, a statically typed language: the challenge for Typed Racket, as
usual, isn't the types but the typed–untyped interaction.) Formally, a
formlet value is an "applicative functor" or "idiom."

Concretely, a formlet is represented as a function. In Typed Racket syntax,
we might try to write:
(define-type (Formlet A)
  (-> Natural (Values (Listof Xexpr) (-> (Listof Binding) A) Natural)))
(: s-formlet (Formlet String))
That type looks pretty strange! Here's what's going on. The formlet is
called with a numeric counter, which is used to generate field ids. Its
three results are some HTML to display, a function
to process the bindings from the request, and the new value for the
counter. (There is an unchecked invariant that the new counter value should
not be less than the old value.) The `formlet` syntax expands to uses of
the combinators `pure`, `cross`, and `cross*` to assemble compound formlets
from smaller pieces. This functional interface can also be used directly.

That may be enough to illustrate some of the problems. Typed Racket can
have trouble generating contract for polymorphic functions like `(:
formlet-process (∀ (A) (-> (Formlet A) Request A)))`. Furthermore, the
`Formlet` type I wrote is a simplification: formlets are actually allowed
to produce multiple values from the processing function, which again is a
problem for typing. (I think it would be reasonable to eliminate that
feature from a Typed Racket interface: I don't think it is used often,
especially since `formlet/c` was broken for a while
 for the
multiple-return-values case.) Because of the way `cross` is implemented,
there is a great deal of function composition, which could mean many, many
crossings of the typed–untyped boundary with contract enforcement costs.

An approach I might consider would be re-implementing the core
combinators—essentially this module
—in
Typed Racket and writing a typed version of the `formlet` macro that
expands to them. You could still use the library formlets by importing them
with `require/typed` at some concrete type.

I'm happy to talk more if you're interested.

-Philip

On Mon, Feb 24, 2020 at 10:28 AM Marc Kaufmann 
wrote:

> Hi all,
>
> I wonder what the best way is to integrate formlets into typed programs. I
> simply `require/typed` formlet-display  as type (-> Any Any), which is not
> illuminating, but the display part is rarely the problem.
>
> formlet-process is tricky. The earliest point at which I 'know' the type
> of processing a given formlet is directly when formlet-process is called,
> so that's the best time to start typing to get most of the types checked.
> Ideally I would do something like:
>
> (define s-formlet
>   (formlet (div (label "Enter a string:")
> ,{=> input-string a-string})
>[a-string : String]))
>
> and be done with it. Of course I cannot type it this 

Re: [racket-users] Starting syntax highlighter project

2020-02-19 Thread Philip McGrath
You don't need a `#lang` to use `color:text<%>`: I've used it to do basic
syntax highlighting for XML. In fact, you don't even need a GUI for the
relevant part of the protocol, which is what `#lang`s implement. The
requirements are described in the documentation
 for the `get-token`
argument to the `start-colorer` method. There are specific requirements on
how the function must behave to support efficient interactive
re-tokenization: these are overkill for an ahead-of-time syntax
highlighter, but if your lexers can meet those requirements, they should be
usable for a wide range of tasks.

I have a theory that you could use delimited continuations to help with
some of the bookkeeping, with the continuation becoming (part of?) the
"mode" value passed between calls to the `get-token` function.

-Philip





On Thu, Feb 20, 2020 at 12:15 AM Sorawee Porncharoenwase <
sorawee.pw...@gmail.com> wrote:

>
> On Wed, Feb 19, 2020 at 11:55 PM Sage Gerard  wrote:
>
>> I'm very much in favor of interoperability and am happy to work in that
>> direction. Does this imply that we need a #lang for each highlighting
>> target?
>
>
> With my approach, yes, but note that technically, the #lang doesn't need
> to be functional. The whole module could just expand into a raising of a
> runtime exception "not implemented". I'm not sure that in practice this is
> a good idea though.
>
>
>> What happens if you want to highlight code mixtures? Some snippets of
>> interest to me can include Javascript, Markdown, CSS, HTML and Racket all
>> within 20 lines.
>>
>
> Then the color lexer would need to be context-sensitive and knows when to
> switch its lexing mode. Note that this is not a problem due to this
> approach. Any other approaches would have the same problem.
>
> It would be cool if there's a way to annotate code with `#reader` at the
> meta level, which would make this problem much easier...
>
> --
> You received this message because you are subscribed to the Google 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/CADcuegs-76-meLv7Lmr7enGy47fUqGeJChwq%2B%2B9Xbk7b%2Bz6GgQ%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAH3z3gby180aDNWhO8fpy7fXZ-j7W9D8_EAGi30%2BPan3LT%2BzFw%40mail.gmail.com.


Re: [racket-users] cast on mutable hash table...

2020-02-15 Thread Philip McGrath
On Sat, Feb 15, 2020 at 1:23 PM 'John Clements' via users-redirect <
us...@plt-scheme.org> wrote:

> Yes, absolutely. One reason that students in my class wind up using cast
> quite frequently in their parsers is that they use patterns like (list (?
> symbol s) …) which (as I recall) expand into unannotated lambda’s, and
> always require a cast.


I like `assert` for those situations: it fails immediately if anything goes
wrong, and it uses a predicate, so it corresponds well to the `?` pattern.
(It can also perform better.)

-Philip

> --
-Philip

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gbMiTHvBBRsRFuNzTJNy0sOMMZ3DGNbe312%2Bmjf7atdDg%40mail.gmail.com.


Re: [racket-users] Re: How to convert String to Integer

2020-02-11 Thread Philip McGrath
On Tue, Feb 11, 2020 at 3:28 PM Alain De Vos  wrote:

> But first i need a list of characters. :)
> Does the language has a conversion operator ?
>

Yes, `string->list`:
https://docs.racket-lang.org/reference/strings.html#(def._((quote._~23~25kernel)._string-~3elist))
But read on …

On Tue, Feb 11, 2020 at 3:28 PM Alain De Vos  wrote:

> 0) Given a string,
> 1) convert to  a list of characters,
> 2) allow me to iterate,
> 3) convert a character to an int ,
> 4) subtract corresponding value of zero,
> 5) allow me to some positional stuff and addition.
>

If you really want to implement the algorithm you described, here's one way
to do it:
#lang typed/racket
(: string->integer (-> String Integer))
(define (string->integer str)
  (define base (char->integer #\0))
  (for/fold ([acc : Integer 0])
([char (in-string str)])
(+ (* 10 acc) (- (char->integer char) base

Again, I actually would do this with `string->number`, as I illustrated
earlier, unless this arithmetic with Unicode scalars is really what you
want to compute. For example, what about "-"?

On Tue, Feb 11, 2020 at 2:15 PM Alain De Vos  wrote:

> But at each step I should raise , this is not ok.
> Otherwise the GUI just keeps eating memory ...
>

I don't understand what you mean here. Raising an exception should not
cause a memory leak. If you mean that it makes the GUI non-responsive, then
you should catch the exception and show a message to the user (or do the
equivalent using a designated "bad value" instead of an exception).

-Philip

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gYQKaKpWmSzWJoiTaHB3HDmrgUrcgH_CZOOhvmYwPV4zQ%40mail.gmail.com.


Re: [racket-users] How to convert String to Integer

2020-02-11 Thread Philip McGrath
Others have tried to be more Socratic in pointing you this way, but here's
an attempt at being more explicit.

As you note, the result of `string->number` has the type `(U Complex
False)`. If we try to think about about this in a version of the HtDP
design recipe, we have a few cases:

   1. `string->number` produces an `Integer` when given an argument like
   `"42"`.
   2. `string->number` can also produce a value of any of the various
   `Number` types that aren't integers, as with `"3.2+6.0i"` or `"2/3"`.
   3. If the given string can't be parsed as any kind of number, like
   `"apple"`, `string->number` returns `#false`.

If you want to write a function with the type `(-> String Integer)`, you
are going to have to handle all of those cases, whether you use
`string->number` or not! What behavior makes sense in cases 2 and 3 (or
maybe it makes sense to break 2 into smaller cases) is going to depend on
your particular use case. Maybe it makes sense to return a default value.
Maybe you just want to raise an exception.

If we write a version of your `myconversion` function with a placeholder
(again in the spirit of HtDP), we might do something like this:
#lang typed/racket
(: myconversion (-> String Integer))
(define (myconversion str)
  (define rslt (string->number str))
  (cond
[(exact-integer? rslt)
 rslt]
[else
 ;; TODO
 ...]))

This is where Ben's suggestion of `exact-integer?` is useful: thanks to
Typed Racket's occurrence typing
, the type
system knows that, in the "then" branch of the conditional, `rslt` must
have the type `Integer` because it satisfied the `exact-integer?` test.
(Note that the `Integer` type corresponds to `exact-integer?`
,
not `integer?`.)

We still need to fill in the "else" branch to handle the case that the
string didn't represent an integer. In your latter example, you raised an
exception, which is a sensible choice. Here's an idiomatic way to do that:
#lang typed/racket
(: myconversion (-> String Integer))
(define (myconversion str)
  (define rslt (string->number str))
  (cond
[(exact-integer? rslt)
 rslt]
[else
 (raise-argument-error 'myconversion
   "a string representing an integer"
   str)]))

One thing to observe is that this is exactly the way you would have
implemented such a function in untyped `#lang racket`: only the single type
annotation is different. Much of the reason is that Typed Racket works hard
through features like occurrence typing to be able to typecheck the kinds
of programs you would idiomatically write in untyped Racket. In this
particular case, though, it also reflects the fact that there isn't a type
for "strings that can be parsed as integers." There's a potential for
dynamic failure here that the static type system may help you to manage,
but ultimately can't escape. (Ignoring for the moment fancier type systems
that are mostly still research projects.)

Your problem with `sweet-exp` is a different one. I'm not familiar with
`sweet-exp`, so I can't really help you, but it looks like either a bug or
a known limitation in the concrete syntax `sweet-exp` supports. I will note
that the lambda function you use in that example would be a syntax error in
`#lang racket`.

-Philip


On Tue, Feb 11, 2020 at 10:04 AM Alain De Vos 
wrote:

> No exact-integer is a check it is not a type.
> The error described above remains
>
> On Tuesday, February 11, 2020 at 3:50:27 PM UTC+1, Alain De Vos wrote:
>>
>>
>>
>> On Tuesday, February 11, 2020 at 3:25:42 PM UTC+1, Ben Greenman wrote:
>>>
>>> You may want `exact-integer?`
>>> True , i should use exact-integer.
>>>
>> --
> You received this message because you are subscribed to the Google 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/89f338be-f574-44b5-82d4-23f833ec14ac%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAH3z3gafGOGZt0p3Xw20-X2deT%3DTO8WW1-omgwBBiNrcq%3DLiVw%40mail.gmail.com.


Re: [racket-users] [racket users] Macro literal "|"

2020-02-03 Thread Philip McGrath
You're right that `|` isn't a valid terminal with the normal reader, but,
as it happens, the zero-length identifier can be written as `||`. (I don't
think the concept of a zero-length identifier is common in other languages:
it corresponds to the empty string.)

-Philip


On Mon, Feb 3, 2020 at 6:27 PM Kevin Forchione  wrote:

> Hi guys,
> I’ve been  trying to figure out how to use “|” in a macro. I’ve got syntax
> like this in mind:
>
> (foo A | B)
>
> Not sure if I can do this because the reader expects a pair. If “|” isn’t
> a convenient literal to work with is there an alternative others have used
> that represents more or less the idea of “or” or “alternate”?
>
> Thanks!
>
> Kevin
>
> --
> You received this message because you are subscribed to the Google 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/447100AA-DB45-46C3-A7DC-2705A1668302%40gmail.com
> .
>

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


Re: [racket-users] Web server + authentication

2020-01-22 Thread Philip McGrath
I configure Postfix to send external mail via Amazon's "Simple Email
Service," then use `net/sendmail`. Having a working mail-transfer agent
means you can easily send yourself mail from other tools on the system,
too, like a cron job to renew the TLS certificates. (I haven't looked at
Postmark, so I can't compare.)

As far as managing users generally, the website code for digitalricoeur.org
isn't (yet!) public, but I could provide access if it would be useful as an
example. We use a passwordless approach based on emailing one-time-use
links, which continuations make especially pleasant.

-Philip

On Wed, Jan 22, 2020 at 7:47 PM Matthew Butterick  wrote:

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

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gaG3To1CZjoex3J4z4Gsk99HQfwyejENt8FBQg7%3DdXTkA%40mail.gmail.com.


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

2019-12-22 Thread Philip McGrath
The other advice here is good and could help to implement a more principled
solution. But, if you want to do something equivalent to editing a running
application's database on the fly, just using Racket values instead of a
DB, I would build on `file-box`:
https://docs.racket-lang.org/web-server/stateless.html#%28mod-path._web-server%2Flang%2Ffile-box%29

(I can elaborate later if that would be helpful.)

-Philip

On Sun, Dec 22, 2019 at 4:44 AM Marc Kaufmann 
wrote:

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

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

2019-12-22 Thread Philip McGrath
You can probably use `make-threshold-LRU-manager
`
with a much higher memory threshold than the default from `serve/servlet`,
which is about 130 MB. The manager will start expiring continuations at
that threshold even if you have lots of RAM available.

-Philip

On Sat, Dec 21, 2019 at 3:31 PM George Neuner  wrote:

>
> On 12/21/2019 4:38 AM, Marc Kaufmann wrote:
>
>
> Did you perhaps change the continuation manager - or its setup?
>>
>> https://docs.racket-lang.org/web-server/servlet.html?q=ffi#%28part._managers%29
>>
>>
> No, not really. I simply import send/suspend/dispatch etc and use them
> without doing anything in particular. I am requiring them within
> typed/racket if that matters via require/typed. So I have no idea where to
> configure the continuation manager - I don't even know where the current
> one is.
>
>
> If you started from serve/servlet - and didn't specify differently - then
> you are using the default LRU continuation manager.   If the load spikes,
> it will drop saved continuations to get memory use back under control.
>
>-
>
> https://docs.racket-lang.org/web-server/run.html?q=serve%2Fservlet#%28def._%28%28lib._web-server%2Fservlet-env..rkt%29._serve%2Fservlet%29%29
>-
>
> https://docs.racket-lang.org/web-server/servlet.html#%28def._%28%28lib._web-server%2Fmanagers%2Flru..rkt%29._make-threshold-.L.R.U-manager%29%29
>
>
> You can specify to use a different manager (including a custom one) in the
> call to serve/servlet.
>
>
> George
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/f974666a-3e1a-3cd8-d371-09e9a283a157%40comcast.net
> 
> .
>

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


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

2019-11-22 Thread Philip McGrath
On Fri, Nov 22, 2019 at 8:50 AM Neil Van Dyke  wrote:

> That hypothetical parser assembling the parsed representation *could*
> then concatenate sequences of 2 or more contiguous strings representing
> CDATA, but that could be expensive, and might not be needed.  Consider
> how large some XML and HTML documents can be, and how little information
> out of them is sometimes needed (e.g., price scraper) --
> performance-wise, the concatenation might be best left up to whatever
> uses that parsed representation.
>

I think a key point here is that the very features that make a
representation of XML ideal for some uses will be troublesome for other
uses.

I parse a lot of XML in Racket, and I often wish the x-expression grammar
were different in various ways, which basically amount to eliminating
artifacts of the concrete syntax: turning numeric entities (`valid-char?`)
and the `cdata` struct into strings, plus concatenating contiguous strings.
When I wander over toward the front-end, though, I start writing HTML pages
as x-expressions, and then I want adjacent strings to be allowed so I can
format my code nicely (perhaps with Scribble's at-syntax). If I were
writing an XML-aware text editor (at one point I took a few small steps in
that direction), I would very much care about the concrete syntax and even
source-location information. While I don't personally want this, some
people have even wished that x-expressions supported HTML-isms like
"boolean attributes."

Of course, these tensions aren't specific to XML: one could also wish for
fancier representations of strings than linear (mutable!) sequences of
characters, like "ropes"/"cords"/"texts" (a tree representation) or
substring "views" that can share storage.

To me, the fact that x-expressions are a good-enough representation of XML
for a lot of different uses suggests that they're in the right neighborhood
for a general-purpose library representation. (As Neil knows, there are
also Racket libraries that use a different representation, SXML
, that's fairly close
neighbor in the design space.) I particularly like that, when I'm doing the
kind of parsing where I want a more normalized representation, I can come
up with a subset of the x-expression grammar that meets my needs (and
enforce it with memoized contracts) and do a normalization pass: I can rely
on stronger invariants internally while still taking full advantage of
existing libraries (for x-expressions, lists, etc.).

-Philip

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gYu0GQphbTzswt0gm3UnpsGnqzq4G5nHF4bLTh5EA9Qvw%40mail.gmail.com.


Re: [racket-users] What's the best way to do these syntax transforms?

2019-11-08 Thread Philip McGrath
On Fri, Nov 8, 2019 at 5:06 PM Christopher Lemmer Webber <
cweb...@dustycloud.org> wrote:

> Huh... somehow I had thought that I had heard that Racket has mutable
> strings by default.  It cropped up on my TODO list because of that.  I
> wonder what gave me that impression?
>

Racket strings are annoyingly mutable, enough so that there are many
reasonable definitions of "default" for which the statement "Racket has
mutable strings by default" would be true. For example:
> (immutable? (string-append ""))
#f
String literals are an exception to the general rule, though there is some
precedent for that exception: IIRC mutating a string literal in C is
undefined behavior.

This is a bit of a pet peeve of mine:
https://github.com/racket/rhombus-brainstorming/issues/22

-Philip

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gYy5akbv6SgR82RcF7Xhu0pJ-T21maT%2BphsSHk_8ghymw%40mail.gmail.com.


Re: [racket-users] What's the best way to do these syntax transforms?

2019-11-08 Thread Philip McGrath
On Fri, Nov 8, 2019 at 2:58 PM Matthew Flatt  wrote:

> More precisely, the reader (via `read-syntax`) creates immutable
> strings.
>
> If a macro constructs a mutable string and converts it to a syntax
> object, the string is not converted to an immutable string. Maybe it
> should be.
>

I see now that this is true, but it isn't what I'd expected. The docs

for `datum->syntax` say that:

> For any kind of value other than a pair, vector, box, immutable hash
> table, immutable prefab structure, or syntax object, conversion means
> wrapping the value with lexical information, source-location information,
> and properties after the value is interned via datum-intern-literal.
>
and `datum-intern-literal` says

that "mutable strings and byte strings are interned as immutable strings
and byte strings," which I just confirmed is true.

Based on this, I'd previously thought that using `datum->syntax` on a
mutable string would convert the string with `datum-intern-literal`, which
would make the wrapped string immutable—but I see now that the wrapped
string is, in fact, still mutable.

-Philip

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gb%2Bztz62%2BykWpZNbNQ1gPy70LVWB_%3DMpkLxKApScJiPEQ%40mail.gmail.com.


Re: [racket-users] What's the best way to do these syntax transforms?

2019-11-08 Thread Philip McGrath
On Fri, Nov 8, 2019 at 9:56 AM Jay McCarthy  wrote:

> On Fri, Nov 8, 2019 at 9:51 AM Christopher Lemmer Webber <
> cweb...@dustycloud.org> wrote:
>
>> I have a need to do two things in a #lang:
>>
>>  - Most importantly, make all strings that appear in the source code
>>immutable
>>
>
> Make #%datum turn literal strings `s` into `(string->immutable-string s)`
>

 But the default `#%datum` (which expands to `quote`) already does this:
> (immutable? "foo")
#t
Or, for another way of thinking about it, strings that go into syntax
objects are interned. The upshot is that literals are immutable by default:
a language that wanted mutable literals would have to make special effort
via `#%datum`.

-Philip

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gaxTm1hfEW2v8FjRFQ3noSMH7H_o%2BfY7oxXNpS5pqGvuA%40mail.gmail.com.


Re: [racket-users] eq? of quoted expressions

2019-10-25 Thread Philip McGrath
On Fri, Oct 25, 2019 at 1:27 PM wanderley.guimar...@gmail.com <
wanderley.guimar...@gmail.com> wrote:

> On Fri, Oct 25, 2019 at 9:28 AM Alexis King  wrote:
>
>> Unlike eq? on symbols, eq?’s behavior on quoted lists is unspecified …
>> Is there a reason you would like the answer to be #t?
>
> Not strong one.  I was implementing a compiler (to a computer simulator
> that I did) and I wanted to express some of my constants as list (because
> it would make easier to read them in case expression).  I switched to use
> match instead.
>

Note that Racket's `case` (unlike the R5RS or R6RS versions) is based on
`equal?`, so the expression:
(case (list 'a)
  [((a))
   "ok"]
  [else
   #f])
reliably produces `"ok"`.

Also, as you very well may know, the left-hand side of a `case` clause
isn't an implicitly-quoted list expression: it's a parenthesized sequence
of implicitly-quoted expressions. I mention this because, often, you might
represent a constant as a symbol. If you use a case expression to, in
logical terms, test if some value is a member of a "list" of constant
symbols, there aren't actually any Racket list values involved.

It's often a good choice to use `match` rather than `case`, since `match`
is more flexible and extensible. However, `match` doesn't provide `case`'s
guarantee of O(log N) performance, which can be important if you are
generating very large case expressions.

-Philip

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gYuV1KGRmZk%3D9oFc9VN2SQ%3DO42Tf%2Bh3wWB%2BjmJd1kSszQ%40mail.gmail.com.


Re: [racket-users] Re: Structured Concurrency in Racket

2019-10-10 Thread Philip McGrath
On Thu, Oct 10, 2019 at 2:42 AM Zelphir Kaltstahl <
zelphirkaltst...@gmail.com> wrote:

> … If that works for arbitrary serializable-lambda with only serializable
> parts, I could continue my process pool project.
>

Yes, this would work for any value created by `serial-lambda`.


> The only issue would then be, that any user of it would have to know in
> advance, that they cannot define their lambdas as usual, but have to use
> serializable-lambda, potentially through their entire code (as there might
> be references to things which contain references to things, which ...). The
> abstraction is in this way leaky, but it would make a working library then.
>
> `n` does not need to be serializable, because it is defined in the module
> and will be defined in the module "on the other side" as well? If I
> understand this correctly.
>
I think it can help in understanding to know a bit about how
`serial-lambda` is implemented. In a context like:
(define (make-serializable-adder n)
  (serial-lambda (x)
(+ n x)))
 `serial-lambda` uses some advanced macrology to generate a module-level
struct declaration like:
(serializable-struct representation (n)
  #:property prop:procedure
  (λ (this x)
(+ (representation-n this) x)))
and the `serial-lambda` expression itself expands to code constructing an
instance of the struct, like `(representation n)`.

The thing to note here is that the fields of the struct hold the contents
of the closure, i.e. local variables from the lexical environment of the
`serial-lambda` expression. These values need to be serializable so that
they can be sent across the place-channel. The arguments to the
`serial-lambda` procedure—in this case, `x`—don't need to be serializable,
because they aren't part of the struct but are supplied when the procedure
is called. Similarly, module-level variables (including imports via
`require`) can be referenced directly in the generated `prop:procedure`
value, so they also don't need to be serializable: this is why `+` in the
example is ok, but the principle also covers much more complicated cases in
general.

So, users of your process pool only need to use `serial-lambda` for
procedures that are captured in the closure you want to send to the other
place, not for all of the functions they use to actually do the
computation. From my experience programming in `#lang web-server`, where
these rules apply to the implicit closure created around a web interaction,
it doesn't turn out to be an issue most of the time.

When hearing actors, then Threads could be thought of a means of
> implementing them, but I think might not be useful to do so when thinking
> about performance. Architecturally yes, maybe. That is, why I would think
> of places as a means of implementing an actor model kind of thing.
>

It depends on how you want to use your system. If you want a few,
relatively long-lived actors, places might work well. If you want many,
potentially short-lived actors, you will want to use threads, because
creating places is expensive and doesn't give a benefit beyond
`(processor-count)` places. Potentially, you could use threads running
across a pool of places, though you would then potentially need to think
about how to optimally distribute the threads among the places.

> When you say, that loci extends the idea of places to multiple machines,
> what do you mean? I thought places can already run on multiple machines.
>
Yes, distributed places can run across multiple machines.

> It would be nice however, to not have to use a different construct to
> define serializable lambdas and to be able to go to any program and simply
> use existing lambdas to send them to a process pool to make use of multiple
> cores, instead of having to refactor many things into serializable things.
>
I do see what you mean, but I think of this as protecting me from bugs.
When a programmer writes `serial-lambda`, they are saying "I've thought
about it, and it makes sense to serialize this and later call the
deserialized procedure in some other context." If you could serialize any
first-class closure you find, without cooperation from the creator of the
closure, it might not logically make sense to call it in some other context
(perhaps because it relies on mutable state), in which case you would get
nonsense results and potentially break the other module's invariant.

 -Philip

-- 
You received this message because you are subscribed to the Google 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/CAH3z3gbwwaHGOPM69ZLi7R30iSk%2BUqToKCstAT0Y37gArUrrfg%40mail.gmail.com.


Re: [racket-users] How do I typeset mixed-code for docs.racket-lang.org?

2019-10-09 Thread Philip McGrath
The way I would approach this would probably be to:

   1. Create a #lang that accepts your source Markdown+Racket syntax.
   2. Add a color lexer as you would for DrRacket, probably using `
   syntax-color/racket-lexer
   
`
   for the Racket parts or dynamically getting a color lexer based on the
   #lang line.
   3. In the Scribble manual, embed these fragments with `codeblock` and
   `code` rather than `racketblock` and `racket`:
   https://docs.racket-lang.org/scribble/scribble_manual_code.html

-Philip


On Wed, Oct 9, 2019 at 5:35 PM William J. Bowman 
wrote:

> Oh right I forgot about documentation links.
>
> No, scribble/minted won’t play well with the scribble/manual functions. It
> hijacks the renderer to use the pygmentize binary to generate typeset
> target code (HTML or LaTeX); it doesn’t just apply scribble styles.
>
> --
> Sent from my phoneamajig
>
> > On Oct 9, 2019, at 14:17, Sage Gerard  wrote:
> >
> > Hi William,
> >
> > Sorry for the delay and thank you for responding so quickly.
> >
> > It's a night and day difference in terms of presentation. I don't see
> documentation links functioning (e.g. the "displayln" in your example). I'm
> assuming that since @minted only applies to styles, it will function fine
> if composed with @racketmod and friends?
> >
> >
> > ~slg
> >
> > ‐‐‐ Original Message ‐‐‐
> >> On Tuesday, October 8, 2019 3:05 PM, William J. Bowman <
> w...@williamjbowman.com> wrote:
> >>
> >> This got me interested.
> >> I tried a quick hack on my scribble-minted package to allow for nesting
> >> different languages.
> >> Is this something like what you want?
> >> https://www.williamjbowman.com/tmp/scribble-minted/nested.html
> >>
> >> Source here:
> >>
> https://github.com/wilbowma/scribble-minted/tree/nested-minted/nested.scrbl
> >>
> >>
> 
> >>
> >> William J. Bowman
> >>
> >>> On Tue, Oct 08, 2019 at 05:06:40PM +, Sage Gerard wrote:
> >>>
> >>> One of my projects allows for embedding Racket modules within 
> elements, within a Markdown page.
> >>>
> >>> Hello World
> >>>
> >>> 
> >>>
> >>>