[racket-users] break-thread + thread-wait can't be handled

2017-05-03 Thread Eric Griffis
Hello,

I'm having trouble catching "terminate break" exceptions when combining 
break-thread with thread-wait.

MWE 1:

  (with-handlers ([exn:break:terminate? writeln])
(let ([t (thread (lambda () (thread-wait (current-thread])
  (break-thread t 'terminate)
  (thread-wait t)))

MWE 2:

  (with-handlers ([exn:break:terminate? writeln])
(let ([t (thread (lambda () (thread-receive)))])
  (break-thread t 'terminate)
  (thread-wait t)))

Expected:

  #(struct:exn:break:terminate "terminate break" # 
#)

Actual:

  terminate break

FWIW, the following snippet works as expected:

  (with-handlers ([exn:break:terminate? writeln])
(break-thread (current-thread) 'terminate))

Am I missing something? Any help is appreciated.

Eric

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


Re: [racket-users] break-thread + thread-wait can't be handled

2017-05-04 Thread Eric Griffis
On Wednesday, May 3, 2017 at 3:04:20 PM UTC-7, Ryan Culpepper wrote:
> On 5/3/17 10:41 PM, Eric Griffis wrote:
> > Hello,
> >
> > I'm having trouble catching "terminate break" exceptions when combining 
> > break-thread with thread-wait.
> >
> > MWE 1:
> >
> >   (with-handlers ([exn:break:terminate? writeln])
> > (let ([t (thread (lambda () (thread-wait (current-thread])
> >   (break-thread t 'terminate)
> >   (thread-wait t)))
> 
> Threads do not inherit exception handlers. You need to move the 
> `with-handlers` to the new thread:
> 
>(let ([t (thread (lambda ()
>   (with-handlers ([exn:break:terminate? writeln])
> (thread-wait (current-thread)])
>  (break-thread t 'terminate)
>  (thread-wait t))
> 
> Except that isn't quite right either, because , the main thread might 
> (very likely) send the break to `t` before `t` is ready to catch it. So 
> we need some additional synchronization:
> 
>(define t-ready (make-semaphore 0))
>(let ([t (thread (lambda ()
>   (with-handlers ([exn:break:terminate? writeln])
> (semaphore-post t-ready)
> (thread-wait (current-thread)])
>  (semaphore-wait t-ready)
>  (break-thread t 'terminate)
>  (thread-wait t))
> 
> That version should reliably print out the break exception.
> 
> Ryan

Got it. I had with-handlers inside the thread at first, but got the same 
result. A simple test showed clearly that the thread was not ready to catch the 
break, hence my attempt to extract with-handlers. The semaphore did the trick, 
though.

The big lesson (for me) here is that exceptions inside a thread do not "bubble 
up" to the parent. This was not obvious (to me) from the docs.

My code is now behaving predictably. Thanks, Ryan.

Eric

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


Re: [racket-users] Intro and projects inquiry

2017-10-13 Thread Eric Griffis
On Thu, Oct 12, 2017 at 2:27 PM Andrew Gwozdziewycz 
wrote:

> I love seeing all of these project ideas, but I really don't think
> Racket needs a "killer app." I think what it needs is the people
> passionate about it building tools in it, and *using* those tools in
> the work place, and sharing the experiences of using those tools more
> vocally.
>

This line of reasoning also works in reverse. When Racket becomes more
popular, people will talk about it more. There's a network effect to
consider.


> We need people building tools and blogging about why using Racket made
> the job easier. Why would it be harder to do in Python, or Ruby? We
> need straight up advocacy, and that starts with everyone in this
> thread who *hasn't* done that yet.
>

These activities are good for hardcore developer advocacy. They are less
effective at swaying casual devs who can't code themselves out of a jam.

You might get some push back on [...]. Explain to them [...]
>

Education is important. It's also slow and expensive. In my experience,
"lead by example" is a more effective starting strategy than "show them the
light."

Anyway. I don't think it makes sense to solve problems that you don't
> have.


I've made a career out of solving other people's problems. It's why I'm an
expert tool maker and an awful astrophysicist. Programmers and
astrophysicists need each other to remain relevant.

Ideas are cheap, but it's an easy way to get people taking. And this kind
of discussion can lead to truly valuable insights as we share interests,
hopes, pain points, and coping mechanisms.

Eric

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


Re: [racket-users] Intro and projects inquiry

2017-10-13 Thread Eric Griffis
On Thu, Oct 12, 2017 at 9:31 AM David Storrs  wrote:

> My suggestion would be that the single largest thing that would make
> Racket take off is if it could become a replacement for Javascript.


RacketScript Playground does not optimize tail calls. If it turned ES6
strict mode on, and if strict mode works as advertised, could RacketScript
leverage more Racket code to some advantage?

It's an interesting problem, but I doubt making Racket work better in the
browser would have the desired effect. Web dev culture is a bigger issue.

Eric

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


Re: [racket-users] Intro and projects inquiry

2017-10-11 Thread Eric Griffis
On Wed, Oct 11, 2017 at 2:58 PM Neil Van Dyke  wrote:

>
> * Being there soon with a Web Assembly and HTML5 plus server full-stack
> story, in case developers respond favorably to that.
>

Web back-ends are my wheelhouse. It sure would make my professional life
easier... Not gonna lie, this isn't something I'd look forward to banging
out alone.


> * Push DSL-based programming, for which Racket might already have the
> best technology.  (The other day, I saw someone looking to hire
> developers to use some DSL-based speculative methodology thing... in Ruby.)
>

This might also be interesting. Any concrete demand out there to drive the
process?

* Find other application or technology niches that people want right
> now, and figure out some value-added support for them other than SaaS
> bindings that everyone else is doing.  Deep learning and other machine
> learning, traditional scientific/stats programming and visualization,
> voice AI-ish assistants, FPS video game engines, GPU targeting, etc.
>

The Godot game engine is kinda like this, but for Python. It has a lot of
rough edges, which could help design a good Racket alternative. There may
be a ton of reusable functionality in a project like that.

Thanks, Neil!

Eric

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


Re: [racket-users] Intro and projects inquiry

2017-10-11 Thread Eric Griffis
Thanks for the quick reply. My goal is to make Racket more relevant for
general engineering and application development.

For example, I asked my scientist brother why he's using Python instead of
Racket on his next project. His response:

"but would I have to write my own routines for calculating mahalanobis
distance, or jensen-shannon entropy with bootstrap correction?"

Apologies for any confusion.

Eric


On Wed, Oct 11, 2017, 1:30 PM William J. Bowman <w...@williamjbowman.com>
wrote:

> Eric,
>
> I don’t mean to inadvertently kill any conversations, but I wanted to
> point out that there is an existing list of Racket projects on the Racket
> GitHub wiki:
>   https://github.com/racket/racket/wiki/Intro-Projects
>
> It hasn’t seen an update in a while, so some of those may be solved or
> have others working on them, but if you’re looking for projects I’d start
> by looking there.
>
> —
> William J. Bowman
>
> > On Oct 11, 2017, at 10:12 PM, Eric Griffis <ded...@gmail.com> wrote:
> >
> > Hello,
> >
> > My name is Eric and I love Racket.
> >
> > I am 39 years old and have been writing software for 30 years. I studied
> metaprogramming and taught programming languages as a grad student. My sole
> academic publication is on semantics and provenance for distributed data
> science tools. These days, I teach elementary school kids why and how to
> care about "coding," which means so much more than just banging out text.
> >
> > Racket is special to me because it makes programming fun again. When
> it's time to get real work done, I want more people to reach for Racket
> first. This is my goal, so I'm making this call for projects or project
> ideas as a conversation starter.
> >
> > Does a killer app or library sorely need a Racket alternative?
> >
> > Do you dread certain tasks that have you reaching for Python or
> JavaScript, or worse?
> >
> > Is your professional community holding out on adopting Racket, and do
> you know why?
> >
> > Any amazing projects pitched at the conference?
> >
> > I enjoyed following the graph drawing thread a few weeks ago. A serious
> attempt at "better than graphviz" could be fun and worthwhile.
> >
> > Eric
> >
> > --
> > You received this message because you are subscribed to the Google
> Groups "Racket Users" group.
> > To unsubscribe from this group and stop receiving emails from it, send
> an email to racket-users+unsubscr...@googlegroups.com.
> > For more options, visit https://groups.google.com/d/optout.
>
>

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


[racket-users] Intro and projects inquiry

2017-10-11 Thread Eric Griffis
Hello,

My name is Eric and I love Racket.

I am 39 years old and have been writing software for 30 years. I studied 
metaprogramming and taught programming languages as a grad student. My sole 
academic publication is on semantics and provenance for distributed data 
science tools. These days, I teach elementary school kids why and how to care 
about "coding," which means so much more than just banging out text.

Racket is special to me because it makes programming fun again. When it's time 
to get real work done, I want more people to reach for Racket first. This is my 
goal, so I'm making this call for projects or project ideas as a conversation 
starter.

Does a killer app or library sorely need a Racket alternative?

Do you dread certain tasks that have you reaching for Python or JavaScript, or 
worse?

Is your professional community holding out on adopting Racket, and do you know 
why?

Any amazing projects pitched at the conference?

I enjoyed following the graph drawing thread a few weeks ago. A serious attempt 
at "better than graphviz" could be fun and worthwhile.

Eric

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


Re: [racket-users] Announcing Event-lang

2018-05-22 Thread Eric Griffis
On Mon, May 21, 2018 at 11:21 AM Jay McCarthy 
wrote:

> This is very cute! Can you point to a fun example? I looked through
> the repo and it wasn't obvious where some tests and examples were.
>
> Jay
>

Here's a variety of small examples.

Sometimes, I just want to wait until a bunch of stuff is done:

  > (sync
 (async-void*
  (append
   (for/list ([i 10])
 (thread (λ () (channel-put ch i
   (for/list ([_ 10])
 (thread (λ () (write (channel-get ch
  1594302867

Sometimes, I want to do something more than once:

  > (define (channel-dup-evt cs v)
  (async-void* (map (curryr channel-put-evt v) cs)))

With some background getters,

  > (define cs (build-list 5 (λ _ (make-channel
  > (for ([c cs] [i 5])
  (thread (λ () (writeln (cons i (channel-get c))

it's ready for synchronization.

  > (sync (channel-dup-evt cs 'X))
  (1 . X)
  (3 . X)
  (0 . X)
  (2 . X)
  (4 . X)

The natural numbers:

  > (define nats
  (let ([n 0]) (pure (begin0 n (set! n (add1 n))

This event acts like a generator.

  > (sync nats)
  0
  > (sync nats)
  1
  > (sync nats)
  2

nats is handy for generating indices and unique keys in bulk through
repetition.

  > (sync (event-list* (make-list 4 nats)))
  '(3 4 5 6)

It's always fun to implement the fibonacci sequence:

  > (define (naive-fib n)
  (case n
[(0) (pure 0)]
[(1) (pure 1)]
[else (fmap + (naive-fib (- n 1)) (naive-fib (- n 2)))]))

Of course, the naive implementation is very slow.

  > (time (sync (naive-fib 29)))
  cpu time: 5826 real time: 5831 gc time: 1004
  514229

This one:

  > (define fib
  (let ([a 1] [b 0])
(pure (begin0 b (set!-values (a b) (values (+ a b) a))

is much faster.

  > (time (last (sync (event-list* (make-list 30 fib)
  cpu time: 1 real time: 1 gc time: 0
  514229

nats and fib can be combined to build an index:

  > (define fibs (make-hash))
  > (sync
 (async-void*
  (make-list 30 (fmap (curry hash-set! fibs) nats fib
  > (hash-ref fibs 29)
  514229
  > (hash-ref fibs 15)
  610

Promises are pretty easy, too:

  > (define (promise thunk)
  (define result #f)
  (bind (thread (λ ()
  (define vs (call-with-values thunk list))
  (set! result (pure (apply values vs)
(λ _ result)))

The results are memoized so multiple syncs don't replay side effects.

  > (define p (promise (λ () (writeln 123) 4)))
  123
  > (sync p)
  4
  > (sync p)
  4

My personal favorite is more practical than fun:

  > (define (dispatch m ms [default void-mediator])
  (define (dispatch-put m0)
(bind-put
 (make-mediator)
 (λ _ (λ (k . vs) (say* (hash-ref ms k default) vs m0)
  (event-let ([m0 (accept m)]) (offer m0 (dispatch-put m0

Without getting into what mediators are, this one forwards a message from m
 to
an element of hash ms. If the message is a list and the first element is a
key
of ms, the rest of the message is delivered to the keyed element. The
dispatch
event may finish before the message is delivered, but the sender and
receiver
are guaranteed to synchronize on each other. Getting this right was hard.

Most of my work with event-lang is in solving hairy synchronization problems
like this, so I felt I should sneak one in.

Eric

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


Re: [racket-users] Announcing Event-lang

2018-05-24 Thread Eric Griffis
These are in and should be visible in a few hours. I'll keep collecting
more!

Eric


On Tue, May 22, 2018 at 1:48 PM Matthew Butterick <m...@mbtype.com> wrote:

> I'm sure I'm not the only one who would like to see these (and other
> examples you have handy) added to your `event-lang` docs.
>
>
> On May 22, 2018, at 7:29 AM, Eric Griffis <ded...@gmail.com> wrote:
>
> Here's a variety of small examples.
>
>
>

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


[racket-users] Announcing Event-lang

2018-05-18 Thread Eric Griffis
Hi everyone,

I would like to announce the initial release of event-lang, an
experimental Racket library that simplifies the creation of complex
synchronizable events.

https://pkgd.racket-lang.org/pkgn/package/event-lang

Event-lang provides a primitive expression lifting form,

  > (pure 123)
  #

some event combinators,

  > (sync (fmap + (pure 1) (pure 2)))
  3
  > (sync (app (pure +) (pure 1) (pure 2)))
  3
  > (sync (bind (pure 1) (pure 2) (λ xs (pure (apply + xs)
  3

and a collection of event-friendly alternatives to base Racket forms
and functions.

  > (sync
 (event-let
  ([x (pure 1)]
   [y (pure 2)])
  (pure (list x y
  '(1 2)

Composite events make progress by synchronizing constituent events,
either concurrently or in a predictable sequence. Synchronization
results can be ordered as specified,

  > (let ([t0 (current-inexact-milliseconds)])
  (define (now) (- (current-inexact-milliseconds) t0))
  (sync
   (async-args
(pure (cons 1 (now)))
(pure (cons 2 (now)))
(pure (cons 3 (now))
  '(1 . 0.200927734375)
  '(2 . 0.14990234375)
  '(3 . 0.178955078125)

or as completed.

  > (let ([t0 (current-inexact-milliseconds)])
  (define (now) (- (current-inexact-milliseconds) t0))
  (sync
   (async-set
(pure (cons 1 (now)))
(pure (cons 2 (now)))
(pure (cons 3 (now))
  '(2 . 0.0771484375)
  '(3 . 0.093017578125)
  '(1 . 0.123046875)

The project has three outstanding objectives:

1. Provide a sophisticated lifting form

  to simplify usage of the provided constructs. The event/event module
  contains a first approximation. Its construction was tedious and
  error prone, so I commented out the docs.

2. Provide a full-blown #lang event/racket/base

  for producing whole modules of events and event constructors from
  ordinary Racket code in a principled manner.

3. Provide support for static analysis of synchronization behaviors.

  Event programming in Racket is a curious form of meta-programming,
  and a few simple compile-time checks could reduce cognitive
  overhead.

This pre-release is a request for feedback in anticipation of a
production-ready version 1.0. I would like to round out the base
collection and devise a comprehensive testing plan, with a stretch
goal of re-introducing the sophisticated lifting form. At the moment,
I'm using event-lang daily and adding base constructs as needed. Feel
free to do the same or request your favorites.

Please take a look and let me know what you think.

Eric

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


Re: [racket-users] Recommendation for learning syntax?

2018-08-10 Thread Eric Griffis
A few months ago, I was similarly confused. Here's what I remember
learning since then.

Let's call the character-level syntax of a language *concrete* and any
higher-level syntax *abstract*. By these definitions, a *parser* makes
concrete syntax abstract, and an *interpreter* translates one piece of
abstract syntax into another.

In Racket-space, I don't often see concrete and abstract syntax
discussed together. We tend to talk exclusively about parsing concrete
syntax "into s-expressions," or just assume s-expressions and focus on
abstract interpretation of *syntax objects* by *syntax transformers*.

I didn't truly "get" syntax transformers until I had a working
understanding of the expander and how it affects phase-based
execution. I like to think of expansion as term rewriting, with syntax
transformers as rewrite rule generators. The expander recursively
rewrites the AST at the current phase into the AST for the next phase.
This is a fundamentally different perspective than macros as function
templates. The paper, *Macros that Work Together*, does a great job
explaining the difference.

Awareness of the current phase and an ability to re-orient "up" or
"down" quickly are now essential skills for my day-to-day macro
programming. Intuiting which phase a piece of code inhabits got a lot
easier once I internalized the difference between define,
define-syntax, and define-for-syntax.

When I started with the syntax/parse collection, it was all
syntax-parse and define-syntax-class. These days, I'll start with
define-simple-macro and increase flexibility -- first to
define-syntax-parser, then to syntax-parse inside define-syntax
-- as needed. I was pretty comfortable with syntax-case and
syntax-rules to begin with, which made picking up the syntax/parse
analogues straight forward.

Eric


On Tue, Aug 7, 2018 at 8:48 AM Alex Gian  wrote:

> Simply put, I find syntax to be a brain
>
> I can do simple stuff, often by extensive study of example code, and I
> even have the odd moment of illumination, which shows me that there is more
> to it than just masochism!
>
> What I do not have is the flow, the mojo, to be able to write syntax like
> second nature, and what's more to intersperse it with normal code without
> freaking out.
>
> So I've decided to bite the bullet and dedicate some quality time to the
> subject, without constantly winging it.  In the light of this, what would
> the good folk here recommend as a reasonable path on which to proceed
> fairly quickly?   I am not averse to meta-anything, but sometimes I just
> don't see the elegance that is supposed to be there.
>
> One of my targets would also be to get the hang of syntax-parse.  Are
> there any tutorials out there?  I do not mind if they are simple.  When it
> comes to syntax, so am I.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: [racket-users] redex features? boolean ops and piece-wise

2018-03-15 Thread Eric Griffis
On Wednesday, March 14, 2018 at 3:14:34 PM UTC-7, Robby Findler wrote:
>
> I usually use metafunctions for that purpose. It might be nice if there 
> were more such functions built into redex that came with their own renders, 
> I guess. 
>
>
More than once, I've gotten stuck typesetting in Redex and go back to 
LaTeX. It would be nice to have something like a Redex cookbook to 
demonstrate visually interesting outputs.
 

> Overall, I think we're missing a higher-level for rendering. I like the 
> low-level that is there, but it is, um, low level. I think the collection 
> of stuff in the unstable redex packae is a good start but we need more. 
>
>
I am profoundly interested in eliminating LaTeX from my workflow. A 
high-level rendering engine would go a long way towards that.
 

> Robby
>
>
> On Wed, Mar 14, 2018 at 4:33 PM, Andrew Kent  > wrote:
>
>> Oh wow, yep that's exactly the piece-wise behavior I was hoping 
>> for, thanks! 
>>
>> I guess my only question then is if there are better ways to get 
>> "and"/"or" behavior and rendering or if my hacky metafunctions are what 
>> people usually use for that purpose.
>>
>> Best,
>> Andrew
>>
>> On Wed, Mar 14, 2018 at 4:23 PM, Robby Findler <
>> ro...@eecs.northwestern.edu > wrote:
>>
>>> Maybe this is a helpful piece of part of the puzzle?
>>>
>>> #lang racket
>>> (require redex)
>>> (define-language L
>>>   (b ::= 1 0)
>>>   (n ::= natural))
>>> (define-metafunction L
>>>   ∪ : n n -> n
>>>   [(∪ n_1 n_2)
>>>0
>>>(side-condition (term (lt n_1 n_2)))
>>>
>>>or
>>>1
>>>(side-condition (term (gt n_1 n_2)))
>>>
>>>or
>>>2
>>>(side-condition (term (eq n_1 n_2)))])
>>>
>>> (define (infix id lws)
>>>   (list ""
>>> (list-ref lws 2)
>>> (~a " " id " ")
>>> (list-ref lws 3)
>>> ""))
>>>
>>> (with-compound-rewriters
>>> (['∪ (λ (lws) (infix "∪" lws))]
>>>  ['lt (λ (lws) (infix "<" lws))]
>>>  ['gt (λ (lws) (infix ">" lws))]
>>>  ['eq (λ (lws) (infix "=" lws))])
>>>   (render-metafunction ∪))
>>>
>>>
>>> On Wed, Mar 14, 2018 at 10:46 AM, Andrew Kent >> > wrote:
>>>
 In some recent redex tinkering I've been doing I've had to hack around 
 two (somewhat related) things that I could easily imagine being "built-in" 
 features for redex:

 1. boolean combinators (e.g. and, or)
 2. a piece-wise form (i.e. basically a "cond" that you can use on the 
 rhs of a metafunction definition which renders in the classic piece-wise 
 way using a large curly brace)

 Both of these are things that are used ubiquitously to describe 
 mathematical algorithms in a clear way... neither adds actual 
 expressiveness to redex (you can certainly model the functionality of both 
 using the current tools), but I think it might be nice to be able to use 
 these common mathematical "features" and have them "just work" (and 
 render!!!) as expected without boilerplate and hoops.

 In case examples are more helpful, for "or" and "and" boolean operators 
 I threw together some silly functions that give "or" and "and" behavior 
 and 
 allow me to render them how I want (e.g. OR is not parenthesized when 
 rendered, POR is). Unfortunately you obviously don't get the 
 short-cuirtining behavior we sometimes want with "or":

 ```
 (define-metafunction sst
   OR : or-bool ... -> bool
   [(OR any_1 ... true any_2 ...) true]
   [(OR any_1 ...) false])

 ;; duplicate definition that will be rendered with parens
 (define-metafunction sst
   POR : or-bool ... -> bool
   [(POR any_1 ... true any_2 ...) true]
   [(POR any_1 ...) false])

 (define-metafunction sst
   AND : and-bool ... -> bool
   [(AND any_1 ... false any_2 ...) false]
   [(AND any_1 ...) true])

 ;; duplicate definition that will be rendered with parens
 (define-metafunction sst
   PAND : and-bool ... -> bool
   [(PAND any_1 ... false any_2 ...) false]
   [(PAND any_1 ...) true])
 ```

 Here's an example function that uses some of those boolean operators:

 ```
 (define-metafunction sst
   gamma : s s N -> bool
   [(gamma s_1 s_2 ∅) false]
   [(gamma s_1 s_2 (set-cons (× t_1 t_2) N))
(AND (POR (subtype s_1 t_1)  or  (gamma (t-diff s_1 t_1) s_2 N))
 and (POR (subtype s_2 t_2)  or  (gamma s_1 (t-diff s_2 t_2) 
 N)))])
 ```

 and here it is rendered:

 [image: Screen Shot 2018-03-14 at 11.29.58 AM.png]

 For a piecewise operator, again certainly you can model the behavior 
 just using the current tools, but if you imagine a metafunction that wants 
 to pattern-match on the lhs of the definition and then piece-wise dispatch 
 on the right-hand side of the definition to clearly illustrate to a reader 
 what is going on... I don't think there's 

[racket-users] Using pict-convertibles in Scribble docs?

2018-04-15 Thread Eric Griffis
Hello,

I'm making composite picts in my Scribble docs and am looking for a clean
way to keep references to sub-picts around for helper functions to draw
lines between. A struct with the `prop:pict-convertible` property would
suffice, but `raco setup` gives an error.

Given this struct definition:

(struct my-pict () #:property prop:pict-convertible (λ _ (circle 30)))

If I call its constructor from Scribble:

@my-pict[]

I get the error:

not valid in document body (need a pre-part for decode) in: #

Manually `pict-convert`ing can be painful. Is there an easier way?

Thanks!

Eric

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


Re: [racket-users] struct-copy question

2018-03-17 Thread Eric Griffis
How about a list of identifiers bound to getters or setters? The
`extract-struct-info` procedure in Section 5.7 of the Racket Reference
appears to give you that.

Eric


On Fri, Mar 16, 2018 at 2:56 PM Kevin Forchione  wrote:

>
>
> > On Mar 16, 2018, at 2:38 PM, Kevin Forchione  wrote:
> >
> > Hi guys,
> > I’ve noticed that struct-copy doesn’t appear to work when fields are
> defined with #:auto. So this leads to my question, which may not be
> answerable since it would presumably be used to fix struct-copy, but is
> there a way to retrieve a list of struct fields for a struct? I have a
> feeling there is some macro work going on and that the struct isn’t really
> “aware” of its field names. If that’s the case, wouldn’t it be interesting
> if the macro included building a function that would return these names as
> a symbols list? :)
>
> Actually, what wold be interesting would be a list of lists, containing
> the getters and setters for the struct. :)
>
> 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.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: [racket-users] struct-copy question

2018-03-19 Thread Eric Griffis
Does this help?

```
(define-syntax (dump-struct-info stx)
  (syntax-case stx ()
[(_ info)
 (pretty-write
  `(GOT ,(extract-struct-info (syntax-local-value #'info (λ () #f)
 #'(void)]))
```

Then we can do:

```
> (struct point (x y [z #:auto #:mutable]) #:transparent)
> (dump-struct-info point)
(GOT
 (#
  #
  #
  (# # #)
  (# #f #f)
  #t))
```

Eric


On Sat, Mar 17, 2018 at 8:15 PM Kevin Forchione <lyss...@gmail.com> wrote:

>
>
> > On Mar 17, 2018, at 9:24 AM, Eric Griffis <ded...@gmail.com> wrote:
> >
> > How about a list of identifiers bound to getters or setters? The
> `extract-struct-info` procedure in Section 5.7 of the Racket Reference
> appears to give you that.
> >
> > Eric
>
> Souned promising, but  it sounds like you have to roll a struct-info
> first, unless I’ve missed something. I did have some fun exploring 5.2
> Creating Structure Types (the link to Examples for
> make-struct-field-accessor & make-struct-field-mutaor appear to lead you
> back to the top of the page, but as far as I can tell there are no examples
> there for those functions…)
>
>

> No, what I was hoping for was something you could throw a structure
> instance at and obtains a list of its accessors/mutators so that I could
> then write a generalized version of struct-copy (which appears not to copy
> a struct that has #:auto fields. Placing a struct inside of  a define
> though gives a pretty quick glimpse at the underlying code that the (struct
> ….) generates, and the mutator created by make-struct-type is simply thrown
> away (when not used by make-struct-mutator. I would think that between that
> (if it could be retained) and the struct->list function, which produces an
> index-ordered list of the struct’s values, that you could create a
> struct-copy that would populate all of the fields. Of course, you’d have a
> mutator out in the wild that could always modify the struct… no, you’d have
> to encapsulate all that into a special function foo-copy for struct foo,
> and pass that out with the mutator safely encapsulated in a lambda, I
> supposed
>
> 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.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] struct-copy question

2018-03-21 Thread Eric Griffis
I bump into struct subtleties all the time. For example, my attempts to
#:auto always degenerate into custom constructor procedures; This usually
involves #:constructor-name and #:omit-define-syntaxes, which might not be
a big deal if I had a solid understanding of what these flags actually do.
So far, all of my struct troubles have been rooted in a lack of
understanding.

It is unfortunate that such a fundamental aspect can be so un-intuitive.
Reading the source hasn't helped much because structs are a low-level
construct used *everywhere* for *everything*. This would be a code smell if
I didn't trust that our Racket ancestors knew what they were doing, so the
notion of "fixing" structs (or even struct-copy) seems misguided.

Structs seem to occupy an awkward region of the design space between
totally opaque (e.g. objects) and totally transparent (e.g. algebraic data
types). On one hand, structs are too "open." The "good for everything"
design makes them not particularly great at anything. Prefabs are a
pathological case -- every attempt I've made at using them devolves into
lists or non-prefabs in order to re-gain control over basic things like
construction or printing. On the other hand, structs aren't "open" enough.
Racket's pattern-based binding forms allow me to de-structure, but it's not
yet clear to me how much extra plumbing would be needed for something like
a totality check, or even where that plumbing would go.

I can appreciate the architectural decision that structs represent for the
core -- flexibility often comes with a cost to conciseness and convenience.
For something like a standard library, where transparency prevents friction
between language users and implementers, I think higher-level abstractions
are more appropriate. My preference is for ADTs: they support a
pattern-based functional style, are amenable to static analysis and
automatic tooling, and I already have an intuition for how they should
behave.

/rant

Eric


On Tue, Mar 20, 2018 at 9:36 PM Kevin Forchione  wrote:

>
> Just read your GitHub link and see the problem goes beyond my simple
> #:auto issue. Thanks for that link. I’m pretty green to all the thorny
> issues when it comes to dressing primitive datatypes up in fancy bindings
> and hope the magicians of indirection can somehow pull a rabbit out of the
> hat on this one someday. :)
>
> 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.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Scribble xref links in frog

2018-10-08 Thread Eric Griffis
This is an interesting angle I hadn't yet considered. Working on a GitHub
issue for frog right now.

Eric


On Mon, Oct 8, 2018, 2:04 PM Alexis King  wrote:

> IIRC, --redirect-main only applies to packages installed in installation
> scope, not packages installed in user scope. I don’t know why this is the
> case, and I don’t know if it’s a bug or a (mis)feature, I just vaguely
> remember running into that problem before when using --redirect-main. You
> might try moving everything into installation scope to see if that changes
> things.
>
> > On Oct 8, 2018, at 15:07, Greg Hendershott 
> wrote:
> >
> > Is this for .md or .scrbl sources?
> >
> > If scribble: It's been some years since I worked on this, but at a
> > quick glance Frog is running Scribble with --redirect-main
> > http://docs.racket-lang.org/
> >
> >
> https://github.com/greghendershott/frog/blob/master/frog/private/read-scribble.rkt
> >
> > So I'm not sure what's going on. Maybe easier (for me anyway) if you
> > open an issue there to discuss and investigate more?
> >
> > p.s. It would probably be nice to update the docs.racket-lang.org URL
> > to use https, if that's an easy PR you wanted to do?
> >
> > On Mon, Oct 8, 2018 at 2:50 PM Eric Griffis  wrote:
> >>
> >> My frog-generated blog is almost ready, but there's one detail stopping
> >> the show:
> >>
> >> Is there a way to make frog link to docs.racket-lang.org for all
> scribble
> >> cross-references?
> >>
> >> Exports from the "special" modules (racket/base, racket, ...) already
> >> point to docs.racket-lang.org, but cross-referencing into other
> >> locally-installed packages produces relative URLs to the local docs.
> >>
> >> In the Scribble docs (7.2 Handling Cross-References), I found this:
> >>
> >>The --redirect-main flag for HTML output redirects links to the local
> >>installation’s documentation to a given URL, such as
> >>http://docs.racket-lang.org/.
> >>
> >> Is there some way to pass this flag or emulate its behavior in frog?
> >>
> >> Eric
>
>

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


Re: [racket-users] Scribble xref links in frog

2018-10-08 Thread Eric Griffis
On Mon, Oct 8, 2018 at 1:07 PM Greg Hendershott
 wrote:
>
> Is this for .md or .scrbl sources?

For .scrbl sources.

> If scribble: It's been some years since I worked on this, but at a
> quick glance Frog is running Scribble with --redirect-main
> http://docs.racket-lang.org/
>
> 
> https://github.com/greghendershott/frog/blob/master/frog/private/read-scribble.rkt
>
> So I'm not sure what's going on. Maybe easier (for me anyway) if you
> open an issue there to discuss and investigate more?

Issue opened at https://github.com/greghendershott/frog/issues/229

As Alexis posited, the difference appears to be installation versus user
scope. Not sure how to pursue this yet, so I opened an issue on the frog
tracker anyways.

> p.s. It would probably be nice to update the docs.racket-lang.org URL
> to use https, if that's an easy PR you wanted to do?

Done. PR at https://github.com/greghendershott/frog/pull/230

Eric

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


Re: [racket-users] Scribble xref links in frog

2018-10-08 Thread Eric Griffis
On Mon, Oct 8, 2018 at 5:40 PM Matthew Flatt  wrote:
>
>   --redirect https://docs.racket-lang.org/local-redirect/

This works. Thanks!

Eric

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


[racket-users] Scribble xref links in frog

2018-10-08 Thread Eric Griffis
My frog-generated blog is almost ready, but there's one detail stopping
the show:

Is there a way to make frog link to docs.racket-lang.org for all scribble
cross-references?

Exports from the "special" modules (racket/base, racket, ...) already
point to docs.racket-lang.org, but cross-referencing into other
locally-installed packages produces relative URLs to the local docs.

In the Scribble docs (7.2 Handling Cross-References), I found this:

The --redirect-main flag for HTML output redirects links to the local
installation’s documentation to a given URL, such as
http://docs.racket-lang.org/.

Is there some way to pass this flag or emulate its behavior in frog?

Eric

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


Re: FW: [racket-users] colon keywords

2018-09-23 Thread Eric Griffis
Thanks for the crisp explanation, Jos. This is exactly my concern.

Eric


On Sun, Sep 23, 2018, 2:38 PM Jos Koot  wrote:

>  Forgot to include the users group.
>
> -Original Message-
> From: Jos Koot [mailto:jos.k...@gmail.com]
> Sent: 23 September 2018 21:37
> To: 'Tomasz Rola'
> Subject: RE: [racket-users] colon keywords
>
> MHO, adhere to #:foo,
> because :foo is a permitted identifier.
> I prefer a clear distinction between keywords and identifiers.
> Just like the sharp sign is used in many other output.
> Jos
>
> -Original Message-
> From: racket-users@googlegroups.com [mailto:racket-users@googlegroups.com]
> On Behalf Of Tomasz Rola
> Sent: 23 September 2018 18:50
> To: Racket-Users List
> Cc: Neil Van Dyke; Tomasz Rola
> Subject: Re: [racket-users] colon keywords
>
> On Wed, Sep 19, 2018 at 04:56:05AM -0400, Neil Van Dyke wrote:
> > Currently, in main Racket reader, `#:` starts a keyword, as in `#:foo`.
> >
> > Who on this email list would also like (or not like) `:` to start a
> > keyword, as in `:foo`?
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: [racket-users] Re: Functional augmenting

2019-01-08 Thread Eric Griffis
My bad. I confused ordinary with generic.

On Tue, Jan 8, 2019, 9:47 AM Eric Griffis  Apologies for the backtracking, but I'm still having trouble understanding
> before/after/between and ordinary function composition. For non-method
> functions, what's the difference?
>
> Also, I'd never heard of these functions as a Perl dev. A quick search
> turns up Moose. Is that what you're talking about?
>
> Eric
>
>
> On Tue, Jan 8, 2019, 8:57 AM David Storrs 
>>
>>
>> On Mon, Jan 7, 2019 at 9:58 PM Neil Van Dyke 
>> wrote:
>>
>>> George Neuner wrote on 1/7/19 4:49 PM:
>>> > Though I mostly agree with you, your "advice" does have its uses:
>>> >
>>> >
>>> http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html
>>> > in particular see the sections on method combinations.
>>>
>>> Thank you; I should've looked it up before incorrectly assuming that you
>>> were talking about "advice" from some Lisps.  I initially thought the
>>> original question was getting at something like `defadvice`:
>>>
>>>
>>> https://franz.com/support/documentation/10.1/doc/operators/excl/defadvice.htm
>>>
>>> https://www.gnu.org/software/emacs/manual/html_node/elisp/Porting-old-advice.html
>>>
>>> Part of what bugs me is violation of expectations:  In Racket, when I
>>> see or use a procedure reference in some code, I expect to get a
>>> particular procedure implementation.  (Given a straightforward
>>> understanding of `#lang`, `require`, scoping, and syntax extension.)  If
>>> that's instead documented to be a generic, then my expectations change
>>> to the implementation I receive (probably) performing an analogous
>>> operation.  (Actually, in Racket, I'd say generics and classes are
>>> usually used only when overriding is definitely happening.)
>>>
>>
>> When I use 'advice' (a term which strikes me as an odd choice -- where
>> does it come from?), it's typically because I have a commonly-used library
>> function with a defined interface that isn't quite what I need.
>> String-handling functions are a good example; if my data sources mean I'm
>> going to be feeding either symbols or strings into something that always
>> wants strings, then I can either remember to (e.g.) always wrap a (map ~a)
>> around the args or I can use a 'before' and call it a day.
>>
>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Racket Users" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to racket-users+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Racket Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to racket-users+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>

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


Re: [racket-users] Error location in test submodules

2019-04-02 Thread Eric Griffis
On Tue, Apr 2, 2019 at 1:04 PM Tom Gillespie  wrote:
>
> Are you using emacs racket-mode?

I am, almost exclusively. Exception and check failure locations can be a
pain, but they work in general.

> On Tue, Apr 2, 2019 at 3:41 PM zeRusski  wrote:
>>
>> If I have many test chunks spread around my code and some code change
throws an exception or a contract violation it is impossible to tell which
test triggered it. The only thing in the context is (submod "file.rkt"
test):1:1.

Let's make this concrete. If I create a /tmp/somefile.rkt in Emacs:

#lang racket/base
(define f (λ _ (error 'FAIL)))
(module+ test
  (require rackunit)
  (define OK (string->unreadable-symbol "OK"))
  (define-simple-check (check-OK val)
(eq? val OK))
  (check-OK OK)
  (check-OK #f)
  (check-OK (f)))

and hit C-c C-c with my cursor inside the test sub-module, it prints this
in my Racket REPL:


; FAILURE
; /tmp/somefile.rkt:9:2
name:   check-OK
location:   somefile.rkt:9:2
params: '(#f)

; error: FAIL
; Context:
;  (submod "/tmp/somefile.rkt" test):1:1 [running body]

The first check succeeds silently.

The second check fails because #f is not OK. The location is accurate and
automatically linked to the source.

The third check is never invoked. While evaluating the argument, f throws
an exception and the REPL gives no useful context. I think you're asking
specifically about this case. If the error is in the code being tested and
not in the test itself, I'd want to know where the exception was raised.

In Emacs, hitting C-u C-c C-c inside the test sub-module exposes the
context I'm looking for:

; ...

; error: FAIL
; Context (errortrace):
;/tmp/somefile.rkt:2:15: (error (quote FAIL))
; ...

If I'm generating tests with macros, getting the source locations right can
be a hassle. Sometimes, it's easier to just add with-check-info:

#lang racket/base
(define f (λ _ (error 'FAIL)))
(module+ test
  (require rackunit)
  (define OK (string->unreadable-symbol "OK"))
  (define-syntax-rule (check-OK-form expr)
(let ([val expr])
  (with-check-info (['input 'expr] ['expected OK] ['actual val])
(check eq? val OK
  (check-OK-form OK)
  (check-OK-form (values #f))
  (check-OK-form (f)))

Even without a C-u prefix, the input can help locate the offending check:


; FAILURE
; /tmp/somefile.rkt:9:8
input:  (values #f)
expected:   OK
actual: #f
name:   check
location:   somefile.rkt:9:8

; error: FAIL
; Context:
;  (submod "/tmp/somefile.rkt" test):1:1 [running body]

Most of the time, this is enough for me and I have a habit of polishing
cannon balls.

Eric

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


[racket-users] [ANN] Algebraic Racket

2019-03-31 Thread Eric Griffis
I am pleased to announce Algebraic Racket, an extension for algebraic
structures in untyped Racket.

https://github.com/dedbox/racket-algebraic

Algebraic structures provide the operational under-pinnings for algebraic
data types. What's missing is the static typing constraints.

The initial release provides a #lang algebraic/racket/base that extends
#lang racket/base with:

1. First class, lexically scoped, naturally ordered data constructors.

  > (data Maybe (Just Nothing))
  > (define maybe
  (function*
[(n _ Nothing) n]
[(_ f (Just x)) (f x)]))
  > (maybe #f values (Just 123))
  123
  > (maybe #f values Nothing)
  #f

2. A consistent destructuring syntax for functions and macros.

  > (define fib
  (function
[n #:if (< n 2) 1]
[n (+ (fib (- n 1))
  (fib (- n 2)))]))
  > (map fib (build-list 7 values))
  '(1 1 2 3 5 8 13)

  > (define-syntax m-fib
  (macro
[n:nat #:if (< (var n) 2) 1]
[n:nat (+ (m-fib #,(- (var n) 1))
  (m-fib #,(- (var n) 2)))]))
  > (list (m-fib 0) (m-fib 1) (m-fib 2)
  (m-fib 3) (m-fib 4) (m-fib 5) (m-fib 6))
  '(1 1 2 3 5 8 13)

The package is fully documented. The documentation includes the first of
three tutorials in a series on building interpreters with Algebraic
Racket.

Algebraic Racket is the first major milestone in a larger effort to
produce a complete language-oriented toolkit for integrating algebraic
structure into more sophisticated designs.

The project aims to:

  1. Implement and document the forms, functions, and syntax classes
 comprising Algebraic Racket for maximum potential reuse.

  2. Support the development of modular type systems and other
 language-facing components as libraries.

Pull requests of any size are welcome. For major changes, please start a
conversation on racket-users or open an issue to discuss what you would
like to change.

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


Re: [racket-users] Re: What is the best way to "raco make" all *.rkt files in a directory tree?

2019-03-11 Thread Eric Griffis
On Mon, Mar 11, 2019 at 12:04 PM Brian Adkins  wrote:
>
> Hmm...  maybe the problem was just my lack of shell skills. I think the 
> following works:
>
> raco make -j 8 */*.rkt

This will only make the rkt files in subdirectories of the current
working directory, excluding sub-subdirectories and the current
working directory.

You can get them all with "find":

find . -name \*.rkt -exec raco make -j 8 {} \;

But this will run a separate "raco make" for each file, which may
defeat the purpose of your "-j 8" switch. If your shell supports the
"globstar" (**) in file paths (e.g. bash, zsh, maybe ksh):

raco make -j 8 *.rkt **/*.rkt

Otherwise, there's always xargs:

find . -name \*.rkt -print0 | xargs -0 -- raco make -j 8

FWIW, when my projects need "make"-ing, I turn them into packages and
install them. The installation process will "make" every rkt file in
the project folder, and the whole thing can be rebuilt with raco
setup:

raco setup -D 

Eric

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


[racket-users] scopes across files

2019-06-03 Thread Eric Griffis
Several times now, I've run into one or another form of the following
problem:

Say I want to build primitives to

   1. declare an "interface" as a list of names, and
   2. implement and use those names at run time in a limited scope

Concretely, I want to run the following code:

(interface Speaker say speak)
(implement Speaker displayln (say 'hello) speak)

If I put these lines at the end of a file that implements the two forms, it
should (displayln 'hello) when I run it.

Here is the interface macro:

(define-syntax (interface stx)
  (syntax-case stx ()
[(_ id member-id ...) #'(define-syntax id #'(member-id ...))]))

The implement macro is trickier. A naive implementation looks like this:

(define-syntax (implement stx)
  (syntax-case stx ()
[(_ class-id def ... expr)
 (with-syntax ([(id ...) (syntax-e (syntax-local-value #'class-id))])
   #'(letrec ([id def] ...) expr))]))

It fails with the following message:

; /tmp/j.rkt:44:30: say: unbound identifier;   in: say;   context...:;
   #(570423 use-site) [common scopes];   other binding...:;local;
  #(570422 macro) [common scopes];   common scopes...:;#(570223
module) #(570226 module j) #(570426 local) #(570427 intdef);
#(570428 local)

Incorporating the debug-scopes package's +scopes macro shows this:

(letrec⁰˙˙¹
 ((say⁰˙˙¹ displayln⁰˙˙³) (speak⁰˙˙¹ (say⁰˙˙³ (quote⁰˙˙³ hello⁰˙˙³
 speak⁰˙˙³)ˢˡⁱ⁼²⁺ᵘˢᵉ⁼³0 module   5705121 module j 5705152 macro
5707193 use-site 570720

For reasons I don't yet fully comprehend, it just works out if I use
syntax-local-introduce on the id's, so +scopes gives me this:

(letrec⁰˙˙¹
 ((say⁰˙˙³ displayln⁰˙˙³) (speak⁰˙˙³ (say⁰˙˙³ (quote⁰˙˙³ hello⁰˙˙³
 speak⁰˙˙³)ˢˡⁱ⁼²⁺ᵘˢᵉ⁼³0 module   5712471 module j 5712502 macro
5714553 use-site 571456

But if the interface and implement invocations are not in the same file as
their implementations, it breaks with a similar error:

; /tmp/h.rkt:5:30: say: unbound identifier;   in: say;   context...:;
  #(572682 module) [common scopes];   other binding...:;local;
#(572388 module) #(572391 module j) #(572596 module);#(572599
module j) [common scopes];   common scopes...:;#(572685 module h)
#(572700 local) #(572701 intdef) #(572702 local)

In this situation, +scopes gives:

(letrec⁰˙˙³
 ((say⁴˙˙⁵ displayln⁴˙˙⁶) (speak⁴˙˙⁵ (say⁴˙˙⁶ (quote⁴˙˙⁶ hello⁴˙˙⁶
 speak⁴˙˙⁶)ˢˡⁱ⁼⁶⁺ᵘˢᵉ⁼0 module   5768541 module j 5768572 module
5770563 module j 5770594 module   5771505 module h 5771536 macro
577173

If I move the interface invocation back into the original file and keep the
implement invocation in a separate file, I get the same error but +scopes
gives something slightly different:

(letrec⁰˙˙³
 ((say⁰˙˙⁴ displayln⁴˙˙⁶) (speak⁰˙˙⁴ (say⁴˙˙⁶ (quote⁴˙˙⁶ hello⁴˙˙⁶
 speak⁴˙˙⁶)ˢˡⁱ⁼⁴⁺ᵘˢᵉ⁼0 module   5723881 module j 5723912 module
5725963 module j 5725994 macro5726975 module   5726826 module h
572685

What's going on here? How do I fix this?

Eric

-- 
You received this message because you are subscribed to the Google 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/CAORuSUz_v5jYSFQetnuLb6haNx8Hwo0CqR0Bm-jCJO0DT7Bz6w%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: scopes across files

2019-06-03 Thread Eric Griffis
Apologies to mobile users. The superscripts added by +scopes aren't boxes
in the Web client.

To clarify my question: how do I handle the situation where variables bound
by one macro and used by another are out of scope when file boundaries are
involved?

The +scopes into shows that the scope sets go from intersecting to disjoint
or sharing only a macro scope.

On Mon, Jun 3, 2019, 11:52 AM Eric Griffis  wrote:

> Several times now, I've run into one or another form of the following
> problem:
>
> Say I want to build primitives to
>
>1. declare an "interface" as a list of names, and
>2. implement and use those names at run time in a limited scope
>
> Concretely, I want to run the following code:
>
> (interface Speaker say speak)
> (implement Speaker displayln (say 'hello) speak)
>
> If I put these lines at the end of a file that implements the two forms,
> it should (displayln 'hello) when I run it.
>
> Here is the interface macro:
>
> (define-syntax (interface stx)
>   (syntax-case stx ()
> [(_ id member-id ...) #'(define-syntax id #'(member-id ...))]))
>
> The implement macro is trickier. A naive implementation looks like this:
>
> (define-syntax (implement stx)
>   (syntax-case stx ()
> [(_ class-id def ... expr)
>  (with-syntax ([(id ...) (syntax-e (syntax-local-value #'class-id))])
>#'(letrec ([id def] ...) expr))]))
>
> It fails with the following message:
>
> ; /tmp/j.rkt:44:30: say: unbound identifier;   in: say;   context...:;
> #(570423 use-site) [common scopes];   other binding...:;local;
> #(570422 macro) [common scopes];   common scopes...:;#(570223 module) 
> #(570226 module j) #(570426 local) #(570427 intdef);#(570428 local)
>
> Incorporating the debug-scopes package's +scopes macro shows this:
>
> (letrec⁰˙˙¹
>  ((say⁰˙˙¹ displayln⁰˙˙³) (speak⁰˙˙¹ (say⁰˙˙³ (quote⁰˙˙³ hello⁰˙˙³
>  speak⁰˙˙³)ˢˡⁱ⁼²⁺ᵘˢᵉ⁼³0 module   5705121 module j 5705152 macro5707193 
> use-site 570720
>
> For reasons I don't yet fully comprehend, it just works out if I use
> syntax-local-introduce on the id's, so +scopes gives me this:
>
> (letrec⁰˙˙¹
>  ((say⁰˙˙³ displayln⁰˙˙³) (speak⁰˙˙³ (say⁰˙˙³ (quote⁰˙˙³ hello⁰˙˙³
>  speak⁰˙˙³)ˢˡⁱ⁼²⁺ᵘˢᵉ⁼³0 module   5712471 module j 5712502 macro5714553 
> use-site 571456
>
> But if the interface and implement invocations are not in the same file
> as their implementations, it breaks with a similar error:
>
> ; /tmp/h.rkt:5:30: say: unbound identifier;   in: say;   context...:;
> #(572682 module) [common scopes];   other binding...:;local;#(572388 
> module) #(572391 module j) #(572596 module);#(572599 module j) [common 
> scopes];   common scopes...:;#(572685 module h) #(572700 local) #(572701 
> intdef) #(572702 local)
>
> In this situation, +scopes gives:
>
> (letrec⁰˙˙³
>  ((say⁴˙˙⁵ displayln⁴˙˙⁶) (speak⁴˙˙⁵ (say⁴˙˙⁶ (quote⁴˙˙⁶ hello⁴˙˙⁶
>  speak⁴˙˙⁶)ˢˡⁱ⁼⁶⁺ᵘˢᵉ⁼0 module   5768541 module j 5768572 module   5770563 
> module j 5770594 module   5771505 module h 5771536 macro577173
>
> If I move the interface invocation back into the original file and keep
> the implement invocation in a separate file, I get the same error but
> +scopes gives something slightly different:
>
> (letrec⁰˙˙³
>  ((say⁰˙˙⁴ displayln⁴˙˙⁶) (speak⁰˙˙⁴ (say⁴˙˙⁶ (quote⁴˙˙⁶ hello⁴˙˙⁶
>  speak⁴˙˙⁶)ˢˡⁱ⁼⁴⁺ᵘˢᵉ⁼0 module   5723881 module j 5723912 module   5725963 
> module j 5725994 macro5726975 module   5726826 module h 572685
>
> What's going on here? How do I fix this?
>
> Eric
>

-- 
You received this message because you are subscribed to the Google 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/CAORuSUzCs5SiisiLjG3uQMiBdK%2BOHOjq8sgEsNdw54LUMAeEEA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] scopes across files

2019-06-11 Thread Eric Griffis
On Thu, Jun 6, 2019 at 12:19 AM Fastmail  wrote:
>
> The `implement` macro needs to place its identifiers (say, `say`) inside
> the lexical context of the calling site, so that they bind other code
> coming in from the calling site (for instance, `(say 'hello)`).

Thanks! This was incredibly helpful. Swimming in a soup of phase-1 details, I
forgot which way is up -- in this case, toward the caller's context.

It's too easy to lose sight of the forest for the trees at this part of the
journey.

Eric

-- 
You received this message because you are subscribed to the Google 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/CAORuSUzYJL87NdTFLcb27pdMRe2yddD6fdnO37O7Y5b0Zj0dHw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Re: doing a "show hn" of your racket project

2019-06-23 Thread Eric Griffis
This is the kind of stuff I look for in my Twitter feed. If I knew how
to subscribe to updates, I would.

Eric


On Fri, Jun 21, 2019 at 1:16 AM Dexter Lagan  wrote:
>
>   Once my git repos will be presentable, you can be sure I'll show it all to 
> HN. I'm a beyond-full-time Racket programmer and I intend to share most of 
> the non-commercial code I write. I also started two blogs:
>
> About lisp in general, but contains a lot of Racket-related posts
> www.newlisper.com/blog
>
> and
>
> A more general, deeply technical blog, will also contain less specific posts 
> about Racket:
> www.eicm.net/blog
>
>   They haven't been published anywhere, and maybe Racketeers can give me some 
> feedback before I make a fool of myself elsewhere. If the content is up to 
> par, feel free to mention it in the newsletter.
>
> Dex

-- 
You received this message because you are subscribed to the Google 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/CAORuSUykoJQ9-Fa9S4DEgDDEgTi5u%3D2fgXp6EAjyk3DxPyn_-w%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Can phase-1 transformer bindings be overridden locally?

2019-05-03 Thread Eric Griffis
I have a macro that creates transformer bindings at phases 0 and 1:

(define-syntax (f stx)
  (with-syntax ([name (cadr (syntax-e stx))])
#'(begin
(define-syntax name (syntax-id-rules () [_ 1]))
(begin-for-syntax (define-syntax name (syntax-id-rules () [_
2]))

Normally, this works fine. I have syntax transformers bound at both phases
that can resolve "name" with syntax-local-value.

In an expression context, the phase-0 transformer binding can be
overridden temporarily with let-syntax:

(cons
 x (let-syntax
   ([x (syntax-id-rules () [_ 'one])]
[y (λ (stx) (datum->syntax stx (syntax-local-value #'x)))])
 (list x y)))

This produces '(1 one #). With syntax-local-eval instead
of syntax-local-value, it produces '(1 one 2).

Because "f" produces begin-for-syntax, it only works in a module or
top-level evaluation context:

(let () (f x) x)

/tmp/g.rkt:10:8: begin-for-syntax: not in a definition context
  in: (begin-for-syntax (define-syntax x (syntax-id-rules () (_ 2

Is there a way to override temporarily the phase-1 transformer binding as
well?

Eric

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


Re: [racket-users] Pattern matching as computation

2019-06-27 Thread Eric Griffis
On Thu, Jun 27, 2019 at 11:56 AM David Storrs 
wrote:
>
> Suppose instead I wanted to have a pattern like so (this does not work):
>
> (match (vector 1 2 3 4)
>   [(vector a (app + b ..2 x) c) (list a b c x)]
> ; => '(1 (2 3) 4 5))  ;  NB:  does not work

We have a few problems here.

The pattern (vector a ? c) does not match the shape of the val-expr
(vector 1 2 3 4).

In the second sub-pattern (app + b ..2 x), Racket complains `..2' is an
"incorrect use of ... in pattern" because every sub-pattern of `app' must
independently match the result of (+ 2).

To get the expected result '(1 (2 3) 4 5) from the actual result (list a b
c x), we'd need the following bindings:

a --> 1
b --> '(2 3)
c --> 4
x --> 5

At this point, I'm not sure what you're trying to do. Maybe you're trying
to bind `b' to '(2 3), then `x' with the sum (+ 2 3), then `c' with 4.

Here's one way to do it from within a single pattern:

(match (vector 1 2 3 4)
  [(and (vector a _ _ c)
(app (λ (vec)
   (match vec
 [(vector _ p q _)
  (list (list p q) (+ p q))]))
 (list b x)))
   (list a b c x)])

> Less trivially, I'd like to be able to do something like this:
>
> #lang racket
> (struct person (name age) #:prefab)
> (struct horse (color owner) #:prefab)
>
> ; The following does not work
> (match (vector 'brown 'bob 23)
>   [(vector the-color (app (curry apply person) args ... the-owner))
>(horse the-color the-owner)])

Here's an adaptation of the above technique that works:

(match (vector 'brown 'bob 23)
  [(and (vector the-color _ _)
(app (λ (vec)
   (match vec
 [(vector _ name age)
  (person name age)]))
 the-owner))
   (horse the-color the-owner)])

Incidentally, Algebraic Racket is designed for this:

#lang algebraic/racket/base

(require (prefix-in algebraic- algebraic/racket/base/forms))

(algebraic-case (vector 1 2 3 4)
  [#(a p q c)
   #:with b (list p q)
   #:with x (+ p q)
   (list a b c x)])

(algebraic-case (vector 'brown 'bob 23)
  [#(the-color name age)
   #:with the-owner (person name age)
   (horse the-color the-owner)])

If a #:with directive fails, the overall match fails:

(algebraic-case (vector 'brown 'bob 23)
  [#(the-color name age)
   #:with the-owner #f
   #:with (person _ _) the-owner
   (horse the-color the-owner)])

Eric

-- 
You received this message because you are subscribed to the Google 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/CAORuSUxETFymuLMd1RQmUNdqrLug4CghXYvCDB__VYvGgP0zGA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] [PSA] Upcoming projects

2019-06-27 Thread Eric Griffis
Hello everyone,

Over the next few months, I will be breaking ground on three new projects.

== A diagramming library ==

  An Algebraic Racket port of Haskell's diagrams library:

  https://archives.haskell.org/projects.haskell.org/diagrams/

  I love this design. It's like Pict, but the API is structured as a
  monoid under cc-superimpose.

== A dynamic, interactive data visualization library ==

  An aggressive Algebraic Racket adaptation of the parts of D3.js I like.

  Initial use cases:
  - concurrent / distributed process network visualizations
  - hybrid text/graphical UIs with automatic layout
  - a generic feed browser

== A digital audio workstation library ==

  An experiment in real-time interactive Neuron programming.

  The base package will include a basic synth, a sampler, a sequencer, and
  a multi-track recorder -- like a developer API for Fruity Loops.

  Endpoints for MIDI and audio I/O should be easy to build with packages
  in the official repo.

  Optimistic feature list:
  - multi-track recording and playback (audio & MIDI)
  - non-destructive edits
  - mix automation
  - inter-process signal routing
  - global clock synchronization

I will then combine these projects into a hybrid DAW / VJ instrument and
target a live A/V performance for FARM 2020, the SIGPLAN workshop for
functional art and music co-located with ICFP.

If any part of this interests you, however large or small, reach out!

If you are working on related software, or planning to, speak up!

Eric

-- 
You received this message because you are subscribed to the Google 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/CAORuSUxhq5baH%3D7eKQ-hy6AMo1qnkRP60awNxYY_2VH_8kg8QQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] [PSA] Upcoming projects

2019-06-28 Thread Eric Griffis
On Thu, Jun 27, 2019 at 9:12 PM Daniel Prager  wrote:
>
> Hi Eric
>
> They all sound great.
>
> I'm particularly interested in the first two, and was very impressed by the 
> Diagram project gallery, and it would be great to see in Racket.

Cool! Thanks for the comments.

> Quick question: Why Algebraic Racket?
>
> Dan

If I understand the question, you're asking what makes Algebraic Racket
"algebraic?"

It started as an attempt to implement algebraic data types without
committing to a type system. Turns out, "typed algebraic structures minus
the typing constraints" is a useful design heuristic.

Eric

-- 
You received this message because you are subscribed to the Google 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/CAORuSUzu0BoeBLZ9v9XwuapWPge%3DQ_Qj3q6vVt39U6euFA5Heg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] [PSA] Upcoming projects

2019-06-28 Thread Eric Griffis
> Why implement these projects in Algebraic Racket?

Good question -- not so easy to answer cleanly. Here's a smattering.

I created Algebraic Racket to make functional meta-programming in Racket
more enjoyable. My talk will demonstrate what I mean by that and why it
matters in practice.

The packages are also a field test for Algebraic Racket's extended feature
set. The diagrams library uses classes for ad hoc polymorphism. The
visualization and audio libraries use algebraic data for inter-process
messaging.

Algebraic Racket is designed to accommodate my programming style:
mostly-pure, compositional, driven by structural pattern matching at
multiple run-time phases. I like match and syntax-parse, but I love
Algebraic Racket.

(Don't tell Matthias I said this, but sometimes point-free style is more
compact and easier to read. This happens a lot more often in Algebraic
Racket, and it leads to good things.)

Algebraic Racket is mostly just extra syntax for the Racket base.
Replacing #lang racket/base with #lang algebraic/racket/base should not
change what a program does or slow it down much, and modules in one
language can be used in the other. Pattern-based variants of core Racket
syntactic forms (e.g, let, case, define) can be imported, but that breaks
drop-in compatibility.

Eric

-- 
You received this message because you are subscribed to the Google 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/CAORuSUydHGPBd7bpKEtnqaL2-H5hCYUvysyn2tQ1-ai5JSejfA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Evaluating to get the output with a specific lang

2019-11-10 Thread Eric Griffis
This works:

1. mkdir foo; cd foo; raco pkg install

2. create foo/main.rkt:

```
#lang racket/base

(module reader racket/base
  (require racket/port)
  (provide (rename-out [foo-read read]
   [foo-read-syntax read-syntax]))
  (define (foo-read port)
`(module ,(gensym 'foo) racket/base
   (provide the-foo)
   (define the-foo (let () ,@(port->list read port)
  (define (foo-read-syntax path port)
(datum->syntax #f (foo-read port
```

3. In the REPL or another file, we can simulate the game's interaction with
the player's connection through an input port:

```
(define foo-source #<namespace 'racket/base
```

The value-extraction code is kind of messy, so you might want to stow it in
a `port-read-handler`, like this:

```
(port-read-handler
 player-input
 (let ([default-handler (port-read-handler player-input)])
   (case-lambda
 [(in) (define original-handler (port-read-handler in))
   (define define-mod
 (parameterize ([read-accept-reader #t])
   (port-read-handler in default-handler)
   (begin0 (read in) (port-read-handler in original-handler
   (define mod-name `(quote ,(cadr define-mod)))
   (eval `(begin ,define-mod (let () (local-require ,mod-name)
the-foo))
 (module->namespace 'racket/base))]
 [(in source) (datum->syntax #f (read in))])))

(println `(GOT ,(read player-input)))
```

Eric



On Sun, Nov 10, 2019 at 12:19 PM Christopher Lemmer Webber <
cweb...@dustycloud.org> wrote:

> Hi Eric!  Thanks very much for the reply.
>
> Eric Griffis writes:
>
> >> It appears there must be; when I look at `build-program` in
> >> sandbox.rkt it also looks like it's wrapping things in a module
> >> structure... but I don't see how it then exports from that module or
> >> how the code evaluating it imports its export.  Or does it actually
> >> do so via an effect?  I see there are some channels involved
> >> (input-ch / result-ch) so maybe it's passing back the result through
> >> there, but I am having trouble figuring out how.
> >
> > Apologies for stating the obvious, but to get a value out of a module, we
> > `provide` it:
> >
> > In foo/main.rkt:
> >
> > ```
> > (define-syntax-rule (foo-module-begin form ... final-form)
> >   (#%module-begin (provide the-foo) form ... (define the-foo
> final-form)))
> > ```
> >
> > Then we can produce and consume foo-based modules like this:
> >
> > ```
> > (module bar-mod foo (define bar 1) (+ bar 2))
> >
> > (define my-bar (let () (local-require 'bar-mod) the-foo))
> > ```
>
> This approach works, but I'm not sure it works for my use case, because
> `module` is appearing at compile-time.
>
> Let me try to lay out the use case, and maybe it helps.
>
>  - We are in a MUD, or some other interactive game.  The game is running
>live.  Some players have capabilities to provide new code for game
>characters in the system or other interesting features.
>
>  - The users are able to write scripts that return things... however,
>they are providing the scripts as the game is running.  (This will be
>ocap safe, but I'll explains how that works in a separate
>email... just trust me that I believe that if I can run it with in a
>special restricted language and return a value from that module which
>is loaded *at runtime* somehow, I can pull off this goal safely.)  As
>such, we cannot at the time that we are starting the program actually
>know or load all of the modules, because the users are providing some
>of them live.
>
>  - As such we need to be able to do something along the lines of what
>you just did, but we have to do it at runtime.
>
>  - I don't necessarily want to attach each of these user-supplied
>modules to a global namespace; a user might experiment with making
>many of them, and there's no need.
>
> Does that make sense?
>
> I'll explain more about how this can be ocap safe in a future email.
> For the moment, if you're curious on how this design works, more is
> here (the "emaker" pattern):
>
>   http://www.skyhunter.com/marcs/ewalnut.html#SEC16
>

-- 
You received this message because you are subscribed to the Google 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/CAORuSUyo6isrHBY%3Do40XH6fCQviCEasDQGd7d2t%2ByhRPc%2BAzfw%40mail.gmail.com.


Re: [racket-users] Evaluating to get the output with a specific lang

2019-11-10 Thread Eric Griffis
On Sun, Nov 10, 2019 at 6:45 AM Christopher Lemmer Webber <
cweb...@dustycloud.org> wrote:
>
> It sounds like what I want is the case of the export.

I'll run with this.

> I guess a question remaining then is: if I'm doing this kind of dynamic
> import of the module, is there a way to require from it (especially if
> it isn't assigned to a "filename" on disk?).

Try `local-require` inside a `let` or `let-values` body.

> It appears there must be;
> when I look at `build-program` in sandbox.rkt it also looks like it's
> wrapping things in a module structure... but I don't see how it then
> exports from that module or how the code evaluating it imports its
> export.  Or does it actually do so via an effect?  I see there are some
> channels involved (input-ch / result-ch) so maybe it's passing back the
> result through there, but I am having trouble figuring out how.

Apologies for stating the obvious, but to get a value out of a module, we
`provide` it:

In foo/main.rkt:

```
(define-syntax-rule (foo-module-begin form ... final-form)
  (#%module-begin (provide the-foo) form ... (define the-foo final-form)))
```

Then we can produce and consume foo-based modules like this:

```
(module bar-mod foo (define bar 1) (+ bar 2))

(define my-bar (let () (local-require 'bar-mod) the-foo))
```

Coincidentally, I've got notes on using this technique to wedge a `#lang`
into the body of a defining form; a `define-foo` form, for example, that
treats its contents as if it were read from a file that starts with `#lang
foo`. It's part of an upcoming blog series on functional meta-programming
with Racket. I've got a few graphics packages in the pipe to celebrate the
Racket Game Jam, so it might be a few weeks before this article hits the
blog, but I'm happy to continue discussing and share my notes any time.

Eric

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


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

2019-12-14 Thread Eric Griffis
Unsafe operations are usually defined externally, like in a C extension,
where safety is harder to guarantee and module hierarchies are less
idiomatic. The "unsafe" moniker is a standard warning that you are
responsible for understanding the underlying implementation and calling
into it responsibly, or risk crashing.

The documentation, assuming you know this, explains how to swap the unsafe
variants into a module that already uses the safe API, effectively
bypassing safety features like contracts and dynamic dispatch.

If you're going to use unsafe operations, make sure you need the extra
juice and are confident nothing is going to break. This isn't just the deep
end of the pool -- it's the screws holding the drain to the bottom.

Eric


On Sat, Dec 14, 2019, 5:58 PM Jack Firth  wrote:

> I think that documentation fix is a good idea. More broadly, it seems
> awkward that all of the unsafe ops for different data types are combined
> together into a single module. I would instead expect there to be modules
> like racket/fixnum/unsafe, racket/struct/unsafe, racket/vector/unsafe, etc.
> But I've never used the unsafe ops before, maybe those who have can chime
> in?
>
> On Saturday, December 14, 2019 at 1:03:14 PM UTC-8, Dominik Pantůček wrote:
>>
>> Hello,
>>
>> the documentation at https://docs.racket-lang.org/reference/fixnums.html
>> is misleading at best. If you - as I did - use the suggested approach of
>> requiring optimized (and unsafe) fx... operations from racket/unsafe/ops
>> with:
>>
>> (require (filtered-in
>>   (λ (name) (regexp-replace #rx"unsafe-" name ""))
>>   racket/unsafe/ops))
>>
>> You end up using _all_ symbols from racket/unsafe/ops. All of them are -
>> of course - uncontracted. Which means that if you issue for example
>> vector-ref on something that is not a vector, it can crash the runtime
>> without any apparent reason - instead of just throwing an exception as
>> one would expect.
>>
>> A simple documentation fix should probably go along the lines:
>>
>> (require racket/require
>>  (filtered-in
>>   (λ (name)
>> (and (regexp-match #rx"^unsafe-fx" name)
>>  (regexp-replace #rx"unsafe-" name "")))
>>racket/unsafe/ops))
>>
>> Or is it just me running into corner cases with optimized Racket code?
>>
>>
>> Cheers,
>> Dominik
>>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/c118c47e-fccd-4fab-b252-7a24afe6eef1%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/CAORuSUxiZ%3DD9446pqs1cK2XCGzt1OHkoij5Kzf2-65QE_APyTA%40mail.gmail.com.


Re: [racket-users] Remind me?: bidirectional channel-ish thing in two parts

2019-10-25 Thread Eric Griffis
Maybe pipe ports?

https://docs.racket-lang.org/reference/pipeports.html

Eric


On Thu, Oct 24, 2019, 11:28 PM David Storrs  wrote:

> I saw something in the Reference about bi-directional {pipes |
> channels | ???} with a constructor that returned two values, A and B,
> where data put onto A could be read out of B and vice versa.  I can't
> remember what it was called and my reference-search-fu is weak.  It's
> not the one from Distributed Places
> (
> https://docs.racket-lang.org/distributed-places/index.html?q=bi-directional#%28part._.Async_.Bidirectional_.Channels%29
> ).
>
> Could someone remind me what these things are called?
>
> --
> You received this message because you are subscribed to the Google 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/CAE8gKod4smzgAwye14zZauVL4nhHB%3DnNPMWRGKkgKEOM3wCxAg%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/CAORuSUzQ-igz1gd1qE-j_diRwLH%3D9Pgp2Nufk7O8r8OxL0LLpw%40mail.gmail.com.


Re: [racket-users] Re: My macro works in the global namespace, but fails inside of a let

2019-10-07 Thread Eric Griffis
Hi Cistian,

Both of your examples are hygienic, in the sense that neither actually
do anything that violates macro hygiene.

When `a_definition` is defined in the module context (i.e., the
"global namespace"), it has the same scope as the `a_definition` used
inside `my-macro`. (There's more to it, but this is enough for now.)

When `a_definition` is defined in a local context (e.g., inside a
`(let () ...)` form) outside `my-macro`, it won't have the same scope
as the `a_definition` used inside `my-macro`.

There's an easy trick to get around this. As Simon suggested, make
`a_definition` an argument to `my-macro`:

  (define-simple-macro (my-macro a_definition)
(display a_definition))

Now, each call to `my-macro` "borrows" `a_definition` from the macro
caller's scope. There are other ways to tackle the problem, but this
is the safest option.

Eric

On Mon, Oct 7, 2019 at 7:33 AM Cistian Alejandro Alvarado Vázquez
 wrote:
>
> Okay, that I am aware of, but why is it hygienic inside of let but *not* in 
> the global namespace? Also, you should (from my limited understanding!) still 
> be able to access bindings from inside of a macro, no? For example, I can 
> call functions inside of a macro and those identifiers are available even 
> though they weren't provided as arguments. So it appears that macros have 
> access to module-level bindings but NOT more local bindings, and that is what 
> I'm confused about.
>
> On Monday, 7 October 2019 08:04:56 UTC-5, Simon Schlee wrote:
>>
>> Your second macro does not work as you expect, because by default macros in 
>> racket are hygienic, described roughly that means that a macro only 
>> "manipulates" the syntax it is given as arguments, not with the syntax 
>> around its invocation. As gfb has mentioned one way to do this is to use 
>> parameters, this way you can achieve dynamic effects without breaking 
>> hygiene.
>>
>> Why is hygiene good? This section in the guide explains: 
>> https://docs.racket-lang.org/guide/pattern-macros.html?q=macro#%28part._.Lexical_.Scope%29
>>
>> You say you want to use some definitions in your macro, why not just pass 
>> the relevant ones as parameters?
>> Without knowing more about what you are trying to do, it is difficult to 
>> suggest a good direction/solution.
>>
>> Not part of the answer, but related and interesting:
>> (fifth RacketCon): Matthew Flatt — Bindings as Sets of Scopes
>> https://www.youtube.com/watch?v=ABWLveMNdzg
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/47407fc2-2c51-4cf1-a5b7-78a390484fbf%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/CAORuSUwA-%3DLEK7DughwXZKyW2d10oxV8EcXgGgx5jnonioMX6g%40mail.gmail.com.


Re: [racket-users] Announcing something Kinda FRP-y

2020-01-27 Thread Eric Griffis
Hi Sage,

This is pretty cool. With a non-OOP option on the table, I might
finally get around to working on an IMGUI-like for Racket.

Have you thought about a reader extension to compress the notation?
The `stateful-cell` function kinda acts like a box and kinda looks
like a `syntax` (or `quote-syntax` w/ kw arg) form, both of which have
special #-prefixed notations. Extending the reader to abbreviate
`(stateful-cell 1)` and  `(stateful-cell (λ _ (+ (x) (y` to, say,
#?1 and #?(+ (x) (y)), respectively, could be a fun project.

Eric

On Sun, Jan 26, 2020 at 3:30 PM Sage Gerard  wrote:
>
> Announcing a new package: kinda-ferpy. Here's a write-up. It implements the 
> spreadsheet metaphor in an expressive way, based on MaiaVictor's excellent 
> PureState library. It's not a complete functional reactive programming 
> interface, but it does conveniently express Racket values as dependent 
> computations.
>
> (require kinda-ferpy)
>
> (define x (stateful-cell 1))
> (define y (stateful-cell 1))
> (define sum (stateful-cell (λ _ (+ (x) (y)
>
> (displayln (sum)) ; 2
> (y 8)
> (displayln (sum)) ; 9
>
>
> ~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/QO0uwg7I2YeD0nczzY77m3RVr6TceC-IY1YunNNYqiq55n_bjHpKh-Rnf5xo1zGgLa44giG3SmxwhenvbHt84u4J4Rm6M2whybBOpWxuCtY%3D%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/CAORuSUw8fDe8CtxKH-gCke3hoWnhekUHMx8B9DxvYcn8HwaHnw%40mail.gmail.com.


Re: [racket-users] how to reinstall a broken package?

2020-01-23 Thread Eric Griffis
Hi Hendrick,

There's always --force.

raco pkg remove --force glm

This works fine when I know I'm going to reinstall the package before
using its dependents.

Eric

On Thu, Jan 23, 2020 at 6:34 AM Hendrik Boom  wrote:
>
> My installation of OpenGL Mathematics (GLM) for Racket is defective
> in that the installed manual has tha complete table of contents but does not
> have any content past section 2.1.1.
> This may be because of running out of disk space during installation.
>
> Asking raco pkg to install it does not work because it thinks it is already
> installed and up-to-date.
>
> Asking raco pkg to remove it just gives ma complaints that other packages
> depend on it - other packages that I don't want to uninstall.
>
> Is there a convenient way to ask raco to reinstall a package?
>
> -- 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/20200123143402.3gsduqfndq6rer3n%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/CAORuSUxo8f9%2B2sSEa9LXEFzcuOmfGFy9yZrxX2MNoBnzX3Dusg%40mail.gmail.com.


Re: [racket-users] How do I provide a name as both a match expander and contracted function?

2019-12-31 Thread Eric Griffis
Hi Jack,

It can be done with make-rename-transformer.

(define (foo? obj) (equal? obj foo-impl))
> (define foo-widget list)
>
> (define/contract (foo-impl _) (-> number? symbol?) 'a-foo)
>
> (define-match-expander foo
>   (syntax-parser [(_ widget) #'(? foo? (app foo-widget widget))])
>   (make-rename-transformer #'foo-impl))
>
> ; (foo #t) ; contract violation
>
> (foo 123)


Eric


On Mon, Dec 30, 2019 at 7:07 PM Jack Firth  wrote:

> If I'm making my own data types, one common thing I want to do is make
> smart constructors that double as match expanders. I could use
> `define-match-expander` with two transformers, but then I can't add a
> contract to the smart constructor with `contract-out`. If I try to write
> this:
>
> (provide
>  (contract-out
>   [foo (->* (widget?) (#:name symbol?) foo?)]))
>
> (define (make-foo widget #:name [name #f])
>   ...)
>
> (define-match-expander foo
>   (syntax-parser [(_ widget) #'(? foo? (app foo-widget widget))])
>   (syntax-parser [(_ arg ...) #'(make-foo arg ...)]))
>
> ...then the use of `contract-out` hides the fact that `foo` is a match
> expander. What should I do?
>
> --
> You received this message because you are subscribed to the Google 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/2dac85e9-8058-437c-b5bc-a92f659c02f6%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/CAORuSUwWSyb42_-a1fgoRDFi0rKeCiRHmO7st3E3n_j-CKdL1w%40mail.gmail.com.


[racket-users] Re: Code generation performance

2020-03-14 Thread Eric Griffis
I'm reluctant to 
anti-inline these because they keep the written code small and the 
generated code fast.

I guess the next step is to anti-inlinedefine-dvec4-unop and 
define-dvec4-binop, maybe eliminate some define/contract's, and re-profile.

Eric


On Friday, March 13, 2020 at 6:20:47 PM UTC-7, Eric Griffis wrote:
>
> Hello, 
>
> I've got a package that generates (i.e., expands into) a ridiculous 
> amount of Racket code. I'd like to generate an unbelievable amount of 
> code, but things have already slowed down a lot. 
>
> At this point, I'm generating 20% of a massive code base and it takes 
> 4 minutes to compile (i.e., raco make) it all. If those numbers scale 
> linearly, I'm looking at 20 minutes to generate and compile the full 
> code base. Realistically, that's an optimistic lower bound. 
>
> How might I go about profiling something that does most of its work at 
> expansion time? 
>
> Should I be concerned about knocking over or clogging the package 
> repository when checking in highly "compressed" meta-programs that 
> unfurl at compile time? 
>
> Thanks! 
>
> Eric 
>

-- 
You received this message because you are subscribed to the Google 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/a0b03065-9626-4555-b29e-6e1ed63691c4%40googlegroups.com.


Re: [racket-users] Re: Code generation performance

2020-03-15 Thread Eric Griffis
On Sat, Mar 14, 2020 at 10:25 PM Hendrik Boom  wrote:
>
> There's a port of glm in the Racket package library.
> Is that the same one?  If not, is it also that huge?

Same repository, different branch. The master branch, which is a
couple months old now, implements the matrix and vector types on top
of a single, list-based, length-agnostic structure type. It's a
snapshot of the moment I realized the volume of code and run-time
loops were becoming a problem.

The new code is in the dev branch. It implements just the vector types
in a manner similar to generic interfaces while also exposing a
progression of increasingly type-specific variants. This allows me to
prototype with a generic API, then eliminate the overhead of dynamic
dispatch later by switching to more type-specific operations. (If it's
not obvious, I'm working toward a pluggable type system harness, so
the compiler can specialize and prune automatically.)

> By the way, I'm working on updating the opengl package to the current
> OpenGL 4.6 spec.  Because a change of format in Khronos's
> specfiles, it appears to require a complete rewrite to its
> specification translator.

This is good news! Through March, I'll be announcing several graphics
packages that could benefit from this directly. Let's try to keep a
conversation going.

Eric

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


[racket-users] Code generation performance

2020-03-13 Thread Eric Griffis
Hello,

I've got a package that generates (i.e., expands into) a ridiculous
amount of Racket code. I'd like to generate an unbelievable amount of
code, but things have already slowed down a lot.

At this point, I'm generating 20% of a massive code base and it takes
4 minutes to compile (i.e., raco make) it all. If those numbers scale
linearly, I'm looking at 20 minutes to generate and compile the full
code base. Realistically, that's an optimistic lower bound.

How might I go about profiling something that does most of its work at
expansion time?

Should I be concerned about knocking over or clogging the package
repository when checking in highly "compressed" meta-programs that
unfurl at compile time?

Thanks!

Eric

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


Re: [racket-users] Re: Code generation performance

2020-03-18 Thread Eric Griffis
Made a tiny bit of progress today.

On a bigger machine, I was able to profile the giant unit tests module. It
has one top-level for/template that iterates over the 5 scalar types, and a
bunch of smaller ones inside that cover the multitude of operations for
each of the 4 fixed vector lengths.

profiling (lib "glm/vector/tests.rkt")
> Initial code size: 5039
> Final code size  : 1019095
>

The good news is, I'm seeing around 200x compression. I mean, who wouldn't
mind getting completely DRY source for as little as 1/250th the effort?
(Assuming, of course, that programming time is proportional to program size
in bytes.)

The bad news is, compilation takes around 40 seconds on a modern desktop
with plenty of CPU and RAM. From the rest of the profiling output, it looks
like phase-0 for/template is responsible for about 12.5% of the total size,
but phase-1 for/list contributes 57.2% and phase-0 check contributes 48.4%.

I'm not sure how to interpret these numbers yet. On one hand, for/template
is essentially a for/list loop unroller, so the stats could just mean it
did its job. On the other hand, I don't know how much of that 57.2% is
merely the cost of doing business in Racket.

When I comment out everything but the first two tests, I see this:

Initial code size: 243
> Final code size  : 21725
>

That's a mere 89x compression, which is OK because the first two tests are
relatively simple, with phase-0 for/template accounting for 58.5% of the
total size, phase-1 for/list contributing 23.2%, and no phase-0 check.

It's starting to look like there isn't much I can do to bring down the
total size. But what about total compile time?

When I manually unroll the for/template forms, the profiler gives:

Initial code size: 1509
> Final code size  : 21725
>

The identical final size is interesting -- it suggests the original output
sizes are what they would be if templates weren't used.

This version takes, on average, 1.883 seconds to compile. The for/template
version takes 2.499 seconds, and an empty test suite takes 1.743 seconds.
Subtracting out the control time, it took 0.612 seconds more, or 5.4x
longer, to compile a fairly simple module with for/template than without.

Is the extra cost acceptable? I'm guessing that's highly context dependent.
In this case, adding half a second to compile one module wouldn't
inconvenience me terribly, but it doesn't take much imagination to find a
situation where it would, and I have no idea how any of these numbers will
scale.

Eric


On Sat, Mar 14, 2020 at 3:28 PM Eric Griffis  wrote:

> Alright, I re-discovered Ryan Culpepper's talk, "The Cost of Sugar," from
> the RacketCon 2018 video stream (https://youtu.be/CLjXhr_TgP8?t=5908) and
> made some progress by following along.
>
> Here are the .zo files larger than 100K:
>
> 993K ./vector/compiled/tests_rkt.zo
> 830K ./scribblings/compiled/glm_scrbl.zo
> 328K ./vector/compiled/relational_rkt.zo
> 295K ./vec4/compiled/bool_rkt.zo
> 291K ./vec4/compiled/int_rkt.zo
> 290K ./vec4/compiled/uint_rkt.zo
> 290K ./vec4/compiled/double_rkt.zo
> 289K ./vec4/compiled/float_rkt.zo
> 280K ./vec3/compiled/bool_rkt.zo
> 276K ./vec3/compiled/int_rkt.zo
> 275K ./vec3/compiled/uint_rkt.zo
> 275K ./vec3/compiled/double_rkt.zo
> 274K ./vec3/compiled/float_rkt.zo
> 262K ./vec2/compiled/bool_rkt.zo
> 258K ./vec2/compiled/uint_rkt.zo
> 258K ./vec2/compiled/int_rkt.zo
> 258K ./vec2/compiled/double_rkt.zo
> 257K ./vec2/compiled/float_rkt.zo
> 213K ./vec1/compiled/bool_rkt.zo
> 210K ./vec1/compiled/uint_rkt.zo
> 210K ./vec1/compiled/int_rkt.zo
> 210K ./vec1/compiled/double_rkt.zo
> 209K ./vec1/compiled/float_rkt.zo
> 102K ./compiled/main_rkt.zo
> 101K ./compiled/vector_rkt.zo
>
> I'm pretty sure that's a lot of big files. It's for a port of GLM, a
> graphics math library that implements (among other things) fixed-length
> vectors of up to 4 components over 5 distinct scalar types, for a total of
> 20 distinct type-length combinations with many small variations in their
> APIs and implementations.
>
> The variations I'm targeting either require a macro or exacerbate
> developer- or run-time overhead when functions are introduced. For example,
> the base component accessors for a four-component vector of doubles are:
>
>   dvec4-x
>   dvec4-y
>   dvec4-z
>   dvec4-w
>
> Each of the "xyzw" components has two aliases -- one from "rgba" and
> another from "stpq". Each accessor also has a corresponding mutator, e.g.,
> dvec4-g and set-dvec4-g!.
>
> For another example, whereas adding two dvec4's sums four components,
>
>   (dvec4
>(fl+ (dvec4-x v1) (dvec4-x v2))
>(fl+ (dvec4-x v1) (dvec4-x v2))
>(fl+ (dvec4-x v1) (dvec4-x v2))
>(fl+ (dvec4-x v1) (dvec4-x v2)))
>
> the same operation on dvec2

[racket-users] [ANN] Template Macros: A Toolkit for the Practicing Language-Oriented Programmer

2020-03-17 Thread Eric Griffis
Hello,

I'm pleased to announce the initial release of *Template Macros*, a Racket
library that dramatically simplifies the generation of meta-program code.

https://github.com/dedbox/racket-template

Template macros infiltrate the spaces under-served by Racket's existing
pattern-based and procedural macros, such as the insides of literal data,

  > (with-template ([X 1] [Y 2]) (values XY3 "YX0" #rx"^X+Y$"))
>   123
>   "210"
>   #rx"^1+2$"
>

or in the various quoted forms;

  > (begin-template #'(untemplate (build-list 10 values)))
>   #
>

and when one template macro is used by another, the results are spliced in
place automatically.

  > (begin-template (list (for/template ([K (in-range 10)]) K)))
>   '(0 1 2 3 4 5 6 7 8 9)
>

Template macros eliminate common technical barriers to advanced Racket
meta-programming techniques by preempting the default macro expander. The
current API offers a lot more than I could jam into a release announcement,
and it's still evolving!

In the coming weeks and months, I'll try to post some topic-focused
tutorials that highlight the wealth of functionality template macros
provide to the practicing language-oriented Racket programmer.

But the next time you trip on a missing syntax-local-introduce,

  > (define-template (urlang-js modpath)
>   (let ()
> (local-require (only-in modpath the-javascript))
> (the-javascript)))
>

or find yourself facing a wall of format-id's,

  > (for*/template ([M (in-range 1 6)]
> [N (in-range 1 6)])
>   (define idMxN '((for/template ([I (in-range 1 (add1 M))])
> (vector (for/template ([J (in-range 1 (add1 N))])
>   (if-template (= I J) 1 0))
>   (when-template (= M N)
> (define idM idMxN)))
>   > id5
>   '((vector 1 0 0 0 0)
> (vector 0 1 0 0 0)
> (vector 0 0 1 0 0)
> (vector 0 0 0 1 0)
> (vector 0 0 0 0 1))
>

or struggle to interleave a medley

of functions with "syntax" in their names,

  > (define-template (hyphen-define* Names Args Body)
>   (define
> #,(string->symbol (string-join (map symbol->string 'Names) "-"))
> (λ Args Body)))
>   > (hyphen-define* (foo bar baz) (v) (* 2 v))
>   > (foo-bar-baz 50)
>   100
>

give template macros a try and let me know how it goes!

Eric

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


Re: [racket-users] Contracts on parameters

2020-03-23 Thread Eric Griffis
AFK, but it looks like the contract and function on your define/contract
are swapped. Maybe the contract check on the one-arg call sets the
parameter and then hilarity ensues?

Eric


On Mon, Mar 23, 2020, 12:36 PM David Storrs  wrote:

> (define/contract (foo x)
>   (-> boolean? any)
>   'ok)
>
> (foo #t)
> 'ok
> (foo 7)
> ; foo: contract violation
> ;   expected: boolean?
> ;   given: 7
> ;   in: the 1st argument of
> ;   (-> boolean? any)
> ;   contract from: (function foo)
> ;   blaming: top-level
> ;(assuming the contract is correct)
> ;   at: readline-input:4.18
> ; [,bt for context]
>
> Yup, all good.
>
>
> (define/contract foo (make-parameter #f) boolean?)
> (foo #t)
> (foo)
> #t
> (foo 7)
> #f
>
>
> This isn't what I expected.  What am I missing?
>
> --
> You received this message because you are subscribed to the Google 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/CAE8gKocV-TC1U6g5sq7C%2BZAjSVqDc%2B4yZWobr245qx4fZ9%2Bi3w%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/CAORuSUyw8_sBLzo5B4cx2PursiVzmmM3rBe3USCNn-cPip_ytA%40mail.gmail.com.


Re: [racket-users] Scribbling hexadecimal values

2020-09-18 Thread Eric Griffis
Hi Dominik,

If you put the hex number in a string, many of the formatting functions in
the Scribble manual, section 4.2.1.4 will work:

  (proc-doc/names
   name
   (->* () (integer?) void?)
   (()
((argument #,(racketvalfont "#x1f"
   @{ some description }))

Eric


On Fri, Sep 18, 2020 at 2:23 PM Dominik Pantůček <
dominik.pantu...@trustica.cz> wrote:

> Hello Racketeers,
>
> I am struggling to make scribble typeset default values in
> proc-doc/names in hexadecimal. An example would be:
>
> (proc-doc/names
>   name
>   (->* () (integer?) void?)
>   (()
>((argument #x1f)))
>   @{ some description }) ; yes, at-exp reader
>
> The same applies to values in nested contracts of ->* - like (integer-in
> 0 #x1f).
>
> Of course #,(~a "~x" #x1f) will produce the string with appropriate
> contents - but enclosed in parentheses which does not help much. Also it
> is not just a matter of typesetting because the provide form really
> contracts the procedure being provided and the actual values should
> actually be present.
>
> I would love to see some documentation-stage parameter where I could
> just (parameterize ((numbers-as-hexadecimal #t)) (integer-in ...) ...)
> and it would keep the values as they are for contract purposes and
> render them hexadecimal. Of course, this is quite specific - more
> generic solution is probably more appropriate, this is just to explain
> the problem I am trying to solve.
>
>
> Cheers,
> Dominik
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/aca5b2ab-36b6-98c6-0747-9d5447ae9766%40trustica.cz
> .

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


Re: [racket-users] Rationale for package structure

2021-10-14 Thread Eric Griffis
It's been a while since I created a new package, but as of ~1 year ago,
another advantage (or perhaps the same, from a different angle) of the
multi-collection format was that it allowed third parties to add modules to
the collections I defined.

Eric


On Sat, Oct 9, 2021, 1:58 PM 'Joel Dueck' via Racket Users <
racket-users@googlegroups.com> wrote:

> I’ve always used the single collection format [1] in my packages.
>
> However, I see a lot of package authors will use a multi-collection format
> and split the library, documentation and maybe tests out into separate
> collections.
>
> What are the benefits of splitting the main library and its documentation
> into separate collections?
>
> [1]:
> https://docs.racket-lang.org/pkg/Package_Concepts.html#%28part._concept~3amulti-collection%29
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/6ea9f50e-0d4f-4800-bc17-d31979a614cfn%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/CAORuSUwGH0vAZvx-Y7jQNEqzwhks8X-%2B0y4t_m6Nc_%3DTWW45YA%40mail.gmail.com.