Pergunta

Eu vou estar ensinando um curso de menor divisão em estruturas discretas. Eu selecionei o livro de texto discretos Estruturas, lógica, e Computability em parte porque contém exemplos e conceitos que são favoráveis ??para a implementação com uma linguagem de programação funcional. (Eu também acho que é um bom livro.)

Eu quero um fácil de entender a linguagem FP para ilustrar conceitos DS e que os alunos podem usar. A maioria dos estudantes terá tido apenas um ou dois semestres de programação em Java, na melhor das hipóteses. Depois de olhar para Scheme, Erlang, Haskell, OCaml, e SML, eu tenha resolvido em um ou outro Haskell ou ML padrão. Estou inclinado para Haskell pelas razões descritas abaixo, mas eu gostaria que a opinião daqueles que são programadores ativos em um ou o outro.

  • Ambos Haskell e SML tem correspondência padrão que torna descrevendo um algoritmo recursivo uma coisa fácil.
  • Haskell tem bons compreensões lista que correspondem bem com a forma como essas listas são expressos matematicamente.
  • Haskell tem avaliação preguiçosa. Grande para a construção de listas infinitas usando a técnica de compreensão da lista.
  • SML tem um intérprete verdadeiramente interativa em que as funções podem ser ambos definidos e utilizados. Em Haskell, funções devem ser definidos em um arquivo separado e compilados antes de serem utilizados no shell interativo.
  • SML dá confirmação explícita do argumento função e tipos de retorno em uma sintaxe que é fácil de entender. Por exemplo: val foo = fn: int * int -> int. sintaxe caril implícita de Haskell é um pouco mais obtuso, mas não totalmente estranho. Por exemplo:. Foo :: Int -> Int -> Int
  • Haskell usa inteiros de precisão arbitrária por padrão. É uma biblioteca externa em SML / NJ. E SML / NJ trunca saída para 70 caracteres por padrão.
  • sintaxe lambda de Haskell é sutil - ele usa uma única barra invertida. SML é mais explícito. Não tenho certeza se alguma vez vai precisar lambda nesta classe, no entanto.

Essencialmente, SML e Haskell são aproximadamente equivalentes. Eu me inclino para Haskell porque eu estou amando as compreensões de lista e listas infinitas em Haskell. Mas eu estou preocupado que o número extenso de símbolos na sintaxe compacta de Haskell pode causar problemas alunos. Pelo que eu recolhi ler outros posts sobre SO, Haskell não é recomendado para iniciantes começando com FP. Mas nós não vamos estar construindo aplicações de pleno direito, apenas experimentar algoritmos simples.

O que você acha?


Edit:. Ao ler alguns de seus grandes respostas, devo esclarecer alguns dos meus pontos de bala

Em SML, não há distinção sintática entre a definição de uma função no intérprete e defini-lo em um arquivo externo. Vamos dizer que você quer escrever a função fatorial. Em Haskell você pode colocar essa definição em um arquivo e carregá-lo em GHCi:

fac 0 = 1
fac n = n * fac (n-1)

Para mim, isso é claro, sucinto, e coincide com a definição matemática no livro. Mas se você quer escrever a função no GHCi diretamente, você tem que usar uma sintaxe diferente:

let fac 0 = 1; fac n = n * fac (n-1)

Ao trabalhar com intérpretes interativos, a partir de uma perspectiva de ensino é muito, muito útil quando o aluno pode usar o mesmo código em ambos um arquivo e linha de comando.

Por "confirmação explícita da função," Eu quis dizer que após a definição da função, SML imediatamente informa o nome da função, os tipos dos argumentos, e o tipo de retorno. Em Haskell você tem que usar o comando :type e então você começa a notação de caril um pouco confuso.

Uma coisa mais legal sobre Haskell - esta é a definição de função válido:

fac 0 = 1
fac (n+1) = (n+1) * fac n

Novamente, isso corresponde a uma definição que pode encontrar no livro. não pode fazer isso na SML!

Foi útil?

Solução

Tanto quanto eu amo Haskell, aqui estão as razões pelas quais eu preferiria SML para uma classe de estruturas discretas de matemática e de dados (e classes maioria dos outros iniciantes):

  • custos de tempo e espaço de programas Haskell podem ser muito difíceis de prever, mesmo para especialistas. SML oferece muito mais maneiras para explodir a máquina limitado.

  • Sintaxe para defintion função em um interpretador interativo é idênticas para sintaxe usada em um arquivo, assim que você pode cortar e colar.

  • Apesar de sobrecarga de operador em SML é totalmente falso, também é simples. Vai ser difícil para ensinar uma classe inteira em Haskell, sem ter que entrar em aulas de tipo.

  • Student pode depurar usando print. (Embora, como um comentarista aponta, é possível obter quase o mesmo efeito em Haskell usando Debug.Trace.trace.)

  • estruturas de dados infinitas explodir a mente das pessoas. Para os iniciantes, é melhor tê-los definir um tipo de fluxo completo com células ref e thunks, para que eles saibam como funciona:

    datatype 'a thunk_contents = UNEVALUATED of unit -> 'a
                               | VALUE of 'a
    type 'a thunk = 'a thunk_contents ref
    val delay : (unit -> 'a) -> 'a thunk
    val force : 'a thunk -> 'a
    

    Agora não é mágica mais, e você pode ir daqui para fluxos (listas infinitas).

  • Layout não é tão simples como em Python e pode ser confuso.

Existem dois lugares Haskell tem uma vantagem:

  • No núcleo Haskell você pode escrever tipo assinatura de uma função pouco antes de sua definição. Isso é extremamente útil para estudantes e outros iniciantes. Não há apenas uma boa maneira de lidar com assinaturas de tipo em SML.

  • Haskell tem melhor sintaxe concreta. A sintaxe Haskell é uma grande melhoria sobre sintaxe ML. Eu escrevi uma nota curta sobre quando usar parênteses em uma ML programa ; isso ajuda um pouco.

Finalmente, há uma espada de dois gumes:

    código
  • Haskell é puro por padrão, para que seus alunos não são susceptíveis de tropeçar construções impuros (IO Mônada mônada estado) por acidente. Mas por isso mesmo, não pode imprimir, e se você quer fazer I / O, em seguida, no minumum você tem que explicar a notação do e return é confuso.

Em um tópico relacionado, aqui estão alguns conselhos para sua preparação claro: não se esqueçam puramente funcional Estruturas de dados por Chris Okasaki. Mesmo se você não tem os seus alunos usá-lo, você certamente vai querer ter uma cópia.

Outras dicas

Nós ensinamos Haskell aos primeiros anos de nossa universidade. Meus sentimentos sobre este são um pouco misturados. Sobre o ensino um lado Haskell a anos os primeiros meios de que eles não têm que desaprender o estilo imperativo. Haskell também pode produzir um código muito conciso que as pessoas que tinham alguma Java antes podem apreciar.

Alguns problemas que eu observei os alunos muitas vezes têm:

  • A correspondência de padrões pode ser um pouco difícil, em primeiro lugar. Os alunos inicialmente tinha alguns problemas em ver como a construção de valor e casamento de padrões estão relacionados. Eles também tinham alguns problemas, distinguindo entre abstrações. Nossos exercícios incluíam escrever funções que simplificam a expressão aritmética e alguns alunos tiveram dificuldade em ver a diferença entre a representação abstrata (por exemplo, Const 1) ea representação meta-linguagem (1).

    Além disso, se seus alunos são supostamente para funções de processamento de lista de escrever-se, tenha cuidado para apontar a diferença entre os padrões

    []
    [x]
    (x:xs)
    [x:xs]
    

    Dependendo da quantidade de programação funcional que você quer ensinar-lhes no caminho, você pode apenas dar-lhes algumas funções de biblioteca e deixá-los brincar com isso.

  • Nós não ensinamos nossos alunos sobre funções anônimas, nós simplesmente disse-lhes sobre cláusulas where. Para algumas tarefas este foi um pouco detalhado, mas funcionou bem o contrário. Também não dizer-lhes sobre aplicações parciais; esta é provavelmente bastante fácil de explicar em Haskell (devido à sua forma de escrita tipos), por isso pode valer a pena mostrando a eles.

  • Eles rapidamente descobriram compreensões lista e preferiu-los funções ao longo de ordem superior como filter, map, zipWith.

  • I acha que faltou um pouco sobre ensiná-los a deixá-los guiar os seus pensamentos pelos tipos. Eu não estou muito certo, no entanto, se esta é útil para iniciantes ou não.

  • As mensagens de erro não são geralmente muito útil para iniciantes, eles podem, ocasionalmente, precisa de alguma ajuda com estes. Eu não tentei isso sozinho, mas há um compilador Haskell especificamente orientadas para os recém-chegados, principalmente por meio de melhores mensagens de erro: Hélio

  • Para os pequenos programas, coisas como possíveis vazamentos espaciais não foram um problema.

No geral, Haskell é uma boa língua de ensino, mas existem algumas armadilhas. Tendo em conta que os alunos se sentem muito mais confortáveis ??com compreensões lista do que funções de ordem superior, isso pode ser o argumento que você precisa. Eu não sei quanto tempo seu curso é ou o quanto de programação que você quer ensiná-los, mas não planejar algum tempo para ensinar-lhes conceitos básicos -. Eles vão precisar dele

BTW,

# SML tem um verdadeiramente interativa intérprete em que as funções podem ser tanto definido e usado. Em Haskell, funções devem ser definidos num arquivo separado e compilado antes sendo usado no shell interativo.

É impreciso. Use GHCi:

Prelude> let f x = x ^ 2
Prelude> f 7
49
Prelude> f 2
4

Há também bons recursos para Haskell na educação sobre a haskell.org edu. página, com experiências de diferentes professores. http://haskell.org/haskellwiki/Haskell_in_education

Finalmente, você vai ser capaz de ensiná-los multicore paralelismo apenas para se divertir, se você usar Haskell: -)

Muitas universidades ensinam Haskell como primeira língua funcional ou mesmo uma primeira linguagem de programação, então eu não acho que isso vai ser um problema.

Depois de ter feito alguns dos ensinamentos de um tal curso, eu não concordo que as possíveis confusões que você identificar são que provável. Maioria das prováveis ??fontes de confusão no início estiver analisando erros causados ??por mau layout, e mensagens misteriosas sobre as classes de tipo, quando literais numéricos são usados ??incorretamente.

Eu também não concordar com qualquer sugestão de que Haskell não é recomendado para iniciantes começando com FP. É certamente a abordagem big bang de maneiras que estritas línguas com mutação não são, mas eu acho que é uma abordagem muito válido.

  • SML tem um intérprete verdadeiramente interativa em que as funções podem ser ambos definidos e utilizados. Em Haskell, funções devem ser definidos em um arquivo separado e compilados antes de serem utilizados no shell interativo.

Enquanto Hugs pode ter essa limitação, GHCi não:

$ ghci
GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> let hello name = "Hello, " ++ name
Prelude> hello "Barry"
"Hello, Barry"

Há muitas razões que eu prefiro GHC (i) sobre Hugs, este é apenas um deles.

  • SML dá confirmação explícita do argumento função e tipos de retorno em uma sintaxe que é fácil de entender. Por exemplo: val foo = fn: int * int -> int. sintaxe caril implícita de Haskell é um pouco mais obtuso, mas não totalmente estranho. Por exemplo:. Foo :: Int -> Int -> Int

SML tem o que você chama de "implícita curry" sintaxe também.

$ sml
Standard ML of New Jersey v110.69 [built: Fri Mar 13 16:02:47 2009]
- fun add x y = x + y;
val add = fn : int -> int -> int

Essencialmente, SML e Haskell são aproximadamente equivalentes. Eu me inclino para Haskell porque eu estou amando as compreensões de lista e listas infinitas em Haskell. Mas eu estou preocupado que o número extenso de símbolos na sintaxe compacta de Haskell pode causar problemas alunos. Pelo que eu recolhi ler outros posts sobre SO, Haskell não é recomendado para iniciantes começando com FP. Mas nós não vamos estar construindo aplicações de pleno direito, apenas experimentar algoritmos simples.

Eu gosto de usar Haskell muito mais do SML, mas eu ainda iria ensinar SML primeiro.

  • pensamentos Destacando de nominolo, compreensões lista do parecem estudantes lentos de chegar a algumas funções de ordem superior.
  • Se você quiser preguiça e listas infinitas, é instrutivo para implementá-lo explicitamente.
  • Porque SML é ansiosamente avaliado, o modelo de execução é muito mais fácil de compreender, e "depuração via printf" funciona muito melhor do que em Haskell.
  • sistema do tipo do SML também é mais simples. Enquanto sua classe provavelmente não iria usá-los de qualquer maneira, typeclasses de Haskell ainda são uma colisão extra para superar -. Levá-los a compreender a 'a contra ''a distinção na SML é suficiente difícil

A maioria das respostas foram técnica, mas eu acho que você deve considerar pelo menos um que não é: Haskell (como OCaml), neste momento, tem uma comunidade maior de usá-lo em uma ampla gama de contextos. Há também um grande banco de dados de bibliotecas e aplicativos escritos para o lucro e diversão em Hackage . Isso pode ser um fator importante em manter alguns dos seus alunos usando a linguagem após o curso é concluído, e talvez tentar outras linguagens funcionais (como ML padrão) mais tarde.

Estou espantado você não está considerando OCaml e F #, dado que eles abordar tantos de suas preocupações. Certamente ambientes de desenvolvimento decentes e votos são de alta prioridade para os alunos? SML é muito atrás e F # está muito à frente de todos os outros FPLs a esse respeito.

Além disso, ambos os OCaml e F # têm compreensões lista.

Haskell. Eu estou à frente na minha classe algos / teoria no CS por causa das coisas que eu aprendi de usar Haskell. É uma linguagem tão abrangente, e vai ensinar-lhe uma tonelada de CS, apenas por usá-lo .

No entanto, SML é muito mais fácil de aprender. Haskell tem recursos como estruturas de avaliação e de controlo preguiçosos que o tornam muito mais poderoso, mas com o custo de uma íngreme (ish) curva de aprendizado. SML não tem essa curva.

Dito isto, a maioria dos Haskell era coisa desaprender de línguas menos científicos / matemáticos tais como Ruby, ObjC, ou Python.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top