[racket-dev] enum returns #f on c->racket no match?

From: Jon Rafkind (rafkind at cs.utah.edu)
Date: Tue Nov 16 14:05:53 EST 2010

I guess using 'from a known integer' could be slightly misleading since
the base type for the enum could be something other than an _int. I
would prefer the error to mention the enum in the text (I see its in the
error, but its at the front).

"expected a known _my-enum from C"

or something like that

On 11/16/2010 12:02 PM, John Clements wrote:
> 	
> On Nov 15, 2010, at 3:02 PM, John Clements wrote:
>
>> The documentation for '_enum" says this:
>>
>> 3.8 Enumerations and Masks
>>
>> Although the constructors below are describes as procedures, they are implemented as syntax, so that error messages can report a type name where the syntactic context implies one.
>>
>> (_enum symbols [basetype]) → ctype?
>>  symbols : list?
>>  basetype : ctype? = _ufixint
>> Takes a list of symbols and generates an enumeration type. The enumeration maps between a symbol in the given symbols list and corresponding integers, counting from0.
>> The list symbols can also set the values of symbols by putting '= and an exact integer after the symbol. For example, the list '(x y = 10 z) maps 'x to 0, 'y to 10, and 'z to11.
>>
>> The basetype argument specifies the base type to use.
>>
>>
>> This says nothing about what happens when using racket->C on a symbol that's not mentioned by the enumeration, or what happens when using C->racket on a number that's not mentioned in the enumeration. 
>>
>> Based on my tests, it appears that the conversion signals an error in the racket->C direction, but simply returns #f in the C->racket direction.  
>>
>> Should I document the current behavior, or would it make more sense to change it to signal an error rather than returning #f?
> Okay the existing behavior was bothering me because (post-conversion to #f) there's no way to recover the problematic integer.  I therefore changed it so it signals an error instead, like this:
>
> . . . plt/collects/racket/private/more-scheme.rkt:265:2: enum:int->_my-enum: expected a known integer from C, got: 6
>
> That error comes from linking to a file with this C function:
>
> int tester(int x){
>   return x+2;
> }
>
> ... using this racket program:
>
> #lang racket
>
> (require ffi/unsafe)
>
> (define lib (ffi-lib "/tmp/tester.dylib"))
>
> (define _my-enum
>   (_enum 
>    '(chicken = 3
>      monkey = 4
>      duck = 5)))
>
> (define tester
>   (get-ffi-obj "tester" lib (_fun _my-enum -> _my-enum)))
>
>
> (tester 'monkey)
>
>
> ... and finally, here's the diff:
>
> pcp062767pcs:~/plt/collects/ffi clements$ git diff unsafe.rkt
> diff --git a/collects/ffi/unsafe.rkt b/collects/ffi/unsafe.rkt
> index 66fd34a..99e0d7f 100644
> --- a/collects/ffi/unsafe.rkt
> +++ b/collects/ffi/unsafe.rkt
> @@ -765,6 +765,8 @@
>    (define int->sym '())
>    (define s->c
>      (if name (string->symbol (format "enum:~a->int" name)) 'enum->int))
> +  (define c->s
> +    (if name (string->symbol (format "enum:int->~a" name)) 'int->enum))
>    (let loop ([i 0] [symbols symbols])
>      (unless (null? symbols)
>        (let-values ([(i rest)
> @@ -784,7 +786,11 @@
>          (if a
>            (cdr a)
>            (raise-type-error s->c (format "~a" (or name "enum")) x))))
> -    (lambda (x) (cond [(assq x int->sym) => cdr] [else #f]))))
> +    (lambda (x) (cond [(assq x int->sym) => cdr] 
> +                      [else
> +                       (error c->s 
> +                              "expected a known integer from C, got: ~s"
> +                              x)]))))
>  
>  ;; Macro wrapper -- no need for a name
>  (provide _enum)
>
>
> Let me know if it's okay to commit this.  If I don't hear back in a couple of days, I'll just go ahead :).
>
> John 
>
>
>
> _________________________________________________
>   For list-related administrative tasks:
>   http://lists.racket-lang.org/listinfo/dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20101116/945a5e2e/attachment.html>

Posted on the dev mailing list.