Re: [racket-users] From Clojure to Racket

2018-08-31 Thread Ben Greenman
+1, especially for the at-exp post

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


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

2018-08-31 Thread Matthew Butterick

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

>From the docs:

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

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


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




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


Re: [racket-users] From Clojure to Racket

2018-08-31 Thread Ben Kovitz
On Thursday, August 23, 2018 at 3:48:03 PM UTC-4, Greg Hendershott wrote:

> This is a bit rough and old but: 
>
> https://github.com/greghendershott/racket-clojure-cheat-sheet 
>

You are too modest! I found your blog, and it's definitely got the kind of 
information I'm looking for. For example:

"A good rule of thumb in Racket is to use a struct instead of list when 
you’re juggling more than two or three items."
https://www.greghendershott.com/2015/07/keyword-structs-revisited.html 

Your blog entry on #lang at-exp told me about at-exp (!) and that it's 
useful for ordinary Racket programming, not just for Scribble.  So *that's* 
how you do string interpolation! And when looking through the 
documentation, I had skipped right over ~a function, which looks like 
another bread-and-butter function.
https://www.greghendershott.com/2015/08/at-expressions.html

Thanks!

Ben

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


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

2018-08-31 Thread Alex Harsanyi


On Friday, August 31, 2018 at 11:11:29 PM UTC+8, Matthew Butterick wrote:
>
>
> On Aug 31, 2018, at 3:25 AM, Alex Harsanyi  > wrote:
>
> Is there a way to write this macro such that the runtime path is defined
> relative to the location of the file that uses `define-sql-statement`?
>
>
> One option, using `syntax-source` to get the starting directory:
>

Hi Matthew, 

Thanks for this solution, it works.  While I understand what is being done, 
I do not understand why it is necessary

Another interesting thing is that, with my original macro, when running the 
code using racket, the file path had to be relative to the file containing 
the definition, but when creating an executable using raco exe, the file 
path had to be relative to the file using the macro.  Your solution works 
in both cases.

Best Regards,
Alex.



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

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


[racket-users] (eighth RacketCon) in St. Louis on September 29th & 30th - Early registration ends next week

2018-08-31 Thread Jay McCarthy
Remember that

(eighth RacketCon) in St. Louis on September 29th & 30th

http://con.racket-lang.org

The early registration will end week.

http://con.racket-lang.org

The schedule of speakers and events is up.

http://con.racket-lang.org

We hope to see you all there! Tell your friends!

http://con.racket-lang.org

Jay

-- 
-=[ Jay McCarthy   http://jeapostrophe.github.io]=-
-=[ Associate ProfessorPLT @ CS @ UMass Lowell ]=-

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


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

2018-08-31 Thread Matthias Felleisen


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

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

(define-sql-statement a #;"b")

(provide define-sql-statement)

(But this creates a system-specific path.) 


> On Aug 31, 2018, at 6:25 AM, Alex Harsanyi  wrote:
> 
> 
> I have defined a macro to help with using SQL queries from external files: it
> uses `define-runtime-path` to store the path to the file and defines a
> function that reads the data when called the first time and constructs a
> `virtual-statement`:
> 
> #lang racket
> (require racket/runtime-path db (for-syntax racket/base))
> 
> (define-syntax (define-sql-statement stx)
>   (syntax-case stx ()
> [(_ name path)
>  #'(begin
>  (define-runtime-path rpath path)
>  (define name
>(let ([vq #f])
>  (lambda ()
>(unless vq
>  (let ([s (call-with-input-file rpath port->string)])
>(set! vq (virtual-statement (lambda (_) s)
>vq]))
> 
> (provide define-sql-statement)
> 
> Unfortunately, the generated runtime path is relative to the location of the
> file defining the macro, not the file that uses it.  That is, in the example
> below, "query.sql" needs to be in "subdir" together with
> "define-sql-statement.rkt":
> 
> #lang racket
> (require "subdir/define-sql-statement.rkt")
> (define-sql-statement x "query.sql")
> 
> Is there a way to write this macro such that the runtime path is defined
> relative to the location of the file that uses `define-sql-statement`?
> 
> If you want to test this, you can put any text in query.sql (e.g "select *
> from test")
> 
> Thanks,
> Alex.
> 
> 
> 
> -- 
> You received this message because you are subscribed to the Google 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] using `define-runtime-path` inside macros

2018-08-31 Thread Matthew Butterick

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


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


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

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

(provide define-sql-statement)

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


Re: [racket-users] Using match on hash tables with optional keys

2018-08-31 Thread David Storrs
Summary of the thread:

"Hey, here's this thing I'd like to do.  Is there a way to do it?"

T = :  "Nope.  Here's some suggestions, though."

T = 22 hours:  "Here, let me add that feature to the language."

Man, I love this community.  Thank you to everyone.


On Fri, Aug 31, 2018 at 5:46 AM, Ryan Culpepper  wrote:

> On 8/31/18 4:28 AM, Greg Hendershott wrote:
>
>> A general trick for optional values with match is something like (or
>> pat (app (λ _ default-value) pat)). But that doesn't work for
>> hash-table which uses [pat path] for each mapping. (At least I
>> couldn't see how.)
>>
>> Here's _a_ way you could write this as a match pattern:
>>
>> (define ((hash-has-keys? keys) ht)
>>   (for/and ([key (in-list keys)])
>> (hash-has-key? ht key)))
>>
>> (match (hash 'a 0 'b 1)
>>   [(? (hash-has-keys? '(a b))
>>   (app (λ (ht)
>>  (values (hash-ref ht 'a)
>>  (hash-ref ht 'b)
>>  (hash-ref ht 'c 'c-default)))
>>a b c))
>>(list a b c)])
>>
>> [I really don't like the hash-has-keys? business, and the resulting
>> double lookups. But (=> id) is available only to bodies, and
>> `failure-cont` didn't work for me. So I don't know how else to handle
>> the case where it should _not_ match.]
>>
>> Obviously the above is tedious. But, it works solely in term of match
>> patterns, and it could be the kind of syntax that a
>> define-match-expander emits for some nicer surface syntax. Where each
>> mapping is either required [k v], or, optional and you must supply a
>> default [k v d]. []
>>
>
> Here's an implementation:
>
>   (define not-found (gensym 'not-found))
>   (define (not-not-found? x) (not (eq? x not-found)))
>
>   (begin-for-syntax
> (define-syntax-class kvpat
>   #:description "hash key-value pattern"
>   ;; Note: be careful to evaluate key expr only once!
>   (pattern [key:expr value-pattern]
>#:with pattern
>#'(app (lambda (h) (hash-ref h key not-found))
>   (? not-not-found? value-pattern)))
>   (pattern [key:expr value-pattern default:expr]
>#:with pattern
>#'(app (lambda (h) (hash-ref h key (lambda () default)))
>   value-pattern
>
>   (define-match-expander hash-table*
> (syntax-parser
>   [(_ kv:kvpat ...)
>#'(? hash? kv.pattern ...)]))
>
>   (match (hash 'a 1 'b 2)
> [(hash-table* ['a a] ['c c 3])
>  (+ a c)])
>   ;; => 4
>
> Ryan
>

-- 
You received this message because you are subscribed to the Google 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] using `define-runtime-path` inside macros

2018-08-31 Thread Alex Harsanyi

I have defined a macro to help with using SQL queries from external files: 
it
uses `define-runtime-path` to store the path to the file and defines a
function that reads the data when called the first time and constructs a
`virtual-statement`:

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

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

(provide define-sql-statement)

Unfortunately, the generated runtime path is relative to the location of the
file defining the macro, not the file that uses it.  That is, in the example
below, "query.sql" needs to be in "subdir" together with
"define-sql-statement.rkt":

#lang racket
(require "subdir/define-sql-statement.rkt")
(define-sql-statement x "query.sql")

Is there a way to write this macro such that the runtime path is defined
relative to the location of the file that uses `define-sql-statement`?

If you want to test this, you can put any text in query.sql (e.g "select *
from test")

Thanks,
Alex.


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


Re: [racket-users] Using match on hash tables with optional keys

2018-08-31 Thread Ryan Culpepper

On 8/31/18 4:28 AM, Greg Hendershott wrote:

A general trick for optional values with match is something like (or
pat (app (λ _ default-value) pat)). But that doesn't work for
hash-table which uses [pat path] for each mapping. (At least I
couldn't see how.)

Here's _a_ way you could write this as a match pattern:

(define ((hash-has-keys? keys) ht)
  (for/and ([key (in-list keys)])
(hash-has-key? ht key)))

(match (hash 'a 0 'b 1)
  [(? (hash-has-keys? '(a b))
  (app (λ (ht)
 (values (hash-ref ht 'a)
 (hash-ref ht 'b)
 (hash-ref ht 'c 'c-default)))
   a b c))
   (list a b c)])

[I really don't like the hash-has-keys? business, and the resulting
double lookups. But (=> id) is available only to bodies, and
`failure-cont` didn't work for me. So I don't know how else to handle
the case where it should _not_ match.]

Obviously the above is tedious. But, it works solely in term of match
patterns, and it could be the kind of syntax that a
define-match-expander emits for some nicer surface syntax. Where each
mapping is either required [k v], or, optional and you must supply a
default [k v d]. []


Here's an implementation:

  (define not-found (gensym 'not-found))
  (define (not-not-found? x) (not (eq? x not-found)))

  (begin-for-syntax
(define-syntax-class kvpat
  #:description "hash key-value pattern"
  ;; Note: be careful to evaluate key expr only once!
  (pattern [key:expr value-pattern]
   #:with pattern
   #'(app (lambda (h) (hash-ref h key not-found))
  (? not-not-found? value-pattern)))
  (pattern [key:expr value-pattern default:expr]
   #:with pattern
   #'(app (lambda (h) (hash-ref h key (lambda () default)))
  value-pattern

  (define-match-expander hash-table*
(syntax-parser
  [(_ kv:kvpat ...)
   #'(? hash? kv.pattern ...)]))

  (match (hash 'a 1 'b 2)
[(hash-table* ['a a] ['c c 3])
 (+ a c)])
  ;; => 4

Ryan

--
You received this message because you are subscribed to the Google 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.