Re: [racket-users] raise-argument-error missing list?

2019-07-08 Thread Matthias Felleisen


We all are indeed at Racket school. 

The arguments for/against contracts have been made over and over again 
especially by Betrand Meyers, before we even introduced and studied the 
higher-order boundary-tied variant. 

+ Contracts separate the core functionality of a service module from its 
assumptions. 
+ Contracts can be read separately as API specs ~~ no need to read the code of 
a function/class/method. 
+ Contracts are more concise than manual checks and they are collected in a 
single space. 
+ Contract error messages are systematically generated and readable. 
+ An improvement to the contract system automatically benefits all contracts. 

- Contracts might occasionally impose a small performance overhead over manual 
contracts. (They might also be faster if they can communicate with the 
compiler.) 
- Contract boundaries are somewhat “stiff” as Oak says in his email. 
Contributions for boundary re-factorings in DrRacket are welcome. 

Now you need to choose which dis/advantages you prefer — 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/A8D728B0-3623-4E85-89DD-66ACE67549CA%40felleisen.org.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Snip bug: "should have been overridden context"

2019-07-08 Thread Kshitij Sachan
I'm setting up a very simple snip class that is based on the example in the 
documentation  (
https://docs.racket-lang.org/gui/editor-overview.html#%28part._snip-example%29 
Section 
5.4). 

I was able to generate a snip that is a circle that grows in size when the 
up arrow key is pressed. However, after running the program again for some 
reason I ran into this bug:

error while rendering snip "test-snip":
should have been overridden  context:
   (...higher-order.rkt:364:33 . #f)
   (.../more-scheme.rkt:261:28 . #f)
   (loop . #(struct:srcloc # 2940 6 114655 2217))
   (|do-insertion method in ports-mixin| . #(struct:srcloc 
# 2933 4 114420 2804))
   (#f . #(struct:srcloc # 2926 9 114164 107))
   (#f . #(struct:srcloc # 435 6 19067 1056))
   (#f . #(struct:srcloc # 486 32 21054 120))
   (#f . #(struct:srcloc # 634 3 26076 58))


Here is my code as reference:

;; snip-class
(define test-snip-class
  (make-object
   (class snip-class%
 (super-new)
 (send this set-classname "test-snip"

;; snip stuff
(define scroll-snip%
  (class snip%
(inherit get-admin set-snipclass set-flags)
(init-field [w 50] [h 50])

(super-new)
(set-snipclass test-snip-class)
(send (get-the-snip-class-list) add test-snip-class)
(set-flags (list 'handles-events))

(define/override (get-extent dc x y width height descent space lspace 
rspace)
  (define (maybe-set-box! b v) (when b (set-box! b v)))
(maybe-set-box! width w)
(maybe-set-box! height h)
(maybe-set-box! descent 1.0)
(maybe-set-box! space 1.0)
(maybe-set-box! lspace 1.0)
(maybe-set-box! rspace 1.0))

(define/override (on-char dc x y editorx editory event)
  (cond
[(equal? (send event get-key-code) 'up)
 (define admin (get-admin))
 (set! w (+ 20 w))
 (set! h (+ 20 h))
 (when admin
   (send admin resized this #t))]))

(define/override (draw dc x y left top right bottom dx dy draw-caret)
  (send dc set-brush "red" 'solid)
  (send dc set-pen "black" 3 'solid)
  (send dc draw-ellipse (+ x 1.0) (+ y 1.0) (- w 2) (- h 2)))

(define/override (copy)
  (new scroll-snip%))
))

(new scroll-snip%)

How can I fix this?

-- 
You received this message because you are subscribed to the Google 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/6d8c4a3c-1dbd-4050-a1f4-172363b15e67%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] raise-argument-error missing list?

2019-07-08 Thread Sorawee Porncharoenwase
On Mon, Jul 8, 2019 at 12:56 PM Greg Hendershott rac...@greghendershott.com
 wrote:

- The return value is `any` -- not even `any/c`, just `any`. Effectively
>   don't check the return value(s).
>
If I use define/contract, does any restore tail-recursion?

You could also move some definitions into a sub-module, and contract the
> provide from there.
>
I’m very excited about #:unprotected-submodule

which could generate an unsafe submodule, and let clients pick a version
they want to use. Note that it’s not in Racket 7.3, but presumably is going
to be in Racket 7.4.

In general, though, I wish there are contract exporting combinators. E.g.,
a combinator that suppresses post-condition checking, or a combinator that
approximates a higher-order contract into a first-order contract.
contract-out then can generate multiple submodules with different contracts
according to these combinators.

In any case, the nice thing is that you can use or create any boundary
> you prefer to put the contract on.
>
It’s nice indeed, but I wish switching boundaries could be easier.
Changing (define/contract
...) to (provide (contract-out ...)) (define ...) (and vice versa) is not
fun. A macro that facilitates this switching in the stdlib would be nice.

But in a call chain we can end up verifying a value repeatedly and wouldn’t
it be marvelous if we could somehow pass it’s certification in syntax (no,
I don’t know what I’m talking about, just dreaming) so that verification
would only happen once and when needed?

That’s what Typed Racket does. As I understand, in untyped modules, Racket
also elides pair checking when it’s safe to do so.

Gustavo’s work-in-progress addition to the Chez Scheme compiler introduces
the kinds of optimizations that he has long built and maintained in the
current Racket implementation. For example, (f (car x) (cdr x)) can be
optimized to (f (car x) (unsafe-cdr x)). These optimizations are
particularly helpful for structure-field access and update, and preliminary
measurements suggest that the optimizations can provide about half of the
performance benefit of unsafe mode (so, typically 5-10%) without the
unsafety.

But yes, eliding contract checks in general is my dream as well.

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


Re: [racket-users] raise-argument-error missing list?

2019-07-08 Thread Greg Hendershott
I'll chime in only because some of the usual suspects who could best
answer this might be busy with the Racket summer school this week.


I believe that function contracts can be about as fast as the sort of
checks you'd code by hand, provided that:

- The parameter contracts are simple, flat, first-order predicates like
  `string?` and combinators thereof like `(or/c number? string?)` or
  `(and/c number? positive?)`.

- The return value is `any` -- not even `any/c`, just `any`. Effectively
  don't check the return value(s).

If callers already have contracts that will check the value as it is
used, then maybe the only thing a non-`any` return value contract would
get you is more precise blame in the error message. Whether that is
worth the probably somewhat slower speed, is your choice.


If you want the contact to protect the function itself, not merely
as-provided by a module, you can use `define/contract`.

You could also move some definitions into a sub-module, and contract the
provide from there.

In any case, the nice thing is that you can use or create any boundary
you prefer to put the contract 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/87tvbwpafx.fsf%40greghendershott.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] [racet-userx] Syntax Class Question

2019-07-08 Thread Kevin Forchione


> On Jul 8, 2019, at 10:50 AM, David Storrs  wrote:
> 
> 
> 
> On Mon, Jul 8, 2019 at 12:59 PM Kevin Forchione  > wrote:
> Hi guys, 
> I’ve noticed that the library provides *some* syntax classes: id, str, char, 
> expo… for various datatypes, but not all. Obviously being such a handy aspect 
> of syntax-parse there’s probably a reason for this. Having spent a few days 
> trying to roll my own for procedure I have to suspect this isn’t a simple 
> thing. 
> 
> What’s the rationale in not reprinting them? 
> 
> Mat.* and/or others will be able to answer this more definitively, but I 
> suspect the issue is that syntax-parse works at phase 1, a macro-expansion 
> (similar to "compile time") phase, as opposed to runtime.  As a result, the 
> thing that will be in that slot is an sexp like (lambda (x) x) instead of a 
> #.  It's easy to tell that the sexp is not an identifier, string, 
> etc, but determining if it will produce a # requires actually 
> evaluating it -- what if it was (and foo bar) or (* x 9) instead of (lambda 
> (x) x)?

Yes, that’s been one of my thoughts well. For example, if it’s an identifier I 
can use syntax-case and a guard to check for identifier-binding, but the lambda 
case seems to mean interrogating the syntax for lambda, or relying on some 
syntactical structure pattern and then dealing with it later in a function. 

It’s a matter of control. I’m constantly being amazed at how rich the 
mechanisms are for manipulating syntax. And never surprised when there’s a 
better way to do it. The Racket development team have created something truly 
remarkable. 

Kevin

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


Re: [racket-users] raise-argument-error missing list?

2019-07-08 Thread Kevin Forchione


> On Jul 8, 2019, at 10:41 AM, David Storrs  wrote:
> 
> Nothing specific that I'm aware of, but others could answer this better.  If 
> there are then they're probably related to speed.
> 
> Personally, I'm quite fond of them because they eliminate the need for a lot 
> of tests and make the code much more self-documenting.
> 
> Function contracts are detailed here: 
> https://docs.racket-lang.org/reference/function-contracts.html 
>   In the 
> left-hand navbar you'll see a bunch of related topics, like data-structure 
> contracts.

That would be my suspicion. I suppose it’s an art form balancing the checking 
with the speed checks. For instance, I’ve used contracts in the provide 
statement, and as I’ve noted in various places in the documentation (and my own 
experience) they only guard the boundaries of whatever they’d are associated 
with. But in a call chain we can end up verifying a value repeatedly and 
wouldn’t it be marvelous if we could somehow pass it’s certification in syntax 
(no, I don’t know what I’m talking about, just dreaming) so that verification 
would only happen once and when needed? 

Kevin

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/D3D604D5-458B-4CA2-9161-47BFD9D0F54A%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] [racet-userx] Syntax Class Question

2019-07-08 Thread David Storrs
On Mon, Jul 8, 2019 at 12:59 PM Kevin Forchione  wrote:

> Hi guys,
> I’ve noticed that the library provides *some* syntax classes: id, str,
> char, expo… for various datatypes, but not all. Obviously being such a
> handy aspect of syntax-parse there’s probably a reason for this. Having
> spent a few days trying to roll my own for procedure I have to suspect this
> isn’t a simple thing.
>
> What’s the rationale in not reprinting them?
>

Mat.* and/or others will be able to answer this more definitively, but I
suspect the issue is that syntax-parse works at phase 1, a macro-expansion
(similar to "compile time") phase, as opposed to runtime.  As a result, the
thing that will be in that slot is an sexp like (lambda (x) x) instead of a
#.  It's easy to tell that the sexp is not an identifier,
string, etc, but determining if it will produce a # requires
actually evaluating it -- what if it was (and foo bar) or (* x 9) instead
of (lambda (x) x)?



> Kevin
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/A1BC76B6-B8FA-4A4C-8A66-A2D467EE511A%40gmail.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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAE8gKof4Ty-yMd6tkBGb1oD4Nz1i-gPHvs-NruYodRuT54Qu7g%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] raise-argument-error missing list?

2019-07-08 Thread David Storrs
Nothing specific that I'm aware of, but others could answer this better.
If there are then they're probably related to speed.

Personally, I'm quite fond of them because they eliminate the need for a
lot of tests and make the code much more self-documenting.

Function contracts are detailed here:
https://docs.racket-lang.org/reference/function-contracts.html  In the
left-hand navbar you'll see a bunch of related topics, like data-structure
contracts.


On Mon, Jul 8, 2019 at 1:28 PM Kevin Forchione  wrote:

>
>
> On Jul 8, 2019, at 8:17 AM, David Storrs  wrote:
>
> Note that in many cases it can be better to use a contract as opposed to
> an explicit check.  For example, you could replace this:
>
> (define (feed-animals cow sheep goose cat)
> (if (not (eq? goose 'goose))
>   (raise-argument-error 'feed-animals "'goose" 2 cow sheep goose cat)
>   "fed the animals"))
>
> With this, which is precisely equivalent:
>
> (define/contract (feed-animals cow sheep goose cat)
>(-> any/c any/c 'goose any/c any)
> "fed the animals")
>
>
> Or maybe you want to verify that neither cow, sheep, nor cat are also
> goose:
>
> (define/contract (feed-animals cow sheep goose cat)
>(-> (not/c 'goose) (not/c 'goose) 'goose (not/c 'goose) any)
> "fed the animals")
>
> Or, maybe you can accept either a symbol or a string for goose:
>
> (define/contract (feed-animals cow sheep goose cat)
>(-> any/c any/c (or/c 'goose "goose") any/c any)
> "fed the animals")
>
> Or maybe do that case-insensitively (I'm getting rid of the excess
> arguments for brevity):
>
> (define/contract (feed-animals goose)
>(-> (compose1 (curry string-ci=? "goose") ~a) any)
> "fed the animals")
>
> Same as above, but let's insist that the return value be a non-empty
> string:
>
> (define/contract (feed-animals goose)
>(-> (compose1 (curry string-ci=? "goose") ~a) non-empty-string?)
> "fed the animals")
>
> If you really want to get nuts then you can do all kinds of inter-argument
> checking in a contract.  Here's an actual contract that I use in my
> database layer, for the 'upsert-rows' function:
>
> (define symbol-string? (or/c symbol? string?))
> (define false-or-unsupplied? (or/c false? unsupplied-arg?))
>
> (define/contract (upsert-rows #:table table-name
>   #:rows  rows
>   #:conflict-clause   conflict-clause
>   #:db[conn #f]
>   #:fields-to-update  [fields-to-update #f]
>   )
>   (->i (#:table   [table symbol-string?]
> #:rows[rows (or/c  (hash/c symbol-string? any/c)
>(listof (hash/c symbol-string?
> any/c)))]
> #:conflict-clause [conflict-clause (or/c #f 'FAIL symbol-string?)]
> ; 'FAIL is redundant with `symbol-string?`. It's there for clarity.
> )
>(
> #:db [db connection?]
> #:fields-to-update   [fields-to-update (or/c #f (non-empty-listof
> symbol-string?))]
> )
>; If conflict clause is 'FAIL then fields-to-update must be #f or
> unsupplied
>; If conflict clause is #f then fields-to-update must be #f or
> unsupplied
>; If conflict clause is NOT #f then fields-to-update must be a list
>
>#:pre (conflict-clause fields-to-update)
>(or  (and (equal? 'FAIL conflict-clause)
>  (false-or-unsupplied? fields-to-update))
> (and (false? conflict-clause) (false-or-unsupplied?
> fields-to-update))
> (and conflict-clause (list? fields-to-update)))
>any)
> ...code…)
>
>
> Thanks, David! I’ll have to look into using contracts in my code. Are
> there any downsides to contracts over the raising an error?
>
> Kevin
>
>

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


Re: [racket-users] raise-argument-error missing list?

2019-07-08 Thread Kevin Forchione


> On Jul 8, 2019, at 8:17 AM, David Storrs  wrote:
> 
> Note that in many cases it can be better to use a contract as opposed to an 
> explicit check.  For example, you could replace this:
> 
> (define (feed-animals cow sheep goose cat)
> (if (not (eq? goose 'goose))
>   (raise-argument-error 'feed-animals "'goose" 2 cow sheep goose cat)
>   "fed the animals"))
> 
> With this, which is precisely equivalent:
> 
> (define/contract (feed-animals cow sheep goose cat)
>(-> any/c any/c 'goose any/c any)
> "fed the animals")
> 
> 
> Or maybe you want to verify that neither cow, sheep, nor cat are also goose:
> 
> (define/contract (feed-animals cow sheep goose cat)
>(-> (not/c 'goose) (not/c 'goose) 'goose (not/c 'goose) any)
> "fed the animals")
> 
> Or, maybe you can accept either a symbol or a string for goose:
> 
> (define/contract (feed-animals cow sheep goose cat)
>(-> any/c any/c (or/c 'goose "goose") any/c any)
> "fed the animals")
> 
> Or maybe do that case-insensitively (I'm getting rid of the excess arguments 
> for brevity):
> 
> (define/contract (feed-animals goose)
>(-> (compose1 (curry string-ci=? "goose") ~a) any)
> "fed the animals")
> 
> Same as above, but let's insist that the return value be a non-empty string:
> 
> (define/contract (feed-animals goose)
>(-> (compose1 (curry string-ci=? "goose") ~a) non-empty-string?)
> "fed the animals")
> 
> If you really want to get nuts then you can do all kinds of inter-argument 
> checking in a contract.  Here's an actual contract that I use in my database 
> layer, for the 'upsert-rows' function:
> 
> (define symbol-string? (or/c symbol? string?))
> (define false-or-unsupplied? (or/c false? unsupplied-arg?))
> 
> (define/contract (upsert-rows #:table table-name
>   #:rows  rows
>   #:conflict-clause   conflict-clause
>   #:db[conn #f]
>   #:fields-to-update  [fields-to-update #f]
>   )
>   (->i (#:table   [table symbol-string?]
> #:rows[rows (or/c  (hash/c symbol-string? any/c)
>(listof (hash/c symbol-string? 
> any/c)))]
> #:conflict-clause [conflict-clause (or/c #f 'FAIL symbol-string?)] ; 
> 'FAIL is redundant with `symbol-string?`. It's there for clarity.
> )
>(
> #:db [db connection?]
> #:fields-to-update   [fields-to-update (or/c #f (non-empty-listof 
> symbol-string?))]
> )
>; If conflict clause is 'FAIL then fields-to-update must be #f or 
> unsupplied   
>; If conflict clause is #f then fields-to-update must be #f or 
> unsupplied  
>; If conflict clause is NOT #f then fields-to-update must be a list
> 
>#:pre (conflict-clause fields-to-update)
>(or  (and (equal? 'FAIL conflict-clause)
>  (false-or-unsupplied? fields-to-update))
> (and (false? conflict-clause) (false-or-unsupplied? 
> fields-to-update))
> (and conflict-clause (list? fields-to-update)))
>any)
> ...code…)

Thanks, David! I’ll have to look into using contracts in my code. Are there any 
downsides to contracts over the raising an error? 

Kevin

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


[racket-users] [racet-userx] Syntax Class Question

2019-07-08 Thread Kevin Forchione
Hi guys, 
I’ve noticed that the library provides *some* syntax classes: id, str, char, 
expo… for various datatypes, but not all. Obviously being such a handy aspect 
of syntax-parse there’s probably a reason for this. Having spent a few days 
trying to roll my own for procedure I have to suspect this isn’t a simple 
thing. 

What’s the rationale in not reprinting them? 

Kevin

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


Re: [racket-users] raise-argument-error missing list?

2019-07-08 Thread David Storrs
Staircase thought:  I shouldn't have said 'precisely equivalent' since the
text of the error message may differ.  'Semantically equivalent' is more
correct.

On Mon, Jul 8, 2019 at 11:17 AM David Storrs  wrote:

> Note that in many cases it can be better to use a contract as opposed to
> an explicit check.  For example, you could replace this:
>
> (define (feed-animals cow sheep goose cat)
> (if (not (eq? goose 'goose))
>   (raise-argument-error 'feed-animals "'goose" 2 cow sheep goose cat)
>   "fed the animals"))
>
> With this, which is precisely equivalent:
>
> (define/contract (feed-animals cow sheep goose cat)
>(-> any/c any/c 'goose any/c any)
> "fed the animals")
>
>
> Or maybe you want to verify that neither cow, sheep, nor cat are also
> goose:
>
> (define/contract (feed-animals cow sheep goose cat)
>(-> (not/c 'goose) (not/c 'goose) 'goose (not/c 'goose) any)
> "fed the animals")
>
> Or, maybe you can accept either a symbol or a string for goose:
>
> (define/contract (feed-animals cow sheep goose cat)
>(-> any/c any/c (or/c 'goose "goose") any/c any)
> "fed the animals")
>
> Or maybe do that case-insensitively (I'm getting rid of the excess
> arguments for brevity):
>
> (define/contract (feed-animals goose)
>(-> (compose1 (curry string-ci=? "goose") ~a) any)
> "fed the animals")
>
> Same as above, but let's insist that the return value be a non-empty
> string:
>
> (define/contract (feed-animals goose)
>(-> (compose1 (curry string-ci=? "goose") ~a) non-empty-string?)
> "fed the animals")
>
> If you really want to get nuts then you can do all kinds of inter-argument
> checking in a contract.  Here's an actual contract that I use in my
> database layer, for the 'upsert-rows' function:
>
> (define symbol-string? (or/c symbol? string?))
> (define false-or-unsupplied? (or/c false? unsupplied-arg?))
>
> (define/contract (upsert-rows #:table table-name
>   #:rows  rows
>   #:conflict-clause   conflict-clause
>   #:db[conn #f]
>   #:fields-to-update  [fields-to-update #f]
>   )
>   (->i (#:table   [table symbol-string?]
> #:rows[rows (or/c  (hash/c symbol-string? any/c)
>(listof (hash/c symbol-string?
> any/c)))]
> #:conflict-clause [conflict-clause (or/c #f 'FAIL symbol-string?)]
> ; 'FAIL is redundant with `symbol-string?`. It's there for clarity.
> )
>(
> #:db [db connection?]
> #:fields-to-update   [fields-to-update (or/c #f (non-empty-listof
> symbol-string?))]
> )
>; If conflict clause is 'FAIL then fields-to-update must be #f or
> unsupplied
>; If conflict clause is #f then fields-to-update must be #f or
> unsupplied
>; If conflict clause is NOT #f then fields-to-update must be a list
>
>#:pre (conflict-clause fields-to-update)
>(or  (and (equal? 'FAIL conflict-clause)
>  (false-or-unsupplied? fields-to-update))
> (and (false? conflict-clause) (false-or-unsupplied?
> fields-to-update))
> (and conflict-clause (list? fields-to-update)))
>any)
> ...code...)
>
>
>
>
>
> On Fri, Jul 5, 2019 at 1:49 PM Kevin Forchione  wrote:
>
>> Hi guys,
>> Been adding raise-argument-error to my functions to catch errors and have
>> noticed that the 2nd version of the form doesn’t actually list the other
>> arguments - even for the example in the docs:
>>
>> >(define (feed-animals cow sheep goose cat)
>> (if (not (eq? goose 'goose))
>>   (raise-argument-error 'feed-animals "'goose" 2 cow sheep goose cat)
>>   "fed the animals"))
>> >(feed-animals 'cow 'sheep 'dog ‘cat)
>>
>> . . feed-animals: contract violation
>>   expected: 'goose
>>   given: 'dog
>>   argument position: 3rd
>>   other arguments...:
>> >
>>
>> Is this form recommended? I’ve noticed that the documentation says some
>> of the error forms have been deprecated.
>>
>> -Kevin
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Racket Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to racket-users+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/racket-users/91E9AD52-8F17-4BC3-98AB-5E43FFABC9DF%40gmail.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.
To view this discussion on the web visit 

Re: [racket-users] raise-argument-error missing list?

2019-07-08 Thread David Storrs
Note that in many cases it can be better to use a contract as opposed to an
explicit check.  For example, you could replace this:

(define (feed-animals cow sheep goose cat)
(if (not (eq? goose 'goose))
  (raise-argument-error 'feed-animals "'goose" 2 cow sheep goose cat)
  "fed the animals"))

With this, which is precisely equivalent:

(define/contract (feed-animals cow sheep goose cat)
   (-> any/c any/c 'goose any/c any)
"fed the animals")


Or maybe you want to verify that neither cow, sheep, nor cat are also goose:

(define/contract (feed-animals cow sheep goose cat)
   (-> (not/c 'goose) (not/c 'goose) 'goose (not/c 'goose) any)
"fed the animals")

Or, maybe you can accept either a symbol or a string for goose:

(define/contract (feed-animals cow sheep goose cat)
   (-> any/c any/c (or/c 'goose "goose") any/c any)
"fed the animals")

Or maybe do that case-insensitively (I'm getting rid of the excess
arguments for brevity):

(define/contract (feed-animals goose)
   (-> (compose1 (curry string-ci=? "goose") ~a) any)
"fed the animals")

Same as above, but let's insist that the return value be a non-empty string:

(define/contract (feed-animals goose)
   (-> (compose1 (curry string-ci=? "goose") ~a) non-empty-string?)
"fed the animals")

If you really want to get nuts then you can do all kinds of inter-argument
checking in a contract.  Here's an actual contract that I use in my
database layer, for the 'upsert-rows' function:

(define symbol-string? (or/c symbol? string?))
(define false-or-unsupplied? (or/c false? unsupplied-arg?))

(define/contract (upsert-rows #:table table-name
  #:rows  rows
  #:conflict-clause   conflict-clause
  #:db[conn #f]
  #:fields-to-update  [fields-to-update #f]
  )
  (->i (#:table   [table symbol-string?]
#:rows[rows (or/c  (hash/c symbol-string? any/c)
   (listof (hash/c symbol-string?
any/c)))]
#:conflict-clause [conflict-clause (or/c #f 'FAIL symbol-string?)]
; 'FAIL is redundant with `symbol-string?`. It's there for clarity.
)
   (
#:db [db connection?]
#:fields-to-update   [fields-to-update (or/c #f (non-empty-listof
symbol-string?))]
)
   ; If conflict clause is 'FAIL then fields-to-update must be #f or
unsupplied
   ; If conflict clause is #f then fields-to-update must be #f or
unsupplied
   ; If conflict clause is NOT #f then fields-to-update must be a list

   #:pre (conflict-clause fields-to-update)
   (or  (and (equal? 'FAIL conflict-clause)
 (false-or-unsupplied? fields-to-update))
(and (false? conflict-clause) (false-or-unsupplied?
fields-to-update))
(and conflict-clause (list? fields-to-update)))
   any)
...code...)





On Fri, Jul 5, 2019 at 1:49 PM Kevin Forchione  wrote:

> Hi guys,
> Been adding raise-argument-error to my functions to catch errors and have
> noticed that the 2nd version of the form doesn’t actually list the other
> arguments - even for the example in the docs:
>
> >(define (feed-animals cow sheep goose cat)
> (if (not (eq? goose 'goose))
>   (raise-argument-error 'feed-animals "'goose" 2 cow sheep goose cat)
>   "fed the animals"))
> >(feed-animals 'cow 'sheep 'dog ‘cat)
>
> . . feed-animals: contract violation
>   expected: 'goose
>   given: 'dog
>   argument position: 3rd
>   other arguments...:
> >
>
> Is this form recommended? I’ve noticed that the documentation says some of
> the error forms have been deprecated.
>
> -Kevin
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/91E9AD52-8F17-4BC3-98AB-5E43FFABC9DF%40gmail.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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAE8gKofEpCP%3DbtqZp6EFzvy2eUe-UYDbZXnq26%3DKRs8OeWX-CA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] What's wrong with my code?

2019-07-08 Thread 曹朝
Alright, thank you very much.

在 2019年7月8日星期一 UTC+8上午3:50:18,Matthias Felleisen写道:
>
>
> With some for/loops in TR you’re out of luck. The expansion are too 
> complex to type-check easily. 
>
>
> On Jul 7, 2019, at 10:24 AM, 曹朝 > wrote:
>
> This is a simple algorithm for compute the shortest edit distance, it can 
> work with `#lang racket/base`.
> But in Typed Racket, I just got the error message: "insufficient type 
> information to typecheck". I don't know why this code can't pass the type 
> checker.
> Someone can help? Thank you.
>
> #lang typed/racket/base
> (require math/array)
>
> (: shortest-edit-distance (-> String String Integer))
> (define (shortest-edit-distance str0 str1)
> (let* ([l0 : Integer (string-length str0)]
>[l1 : Integer (string-length str1)]
>[table : (Mutable-Array Integer) (array->mutable-array (make-array 
> (vector l0 l1) 0))])
>   (for*/last : Integer ([i0 : Integer (in-range l0)]
> [i1 : Integer (in-range l1)])
> (let* ([c0 : Char (string-ref str0 i0)]
>[c1 : Char (string-ref str1 i1)]
>[base : Integer (cond
>  [(and (= i0 0) (= i1 0)) 0]
>  [(= i0 0) (array-ref table (vector i0 (sub1 
> i1)))]
>  [(= i1 0) (array-ref table (vector (sub1 i0) 
> i1))]
>  [else (min (array-ref table (vector i0 (sub1 
> i1)))
> (array-ref table (vector (sub1 i0) 
> i1))
> (array-ref table (vector (sub1 i0) 
> (sub1 i1])]
>[answer : Integer (if (char=? c0 c1) base (add1 base))])
>
>   (array-set! table (vector i0 i1) answer)
>   answer
>
> <截屏2019-07-0800.15.13.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...@googlegroups.com .
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/1fa2f544-9f60-4e00-a451-b42b1e4f5b0f%40googlegroups.com
>  
> 
> .
> For more options, visit https://groups.google.com/d/optout.
> <截屏2019-07-0800.15.13.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/b9998370-acae-47af-8672-4798fdaace20%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.