초보자를위한 Haskell 또는 Standard ML?
저는 이산 구조에서 저학년 과정을 가르 칠 것입니다. 기능적 프로그래밍 언어로 구현하는 데 도움이되는 예제와 개념이 포함되어 있기 때문에 부분적으로 Discrete Structures, Logic 및 Computability 교과서를 선택했습니다 . (또한 좋은 교과서라고 생각합니다.)
DS 개념을 설명하고 학생들이 사용할 수있는 이해하기 쉬운 FP 언어를 원합니다. 대부분의 학생들은 기껏해야 자바로 프로그래밍을 한 두 학기 만 할 수 있습니다. Scheme, Erlang, Haskell, Ocaml 및 SML을 살펴본 후 Haskell 또는 Standard ML을 선택했습니다. 나는 아래에 설명 된 이유로 하스켈에 기대고 있지만, 둘 중 하나에서 활동적인 프로그래머 인 사람들의 의견을 듣고 싶습니다.
- Haskell과 SML은 모두 재귀 알고리즘을 간단하게 설명하는 패턴 매칭을 가지고 있습니다.
- Haskell은 이러한 목록이 수학적으로 표현되는 방식과 잘 어울리는 멋진 목록 이해력을 가지고 있습니다.
- Haskell은 게으른 평가를 가지고 있습니다. 목록 이해 기술을 사용하여 무한 목록을 구성하는 데 적합합니다.
- SML에는 함수를 정의하고 사용할 수있는 진정한 대화 형 인터프리터가 있습니다. Haskell에서 함수는 대화 형 쉘에서 사용되기 전에 별도의 파일에 정의되고 컴파일되어야합니다.
- SML은 이해하기 쉬운 구문으로 함수 인수 및 반환 유형을 명시 적으로 확인합니다. 예 : val foo = fn : int * int-> int. Haskell의 암묵적 카레 구문은 좀 더 둔감하지만 완전히 외계인은 아닙니다. 예 : foo :: Int-> Int-> Int.
- Haskell은 기본적으로 임의 정밀도 정수를 사용합니다. SML / NJ의 외부 라이브러리입니다. SML / NJ는 기본적으로 출력을 70 자로 자릅니다.
- Haskell의 람다 구문은 미묘합니다. 단일 백 슬래시를 사용합니다. SML이 더 명시 적입니다. 하지만이 수업에서 람다가 필요한지 확실하지 않습니다.
기본적으로 SML과 Haskell은 거의 동일합니다. 나는 Haskell의 목록 이해력과 무한한 목록을 좋아하기 때문에 Haskell에 의지합니다. 그러나 Haskell의 압축 구문에 포함 된 많은 기호가 학생들에게 문제를 일으킬 수 있다는 것이 걱정됩니다. 내가 다른 게시물을 읽고 모은 것에서 Haskell은 FP로 시작하는 초보자에게는 권장되지 않습니다. 그러나 우리는 완전한 응용 프로그램을 구축하는 것이 아니라 단순한 알고리즘을 시도하는 것입니다.
어떻게 생각해?
편집 : 귀하의 훌륭한 답변 중 일부를 읽은 후 몇 가지 중요 사항을 명확히해야합니다.
SML에서는 인터프리터에서 함수를 정의하는 것과 외부 파일에서 정의하는 것 사이에 구문상의 차이가 없습니다. 계승 함수를 작성하고 싶다고 가정 해 보겠습니다. Haskell에서는이 정의를 파일에 넣고 GHCi에로드 할 수 있습니다.
fac 0 = 1
fac n = n * fac (n-1)
나에게 그것은 명확하고 간결하며 책의 수학적 정의와 일치합니다. 그러나 GHCi에서 직접 함수를 작성하려면 다른 구문을 사용해야합니다.
let fac 0 = 1; fac n = n * fac (n-1)
대화 형 인터프리터와 함께 작업 할 때 교육 관점에서 학생이 파일과 명령 줄 모두에서 동일한 코드를 사용할 수있을 때 매우 편리합니다.
"함수에 대한 명시 적 확인"이란 함수를 정의 할 때 SML이 함수 이름, 인수 유형 및 반환 유형을 즉시 알려준다는 의미입니다. Haskell에서는 :type
명령 을 사용해야 하며 약간 혼란스러운 카레 표기법이 표시됩니다.
Haskell에 대한 또 하나의 멋진 점-이것은 유효한 함수 정의입니다 :
fac 0 = 1
fac (n+1) = (n+1) * fac n
다시 말하지만 이것은 교과서에서 찾을 수있는 정의와 일치합니다. SML에서는 할 수 없습니다!
내가 Haskell을 좋아하는 것처럼, 이산 수학 및 데이터 구조 (및 대부분의 다른 초보자 클래스)의 클래스에 SML을 선호하는 이유는 다음과 같습니다.
Haskell 프로그램의 시간 및 공간 비용은 전문가에게도 예측하기가 매우 어려울 수 있습니다. SML은 기계를 날려 버리는 훨씬 더 제한된 방법을 제공합니다.
대화 형 인터프리터에서 함수 정의 구문은 파일에서 사용되는 구문 과 동일 하므로 잘라내어 붙여 넣을 수 있습니다.
SML의 연산자 오버로딩은 완전히 가짜이지만 간단합니다. 타입 클래스에 들어 가지 않고 하스켈에서 전체 클래스를 가르치는 것은 어려울 것입니다.
학생은
print
. (주석자가 지적했듯이를 사용하여 Haskell에서 거의 동일한 효과를 얻을 수Debug.Trace.trace
있습니다.)무한한 데이터 구조는 사람들의 마음을 사로 잡습니다. 초보자의 경우 참조 셀과 썽 크로 완전한 스트림 유형을 정의하여 작동 방식을 알고있는 것이 좋습니다.
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
이제 더 이상 마법이 아닙니다. 여기에서 스트림 (무한 목록)으로 이동할 수 있습니다.
레이아웃은 Python만큼 간단하지 않으며 혼란 스러울 수 있습니다.
Haskell이 우위를 점하고있는 두 곳이 있습니다.
핵심 Haskell에서는 정의 직전에 함수의 유형 서명을 작성할 수 있습니다. 이것은 학생과 다른 초보자에게 큰 도움이됩니다. SML에서 유형 서명을 처리하는 좋은 방법이 없습니다.
Haskell은 더 나은 구체적인 구문을 가지고 있습니다. Haskell 구문은 ML 구문에 비해 크게 개선되었습니다. ML 프로그램에서 언제 괄호를 사용해야하는지에 대한 짧은 메모를 작성했습니다 . 이것은 약간 도움이됩니다.
마지막으로 두 가지 방법을 모두 절단하는 검이 있습니다.
- Haskell 코드는 기본적으로 순수하므로 학생들은 우연히 불순한 구조 (IO 모나드, 상태 모나드)를 우연히 발견하지 않을 것입니다. 그러나 동일한 토큰으로 인쇄 할 수 없으며 I / O를 수행하려면 최소로
do
표기법 을 설명해야하며return
혼란 스럽습니다.
관련 주제에 대해 코스 준비를위한 몇 가지 조언이 있습니다 . Chris Okasaki의 Purely Functional Data Structures 를 간과하지 마십시오 . 학생들이 그것을 사용하지 않더라도 분명히 사본을 갖고 싶을 것입니다.
우리는 하스켈을 우리 대학에서 1 학년 때까지 가르칩니다. 이것에 대한 내 감정은 약간 혼합되어 있습니다. 한편으로 Haskell을 처음 몇 년 동안 가르치는 것은 그들이 명령형 스타일을 잊을 필요가 없다는 것을 의미합니다. Haskell은 또한 이전에 Java를 사용했던 사람들이 이해할 수있는 매우 간결한 코드를 생성 할 수 있습니다.
학생들이 자주 발견 한 몇 가지 문제 :
패턴 매칭은 처음에는 약간 어려울 수 있습니다. 학생들은 처음에 가치 구성과 패턴 매칭이 어떻게 관련되어 있는지 확인하는 데 문제가있었습니다. 또한 추상화를 구별하는 데 몇 가지 문제가있었습니다. 우리의 연습은 산술 표현을 단순화하는 쓰기 기능을 포함했으며 일부 학생들은 추상 표현 (예
Const 1
:)과 메타 언어 표현 (1
) 의 차이를 보는 데 어려움을 겪었습니다 .또한 학생들이 목록 처리 기능을 직접 작성해야하는 경우 패턴 간의 차이점을주의 깊게 지적하십시오.
[] [x] (x:xs) [x:xs]
얼마나 많은 함수형 프로그래밍을 가르치고 싶은지에 따라 몇 가지 라이브러리 함수를 제공하고 함께 놀게 할 수 있습니다.
We didn't teach our students about anonymous functions, we simply told them about
where
clauses. For some tasks this was a bit verbose, but worked well otherwise. We also didn't tell them about partial applications; this is probably quite easy to explain in Haskell (due to its form of writing types) so it might be worth showing to them.They quickly discovered list comprehensions and preferred them over higher-order functions like
filter
,map
,zipWith
.I think we missed out a bit on teaching them how to let them guide their thoughts by the types. I'm not quite sure, though, whether this is helpful to beginners or not.
Error messages are usually not very helpful to beginners, they might occasionally need some help with these. I haven't tried it myself, but there's a Haskell compiler specifically targeted at newcomers, mainly by means of better error messages: Helium
For the small programs, things like possible space leaks weren't an issue.
Overall, Haskell is a good teaching language, but there are a few pitfalls. Given that students feel a lot more comfortable with list comprehensions than higher-order functions, this might be the argument you need. I don't know how long your course is or how much programming you want to teach them, but do plan some time for teaching them basic concepts--they will need it.
BTW,
# SML has a truly interactive interpreter in which functions can be both defined and used. In Haskell, functions must be defined in a separate file and compiled before being used in the interactive shell.
Is inaccurate. Use GHCi:
Prelude> let f x = x ^ 2
Prelude> f 7
49
Prelude> f 2
4
There are also good resources for Haskell in education on the haskell.org edu. page, with experiences from different teachers. http://haskell.org/haskellwiki/Haskell_in_education
Finally, you'll be able to teach them multicore parallelism just for fun, if you use Haskell :-)
Many universities teach Haskell as a first functional language or even a first programming language, so I don't think this will be a problem.
Having done some of the teaching on one such course, I don't agree that the possible confusions you identify are that likely. The most likely sources of early confusion are parsing errors caused by bad layout, and mysterious messages about type classes when numeric literals are used incorrectly.
I'd also disagree with any suggestion that Haskell is not recommended for beginners starting out with FP. It's certainly the big bang approach in ways that strict languages with mutation aren't, but I think that's a very valid approach.
- SML has a truly interactive interpreter in which functions can be both defined and used. In Haskell, functions must be defined in a separate file and compiled before being used in the interactive shell.
While Hugs may have that limitation, GHCi does not:
$ 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"
There's many reasons I prefer GHC(i) over Hugs, this is just one of them.
- SML gives explicit confirmation of the function argument and return types in a syntax that's easy to understand. For example: val foo = fn : int * int -> int. Haskell's implicit curry syntax is a bit more obtuse, but not totally alien. For example: foo :: Int -> Int -> Int.
SML has what you call "implicit curry" syntax as well.
$ 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
Essentially, SML and Haskell are roughly equivalent. I lean toward Haskell because I'm loving the list comprehensions and infinite lists in Haskell. But I'm worried that the extensive number of symbols in Haskell's compact syntax might cause students problems. From what I've gathered reading other posts on SO, Haskell is not recommended for beginners starting out with FP. But we're not going to be building full-fledged applications, just trying out simple algorithms.
I like using Haskell much more than SML, but I would still teach SML first.
- Seconding nominolo's thoughts, list comprehensions do seem to slow students from getting to some higher-order functions.
- If you want laziness and infinite lists, it's instructive to implement it explicitly.
- Because SML is eagerly evaluated, the execution model is far easier to comprehend, and "debugging via printf" works a lot better than in Haskell.
- SML's type system is also simpler. While your class likely wouldn't use them anyways, Haskell's typeclasses are still an extra bump to get over -- getting them to understand the
'a
versus''a
distinction in SML is tough enough.
Most answers were technical, but I think you should consider at least one that is not: Haskell (as OCaml), at this time, has a bigger community using it in a wider range of contexts. There's also a big database of libraries and applications written for profit and fun at Hackage. That may be an important factor in keeping some of your students using the language after your course is finished, and maybe trying other functional languages (like Standard ML) later.
I am amazed you are not considering OCaml and F# given that they address so many of your concerns. Surely decent and helpful development environments are a high priority for learners? SML is way behind and F# is way ahead of all other FPLs in that respect.
Also, both OCaml and F# have list comprehensions.
Haskell. I'm ahead in my algos/theory class in CS because of the stuff I learned from using Haskell. It's such a comprehensive language, and it will teach you a ton of CS, just by using it.
However, SML is much easier to learn. Haskell has features such as lazy evaluation and control structures that make it much more powerful, but with the cost of a steep(ish) learning curve. SML has no such curve.
That said, most of Haskell was unlearning stuff from less scientific/mathematic languages such as Ruby, ObjC, or Python.
참고URL : https://stackoverflow.com/questions/810409/haskell-or-standard-ml-for-beginners
'Development Tip' 카테고리의 다른 글
Swift에서 관련 객체를 설정하는 방법이 있습니까? (0) | 2020.10.18 |
---|---|
ImportError : scipy라는 모듈이 없습니다. (0) | 2020.10.18 |
RegExp.exec ()는 NULL을 산발적으로 반환합니다. (0) | 2020.10.18 |
Shadow DOM은 React.js의 Virtual DOM처럼 빠릅니까? (0) | 2020.10.18 |
SQL : 방금 삽입 한 값의 ID를 얻는 방법은 무엇입니까? (0) | 2020.10.18 |