Paste: expectations version 1

Author: randy7
Mode: factor
Date: Sat, 21 Feb 2009 17:22:42
Plain Text |
! proof of concept version
! purpose: to know that the structure you expected for the item is indeed equal to it.
! this helps in debugging. to turn on, do: t expect? set-global
! if you turn this off, the compiler should be able to ignore it (2dup 2drop) and optimize it out.
! you have two usages: 1) item  +expected-type+ expect
!                      2) item1 item2  { +type1+ +type2+ } expecting
! you don't have to duplicate your stack items before usage. just put it anywhere inside your code.
! I thought this idea would be cool, if you have suggestions help me understand them and I'll be happy to hear :)
! if there are errors/bugs please annotate so i'd know.

USING:  namespaces kernel sequences combinators io math arrays 
        generalizations combinators.short-circuit ;
IN: expectations
SINGLETONS: +int+ +float+ +seq+ +pair+ +1pair-seq+ +hash+ +vector+ ; 

! note: would it be wiser to have a generic method,
! with defs, so they don't have to be defined in one place? (need to learn more for that)

! if yes, maybe use parsing/meta features to make a singleton, a generic method with the supplied definition,
! and automatically build the case statement. (from a global seq containing singletons names)

ERROR: expectation-failed item expected ;
ERROR: no-such-singleton singleton ;


SYMBOL: expect?
expect? [ f ] initialize


: expect-result ( singleton item ? -- )
    [ 
        2drop  ! "all is well" print 
    ] [ expectation-failed ] if ;

! =======
: just-one ( seq -- ? )
    length 1 = ;
    
: int-def ( x -- ? ) integer? ; inline
: pair-def ( x -- ? ) 
    {   [ sequence? ]
        [ array? ] 
        [ length 2 = ] 
        [ [ integer? ] all? ]
    } 1&& ; inline
: 1pair-seq-def ( x -- ? ) { [ sequence? ] [ just-one ] [ [ pair-def ] all? ] } 1&& ;  
: pairs-seq-def ( x -- ? ) { [ sequence? ] [ [ pair-def ] all? ] } 1&& ;
    
: seq-def ( x -- ? )
    sequence? ; inline
: float-def ( x -- ? ) float? ; inline
    
! =======    
: do-expect ( item expected -- )
    2dup {
            { +int+  [ int-def ] }
            { +pair+ [ pair-def ] } 
            { +seq+ [ seq-def ] }
            { +float+ [ float-def ] }
            [ dup "no such singleton, please create one and its definition, and add to the case statement." print 
                no-such-singleton ]
         } case expect-result ;

: expect ( item expected -- )
        expect? get-global 
        [ do-expect ] [ 2drop ] if ;
        
: expecting ( objs... singletons-seq -- )
    [ [ expect ] curry ] map
    dup length [ ndup ] curry dip
    spread ; 

! some examples:
! 2 +int+ expect
! 34 56 { "sequence" } { +int+ +int+ +seq+ } expecting
    

Annotation: predicates

Author: me
Mode: factor
Date: Sat, 21 Feb 2009 22:58:59
Plain Text |
note to self: use predicates

it's still useful. predicates will be the definitions, and the way to state what kind the item is.
throw singletons away.
they can be built from any code.
perhaps there is a list of all predicates, so the case statement of do-expect will potentially be built automatically.
predicate, and predicate ask word. { pair [ pair? ] }
etc.
.... get acquainted with the introspection features to generate or get something like this. maybe it's a simple 'instance?>>'

New Annotation

Summary:
Author:
Mode:
Body: