www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit aa72ace7f55b0acfb16ec8b509bca226920d475a
parent d87b895cb1f0fcb8cb3e9ab38882a49c77399e1c
Author: Georges Dupéron <georges.duperon@gmail.com>
Date:   Thu, 12 Jan 2017 21:18:16 +0100

Split package to avoid dependency on aful for just the lib itself

Diffstat:
M.gitignore | 2+-
M.travis.yml | 6+++---
Dinfo.rkt | 17-----------------
Dscribblings/typed-map.scrbl | 113-------------------------------------------------------------------------------
Atyped-map-doc/info.rkt | 14++++++++++++++
Atyped-map-doc/scribblings/typed-map.scrbl | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
RLICENSE.txt -> typed-map-lib/LICENSE.txt | 0
RREADME.md -> typed-map-lib/README.md | 0
Atyped-map-lib/info.rkt | 11+++++++++++
Rmain.rkt -> typed-map-lib/main.rkt | 0
Atyped-map-test/info.rkt | 12++++++++++++
Rtest/test-map.rkt -> typed-map-test/test/test-map.rkt | 0
Atyped-map/info.rkt | 13+++++++++++++
13 files changed, 167 insertions(+), 134 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -3,4 +3,4 @@ .\#* .DS_Store compiled/ -/doc/ +/*/doc/ diff --git a/.travis.yml b/.travis.yml @@ -42,7 +42,7 @@ before_install: - export PATH="${RACKET_DIR}/bin:${PATH}" #install-racket.sh can't set for us install: - - raco pkg install -j 1 --deps search-auto + - raco pkg install -j 1 --deps search-auto ./typed-map ./typed-map-lib ./typed-map-test before_script: @@ -50,8 +50,8 @@ before_script: # `raco pkg install --deps search-auto` to install any required # packages without it getting stuck on a confirmation prompt. script: - - raco test -p typed-map - - raco setup --check-pkg-deps --pkgs typed-map + - raco test -p typed-map typed-map-lib typed-map-test + - raco setup --check-pkg-deps --pkgs typed-map typed-map-lib typed-map-test - raco pkg install --deps search-auto doc-coverage - raco doc-coverage typed-map diff --git a/info.rkt b/info.rkt @@ -1,17 +0,0 @@ -#lang info -(define collection "typed-map") -(define deps '("base" - "rackunit-lib" - "typed-racket-lib" - "typed-racket-more")) -(define build-deps '("scribble-lib" - "racket-doc" - "aful" - "typed-racket-doc")) -(define scribblings '(("scribblings/typed-map.scrbl" ()))) -(define pkg-desc - (string-append "Type inference helper for map with Typed/Racket." - " Supports afl, un-annotated lambdas and polymorphic" - " functions.")) -(define version "1.0") -(define pkg-authors '("Georges Dupéron")) diff --git a/scribblings/typed-map.scrbl b/scribblings/typed-map.scrbl @@ -1,112 +0,0 @@ -#lang scribble/manual -@require[scribble/example - @for-label[typed-map]] - -@title{typed-map} -@author[@author+email["Georges Dupéron" "georges.duperon@gmail.com"]] - -@(module orig racket/base - (require scribble/manual - (for-label racket/base)) - (provide orig:map orig:foldl orig:foldr) - (define orig:map @racket[map]) - (define orig:foldl @racket[foldl]) - (define orig:foldr @racket[foldr])) -@(require 'orig) - -@defmodule[typed-map] - -@defproc[#:kind "syntax" - (map [f (→ A ... B)] [l (Listof A)] ...) (Listof B)]{ - Like @orig:map from @racketmodname[typed/racket/base], but with better type - inference for Typed Racket. - - When @racket[f] is a literal lambda of the form - @racket[(λ (arg ...) body ...)], it is not necessary to specify the type of - the arguments, as they will be inferred from the list. - - @examples[#:eval ((make-eval-factory '(typed-map) #:lang 'typed/racket)) - (map (λ (x) (* x 2)) '(1 2 3)) - (let ([l '(4 5 6)]) - (map (λ (x) (* x 2)) l))] - - This enables the use of @racket[#,(hash-lang) #,(racketmodname afl)] for - @racket[map] in Typed Racket. - - Furthermore, when @racket[f] is a polymorphic function, type annotations are - not needed: - - @examples[#:eval ((make-eval-factory '(typed-map) #:lang 'typed/racket)) - (map car '([a . 1] [b . 2] [c . 3]))] - - Compare this with the behaviour of @orig:map from - @racketmodname[racket/base], which generates a type error: - - @examples[#:eval ((make-eval-factory '() #:lang 'typed/racket)) - (eval:alts (#,orig:map car '([a . 1] [b . 2] [c . 3])) - (eval:error (map car '([a . 1] [b . 2] [c . 3]))))] - - When used as an identifier, the @racket[map] macro expands to the original - @orig:map from @racketmodname[typed/racket/base]: - - @examples[#:eval ((make-eval-factory '(typed-map) #:lang 'typed/racket)) - (eval:alts (require (only-in racket/base [#,orig:map orig:map])) - (require (only-in racket/base [map orig:map]))) - (equal? map orig:map)] - - Note that the implementation expands to a large expression, and makes use of - @racket[set!] internally to build the result list. The trick used proceeds as - follows: - @itemlist[ - @item{It uses @racket[(reverse (reverse l))] to generalise the type of the - list, without having to express that type, so that Type / Racket infers a - more general type of the form @racket[(Listof A)], without detecting that the - output is identical to the input. An unoptimizable guard prevents the - double-reverse from actually being executed, so it does not incur a - performance cost.} - @item{It uses a - @seclink["Named_let" #:doc '(lib "scribblings/guide/guide.scrbl")]{named - @racket[let]} to perform the loop. The function @racket[f] is never passed - as an argument to another polymorphic function, and is instead directly - called with the appropriate arguments. The error message ``Polymorphic - function `map' could not be applied to arguments'' is therefore not raised.} - @item{To have the most precise and correct types, it uses a named let with a - single variable containing the list (with the generalized type). An outer let - binds a mutable accumulator, initialized with a single-element list - containing the result of applying @racket[f] on the first element of the - list. Since all elements of the list belong to the generalized type, the - result of calling @racket[f] on any element has the same type, therefore the - accumulator has the type @racket[(Listof B)], where @racket[B] is the - inferred type of the result of @racket[f].}]} - - -@defproc[#:kind "syntax" - (foldl [f (→ A ... Acc Acc)] [init Acc] [l (Listof A)] ...) Acc]{ - Like @orig:foldl from @racketmodname[typed/racket/base] but with better type - inference for Typed Racket. - - This form is implemented in the same way as the overloaded version of - @racket[map] presented above. - - Note that in some cases, the type for the accumulator is not generalised - enough based on the result of the first iteration, in which cases annotations - are needed: - - @examples[#:eval ((make-eval-factory '(typed-map) #:lang 'typed/racket)) - (eval:error (foldl (λ (x acc) (cons acc (add1 x))) '() '(1 2 3))) - (foldl (λ (x [acc : (Rec R (U Null (Pairof R Positive-Index)))]) - (cons acc (add1 x))) - '() - '(1 2 3))]} - -@defproc[#:kind "syntax" - (foldr [f (→ A ... Acc Acc)] [init Acc] [l (Listof A)] ...) Acc]{ - Like @orig:foldr from @racketmodname[typed/racket/base] but with better type - inference for Typed Racket. - - This form is implemented in the same way as the overloaded version of - @racket[map] presented above. - - Note that in some cases, the type for the accumulator is not generalised - enough based on the result of the first iteration, in which cases annotations - are needed. See the example given for @racket[foldl].} -\ No newline at end of file diff --git a/typed-map-doc/info.rkt b/typed-map-doc/info.rkt @@ -0,0 +1,14 @@ +#lang info +(define collection "typed-map") +(define deps '("base")) +(define build-deps '("scribble-lib" + "racket-doc" + "typed-racket-doc")) +(define scribblings '(("scribblings/typed-map.scrbl" ()))) +(define pkg-desc + (string-append "Documentation for typed-map-lib, a" + " type inference helper for map with Typed/Racket." + " Supports afl, un-annotated lambdas and polymorphic" + " functions.")) +(define version "1.0") +(define pkg-authors '("Georges Dupéron")) diff --git a/typed-map-doc/scribblings/typed-map.scrbl b/typed-map-doc/scribblings/typed-map.scrbl @@ -0,0 +1,112 @@ +#lang scribble/manual +@require[scribble/example + @for-label[typed-map]] + +@title{typed-map} +@author[@author+email["Georges Dupéron" "georges.duperon@gmail.com"]] + +@(module orig racket/base + (require scribble/manual + (for-label racket/base)) + (provide orig:map orig:foldl orig:foldr) + (define orig:map @racket[map]) + (define orig:foldl @racket[foldl]) + (define orig:foldr @racket[foldr])) +@(require 'orig) + +@defmodule[typed-map] + +@defproc[#:kind "syntax" + (map [f (→ A ... B)] [l (Listof A)] ...) (Listof B)]{ + Like @orig:map from @racketmodname[typed/racket/base], but with better type + inference for Typed Racket. + + When @racket[f] is a literal lambda of the form + @racket[(λ (arg ...) body ...)], it is not necessary to specify the type of + the arguments, as they will be inferred from the list. + + @examples[#:eval ((make-eval-factory '(typed-map) #:lang 'typed/racket)) + (map (λ (x) (* x 2)) '(1 2 3)) + (let ([l '(4 5 6)]) + (map (λ (x) (* x 2)) l))] + + This enables the use of @racket[#,(hash-lang) #,(racketmodname aful)] for + @racket[map] in Typed Racket. + + Furthermore, when @racket[f] is a polymorphic function, type annotations are + not needed: + + @examples[#:eval ((make-eval-factory '(typed-map) #:lang 'typed/racket)) + (map car '([a . 1] [b . 2] [c . 3]))] + + Compare this with the behaviour of @orig:map from + @racketmodname[racket/base], which generates a type error: + + @examples[#:eval ((make-eval-factory '() #:lang 'typed/racket)) + (eval:alts (#,orig:map car '([a . 1] [b . 2] [c . 3])) + (eval:error (map car '([a . 1] [b . 2] [c . 3]))))] + + When used as an identifier, the @racket[map] macro expands to the original + @orig:map from @racketmodname[typed/racket/base]: + + @examples[#:eval ((make-eval-factory '(typed-map) #:lang 'typed/racket)) + (eval:alts (require (only-in racket/base [#,orig:map orig:map])) + (require (only-in racket/base [map orig:map]))) + (equal? map orig:map)] + + Note that the implementation expands to a large expression, and makes use of + @racket[set!] internally to build the result list. The trick used proceeds as + follows: + @itemlist[ + @item{It uses @racket[(reverse (reverse l))] to generalise the type of the + list, without having to express that type, so that Type / Racket infers a + more general type of the form @racket[(Listof A)], without detecting that the + output is identical to the input. An unoptimizable guard prevents the + double-reverse from actually being executed, so it does not incur a + performance cost.} + @item{It uses a + @seclink["Named_let" #:doc '(lib "scribblings/guide/guide.scrbl")]{named + @racket[let]} to perform the loop. The function @racket[f] is never passed + as an argument to another polymorphic function, and is instead directly + called with the appropriate arguments. The error message ``Polymorphic + function `map' could not be applied to arguments'' is therefore not raised.} + @item{To have the most precise and correct types, it uses a named let with a + single variable containing the list (with the generalized type). An outer let + binds a mutable accumulator, initialized with a single-element list + containing the result of applying @racket[f] on the first element of the + list. Since all elements of the list belong to the generalized type, the + result of calling @racket[f] on any element has the same type, therefore the + accumulator has the type @racket[(Listof B)], where @racket[B] is the + inferred type of the result of @racket[f].}]} + + +@defproc[#:kind "syntax" + (foldl [f (→ A ... Acc Acc)] [init Acc] [l (Listof A)] ...) Acc]{ + Like @orig:foldl from @racketmodname[typed/racket/base] but with better type + inference for Typed Racket. + + This form is implemented in the same way as the overloaded version of + @racket[map] presented above. + + Note that in some cases, the type for the accumulator is not generalised + enough based on the result of the first iteration, in which cases annotations + are needed: + + @examples[#:eval ((make-eval-factory '(typed-map) #:lang 'typed/racket)) + (eval:error (foldl (λ (x acc) (cons acc (add1 x))) '() '(1 2 3))) + (foldl (λ (x [acc : (Rec R (U Null (Pairof R Positive-Index)))]) + (cons acc (add1 x))) + '() + '(1 2 3))]} + +@defproc[#:kind "syntax" + (foldr [f (→ A ... Acc Acc)] [init Acc] [l (Listof A)] ...) Acc]{ + Like @orig:foldr from @racketmodname[typed/racket/base] but with better type + inference for Typed Racket. + + This form is implemented in the same way as the overloaded version of + @racket[map] presented above. + + Note that in some cases, the type for the accumulator is not generalised + enough based on the result of the first iteration, in which cases annotations + are needed. See the example given for @racket[foldl].} +\ No newline at end of file diff --git a/LICENSE.txt b/typed-map-lib/LICENSE.txt diff --git a/README.md b/typed-map-lib/README.md diff --git a/typed-map-lib/info.rkt b/typed-map-lib/info.rkt @@ -0,0 +1,11 @@ +#lang info +(define collection "typed-map") +(define deps '("base" + "typed-racket-lib")) +(define build-deps '()) +(define pkg-desc + (string-append "Type inference helper for map with Typed/Racket." + " Supports afl, un-annotated lambdas and polymorphic" + " functions.")) +(define version "1.0") +(define pkg-authors '("Georges Dupéron")) diff --git a/main.rkt b/typed-map-lib/main.rkt diff --git a/typed-map-test/info.rkt b/typed-map-test/info.rkt @@ -0,0 +1,12 @@ +#lang info +(define collection "typed-map") +(define deps '("base" + "rackunit-lib" + "typed-racket-lib" + "typed-racket-more" + "typed-map-lib")) +(define build-deps '("aful")) +(define scribblings '(("scribblings/typed-map.scrbl" ()))) +(define pkg-desc "Tests for typed-map-lib") +(define version "1.0") +(define pkg-authors '("Georges Dupéron")) diff --git a/test/test-map.rkt b/typed-map-test/test/test-map.rkt diff --git a/typed-map/info.rkt b/typed-map/info.rkt @@ -0,0 +1,13 @@ +#lang info +(define collection 'multi) +(define deps '("typed-map-lib" + "typed-map-test")) +(define implies '("typed-map-lib" + "typed-map-test")) +(define build-deps '()) +(define pkg-desc + (string-append "Type inference helper for map with Typed/Racket." + " Supports afl, un-annotated lambdas and polymorphic" + " functions.")) +(define version "1.0") +(define pkg-authors '("Georges Dupéron"))