Earlier quoted context omitted.
Sorry, my point was not to get into a popularity pissing match. I do believe popularity and quality are largely unrelated. What I meant is, since most people have stopped teaching with Smalltalk, it's really hard to do the kind of research I'm talking about! We had no trouble doing it for Racket because we were able to get lots of data and from it measure for statistical significance.
No worries, I understood that. I just thought you were in a great position to actually preform such a study, if you were willing to run it on a group of students :-) I can certainly understand why you wouldn't "just try Smalltalk on a class or two", though!
Pyret: A new programming language from the creators of Racket
251–260 of 288 posts
Re: Pyret: A new programming language from the creators of Racket
#252Earlier quoted context omitted.
You seem to be under the impression I haven't programmed in Lispy languages. And our data are from students using DrRacket, which very much has paredit support. These are just inconvenient truths.
DrRacket is a very big language. How does it compare with using a much smaller language such as the Scheme used in SICP?
Re: Pyret: A new programming language from the creators of Racket
#253Earlier quoted context omitted.
I've seen an MIT Scheme class video, and it was painfully slow and the guy seemed to explain everything in painstaking detail. I've heard about the bimodal distribution, which I believe I witnessed among fellow students when I was taking classes. But I'm having trouble seeing how Scheme made it any worse or how the class was too fast. And, Pyret looks like a terrible beginner language! I like PltScheme, but I can't s…
Scheme makes it worse, I think, because the way in which you usefully teach Scheme to someone who's never programmed before is different from the way you teach Scheme to someone who already knows C++ or Java or something pretty well.
Re: Pyret: A new programming language from the creators of Racket
#254Pyret looks very promising. Keep on the good work! But please remove the minus sign from identifiers! I am concerned that people may abstain from Pyret for this simple reason. It is really annoying to embrace every operator with blanks. That should be an optional job for the IDE to increase readibility. By the way, is there already a raco exe for Pyret?
We're sticking with the identifier syntax for now. We've written a lot of code in Pyret over the course of 9-12 months and we really like it. My guess is that people will only notice it if someone points it out (only one person on HN noticed, and even that was to ask how it could work). Most folks will just get on with the job at hand.
Re: Pyret: A new programming language from the creators of Racket
#255Earlier quoted context omitted.
If s-expressions constitute "most" of the benefits of Lisp, that's a pretty sad statement for Lisp. I don't see any other benefits that it gives up.
Well, the word "macro" doesn't appear on the Pyret home page ... :)
Re: Pyret: A new programming language from the creators of Racket
#256Earlier quoted context omitted.
Scala is a great language with a rich excursion into type system design (and other things). Pyret is designed to reinforce specification (more general than types) and to do so through a combination of static and dynamic means. That much I've already said. Let me point to testing as an example of where we differ. Testing is really important to us. As you've seen, we have lightweight, in-place test cases. In addition:…
That's pretty fascinating. (static) Type inference based on tests sounds like an ill-posed problem, or at least one that can't produce human-meaningful annotations. That is to say, If one function has spec A for a generic parameter, and another function has spec B, it doesn't seem like it's possible to generate in general the spec for their composition in "closed-form". Like, what's the type spec of "map" where the m…
Our philosophy is that the typed Pyret language is an explicitly-typed one. Inference is just a convenience to save you some amount of typewritering. We want to do a good enough job of it, and if you want to get more specific, you do it yourself. For instance, in the foreseeable future we do not plan to ever infer a refinement. So I think that addresses your example.
Furthermore, we aren't going to play the cute trick of having an inference process that is so consistent with the type-checker that we can get rid of a type-checker. One nice thing about old fashioned recursive-descent type-checkers is that they give simple and familiar error messages; I don't know of any research papers that have been written about better error reporting by them (at least in the past few decades). That's a feature. [NB: There's always an exception. Hopefully my point is clear.]
So, whatever type we infer is one that gets fed to the type-checker to check against the function. Typically, assuming the function has passed its tests, the function should be consistent with its inferred type, unless the tests didn't cover the code properly.
What happens with code that can apply to multiple types, i.e., parametrically polymorphic code? We made an explicit decision to not have union types; had we had them, this would have been more sticky. But because we don't, we simply assume you mean to use the function in a polymorphic fashion, and that's the type we "infer". [Put differently, if you have a polymorphic function, you should test it on at least two different types!]
For reporting errors, we intend to make a distinction between declared types and inferred ones -- a distinction that I don't believe is commonly made in other type inference error presentations. For instance, inconsistency between two inferred types should perhaps be treated a bit differently than inconsistency between two declared types or between an inferred and a declared type.
More broadly, types are specifications. The point of a spec is to provide a redundant statement of program behavior, that can be checked against an implementation. From that perspective, inferring the type from the implementation is a strange idea: one shouldn't be inferring specs from code. [Yes, I know, it's been fashionable to infer "specs" from code for over a decade now. I would not call those specs -- they're more like summaries of the code.]
But tests, to my mind, are a lightweight form of specification, so it does make sense to infer one specification from another [just as people have gone the other way and used specifications to derive tests: the area of specification-driven test-generation]. Especially since it's being backed up by a true type-checker.
As I said, these are all pretty novel and possibly heretical ideas. But this is the experiment we're trying.
Re: Pyret: A new programming language from the creators of Racket
#257I also like the fact that you can put unit tests for helper functions that are inside of other functions. This means you can use the inputs to your outer function as part of the tests for an inner function, which has been hard to do in the past.
Re: Pyret: A new programming language from the creators of Racket
#258Earlier quoted context omitted.
If you think parsing is the hard part, wait for the semantics. See, for instance, the Ruby examples on the Pyret home page.
I don't see any difficult semantics in those examples. The hard part of parsing Ruby is mostly trying to conform to MRI rather than to a formal grammar. In comparison the semantics are reasonably simple. It's hard to compile Ruby efficiently , though, but for reasons unrelated to those examples. (Incidentally I don't know if that scoping example is intentionally ignoring the fact that Ruby does support lexical scopin…
Re: scope, you're right that using "def" the way I did isn't very idiomatic Ruby, but I always run afoul of it because it looks so similar to what I'd write in another language. I took that example down for the moment; I still have a personal gripe with it, but my "fundamentally broken" language was a bit strong. If I think of a more illustrative example, I'll put something back up.
The currying example I still think is weird in Ruby, and it's because it interacts bizarrely with the syntactic choice about optional argument lists. The thing that is wrong with JavaScript and Ruby is that they both have dot expressions and application expressions; o.m and f(x). It looks like
o.m(x)
should be a composition of dot lookup followed by an application, since both of those raw expressions make sense on their own. But in neither does the decomposition actually work:
m = o.m m(x)
There's no state or funny mutation going on here, but a simple kind of substitutability isn't working. JavaScript does it especially poorly, and Ruby has this awkward inability to decompose because of its choices about application syntax. Now, in Ruby I'm aware that with or without parens are actually both method calls, so it's not like there's a field access and an application in the underlying language model. But Ruby then adds the syntactic convenience of no arguments to make it look like access is possible, but that syntactic convenience is a bit of a leaky abstraction.
I should note that Python actually gets this nicely right IMO, and dot lookup curries self so this works out.
The underlying thing that irks me and I'm calling out here is the non-compositionality of what looks like two expressions that should compose. This is something we felt like figuring out and getting consistent for Pyret.
Re: Pyret: A new programming language from the creators of Racket
#259Earlier quoted context omitted.
Scheme makes it worse, I think, because the way in which you usefully teach Scheme to someone who's never programmed before is different from the way you teach Scheme to someone who already knows C++ or Java or something pretty well.
Scheme makes it difficult because it more quickly gets you to teaching difficult ideas . This is an issue about SICP that most people simply never grok. Most courses don't cover a third of the concepts (if that) of SICP in the same amount of time. That's the book, not the language (and the only "fault" of the language is that it lets the book get that far that soon).
Still, I think Scheme is sufficiently different from mainstream programming languages that it's... like teaching git to a crowd composed half of SVN power users and half of people who have never copied a folder to folder.old in their life. You're balancing teaching "oh, here's how Scheme's different" from "oh, here's how you should have thought about it all along".
In particular I remember the OO system being pretty confusing at first, since my background, from high school, was C++. It makes a lot of sense that Scheme gets out of your way and lets you implement a nifty OO system using just closures, but to someone who expects a language to treat objects as first-class and lambdas not, you're inevitably going to be trying to learn the SICP OO system by comparison to the C++ or Java one.
All that said, I'm not blaming the language at all. I think the quickest fix would have been for MIT to offer either a placement exam or voluntary registration for two classes, one for students who were more-or-less new to programming and one for students with a strong background in something like C++ or Java. Both classes could have used SICP as a text and worked fine.
Re: Pyret: A new programming language from the creators of Racket
#260Earlier quoted context omitted.
By that logic, assembly is the best language to learn programming. Presumably it is easier to learn about concepts with a language that has them.
Obviously I'm not suggesting that assembler is the best teaching language. I could also take your logic and use it to conclude that C++ is the best programming language to learn first because with C++ you can learn about the implications of heap corruption when improperly handling exceptions in constructors. C++ allows functional, procedural and OO and many more programming styles. It supports manual and automatic me…
I am already seeing a trend in Python tutorials where they just stay away from complex data, and stick to what is easy to encode in the data structures that Python does provide (lists, dictionaries, arrays).
We've seen this movie before: it's what happened when languages like Fortran, Pascal, and C dominated programming education, and the fact that they made some data (particularly of the linear kind) really easy and others a nuisance meant that curricula diverted towards the path of least resistance.
It's harder now to spot the pattern because it's better hidden. But it's still there.