[icfp] new deal intro, going slow but well
This commit is contained in:
parent
82927b6d17
commit
5db0b3a5ed
|
@ -1,73 +1,115 @@
|
||||||
#lang scribble/sigplan
|
#lang scribble/sigplan
|
||||||
|
|
||||||
|
@; Tuples in Haskell http://hackage.haskell.org/package/tuple
|
||||||
|
@; Regexp
|
||||||
|
@; - ocaml http://caml.inria.fr/pub/docs/manual-ocaml/libref/Str.html
|
||||||
|
@; - haskell https://hackage.haskell.org/package/regex-compat/docs/Text-Regex.html
|
||||||
|
|
||||||
@require["common.rkt"]
|
@require["common.rkt"]
|
||||||
|
|
||||||
|
|
||||||
@title{Introduction}
|
@title{Introduction}
|
||||||
@; format/printf : played out
|
@; tautology checker
|
||||||
@; regexp-match : complicated, from HM
|
@; curry
|
||||||
@; + : way too simple
|
@; deep
|
||||||
@; vector-length : boring
|
@; regexp match
|
||||||
|
|
||||||
Suppose @racket[regexp-match] is a function for matching a
|
Many useful functions do not have simple types.
|
||||||
regular expression pattern against a string value.
|
For example, one cannot write a general procedure for currying functions
|
||||||
If the match succeeds then the function returns a list containing the
|
or accessing the first element of an arbitrarily-sized tuple in OCaml or Haskell.
|
||||||
part of the string that was matched and all matched groups
|
@; TODO don't mention ML/Hask ... use System F?
|
||||||
corresponding to parenthesized sub-patterns of the regular expression.
|
Nevertheless, specialized versions of @racket[curry] and @racket[first] are
|
||||||
Otherwise, it returns a value indicating the match failed.
|
easy to define and type.
|
||||||
@; TODO Specify the type system?
|
|
||||||
Suppose also that @racket[pattern] and @racket[group] are variables
|
|
||||||
bound to string values at run-time.
|
|
||||||
Given these premises, what is the type of this expression?
|
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(regexp-match pattern str)
|
> curry (λ (x y) x) > first (x, y)
|
||||||
|
(λ (x) (λ (y) x)) x
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
One simple answer is @racket[(Option (Listof String))].
|
That is, once some basic structure of the input is fixed, the general
|
||||||
If all goes well the resulting value will be a list of strings (of unspecified
|
problem becomes a much simpler, specific problem.
|
||||||
length), but we know ahead of time that the match may fail.
|
If ever a 16-argument function needs currying, we can write a new function for
|
||||||
|
the task.
|
||||||
|
@; This pearl explains how ...
|
||||||
|
By creating the specific @racket[curry] or @racket[first] for each size of
|
||||||
|
function or tuple value in a program, we
|
||||||
|
|
||||||
In a programming language with the full power of dependent types, we can encode
|
In general, we consider functions like @racket[curry] and @racket[first] for
|
||||||
the relationship between @racket[pattern] and @racket[str] and give a very
|
arbitrarily-sized
|
||||||
specific type relating the number of groups in @racket[pattern] to the number
|
|
||||||
of elements in the result list.
|
|
||||||
Dependent types, however, typically require strategic use of type annotations
|
|
||||||
and carefully-selected data representations.
|
|
||||||
One relatively simple type for the expression above is
|
|
||||||
@racket[(Option (List[N] String))] where @racket[N] is the number of groups
|
|
||||||
in @racket[pattern], but this requires the type @racket[List] to carry length
|
|
||||||
information and a type for regular expressions that counts groups.
|
|
||||||
Building the infrastructure necessary to express that particular type of
|
|
||||||
the call to @racket[regexp-match] may give more trouble than relief.
|
|
||||||
|
|
||||||
This paper explores a solution between simple and dependent types that
|
@; Introduce name? Talk about indexed families?
|
||||||
should apply in any typed language with sufficiently powerful
|
|
||||||
@emph{syntax extensions}, or macros.
|
|
||||||
The key idea is to refine types based on values apparent in the program text.
|
|
||||||
When the parameters to @racket[regexp-match] are bound at run-time, we
|
|
||||||
conservatively assign the type @racket[(Option (Listof String))].
|
|
||||||
But if there is more information at hand, we use it.
|
|
||||||
For instance, both these expressions have the type
|
|
||||||
@racket[(Option (List String String))] in our system.@note{Where @racket[List]
|
|
||||||
is Typed Racket's type for heterogenous, sized lists; akin to tuple types in ML.}
|
|
||||||
|
|
||||||
@racketblock[
|
|
||||||
(regexp-match "hello(o*)" str)
|
|
||||||
|
|
||||||
(let ([pattern "hello(o*)"])
|
|
||||||
(regexp-match pattern str))
|
|
||||||
]
|
|
||||||
|
|
||||||
The pattern here has exactly one group, delimited by the parentheses.
|
@;These functions behave in a straightforward manner, but depend on
|
||||||
Thus if the match succeeds we get a list of two elements: the first being
|
@; characteristics of their input that most type systems do not express generically.
|
||||||
the entire matched substring and the second a string matching the regular
|
|
||||||
expression @racket{o*}.
|
|
||||||
All this is clear from the program text to the programmer; our contribution
|
|
||||||
is parsing the relevant information and forwarding it to the type checker.
|
|
||||||
|
|
||||||
@;Additionally replacing @racket[str] with a value gives an even more precise type by
|
|
||||||
@; evaluating the expression while type checking.
|
|
||||||
|
|
||||||
|
Many workarounds = polydots, pi-types, printf-types, ...
|
||||||
|
|
||||||
|
|
||||||
|
@; Suppose @racket[regexp-match] is a function for matching a
|
||||||
|
@; regular expression pattern against a string value.
|
||||||
|
@; If the match succeeds then the function returns a list containing the
|
||||||
|
@; part of the string that was matched and all matched groups
|
||||||
|
@; corresponding to parenthesized sub-patterns of the regular expression.
|
||||||
|
@; Otherwise, it returns a value indicating the match failed.
|
||||||
|
@; @; TODO Specify the type system?
|
||||||
|
@; Suppose also that @racket[pattern] and @racket[group] are variables
|
||||||
|
@; bound to string values at run-time.
|
||||||
|
@; Given these premises, what is the type of this expression?
|
||||||
|
@;
|
||||||
|
@; @racketblock[
|
||||||
|
@; (regexp-match pattern str)
|
||||||
|
@; ]
|
||||||
|
@;
|
||||||
|
@; One simple answer is @racket[(Option (Listof String))].
|
||||||
|
@; If all goes well the resulting value will be a list of strings (of unspecified
|
||||||
|
@; length), but we know ahead of time that the match may fail.
|
||||||
|
@;
|
||||||
|
@; In a programming language with the full power of dependent types, we can encode
|
||||||
|
@; the relationship between @racket[pattern] and @racket[str] and give a very
|
||||||
|
@; specific type relating the number of groups in @racket[pattern] to the number
|
||||||
|
@; of elements in the result list.
|
||||||
|
@; Dependent types, however, typically require strategic use of type annotations
|
||||||
|
@; and carefully-selected data representations.
|
||||||
|
@; One relatively simple type for the expression above is
|
||||||
|
@; @racket[(Option (List[N] String))] where @racket[N] is the number of groups
|
||||||
|
@; in @racket[pattern], but this requires the type @racket[List] to carry length
|
||||||
|
@; information and a type for regular expressions that counts groups.
|
||||||
|
@; Building the infrastructure necessary to express that particular type of
|
||||||
|
@; the call to @racket[regexp-match] may give more trouble than relief.
|
||||||
|
@;
|
||||||
|
@; This paper explores a solution between simple and dependent types that
|
||||||
|
@; should apply in any typed language with sufficiently powerful
|
||||||
|
@; @emph{syntax extensions}, or macros.
|
||||||
|
@; The key idea is to refine types based on values apparent in the program text.
|
||||||
|
@; When the parameters to @racket[regexp-match] are bound at run-time, we
|
||||||
|
@; conservatively assign the type @racket[(Option (Listof String))].
|
||||||
|
@; But if there is more information at hand, we use it.
|
||||||
|
@; For instance, both these expressions have the type
|
||||||
|
@; @racket[(Option (List String String))] in our system.@note{Where @racket[List]
|
||||||
|
@; is Typed Racket's type for heterogenous, sized lists; akin to tuple types in ML.}
|
||||||
|
@;
|
||||||
|
@; @racketblock[
|
||||||
|
@; (regexp-match "hello(o*)" str)
|
||||||
|
@;
|
||||||
|
@; (let ([pattern "hello(o*)"])
|
||||||
|
@; (regexp-match pattern str))
|
||||||
|
@; ]
|
||||||
|
@;
|
||||||
|
@; The pattern here has exactly one group, delimited by the parentheses.
|
||||||
|
@; Thus if the match succeeds we get a list of two elements: the first being
|
||||||
|
@; the entire matched substring and the second a string matching the regular
|
||||||
|
@; expression @racket{o*}.
|
||||||
|
@; All this is clear from the program text to the programmer; our contribution
|
||||||
|
@; is parsing the relevant information and forwarding it to the type checker.
|
||||||
|
@;
|
||||||
|
@; @;Additionally replacing @racket[str] with a value gives an even more precise type by
|
||||||
|
@; @; evaluating the expression while type checking.
|
||||||
|
|
||||||
|
|
||||||
@section{Prior & Current Work}
|
@section{Prior & Current Work}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
@(require "common.rkt")
|
@(require "common.rkt")
|
||||||
|
|
||||||
@authorinfo["Ben Greenman"
|
@authorinfo["Ben Greenman"
|
||||||
"Northeastern University, Boston, USA"
|
"PLT @ Northeastern University, Boston, USA"
|
||||||
""]
|
""]
|
||||||
|
|
||||||
@title{Functional Pearl: Do you see what I see?}
|
@title{Functional Pearl: Do you see what I see?}
|
||||||
|
@ -29,13 +29,13 @@
|
||||||
@;@keywords{Gradual typing, performance evaluation}
|
@;@keywords{Gradual typing, performance evaluation}
|
||||||
|
|
||||||
@include-section{intro.scrbl}
|
@include-section{intro.scrbl}
|
||||||
@include-section{solution.scrbl}
|
@;@include-section{solution.scrbl}
|
||||||
@include-section{usage.scrbl}
|
@;@include-section{usage.scrbl}
|
||||||
@include-section{experience.scrbl} @; Merge with usage?
|
@;@include-section{experience.scrbl} @; Merge with usage?
|
||||||
@include-section{implementation.scrbl}
|
@;@include-section{implementation.scrbl}
|
||||||
@include-section{correctness.scrbl}
|
@;@include-section{correctness.scrbl}
|
||||||
@include-section{related.scrbl}
|
@;@include-section{related.scrbl}
|
||||||
@include-section{conclusion.scrbl}
|
@;@include-section{conclusion.scrbl}
|
||||||
|
|
||||||
@section[#:style 'unnumbered]{Acknowledgments}
|
@section[#:style 'unnumbered]{Acknowledgments}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
% Better horizontal rules
|
% Better horizontal rules
|
||||||
\usepackage{booktabs}
|
\usepackage{booktabs}
|
||||||
|
\usepackage{listings}
|
||||||
|
\lstset{language=ML}
|
||||||
\usepackage[usenames,dvipsnames]{xcolor}
|
\usepackage[usenames,dvipsnames]{xcolor}
|
||||||
\usepackage{multicol}
|
\usepackage{multicol}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user