5 research outputs found

    Type-Directed Program Transformations for the Working Functional Programmer

    Get PDF
    We present preliminary research on Deuce+, a set of tools integrating plain text editing with structural manipulation that brings the power of expressive and extensible type-directed program transformations to everyday, working programmers without a background in computer science or mathematical theory. Deuce+ comprises three components: (i) a novel set of type-directed program transformations, (ii) support for syntax constraints for specifying "code style sheets" as a means of flexibly ensuring the consistency of both the concrete and abstract syntax of the output of program transformations, and (iii) a domain-specific language for specifying program transformations that can operate at a high level on the abstract (and/or concrete) syntax tree of a program and interface with syntax constraints to expose end-user options and alleviate tedious and potentially mutually inconsistent style choices. Currently, Deuce+ is in the design phase of development, and discovering the right usability choices for the system is of the highest priority

    Types to the rescue: verification of REST APIs Consumer Code

    Get PDF
    Tese de mestrado, Engenharia Informática (Engenharia de Software) Universidade de Lisboa, Faculdade de Ciências, 2019As arquiteturas de software são fundamentais para o desenvolvimento de um software fiável, escalável e com uma fácil manutenção. Com a criação e crescimento da internet, surgiu a necessidade de criar padrões de software que permitam trocar informação neste novo ambiente. O protocolo SOAP e a arquitetura REST são, dos padrões que emergiram, os que mais se destacaram ao nível da utilização. Durante as últimas décadas, e devido ao grande crescimento daWorld WideWeb, a arquitetura REST tem se destacado como a mais importante e utilizada pela comunidade. REST (Representational State Transfer) retira partido das características do protocolo HTTP para descrever as mensagens trocadas entre clientes e servidores. Os dados na arquitectura REST são representados por recursos, que são identificados por um identificador único (p.e. URI) e que podem ter várias representações (em vários formatos), que são os dados concretos de um recurso. A interação com os recursos é feita usando os métodos HTTP: get para obter um recurso, post para adicionar um novo recurso, put para fazer uma atualização de um recurso, delete para remover um recurso; entre outros, sendo estes os principais para aplicações CRUD. As aplicações RESTful, isto é, aplicações que fornecem os seus serviços através da arquitetura REST, devem ser claras na especificação dos seus serviços de forma a que os seus clientes possam utilizá-las sem erros. Para tal, existem várias linguagens de especificação de APIs REST, como a Open API Specification ou a API Blueprint, no qual é possível descrever formalmente as várias operações fornecidas pelo serviço, como o formato dos pedidos de cada operação e as respetivas respostas. No entanto, estas linguagens apresentam uma limitação nas condições formais que se pode colocar nos parâmetros dos pedidos e no impacto que estes têm no formato e conteúdo da resposta. Deste modo, foi introduzida uma nova linguagem de especificação de aplicações REST, HeadREST, onde é adicionada a expressividade necessária para cobrir as lacunas das outras linguagens. Esta expressividade é introduzida com a utilização de tipos refinados, que permitem restringir os valores de um determinado tipo. Adicionalmente, é introduzida também uma operação que permite verificar se uma determinada expressão pertence a um determinado tipo. Em HeadREST, cada operação é especificada usando uma ou mais asserções. Cada asserção é composta por um método HTTP, um URI template da operação, uma pré-condição que define as condições onde esta operação é aceite, e uma pós-condição que estabelece os resultados da operação se a pré-condição for comprida. Deste modo, estas condições permitem expressar os dados enviados nos pedidos e a receber na resposta, assim como expressar o estado do conjunto de recursos antes e depois do pedido REST. Devido à utilização de tipos refinados não é possível resolver sintaticamente a relação de subtipos na validação de uma especificação HeadREST. Deste modo, é necessária uma abordagem semântica: a relação de subtipos é transformada em fórmulas de lógica de primeira ordem, e depois é utilizado um SMT solver para resolver a formula e, consecutivamente, resolver a relação de subtipos. Por outro lado, é também importante garantir que as chamadas às APIs REST cumprem as especificações das mesmas. As linguagens de programação comuns não conseguem garantir que as chamadas a um serviço REST estão de acordo com a especificação do serviço, nomeadamente se o URL da chamada é válido e se o pedido e resposta estão bem formados ao nível dos valores enviados. Assim, um cliente só percebe se as chamadas estão bem feitas em tempo de execução. Existem poucas soluções para análise estática deste tipo de chamadas (RESType é um raro exemplo) e tendem a ser limitadas e a depender de um único tipo de linguagem de especificação. Para além disso, os clientes de serviços REST tendem a ser maioritariamente desenvolvidos em JavaScript, que possui uma fraca análise estática, o que potencializa ainda mais o problema identificado.Numa primeiro passo para tentar resolver este problema desenvolveu-se a linguagem SafeScript, que se caracteriza por ser um subconjunto do JavaScript equipado com um forte sistema de tipos. O sistema de tipos é muito expressivo graças à adição de tipos refinados e também de um operador que verifica se uma expressão pertence a um tipo. SafeScript apresenta flow typing, isto é, o tipo de uma expressão depende da sua localização no fluxo de controlo do programa. Tal como no HeadREST, não é possível realizar uma simples análise sintática para a validação de tipos. No entanto, neste caso trata-se de uma linguagem imperativa com flow typing, logo uma abordagem igual de tradução direta para um SMT solver não é trivial. Deste modo, a validação de tipos é feita traduzido o código SafeScript para a linguagem intermédia Boogie, onde as necessárias validações são traduzidas como asserções, sendo que o Boogie utiliza internamente o Z3 SMT solver para resolver semanticamente as asserções. Devido à validação semântica, o compilador de SafeScript consegue detetar estaticamente diversos erros de execução comuns, como divisão por zero ou acesso a um array fora dos seus limites, e que não conseguem ser detetados por linguagens similares, como o TypeScript. SafeScript compila para JavaScript, com o intuito de poder ser utilizado em conjunto com este. Graças ao seu expressivo sistema de tipos, o validador de programas SafeScript é também um verificador estático. A partir deste é possível provar que um programa cumpre uma determinada especificação, que pode ser descrita usando os tipos refinados. Neste trabalho destacou-se a capacidade de prova do validador de SafeScript, concretamente resolvendo alguns desafios propostos pelo Verification Benchmarks Challange. A partir do SafeScript desenvolveu-se a extensão SafeRESTScript, que adiciona pedidos REST à sintaxe do SafeScript e valida-os estaticamente de encontro a uma especificação HeadREST. Para cada chamada REST são feitas principalmente duas validações. Em primeiro lugar, é verificado se o URL é um endereço válido do serviço para o método HTTP do pedido, isto é, se existe algum triplo na especificação com o par método e URL do pedido. De seguida, e com a tradução da especificação HeadREST importada para Boogie, é verificado se as chamadas REST cumprem os triplos da especificação, nomeadamente, se as pré-condições são cumpridas então as pós-condições também se devem verificar. Por exemplo, se uma pós-condição, cuja respetiva pré-condição é verdadeira para uma determinada chamada, asserta que no corpo da resposta existe um objeto com o campo id, então um acesso a este campo no corpo da resposta é validado. Neste trabalho, como exemplo ilustrativo das capacidades da linguagem, desenvolveu-se um cliente SafeRESTScript da API REST do conhecido repositório GitHub. Ambas as linguagens possuem um compilador e editor que estão disponíveis como plug-in para o IDE Eclipse, para além de uma versão terminal. As duas linguagens possuem várias limitações, e por isso muito trabalho ainda existe pela frente. No entanto, SafeScript e SafeRESTScript não têm ambição de ser linguagens de produção, mas sim contribuir para um melhoramento da análise estática de programas e mostrar que é possível auxiliar o desenvolvimento fiável de código cliente de serviços REST.REST is the architectural sytle most used in the web to exchange data. RESTful applications must be well documented so clients can use its services without doubts and errors. There are several specification languages for describing REST APIs, e.g. Open API Specification, but they lack on expressiveness to describe the exchanged data. Head- REST specification language was introduced to address this gap, containing an expressive type system that allows to describe rigorously the request and response formats of a service endpoint. On the other hand, it is also important to ensure that REST calls in client code meet the service specification. This challenge is even more important taking in account that most REST clients are made in JavaScript, a weakly typed language. To aim this problem, we firstly developed SafeScript, a subset of JavaScript equipped with a strong type system. SafeScript has a expressive type system thanks to refinement types and to an operator that checks if an expression belongs to a type. A semantic subtyping analysis is necessary; the typing validation in done by translating the code to Boogie intermediate language which uses the Z3 SMT solver for the semantic evaluation. SafeScript compiles directly to JavaScript. SafeRESTScript is an extension of SafeScript that adds REST calls, being a client-side language for consuming REST services. It uses HeadREST specifications to verify REST calls: whether the URL of the call is a valid endpoint and whether the data exchanged match the pre and post-conditions declared in the specification. With the creation of this new languages, we dot not intend in having them as production languages, but to show that it is possible to contribute with a better verification and correction in area where software reliability is weak

    Executable Refinement Types

    Full text link
    This dissertation introduces executable refinement types, which refine structural types by semi-decidable predicates, and establishes their metatheory and accompanying implementation techniques. These results are useful for undecidable type systems in general. Particular contributions include: (1) Type soundness and a logical relation for extensional equivalence for executable refinement types (though type checking is undecidable); (2) hybrid type checking for executable refinement types, which blends static and dynamic checks in a novel way, in some sense performing better statically than any decidable approximation; (3) a type reconstruction algorithm - reconstruction is decidable even though type checking is not, when suitably redefined to apply to undecidable type systems; (4) a novel use of existential types with dependent types to ensure that the language of logical formulae is closed under type checking (5) a prototype implementation, Sage, of executable refinement types such that all dynamic errors are communicated back to the compiler and are thenceforth static errors.Comment: Ph.D. dissertation. Accepted by the University of California, Santa Cruz, in March 2014. 278 pages (295 including frontmatter

    A Theory of Program Refinement

    Get PDF
    We give a canonical program refinement calculus based on the lambda calculus and classical first-order predicate logic, and study its proof theory and semantics. The intention is to construct a metalanguage for refinement in which basic principles of program development can be studied. The idea is that it should be possible to induce a refinement calculus in a generic manner from a programming language and a program logic. For concreteness, we adopt the simply-typed lambda calculus augmented with primitive recursion as a paradigmatic typed functional programming language, and use classical first-order logic as a simple program logic. A key feature is the construction of the refinement calculus in a modular fashion, as the combination of two orthogonal extensions to the underlying programming language (in this case, the simply-typed lambda calculus). The crucial observation is that a refinement calculus is given by extending a programming language to allow indeterminate expressions (or 'stubs') involving the construction 'some program x such that P'. Factoring this into 'some x ...' and '... such that P', we first study extensions to the lambda calculus providing separate analyses of what we might call 'true' stubs, and structured specifications. The questions we are concerned with in these calculi are how do stubs interact with the programming language, and what is a suitable notion of structured specification for program development. The full refinement calculus is then constructed in a natural way as the combination of these two subcalculi. The claim that the subcalculi are orthogonal extensions to the lambda calculus is justified by a result that a refinement can actually be factored into simpler judgements in the subcalculi, that is, into logical reasoning and simple decomposition. The semantics for the calculi are given using Henkin models with additional structure. Both simply-typed lambda calculus and first-order logic are interpreted using Henkin models themselves. The two subcalculi require some extra structure and the full refinement calculus is modelled by Henkin models with a combination of these extra requirements. There are soundness and completeness results for each calculus, and by virtue of there being certain embeddings of models we can infer that the refinement calculus is a conservative extension of both of the subcalculi which, in turn, are conservative extensions of the lambda calculus
    corecore