Re: Fwd: [racket-users] Writing a "command-line front-end" for a language

2022-09-04 Thread Philip McGrath
On Sun, Sep 4, 2022, at 10:00 AM, Reuben Thomas wrote:
> On Sun, 4 Sept 2022 at 10:31, Reuben Thomas  wrote:
>> On Sun, 4 Sept 2022 at 04:13, Philip McGrath  
>> wrote:
>>> 
>>> However, in some cases you might really want a program other than `racket` 
>>> as the entry point for your language: for instance, maybe you want to have 
>>> flags for controlling where the output goes. One example of such a program 
>>> is the `scribble` executable included in the main Racket distribution. The 
>>> implementation is in 
>>> <https://github.com/racket/scribble/blob/master/scribble-lib/scribble/run.rkt>,
>>>  and the associated "info.rkt" file 
>>> (<https://github.com/racket/scribble/blob/master/scribble-lib/scribble/info.rkt>)
>>>  arranges for `raco setup` to create a `scribble` to run it. (This example 
>>> uses the old mzscheme-launcher-names/mzscheme-launcher-libraries instead of 
>>> the newer racket-launcher-names/racket-launcher-libraries: see 
>>> documentation at 
>>> <https://docs.racket-lang.org/raco/setup-info.html#%28idx._%28gentag._18._%28lib._scribblings%2Fraco%2Fraco..scrbl%29%29%29>.)
>> 
>> Thanks for the pointer.
>>  
>>> It is possible to use Racket to implement languages that don't use #lang, 
>>> but you would loose many advantages like IDE support and well-defined 
>>> separate compilation, and you would need to use some fairly low-level 
>>> mechanisms. Unless there is a hard requirement, I'd recommend that you just 
>>> use #lang in your programs.
>> 
>> I'm trying to write a standalone assembler (nothing to do with Racket), so 
>> I'm happy to lose this advantage!

You may indeed want a tool that supports files without #lang if you are working 
with an existing language and there isn't a way to make the #lang line 
acceptable to its existing grammar. That's about the only situation I can think 
of. Almost always, things will work better in the long run if you can make 
#lang work somehow, even for languages that have "nothing to do with Racket". 
For example:
 * Zuo programs start with #lang, even though the primary implementation of 
`#lang zuo/kernel` is written in C and runs without Racket. (IIUC Sam 
Tobin-Hochstadt has an almost-complete implementation of zuo/kernel in Racket, 
but the C implementation is needed to build Racket itself.) See 
<https://docs.racket-lang.org/zuo/>.
 * The `jsonic` and BASIC languages from Beautiful Racket have fairly little to 
do with Racket, but #lang is the basis for the syntax coloring and indentation 
mechanisms introduced in 
<https://beautifulracket.com/jsonic-2/drracket-integration.html>. Despite the 
title of the chapter, this isn't limited to DrRacket: you also get editor 
support for your language in Emacs' racket-mode, VSCode, and other clients of 
the Language Server Protocol.
(Small caveat: I have not actually read Beautiful Racket, just looked at it 
admiringly, recommended it to others, and wished MB had written it a year 
earlier than he did.)

> OK, I've had another look, and I still can't see how to do this, so I would 
> appreciate a hint. I have updated my repo to add a launcher script, but again 
> this only works with files that have a #lang line. As I said before, I have 
> worked out how to parse a file without a #lang line (just pass it to my 
> language's read-syntax), but I can't work out how to turn that into a module 
> and execute it. I guess I need something like dynamic-require that takes a 
> syntax-object and an expander module or #%begin-module macro as arguments?

For running a file without a #lang, you will need to use `eval`. Probably the 
right example to follow is the implementation of the plt-r6rs command-line tool 
(part of the main Racket distribution; source at 
<https://github.com/racket/r6rs/blob/master/r6rs-lib/r6rs/run.rkt>), which uses 
`get-module-code` from 
<https://docs.racket-lang.org/syntax/module-helpers.html#%28def._%28%28lib._syntax%2Fmodcode..rkt%29._get-module-code%29%29>
 and similar functions to control low-level evaluation and compilation. See 
more details about plt-r6rs at 
<https://docs.racket-lang.org/r6rs/Running_Top-Level_Programs.html> and in its 
--help output.

A different way to use eval would be to use `define-namespace-anchor` in the 
module that provides your hackasm language, explicitly read-syntax the given 
file, and evaluate the expressions with current-namespace parameterized to a 
namespace created using namespace-anchor->namespace.

Yet another option would be to split your files in two: have files in your 
language without #lang and separate files in a wrapper #lang that uses 
include-at/relative-to/reader 
<https://docs.racket-lang.org/reference/include.

Re: Fwd: [racket-users] Writing a "command-line front-end" for a language

2022-09-03 Thread Philip McGrath
On Sat, Sep 3, 2022, at 2:09 PM, Shu-Hung You wrote:
> -- Forwarded message -
> From: Shu-Hung You 
> Date: Sat, Sep 3, 2022 at 1:03 PM
> Subject: Re: [racket-users] Writing a "command-line front-end" for a language
> To: Reuben Thomas 
>
>
> Running `racket foo.asm` will produce the desired output, so a shell
> script that directly passes the arguments to Racket could work.
> Otherwise, just use (dynamic-require filename #f) in main.rkt.
>
> At the technical level, foo.asm is in fact an ordinary Racket module,
> just like any other .rkt file. Therefore it can be run in the same way
> using APIs that require and instantiate modules.
>
> ---
>
> On a side note, the forum has mostly moved to Discourse
> (https://racket.discourse.group/).
>

This is all correct, and you can also make just `./foo.asm` work: 
https://docs.racket-lang.org/guide/scripts.html

However, in some cases you might really want a program other than `racket` as 
the entry point for your language: for instance, maybe you want to have flags 
for controlling where the output goes. One example of such a program is the 
`scribble` executable included in the main Racket distribution. The 
implementation is in 
, 
and the associated "info.rkt" file 
()
 arranges for `raco setup` to create a `scribble` to run it. (This example uses 
the old mzscheme-launcher-names/mzscheme-launcher-libraries instead of the 
newer racket-launcher-names/racket-launcher-libraries: see documentation at 
.)

A couple additional details:

> On Sat, Sep 3, 2022 at 6:01 AM 'Reuben Thomas' via Racket Users
>  wrote:
>>
>> I have a partial implementation up and running using #lang lines. I would 
>> like to add a more traditional command-line interface, so I can (eventually) 
>> say:
>>
>> hackasm foo.asm
>>
>> on a file without a #lang line.
>>
>> My code is available at https://github.com/rrthomas/hackasm
>>
>> [...]
>>
>> So far, all I've worked out how to do is run the language's read-syntax 
>> function (imported from parser.rkt), and thereby return the parsed syntax 
>> object as the result.
>>
>> What I'd like to do is call the evaluator on the parse tree, but after a lot 
>> of scratching my head over the Racket documentation and search results, I 
>> cannot work out how to do that.

It is possible to use Racket to implement languages that don't use #lang, but 
you would loose many advantages like IDE support and well-defined separate 
compilation, and you would need to use some fairly low-level mechanisms. Unless 
there is a hard requirement, I'd recommend that you just use #lang in your 
programs. For example, the whole family of languages supported by the 
`scribble` command-line tool use #lang. (Indeed, #lang is how the tool can 
support a whole *family* of languages.)

> On Sat, Sep 3, 2022 at 6:01 AM 'Reuben Thomas' via Racket Users
>  wrote:
>>
>> I have implemented the language as a dialect, so that the "main.rkt" module 
>> is "free" to be used for the command-line interface. (Perhaps this can be 
>> fixed too, that would be nice!)
>>
>> [...]
>>
>> The contents of my main.rkt looks like this:
>>
>> #lang br/quicklang
>> (require "parser.rkt" "tokenizer.rkt" (submod "asm.rkt" reader))
>>
>> (module+ main
>>   (require racket/cmdline)
>>   (let ((filename
>>  (command-line
>>   #:program "hackasm" ;
>>   #:args (filename)
>>   filename)))
>> (read-syntax filename (open-input-file filename
>>

There are many possible ways to organize this: to some extent it's a matter of 
how you expect your language and cli to be used, and to some extent it's a 
matter of taste. I wouldn't consider your current organization "wrong", 
necessarily. But, if you'd like hackasm to be a multi-purpose entry point, one 
way to do that would be:

 1. Move "expander.rkt" to "main.rkt"

 2. Add a reader submodule like the one in "asm.rkt", but using just hackasm 
where you currently have hackasm/expander in the result of read-systax. 
Optionally, you might consider using syntax/module-reader (Guide: 
 Reference: 
)
 with the #:whole-body-readers? option for your reader submodule.

 3. Add a main submodule like the one in the current version of "main.rkt", but 
implemented more like scribble/run. You might want to write it as `(module* 
main racket/base ...)` unless you want to implement the command line tool in 
your hackasm language.

If you do that, `(require hackasm)`, `(module foo hackasm)` and `#lang hackasm` 
will all access your language, and running the file will run your 

Re: [racket-users] How shall I add collection path?

2022-08-08 Thread Philip McGrath
Hi,

On Mon, Aug 8, 2022, at 12:59 PM, Don Green wrote:
> For some reason, the collection directories below does not include the only 
> collection directory that I use: 
> /home/don/.plt-scheme/4.2.1/collects
> which I do have showing up in DrRacket's options: /Language/Choose Language/ 
> Collection Paths: 
> <>
> /home/don/.plt-scheme/4.2.1/collects
> --
> Error Msg:
> standard-module-name-resolver: collection not found
>   for module path: DG/all/copy-dir-without-subdirs
>   collection: "DG/all"
>   in collection directories:
>/home/don/.racket/8.1/collects
>/home/don/racket/collects/
>... [175 additional linked and package directories]
>   context...:
>/home/don/racket/share/pkgs/scribble-lib/scribble/search.rkt:69:5: loop
>[repeats 1 more time]
>/home/don/racket/share/pkgs/scribble-lib/scribble/xref.rkt:122:2: 
> xref-binding-tag
>.../private/coroutine.rkt:20:33
>/home/don/racket/share/pkgs/gui-lib/framework/private/coroutine.rkt:47:20
>/home/don/racket/share/pkgs/gui-lib/framework/private/coroutine.rkt:56:0: 
> coroutine-run
>
> /home/don/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
>
> /home/don/racket/share/pkgs/drracket/drracket/private/syncheck/blueboxes-gui.rkt:457:4:
>  update-the-strs method in docs-text-gui-mixin
>
> /home/don/racket/share/pkgs/gui-lib/framework/private/logging-timer.rkt:41:0: 
> log-timeline/proc
>/home/don/racket/share/pkgs/gui-lib/mred/private/wx/common/timer.rkt:34:38
>/home/don/racket/share/pkgs/gui-lib/mred/private/wx/common/queue.rkt:435:6
>/home/don/racket/share/pkgs/gui-lib/mred/private/wx/common/queue.rkt:486:32
>/home/don/racket/share/pkgs/gui-lib/mred/private/wx/common/queue.rkt:634:3
> 

It would be easier to help if you could keep you could keep your replies within 
a single thread.

This error message reveals that the update-the-strs method of 
docs-text-gui-mixin defined in 
,
 which seems to be part of how DrRacket displays "blue boxes" with 
documentation, is calling the Scribble function `find-racket-tag` defined at 
.

Could you explain what you are doing when you encounter this error? For 
example, are you hovering over an identifier in DrRacket? Is the error 
displayed in a dialog box saying "DrRacket Internal Error".

Also, it would help to know if you have made any changes to your Racket 
installation recently, such as changing to a new Racket version.

One possibility is that DrRacket may not communicate the collection paths set 
through the GUI to the functions that look up documentation. I'm not sure if 
DrRacket intends to support finding documentation for collections configured 
that way (though, even if not, it shouldn't cause an internal error).

More generally, it sounds like you have code in 
"/home/don/.plt-scheme/4.2.1/collects" that predates Racket's package system. 
You are of course free to continue to manage it using "collection links", but 
manipulating collection links directly is no longer recommended: it is 
difficult to do correctly, there are limited tools to assist you, and you may 
encounter bugs in tools that haven't thought about non-standard configurations. 
(Buggy tools should be fixed, of course! And I say this as someone who myself 
runs Racket in non-standard configurations that sometimes expose such bugs.)

But I think it would be much easier for you if you could structure the code in 
"/home/don/.plt-scheme/4.2.1/collects" as a package, as I suggested before: 
https://groups.google.com/g/racket-users/c/OtJV3yUDp2k/m/swka-AWXBwAJ

-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/cc0ac6a9-8e6b-4859-9daf-c80886049ee7%40www.fastmail.com.


Re: [racket-users] raco pkg for a one-directory, moveable installation

2022-08-08 Thread Philip McGrath
Hi,

On Mon, Aug 8, 2022, at 5:46 PM, knigh...@gmail.com wrote:
> Hello all
> 
> I'm trying to generate an installation that is self-contained, that I can 
> move to another machine just by tar-untar or zip-unzip.
> 
> The target machine may never be connected to the internet, so if I want to 
> install packages I must follow this procedure. 
> 

I would suggest running:

./bin/raco pkg config -i  --set default-scope installation

Setting the default scope to `installation` will cause commands like `raco pkg 
install` to install packages in the "pkgs" directory of your self-contained 
installation, rather than putting packages in a user-specific place by default.

(The more general `--scope` option is tricky to use correctly: I would think of 
it as a hook for higher-level tools.)

-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/dd82c2f0-af52-41d4-8231-2cd659389f62%40www.fastmail.com.


Re: [racket-users] looking for advice on a web background process manager

2022-01-05 Thread Philip McGrath
Hi,

On Thu, Dec 30, 2021 at 3:33 PM 'Wayne Harris' via Racket Users <
racket-users@googlegroups.com> wrote:

> I'm considering writing a manager for background processes --- such as
> send a batch of e-mail or other process that takes a while to finish ---
> for a web system.
>
> I see the challenge here as just writing something that will look like a
> very basic UNIX shell --- so I'll call it ``web-api-shell'' from now on.
> (``Web'' because it will be used by a web system through some HTTP API.)
>
> This thing has to be flawless.  I'm looking for design principles and
> advice.
>
> I don't know which language I will use, but I'd like to use Racket at
> least as a prototype.  I am looking at section 15.4 at
>
>   https://docs.racket-lang.org/reference/os.html
>
> and I'm not sure it gives me all the control I need.  I have a more
> lower view of the job --- fork(), execve(), waitpid(), SIGCHLD.  But I
> suppose Racket handles this much more elegantly that I would in C.
>

> Your advice will be very appreciated.
>
> (*) Where will it run
>
> It will run on GNU systems running the Linux kernel.
>
> (*) My own thoughts
>
> The interface to shell will be through HTTP requests, so this shell will
> likely be a web server of some sort.  But before I get involved in the
> web at all, I need the shell working flawlessly.
>
> So I need a laboratory first.  I could write a program that reads some
> named pipe on disk to get commands such as ``run this or that'' while I
> work.  (Later I can write a web server replacing this named-pipe
> interface.)
>
> Just like a UNIX shell, this web-api-shell must know all every process
> it runs.  I suppose the work is essentially fork(), execve() followed by
> waitpid().
>
> One concern I have is the following.  Is it possible for a process to
> simply ``get out of'' the shell?  What do I mean by that?  A process
> that does fork() and puts itself into background would leave the
> web-api-shell's control, wouldn't it?
>

> I think I must avoid that.  Perhaps I can't let just any process run.
> Perhaps the web-api-shell must only offer a few processes carefully
> written by myself --- so that I know they won't put themselves in
> background.  (For instance, I can't let them change PIDs, otherwise I
> won't have any idea who they are and that's a mess.  I'd love to somehow
> restrict system calls such as fork().)
>
> (*) Serialization
>
> I also think this web-api-shell must not be invoked in parallel.  So I
> guess I must use some queue of requests with no race condition and
> pull each request as it comes.  Any pointers on how to do this basic
> thing with my zero experience?
>
> (*) What is my level of training?
>
> In the past I've studied many parts of
>
>   Advanced Programming in the UNIX Environment
>   W. Richard Stevens
>
> I will definitely have to read it again to get work on this project.
> Can you mention any UNIX concepts that are of great relevance for this
> project?  I don't think I ever got my mind wrapped around things like
> sessions, session leaders and so on.  Are these concepts relevant to
> this application?
>

As you suspected, in Racket, the approach will be significantly different
than in C—hopefully, safer and more elegant!

The most basic concepts you will need to learn about are Racket's "green"
threads (not OS/POSIX threads) and "synchronizable events," which are based
on Concurrent ML. A good place to start would be the tutorial introduction
"More: Systems Programming with Racket":
https://docs.racket-lang.org/more/index.html

You will surely also want to read the Racket Guide chapter on "Concurrency
and Synchronization" (https://docs.racket-lang.org/guide/concurrency.html)
and the associated Racket Reference sections. I have found Matthew and
Robbie's paper “Kill-Safe Synchronization Abstractions” (
https://www.cs.utah.edu/plt/publications/pldi04-ff.pdf) an accessible
introduction to "synchronizable events" and the Concurrent ML
implementation. Andy Wingo, the Guile maintainer, has some blog posts about
how Concurrent ML's approach to concurrency works under the hood:
https://wingolog.org/archives/2017/06/29/a-new-concurrent-ml For maximum
detail, I can also recommend John Reppy's book *Concurrent Programming in
ML* from Cambridge UP (most recently revised in 2007, IIUC).

Once you understand Racket's approach to synchronization in general, I
think the way OS-level facilities (especially processes:
https://docs.racket-lang.org/reference/subprocess.html) interact with them
will make more sense. In particular, when we say that something is
"blocking" in Racket, we mean that it blocks a Racket-level green thread,
while allowing other Racket threads implemented by the same OS thread to
run concurrently. (It is possible to block the whole process using unsafe
functionality from the FFI, but that would generally be a bug.) This means
that even the simple `system*/exit-code` function, wrapped in a call to
`thread`, can do very well for running a 

Re: the end of the [racket-users] mailing list and the migration to Discourse as a forum for Racket

2021-11-22 Thread Philip McGrath
On Monday, November 22, 2021 at 10:16:49 AM UTC-5 Jens Axel Søgaard wrote:

> There is no need to rush things however. 
> In due course maybe the number of users on the forum will
> grow to outshadow the number of participants on the mailing list,
> but it will take some years. 
>

This was my opinion until the last few weeks, but I've become convinced 
that doing nothing is no longer a viable option.

It appears that some Gmail spam filter has decided that 
racket-users@googlegroups.com 
is a suspicious email address. It seems like roughly half of the legitimate 
traffic on the list is never reaching me and being marked as spam (at one 
of two or three hops on its way—but I have every reason to believe the 
situation would be as bad or worse for a new subscriber with a less 
convoluted email setup, especially since even mail from people I've 
corresponded with directly is being marked as spam). This seems reasonable, 
actually, since the Google Groups filters don't seem to be stopping a very 
high proportion of total traffic on the list from consisting of all-caps 
spam in Italian with some obviously-off-topic keywords.

I understood John's email not as a threat to shut down this list 
immediately, but as a call for those (like me) who have been skeptical of 
Discourse to give it a serious try and look for any actual, concrete 
problems, with an eye toward making it the primary Racket communication 
channel. The points raised about the terms of service seem like a good 
example of this. Hopefully they can be fixed. If Discourse's "mailing-list 
mode" works well enough that people like me can treat it like a generic 
mailing list, while people who want a fancy web app can use it, that seems 
ideal. The discussion yesterday about starting new topics by email seems 
important, if that's the goal: 
https://racket.discourse.group/t/how-to-enable-mailing-list-mode/167/3

As someone not involved in the decision-making process, I also want to say 
(more in response to previous discussions than this one) that hosting a 
high-volume public mailing list like racket-users is not a trivial job. I 
have enough experience running Postfix to know I shouldn't volunteer. Take 
note, for example, of the multi-billion-dollar corporation that isn't doing 
an adequate job hosting this list currently. It's also worth emphasizing 
that Discourse is free/libre and open source software under the 
GPL-2.0-or-later. Google Groups is not!

Finally, I think this would be a great area for the Software Freedom 
Conservancy to provide support. I'm sure Racket isn't the only project 
facing these questions. At a minimum, it would be good to have them review 
the legal boilerplate, since some of them are lawyers and I, for one, am 
not. If there were some concrete reason not to use the hosting generously 
offered at no charge by the company Civilized Discourse Construction Kit, 
Inc. (but at first glance they seem to be doing many things right), perhaps 
the Conservancy could provide hosting for Racket and other member projects. 
If ultimately we were to determine that Discourse wouldn't work as a 
mailing-list replacement—but I think we should seriously try it before 
jumping to that conclusion!—I've noted before that the Conservancy hosts a 
few mailing lists: https://lists.sfconservancy.org Mailman 2 would be a 
step in the wrong direction as far as friendly UI, but I've been impressed 
by Mailman 3 with HyperKitty (also more than the Google Groups web UI, 
which I've never especially liked): e.g. 
https://lists.wikimedia.org/hyperkitty/list/wikimedi...@lists.wikimedia.org/ 
Presumably they will upgrade their server to Debian 11 and get that 
improvement (https://packages.debian.org/bullseye/mailman3-full).

-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/858cc8d7-7dbb-46ea-b1ad-d2a32a4c722dn%40googlegroups.com.


Re: [racket-users] Racket Discourse

2021-11-21 Thread Philip McGrath
I've long been in the basically-content-with-the-mailing-list camp, but
I've recently come around to the view that the status quo is untenable. I
looked into it after Racket 'Con and discovered the mailing list had shrunk
especially much for me, because the Google Groups spam filters were letting
through so much spam that Google spam filters on one hop of my receiving
side have been classifying a great deal of legitimate mailing list traffic
as spam.

I haven't done much with Discourse yet, but it seems promising, and I hope
it works out.

I'd guess the list administrators have tried this already, but, just in
case, the Google Group settings should have a "Spam message handling"
setting that could be set to "Moderate without notifying content
moderators" (see
https://support.google.com/groups/answer/2464926?hl=en#posting=%2Csettings-reference%2Cadvanced-settings-reference).
If this is the official moment for giving up on this mailing list, it would
probably be good to turn up these settings to some draconian level anyway,
just to leave one fewer spam target on the internet.

-Philip

On Sun, Nov 21, 2021 at 6:08 PM 'John Clements' via Racket Users <
racket-users@googlegroups.com> wrote:

> Wait, you think that’s high traffic? Gee whiz, the mailing list *has*
> shrunk, hasn’t it?
>
> Okay, that was not an entirely serious reply, but I do think that in
> contrast to the discord & slack channels, the discourse is likely to be
> searchable and at least lightly curated six months from now. Also, if you
> take a look at the mailing list archive
>
> https://www.mail-archive.com/racket-users@googlegroups.com/
>
> … you’ll see a *shocking* amount of spam. Many of us don’t see this
> because we have semi-reasonable spam filters, but others are putting up
> with what looks like more than 50% spam on this list. That’s just not
> acceptable.
>
> John
>
>
> > On Nov 21, 2021, at 14:14, Sorawee Porncharoenwase <
> sorawee.pw...@gmail.com> wrote:
> >
> > I could be in the minority here, but as an early proponent of Discourse
> to replace the mailing list (even before RacketCon), I feel reluctant to
> join it after observing it for a while. It has a very high traffic, with
> almost 100% of the contents being cross-posted everywhere else (and vice
> versa) anyway.
> >
> > While I appreciate any efforts into promoting the site, I do think
> different content has different appropriate mediums. For example, FAQs
> probably should go to the wiki. There's no need to clutter anyone's inbox
> for this type of content.
> >
> > On Sun, Nov 21, 2021 at 10:09 AM 'John Clements' via Racket Users <
> racket-users@googlegroups.com> wrote:
> > TL;DR: Go to
> >
> >https://racket.discourse.group/invites/okLTSrQw1T
> >
> > and sign up for Racket Discourse (https://racket.discourse.group/)
> >
> > # Thoughts behind the move:
> >
> > Over time, it has become steadily more apparent that email-only
> > mailing lists are an outdated communication medium for the Racket
> > community. More recent arrivals in our community have generally
> > chosen other platforms like slack or discord to carry on discussions.
> > As a result, the signal-to-noise ratio of the racket users mailing list
> > has dropped below the level of viability.
> >
> > In short, it’s time to give up on the mailing list.
> >
> > After a good deal of research, it looks like there’s room for a whole
> > bunch of discussion platforms for Racket, but it also seems as though
> > there should be a “permanent” one; it should be archived, it should be
> > searchable in its entirety, and it should not tie us to someone else’s
> > plan to monetize user data.
> >
> > Given these criteria, the winner is Discourse, an open-source
> > messaging platform built by Jeff Atwood, Robin Ward, and Sam
> > Saffron. It has a reasonable business model (they host projects like
> > ours unless they get really big, whereupon you can either host it
> > yourself or pay them to do it); it’s widely used by other language
> > communities; and it appears to do most of what we want.
> >
> > # So where can I sign up?
> >
> > Sign up here: https://racket.discourse.group/invites/okLTSrQw1T
> >
> > The discourse platform has been in a “soft opening” phase for about
> > two weeks now, since RacketCon, and we have about a hundred users.
> > You’re receiving this message because we’d like to have *YOU* there
> > as well.
> >
> > # Can I still receive messages like a mailing list?
> >
> > Yes, you can. I have it enabled myself!
> > To use discord as a mailing-list:
> > Sign up, go to Preferences > Email, and tick “Enable mailing list mode'.
> >
> > Yours,
> >
> > John Clements & Stephen De Gabrielle
> >
> > --
> > You received this message because you are subscribed to the Google
> Groups "Racket Users" group.
> > To unsubscribe from this group and stop receiving emails from it, send
> an email to racket-users+unsubscr...@googlegroups.com.
> > To view this discussion on the web visit
> 

Re: [racket-users] How to learn the *core* of Racket?

2021-11-11 Thread Philip McGrath
On Thu, Nov 11, 2021 at 9:20 PM Yushuo Xiao  wrote:

> Thank you very much! I didn't know the set is not fixed. And thinking of
> them as an IR really helps.
>
> On Friday, November 12, 2021 at 12:15:39 AM UTC+8 johnbclements wrote:
>
>> That’s a true statement… but that set is by no means fixed.
>>
>
To nitpick a little, while it's true that the set of forms allowed in fully
expanded programs is not fixed, the last change was in Racket 6.3, adding
`(quote-syntax datum #:local)` and removing `letrec-syntaxes+values`:
https://docs.racket-lang.org/reference/syntax-model.html#%28part._fully-expanded%29

So, while not fixed, they are in fact quite stable, and the list of
identifiers is exposed through APIs like the `kernel-literals`

literal set for `syntax-parse` and, at a lower level,
`kernel-form-identifier-list`

and the `syntax/kerncase`

module. Authors of advanced macros that use `local-expand` and friends need
a general awareness of their shapes, e.g. to recognize definitions, splice
`begin`s, or recur into local binding forms, so changes have to be
unobtrusive to avoid breaking compatibility.

If you're interested in the low-level internals of Racket, you may also
want to read the manual section on Linklets and the Core Compiler
.

-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/0100017d121a0121-031c9bd8-10ec-45b2-84b3-91c93d4e19bc-00%40email.amazonses.com.


Re: [racket-users] [ANN] Splitflap: generating valid Atom and RSS feeds

2021-10-26 Thread Philip McGrath
On Tue, Oct 26, 2021 at 1:30 PM Sage Gerard  wrote:

> > Jon: I'm guessing you haven't actually tried this
> > Phillip: I guess the check doesn't happen as part of `tz/c`, but I can
> tell you that this program
>
> Yes, but I'm talking about code we were asked to give feedback on. I focus
> on `tz/c` because it is documented as a flat contract that checks for "an
> identifier from the IANA tz database ",
> but it does not parse the timezone name to check correctness.
>
I agree that I would have expected `tz/c` to consult the IANA database.

> My feedback says no validation occurs for the timezone name in a parameter
> for Splitflap. Joel indicated that parameter will go away below, and I'm
> glad to know of the tzinfo package.
>
Ah, the undocumented `feed-timezone` parameter is not what I had in mind:
I've been considering functions like `feed-item` and `episode`, which take
their created and updated timestamps as `moment?`s—I think any Racket
function that needs to operate on timestamps with timezones ought to
operate on `moment?`s (or perhaps `moment-provider?`s). Gregor does ensure
that `moment?`s are valid.

-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/0100017cbdcf4c28-12d5c1df-f829-4ca2-af95-ec768b5309da-00%40email.amazonses.com.


Re: [racket-users] [ANN] Splitflap: generating valid Atom and RSS feeds

2021-10-26 Thread Philip McGrath
On Tue, Oct 26, 2021 at 12:01 PM Sage Gerard  wrote:

>
>- The IANA's timezone database changed this month, and gregor's last
>commit was 2 years ago.
>
> My comment was not meant to say that timezone math is easy to replace, or
> even that gregor isn't a fit. It's to say  that I'm not seeing correct
> answers without a name lookup in front of tz/c, and the latest data from
> the IANA.
>
The timezone database lookup logic is in the `tzinfo` package (
https://docs.racket-lang.org/tzinfo/index.html), last updated two *months*
ago: https://github.com/97jaz/tzinfo Further, on Unix and Mac, it simply
consults the OS-provided IANA timezone database. (It does look like the
`tzdata` package that ships the database for Windows or other cases when
you don't rely on the OS could use a pull request, though:
https://github.com/97jaz/tzdata)

On Tue, Oct 26, 2021 at 12:01 PM Sage Gerard  wrote:

>
>- Assuming I have the right repository link, gregor's tz/c contract is
>only (or/c string? (integer-in -64800 64800)) [1]. I can set the
>feed-timezone parameter in Splitflap to an arbitrary string and the guard
>won't stop me.
>
> I guess the check doesn't happen as part of `tz/c`, but I can tell you
that this program:

#lang racket
(require gregor)
(now/moment #:tz "Nowhere/Middle")

raises an exception saying, "Cannot find zoneinfo file for
[Nowhere/Middle]".

-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/0100017cbd702ddf-9c09541b-7c04-42d5-99be-00e7162b4dc6-00%40email.amazonses.com.


Re: [racket-users] [ANN] Splitflap: generating valid Atom and RSS feeds

2021-10-26 Thread Philip McGrath
Excited to try this! Generating Atom and RSS feeds is on the to-do list for
one of my current projects.

On Mon, Oct 25, 2021 at 10:25 PM 'Joel Dueck' wrote:

>
>- MIME types: Yes, I should use/add a more complete extension→type
>mapping, though I probably will continue not to validate MIME types against
>the IANA list. (My somewhat erroneous note in the docs notwithstanding, it
>turns out having a non-IANA MIME type or a valid but mismatched type in an
>enclosure doesn’t actually cause feed validation errors.)
>
>
Since you have a dependency on `web-server-lib`, instead of shipping your
own "mime.types", you can write:

(define-runtime-path mime.types
  '(lib "web-server/default-web-root/mime.types"))

to use the one it ships. It seems generally useful enough that maybe it
should be split into a package like "web-server-mime-types-lib". I've been
meaning for years to improve the file, and the general
`make-path->mime-types` functionality, with some upstream database, perhaps
the fairly comprehensive one at https://github.com/jshttp/mime-db (which
pools data from Apache, Nginx, and IANA, and is used by e.g. Github Pages).


>
>- language-codes: yes this should be a value, not a procedure. Will
>change it.
>
> `system-language` should use `delay/sync` to be safe for concurrent access.

I'm not totally clear about all of the different sets of requirements (RSS,
Atom, and, de facto, Apple), but I thought there were more language codes
permitted than ISO 639-1 (e.g. https://www.rssboard.org/rss-language-codes
points to ISO 639-2, and
https://validator.w3.org/feed/docs/rfc4287.html#rfc.section.4.2.7.4 for
Atom points to RFC 3066. These standards also allow for the assignment of
new codes (and, at least for ISO 639-3, deprecation). I hope the right set
of codes might be in the one of the CLDR packages (also used by Gregor): if
so, I'd recommend getting it from there.


>
>- Removing dependencies: yes, I see the appeal. I’m really not eager
>to reimplement all the timezone handling and temporal comparison stuff in
>gregor, though.
>
> Please keep depending on Gregor! I think it's one of the treasures of the
Racket library, and we should all just use it, as even the documentation
for `racket/date` suggests
,
rather than create any more, as Greenspun might put it, "ad hoc,
informally-specified, bug-ridden, slow implementation[s] of half of" Gregor.

On a different topic, for the XML stuff, is there a requirement that
embedded HTML be represented with the CDATA lexical syntax? Under normal
XML rules, this xexpr:

`(content
  ,(cdata #f #f ""))

should be semantically equivalent to this one:

'(content "Hi & < >")

which would generate the XML concrete syntax:

divpHi  
/p/div

This has the advantage of avoiding prohibition on `]]>` within CDATA
concrete syntax, and it lets everyone manipulating these feeds in Racket
avoid the need to add and remove "" from the string
inside the CDATA struct. (Tangentially, AIUI the convention is to use `#f`
for the start and stop fields when creating cdata and p-i structures in
code, though apparently the docs for `source`

say something about symbols.)

Regardless, rather than using an ad-hoc encoding scheme for the entities
Apple has odd rules about, you can just replace them with symbols or
`valid-char?`s and let the library take care of everything. Well, my
example code for that has grown complete enough that I'll just make a PR
shortly :)

-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/0100017cbc714ad9-99e03c7f-69ae-43c1-92d4-58536cab5278-00%40email.amazonses.com.


Re: [racket-users] Having trouble getting documentation to generate

2021-09-28 Thread Philip McGrath
On Tue, Sep 28, 2021 at 3:30 PM Ben Greenman 
wrote:

> On 9/28/21, David Storrs  wrote:
> > $ raco pkg remove try-catch
> > raco pkg remove: invalid `deps' specification
> >   specification: '("base" racket/format racket/string)
> >
> > That is not the deps specification from the info.rkt file so I don't know
> > where it's getting that.
>
> Some package somewhere must have that bad info.rkt file.
>

I'm not sure exactly what `raco pkg` should do when it encounters such an
error, but it probably shouldn't just leave you stuck with unwanted
erroneous packages forever.

I haven't tried `raco setup` to look at its output, but one possible
improvement would be for whatever code complains about the "invalid `deps'
specification" to always report the invalid file's path.

-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/0100017c2f6138bb-a571c1dd-eacf-4a18-8481-48f1a50dd0fa-00%40email.amazonses.com.


Re: [racket-users] Can a new user defined pkg encompass nothing more than references to previously defined pkgs?

2021-06-07 Thread Philip McGrath
On Mon, Jun 7, 2021 at 1:46 PM Don Green  wrote:

> Following from Philip's 3rd point, which I think is very relevant, I
> surmise that I really should:
> 1) build libraries ;that reference my code (These libraries are built
> within a user-defined package.)
>

This seems right, though I would say that the libraries will be your code.


> 2) Then my initial question, refined, becomes:
> Can a new user defined library encompass nothing more than references to
> previous user defined libraries? (I think the answer is: yes).
>

Yes.


> 3) Since the library is said to be referenced through their
> collection-based paths this leads me to wonder:
> Am I expected to create my own pathed-collection that gives my code
> independence from the default installled racket pathed-collections?
>
> Then am I to use: (current-library-collection-links paths) to link my
> collection into the racket system?
>

It is exceedingly unlikely that using `current-library-collection-links` is
what you want. I would go so far as to say that you should not need to use
any feature relating to collection links in normal use of Racket: those
features are really for tinkering under the hood with new ways of building
and installing Racket.

I'm going to try to offer some concrete advice, with a lot of
assumptions—they may be wrong, but perhaps laying them out will highlight
anything I've missed. Given that you've mentioned the path
"/home/don/.plt-scheme/4.2.1/collects", it sounds like you have some code
that predates Racket's package system. The right thing to do is to turn
that code into a package and install it. (Note that, in Racket, making
something a package doesn't mean publishing it. It may exist only as a
directory on your local file system.)

Let's assume you have your code in paths like
"/home/don/.plt-scheme/4.2.1/collects/tic-tac-toe" and
"/home/don/.plt-scheme/4.2.1/collects/tetris". Make a new directory
"/home/don/my-first-racket-package" and copy your code from
"/home/don/.plt-scheme/4.2.1/collects" there. Create a file
"/home/don/my-first-racket-package/info.rkt" with contents like this:


#lang info

(define pkg-name "my-first-racket-package")
(define collection 'multi)
(define pkg-desc "My first Racket package")
(define version "0.0")
(define pkg-authors '(don))

(define deps
  '("base"))

(define build-deps
  '())


At this point, you should have a directory structure like this:

   - /home/don/my-first-racket-package/
  - info.rkt
  - tetris/
 - … various files and directories …
 - tic-tac-toe/
 - … various files and directories …

An important caveat: for simplicity, I've assumed your code in
"/home/don/.plt-scheme/4.2.1/collects" is not intermingled with the default
collections of minimal Racket. If they are mixed up, copy only your files.
(Corresponding collection directories will effectively be merged.)

Then, install your new package. You should not need to set any environment
variables or change anything in "config.rktd": indeed, it would be best if
you do not. You may want to uninstall and replace your system Racket
installation to get a clean configuration. To install the package, run:

cd /home/don/my-first-racket-package/ && raco pkg install

If your code uses functionality outside of minimal Racket, you may get a
warning about missing dependencies. Running:

raco setup --fix-pkg-deps my-first-racket-package

will attempt to add the necessary declarations to your "info.rkt" file.

In the future, you can run:

raco setup my-first-racket-package

to recompile all the code in your package. You can run these `raco setup`
commands regardless of your current working directory.

I 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/01000179e7db69dd-946513ef-9a47-437b-88eb-6655396b83ac-00%40email.amazonses.com.


[racket-users] Should minimal Racket include "base"?

2021-06-07 Thread Philip McGrath
There seems to be an inconsistency about whether "minimal Racket" 
includes the "base" package. The downloads for Mac OS and Windows seem 
to include it, but both the Linux downloads and the source tarballs have 
only "racket-lib".


I know that Mac OS, Windows, and "natipkg" use the "racket-lib" package 
to pull in platform-specific dependencies, but this discrepancy seems 
unrelated to that difference.



-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/3bcf82a0-8f9e-c822-0f34-a0bd30b8657d%40philipmcgrath.com.


Re: [racket-users] Could Racket be used as a "frontend" for a non-Racket language?

2021-06-06 Thread Philip McGrath
I haven't done much with this personally, but a few pointers in Racket:

   - Urlang uses Racket's macro system as a front-end for JavaScript (in
   the way you discuss with C#, not compiling Racket to JavaScript):
   https://github.com/soegaard/urlang
   - Alexis King's Hackett is an experimental Haskell-like `#lang`:
   https://lexi-lambda.github.io/hackett/ While it currently only runs on
   the Racket runtime system, Alexis' blog post, "Reimplementing Hackett’s
   type language: expanding to custom core forms in Racket", discusses the
   possibility of an alternate backend targeting GHC and goes into extremely
   useful detail about implementation techniques that can help:
   
https://lexi-lambda.github.io/blog/2018/04/15/reimplementing-hackett-s-type-language-expanding-to-custom-core-forms-in-racket/
   - The recent paper "Macros for Domain-Specific Languages" (
   https://dl.acm.org/doi/pdf/10.1145/3428297) presents a high-level API
   for doing many of the things the aforementioned blog post implements by
   hand. (Alexis is a co-author on the paper.)  The `ee-lib` library provides
   the API discussed in the paper:
   https://docs.racket-lang.org/ee-lib/index.html (I have done the by-hand
   approach to custom core forms, and I'm excited to try the new library.)

-Philip


On Sun, Jun 6, 2021 at 11:35 PM Robert Calco  wrote:

> Check out IronScheme ... it may
> be just what you're looking for.
>
> - Bob
>
> On Sun, Jun 6, 2021 at 10:02 PM Ryan Kramer 
> wrote:
>
>> I have no plans to work on this, but I am curious if this has been
>> discussed or attempted...
>>
>> Motivation: My job has been C# for many years and while C# is very
>> appropriate for most of the problems I encounter at work, sometimes a
>> problem comes along that makes me want more power. In those situations, I
>> think the language I want is "C# except now it's S-expressions and it has
>> Racket's macro system."
>>
>> And then I wonder if an alternate version of C# could be implemented this
>> way:
>> 1) Create a new grammar for what a fully-expanded C# AST is. This will be
>> in terms of Racket syntax objects, just like Racket's definition of a Fully
>> Expanded Program.
>> 2) Write a compiler that generates CIL (the bytecode) given a
>> fully-expanded C# AST.
>> 3) Use Racket's #lang mechanism and macro system to implement the surface
>> language.
>>
>> Now this new C# could borrow a lot of power from Racket, right? For
>> example, I could make all of Racket available during expansion! Even if I
>> don't want C#-the-surface-language to have macros at all, why shouldn't I
>> keep the Racket-powered backdoor open? As long as you generate a valid C#
>> AST, I should be able to compile it for you.
>>
>> The #lang mechanism and Scribble are two other nice things that could
>> probably be adapted into the new C# if desired.
>>
>> I can understand why Microsoft wouldn't do this. But I've seen enough
>> hobby languages, and I'm surprised that none of them do this. Reusing a
>> backend (like dotnet or the JVM) is common, reusing a "frontend" is
>> something I've never seen. Is Racket's macro system too specific to
>> Racket's definition of a fully-expanded program? (The little bit I've done
>> with local-expand and stop-ids makes me think it would work fine.) Is there
>> something else that would make this approach more trouble than it's worth?
>>
>> --
>> You received this message because you are subscribed to the Google 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/cc7c1792-ba59-400f-856a-3bb02a6096fbn%40googlegroups.com
>> 
>> .
>>
>
>
> --
> *Bob Calco*
>
> bobca...@gmail.com
> 813-997-3583 (work mobile)
> 813-523-3751 (personal mobile)
>
> *"But you can catch yourself entertaining habitually certain ideas and
> setting others aside; and this, I think, is where our personal destinies
> are largely decided." *-- *Alfred North Whitehead*
>
> *"And now I see with eye serene the very pulse of the machine." *--* William
> Wordsworth*
>
> --
> You received this message because you are subscribed to the Google 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/CAATHPo3MJDtgxrt3FKPTRvt-avaniq4LTwF6VH_SSe%3DvAV3V4A%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google 

Re: [racket-users] Can a new user defined pkg encompass nothing more than references to previously defined pkgs?

2021-06-06 Thread Philip McGrath
On Sun, Jun 6, 2021 at 7:59 PM Ben Greenman 
wrote:

> On 6/6/21, Don Green  wrote:
> >
> > Can a new user defined pkg encompass nothing more than references to
> > previously defined pkgs so that every  user created module references a
> > single user defined pkg?
>
> Yes. You can make a new package whose main.rkt provides lots of
> identifiers from other packages.


I can see at least three different interpretations of the question. In an
attempt to clear up any possible misunderstandings, let me try to pull them
apart:

   1. Ben's answer is correct if the question really meant, "so that every
   user created module references a single user defined" *module*. The
   omnibus module (`#lang reprovide` is a good choice) may be in the same
   package as other user-defined modules that use it, or additional packages
   may depend on the package containing the omnibus module.
   2. If the question instead meant, "so that every user created" *package*
   "references a single user defined pkg", the answer is also yes, but in a
   different way. A good example of this would be the "typed-racket" package,
   which combines the packages "typed-racket-lib" and "typed-racket-doc". The
   "typed-racket" consists simply of an "info.rkt" file with appropriate
   definitions for `deps` and `implies`.
   3. On the other hand, if the question literally meant, "so that every
   user created module references a single user defined pkg", then the answer,
   strictly speaking, is no, because modules can not refer to packages per se.

The third possibility is where I see the most potential for
misunderstanding. From Package Management in Racket", § 1.1 "What is a
Package?" <
https://docs.racket-lang.org/pkg/getting-started.html#%28part._.What_is_a_.Package_%29
>:

> A package
> 
> is not something that you refer to directly in your Racket programs.
> Instead, a package
> 
> is a set of libraries that fit into the collection
> 
> hierarchy, and you refer to libraries through their collection
> -based
> paths. Libraries that are close in the hierarchy may be provided by
> different packages, while a single package may provide libraries that are
> far from each other in the hierarchy (but that are conceptually related,
> somehow).
>
> Racket documentation tells you which package provides a given library. For
> example, the documentation for the pict/face
> 
> library says that it is provided by the pict-lib package.If you’re
> reading this in a web browser, click pict/face
> 
> to go straight to its documentation.
>
> Over time, packages may be refactored so that a library moves to a
> different package, but the original package should continue to provide the
> library, too, by declaring a dependency on the new package. More generally,
> a package is intended to have an interface that only grows in terms of
> libraries, bindings, and functionality, which provides a basic level of
> backward compatibility. Incompatible changes should be implemented in a new
> package.
>

-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/01000179e4110586-44232b9f-4563-478e-b00a-6b909a341c13-00%40email.amazonses.com.


Re: [racket-users] Cross-VM method for sending any input port to C runtime?

2021-05-23 Thread Philip McGrath
On Sun, May 23, 2021 at 7:57 PM Matthew Flatt  wrote:

> At Sun, 23 May 2021 14:57:42 +, Sage Gerard wrote:
> > Is there a cross-VM way to pass an arbitrary input port to the C
> > runtime (e.g. via open-input-bytes), such that the C runtime can read
> > bytes on its own?
>
> No, not unless you know that the port's implementation is sufficiently
> constrained. In general, reading from a port can involve thread
> switches and synchronization, and those are not allowed in callbacks
> from foreign libraries.
>

Off hand, I think some some version of "sanitizing" an arbitrary port for
use from C is used by:

   - `racket/system` (here
   

   and here
   
),
   where the implementation comes from `racket/private/streams`;
   - `racket/draw`, for the various parts of Cairo that can read from or
   write to ports, in `racket/draw/unsafe/callback` (and maybe something
   similar in `racket/draw/private/write-bytes`?); and
   - `readline`, which uses callbacks rather than creating file-stream
   ports.

Would it make sense to expose some part of this functionality as a new
primitive?

(I'm not familiar with all of the constraints in these use-cases: maybe
they're different enough that the answer is "no".)

-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/010001799bd5ab46-d39f83a5-bb2d-49e5-8ce2-3315307742ac-00%40email.amazonses.com.


Re: [racket-users] Sharing scope in setup/cleanup for dynamic-wind?

2021-05-18 Thread Philip McGrath
On Tue, May 18, 2021 at 3:52 PM Sam Tobin-Hochstadt 
wrote:

> I think the key question is what you want to happen if you would need
> to re-run the "pre" thunk, because you re-enter the code via a
> continuation.
>
> In many cases, you don't want to support that at all …
>

Then you can use `call-with-continuation-barrier`, right?

(let* ([conn (connect-to-server)])
  (dynamic-wind
   void
   (λ ()
 (call-with-continuation-barrier
  (λ ()
(send-message conn "hi"
   (λ ()
 (finalize-connection conn

-- 
You received this message because you are subscribed to the Google 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/0100017981191578-b5eaa465-de2a-4f1f-a4f1-d2976db88de0-00%40email.amazonses.com.


Re: [racket-users] Packages not being listed after reinstalling

2021-05-15 Thread Philip McGrath
Hi!

I have been working on Guix's packaging of Racket, though I'm not
especially experienced with Guix.

The ssl-connect issue sounds like it may be related to §2.6 "Application
Setup" in the Guix manual, especially the subsections about "X.509
Certificates" and perhaps the "Name Service Switch":
https://guix.gnu.org/manual/en/html_node/Application-Setup.html#Application-Setup
Do you have all of that working properly?

I'm not familiar with the first error, and, in particular, I don't usually
use Racket from Emacs. If the Guix setup doesn't fix the problem, more
details would be helpful, especially the output of `which raco` and `raco
pkg config catalogs`.

-Philip


On Sat, May 15, 2021 at 8:23 PM Dimaugh Silvestris <
dimaughsilvest...@gmail.com> wrote:

> I recently did a clean Ubuntu reinstall, but decided this time to try Guix
> as a package manager and install as much as possible from there. Guix might
> be the issue here, perhaps something else.
> Now I can't run 'raco pkg install', and emacs gives me:
> ;--
> ; Can't suggest packages to install, because pkg/db get-catalogs is '().
> ; To configure:
> ; 1. Start DrRacket.
> ; 2. Choose "File | Package Manager".
> ; 3. Click "Available from Catalog".
> ; 4. When prompted, click "Update".
> ; --
>
> I follow the suggestion, but I get:
> ssl-connect: connect failed (error:1416F086:SSL
> routines:tls_process_server_certificate:certificate verify failed)
>
> --
> You received this message because you are subscribed to the Google 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/CAN4YmRGs2Qc1HXuFSa1KrqGsvWxvZ-KtsGs15vXP1BECMdEf_w%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/0100017972b19987-e18cf59f-285c-4b61-8d59-d9fde9ca894c-00%40email.amazonses.com.


Re: [racket-users] Injecting local contracts for prefab constructors

2021-05-09 Thread Philip McGrath
Here's another minimally-tested sample implementation. A more robust
solution might try to chaperone the struct type, as well, to protect
reflective access to the constructor—but I wonder if that really makes
sense when you are working with prefab structs. If you can explain more
about your requirements, it might be possible to suggest better approaches.


On Sun, May 9, 2021 at 7:57 PM Ryan Culpepper 
wrote:

> I'm not clear on what constraints you're working under with respect to
> modules, but hopefully you can adapt this to your needs.
>
> One option is to use a combination of `define-module-boundary-contract`
> (or `define/contract`) and `define-match-expander` to bind a name that can
> be used as a contracted constructor and as a match pattern. (If you want to
> extend the struct type, though, you still need to use the real one.)
>
> Another option would be to "forge" a new compile-time struct-info based on
> the original struct-info but replacing the constructor.
>
> Minimally tested sample implementations attached.
>
> Ryan
>
>
> On Mon, May 10, 2021 at 12:23 AM Sage Gerard  wrote:
>
>> I have a project with 57 prefab structure types. I need to construct
>> instances using a *local* contract (module level contracts do not fit my
>> needs here). Since I cannot define guards, the solution is easy enough.
>> (struct foo (num) #:prefab)
>> (define/contract make-foo (-> real? foo?) foo)
>>
>> Problem: I already have a few hundred constructor calls without
>> contracts. I could either A) rewrite them all to use contracted
>> constructors, or B) attach local contracts in a sweet spot so that I don't
>> have to rewrite anything else.
>>
>> I prefer option B, but it doesn't look like I can attach a local contract
>> to a constructor with `struct` alone, or even with an impersonator. When I
>> hack around to rebind or hide the constructor's identifier, I break
>> compatibility with `match` and `defstruct*`.
>>
>> If you were in my position, what would you do?
>> --
>>
>> ~slg
>>
>> --
>> You received this message because you are subscribed to the Google 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/0a16cfbe-4789-a939-796e-5f6f9da21626%40sagegerard.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/CANy33qmngGoVoAok6%2BR885jkh8MroMqYHpOd6XtjCSH7iiESQA%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/01000179539521f3-7e3fc7cf-409e-4574-8917-5d2ef798fa1c-00%40email.amazonses.com.


prefab-transformer.rkt
Description: Binary data


Re: [racket-users] Is this a good uninstall then install Racket plan...

2021-04-13 Thread Philip McGrath
On Tue, Apr 13, 2021 at 10:31 PM John Clements 
wrote:

> What if he has directories that aren’t part of an installed package? That
> was my concern, and why I suggested manually deleting compiled subdirs.
>

That's right, but given:

On Tue, Apr 13, 2021 at 8:16 PM Don Green 
wrote:

> Welcome to Racket v8.0 [cs].
> > (current-library-collection-paths)
> '(#
>   #
>   #)
>
> My code files all begin here: /home/don/.plt-scheme/4.2.1/collects/...
>

It looks like the code files are all linked as collections directly (i.e.
not via the package system). I think `raco setup --clean && raco setup`
should take care of anything under those directory trees (recursively).

-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/01000178ce42001c-bfac9d6d-505f-4c5a-b532-7738980da227-00%40email.amazonses.com.


Re: [racket-users] Is this a good uninstall then install Racket plan...

2021-04-13 Thread Philip McGrath
On Tue, Apr 13, 2021 at 8:21 PM 'John Clements' via Racket Users <
racket-users@googlegroups.com> wrote:

> It sounds to me like the solution might be much much simpler than
> re-installing an earlier version of racket. Here’s what I recommend.
>
> 1) Delete all of the “compiled” subdirectories in your development path.
> 2) run “raco setup”.
>

I think you should be able to automate finding and updating the "compiled"
subdirectories by running:

raco setup --clean && raco setup

-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/01000178ce19df5f-46515da8-c86d-4a02-ad84-615dc7c8bc7d-00%40email.amazonses.com.


Re: [racket-users] Re: Executable file size and raco demod

2021-04-07 Thread Philip McGrath
On Tue, Apr 6, 2021 at 7:54 PM Matthew Flatt  wrote:

> In the cross-compilation path that the release builds use, there was an
> unintended layer of compression. (I noticed the size difference before,
> but had not yet investigated.) Checking that again, if the extra layer
> is used, the 10% or so savings in file size causes a 5% decompression
> slowdown for loading. Compressing just the code, meanwhile, makes load
> times faster on machines that I tried. So, I think the current
> (non-cross) default is still the best choice for most situations, and
> I'll adjust cross-compilation to match.
>
…

> Compressing embedded boot files would save 30 MB, which would make a
> big difference in your case. Compressed boot files take 20-40ms longer
> to load on a typical machine, which is significant relative to the
> minimal load time, but it's very little time in many situations.
>

I don't have a problem with the current setup, but I've noticed that other
projects (e.g. OpenZFS) have been adding support for Zstd compression,
which has an especially wide range of options for trading off compression
ratio and (de)compression speed. I don't know if it would be an improvement
here—apparently it is both faster and more efficient than gzip but doesn't
quite displace LZ4 from its core niche—but it's another direction that
could be explored.

-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/01000178ae65a584-6a7d1479-38e4-45c3-88f3-1e8b9700b6c1-00%40email.amazonses.com.


Re: [racket-users] Version metadata on Racket packages

2021-03-16 Thread Philip McGrath
Hi Jeff,

In fact there are two concepts here, and part of what I think confused you
is something I just discovered this week and plan to report as a bug:
https://pkgs.racket-lang.org/pkgs-all does not include the package's
version: that's what's discussed on the Package Concepts
 page you linked
to. The ?version= query parameter corresponds to the `'versions` (plural—in
hindsight this should have had a different name!) entry in the hash table,
which is documented slightly below the passage you quoted from the section
on Remote and Directory Catalogs

:

> -
>
> 'versions (optional) — a hash table mapping version strings and 'default
> to hash tables, where each version-specific hash table provides mappings to
> override the ones in the main hash table, and 'default applies to any
> version not otherwise mapped.
>
> Clients of a remote catalog may request information for a specific
> version, but they should also check for a 'versions entry in a catalog
> response, in case a catalog with version-specific mappings is implemented
> as a directory or by a file-serving HTTP server. A 'default mapping,
> meanwhile, allows the main hash table to provide information that is
> suitable for clients at version 5.3.6 and earlier (which do not check for
> 'versions).
>
This field is not a property of the package: it is part of the package
catalog. For example, when registering a package at
https://pkgs.racket-lang.org, you can optionally enter this data in a field
on the web form. The purpose is to implement "version exceptions", which
are documented further down the page—but clearly this section should be
much more pervasively linked to, because this is quite confusing:

> To make supporting multiple versions of Racket easier, the package catalog
> 
> software supports version exceptions. Version exceptions allow package
> authors to specify alternative package source
> s
> to be used when installing a given package using a specific version of
> Racket.
>
> For example, a package that uses on Racket 6.0-specific features could
> provide a version exception
> 
> for Racket 5.3.6 using a different branch or tag in the package’s GitHub
> repository, or a different zip archive, as package source. Users installing
> the package from Racket 6.0 will use the default source for the package,
> while those using Racket 5.3.5 will install from the alternative branch,
> tag, or archive.
>
This is very rarely useful, in my experience: I thought I might have used
it once, but it now seems I didn't.

With that confusing detour out of the way, on to your actual question:
"What is the intended use of the version field in the Racket package
manager?"

The summary you quoted is right, but there are some important details:

> A version is intended to reflect available features of a package, and
> should not be confused with different releases of a package as indicated by
> the checksum.
>

Let's imagine package A depends on package B. Both are at version 0.0. Now
B exports a new function, which A would like to use. If B is well-behaved,
it has changed its package info.rkt file to include:

> (define version "0.1")
>
Now A can write:

> (define deps
>   '("base"
> ["B" #:version "0.1"]))
>
and `raco pkg` will prompt anyone who installs or updates A but has an old
version of B to update B, too.

Note that there are some important differences from the semver systems used
by some other package managers: in particular, by design, the only possible
version constraint is "at least". When you write:

> It seems natural for packages that tightly depend on quickly evolving
> features of the Racket language to have a versioning scheme coupled to
> Racket's own versions.  On the other hand, for packages that work with a
> variety of possible Racket versions, it seems to make sense that said
> packages would have their own release cycles, compatibility aspirations,
> and semantic versioning contract.
>

Racket has some strong views about compatibility, both as a
language/distribution and in the design of its package manager. Racket has,
from my perspective, a fairly remarkable level of commitment to not
breaking existing code. The package system is modeled on an os-level
package manager, a deliberate choice to move away from the intricate
versioning mechanism of the older PLaneT package system. It is focused on
getting your files installed in the right place. The expectation is that
releases of a package will only add functionality, not remove or break it.
A package therefore need only increment the version number if it has added
something 

Re: [racket-users] bytevector-uncompress: internal error uncompressing

2021-03-15 Thread Philip McGrath
I've submitted a patch at https://issues.guix.gnu.org/47180 that I hope 
will resolve this issue.


-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/f7b8dfd6-ca6b-71b7-db6b-0cb39d2147ef%40philipmcgrath.com.


Re: [racket-users] bytevector-uncompress: internal error uncompressing

2021-03-15 Thread Philip McGrath

Aha! Running:

guix environment --ad-hoc --no-grafts racket -- drracket

launches DrRacket just fine.

My guess is that Racket CS is compressing string literals in compiled 
code. Currently, Guix patches Racket source files to include the 
absolute paths to foreign libraries in the store as string literals. 
There are a bunch of grafts for GTK and such: if I'm right, Guix somehow 
mangles the compiled code while attempting to apply the grafts.


I already thought this strategy was a bad idea. If it is really the 
problem, I should be able to patch it fairly quickly: I've already been 
experimenting along these lines.


-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/53940c03-4f40-3954-0cb4-3d4ae01c39a2%40philipmcgrath.com.


Re: [racket-users] bytevector-uncompress: internal error uncompressing

2021-03-15 Thread Philip McGrath

I can reproduce the error with just:
```
$ racket -l mred/private/wx/gtk/utils
$bytevector-uncompress: internal error uncompressing 
#"\0\0\0\0chez\310\224\206:\r()#\201\256R-d\205\233\24\363\5\20\201P\6A\v\300\0\16\f\6\31\2\f\6\f\275\0\1\0\362\bA\377e\0\1\0C\6A\21\3\v\300\0\201\265!\f\6\n\0\a\1\35\0\1+\0\360\27\201\375\300\0\0\0\17\205\210Z\0\0M\215\245\b\4\0\0M9fH\17\206fZ\0\0I\2...

  context...:
   body of 
"/gnu/store/bbnhjamch9125c412bl7ybf28a0jxrkd-racket-8.0/share/racket/pkgs/gui-lib/mred/private/wx/gtk/utils.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/79c97b4c-defb-3966-dc50-a79fa8f5c053%40philipmcgrath.com.


Re: [racket-users] bytevector-uncompress: internal error uncompressing

2021-03-15 Thread Philip McGrath

Jack, thanks for the pointer: I hadn't noticed this earlier.

On 3/15/21 12:49 AM, Jack Hill wrote:

```
$bytevector-uncompress: internal error uncompressing 
#"\0\0\0\0chez\310\224\206:\r()#\201\256R-d\205\233\24\363\5\20\201P\6A\v\300\0\16\f\6\31\2\f\6\f\275\0\1\0\362\bA\377e\0\1\0C\6A\21\3\v\300\0\201\265!\f\6\n\0\a\1\35\0\1+\0\360\27\201\375\300\0\0\0\17\205\210Z\0\0M\215\245\b\4\0\0M9fH\17\206fZ\0\0I\2...

  context...:
   body of 
"/gnu/store/bbnhjamch9125c412bl7ybf28a0jxrkd-racket-8.0/share/racket/pkgs/gui-lib/mred/private/wx/gtk/utils.rkt"
   body of 
"/gnu/store/bbnhjamch9125c412bl7ybf28a0jxrkd-racket-8.0/share/racket/pkgs/gui-lib/mred/private/wx/platform.rkt"

```


This appears to be an error uncompressing Racket's compiled code—whether 
generated by the Racket layer or the Chez Scheme layer, I'm not sure. 
The stack trace is pointing to the module `mred/private/wx/gtk/utils`, 
which is here: 
https://github.com/racket/gui/blob/master/gui-lib/mred/private/wx/gtk/utils.rkt


At first glance, the most unusual-looking thing about that module is the 
use of `(only-in '#%foreign ctype-c->scheme)` … but it could also be 
something else altogether. I'll try to investigate further, but thoughts 
from others would be very welcome!


-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/07f46e79-4fdb-49ab-63bd-2c106db077d1%40philipmcgrath.com.


Re: [racket-users] Is it safe to `read` untrusted input?

2021-03-05 Thread Philip McGrath
If you don't need the on-the-wire form to be human-readable, you should
look at `racket/fasl`: https://docs.racket-lang.org/reference/fasl.html It
can handle all of the acyclic data that `read` and `write` can (plus a
little extra), it *doesn't* have `read`'s many configuration parameters
that aren't really helpful for plain old data serialization, and it's fast
and efficient.

For a human-readable format, `call-with-default-reading-parameterization`
is the right answer.

-Philip


On Sun, Feb 28, 2021 at 5:33 PM Ryan Kramer 
wrote:

> Thanks everyone. I feel fine to use `read` for this use case now. I
> overlooked `call-with-default-reading-parameterization` which specifically
> mentions "reading from untrusted sources" so that is very reassuring.
>
> On Sunday, February 28, 2021 at 3:36:29 PM UTC-6 John K wrote:
>
>>
>>
>> On Feb 28, 2021, at 2:50 PM, Ryan Kramer  wrote:
>>
>>
>> […]
>>
>>
>> I could use JSON or XML, but that just seems silly when you have a Racket
>> client talking to a Racket server.
>>
>> Are my concerns founded? Are there any existing solutions? Thanks for any
>> advice.
>>
>>
>> I don’t think this necessarily answers your question, at least not
>> directly, but receiving code from a remote client is certainly a potential
>> security risk.
>>
>> Fortunately, Racket is well-adapted to writing (and parsing) a language
>> (DSL) inside of the language.
>>
>> Personally I’m a fan of object capability mechanisms. In Scheme and
>> Racket, some interesting places to start might be
>>
>> * Jonathan Rees’ Scheme-based “security kernel” paper:
>> http://mumble.net/~jar/pubs/secureos/secureos.html
>> * Marketplace by Tony Garnock-Jones: http://tonyg.github.io/marketplace/
>>
>> Christoper Lemmer Webber (may be on this list even?) is working on
>> something called Spritely Goblins, an implementation, in Racket, of the
>> CapTP/VatTP protocols that were invented by Mark Miller and others in the E
>> language (
>> http://www.erights.org/elib/capability/ode/ode-capabilities.html) and
>> now being used in Javascript/SES.
>>
>> * https://docs.racket-lang.org/goblins/index.html
>>
>> And finally, for serializing object (capabilities), the other piece of
>> relevant interesting work is CapnProto by Kenton Varda:
>> https://capnproto.org/
>>
>> Have fun :)
>>
>> - johnk
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Racket Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to racket-users...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/racket-users/a2580765-3cc2-482b-8d20-f62dc1e1dc91n%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/cf2a07a1-adff-4a4b-9856-679c98c797cfn%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/01000178016e58fb-d8cf5929-bf98-4cc3-add5-95f2b33fb63a-00%40email.amazonses.com.


Re: [racket-users] Unsafe structs

2020-12-21 Thread Philip McGrath
On Mon, Dec 21, 2020 at 7:30 PM Robby Findler 
wrote:

> Is Typed Racket able to prove that your use of unsafe accessors is
> actually safe?
>

On a similar note, my understanding is that, even without types, in a
program like this:
#lang racket
(struct cell (val))
(λ (x)
  (if (cell? x)
  (cell-val x)
  ...))
the compiler can optimize the use of `cell-val` guarded by `cell?` to omit
the redundant check. I think the optimized version should be as good as
`unsafe-struct-ref`.

If that's the case, the only extra invariant for `unsafe-struct*-ref` is
that it does not work on impersonators (including chaperones, IIUC). If you
need the extra performance, I think you can get it safely by declaring your
structs as `#:authentic` (or equivalently adding `prop:authentic`), which
will cause the struct types involved not to support impersonators:
`impersonate-struct` and similar functions will raise exceptions. On the
other hand, if you need to support impersonators, then it really is unsafe
to use `unsafe-struct*-ref`.

-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/01000176c2ba-c84b6b21-d30d-488f-b4ad-43878e96f06d-00%40email.amazonses.com.


Re: [racket-users] DrRacket caret blink

2020-11-28 Thread Philip McGrath
I put up a very quick version on GitHub: 
https://github.com/LiberalArtist/disable-blink-caret-drracket-tool

You should be able to install it with `raco pkg install 
https://github.com/LiberalArtist/disable-blink-caret-drracket-tool`.

Hope this helps!

-Philip
On Saturday, November 28, 2020 at 3:49:39 PM UTC-5 Philip McGrath wrote:

> On Sat, Nov 28, 2020 at 3:10 PM 'Mark' via Racket Users <
> racket...@googlegroups.com> wrote:
>
>> (But it is still a pity that there's no config option to turn off 
>> blinking in DrRacket.)
>>
>
> I agree that this would be a valuable feature to add, not just to DrRacket 
> but to `racket/gui` in general. It seems the blinking behavior is 
> controlled with a hard-coded interval here: 
> https://github.com/racket/gui/blob/aa5ebfec7402bdcbc3813f822caedb4a3ceb2c4c/gui-lib/mred/private/wxme/editor-canvas.rkt#L84-L104
>  
> Probably the hard part of a solution would be detecting the user's 
> preference properly across platforms.
>
> In the meantime, I think it would be possible for a DrRacket plugin 
> <https://docs.racket-lang.org/tools/Extending_the_Existing_DrRacket_Classes.html>
>  
> to use `drracket:get/extend:extend-interactions-text` and 
> `drracket:get/extend:extend-definitions-text` to override the 
> `blink-caret` 
> <https://docs.racket-lang.org/gui/editor___.html#(meth._(((lib._mred%2Fmain..rkt)._editor~3c~25~3e)._blink-caret))>
>  
> method with a no-op.
>
> -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/3cd9b003-43d6-4611-85f3-69ce981705ddn%40googlegroups.com.


Re: [racket-users] DrRacket caret blink

2020-11-28 Thread Philip McGrath
On Sat, Nov 28, 2020 at 3:10 PM 'Mark' via Racket Users <
racket-users@googlegroups.com> wrote:

> (But it is still a pity that there's no config option to turn off blinking
> in DrRacket.)
>

I agree that this would be a valuable feature to add, not just to DrRacket
but to `racket/gui` in general. It seems the blinking behavior is
controlled with a hard-coded interval here:
https://github.com/racket/gui/blob/aa5ebfec7402bdcbc3813f822caedb4a3ceb2c4c/gui-lib/mred/private/wxme/editor-canvas.rkt#L84-L104
Probably the hard part of a solution would be detecting the user's
preference properly across platforms.

In the meantime, I think it would be possible for a DrRacket plugin

to use `drracket:get/extend:extend-interactions-text` and
`drracket:get/extend:extend-definitions-text` to override the `blink-caret`

method with a no-op.

-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/01000176109e430d-5ed26ea0-2ae2-440b-b2f3-1c1c3115f50c-00%40email.amazonses.com.


Re: [racket-users] Namespaces and modules

2020-11-15 Thread Philip McGrath
I think you’ll need `define-runtime-module-path` or
`define-runtime-module-path-index` to alert the executable builder to the
dynamic dependency.

On Sun, Nov 15, 2020 at 3:38 AM Dominik Pantůček <
dominik.pantu...@trustica.cz> wrote:

>
> >
> > Using ''sandbox as an argument to `namespace-require` to refer to a
> > local module is something like passing 'x to `eval` to try to refer to
> > a local variable `x`. The `namespace-require` procedure doesn't know
> > where it's being called from, so it doesn't work.
> >
> > Try `quote-module-path`, which expands at compile time to effectively
> > embed its context:
> >
> >  #lang racket/base
> >  (require syntax/location)
> >
> >  (module sandbox racket/base
> >(provide #%app #%datum test)
> >(define (test) (displayln 'test)))
> >
> >  (parameterize ((current-namespace (make-base-empty-namespace)))
> >(namespace-require (quote-module-path sandbox))
> >(eval '(test)))
> >
>
> This is exactly what I was looking for! Thank you. It's a pity I didn't
> ask in the past :)
>
> However, now I see a problem with creating executables with raco exe.
>
> MWE follows.
>
>  test-submod.rkt
> #lang racket
>
> (require syntax/location)
>
> (module my-dsl racket/base
>
>   (provide #%app my-proc)
>
>   (define (my-proc)
> (displayln "my-dsl/my-proc")))
>
> (define (parse sexp)
>   (parameterize ((current-namespace (make-base-empty-namespace)))
> (namespace-require (quote-module-path my-dsl))
> (eval sexp)))
>
>
> (parse '(my-proc))
> 
>
> And then:
>
> $ ../racket-lang/racket/racket/bin/racket --version
> Welcome to Racket v7.9.0.4 [cs].
> $ ../racket-lang/racket/racket/bin/racket test-submod.rkt
> my-dsl/my-proc
> $ ../racket-lang/racket/racket/bin/raco exe test-submod.rkt
> $ ./test-submod
> require: unknown module
>   module name: (submod '#%mzc:test-submod my-dsl)
>   context...:
>.../TD4/test-submod.rkt:12:0: parse
>body of '#%mzc:test-submod
> $
>
> When parsed, compiled and run using racket binary, it works as expected.
> When parsed and compiled using raco exe, it succeeds without any error
> and the resulting binary give aforementioned error.
>
> Any idea where did I get it wrong?
>
>
> Dominik
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/d357eb72-0647-d542-5148-852b9e62c2a2%40trustica.cz
> .
>
-- 
-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/01000175cd1985dd-8b6d9cec-b745-4479-a3db-b092fd340434-00%40email.amazonses.com.


Re: [racket-users] Contracts for (partially) specifying dictionary key -> value-predicates

2020-10-30 Thread Philip McGrath
I've wanted this several times (and written more than one ad-hoc partial
version): a general-purpose combinator would be great!

On Fri, Oct 30, 2020 at 1:14 PM William J. Bowman 
wrote:

> > 1. make these functions, not macros
> The main implementation is a procedure, but I think I need a macro to get
> the
> syntactic interface I want.


Personally, I'd think about an approach like `->` and `dynamic->*`: a nice
syntactic interface that covers most use-cases paired with a
somewhat-less-ergonomic procedural interface for more comprehensive
functionality, e.g. when aspects of the contract to be generated aren't
statically known.

On Fri, Oct 30, 2020 at 11:06 AM Ben Greenman 
wrote:

> 2. make "at least" the default behavior for dictof, add an option to
> override (#:exact-keys?), and remove rho-dictof
>

To go a step further, I think there are two dimensions of "exactness":

   1. Are keys other than those specified permitted?
   2. Is a particular key required or optional?

There are some combinations of answers to those questions that I think make
for poor API design, but, in many of the cases when I've wanted these types
of contracts, I've been working with messy pre-existing APIs (often JSON),
which inhabit a whole lot of different points in this space.

An even-more-general way of asking "Are keys other than those specified
permitted?" would be, "What is the contract for a key–value pair not
otherwise specified?", where `any/c` and `none/c` are important special
cases. Even more generally, this could be a function to produce a contract
à la `hash/dc`: I'll see if I can remember an example, but I think I've
encountered APIs where this would have been useful.

As far as "Is a particular key required or optional?", I'd want a nice
syntax to specify this for all keys (I don't have a considered opinion
about what the default should be), but I'd also want support for specifying
it at the level of the individual key–value pair.

Of course, even an implementation that didn't support all of this would be
useful!

-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/010001757ab1f633-6511db02-9764-4008-a0ec-088f33caafe9-00%40email.amazonses.com.


Re: [racket-users] Help implementing an early return macro

2020-10-28 Thread Philip McGrath
The most similar example that comes to mind is the way `for`-like forms
handle the `body-or-break` nonterminal to support `#:break` and `#:final`.
In particular, I think you would end up needing something analogous to these
semantics for definitions

:

> Among the `body`s, besides stopping the iteration and preventing later `
> body` evaluations, a `#:break guard-expr` or `#:final guard-expr` clause
> starts a new internal-definition context.
>

Personally, I'd also want to call your `guard` form something like
`return-when` and `return-unless`, with the relationship between the
condition expression and the right-hand side being the same as `when` and
`unless`.

-Philip


On Wed, Oct 28, 2020 at 7:25 AM Laurent  wrote:

> I've also had the same issues for a long time, and condd was almost good
> enough, but the #:do is too specific.
> But recently I'm using something much simpler (no continuation) and
> straightforward: cond/else
> https://github.com/Metaxal/bazaar/blob/master/cond-else.rkt
>
> By contrast to other approaches—which I usually try a few times then
> discard—I'm using this form regularly.
>
> It does precisely what you request (early return without continuations),
> but keeps both the readable cond and else structure while removing all
> unnecessary parentheses.
> Your example would look like this:
>
> (define x (random 10))
> (cond/else
>   [(not (even? x))
>(log-info "x wasn't even, x = ~a" x)
>-1]
>   #:else
>   (define y (random 10))
>   #:cond
>   [(not (even? y))
>(log-info "y wasn't even, y = ~a" y)
>-1]
>   #:else
>   (+ x y))
>
> You say you don't like the keywords, but I find that they actually
> increase readability.
>
> On Wed, Oct 28, 2020 at 10:54 AM Jack Firth  wrote:
>
>> So I'm a little tired of writing code like this:
>>
>> (define x ...)
>> (cond
>>   [(take-shortcut? x) (shortcut x)]
>>   [else
>>(define y (compute-y x))
>>(cond
>> [(take-other-shortcut? x y) (other-shortcut x y)]
>> [else
>>  (define z ...)
>>  (cond ...)])])
>>
>> That is, I have some logic and that logic occasionally checks for
>> conditions that make the rest of the logic irrelevant, such as an empty or
>> false input or something else that should trigger an early exit. Each check
>> like this requires me to write a cond whose else clause wraps the
>> remainder of the body, leading to an awkward nesting of cond forms. I
>> don't have this issue when the early exits involve raising exceptions: in
>> those cases I can just use when and unless like so:
>>
>> (define x ...)
>> (unless (passes-check? x) (raise ...))
>> (define y ...)
>> (unless (passes-other-check? x y) (raise ...))
>> (define z ...)
>> ...
>>
>> I'm aware of a few macros in the racket ecosystem that try to solve this
>> problem. For example, Jay wrote a blog post
>>  that creates
>> a condd form that's like cond but allows embedded definitions using a
>> #:do keyword. I've also seen various approaches that use escape
>> continuations to implement the early exit. There's drawbacks I'm not happy
>> about however:
>>
>>-
>>
>>For cond-like macros that allow embedded definitions, it looks too
>>different from regular straight-line Racket code. I like my function 
>> bodies
>>to be a sequence of definitions and expressions, with minimal nesting, 
>> just
>>like the when and unless version above. I don't have to use a keyword
>>or extra parentheses to signal whether a form is a definition or a
>>when / unless check in error-raising code, why should I have to do
>>that in code that uses early returns?
>>-
>>
>>Continuation-based solutions impose a nontrivial performance penalty
>>and have complex semantics. I don't like that the generated code behaves
>>differently from the cond tree I would normally write. What happens
>>if I stick an early exit inside a lambda? Or a thread? What if I set up a
>>continuation barrier? Does that matter? I don't know and I don't want to
>>think about that just to write what would be a simple if (condition)
>>{ return ... } block in other languages.
>>
>> So I wrote a basic macro for this and I have some questions about how to
>> make it more robust. The macro is called guarded-block and it looks like
>> this:
>>
>> (guarded-block
>>   (define x (random 10))
>>   (guard (even? x) else
>> (log-info "x wasn't even, x = ~a" x)
>> -1)
>>   (define y (random 10))
>>   (guard (even? y) else
>> (log-info "y wasn't even, y = ~a" y)
>> -1)
>>   (+ x y))
>>
>> Each guard clause contains a condition that must be true for evaluation
>> to proceed, and if it isn't true the block takes the else branch and
>> finishes. So the above would expand into this:
>>
>> (block
>>   (define x (random 10))
>>   (cond
>> [(not (even? x))
>>  (log-info "x 

Re: [racket-users] Hygiene for a curried macro

2020-09-30 Thread Philip McGrath
I'll also put in a plug for DrRacket's Macro Stepper, which can show your
scopes in pretty colors! (And precise numbers.) In particular, in the
"Stepper > Foreground colors" menu, you can toggle between "By macro
scopes" and "By all scopes".

[image: Screen Shot 2020-09-30 at 3.47.40 AM.png]
-Philip


On Wed, Sep 30, 2020 at 3:40 AM Philip McGrath 
wrote:

> Hi Nia,
>
> Here's a variant that passes your test:
>
> #lang racket
>
> (require rackunit
>  syntax/parse/define)
>
> (define-syntax let-second-and-create-let-third
>   (syntax-parser
> [(_ var let-third body-of-let-second)
>  #'(let ([var "second"])
>  (let-syntax ([let-third
>(syntax-parser
>  [(_ body-of-let-third)
>   #:with var* (syntax-local-introduce #'var)
>   #'(let ([var* "third"])
>   body-of-let-third)])])
>body-of-let-second))]))
>
> (check-equal?
>   (let ([x "first"])
> (let-second-and-create-let-third x let-third
>   (let-third
> x)))
>   "third"
>   "Test that a macro generated by a macro can bind a variable the user
> supplied to the generator macro")
>
> You need `syntax-local-introduce` (or another mechanism, like
> `datum->syntax`) for `let-third` to be able to capture `x` in its body:
> otherwise, the expander will see that it is a macro-introduced binding. You
> also need to address the fact that each `let` in the expansion creates a
> new scope: if the binding to `"second"` isn't in scope for the
> right-hand-side of `let-third`, you can get an ambiguous binding (see:
> https://www.cs.utah.edu/plt/scope-sets/pattern-macros.html#(part._pattern-ambiguous)).
> In this case I just moved the `let-syntax` inside the `let`, but you could
> also use something like `letrec-syntaxes+values`.
>
> -Philip
>
> On Wed, Sep 30, 2020 at 2:46 AM rocketnia  wrote:
>
>>
>> Hi all,
>>
>> I've been experimenting with a custom system of managed local variables,
>> and I came up with a hygiene test case that was failing. So then I tried
>> the same test case with plain Racket variables, and it failed that way
>> too. Here's a minimalistic example.
>>
>> Basically, this is a curried macro: The user supplies a variable and gets
>> a macro out, and then the user calls that macro. Can the second macro
>> bind the variable the user supplied to the first one? I thought it would
>> be able to, but this doesn't currently seem to be case on Racket v7.8
>> [cs].
>>
>> Could anyone explain what's going on with this? Is there a workaround if
>> I want to write this kind of macro? Should I file a bug in Racket? This
>> looks pretty close to R5RS Scheme, so I wonder what the situation in the
>> broader Scheme world is like, too.
>>
>>
>> #lang racket
>>
>> (require rackunit)
>>
>> (define-syntax-rule
>>   (let-second-and-create-let-third var let-third body-of-let-second)
>>   (let-syntax ([let-third
>>  (syntax-rules ()
>>[(let-third body-of-let-third)
>> (let ([var "third"])
>>   body-of-let-third)])])
>> ; This binding shows that the first macro *does* manage to bind
>> ; the given variable, even though the second macro doesn't.
>> (let ([var "second"])
>>   body-of-let-second)))
>>
>> (check-equal?
>>   (let ([x "first"])
>> (let-second-and-create-let-third x let-third
>>   (let-third
>> x)))
>>   "third"
>>   "Test that a macro generated by a macro can bind a variable the user
>> supplied to the generator macro")
>>
>> ; FAILURE
>> ; actual: "second"
>> ; expected: "third"
>>
>>
>> You can also find this code in Gist form here:
>> https://gist.github.com/rocketnia/cb83da2cfcddbf614dfe1dfc5e08792c
>>
>> Thanks in advance for any insight you have about what's going on here.
>>
>> - Nia
>>
>> --
>> You received this message because you are subscribed to the Google 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/71daa8da-25cf-426b-b709-ee9ed25b53f0n%40googlegroups.com
>> <https://groups.google.com/d/msgid/racket-users/71daa8da-25cf-426b-b709-ee9ed25b53f0n%40googlegroups.com?utm_medium=email_source=footer>
>> .
>>
>

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


Re: [racket-users] Hygiene for a curried macro

2020-09-30 Thread Philip McGrath
Hi Nia,

Here's a variant that passes your test:

#lang racket

(require rackunit
 syntax/parse/define)

(define-syntax let-second-and-create-let-third
  (syntax-parser
[(_ var let-third body-of-let-second)
 #'(let ([var "second"])
 (let-syntax ([let-third
   (syntax-parser
 [(_ body-of-let-third)
  #:with var* (syntax-local-introduce #'var)
  #'(let ([var* "third"])
  body-of-let-third)])])
   body-of-let-second))]))

(check-equal?
  (let ([x "first"])
(let-second-and-create-let-third x let-third
  (let-third
x)))
  "third"
  "Test that a macro generated by a macro can bind a variable the user
supplied to the generator macro")

You need `syntax-local-introduce` (or another mechanism, like
`datum->syntax`) for `let-third` to be able to capture `x` in its body:
otherwise, the expander will see that it is a macro-introduced binding. You
also need to address the fact that each `let` in the expansion creates a
new scope: if the binding to `"second"` isn't in scope for the
right-hand-side of `let-third`, you can get an ambiguous binding (see:
https://www.cs.utah.edu/plt/scope-sets/pattern-macros.html#(part._pattern-ambiguous)).
In this case I just moved the `let-syntax` inside the `let`, but you could
also use something like `letrec-syntaxes+values`.

-Philip

On Wed, Sep 30, 2020 at 2:46 AM rocketnia  wrote:

>
> Hi all,
>
> I've been experimenting with a custom system of managed local variables,
> and I came up with a hygiene test case that was failing. So then I tried
> the same test case with plain Racket variables, and it failed that way
> too. Here's a minimalistic example.
>
> Basically, this is a curried macro: The user supplies a variable and gets
> a macro out, and then the user calls that macro. Can the second macro
> bind the variable the user supplied to the first one? I thought it would
> be able to, but this doesn't currently seem to be case on Racket v7.8
> [cs].
>
> Could anyone explain what's going on with this? Is there a workaround if
> I want to write this kind of macro? Should I file a bug in Racket? This
> looks pretty close to R5RS Scheme, so I wonder what the situation in the
> broader Scheme world is like, too.
>
>
> #lang racket
>
> (require rackunit)
>
> (define-syntax-rule
>   (let-second-and-create-let-third var let-third body-of-let-second)
>   (let-syntax ([let-third
>  (syntax-rules ()
>[(let-third body-of-let-third)
> (let ([var "third"])
>   body-of-let-third)])])
> ; This binding shows that the first macro *does* manage to bind
> ; the given variable, even though the second macro doesn't.
> (let ([var "second"])
>   body-of-let-second)))
>
> (check-equal?
>   (let ([x "first"])
> (let-second-and-create-let-third x let-third
>   (let-third
> x)))
>   "third"
>   "Test that a macro generated by a macro can bind a variable the user
> supplied to the generator macro")
>
> ; FAILURE
> ; actual: "second"
> ; expected: "third"
>
>
> You can also find this code in Gist form here:
> https://gist.github.com/rocketnia/cb83da2cfcddbf614dfe1dfc5e08792c
>
> Thanks in advance for any insight you have about what's going on here.
>
> - Nia
>
> --
> You received this message because you are subscribed to the Google 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/71daa8da-25cf-426b-b709-ee9ed25b53f0n%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/01000174ddf4d987-bb428eb4-b346-4bf9-a565-985b02610563-00%40email.amazonses.com.


Re: [racket-users] Why are these @defthing blocks typeset incorrectly?

2020-09-23 Thread Philip McGrath
I have encountered this problem. I don't have a real solution, but maybe my
hacky solution will be good enough.

On Wed, Sep 23, 2020 at 7:37 PM Sorawee Porncharoenwase <
sorawee.pw...@gmail.com> wrote:

> I think Scribble uses source location equipped with syntax objects to
> figure out spacing. Since you generate stuff on the fly, there’s no source
> location, so the rendered text is screwed up.
>
This is indeed the explanation. My hacky solution (you can see it here
)
is to build up term for Scribble to typeset—the equivalent of what you do
here
,
I think—using `syntax` rather than `quasiquote`. IIRC (I haven't touched
this code in a while), it didn't work to use `quasisyntax`/`unsyntax`, so I
used `define/syntax-parse` to bind pattern variables to the generated
sub-terms. This way, Scribble picks up the source locations from the
template and uses spaces as it should.

This is a hack, though: in my case, I'm building a `let*` expression with
potentially several binding pairs, and they will run off the margin of the
page. There are probably various other problems: I remember this code being
a bit annoying to write.

-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/01000174bd6f57cc-a40851c2-a167-4790-b636-b43d9cf21e97-00%40email.amazonses.com.


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