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

2021-11-12 Thread Daniel Prager
An alternative answer to the implied question: "How do I learn the core of
the language-oriented features of Racket?"

Check out Beautiful Racket: https://beautifulracket.com

- Dan




On Fri, Nov 12, 2021 at 2:03 PM Philip McGrath 
wrote:

> On Thu, Nov 11, 2021 at 9:20 PM Yushuo Xiao  wrote:
>
>> Thank you very much! I didn't know the set is not fixed. And thinking of
>> them as an IR really helps.
>>
>> On Friday, November 12, 2021 at 12:15:39 AM UTC+8 johnbclements wrote:
>>
>>> That’s a true statement… but that set is by no means fixed.
>>>
>>
> To nitpick a little, while it's true that the set of forms allowed in
> fully expanded programs is not fixed, the last change was in Racket 6.3,
> adding `(quote-syntax datum #:local)` and removing
> `letrec-syntaxes+values`:
> https://docs.racket-lang.org/reference/syntax-model.html#%28part._fully-expanded%29
>
> So, while not fixed, they are in fact quite stable, and the list of
> identifiers is exposed through APIs like the `kernel-literals`
> 
> literal set for `syntax-parse` and, at a lower level,
> `kernel-form-identifier-list`
> 
> and the `syntax/kerncase`
> 
> module. Authors of advanced macros that use `local-expand` and friends need
> a general awareness of their shapes, e.g. to recognize definitions, splice
> `begin`s, or recur into local binding forms, so changes have to be
> unobtrusive to avoid breaking compatibility.
>
> If you're interested in the low-level internals of Racket, you may also
> want to read the manual section on Linklets and the Core Compiler
> .
>
> -Philip
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/0100017d121a0121-031c9bd8-10ec-45b2-84b3-91c93d4e19bc-00%40email.amazonses.com
> 
> .
>

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


Re: [racket-users] Is there a good Racket DSL alternative to Image Magick?

2021-05-11 Thread Daniel Prager
Hi Robert

> Even better if I could point the function at a directory, it finds all of
the images in it, and creates the data structure for me. Any ideas?

You can get the files in a directory using *directory-list *and filter for
the image files using a regex.

(for ([f (directory-list "/some/path")] #:when (regexp-match? "\\.png$" f))
 (displayln f))

Dan

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


Re: [racket-users] fluent: unix style pipes and lambda shorthand to make your code more readable

2021-03-09 Thread Daniel Prager
Impressive!

How does fluent manage this infixing from a (require ...) rather than a
#lang?

I've been using the Clojure-like threading package for a while now and this
has some nice advantages that are mentioned in the docs, like blending the
first arg > and last arg >> variants easily in a sequence.

How does fluent manage this infixing from a (require ...) rather than a
#lang?

It might be nice to use ~> and ~>> (or |> and |>> or choose your own) as
infix to avoid clashing with >.


Dan

-- 
You received this message because you are subscribed to the Google 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/CAFKxZVVBV1sP%2BKk%2B%2Bdw7k7a_TcEsL-yz6%2BLKDLZOa2Wfc1RAYw%40mail.gmail.com.


Re: [racket-users] garbage collection

2020-10-25 Thread Daniel Prager
>  is it possible to run modern Lisp-y languages without a garbage
collector? Is it even smart to try?

This seems to cover it ...

https://stackoverflow.com/questions/16240183/not-using-garbage-collector-in-scheme-lisp-implementation

Dan

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


[racket-users] TCR (test && commit || revert) in DrRacket?

2020-05-14 Thread Daniel Prager
Has anyone figured out how to do TCR  (test && commit || revert) in Racket?

Here's Kent Beck demoing TCR in VSCode, using Python:

www.youtube.com/watch?v=Aof0F9DvTFg=PLlmVY7qtgT_nhLyIbeAaUlFOWbWT5y53t=1

His set-up is described in Video 0 (#2 in the playlist).

Dan

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


Re: [racket-users] HTDP2e Exercise 309

2020-03-05 Thread Daniel Prager
Hint:

(define (words-on-line llos)
  (match llos
  ['() empty]
  [(list a b ...) ))

Dan

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


[racket-users] Day 7 Advent of Code - continuations?

2019-12-06 Thread Daniel Prager
Does anyone have a continuation-based solution to AoC day 7?

https://adventofcode.com/2019/day/7

I don't normally use continuations, and I solved today's puzzles without
them, but part 2 looks to me like it might have yielded ;-) a more elegant
solution.

Dan

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


Re: [racket-users] DrRacket 7.5 colors a bit dark and low contrast on Mac

2019-12-06 Thread Daniel Prager
Thank-you both!

Cheers

Dan





On Sat, Dec 7, 2019 at 8:25 AM Robby Findler 
wrote:

> Okay, Sorawee and I had a side-bar conversation and I've pushed a fix.
> Thanks for alerting me to the problem!
>
> (The DrRacket-level preferences don't default to the right color scheme
> when the OS is in dark mode currently either, but maybe I'll have to fix
> that one another day.)
>
> Robby
>
> On Fri, Dec 6, 2019 at 2:30 PM Robby Findler 
> wrote:
>
>> Can you folks send me your preference file (off list)? Feel free to
>> redact it however you want.
>>
>> Robby
>>
>> On Fri, Dec 6, 2019 at 1:29 PM Sorawee Porncharoenwase <
>> sorawee.pw...@gmail.com> wrote:
>>
>>> Confirm that I have this problem as well, even when I reset all
>>> preference files.
>>>
>>> On Fri, Dec 6, 2019 at 11:17 AM Daniel Prager 
>>> wrote:
>>>
>>>> Hi Robby
>>>>
>>>> > What happens if you open the preferences dialog and turn
>>>> white-on-Black on and back off again?
>>>>
>>>> No change.
>>>>
>>>> I still have 7.2 on my system, which works fine.
>>>>
>>>> Here's what it looks like in black-on-white for reference.
>>>>
>>>> [image: image.png]
>>>>
>>>>>
>>>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> 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/CAFKxZVWwkztEadAFEruizXZ%3DJ3pHyK7Kd%2BpU0UBzqo95Sdr%2B4A%40mail.gmail.com
>>>> <https://groups.google.com/d/msgid/racket-users/CAFKxZVWwkztEadAFEruizXZ%3DJ3pHyK7Kd%2BpU0UBzqo95Sdr%2B4A%40mail.gmail.com?utm_medium=email_source=footer>
>>>> .
>>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Racket Users" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to racket-users+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/racket-users/CADcuegsoMSqnzCZG9uRy2Sv%2BOzsfcP0%3DyAVxnyzQ0ndqJ5DP4w%40mail.gmail.com
>>> <https://groups.google.com/d/msgid/racket-users/CADcuegsoMSqnzCZG9uRy2Sv%2BOzsfcP0%3DyAVxnyzQ0ndqJ5DP4w%40mail.gmail.com?utm_medium=email_source=footer>
>>> .
>>>
>>

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


Re: [racket-users] DrRacket 7.5 colors a bit dark and low contrast on Mac

2019-12-06 Thread Daniel Prager
Hi Robby

> What happens if you open the preferences dialog and turn white-on-Black
on and back off again?

No change.

I still have 7.2 on my system, which works fine.

Here's what it looks like in black-on-white for reference.

[image: image.png]

>
>>

-- 
You received this message because you are subscribed to the Google 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/CAFKxZVWwkztEadAFEruizXZ%3DJ3pHyK7Kd%2BpU0UBzqo95Sdr%2B4A%40mail.gmail.com.


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

2019-12-05 Thread Daniel Prager
While playing around with this I came across an error message in match that
could perhaps stand some improvement ...

> (define (super-cool?/flawed ds)
(match ds
  [(list _ ... a a ... _) #t]
  [_ #f]))
a59: unbound identifier;
 also, no #%top syntax transformer is bound in: a59

Dan

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


Re: [racket-users] Simple macro issues

2019-09-09 Thread Daniel Prager
Hi Simon

I only use macros sparingly, and sympathise with your struggles to develop
macro-fu.

Some simple macros can be written quite simply using define-syntax-rule/s
and aren't that much more complex than writing functions.

To milk a bit more from this example, here's a similarly themed function:

#lang racket

(define (hex/f hs)
  (apply bytes
 (for/list ([h hs])
   (string->number (~a h) 16

(hex/f '(a b c 1 2 3 41 42 43)) ; #"\n\v\f\1\2\3ABC"


The (marginal) advantage of the macro, of course, is that we can omit the
quote from the function call.

Dan

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


Re: [racket-users] Simple macro issues

2019-09-09 Thread Daniel Prager
Hi Simon

I think you'll find that the if statement is misguided, since it treats
numbers as decimal rather than hex valued.

Happily, this simplifies the solution.

#lang racket

(define-syntax-rule (hex h ...)
  (bytes (string->number (~a (quote h)) 16) ...))

(hex a b c 1 2 3 41 42 43) ; #"\n\v\f\1\2\3ABC"

Dan

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


[racket-users] Would it help to call racket2 something else?

2019-08-28 Thread Daniel Prager
Changing the canonical syntax seems like a bigger jump than from PLT Scheme
to Racket.

Perhaps a name change would help.

I looked up English language anagrams of racket and found two: retack and
tacker.

*retack** [Nautical] To tack or alter course by sailing into the wind for a
second or further time.*

I reckon *#lang retack* would at least make an apt working title. ;-)

Dan

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


Re: [racket-users] [standard-fish] A geometric design

2019-08-25 Thread Daniel Prager
Wow!

Loved the background video you linked to explaining the roots in Islamic
art and design: https://www.youtube.com/watch?v=pg1NpMmPv48

So different to the patchwork inspired approach that I've taken to
tessellation.

Brilliant stuff.

Dan

-- 
You received this message because you are subscribed to the Google 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/CAFKxZVVdFD52V5FBXfwHSheU_xmM2a-N3zRWt%3DxU0doOwf%2Bg7Q%40mail.gmail.com.


Re: [racket-users] [standard-fish] Reverse engineered quilt design

2019-08-01 Thread Daniel Prager
Hi Stephen

On Thu, Aug 1, 2019 at 8:31 PM Stephen De Gabrielle 
wrote:

> How your use of racket has evolved over the past 5 years
> * how you handled the changes to racket in that time
> * what was good (and bad) about using Racket
>
> in general what has changed since that presentation?
>

Not a lot to report.

Incremental improvements — go play with the site — didn't make youpatch.com
hugely successful, and we didn't pivot in a big way, but the site's still
there and gets used. Occasionally there's a flurry of quilt designs created
as new quilters find the site and tell their friends.

I experimented with making more traditional quilts using random-ness and
symmetry, but haven't released that software commercially.

I found Racket terrific for the reasons mentioned in the talk, but because
I didn't take anything else commercial — I've mainly been doing non-tech
work of late — so I haven't really upped my Racket game, although I
continue to tinker and learn as time permits.

The changes to Racket occasionally broke something on the site, but those
changes were easily fixed.

Dan

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


Re: [racket-users] [standard-fish] Reverse engineered quilt design

2019-08-01 Thread Daniel Prager
On Thu, Aug 1, 2019 at 9:53 PM John Clements 
wrote:

> That’s a really nice example of the uses of abstraction in non-programming
> domains. Thanks!
>

Thanks, John!

I think there's real potential for a *#lang quilt *as a(nother) creative
way to teach aspects of programming while exploring a subset of
computational art.

Mirela and I made some progress in this direction, from which this example
emerged, but there's a fair bit more to be done.

Dan

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


Re: [racket-users] [standard-fish] Reverse engineered quilt design

2019-08-01 Thread Daniel Prager
Hi Stephen

What specifically would you like to hear more about?


Cheers

Dan

On Thu., 1 Aug. 2019, 00:39 Stephen De Gabrielle, 
wrote:

> Hi Daniel
>
> On Wed, 31 Jul 2019 at 14:16, Daniel Prager 
> wrote:
>
>> On Wed, Jul 31, 2019 at 6:28 PM Stephen De Gabrielle <
>> spdegabrie...@gmail.com> wrote:
>>
>>> Wow.
>>>
>>
>> Thanks Stephen, and good on you for this fun competition!
>>
> :)
>
>
>> It's been almost 5 years since RacketCon 2014, where I talked about
>> youpatch.com, still up and running, BTW.
>>
> TBH. I’d like to hear more about it.
>
>>
>> https://www.youtube.com/watch?v=8psnTEjYIEA
>>
>> I've done some other experiments subsequently, and may one day develop a 
>> *#lang
>> quilt*, but have been diverted by other stuff lately.
>>
>
> That sounds like an idea for another competition. I wonder how people feel
> about hats?
>
>
>
>> Dan
>>
>>> --
> 
>

-- 
You received this message because you are subscribed to the Google 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/CAFKxZVXb1rH2g8brH%2BK6fh7QW6ZTT%3D_-gB__1-1NHqpqNPz_RQ%40mail.gmail.com.


Re: [racket-users] [standard-fish] Reverse engineered quilt design

2019-07-31 Thread Daniel Prager
On Wed, Jul 31, 2019 at 6:28 PM Stephen De Gabrielle <
spdegabrie...@gmail.com> wrote:

> Wow.
>

Thanks Stephen, and good on you for this fun competition!

It's been almost 5 years since RacketCon 2014, where I talked about
youpatch.com, still up and running, BTW.

https://www.youtube.com/watch?v=8psnTEjYIEA

I've done some other experiments subsequently, and may one day develop a *#lang
quilt*, but have been diverted by other stuff lately.

Dan

>

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


[racket-users] [standard-fish] Reverse engineered quilt design

2019-07-30 Thread Daniel Prager
Here's a photo of the original quilt from Red Pepper Quilts (not my work):



More images, including details, here:
http://bastings54.rssing.com/browser.php?indx=6115008=60

And here's my reverse-engineered Racket version:

[image: super-duper-HST-and-QST-quilt.png]

Top-level code, below.


#lang racket

(require threading
 "quilt.rkt")

;; EXAMPLES
;;

;; Build a super-duper quilt from rectangles, hsts, squares, and a
;; few qsts

(define qst_ (qst 1 'black 'white))
(define qst__ (qst 1 'black 'black 'black 'white))
(define hst_ (hst 1 'black 'white 'forward))

(define (around-the-world . ss)
  ; error on (< (length ss) 3)
  (define ts (map (λ (s)
(if (symbol? s)
(square 1 s)
s))
  ss))

(let around ([n(- (* 2 (length ss)) 3)])
  (define half (/ (- n 1) 2))
  (if (= n 3)
  (apply surround (take ts 3))
  (let* ([ps (take (drop ts half) (min (+ half 1)
   (- (length ts) half)))]
 [center (first ps)]
 [corner (last ps)]
 [ts (rest (reverse (rest ps)))]
 [side (apply beside
  (append (make-list (- half (length ts) 1)
 corner)
  ts))])
(surround (around (- n 2))
  (reflect side center)
  corner)

(define (diamond center [surround 'white])
  (4-square (hst 1 surround center 'forward) R))

(define hst-strip
  (~> (reflect (beside/n 4 hst_) qst__)
  (B (H hst_))
  reflect))

(define b1 (around-the-world 'black
 qst_
 'cerise
 'lupine
 'caribbean
 hst_))

(define b2 (around-the-world 'black
 qst_
 'amber
 'cactus
 'maize
 hst_))

(define diamond-strip
  (beside/n 11 (diamond 'black) (diamond 'caribbean)))

(define geese
  (beside/n 9 (A (V hst_) hst_)))

(define quilt
  (~> (grid [b1 (R geese) b2]
[geese (diamond 'maize 'cactus) (H geese)]
[b2 (L geese) b1])
  (surround hst-strip hst_)
  (surround diamond-strip (diamond 'caribbean))
  (add-strips 'cactus)
  (add-strips 'caribbean)
  (add-strips 'black)))


(parameterize ([units 20]
   [show-outline #t])
  (draw quilt))

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


Re: [racket-users] The case, and a proposal, for elegant syntax in #lang racket2

2019-07-17 Thread Daniel Prager
I'm confused on one point.

Why would a new canonical notation be preferable to, say, also fully
supporting an alternative general notation (like Shriram's p4p, or a
derivative thereof) or even multiple notations in addition to retaining
good old s-expressions?

The idea would be that you could transform freely and readably between
alternative notations, enabling round-tripping without degradation.

I imagine that effectively providing tooling, syntax-extension, good error
messages, and documentation across multiple notations would be (ahem)
challenging, but so long as we're dreaming big ...


Dan

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


Re: [racket-users] Thinking in scheme / racket

2019-07-09 Thread Daniel Prager
Hi Bob

My pleasure.

(in-value ...) is a very neat facility that I suspect could do with a
couple of examples in the Racket Guide and Reference to highlight its
utility and application.

Dan

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


Re: [racket-users] Thinking in scheme / racket

2019-07-09 Thread Daniel Prager
Hi Bob

Here's how I'd write your function using for*/sum:

(define (count-primes-in-seq/2 f bound)
  (for*/sum ([n (in-range bound)]
 [k (in-value (f n))]
 #:when (and (positive? k) (prime? k)))
1))

Performance is similar to your original.

Dan

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


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

2019-06-28 Thread Daniel Prager
Hi Eric


On Fri., 28 Jun. 2019, 16:15 Eric Griffis,  wrote:

On Thu, Jun 27, 2019 at 9:12 PM Daniel Prager 
wrote:

[snip]

> Quick question: Why Algebraic Racket?

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.


That's interesting, but not what I was driving at! My bad ...

Take 2:

Why implement these projects in Algebraic Racket?

Dan

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


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

2019-06-27 Thread Daniel Prager
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.

Quick question: Why *Algebraic* Racket?

Dan

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


Re: [racket-users] color-maps for the plot package

2019-03-20 Thread Daniel Prager
Side note:

For people looking for aesthetically pleasing discrete color palettes,
check out the top two tools on this page:
http://www.play-crafts.com/blog/tools/

   1. *Palette builder *helps you select a few colors from a pleasing image
   2. *Color play* randomly creates palettes (the source allows you to
   specify n)

The main people behind the site and the tools — Anne Sullivan and Gillian
Smith — straddle art, craft, and computer science in their work.

Dan

-- 
You received this message because you are subscribed to the Google 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: nested for loops and suggested alternatives

2019-02-11 Thread Daniel Prager
Hi Travis

Glad you found it instructive.

In mathematical terms these kinds of systems map from the current state at
t=n to the next time-step at t=n+1.

Given a transition function I tend to just use for/list (or for/vector) to
build up a history.

E.g.

#lang racket

(require math/matrix)

(define A (matrix [[0 0 5.905]
   [0.368 0.639 0.025]
   [0.001 0.152 0.051]]))

(define n (col-matrix [5 5 5]))

(define (iterate A n iter)
  (for/list ([i iter])
(define temp n)
(set! n (matrix* A n))
(list i temp)))

(iterate A n 25)


You could use for/fold, which avoids the use of set!, but the syntax is a
little heavier.

Dan

-- 
You received this message because you are subscribed to the Google 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: nested for loops and suggested alternatives

2019-02-10 Thread Daniel Prager
Thanks for the screenshot Travis.

Just for fun, here's a version in Racket that eschews assignment, vectors
and for loops, in favour of recursion and lists ...

#lang racket

(define years 30)
(define prop-female 0.5)
(define egg-surv 0.6)

(define fecundity '(0 0 200 400 800))
(define survival '(0.2 0.4 0.6 0.8 0))
(define capacity '(1e6 1e5 1e4 1e3 1e2 -))
(define cap0 (first capacity))

(define (beverton-holt N p c) (/ N (+ (/ 1 p) (/ N c

(define (evolve N [f fecundity] [s survival] [cap (rest capacity)] [Nt0 0]
[Nt null])
(if (null? f)
(cons Nt0 (reverse Nt))
(evolve (rest N) (rest f) (rest s) (rest cap)
(+ Nt0 (if (= (first f) 0)
   0
   (beverton-holt (* (first N) prop-female)
  (* (first f) egg-surv)
  (- cap0 Nt0
(if (= (first s) 0)
Nt
(cons (beverton-holt (first N) (first s) (first cap))
Nt)

(define (iterate N n [i 1])
  (displayln (list i N))
  (unless (= i n) (iterate (evolve N) n (+ i 1

(iterate (make-list (length fecundity) 10) years)

-- 
You received this message because you are subscribed to the Google 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: nested for loops and suggested alternatives

2019-02-10 Thread Daniel Prager
Hi Travis

Would you mind sharing your results from R (and now Racket)?

I'm having a play with the Racket code, and would like to check I'm not
breaking anything as I refactor it.

Dan

-- 
You received this message because you are subscribed to the Google 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] IFL: #lang alda (music composition)

2018-10-18 Thread Daniel Prager
IFL =  Request For #lang

Here's a great talk from Dave Yarwood about his Clojure-based functional
music composition language: Alda.

https://www.youtube.com/watch?v=7nbBSwopG-E

   - Manifesto and introduction:
   https://blog.djy.io/alda-a-manifesto-and-gentle-introduction/
   - Example programs / scores:
   
https://github.com/alda-lang/alda-core/blob/master/examples/clapping_music.alda

I reckon a port or something similar in Racket (on top of rsound?) would be
a very cool project.

Dan

-- 
You received this message because you are subscribed to the Google 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] Should #; comments be colored as comments or code in Dr Racket?

2018-10-07 Thread Daniel Prager
If only there was a way to have the best of both worlds.

E.g. change the background color for #; to something reminiscent of the
foreground color of regular comments:

(display #|Comment|#
 ; comment
 #;(string-join "comm" "ent")
 "Hello world")

Or perhaps something like the emacs rainbow-parens that Christopher
mentioned could help.

Dan


On Mon, Oct 8, 2018 at 4:43 AM Matthias Felleisen 
wrote:

>
> I have some sympathy for this view but I think that it is a
> misunderstanding.
>
> I think #; is rather distinct from #| ... |# and ;;  It signals “the
> following is a
> code snippet that is currently not useful or not quite right but you
> should
> read it as code and with the structure of code in mind”.  Here is a use
> that
> illustrates this. When I write untyped code, I strictly follow the design
> recipe
> (because I discovered that “do as I tell you not as I do” applies here
> too).
> For signatures, I write
>
>  #; [ String String -> (U Number String) ]
>  (define (f s t)
>(if (= (string-length t) 3) 0 s))
>
> and such things. I want this signature to be readable as code when someone
> wishes to inject types into my code.
>
> Similar uses for code snippets abound in my repos too. — Matthias
>

-- 
You received this message because you are subscribed to the Google 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] Should #; comments be colored as comments or code in Dr Racket?

2018-10-07 Thread Daniel Prager
I find the #; construct very convenient for commenting out sexps, but in Dr
Racket the visual cue of switching to comment-color is missing.

Example (in Racket 6.12):

[image: Screen Shot 2018-10-07 at 10.19.09 pm.png]

Expected:

*#lang racket*

(display #|Comment|#
 ; comment
 #;(string-join "comm" "ent")
 "Hello world")


Dan

-- 
You received this message because you are subscribed to the Google 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] 2018 SIGPLAN Software Award

2018-09-27 Thread Daniel Prager
Congratulations!

And thank you ...

Dan

-- 
You received this message because you are subscribed to the Google 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-09-01 Thread Daniel Prager
Not quite string interpolation, but Racket also has (~a ...) with variable
number of arguments, which I find convenient:

E.g.

(define x 5)
(define y 6)

(~a "x is " x
" and y is " y
" and x + y = " (+ x y))

; "x is 5 and y is 6 and x + y = 11"


Dan

-- 
You received this message because you are subscribed to the Google 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] Converting bulleted list to s-expression?

2018-08-20 Thread Daniel Prager
On Sun, Aug 19, 2018 at 11:03 AM, Andrew J  wrote:

> Very nice. The Racket special sauce is the (match*...). I need to get my
> head around what's going on there.
>
>
 If you already understand match, perhaps this will help:

> (match (list 5 6)
[(list a b) (+ a b)])
11

More concise, match* equivalent:

> (match* (5 6)
[(a b) (+ a b)])
11


Dan

-- 
You received this message because you are subscribed to the Google 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] Searching for packages

2018-08-14 Thread Daniel Prager
The "threading" package is an example of something I'd like to see promoted
to the main Racket distribution.

Reason: it adds clarity for an attractive style, and makes it available
out-of-the-box*, on a par with e.g. Clojure,  F#, and Elm.

Just my opinion.

But it does raise a question for the core group, "How do packages get
promoted?"

Dan

* Or almost out-of-the-box, if an additional (require racket/threading) is
still needed.

On Sun., 12 Aug. 2018, 19:29 Stefan Schmiedl,  wrote:

> "Andrew J" , 12.08.2018, 02:09:
>
> > I typically use either threading or composition...
>
> > (require threading)
> > (define (foo x)
> >   (~> x
> > f g h bar))
>
> "threading" is not included in the default racket installer, so
> how do I get it?
>
> The package manager tells me that there is a "threading" package,
> but I'm not sure if it is the correct one.
>
> Browsing over to https://pkgs.racket-lang.org and searching for
> "threading" offers me a few more options, the three "threading"
> packages amongst them. But now there is a link to "Documentation"
> (yay, well-written documentation) and I see that the "threading"
> package indeed provides the threding macro quoted above.
>
>
> Wouldn't it be nice to have a link to https://pkgs.racket-lang.org
> in the "Related Web Sites" submenu of DrRacket's "Help" menu?
>
> Reasons:
> 1. I started looking there instead of under File, Package Manager,
>and expected to find the "official" package site listed there.
> 2. The web site allows me to browse the documentation before
>installing anything, which I can't do from the PM window
>
> Regards,
> s.
>
> --
> You received this message because you are subscribed to the Google 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] Edmond's Blossom Algorithm

2018-05-15 Thread Daniel Prager
A more low-tech approach ...

#lang racket

(require threading)

(define students '(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z))

(define indexes (for/hash ([s students] [i (in-naturals)])
  (values s i)))

; A -> 0, B -> 1, ...
(define (index student)
  (hash-ref indexes student))

; Generate synthetic preferences for 'student'
;
(define (random-preferences student)
  (~> students
  (remove student _)
  shuffle
  (take 3)))

; Generate synthetic preferences for all the students
;
(define preferences
  (for/hash ([s students])
(define prefs (random-preferences s))
(displayln (list s prefs))
(values s prefs)))

; Score 1 if a likes b; 0 otherwise
;
(define (likes a b)
  (if (~> preferences (hash-ref a) (member b _)) 1 0))

; Score 2 is a and b like each other
; Score 1 if only one likes the other
; Score 0 otherwise
;
(define (pair-score a b)
  (+ (likes a b) (likes b a)))

; Find all the pairings where the pair-score is n
;
(define (scores-exactly n)
  (shuffle
   (for*/list ([a students]
   [b students]
   #:when (and (< (index a) (index b))
   (= (pair-score a b) n)))
 (list a b

; What is the total score and pair-wise score for these pairs?
;
(define (score-assignment pairs)
  (define scored-pairs
(for/list ([p pairs])
  (list p (apply pair-score p
  (list (for/sum ([p scored-pairs])
  (last p))
scored-pairs))

; First try tp pair up students who want to work together
; Next students where at least one wants to work with the other
; Finally there may be some unlucky ones
;
(define (assign-pairs [options (apply append (map scores-exactly '(2 1 0)))]
  [remaining students]
  [acc null])
  (if (null? remaining)
  (score-assignment (reverse acc))
  (match-let ([(list a b) (first options)])
(if (and (member a remaining)
 (member b remaining))
(assign-pairs (rest options)
  (~>> remaining (remove a) (remove b))
  (cons (first options) acc))
(assign-pairs (rest options)
  remaining
  acc)

(newline)
(argmax first (for/list ([i 10]) (assign-pairs)))



*Sample output*

(A (D T B))
(B (I A L))
(C (B J P))
(D (K O P))
(E (K Z B))
(F (C O Y))
(G (E C I))
(H (I W M))
(I (V G W))
(J (H Z T))
(K (O M Q))
(L (K V T))
(M (Y R E))
(N (M D J))
(O (N K P))
(P (W R C))
(Q (T O E))
(R (C F Y))
(S (N E U))
(T (B S H))
(U (V N K))
(V (L U Q))
(W (B O X))
(X (A Q Z))
(Y (T B R))
(Z (V T N))

'(18
  (((G I) 2)
   ((U V) 2)
   ((A B) 2)
   ((C P) 2)
   ((K O) 2)
   ((R Y) 2)
   ((E S) 1)
   ((J Z) 1)
   ((D N) 1)
   ((L T) 1)
   ((H W) 1)
   ((Q X) 1)
   ((F M) 0)))

-- 
You received this message because you are subscribed to the Google 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] what do people use for number formatting?

2018-05-07 Thread Daniel Prager
~r works nicely:

> (~r 1.237472387 #:precision 2)
"1.24"

-- 
You received this message because you are subscribed to the Google 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] Mozart's Musical dice with rsound

2018-03-30 Thread Daniel Prager
On Fri, Mar 30, 2018 at 7:18 PM, Thomas F. Burdick 
wrote:

>
>
> If you want to better understand why you need an envelope, it's a pretty
> fun part of synthesis. By clipping the sound, you square off your waveform.
> Square waves are made up of a lot of high-frequency components. To convince
> yourself of that, try to build a square wave by adding together different
> sine waves. It should give you a better intuition about the result.
>

Cool: Gibbs' phenomenon

Courtesy a previous life doing  *lot* of maths and physics I'm pretty good
of underlying theory — for me it's just a matter of understanding the tools.

Dan

-- 
You received this message because you are subscribed to the Google 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] Mozart's Musical dice with rsound

2018-03-29 Thread Daniel Prager
Thanks John

I've made updates (below) based on your suggestions, and the overall effect
is pleasing.


1. The use of asdr fixed the choppiness, although I don't really understand
what I'm doing. [I understand that asdr stands for
Attack-Decay-Sustain-Release

.]

It's unclear to me why I still need to clip, and some documentation would
indeed be welcome.

(define (note->piano n d)
  (define len (tone-length d))
  (clip
   (rs-mult
(piano-tone (string->midi n))
((adsr 2 1.0 2 1.0 (exact-round (* 1/2 len))) len))
   0 len))

2. On my 2012 Mac the streamed version (stream-mozart) is crackly early on,
until the processing finishes.

3. More trivially I added a beats-per-minute parameter.


Finally, I look forward to someone adding some visualisation
!


Dan


#lang racket

(require racket/random
 rsound
 rsound/piano-tones
 rsound/envelope
 net/url)

(define bpm 180) ; presto

(define base-composition-url (string->url "
https://gist.githubusercontent.com/cosmologicon/708fefa9793753ed4f075aaf781f3d67/raw/f08364a6056691215b99f705b4836f3d131ff6eb/mozart-dice-starting.txt
"))

(define (string->midi s)
  (let* ([note (string->symbol (substring s 0 1))]
 [sharp (if (string-contains? s "#") 1 0)]
 [octave (string->number (substring s (+ 1 sharp)))])
(+ (match note ['C 0] ['D 2] ['E 4] ['F 5] ['G 7] ['A 9] ['B 11])
   sharp
   (* 12 (+ octave 1)

(define base-composition
  (for/list ([line (string-split
(port->string
 (get-pure-port base-composition-url))
"\n")])
(define items (string-split line " "))
(cons (first items) (map string->number (rest items)

(define (tone-length d)
  (exact-round (/ (* FRAME-RATE 60 d) bpm)))

(define (note->piano n d)
  (define len (tone-length d))
  (clip
   (rs-mult
(piano-tone (string->midi n))
((adsr 2 1.0 2 1.0 (exact-round (* 1/2 len))) len))
   0 len))

(define (in-measure note measure)
  (match-define (list _ start duration) note)
  (<= (* 3 measure) start (+ start duration) (* 3 (+ measure 1

(define (measure n)
  (for/list ([note base-composition] #:when (in-measure note n)
 #:break (in-measure note (+ 1 n)))
(match-define (list tone start duration) note)
(list tone (- start (* n 3)) duration)))

(define (measure->sound n)
  (rs-overlay*
   (for/list ([note (measure n)])
 (rs-append (silence (+ 1 (tone-length (second note
(note->piano (first note) (last note))

(define preferred-measures
  '((96 32 69 40 148 104 152 119 98 3 54)
(22 6 95 17 74 157 60 84 142 87 130)
(141 128 158 113 163 27 171 114 42 165 10)
(41 63 13 85 45 167 53 50 156 61 103)
(105 146 153 161 80 154 99 140 75 135 28)
(122 46 55 2 97 68 133 86 129 47 37)
(11 134 110 159 36 118 21 169 62 147 106)
(30 81 24 100 107 91 127 94 123 33 5)
(70 117 66 90 25 138 16 120 65 102 35)
(121 39 136 176 143 71 155 88 77 4 20)
(26 126 15 7 64 150 57 48 19 31 108)
(9 56 132 34 125 29 175 166 82 164 92)
(112 174 73 67 76 101 43 51 137 144 12)
(49 18 58 160 136 162 168 115 38 59 124)
(109 116 145 52 1 23 89 72 149 173 44)
(14 83 79 170 93 151 172 111 8 78 131)))

(define measure-length (tone-length 3))

(define (musical-dice)
  (for/list ([m preferred-measures])
(list-ref m (+ (random 6) (random 6)


(define (play-mozart)
  (play
   (rs-append*
(for/list ([i (musical-dice)]
   [d (in-naturals)])
  (display (~a (+ 1 d) ". " i ": "))
  (displayln (measure (- i 1)))
  (measure->sound (- i 1))

(define (stream-mozart)
  (define ps (make-pstream))
  (for ([i (musical-dice)]
[d (in-naturals)])
(display (~a (+ 1 d) ". " i ": "))
(displayln (measure (- i 1)))
(pstream-queue ps
   (measure->sound (- i 1))
   (* (+ d 1) measure-length

(play-mozart)

-- 
You received this message because you are subscribed to the Google 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] Mozart's Musical dice with rsound

2018-03-29 Thread Daniel Prager
For fun, I've written a program to synthesise random compositions based on
Mozart's musical dice procedure, with results played courtesy of rsound.
[Program appended.]

See this Daily Programmer challenge for background:

https://www.reddit.com/r/dailyprogrammer/comments/7i1ib1/20171206_challenge_343_intermediate_mozarts/


*Areas for improvement *

1. There is an unpleasant quality to the ends of the notes, which I
generate by naively clipping piano-tones. Furthermore, if I up the tempo
(e.g. set BEAT-LENGTH to 1/4) it becomes unlistenable. What's a better way
to truncate the notes?

2. I assembled the piece by appending measures and then playing the result.
What's the recommended way to reduce memory and start playing faster using
(say) pstream?

Dan


#lang racket

(require racket/random
 rsound
 rsound/piano-tones
 net/url)

(define BEAT-LENGTH 1/2)

(define base-composition-url (string->url "
https://gist.githubusercontent.com/cosmologicon/708fefa9793753ed4f075aaf781f3d67/raw/f08364a6056691215b99f705b4836f3d131ff6eb/mozart-dice-starting.txt
"))

(define (string->midi s)
  (let* ([note (string->symbol (substring s 0 1))]
 [sharp (if (string-contains? s "#") 1 0)]
 [octave (string->number (substring s (+ 1 sharp)))])
(+ (match note ['C 0] ['D 2] ['E 4] ['F 5] ['G 7] ['A 9] ['B 11])
   sharp
   (* 12 (+ octave 1)

(define base-composition
  (for/list ([line (string-split
(port->string
 (get-pure-port base-composition-url))
"\n")])
(define items (string-split line " "))
(cons (first items) (map string->number (rest items)

(define (note->piano n d)
  (clip (piano-tone (string->midi n)) 0 (exact-round (* FRAME-RATE d 1/2

(define (in-measure note measure)
  (match-define (list _ start duration) note)
  (<= (* 3 measure) start (+ start duration) (* 3 (+ measure 1

(define (measure n)
  (for/list ([note base-composition] #:when (in-measure note n)
 #:break (in-measure note (+ 1 n)))
(match-define (list tone start duration) note)
(list tone (- start (* n 3)) duration)))

(define (measure->sound n)
  (rs-overlay*
   (for/list ([note (measure n)])
 (rs-append (silence (+ 1 (exact-round (* BEAT-LENGTH FRAME-RATE
(second note)
(note->piano (first note) (last note))

(define preferred-measures
  '((96 32 69 40 148 104 152 119 98 3 54)
(22 6 95 17 74 157 60 84 142 87 130)
(141 128 158 113 163 27 171 114 42 165 10)
(41 63 13 85 45 167 53 50 156 61 103)
(105 146 153 161 80 154 99 140 75 135 28)
(122 46 55 2 97 68 133 86 129 47 37)
(11 134 110 159 36 118 21 169 62 147 106)
(30 81 24 100 107 91 127 94 123 33 5)
(70 117 66 90 25 138 16 120 65 102 35)
(121 39 136 176 143 71 155 88 77 4 20)
(26 126 15 7 64 150 57 48 19 31 108)
(9 56 132 34 125 29 175 166 82 164 92)
(112 174 73 67 76 101 43 51 137 144 12)
(49 18 58 160 136 162 168 115 38 59 124)
(109 116 145 52 1 23 89 72 149 173 44)
(14 83 79 170 93 151 172 111 8 78 131)))

(define (musical-dice)
  (for/list ([m preferred-measures])
(list-ref m (+ (random 6) (random 6)

(play
 (rs-append*
  (for/list ([i (musical-dice)])
(display (~a i ": "))
(displayln (measure (- i 1)))
(measure->sound (- i 1)

-- 
You received this message because you are subscribed to the Google 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] minor proposed update to docs typography

2017-11-20 Thread Daniel Prager
Hi Matthew

It looks very nice, but as a side effect slightly exacerbates a
long-standing ergonomic issue with cross-links in the side-notes:

docs.racket-lang.org:

revision:

In almost every case the user will want to click on the unbolded specific
link *(Pattern Matching*), but the bolding entices the user to click on the
generic link (*The Racket Reference*).
​
Suggestion: remove and de-emphasise the distracting hyperlink ...

Pattern Matching
 in *The
Racket *
*Reference* provides more on
pattern matching.


Dan

-- 
You received this message because you are subscribed to the Google 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 Daniel Prager
Great topic!

Providing examples and tutorials around data analysis and visualisation in
Racket (and filling gaps and simplifying) gets my vote.

Another area that might be interesting is generating data-driven web-sites:
e.g. presenting questionnaires and quizzes.

I recently did a bit of consulting  work where I used:

   1. Racket to do some data preparation
   2. Google Forms to run a questionnaire based on the data (SurveyMonkey
   would have been an alternative)
   3. Racket to do some collation and data crunching on the answers
   4. Google Sheets to do some simple visualisation  (mainly for the heat
   mapping feature)
   5. gmail to assemble reports and post the results

It would have been very nice to replace some of the semi-manual non-Racket
steps with all-Racket or Racket-scripted (taking to external APIs).

Dan

-- 
You received this message because you are subscribed to the Google 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: Efficient & "nice" communication mechanism between Racket and other languages

2017-09-08 Thread Daniel Prager
For youpatch.com my colleague and I used a "quasi-microservices
architecture"  to get my Racket, his Python, and our JavaScript to work
together, using JSON and HTTP.

Starting out with a JSON and HTTP would give you a baseline, and then
swapping in other formats and transport mechanisms could allow for
informative benchmarking.

Dan

-- 
You received this message because you are subscribed to the Google 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] Seeking a graphviz like, diagramming language for Racket

2017-08-19 Thread Daniel Prager
Hi Andrew

I did commercial work on mind-map like tools in the 2000's, and have a soft
spot for graph and tree visualisation.

Example: https://www.researchgate.net/figure/221249211_fig1_Fig-1-
Example-hi-tree-laid-out-in-the-standard-layout-style-It-shows-the-logical

I didn't work on the deep layout algorithms, but have some handy peripheral
knowledge.There's a tension between the manual effort of the interactive
tools and more automated layout algorithms. In my ideal world the
auto-layout does most of the heavy lifting, but the layout doesn't jump
around too much in interactive work, and the user can easily play with
styles, aesthetic criteria, and nudge the layout to some extent. It's not
easy to get all at once!

In practice, I tend to settle for GraphViz for my occasional
graph-diagramming needs, but would welcome a Rackety competitor. My sense
is that it may be feasible to do better for specific needs, and challenging
to beat GraphViz as a general purpose tool.

Here's a nice introduction to the evolution of tree-layout algorithms
, explaining how aesthetic
criteria were gradually captured in a series of principles for layout
algorithms to satisfy:

*Principle 1*: *The edges of the tree should not cross each other.*

*Principle 2*:
*All nodes at the same depth should be drawn on the same horizontal line.
This helps make clear the structure of the tree.*

*Principle 3*: *Trees should be drawn as narrowly as possible.*

*Principle 4*: *A parent should be centered over its children.*

*Principle 5*: *A subtree should be drawn the same no matter where in the
tree it lies.*

*Principle 6*: *The child nodes of a parent node should be evenly spaced.*
The author of the first reference, Kim Marriott, is an active academic in
the area of constraint-based graph and tree layout. I collaborated with him
and his student Peter Sbarski on the above-mentioned commercial work. Kim's
a good source.

Dan

-- 
You received this message because you are subscribed to the Google 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: Decision Tree in Racket - Performance

2017-07-28 Thread Daniel Prager
Interesting stuff, but if I may probe a little deeper into scheme history,
why couldn't first have simply been defined as a synonym for car (i.e.
first item in a pair) and rest a synonym for cdr?

Dan

On Fri, Jul 28, 2017 at 6:09 PM, Neil Van Dyke <n...@neilvandyke.org> wrote:

> Daniel Prager wrote on 07/28/2017 01:03 AM:
>
>> > `first` and `rest` need to check if the input is a list.
>>
>> Why is that?
>>
>
> When Racket/Scheme/Lisp people speak of checking whether something is a
> list, I think they usually mean in the sense of the predicate `list?` (or
> `listp`), which is usually an O(n) test for whether a value is a
> properly-formed list of pairs (or cons cells) terminated by a null.
>
> One reason people sometimes do the expensive list check is because it can
> be good practice (to have your procedure check its arguments at entry, so
> it can say the bug is not its fault, as early as possible).  Teaching
> languages are one place I don't think anyone would question whether this is
> good practice.
>
> Another possible reason is that, unless the cost of `list?` has previously
> been pointed out to you, it's easy to just use it without even considering
> whether it might be expensive.  Even once I knew this, I still did this at
> least once, myself.
>
> When writing list-processing code that has to deal with potentially large
> lists, if you're not using a type system that avoids the expensive `list?`
> cost, IMHO, it's usually OK for an initial argument type check to use a
> `pair?`/`null?` in lieu of `list?`, or possibly do no initial check at
> all.  If you want to provide better exceptions on improper lists, you can
> check for list correctness as you proceed with your algorithm, and raise an
> exception yourself (such as including the original argument value, which
> info would not be in the exception if, say, `cdr` raised it).
>
> BTW, if you want to be professional about list-processing code you write
> for use with potentially arbitrary lists, it's good to remember that lists
> can have cycles, and... uh, you can usually just document that "behavior is
> undefined" for lists with cycles. :) Especially since today you're usually
> dealing with immutable pairs, in modern Racket, where cycles are much less
> likely than they were when we used `set-cdr!`.  (Or, if you can't afford to
> hang in an infinite loop on cycles that are reasonably plausible, and you
> don't mind slowing down and complicating things a little, and you don't
> mind having a maximum list size for your procedure, you can keep a counter
> during what could otherwise be an infinite loop in your algorithm, which
> you can then keep checking, to decide whether to raise an exception.  Or
> you can do it a harder way, like one of "https://en.wikipedia.org/wiki
> /Cycle_detection".[1]  Or you could use a less-basic language/platform
> facility, and raise an exception if some limit of compute resource or time
> is reached for that procedure call.)
>
>
> [1] Tangential story about school and industry.  The first time that I hit
> a speed bump in a software development interview was a long time ago, when
> some CS student co-founder of a video game startup asked me how to detect
> whether a linked list had cycles.  So, having some schooling and experience
> by that time, but not recalling this problem from when I took Data
> Structures & Algorithms years earlier, I started working through the
> problem, while trying to ignore distracting social cues that the
> interviewer might not have realized he was making--  Then the interviewer
> tells me he'd recently given the same question to a CS student from his
> school, who'd immediately named "the" algorithm, and who'd then proceeded
> to derive a proof of it on the whiteboard.  Then the interviewer vetoed me
> as a hire, despite the CS systems cred for which his co-founder recruited
> me in the first place, not that I'm still bitter. :)  So, if you didn't
> know/remember that there are off-the-shelf algorithms for cycle detection,
> now you do, and, when you someday interview others, consider not being a
> punk about it. :)
>
>
> --
> You received this message because you are subscribed to the Google 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: Decision Tree in Racket - Performance

2017-07-27 Thread Daniel Prager
s) (null? bs))
> >>  acc]
> >> [else
> >>  (match-define (cons this-a more-as)
> >>as)
> >>  (match-define (cons this-b more-bs)
> >>bs)
> >>  (z more-as more-bs (+ acc (* this-a this-b)))]))
> >>
> >> (let ([as (as)]
> >>   [bs (bs)])
> >>   (collect-garbage)
> >>   (collect-garbage)
> >>   (collect-garbage)
> >>   (time (z as bs)))
> >>
> >> ; timed at the command line
> >> ;cpu time: 242 real time: 241 gc time: 0
> >> ;2452993452
> >> ;cpu time: 21 real time: 21 gc time: 0
> >> ;2450414634
> >> ;cpu time: 22 real time: 22 gc time: 0
> >> ;2450010495
> >>
> >> -Philip
> >>
> >> On Thu, Jul 27, 2017 at 8:22 PM, Matthias Felleisen <
> matth...@ccs.neu.edu>
> >> wrote:
> >>>
> >>>
> >>> On Jul 27, 2017, at 9:18 PM, Matthew Flatt <mfl...@cs.utah.edu> wrote:
> >>>
> >>> I don't think optional arguments are all that slow.
> >>>
> >>>
> >>>
> >>> This isn’t just Matthew’s opinion. Vincent’s feature-specific profiler
> >>> could not detect a significant impact of optional or keyword
> arguments. (See
> >>> Compiler Construction paper, London 2014 I think)
> >>>
> >>> --
> >>> You received this message because you are subscribed to the Google
> 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.
>



-- 
*Daniel Prager*
Agile/Lean Coaching, Innovation, and Leadership
Profile: skillfire.co/dan
Startups: youpatch.com <http://www.youpatch.com>, skillfire.co
Twitter: @agilejitsu <https://twitter.com/agilejitsu>
Blog: agile-jitsu.blogspot.com
Linkedin: au.linkedin.com/in/danielaprager

-- 
You received this message because you are subscribed to the Google 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: Decision Tree in Racket - Performance

2017-07-27 Thread Daniel Prager
The performance hit of first / rest vs car / cdr is a little disquieting
from a readability POV.

Very informative discussion, though!

Dan

-- 
You received this message because you are subscribed to the Google 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: Decision Tree in Racket - Performance

2017-07-27 Thread Daniel Prager
Revised to collect garbage before each timing shows the recursive function
isn't too bad (but not great):

cpu time: 405 real time: 404 gc time: 0
2452578471

cpu time: 368 real time: 368 gc time: 0
2452578471

cpu time: 50 real time: 50 gc time: 0
2452578471

cpu time: 194 real time: 195 gc time: 75
2452578471


Dan

-- 
You received this message because you are subscribed to the Google 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: Decision Tree in Racket - Performance

2017-07-27 Thread Daniel Prager
To dramatise Gustavo's point, here's a quick comparison of some different
methods:

#lang racket

(collect-garbage)
(collect-garbage)
(collect-garbage)

(define as (build-list 100 (λ (n) (random 100
(define bs (build-list 100 (λ (n) (random 100

(define (f as bs [acc 0])
  (if (or (null? as) (null? bs))
  acc
  (f (rest as) (rest bs) (+ acc (* (first as) (first bs))

(time (f as bs))

(time
 (for/sum ([a as]
   [b bs])
   (* a b)))

(time
 (for/sum ([a (in-list as)]
   [b (in-list bs)])
   (* a b)))

(time (apply + (map (λ (a b) (* a b)) as bs)))

Results:

cpu time: 779 real time: 907 gc time: 111; Recursive function f
2449403808

cpu time: 437 real time: 434 gc time: 0   ; for/sum
2449403808

cpu time: 61 real time: 62 gc time: 0; for/sum with in-list
2449403808

cpu time: 307 real time: 334 gc time: 155; apply +
2449403808


To be honest I'm a little surprised how *slow* the hand-coded recursive
solution is!

Dan


On Fri, Jul 28, 2017 at 10:02 AM, Gustavo Massaccesi <gust...@oma.org.ar>
wrote:

> I agree with the in-list explanation, but I want to remark a few details.
>
> >> I don't really understand the (in-list ...) thing. This seems to be
> internal magic to me.
>
> `in-list` is not a function, it's a macro that looks like a function.
> `for` is another macro (that doesn't look like a function). But in
> Racket the macros are not just straightforward text substitution, they
> can do a lot of things. Most are simple, but some macros are very
> complex. For example `for` can examine some additional information
> stored in `in-list` and write very efficient code. I.e. magic, a lot
> of magic, but you can write your own magical `in-something`. The
> details are in https://docs.racket-lang.org/reference/for.html but
> it's not easy so I recommend reading it later after playing more with
> the simple macros.
>
> I looked at your solution with vectors. I think that vectors are not
> slower than lists, moreover, they should be slightly faster, but
> sometimes I guess wrong. The problem with your implementation is that
> it creates a lot of intermediate lists. For example in
>(apply + (map (lambda (class-label) ...) class-labels)
> The intermediate list must be allocated and free after use, the values
> are scattered in memory so it may be slower to use them.
>
> Also, the compiler can write more efficient code for the + in (+ x y)
> than for the + in (apply + ...).
>
> The solution of Daniel use (for/sum ...) instead of (apply + (map ...)).
>
> There are a few places that can be rewritten. My recommendation for
> fast code is to try to avoid allocations when possible.
>
> Gustavo
>



-- 
*Daniel Prager*
Agile/Lean Coaching, Innovation, and Leadership
Profile: skillfire.co/dan
Startups: youpatch.com <http://www.youpatch.com>, skillfire.co
Twitter: @agilejitsu <https://twitter.com/agilejitsu>
Blog: agile-jitsu.blogspot.com
Linkedin: au.linkedin.com/in/danielaprager

-- 
You received this message because you are subscribed to the Google 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: Decision Tree in Racket - Performance

2017-07-27 Thread Daniel Prager
Zelphir:
> I don't really understand the (in-list ...) thing. This seems to be
internal magic to me. Maybe it informs about the type of what is iterated
over and that makes it faster?

Pretty much. Here's a program that constructs a lot of random numbers and
adding them up in a few different ways.

#lang racket

(define random-list (build-list 50 (λ (n) (random 100
(define random-vector (list->vector random-list))

(define (sum-generic xs)
  (for/sum ([i xs]) i))

(define (sum-list xs)
  (for/sum ([i (in-list xs)]) i))

(define (sum-vector xs)
  (for/sum ([i (in-vector xs)]) i))

(displayln "Sum a List: Generic vs Specific (with in-list)")
(time (sum-generic random-list))
(time (sum-list random-list))
(newline)

(displayln "Sum a Vector: Generic vs Specific (with in-vector)")
(time (sum-generic random-vector))
(time (sum-vector random-vector))
(newline)

(displayln "Specialisation limits applicability")
(sum-list random-vector)


Output:

Sum a List: Generic vs Specific (with in-list)
cpu time: 161 real time: 178 gc time: 0
24772117
cpu time: 33 real time: 41 gc time: 0
24772117

Sum a Vector: Generic vs Specific (with in-vector)
cpu time: 113 real time: 114 gc time: 0
24772117
cpu time: 36 real time: 40 gc time: 0
24772117

Specialisation limits applicability
. . in-list: contract violation
  expected: list?
  given: '#(12 44 14 8 10 81 33 56 78 32 95 43 96 34 52 46 59 5 29 86 91 44
38 87 28 25 62 85 46 4 39 44 19 47 76 53 14 17 11 47 55 47 55 58 31 82 15
51 23 21 25 91 82 30 86 99 99 91 94 93 75 40 28 61 23 28 40 65 58 62 14 87
72 67 94 8 81 76 1 10 3 48 95 7...

Dan

-- 
You received this message because you are subscribed to the Google 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: Decision Tree in Racket - Performance

2017-07-27 Thread Daniel Prager
> Wow, are those timings for the "big" data set?!

I use 1/5 of the data as a training set, in line with my understanding of
the original article, which splits it in 5.

I use the remaining 4/5 as a single validation set rather than four
separate sets (because I got lazy). That won't impact the speed since
validating the model is fast.

> When I tried I could not run @Daniel's solution. There was some kind of
error. I am running Racket 6.8. Should I update to 6.9, could that be the
issue?

I'm running on 6.8 as well, so it's not that.

Are you running on Windows or Linux (I'm on Mac)?

You may need to modify the string-split to correctly parse line-endings per
Gustavo:

(string-split s #rx"\r?\n")


Is that it?

Dan



On Fri, Jul 28, 2017 at 6:01 AM, Zelphir Kaltstahl <
zelphirkaltst...@gmail.com> wrote:

> On Wednesday, July 26, 2017 at 3:17:46 PM UTC+2, gustavo wrote:
> > I read the solution of Daniel Prager and I have a few minor changes.
> >
> > * First I added a test that repeats `build-tree` 20 times, so the run
> > time is approximately 1-2 seconds. This is not necessary, but times
> > smaller than 1 second are sometimes not reliable. I'm using:
> > ;---
> > (random-seed 12345)
> > (define data2 (shuffle banknote-data))
> > (time
> >  (void
> >   (build-tree (take data2 274) 5 10)))
> > (time
> >  (for ([i (in-range 20)])
> >(build-tree (take data2 274) 5 10)))
> > ;---
> >
> >
> >
> > * Second I modified the split function so it is usable in Windows and
> > Linux. I'm using:
> > (string-split s #rx"\r?\n")
> > I'm almost sure this is not the best method to write portable code.
> > Any recommendation?
> >
> >
> >
> > * The most important change is to add `in-list` everywhere, i.e. replace
> > (for/sum ([split splits])  ...)
> > with
> > (for/sum ([split (in-list splits)])  ...)
> >
> > I'm not sure that all of them are necessary. The `for` clauses without
> > `in-list` are nice because they are very generic and can iterate over
> > a lot of different data types. The problem is that they create a
> > auxiliary sequence and use the methods of the sequence to iterate, so
> > they are slower than expected. If you use `in-list`, the `for` is
> > expanded to code that is specific to lists and is almost as efficient
> > as the hand coded version like (let loop ([l my-list]) ...) and
> > sometimes better.
> >
> > Most of the times you can use the generic version and use the code
> > with any data type for free, but in the spots where you need fast code
> > remember to use in-range, in-list, in-vector, ... (For the version
> > that uses vectors for internal representation, you should probably use
> > in-vector. I didn't look at the code.)
> >
> > Before this change a typical run time of the test is
> >cpu time: 157 real time: 165 gc time: 0
> >cpu time: 3390 real time: 3393 gc time: 63  (20 times)
> >
> > After this change a typical run time of the test is
> >cpu time: 62 real time: 61 gc time: 0
> >cpu time: 1266 real time: 1277 gc time: 62 (20 times)
> >
> > Gustavo
> >
> > PS: I made a PR with these changes in github.
>
> Wow, are those timings for the "big" data set?!
>
> This is about 20x faster than the vector solution. I wonder where I am
> loosing so much time. Still not finished implementing everything, but I can
> build a tree now with the vector solution. One guess I have is, that I am
> currently (partly for debugging purposes) storing subsets of data in each
> node of the tree, instead of only the split value. Another is, that I am
> using structs (instead of minimalistic lists? tagged data?) to represent
> nodes and they are constructed etc.
>
> But other than that I have no clue what is using up so much time. Maybe I
> can time every procedure in DrRacket somehow and see where the most time is
> spend.
>
> I am also curious about the Typed Racket version and consider doing this
> once I am done with the vector solution as well.
>
> I don't really understand the (in-list ...) thing. This seems to be
> internal magic to me. Maybe it informs about the type of what is iterated
> over and that makes it faster?
>
> When I tried I could not run @Daniel's solution. There was some kind of
> error. I am running Racket 6.8. Should I update to 6.9, could that be the
> issue?




-- 
*Daniel Prager*
Agile/Lean Coaching, Innovation, and Leadership
Profile: skillfire.co/dan
Startups: youpatch.com <http://www.youpatch.com>, skillfire.co
Twitter: @agilejitsu <https://twitter.com/agilejitsu>
Blog: agile-jitsu.blogspot.com
Linkedin: au.linkedin.com/in/danielaprager

-- 
You received this message because you are subscribed to the Google 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: Decision Tree in Racket - Performance

2017-07-27 Thread Daniel Prager
Thanks!

That's a useful technique, and your adjutant utilities look handy.

There should (could?) be an annual poll for promotion of the best
conveniences into the mainstream of Racket!

Dan

On 27 Jul. 2017 1:43 pm, "Philip McGrath" <phi...@philipmcgrath.com> wrote:

> Re multiple return values, you can write (call-with-values (λ () (values 1
> 2 3)) list)
>
> Because this problem bugs me, I've also written a package adjutor that
> includes values->list, list->values, and for/fold/define: http://docs.
> racket-lang.org/adjutor/index.html
>
> -Philip
>
> On Wed, Jul 26, 2017 at 3:00 AM, Daniel Prager <daniel.a.pra...@gmail.com>
> wrote:
>
>> Actually, I only use multiple values because that's what for/fold returns.
>>
>> Is there a way to convert from values to a list without going through
>> define-values or similar?
>>
>> Dan
>>
>>
>> On 26 Jul. 2017 09:40, "Zelphir Kaltstahl" <zelphirkaltst...@gmail.com>
>> wrote:
>>
>> I've come to the conclusion, that not assuming binary classification
>> makes no sense, since every n-class classification problem can be split
>> into n binary classification problems.
>>
>> When assuming classes 0 and 1, the performance increases and I get to:
>>
>> cpu time: 608 real time: 605 gc time: 68
>>
>> For finding the best split.
>>
>> Daniel's solution makes use of multiple return values, which were new to
>> me. I am using a struct for this, which might be unnecessary and later
>> removed in favor of returning multiple values like in Daniel's solution.
>>
>> --
>> You received this message because you are subscribed to the Google 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] Re: Decision Tree in Racket - Performance

2017-07-26 Thread Daniel Prager
Hi Gustavo

Nice catch on the in-list front.

I keep forgetting to do this, although I usually remember to use in-range
when iterating from 0 to n-1.

I tend to omit in-list for convenience rather than because I'm writing
generic algorithms. I wonder what the general usage patterns are like.

I guess the next step is for summertime to port this code to Typed Racket
and see how that performs.

Dan

On 26 Jul. 2017 23:17, "Gustavo Massaccesi" <gust...@oma.org.ar> wrote:

I read the solution of Daniel Prager and I have a few minor changes.

* First I added a test that repeats `build-tree` 20 times, so the run
time is approximately 1-2 seconds. This is not necessary, but times
smaller than 1 second are sometimes not reliable. I'm using:
;---
(random-seed 12345)
(define data2 (shuffle banknote-data))
(time
 (void
  (build-tree (take data2 274) 5 10)))
(time
 (for ([i (in-range 20)])
   (build-tree (take data2 274) 5 10)))
;---



* Second I modified the split function so it is usable in Windows and
Linux. I'm using:
(string-split s #rx"\r?\n")
I'm almost sure this is not the best method to write portable code.
Any recommendation?



* The most important change is to add `in-list` everywhere, i.e. replace
(for/sum ([split splits])  ...)
with
(for/sum ([split (in-list splits)])  ...)

I'm not sure that all of them are necessary. The `for` clauses without
`in-list` are nice because they are very generic and can iterate over
a lot of different data types. The problem is that they create a
auxiliary sequence and use the methods of the sequence to iterate, so
they are slower than expected. If you use `in-list`, the `for` is
expanded to code that is specific to lists and is almost as efficient
as the hand coded version like (let loop ([l my-list]) ...) and
sometimes better.

Most of the times you can use the generic version and use the code
with any data type for free, but in the spots where you need fast code
remember to use in-range, in-list, in-vector, ... (For the version
that uses vectors for internal representation, you should probably use
in-vector. I didn't look at the code.)

Before this change a typical run time of the test is
   cpu time: 157 real time: 165 gc time: 0
   cpu time: 3390 real time: 3393 gc time: 63  (20 times)

After this change a typical run time of the test is
   cpu time: 62 real time: 61 gc time: 0
   cpu time: 1266 real time: 1277 gc time: 62 (20 times)

Gustavo

PS: I made a PR with these changes in github.

-- 
You received this message because you are subscribed to the Google 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: Decision Tree in Racket - Performance

2017-07-26 Thread Daniel Prager
Actually, I only use multiple values because that's what for/fold returns.

Is there a way to convert from values to a list without going through
define-values or similar?

Dan

On 26 Jul. 2017 09:40, "Zelphir Kaltstahl" 
wrote:

I've come to the conclusion, that not assuming binary classification makes
no sense, since every n-class classification problem can be split into n
binary classification problems.

When assuming classes 0 and 1, the performance increases and I get to:

cpu time: 608 real time: 605 gc time: 68

For finding the best split.

Daniel's solution makes use of multiple return values, which were new to
me. I am using a struct for this, which might be unnecessary and later
removed in favor of returning multiple values like in Daniel's solution.

--
You received this message because you are subscribed to the Google 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: Decision Tree in Racket - Performance

2017-07-24 Thread Daniel Prager
Hi Zelphir

Thanks for the attribution.

I'm running on a MacBook Air, 2012 vintage.

Why not run both my and your code on your machine and compare?

I made no optimisations other than assuming binary classification.


Dan

On Tue, Jul 25, 2017 at 6:46 AM, Zelphir Kaltstahl <
zelphirkaltst...@gmail.com> wrote:

>
> With my implementation of a list of vectors I only get down to:
>
> cpu time: 996 real time: 994 gc time: 52
>
> on my machine. Now I don't know what kind of machine you have, but I guess
> with such small data sets it does not matter that much and the list of
> lists implementation is faster, at least for low dimensional data :) It
> seems vectors involve a bit of overhead or you did some other optimization,
> which I still have to add to my code. (Maybe assuming binary class, but
> that should not make that much of a difference, I think. Might try that
> soon.)
>
> I added your code as a new file and added a comment at the top of the file:
>
> #|
> Attribution:
>
> This implementation of decision trees in Racket was written by Daniel
> Prager and
> was originally shared at:
>
> https://groups.google.com/forum/#!topic/racket-users/cPuTr8lrXCs
>
> With permission it was added to the project.
> |#
>
> My project on Github is GPLv3.
>
>

-- 
You received this message because you are subscribed to the Google 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: Decision Tree in Racket - Performance

2017-07-24 Thread Daniel Prager
Jon wrote:
> Aside: if I read Daniel's solution correct, he avoids the first issue by
assuming that it's a binary classification task (that is, that there are
only two classes).

Yep: I'm assuming binary classification.

David wrote:
> Out of curiosity, how much of that 0.5 seconds is overhead?  Could you
run a simple 'add 1 and 1' procedure and see how long it takes?

I'm not exactly sure what you mean. Please feel free to profile however you
like on the supplied code.

My observation (primarily to Zelphir) on performance is that lists don't
seem like a bad choice for this algorithm.

If it hadn't been reasonably quick I might have tried replacing the dataset
(a list of lists) with a list of vectors, but otherwise I'd be looking at
modifying the exhaustive, greedy algorithm itself for possible speedups
rather than data structures.

Zelphir:
> Maybe you could put it in a repository, so that other people are more
likely to find your code.

If I ever get back into ML I might, but don't have the time to do a proper
write up.

Please feel free to include it in your github repository, with or without
attribution.

Dan

-- 
You received this message because you are subscribed to the Google 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] Struggling with writing array generator function

2017-07-13 Thread Daniel Prager
Hi Vasily

Since you insist ... ;-)

The main issue is how to reduce the number of args with each step of the
recursion: looks like a job for curry!

Here's one way to do it:

(define (generate-array n f)
  (for/list ([i 3])
(if (= n 1)
(f i)
(generate-array (sub1 n) ((curry f) i)

(generate-array 1 (lambda (i) 10))
(generate-array 1 (lambda (i) i))
(generate-array 2 (lambda (i j) (+ (* 10 i) j)))

A more robust version would introspect the number of arguments to f and
drop the need for an explicit n.
Also should guard against the n = 0 case.

Dan

On Fri, Jul 14, 2017 at 6:07 AM, Vasily Rybakov <madbada...@gmail.com>
wrote:

> On Thursday, July 13, 2017 at 9:30:44 PM UTC+2, Daniel Prager wrote:
> > It's straightforward to design a recursive macro with similar intent,
> but different surface syntax:
> >
> > (generate-array (i) 10)
> > (generate-array (i) i)
> > (generate-array (i j) (+ (* 10 i) j))
> >
> >
> > Dan
>
>
> Thanks for the answer, but I really need to pass generating function to it.
>
> I know that expended recursion shiuld look something like this (for
> examples of functions of 1, 2 and 3 arguments):
>
> ((lambda (f) (build-vector 3 (lambda (x) (f x (lambda (i) i))
> ((lambda (f) (build-vector 3 (lambda (x) (build-vector 3 (lambda (y) (f x
> y)) (lambda (i j) (+ i j)))
> ((lambda (f) (build-vector 3 (lambda (x) (build-vector 3 (lambda (y)
> (build-vector 3 (lambda (z) (f x y z (lambda (i j k) 10))
>
>
> But I don't know how to make such a recursion, that will produce this
> expansions.
>
> --
> You received this message because you are subscribed to the Google 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] Struggling with writing array generator function

2017-07-13 Thread Daniel Prager
It's straightforward to design a recursive macro with similar intent, but
different surface syntax:

(define-syntax generate-array
  (syntax-rules ()
[(_ (i) exp) (for/list ([i 3]) exp)]
[(_ (i j...) exp) (for/list ([i 3]) (generate-array (j...) exp))]))

(generate-array (i) 10)
(generate-array (i) i)
(generate-array (i j) (+ (* 10 i) j))

Dan

On Fri, Jul 14, 2017 at 4:52 AM, Vasily Rybakov <madbada...@gmail.com>
wrote:

> I need to write function generete-array:
>
> (define (generate-array num-dimensions generator)
>...)
>
> such that it generate num-dimensions array (each dimension is of size 3)
> and uses generator function to produce elements of array (generator accepts
> num-dimensions arguments and returns number; each element is equal to the
> result of passing its indices to generator).
>
> So
>
> (generate-array 1 (lambda (i) 10)) => '(10 10 10)
>
> (generate-array 1 (lambda (i) i)) => '(0 1 2)
>
> (generate-array 2 (lambda (i j) (+ (* 10 i) j))) =>
>   => '((0 1 2) (10 11 12) (13 14 15))
>
> and so on...
>
> I think it should use recursion, because I don't know in advance the
> number of dimensions, but I can't figure out how to do it and where I
> should begin with.
>
> Any advice on which path to take for wrighting this function will be
> helpful.
>
> --
> You received this message because you are subscribed to the Google 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.
>



-- 
*Daniel Prager*
Agile/Lean Coaching, Innovation, and Leadership
Profile: skillfire.co/dan
Startups: youpatch.com <http://www.youpatch.com>, skillfire.co
Twitter: @agilejitsu <https://twitter.com/agilejitsu>
Blog: agile-jitsu.blogspot.com
Linkedin: au.linkedin.com/in/danielaprager

-- 
You received this message because you are subscribed to the Google 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] RacketCon Code of Conduct

2017-06-17 Thread Daniel Prager
+1 for a code of conduct from me.

Although I can only rarely attend RacketCon (coming from Australia) codes
of conduct seem to have had a net positive effect at local conferences:
enhancing inclusivity and tone.

Perhaps one day such codes can be optimized away, but in the present day
requiring these contracts makes for explicit and efficient exception
handling.


Dan

-- 
You received this message because you are subscribed to the Google 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] Making change in Racket / lazy language question

2017-06-16 Thread Daniel Prager
Indeed it does.

Thanks!

On Sat, Jun 17, 2017 at 7:53 AM, Jon Zeppieri <zeppi...@gmail.com> wrote:

> On Fri, Jun 16, 2017 at 5:41 PM, Daniel Prager
> <daniel.a.pra...@gmail.com> wrote:
> >
> > But I get a perplexing error if I try to use foldl for added elegance
> when
> > defining twos:
> >
> > (define (cc x . xs) (foldl sadd (fcoin x) xs))
> > (define twos (cc 1 2 5 10 20 50 100 200))
> >
> > take: expects type  as 1st argument, given:
> '(1
> > . #); other arguments were: 2
> >
> > What's going on?
>
> The procedure that you use as `foldl`'s first argument expects the
> accumulator last, not first, so you'd just need to swap the order of
> `sadd`'s arguments.
>
> if you define `sadd` as:
>
>(define (sadd n xs) (append (take n xs) (map + (list-tail xs n)
> (sadd n xs
>
> Then it should work.
>
> - Jon

-- 
You received this message because you are subscribed to the Google 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] Making change in Racket / lazy language question

2017-06-16 Thread Daniel Prager
The classic making change problem cropped up in discussion on the Racket
reddit with solutions proffered in Haskell and Clojure.

See:
https://www.reddit.com/r/Racket/comments/6gumem/what_is_a_string_p/dixlvpr/

I was able to contribute a Lazy Racket translation:

#lang lazy
(define zeros (cons 0 zeros))
(define (fcoin n) (append (take n (cons 1 zeros)) (fcoin n)))
(define (sadd xs n) (append (take n xs) (map + (list-tail xs n) (sadd xs
n
(define twos (sadd (sadd (sadd (sadd (sadd (sadd (sadd (fcoin 1) 2) 5) 10)
20) 50) 100) 200))
(! (list-ref twos 200))

But I get a perplexing error if I try to use foldl for added elegance when
defining twos:

(define (cc x . xs) (foldl sadd (fcoin x) xs))
(define twos (cc 1 2 5 10 20 50 100 200))

take: expects type  as 1st argument, given: '(1
. #); other arguments were: 2

What's going on?

Also, I failed to get a solution in regular Racket using streams, wherein
my attempt hanged.


Dan

-- 
You received this message because you are subscribed to the Google 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] Apropos contracts: simple predicates and switching on and off

2017-05-07 Thread Daniel Prager
On Mon, May 8, 2017 at 3:05 AM, Matthias Felleisen 
wrote:

>
> Measure with outer contract and remove the inner define/tight. If you
> wrote this algorithm with a loop in Eiffel, instead of a tail-recursive
> function, you wouldn’t check the invariant for every loop iteration either
>
>
Fair comment.

[In Eiffel I'd need to use a check condition in my loop. Below I explore
the moral equivalent of raising an error in Racket, which seems to work
well enough.]


I've removed the offending post-condition and redone the timings. (Code at
end)


*No contracts*
cpu time: 13 real time: 13 gc time: 0

*Outer contract only*
cpu time: 48 real time: 48 gc time: 0

*Outer contract + inner exception check*
cpu time: 63 real time: 73 gc time: 15

*Outer + tight inner contract*
cpu time: 1251 real time: 1268 gc time: 27



The virtue of the inner contract is that it catches non-terminating cases
during development.

E.g. In the recursive call (S (* 0.5 (+ estimate (/ x estimate if we
replace / with * the "tight" contract catches it by imposing a bounds
check.

*Note*: I haven't reintroduced the more stringent requirement that the
error reduces with every iteration (monotonic convergence).


*Take-away*

The timings suggest that applying the contract system is a particularly
expensive way to achieve this level of safety. The outer contract + inner
exception check is a much more affordable alternative.

This example isn't enough to really explore the question of whether it
makes sense to later turn off the inner checks, once confidence has been
achieved. Personally, I'd say "it depends" on how slow we're going and
whether it makes a difference and what cheaper checks are available.

YMMV

Dan



#lang racket

(define-syntax-rule (define/tight (fn args ...)
  ctc
  body ...)
  (begin
(define (fn args ...) (fn/impl args ...))
(with-contract fn
  ([fn/impl ctc])
  #:freevar fn ctc
  (define (fn/impl args ...)
body ...

(define-syntax-rule (implies a b)
  (or (not a) b))


(define (default-eps) 1e-14)

(define (sqrt-error x estimate)
  (-> (>/c 0) (>/c 0) (>=/c 0))
  (abs (- 1 (/ (sqr estimate) x

(define/contract (real-sqrt x [eps (default-eps)])
  (->i ([x (>=/c 0)])
   ([eps (>/c 0)])
   [result (>=/c 0)]
   #:post (x result)
   (implies (= x 0) (= result 0))
   #:post (x eps result)
   (let ([EPS (if (unsupplied-arg? eps)
  (default-eps)
  eps)])
 (implies (> x 0) (< (sqrt-error x result) EPS

  (define/tight (S estimate)
(->i ([estimate (and (>/c 0) (<=/c (max 1 x)))])
 [result (>/c 0)])

(if (< (sqrt-error x estimate) eps)
estimate
(S (* 0.5 (+ estimate (/ x estimate))

  (if (zero? x)
  0
  (S (* 0.5 (+ 1 x)


(define/contract (real-sqrt-moderate x [eps (default-eps)])
  (->i ([x (>=/c 0)])
   ([eps (>/c 0)])
   [result (>=/c 0)]
   #:post (x result)
   (implies (= x 0) (= result 0))
   #:post (x eps result)
   (let ([EPS (if (unsupplied-arg? eps)
  (default-eps)
  eps)])
 (implies (> x 0) (< (sqrt-error x result) EPS

  (define (sqrt-error estimate)
(abs (- 1 (/ (sqr estimate) x

  (define (S estimate)
(if (< (sqrt-error estimate) eps)
estimate
(S (* 0.5 (+ estimate (/ x estimate))

  (if (zero? x)
  0
  (S (* 0.5 (+ 1 x)

(define/contract (real-sqrt-modified x [eps (default-eps)])
  (->i ([x (>=/c 0)])
   ([eps (>/c 0)])
   [result (>=/c 0)]
   #:post (x result)
   (implies (= x 0) (= result 0))
   #:post (x eps result)
   (let ([EPS (if (unsupplied-arg? eps)
  (default-eps)
  eps)])
 (implies (> x 0) (< (sqrt-error x result) EPS

  (define (sqrt-error estimate)
(abs (- 1 (/ (sqr estimate) x

  (define (S estimate)
(unless (<= 0 estimate (max 1 x))
  (raise-arguments-error 'real-sqrt-modified "Broken bounds"
"estimate" estimate
"x" x))
(if (< (sqrt-error estimate) eps)
estimate
(S (* 0.5 (+ estimate (/ x estimate))

  (if (zero? x)
  0
  (S (* 0.5 (+ 1 x)


(define (real-sqrt-fast x [eps (default-eps)])
  (define (sqrt-error estimate)
(abs (- 1 (/ (sqr estimate) x

  (define (S estimate)
(if (< (sqrt-error estimate) eps)
estimate
(S (* 0.5 (+ estimate (/ x estimate))

  (if (zero? x)
  0
  (S (* 0.5 (+ 1 x)


(displayln "No contracts")
(time
 (for ([i (in-range 5000)])
   (real-sqrt-fast i)))

(newline)
(displayln "Outer contract only")
(time
 (for ([i (in-range 5000)])
   (real-sqrt-moderate i)))

(newline)
(displayln "Outer contract + inner exception check")
(time
 (for ([i (in-range 5000)])
   (real-sqrt-modified i)))

(newline)
(displayln "Outer 

Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-07 Thread Daniel Prager
Thanks Georges, Matthias, and Philip for the further pointers:

Helped by your comments I inferred that I could construct a legitimate
unsupplied-arg case using case-lambda.

I think that this is the kind of illustration would be helpful in the docs:


#lang racket

(module server racket
  (provide (contract-out
[f (->* (number?) (number?) number?)]
[g (->i ([a real?])
([b real?])
(result real?)
#:post (a b result)
(let ([B (if (unsupplied-arg? b) (default-b) b)])
  (= (* (sgn a) (sgn B)) (sgn result]))

(define (default-b) 10)

(define f (case-lambda
[(a) (+ a (default-b))]
[(a b) (+ a b)]))

(define g (case-lambda
[(a) (* a (default-b))]
[(a b) (* a b)])))



(require 'server)

(f 10)
(f 10 -5)

(g 10)
(g 10 -5)

I suppose this falls into the class of learning challenges where certain
aspects of the design of a feature are explained by the existence of
"advanced" concepts that not everyone may be yet using routinely, or even
be familiar with.

Dan

-- 
You received this message because you are subscribed to the Google 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] Apropos contracts: simple predicates and switching on and off

2017-05-07 Thread Daniel Prager
Hi Georges

Thanks for the explanation on 2. Pragmatically, it's just another
contributor to the cost of contract checking.

On 1, I'm (naïvely) baffled as to why the contract should regard an
optional argument as unsupplied when it comes from the default rather than
an explicit passing.

GIven that Racket obliges you to supply a default when declaring an
optional argument, in what sort of situations does the unsupplied case
arise?

Dan



On Sun, May 7, 2017 at 10:36 PM, Dupéron Georges <
jahvascriptman...@gmail.com> wrote:

> Le dimanche 7 mai 2017 07:27:08 UTC+2, Daniel Prager a écrit :
> > 1. Default argument goes missing from post-condition, leading to an
> > unexpected error ...
>
> You should use unsupplied-arg? . But I couldn't find a way to get the
> default value from the contract. I would guess that the problem is that the
> contract can be specified separately from the function, and the function
> itself knows the default argument's value. In the general case, extracting
> the default argument's value (without running the default expression
> multiple times) might be tricky.
>
>

-- 
You received this message because you are subscribed to the Google 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] Apropos contracts: simple predicates and switching on and off

2017-05-06 Thread Daniel Prager
Putting this new set-up through its paces I think I've found a few issues:

*1. Default argument goes missing from post-condition, leading to an
unexpected error ...*

(define/contract (greater-than-square? x [y 0])
  (->i ([x real?])
   ([y real?])
   [result boolean?]
   #:post (x y result)
   (equal? result (< (sqr y) x)))

  (> x (sqr y)))

(greater-than-square? 10)


sqr: contract violation
  expected: number?
  given: #


*2. contract-exercise seems to miss explicit #pre-conditions ...*

(contract-exercise sqrt2) finds no counter-examples (correct)
(contract-exercise sqrt3) finds bogus counter-examples (incorrect),
typically -inf.0 and -1


(define/contract (real-sqrt2 x)
  (-> (>=/c 0) (>=/c 0))
  (sqrt x))


(define/contract (real-sqrt3 x)
  (->i ([x real?])
   #:pre (x)
   (>= x 0)
   [result (>=/c 0)])
  (sqrt x))



*3. post-conditions appear to be called twice ...*

Is there a double boundary crossing on post-conditions?

Output from instrumenting of (real-sqrt 100), Newton's method for
calculating the sqrt loaded with contracts (source code at end of e-mail)
...


> (real-sqrt 100 1e-14)


(10.0 0.0)
(10.0 0.0)
(10.0139897 2.7979396577393345e-11)
(10.0139897 2.7979396577393345e-11)
(10.52895642693 1.0579156517920296e-05)
(10.52895642693 1.0579156517920296e-05)
(10.032578510960604 0.0065263157858850285)
(10.032578510960604 0.0065263157858850285)
(10.840434673026925 0.17515023900164373)
(10.840434673026925 0.17515023900164373)
(15.025530119986813 1.257665553866309)
(15.025530119986813 1.257665553866309)
(26.24009900990099 5.88542796049407)
(26.24009900990099 5.88542796049407)
(50.5 24.5025)
10.0


Note: The reverse order is because of the nature of the recursion — to be
useful in catching errors in runaway computations the check should be moved
to the pre-condition.

* * *

Finally, some timings.

Stripping out the contracts to get a fast implementation for comparison:

(define (real-sqrt-fast x [eps 1e-14])
  (define (sqrt-error estimate)
(abs (- 1 (/ (sqr estimate) x

  (define (S estimate)
(if (< (sqrt-error estimate) eps)
estimate
(S (* 0.5 (+ estimate (/ x estimate))

  (if (zero? x)
  0
  (S x)))

More moderate choice of contracts:

(define/contract (real-sqrt-moderate x [eps 1e-14])
  (->* ((>=/c 0)) ((>/c 0)) (>=/c 0))
  (define (sqrt-error estimate)
(abs (- 1 (/ (sqr estimate) x

  (define/tight (S estimate)
(-> (and (>/c 0) (<=/c (max 1 x))) (>/c 0))
(if (< (sqrt-error estimate) eps)
estimate
(S (* 0.5 (+ estimate (/ x estimate))

  (if (zero? x)
  0
  (S x)))

The fully contract-loaded code is at the end of this email (just comment
out the displayln).


Timing code:


(time
 (for/last ([i (in-range 1000)])
   (real-sqrt 1000 1e-14)))

(time
 (for/last ([i (in-range 1000)])
   (real-sqrt-moderate 1000)))

(time
 (for/last ([i (in-range 1000)])
   (real-sqrt-fast 1000)))



*All the contracts*
cpu time: 840 real time: 1048 gc time: 288
31.622776601683793

*Moderate (but still some "tight") use of contracts *
cpu time: 404 real time: 443 gc time: 163
31.622776601683793

*No contracts*
cpu time: 3 real time: 3 gc time: 0
31.622776601683793

So a 280x speed-up / slow-down for heavy-duty use of "tight" contracts. ;-)
Only a factor of 2x difference between the contract variations.

Dan


Contracts for real-sqrt

#lang racket

(define-syntax-rule (define/tight (fn args ...)
  ctc
  body ...)
  (begin
(define (fn args ...) (fn/impl args ...))
(with-contract fn
  ([fn/impl ctc])
  #:freevar fn ctc
  (define (fn/impl args ...)
body ...

(define-syntax-rule (implies a b)
  (or (not a) b))

(define (sqrt-error x estimate)
  (-> (>/c 0) (>/c 0) (>=/c 0))
  (abs (- 1 (/ (sqr estimate) x

(define/contract (real-sqrt x eps)
  (->i ([x (>=/c 0)]
[eps (>/c 0)])
   [result (>=/c 0)]
   #:post (x result)
   (implies (= x 0) (= result 0))
   #:post (x eps result)
   (implies (> x 0) (< (sqrt-error x result) eps)))

  (define/tight (S estimate)
(->i ([estimate (and (>/c 0) (<=/c (max 1 x)))])
 [result (>/c 0)]
 #:post/name (estimate result)
 "Unless it is practically zero, the error should decrease with
every iteration"
 (let ([dr (sqrt-error x result)])
   (displayln (list estimate (sqrt-error x estimate)))
   (or (< dr eps)
   (< dr (sqrt-error x estimate)

(if (< (sqrt-error x estimate) eps)
estimate
(S (* 0.5 (+ estimate (/ x estimate))

  (if (zero? x)
  0
  (S (* 0.5 (+ 1 x)


(define (real-sqrt-fast x [eps 1e-14])
  (define (error estimate)
(abs (- 1 (/ (sqr estimate) x

  (define (S estimate)
(if (< (error estimate) eps)
estimate
(S (* 0.5 (+ estimate (/ x estimate))

  (if (zero? x)
  0
  (S x)))

-- 
You received 

Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-06 Thread Daniel Prager
Thanks Georges

It looks suggestive, but I'm struggling to follow the details of
with-contract / blame-id. An example of use would be very helpful in the
docs!

Have you used this construct?


Dan


On Sun, May 7, 2017 at 7:44 AM, Dupéron Georges <jahvascriptman...@gmail.com
> wrote:

> Le samedi 6 mai 2017 23:38:29 UTC+2, Daniel Prager a écrit :
> > Although I understand why my macro does this
> >
> > unsafe-factorial: contract violation
> > ...
> >   blaming: (function fn/impl)
> > ...
> >   at: unsaved-editor:13.15
> >
> >
> > Ideally I would prefer one which blames unsafe-factorial
> >
> > unsafe-factorial: contract violation
> > ...
> >   blaming: (function unsafe-factorial)
> > ...
> >   at: unsaved-editor:13.15
> >
> >
> > i.e. it's leaking an auxillary introduced by the macro (fn/impl) into the
> > message & Dr Racket. It seems that the line-number refers to the line
> that
> > defines unsafe-factorial, though, which looks right.
>
> Perhaps with-contract's `blame-id` can help?
>
> http://docs.racket-lang.org/reference/attaching-contracts-
> to-values.html#%28form._%28%28lib._racket%2Fcontract%
> 2Fregion..rkt%29._with-contract%29%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.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-06 Thread Daniel Prager
Although I understand why my macro does this

unsafe-factorial: contract violation
...
  blaming: (function fn/impl)
...
  at: unsaved-editor:13.15


Ideally I would prefer one which blames unsafe-factorial

unsafe-factorial: contract violation
...
  blaming: (function unsafe-factorial)
...
  at: unsaved-editor:13.15


i.e. it's leaking an auxillary introduced by the macro (fn/impl) into the
message & Dr Racket. It seems that the line-number refers to the line that
defines unsafe-factorial, though, which looks right.

I could ameliorate this by having my macro give a more suggestive name e.g.
"unsafe-factorial/impl", but perhaps there's a better approach.

* * *

Matthias wrote
> The only thing that leaks is that >/c is actually an and/c contract — and
I will say I am rather surprised by that.

Me too!

I ended up switching my contract to (and/c integer? (not not/c negative?))
to remove the inconsistency, but it does seem to point to another leak.

Dan


On Sun, May 7, 2017 at 12:25 AM, Matthias Felleisen <matth...@ccs.neu.edu>
wrote:

>
> On May 5, 2017, at 11:30 PM, Daniel Prager <daniel.a.pra...@gmail.com>
> wrote:
>
> Thank-you Matthias
>
> That's neat!
>
> And yes, I can write a basic macro. By introducing #:freevar I was able to
> improve the blame situation, but the abstraction is a bit leaky ...
>
> (define-syntax-rule (define/tight (fn args ...)
>   ctc
>   body ...)
>   (begin
> (define (fn args ...) (fn/impl args ...))
> (define/contract (fn/impl args ...)
>   ctc
>   #:freevar fn ctc; Directs blame to "fn/impl" rather than the
> enclosing module
>   body ...)))
>
>
>
> I am not sure what you mean by ‘leaky’. When I run this,
>
> (define/tight [unsafe-factorial n]
>   (-> (and/c integer? (>=/c 0)) (and/c integer? (>=/c 0)))
>   (if (zero? n)
>   1
>   (* n (unsafe-factorial (- n 10)
> (unsafe-factorial 5) ; Does not terminate
>
> I get
>
> unsafe-factorial: contract violation
>   expected: (and/c real? (not/c negative?))
>   given: -5
>   in: an and/c case of
>   the 1st argument of
>   (->
>(and/c
> integer?
> (and/c real? (not/c negative?)))
>(and/c
> integer?
> (and/c real? (not/c negative?
>   contract from: anonymous-module
>   blaming: (function fn/impl)
>(assuming the contract is correct)
>   at: unsaved-editor:13.15
>
>
>
> The only thing that leaks is that >/c is actually an and/c contract — and
> I will say I am rather surprised by that.
>
>

-- 
You received this message because you are subscribed to the Google 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] Apropos contracts: simple predicates and switching on and off

2017-05-05 Thread Daniel Prager
Thank-you Matthias

That's neat!

And yes, I can write a basic macro. By introducing #:freevar I was able to
improve the blame situation, but the abstraction is a bit leaky ...

(define-syntax-rule (define/tight (fn args ...)
  ctc
  body ...)
  (begin
(define (fn args ...) (fn/impl args ...))
(define/contract (fn/impl args ...)
  ctc
  #:freevar fn ctc; Directs blame to "fn/impl" rather than the
enclosing module
  body ...)))

Dan


On Sat, May 6, 2017 at 11:15 AM, Matthias Felleisen 
wrote:

>
> Sure:
>
> #lang racket
>
> (define/contract [unsafe-factorial n]
>   (-> (and/c integer? (>=/c 0)) (and/c integer? (>=/c 0)))
>   (if (zero? n)
>   1
>   (* n (factorial (- n 10)
> (define (factorial n)  (unsafe-factorial n)) ;; cross the boundary and go
> right back in
> (unsafe-factorial 5) ; Does not terminate
>
>
> I suspect you can implement this with a macro now.
>

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


Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-05 Thread Daniel Prager
Hi Matthias

Thanks for the pointer to Robby's 2014 keynote.

Here's the link for those interested — it's really good:
https://www.youtube.com/watch?v=gXTbMPVFP1M

* * *

In regard to Racket's use of boundaries,  am I right in thinking that it's
difficult to pull the boundaries in really *tight*?

For instance, the following example does not terminate and cannot help with
the necessary debugging because the contract is only checked on the call
through the module boundary, with recursive calls incorrectly and
implicitly trusted:


#lang racket

(module server racket
  (provide (contract-out
[unsafe-factorial (-> (and/c integer? (>=/c 0))
  (and/c integer? (>=/c 0)))]))

  (define (unsafe-factorial n)
(if (zero? n) ; Naïvely relying on the
contract to rule out -ve n's
1
(* n (unsafe-factorial (- n 10))  ; Bug


(require 'server)

(unsafe-factorial 5) ; Does not terminate


My best idea at the moment is to add some extra checking, e.g. (just
duplicating the pre-conditions) ...

  (define (safe-factorial n)
(unless (integer? n)
  (raise-argument-error 'safe-factorial "n must be an integer" n))
(unless (>= n 0)
  (raise-argument-error 'safe-factorial "n must be >= 0" n))
(if (zero? n)
1
(* n (safe-factorial (- n 10))

... but this is verbose, no good for higher-oder conditions, and redundant:
once it has been debugged the contract at the module-boundary suffices.

What do others do / suggest?


Dan

-- 
You received this message because you are subscribed to the Google 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] Apropos contracts: simple predicates and switching on and off

2017-05-03 Thread Daniel Prager
Using Ben's left-pad example as a model I get the following re-write of the
real-sqrt contract

  (([x real?])
   #:pre/name (x)
   "non-negative argument expected"
   (>= x 0)
   . ->i .
   [result (x) real?]
   #:post/name (x result)
   "the sqrt of zero is zero"
   (implies (= x 0) (= result 0))
   #:post/name (x result)
   "the sqrt of a positive number is positive"
   (implies (> x 0) (> result 0))
   #:post/name (x result)
   "result * result = x (to within error)"
   (implies (> x 0) (<= (abs (- x (* result result))) 0.0001)))

Other than a bit of repetition — multiple uses of #:post/name — this is
pretty darn close to what I was after.

Like most people, when faced with something complex and a bit daunting — in
this case the ->i contract combinator — I benefit from concrete examples.

If enough people encourage me to "make a pull request" once I'm more
familiar I'll propose some more examples myself.

* * *

My off-hand proposal would be to permit a variation on #:pre/name,
#:post/name and friends to allow multiple clauses. For example:

 #:post/name (x result)
   ["sqrt of zero is zero" (implies (= x 0) (= result 0))]
   ["sqrt of a positive number is positive" (implies (> x 0) (> result 0))]
   ["result * result = x (to within error)"
(implies (> x 0) (<= (abs (- x (* result result))) 0.0001))]


Next stop ... boundaries.


Thanks again

Dan


On Wed, May 3, 2017 at 1:57 PM, Ben Greenman 
wrote:

1. To practice with dependent contracts, I made a "full" spec for the
> JavaScript left-pad function.
> https://www.npmjs.com/package/left-pad
>
> The exercise was fun, I learned a lot, and I think my solution is "as
> readable as possible" :) .
> https://github.com/bennn/racket-left-pad
>
>

-- 
You received this message because you are subscribed to the Google 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] Apropos contracts: simple predicates and switching on and off

2017-05-03 Thread Daniel Prager
Hi Matthias (and everyone)

Matthias wrote:
> As Tony Hoare said, what do you think of a boater who practices on land
with his swim vest on and then goes to sea and takes the swim vest off?

I think the only way to reply to these sorts of arguments is to wrestle
back the framing!

Do you bet on the Formula I driver whose team includes the most safety
features? ;-)

> We want you to take responsibility for taking the swim vest off.

I love this comment!

* * *

On the Eiffel in contrast to Racket stuff, I appreciate that significant
advances have been made, serious issues addressed, and changes too in your
group's work on Contracts.

For me, as a practitioner, Eiffel did some things very well within its
limitations, and I wasn't affected by the shortcomings too badly.

In moving over to Racket I appreciate the breadth and depth of all the
additional stuff one can do, which — along with the terrific community — is
why I'm here.

>From a technical perspective I'm happy to not mention invariants or
covariance again for now: they don't seem very relevant in the main Racket
use cases.


Thanks again!

Dan


On Thu, May 4, 2017 at 1:51 AM, Matthias Felleisen <matth...@ccs.neu.edu>
wrote:

>
> You have gotten plenty of good answers so let me focus on some of the
> high-level points and some details that people didn’t respond to:
>
>
> > On May 2, 2017, at 6:01 PM, Daniel Prager <daniel.a.pra...@gmail.com>
> wrote:
> >
> > More concise and clear expression of contracts
> >   • The implies operator
>
>
> Missing but I am sure we would accept a pull request on that one.
>
>
> >   • Proper support for invariant-checking
>
>
> Well. It’s kind of there (see appended code at end) but not exactly.
> Eiffel has re-entry problems with invariants and Spec# cleaned this up a
> bit. We have a ‘boundary philosophy’ (see beginning of Contract Guide and
> what I wrote there) and that is much cleaner but distinct from Eiffel for
> sure.
>
>
> >   • Proper support for covariant inheritance
>
>
> That’s unsound so we did not want to go there.
>
>
> >   • Tools for automatically generating documentation
>
> Good idea. We have bits and pieces for that. Nothing too useful.
>
>
> >   • Better tools for turning off contracts by configuration
>
>
> As Tony Hoare said, what do you think of a boater who practices on land
> with his swim vest on and then goes to sea and takes the swim vest off?
>
>
> > My questions are:
> >   • Is it feasible to get similar behaviour from the official
> contract system?, or
> >   • Do these considerations call for building up an alternative
> system?
>
>
> Yes you can. Racket’s contract system is far more expressive than
> Eiffel’s. It also repairs obvious short-comings (a polite way of saying
> problems) with Eiffel’s.
>
> What you are missing is what you can do with macros.
>
>
> >
> > Restating my goals:
> >   • Specify pre-conditions and post-conditions as simple predicates
> (boolean expressions)
> >   • Selectively turn off contracts (mainly post-conditions) for
> performance in well-tested code.
>
> See Hoare above. See Macro above. See the Literature pointer in Ben’s
> message. We want you to take responsibility for taking the swim vest off.
>
>
> #lang racket
>
> (module server racket
>   (provide
>(contract-out
> (c% (class/c (field [x positive?]) (setter (->m number? number?))
>
>   (define c%
> (class object%
>   (super-new)
>   (field [x -1])
>   (define/public (setter x*) (begin0 x (set! x x*))
>
> (module client racket
>   (require (submod ".." server))
>
>   (define c (new c%))
>   (displayln `(the initial value does not have to live up to the field
> contract ,(send c setter 2)))
>   (with-handlers ([exn:fail:contract? (lambda (xn) (displayln `(you can't
> get away with bad sets)))])
> (send c setter 0)))
>
> (require 'client)

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


Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-03 Thread Daniel Prager
Thanks Ben

The left-pad example is most helpful. Perhaps it could be included in the
docs, given that usefully illustrates features of ->i for which no example
is given.

I may well have a shot at re-implementing it once I have sufficient
machinery set up to support multiple and optional arguments in the kind of
style I favor for expressing contracts. Then it will be interesting to see
how the readability compares.

Thanks also for pointing me to the paper on contracts — time for a re-read!

Dan

On Wed, May 3, 2017 at 1:57 PM, Ben Greenman <benjaminlgreen...@gmail.com>
wrote:

>
> On Tue, May 2, 2017 at 11:43 PM, Daniel Prager <daniel.a.pra...@gmail.com>
> wrote:
>
>> I kind of expected that it would be possible to do what I wanted with
>> "indy" contracts, but struggled with the heavy use of combinators in the
>> examples.
>
>
> Two offhand thoughts:
>
> 1. To practice with dependent contracts, I made a "full" spec for the
> JavaScript left-pad function.
> https://www.npmjs.com/package/left-pad
>
> The exercise was fun, I learned a lot, and I think my solution is "as
> readable as possible" :) .
> https://github.com/bennn/racket-left-pad
>
>
> 2. "Oh Lord, Don't Let Contracts be Misunderstood" implements a little DSL
> on top of ->i contracts: http://www.ccs.neu.edu/racket/
> pubs/icfp16-dnff.pdf
>
>
>

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


Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-03 Thread Daniel Prager
Hi Philip

Thank-you for sharing your version: each example and variation is helping
me understand the machinery better.

I agree that clarity in error reporting is also vital, and it's been made
clear to me that it is feasible to hook into the contract system and take
advantage of its facilities, which is great.

Once I've made another pass I'll include the error messages for critical
discussion.

On the subject of turning down contracts for performance and then being
bitten, believe me, I hear you: my preference is to have the maximum
checking I can afford. But when I'm really writing stringent
post-conditions (or invariants) they can get *really* expensive, negatively
impacting on user experience, which takes us into the land of pragmatic
trade-offs.

If I don't have a way to turn them off I'm either not going to write them
at all or comment them out, and then regret not using them on smaller test
scenarios.

Dan





On Wed, May 3, 2017 at 1:51 PM, Philip McGrath 
wrote:

> Here's the "quick" way I'd write the real-sqrt in Racket, combined with an
> illustration of one of the advantages of using the established contract
> combinators: here they gracefully report a kind of error that in the
> original would have caused an error in the error-checking code.
>
> (define/contract (real-sqrt x)
>   (->i ([x (>=/c 0)])
>[rslt (x)
> (if (= 0 x)
> (=/c 0)
> (and/c (>=/c 0)
>(λ (rslt) (<= (abs (- x (* rslt rslt))) error])
>   "not even a number")
>
>
> The part of what you describe that has the least support in the Racket
> system is controlling the level of safety through a mechanism
> like pre-conditions-on/post-conditions-on. It would be easy enough to
> create a contract that is always satisfied if e.g. pre-conditions-on (which
> might be most Rackety to right as a parameter) is non-false, but I would
> suspect, at least in a case like this, you would already have paid most of
> the cost by getting into the contract system in the first place.
>
> The most typical solution, as Matthew illustrates, is to attach the
> contract at a module boundary with contract-out rather than a function
> boundary with define/contract, perhaps ultimately to attach it only to the
> public API of your library rather than for internals, and to leave off
> checks on the domains of functions (with the "any" contract) once you know
> they behave properly. Personally, though, having been annoyed once too
> often in tracking down an error that turned out to result from having
> changed the number of values a function returned, I'm happy to pay the
> price for good errors and trust the wonderful Racket implementers to keep
> the price as cheap as possible.
>
> Interestingly I had some trouble getting the nicely specific error
> messages you had in your example: I'll post about that separately.
>
> -Philip
>

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


Re: [racket-users] Apropos contracts: simple predicates and switching on and off

2017-05-02 Thread Daniel Prager
Thanks Matthew

That's very helpful. I definitely want to hook into the existing contract
system if possible, and you've given some good pointers to how this might
be done.

I kind of expected that it would be possible to do what I wanted with
"indy" contracts, but struggled with the heavy use of combinators in the
examples.

Your example is illuminating: I'll have a play with it and see if I can
figure out a suitable macro to reduce the boilerplate.

The use of module+ approach is good motivation to get more familiar with
the module system: back to Beautiful Racket for a refresher!

* * *

Thinking more about it, it also makes sense to reify contracts to allow
them to clip onto alternative implementations.

I'll come back later with some more code (unless someone beats me to it ;-).

* * *

I'm also interested in whether more people would use contracts routinely if
they were made a bit more accessible in terms of ease-of-use and making it
easy to turn them on and off.

When I used and advocated them first in the late 90s my colleagues thought
it was all too "bondage and discipline" so I went it alone.

When I was tech lead in naughties I corralled one team into using them to
good effect, but it required a degree of leadership and personal support.

Now, with the more widespread acceptance of unit tests and TDD, I wonder
whether they might be an easier "sell".


Dan



On Wed, May 3, 2017 at 12:22 PM, Matthew Butterick <m...@mbtype.com> wrote:

>
> On May 2, 2017, at 4:33 PM, Daniel Prager <daniel.a.pra...@gmail.com>
> wrote:
>
> (define/pre-post (real-sqrt x)
>   #:pre ([(real? x) "real argument expected"]
>  [(>= x 0) "non-negative argument expected"])
>
>   #:implementation (sqrt x)
>
>   #:post ([(implies (= x 0) (= result 0)) "The sqrt of zero should be
> zero"]
>   [(implies (> x 0) (> result 0)) "Positive numbers have positive
> square-roots"]
>   [(implies (> x 0) (<= (abs (- x (* result result))) 0.001))
>"result * result = x (to within error)"]))
>
>
>
> It sounds like you want alternate notation for stuff the contract system
> can already do.
>
> AFAICT the function below is equivalent to your function above. One could
> create a macro to go from one to the other:
>
>
> (define/contract (real-sqrt x)
>   (([x (and/c
> (or/c (λ (x) (real? x))
>   (curry raise-argument-error 'real-sqrt "real argument
> expected"))
> (or/c (λ (x) (>= x 0))
>   (curry raise-argument-error 'real-sqrt "non-negative
> argument expected")))])
>. ->i .
>[result (x)
>(cond
>  [(= x 0) (or/c (λ (result) (= result 0))
> (curry raise-result-error 'real-sqrt "sqrt of
> zero should be zero"))]
>  [(> x 0) (and/c
>  (or/c (λ (result) (> result 0))
>(curry raise-result-error 'real-sqrt
> "sqrt of positive number should be positive"))
>  (or/c (λ (result) (<= (abs (- x (* result
> result))) 0.0001))
>  (curry raise-result-error 'real-sqrt
> "result * result = x (to within error)")))])])
>   (sqrt x))
>
>
> Thinking more about the functional context, a macro — say (define/pre-post
> ...) that cleanly defined the following functions would be pretty sweet
> (continuing with the real-sqrt example):
>
>- real-sqrt-unsafe
>- real-sqrt-with-pre-conditions
>- real-sqrt-with-pre-and-post-conditions
>- real-sqrt (make-parameter one-of-the above)
>
>
> Rather than mint new identifiers, one could also export the function via
> multiple submodules, each of which has a different level of contracting.
> The advantage is that the "safety level" 1) can be adjusted by the caller,
> 2) without having to change the name of the identifier in the code. Again,
> this could all be automated through a macro:
>
> (begin
>   (define (real-sqrt x)
>  ;; no contract)
>   (provide real-sqrt)
>
>   (module+ precheck
> (provide (contract-out [real-sqrt precheck-contract ···])))
>
>   (module+ allchecks
> (provide (contract-out [real-sqrt allcheck-contract ···])))
> )
>
> And so on.
>
>

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


[racket-users] Re: Apropos contracts: simple predicates and switching on and off

2017-05-02 Thread Daniel Prager
Thinking more about the functional context, a macro — say (define/pre-post
...) that cleanly defined the following functions would be pretty sweet
(continuing with the real-sqrt example):

   - real-sqrt-unsafe
   - real-sqrt-with-pre-conditions
   - real-sqrt-with-pre-and-post-conditions
   - real-sqrt (make-parameter one-of-the above)

and of course plugging into the contract system.

Example sketch of use and expansion below ...

Dan



*Example ...*

(define/pre-post (real-sqrt x)
  #:pre ([(real? x) "real argument expected"]
 [(>= x 0) "non-negative argument expected"])

  #:implementation (sqrt x)

  #:post ([(implies (= x 0) (= result 0)) "The sqrt of zero should be zero"]
  [(implies (> x 0) (> result 0)) "Positive numbers have positive
square-roots"]
  [(implies (> x 0) (<= (abs (- x (* result result))) 0.001))
   "result * result = x (to within error)"]))


*Expansion (not yet using the contract system): *

(define (real-sqrt-unsafe x)
  (sqrt x))


(define (real-sqrt-with-pre-conditions x)
  (pre [(real? x) "real argument expected"]
   [(>= x 0) "non-negative argument expected"])

  (real-sqrt-unsafe x))


(define (real-sqrt-with-pre-and-post-conditions x)
  (define result (real-sqrt-with-pre-conditions x))

  (post [(implies (= x 0) (= result 0)) "The sqrt of zero should be zero"]
[(implies (> x 0) (> result 0)) "Positive numbers have positive
square-roots"]
[(implies (> x 0) (<= (abs (- x (* result result))) 0.001))
 "result * result = x (to within error)"])
  result)


(define real-sqrt (make-parameter real-sqrt-with-pre-and-post-conditions))

-- 
You received this message because you are subscribed to the Google 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] Apropos contracts: simple predicates and switching on and off

2017-05-02 Thread Daniel Prager
My concept of how (simple) contracts should work was influenced by the
Bertrand Meyer /  Eiffel approach and spent many years of rolling my own
contracts in lesser languages to mimic this.

The main things I found pragmatically useful were:

   1. Being able to specify pre-conditions and post-conditions as simple
   predicates
   2. Being able to selectively turn off contracts (typically
   post-conditions) in well-tested code for performance.

With very simple hand-rolled assertions (plus some design discipline) I
reckon I achieved 80% pf the promise of contracts, with my debugging time
plunging by a factor of 10, and much cleaner designs.

When I finally programmed in Eiffel there were several added benefits of
language support that I appreciated:

   - More concise and clear expression of contracts
   - The implies operator
   - Proper support for invariant-checking
   - Proper support for covariant inheritance
   - Tools for automatically generating documentation
   - Better tools for turning off contracts by configuration

But I was only able to get to use Eiffel in one organisational setting —
quite a big negative!

* * *

Coming across to Racket I was thrilled to see that contracts are a big part
of the system, but they are certainly a bit different to what I was used to!

I'd like to share a sketch of how I would start to hand-roll the kind of
contracts I was used to in Racket.

My questions are:

   - Is it feasible to get similar behaviour from the official contract
   system?, or
   - Do these considerations call for building up an alternative system?


Restating my goals:

   1. Specify pre-conditions and post-conditions as simple predicates
   (boolean expressions)
   2. Selectively turn off contracts (mainly post-conditions) for
   performance in well-tested code.

Example: real square root function, and sketch of support below.

Now, I appreciate that the Racket contract system provides all sorts of
support for higher-level functional programming, but it concerns me that as
a big fan of contracts I've been reluctant to use them consistently in
Racket.

I hope to change that in my second decade of Racket (formerly PLT Scheme)
use, but may need some support and guidance!

Dan



#lang racket

(define pre-conditions-on #t)
(define post-conditions-on #t)

(define (implies a b)
  (or (not a) b))

(define-syntax-rule (pre [test? msg] ...)
  (unless (not pre-conditions-on)
(unless test?
  (error (~a "Pre-condition violation: " msg))) ...))

(define-syntax-rule (post [test? msg] ...)
  (unless (not post-conditions-on)
(unless test?
  (error (~a "Post-condition violation: " msg))) ...))

(define (real-sqrt x)
  (pre [(real? x) "real argument expected"]
   [(>= x 0) "non-negative argument expected"])

  (define result (sqrt x))
  ; Change the implementation to 1, 0, (- x) to trigger various
post-condition errors

  (post [(implies (= x 0) (= result 0)) "The sqrt of zero should be zero"]
[(implies (> x 0) (> result 0)) "Positive numbers have positive
square-roots"]
[(implies (> x 0) (<= (abs (- x (* result result))) 0.001))
 "result * result = x (to within error)"])
  result)


(real-sqrt 0)
(real-sqrt 9)
(real-sqrt -9) ; Pre-condition error

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


Re: [racket-users] Speeding up graphics / moving away from 2htdp/image

2017-05-02 Thread Daniel Prager
Hi Ju

Interesting results. Did you run the Contract Profiler tool? [
http://docs.racket-lang.org/contract-profile/]

I think it's fairly well understood that the contract-induced performance
costs across the typed / untyped boundary can be severe.

BTW: At the back of my mind is the thought that the performance one could
achieve on these kinds of benchmarks would go up ridiculously by pushing
the work to a GPU.

Dan


On Tue, May 2, 2017 at 8:06 PM, WarGrey Gyoudmon Ju 
wrote:

> Hello, I found an interesting thing.
>
> My conclusion was totally wrong since your example are written in Untyped
> Racket, the generated contracts eat all the seconds unconsciously.
>
> Timing your example in Typed Racket with my functional bitmap combiners:
>
> no optimizing, generating all 2500 bitmaps on the fly:
> bitmap-*-append...
> cpu time: 386 real time: 387 gc time: 20
> bitmap-table...
> cpu time: 381 real time: 381 gc time: 10
>
> with memorizing (only 2 distinguishable bitmaps are generated):
> bitmap-*-append...
> cpu time: 85 real time: 85 gc time: 0
> bitmap-table...
> cpu time: 93 real time: 94 gc time: 23
>
> Still slower than pict, but as a raster graphics API, it does a great job!
>
>

-- 
You received this message because you are subscribed to the Google 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] Speeding up graphics / moving away from 2htdp/image

2017-04-29 Thread Daniel Prager
On Sat, Apr 29, 2017 at 11:44 PM, Robby Findler <ro...@eecs.northwestern.edu
> wrote:

> On Sat, Apr 29, 2017 at 3:18 AM, Daniel Prager
> <daniel.a.pra...@gmail.com> wrote:
> > On Sat, Apr 29, 2017 at 6:04 PM, Philip McGrath <
> phi...@philipmcgrath.com>
> > wrote:
> >>
> >> I think that would be because "the draw is called during the dynamic
> >> extent of the call to dc as part of the contract checking."
> >
> >
> >  That explains it!
> >
> > I think I can take the performance hit — it would be nice to have
> > fine-grained control of contract-checking for these expensive checks,
> > though.
>
> I've added unsafe-dc that skips the pre-condition check.
>
> Robby
>

Thanks!

Dan

-- 
You received this message because you are subscribed to the Google 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] Speeding up graphics / moving away from 2htdp/image

2017-04-29 Thread Daniel Prager
On Sat, Apr 29, 2017 at 6:04 PM, Philip McGrath 
wrote:

> I think that would be because "the *draw* is called during the dynamic
> extent of the call to dc
> 
> as part of the contract checking."
>

 That explains it!

I think I can take the performance hit — it would be nice to have
fine-grained control of contract-checking for these expensive checks,
though.

Dan

-- 
You received this message because you are subscribed to the Google 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] Speeding up graphics / moving away from 2htdp/image

2017-04-29 Thread Daniel Prager
Thanks for all the suggestions.

I was able to get pict down to "direct to dc"-like performance by making a
custom pict that calls my direct-to-dc code ...

(define (pict:render block)
  (pict:dc (λ (dc dx dy)
(define old-brush (send dc get-brush))
(define old-pen (send dc get-pen))
(dc:draw dc block dx dy)
(send dc set-brush old-brush)
(send dc set-pen old-pen))
(* *size* *n*) (* *size* *n*)))


My only remaining question is why pict calls the custom code on
construction, as well as on rendering.

(displayln "Render, then convert to bitmap%...")
(define pict:c1 (time (pict:render b1)))
(define p1 (time (pict->bitmap% pict:c1)))


Dan


Revised timings ...


SQUARES
===

2htdp/image
---
Render, then convert to bitmap%...
cpu time: 134 real time: 136 gc time: 46
cpu time: 344 real time: 355 gc time: 60

pict

Render, then convert to bitmap%...
cpu time: 80 real time: 87 gc time: 0
cpu time: 83 real time: 84 gc time: 13

direct to dc

Render direct to bitmap%...
cpu time: 67 real time: 68 gc time: 0


TRIANGLES
=

2htdp/image
---
Method 1 - Render, then convert to bitmap%...
cpu time: 542 real time: 559 gc time: 76
cpu time: 606 real time: 622 gc time: 63

Method 2 - Render, then convert to bitmap%...
cpu time: 332 real time: 337 gc time: 51
cpu time: 539 real time: 550 gc time: 62

Method 3 - Render, then convert to bitmap%...
cpu time: 223 real time: 230 gc time: 37
cpu time: 276 real time: 279 gc time: 25


pict

Render, then convert to bitmap%...
cpu time: 176 real time: 173 gc time: 22
cpu time: 188 real time: 188 gc time: 9

direct to dc

Render direct to bitmap%...
cpu time: 193 real time: 194 gc time: 16

-- 
You received this message because you are subscribed to the Google 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] Speeding up graphics / moving away from 2htdp/image

2017-04-28 Thread Daniel Prager
On Sat, Apr 29, 2017 at 2:10 AM, WarGrey Gyoudmon Ju 
wrote:

> Hello, I think the main reason that pict is faster than 2htdp/image is,
> the pict is implemented with struct while the 2htdp/image is implemented
> with class, the speed of rendering is just as fast/slow as each other, but
> manipulation on class is much heavier than on struct when combining large
> numbers of shapes. Maybe you want to check the code of `table` in pict-lib,
> it is a good example to place shapes into grids in a functional way.
>

Interesting. I'd also note that unlike pict 2htdp/image doesn't provide a
way to draw direct to dc, necessitating going via bitmaps when using it in
conjunction with racket/gui.


> I tested your example with my functional bitmap APIs (with arguments
> memorized, and it only creates one bitmap% when combining a list of
> shapes), as expected it is too slow(<3s, without memorizing it's <6s) to
> stand with, but it also indicates that half or less time used is not
> creating or drawing single primitive shapes, but every primitive shape is
> rendered duplicately whenever its combining shape is rendering. So the
> issue is, to find a strategy to call `freeze` at a reasonable level of
> combined shapes.
>

My thinking has been to strip back to simpler strategies initially to see
how much speed is possible, then apply freezing and caching strategies
later, if applicable. (Something, something "premature optimization ...
evil" ;-)


>
> One reason that you may have to write your own combiner(here the term
> should be "layout") is, `freeze` can make a big shape, but it cannot avoid
> the duplicate rendering since it actually do the drawing. So your combiner
> would focus on providing the position and size information for dc to `draw`
> or `copy` and/or `rotate/flip`. Sounds hard to do it with fewer bugs.
>

Before resorting to writing my own combiner / layout I think I'll see what
performance I can get from a custom "block" pict. From the pict library's
POV this would reduce the number of picts in my examples from 1000s to 1.

Thanks

Dan

-- 
You received this message because you are subscribed to the Google 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] Speeding up graphics / moving away from 2htdp/image

2017-04-28 Thread Daniel Prager
Thanks Hendrik & Alex

Hendrik:

What you're suggesting sounds to me a lot like what the pict library
already does. Switching to pict would seem to give a good speed-up, but
perhaps it's possible to do better. Hence the benchmarking exercise.

Perhaps make a closure that, when called, does the rendering to dc,
> and treat the closure as a representation for the image?  Then let the
> image and pict combiners operate on the closures to produce more
> closures?



Alex:

I'm using rendering to a bitmap% in the case of the pict library as a proxy
for direct rendering to a dc. I would certainly  render directly if I were
to switch to pict.

Timings vary on the actual layout in Quilt Explorer, depending on block
complexity. The 18 blocks at the bottom of the page are choices in block
layout / shading or color that the user can click on — that's the
"exploring" part.

A "next level" improvement might be something similar to the "virtual dom"
pioneered (or at least popularised) by the react-js folk, to simplify and
reduce the cost of re-rendering.

Dan



On Fri, Apr 28, 2017 at 11:05 PM, Alex Harsanyi <alexharsa...@gmail.com>
wrote:

> On Friday, April 28, 2017 at 6:40:06 PM UTC+8, Daniel Prager wrote:
>
> > The reason is that what I really want to do is more complex layouts, for
> which 2htdp/image or pict combiners make life a lot easier.
>
> The code to convert to bitmap allocates the bitmap and draws to the
> bitmap.  In the actual application you can draw directly to the canvas DC
> in the on-paint method, which would save a bitmap allocation and an
> intermediate draw step.
>
> >
> > Some work-in-progress ...
> >
> > The idea of Quilt Explorer is to use symmetry and randomness, combined
> with some user selection to create original quilt designs.
>
> looking at these designs, I think by the time you're done writing code
> that draws directly to a dc, the code will be just as slow as the pict
> code, and probably with more bugs.
>
> Also, it seems you are rendering about 20 designs on the page.
>
> How long does it take to render an actual quilt design?
>
> Best Regards,
> 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] Speeding up graphics / moving away from 2htdp/image

2017-04-26 Thread Daniel Prager
On Thu, Apr 27, 2017 at 12:34 PM, Vishesh Yadav  wrote:

>
>> BTW: I'm interested in porting to RacketScript. How does the performance
>> of the image library equivalent compare with regular Racket?
>>
>>
> It is slower than regular Racket. I did not spend much time comparing it
> with Racket, and there is definitively scope for improvement. Let us know
> how porting goes.
>

Thanks: it's on my list.

I may try to do some reduced-case benchmarks for a few approaches in
Racket, and for RacketScript.

Dan

-- 
You received this message because you are subscribed to the Google 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] Speeding up graphics / moving away from 2htdp/image

2017-04-26 Thread Daniel Prager
Thank-you all for the suggestions. I'll check them out and report back.

Vishesh: There is some repetition (not animation), but I removed all
caching to simplify and rework the interactive flow. It would be with
trying freeze in conjunction with updated caching.

BTW: I'm interested in porting to RacketScript. How does the performance of
the image library equivalent compare with regular Racket?

Dan

On 26 Apr. 2017 15:30, "Vishesh Yadav" <vishes...@gmail.com> wrote:

Are you repeatedly generating image for an animation inside an event loop?

Depending on the kind of program `freeze` from 2htdp/image may help if you
haven't tried already. For example this[1] program renders faster with
freeze both in RacketScript and 2htdp/image.

[1] http://rapture.twistedplane.com:8080/#example/default

--Vishesh

On Tue, Apr 25, 2017 at 9:09 PM, Daniel Prager <daniel.a.pra...@gmail.com>
wrote:

> Much as I enjoy making images using 2htdp/image it does get a tad slow as
> complexity increases.
>
> I currently have a program in which I generate images in 2htdp/image and
> translate them into bitmap%s per racket/gui and render on canvas%'s via a
> dc.
>
> Speed has become sluggish and I'm going to need to move away from
> 2htdp/image to address this.
>
> A typical image is built up out of lots of above, beside, overlay, square,
> and triangle calls.
>
> Does anyone have a "clever" way to do this programatically (rather than a
> manual re-write with lots of absolute calculations replacing heights and
> widths)?
>
> Many thanks
>
> Dan
>
>
> --
> You received this message because you are subscribed to the Google 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.


[racket-users] Speeding up graphics / moving away from 2htdp/image

2017-04-25 Thread Daniel Prager
Much as I enjoy making images using 2htdp/image it does get a tad slow as
complexity increases.

I currently have a program in which I generate images in 2htdp/image and
translate them into bitmap%s per racket/gui and render on canvas%'s via a
dc.

Speed has become sluggish and I'm going to need to move away from
2htdp/image to address this.

A typical image is built up out of lots of above, beside, overlay, square,
and triangle calls.

Does anyone have a "clever" way to do this programatically (rather than a
manual re-write with lots of absolute calculations replacing heights and
widths)?

Many thanks

Dan

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


Re: [racket-users] How to apply side effects to all elements in a list

2017-03-22 Thread Daniel Prager
Hi Angus

Usually it helps to start by getting something simple to work and then
little-by-little adding more.

E.g. Here's a working example with squares instead of bears, and limited to
just varying rotation ...


#lang racket

(require 2htdp/image)

(define blue-square (square 25 'solid 'blue))

(apply beside
   (for/list ([i 18])
 (rotate (* 20 i) blue-square)))



Dan

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

2017-03-15 Thread Daniel Prager
Bravo Matthew!

Great stuff.

I look forward to buying it and using the payment to help motivate me to
work through *all* the goodness.


Cheers

Dan

-- 
You received this message because you are subscribed to the Google 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] change 'random' contract to allow zero in first position?

2017-03-03 Thread Daniel Prager
On Sat, Mar 4, 2017 at 6:21 AM, John Clements <cleme...@brinckerhoff.org>
wrote:

>
> > On Mar 2, 2017, at 3:00 PM, Daniel Prager <daniel.a.pra...@gmail.com>
> wrote:
> >
> > While we're at it, please allow negative arguments too, to allow for
> cases such as
> >
> > (random -100 100)
>
> Well, that’s different; that’s actually changing the implementation. I’m
> not proposing that…
>
>
The implementation looks fine to me. In pre-base.rkt the relevant lines
should work fine with -ve arguments as long as the inequality constraint
holds. E.g.

(+ x (random (- y x)))  with x=-100, y=100
-> (+ -100 (random 200))

Dan

-- 
You received this message because you are subscribed to the Google 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] change 'random' contract to allow zero in first position?

2017-03-02 Thread Daniel Prager
While we're at it, please allow negative arguments too, to allow for cases
such as

(random -100 100)


Dan

-- 
You received this message because you are subscribed to the Google 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] Client side web applications in Racket

2017-01-22 Thread Daniel Prager
On the client-side framework front, I found some of the lightweight, post
React / post Angular frameworks were easy enough to get going with Urlang,
hence definitely worth a look for RacketScript.

I played mainly with Ractive; vue.js is similar. There are others. The main
seeking point for me was that these frameworks are much quicker and easier
to learn than React and Angular.

Interestingly, the creator of Ractive, Rich Harris, has a new
"framework-less framework" out, sveltejs, which incorporates a compilation
phase to minimise payload.

Dan

On 23 Jan 2017 04:48, "Vishesh Yadav"  wrote:

Hi Stephen,


- is there a JavaScript MVC framework that is suitable to use with
> racketscript? (should I be using react or angular ?)
>

I can not speak for Angular, but I think React should be suitable. You'll
have to use ES5 API instead of classes and JSX, and therefore may want to
build a small layer in between for things to look nicer.


- can I use Racketscrips with racket web applications stuff for the
> backend or am I compiling racketscript to nodejs to run on the server?
>

RacketScript provides a small FFI to interact with JS stuff. You can use
some NodeJS library, to write server-side code. Our Playground[1] client
and server is built entirely using RacketScript.

I would also like to add that RacketScript is not entirely Racket. Our aim
is to preserve Racket semantics as much as possible, but drop expensive
features. Specifically, RacketScript does not implement proper tail calls
(we try to convert self-tail calls to loops) and continuations. Among other
things, we use JS numbers, do not support submodules and make fewer runtime
checks.

Note that RacketScript is  not ready for production use, and is constantly
changing. Therefore, we do not recommend it for anything big and serious at
the moment. Despite that, we encourage developers to try RacketScript and
share their experiences with us.

--Vishesh

[1] https://github.com/vishesh/racketscript-playground


> Thanks again
> On Sun, 22 Jan 2017 at 14:11, Jens Axel Søgaard  > wrote:
>
> Hi Stephen,
>
> If you want to write real Racket on the client side, your best bet
> is to use racketscript.
>
>  https://github.com/vishesh/racketscript
>
> Try it out here:
>
>  http://rapture.twistedplane.com:8080/
>
> Note that tail recursion is not supported.
>
> Urlang as-is will allow you to write JavaScript using S-expression
> syntax and
> also allow you to write macros using the standard Racket tools such as
> syntax-parse.
>
> An example: http://soegaard.github.io/urlang/space-invaders.html
>
> The plan is to use Urlang as backed for a Racket to JavaScript
> compiler,
> but that project [*] is not ready for use yet (I plan to hack on
> this during the
> summer vacation).
>
> [*]
> https://github.com/soegaard/urlang/blob/master/compiler-rjs/
> compiler.rkt
>
>
> Whalesong implements full Racket with tco and correct error reporting.
> The Whalesong compiler only runs on old versions of Racket and Danny
> stopped worked on it years ago.
>
> /Jens Axel
>
>
>
> 2017-01-22 14:13 GMT+01:00 Stephen De Gabrielle
> >:
>
>
> Hi,
>
> What are my options for doing client side web applications in
> Racket ?
>
> I've been getting my head around server side - I can auth a user
> and set a cookie - but I'm not sure what my options for client
> side web apps:
>
> - Should I be using Whalesong and/or Urlang?
> - Is there a right/wrong [WhaleSong | Urlang | JavaScript]
> framework?
> - Can I write both the front and back end in Racket?
> - Is WeScheme a Racket web app?
>
> I'm not sure where to start - the last time I did any
> significant JavaScript it was writing a pong game using the
> adobe svg plugin!
>
> Any feedback/advice appreciated,
>
> Kind regards,
>
> Stephen
>
> --
> Kind regards,
> Stephen
> --
> Bigger than Scheme, cooler than Clojure & more fun than CL.(n=1)
> --
>
> --
> You received this message because you are subscribed to the
> Google 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.
>
>
>
>
> --
> --
> Jens Axel Søgaard
>
> --
> Kind regards,
> Stephen
> --
> Bigger than Scheme, cooler than Clojure & more fun than CL.(n=1)
> --
>
> --
> You received this message because you are subscribed to the Google
> Groups "Racket Users" group.
> To unsubscribe from 

Re: [racket-users] Re: Racket graphics?

2017-01-14 Thread Daniel Prager
> Also, are these links listed in your responses done in Scribble?

Yes: it's standard for Racket documentation.

What would be the novel aspect(s) of your GIS app?

Dan

-- 
You received this message because you are subscribed to the Google 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: Racket graphics?

2017-01-14 Thread Daniel Prager
Lawrence writes
> Could it do diagrams as well as TikZ  ...

For making-TIkz like diagrams check out Jens Axel Søgaard's MetaPict
library. It has as an explicit goal "to narrow the gap between Scribble and
LaTeX + MetaPost/Tikz".

https://soegaard.github.io/docs/metapict/metapict.html


Personally, I get a lot of mileage out of 2htdp/image:



https://docs.racket-lang.org/teachpack/2htdpimage.html



Dan

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


Re: [racket-users] How to write string-match?

2016-12-20 Thread Daniel Prager
Thanks Alexis!

That's such an elegant solution. I'm a little in awe of all the pieces that
you pulled together to make it work.

Fantastic!

In terms of surface syntax, I think that your straight extension to match
is preferable to what I asked for, allowing this sort of thing

  (match s
[(str a "--" b " " c " end") (list (string->symbol a) (string->number
b) c)]
[(str "the " object " is " adjective) (~a adjective " " object)]
[(str "what (" a ") the [" b "] was that?") (list a b)]
[(str "whole-string") 'whole]
[else 'no-match-found]))

On the greediness -- I agree that just allowing regex to do its thing makes
sense -- I gave that restriction with the aim of simplifying the
specification through constraint, but as it turns out it's a hindrance.

I tried several other test cases to try to trip it up, but it's pretty darn
good - nice use of regep-quote, BTW!

When you try patterns like (str "a" "b" c d), for example, its behavior
seems to be the most sensible, although a constraint forcing alternating
strings and ids would arguably make sense.

* * *

It would be great to have this available as a package.

I installed and tried out Alex's match-string package and it does the job,
but as Alex warned it is  "super-slow". Could it be completely
re-engineered to use regexes for performance?

Dan

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


[racket-users] How to write string-match?

2016-12-20 Thread Daniel Prager
While working through many of the puzzles in this year's adventofcode.com I
tend to parse the input with a sequence of string-splits.

This isn't too bad, but What I'd *really* like is a "string-match" form to
more elegantly process structured data, via a few strings based on a simple
(and greedy) left-to-right algorithm.

For example:

(define (sm s)
  (string-match s
[(a "--" b " " c " end") (list (string->symbol a) (string->number b) c)]
[("the " object " is " adjective) (~a adjective " " object)]
[("whole-string") 'whole]
[else 'no-match-found]))

(sm "abc--123 foo end") -> '(abc 123 "foo")
(sm "the fox is black") -> "black fox"
(sm "whole-string") -> 'whole
(sm "abc--123--456 bar end") -> 'no-match-found ; greedy strategy keeps
things simple and explicit



But my macro-fu is too weak.

1. Can someone show me how to write this style of macro?
2. Is this of more general interest?

Dan

-- 
You received this message because you are subscribed to the Google 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: Advent of Code 2016

2016-12-15 Thread Daniel Prager
Hi Matthew

Really nice work, with Wires tutorial and all those AoC DSLs!


Dan

On 14 Dec 2016 14:34, "Matthew Butterick" <m...@mbtype.com> wrote:

I liked last year's Day 7 problem so much, I licensed it from the author
for a Racket DSL tutorial:

http://beautifulracket.com/wires/

This year I’m solving every problem as a DSL. Like cookies for Santa, I
will leave at least one for Benjamin Greenman.

https://github.com/mbutterick/aoc-racket/tree/2016/2016


On Monday, December 12, 2016 at 8:39:48 PM UTC-8, Daniel Prager wrote:
> Is anyone else Racketing their way through www.adventofcode.com this year?
>
> It's worth checking out.
>
> We could even do a "private" leaderboard for Racketeers.
>
> Last year's problems (2015) are still available, and the awesome Matthew
Butterick wrote up his Racket solutions: https://docs.
racket-lang.org/aoc-racket/index.html

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


Re: [racket-users] Animation-problem

2016-12-05 Thread Daniel Prager
My pleasure.

Good on you for doing the exercise.

Here's a slightly modified version that:

   - removes the use of set!: it's cleaner "functional" style to avoid
   mutation where possible
   - illustrates the use of match-define to unpack world
   - other small tweaks and tricks

Dan


#lang racket

(require 2htdp/universe)
(require 2htdp/image)

(struct world (foreground background count))

(define (random-color)
  (make-color (random 255) (random 255) (random 255)))

(define (next-state state)
  (world (random-color)
 (random-color)
 (add1 (world-count state

(define (SUPER state)
  (match-define (world fg bg n) state)
  (overlay/align 'left 'top
 (text (~a n) 30 "gray")
 (overlay (text "SUPER" 105 fg)
  (circle 200 "solid" bg

(big-bang (world (random-color) (random-color) 0)
  (on-tick next-state 0.3)
  (to-draw SUPER))

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

2016-12-04 Thread Daniel Prager
Hi Janiho

This should help get you get going ...

The function big-bang takes minimally:
*  an initial "state of the world",
* a function that  that takes the current world state and evolves it with
every tick of a notional clock, and
* a function that takes the state of the world and draws it.

In this case there's no dependence on the existing state, so the function
random-state ignores what is passed in, but it has the necessary form to
work with big-bang.

Exercise: add a counter to the world state that increments with every tick,
and show this as a number in the top-left corner of the animated image.

Dan


#lang racket

(require 2htdp/universe)
(require 2htdp/image)

(struct world (foreground background))

(define (random-color)
  (make-color (random 255) (random 255) (random 255)))

(define (random-state current)
  (world (random-color) (random-color)))

(define (SUPER state)
  (overlay (text "SUPER" 105 (world-foreground state))
   (circle 200 "solid" (world-background state

(big-bang (random-state null)
  (on-tick random-state 0.3) ; change the image every 0.3 seconds
  (to-draw SUPER))

-- 
You received this message because you are subscribed to the Google 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] Cleanest way to locate contiguous sequences? (as part of reuniting segments of a file)

2016-12-02 Thread Daniel Prager
Perhaps this is a more elegant approach to the tactical problem:
simultaneously iterating over displaced versions of the original list. E.g.

_x '(1 1 2 3   5   7 200 201 202) ; shifted right
x  '(1 2 3 5   7 200 201 202 203) ; original list
x_ '(2 3 5 7 200 201 202 203 203) ; shifted left

When (= (+ _x 1) x (- x_ 1)) we are mid-run. Otherwise we're at the start
or end of a run. Code below.

A further displacement is needed to deal with extended runs: x__ to skip
elements in long runs.


#lang racket

; Given a strictly ascending list of numbers, summarise runs
; (... b b+1 ... b+n c ...) -> (... a b - b+n c ...)
(define (runify xs)
  (define MIN (first xs))
  (define MAX (last xs))
  (for/list ([_x (cons MIN xs)]
 [x xs]
 [x_ (append (rest xs) (list MAX))]
 [x__ (append (drop xs 2) (list MAX MAX))]
 #:unless (= (+ _x 2) x_ (- x__ 1)))
(if (= (+ _x 1) x (- x_ 1))
'-
x)))

; Replace runify-ed lists with lists of lists
; E.g. '(1 - 3 8 12 15 - 100) -> '((1 3) (8) (12) (15 100))
;
(define (chunkify xs [acc null])
  (cond [(null? xs) acc]
[(equal? (first xs) '-)
 (chunkify (drop xs 2)
   (cons (list (caar acc) (second xs))
 (rest acc)))]
[else
 (chunkify (rest xs) (cons (list (first xs)) acc))]))


(define xs '(1 2 3 5 7 200 201 202 203))

(runify xs) ; '(1 - 3 5 7 200 - 203)

(reverse (chunkify (runify xs))) ; '((1 3) (5) (7) (200 203))


* * *

Racket question: How do I define a sequence generator (in-shifted-list xs
shift) to make runify work in true single pass fashion?

I would like to be able to write the following version of runify, without
generating auxiliary lists:

(define (runify-efficient xs)
  (for/list ([_x (in-shifted-list xs -1)]
 [x xs]
 [x_ (in-shifted-list xs 1)]
 [x__ (in-shifted-list xs 2)]
 #:unless (= (+ _x 2) x_ (- x__ 1)))
(if (= (+ _x 1) x (- x_ 1))
'-
x)))

Dan

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

2016-10-29 Thread Daniel Prager
Starting at the very beginning, you could pick up some material on graph
theory, and work through it, while making use of the graph library.

E.g. Here's an introduction to the absolute basics of Graph Theory:

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


And here I've followed along in Racket, figuring out parts of the library
as I go:

#lang racket

(require graph
 math/matrix)

; Define a simple graph
(define g (unweighted-graph/undirected
   '((v1 v2) (v1 v3) (v1 v4) (v4 v5) (v5 v6


; How many vertices are in the graph?
(define (cardinality g)
  (length (get-vertices g)))

(cardinality g)


; How many neighbors does vertex v have?
(define (degree g v)
  (length (get-neighbors g v)))

(degree g 'v1)


; Compute the adjacency list
(define (adjacency-list g)
  (for/list ([v (in-vertices g)])
(list v
  (for/list ([ n (in-neighbors g v)])
n

(adjacency-list g)


; Compute the adjacency matrix
(define (adjacency-matrix g)
  (define card-g (cardinality g))
  (define vertices (for/list ([v (in-vertices g)]) v))
  (build-matrix card-g card-g
(λ (u v)
  (if (has-edge? g (list-ref vertices u) (list-ref vertices
v))
  1 0

(adjacency-matrix g)


; Is the graph actually a tree?
(define (is-tree? g)
  (= (length (get-edges g)); Counts edges twice (in both
directions)
 (* 2 (length (mst-kruskal g)

(is-tree? g)

(define loop (unweighted-graph/undirected '((a b) (a c) (b c
(is-tree? loop)


; Visualize the tree
(displayln (graphviz g))

; Paste output into www.webgraphviz.com to make an image


I hope that's enough to get you started

Dan

-- 
You received this message because you are subscribed to the Google 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] Funtional programming and the maximum of something

2016-10-22 Thread Daniel Prager
> circle of recursion

I reckon "helix of recursion" would be a more helpful image.

Dan

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


  1   2   >