19 ms·
Pyret: A new programming language from the creators of Racket
- tel 13y agoPython-like syntax with pattern matching and recursive ADTs!? What a great idea!
- rhizome31 13y ago+1 This looks a lot like the language I've been dreaming about. I actually like the explicit `end` keyword to materialize the end of blocks. The lambda expression syntax, as illustrated by the filter/map/fold example, looks like Ruby blocks with a much simpler syntax. A couple of questions to the crew: Why advertise it as a teaching language ? As a working programmer this looks very appealing to me. Are there limitations that don't make it a good language for practical programming (other than the fact that it's not ready yet, of course)? Are you planning to provide a tutorial more approachable than the language reference?
- tel 13y agoIt's not my language, so I can't really talk to those questions. I think it's fair to say that the Racket group has always been focused on teaching languages not to exclude "production languages" but instead because it's of their personal interest and lets them focus on certain aspects of the language to exclusion of others. They don't need to build performant standard libraries---they need to cleanly introduce good programming concepts.
- mageofmath 13y agoIt still has some performance issues that I say would make it hard to put into an industry environment. I think the teaching language part is in reference to Captain Teach, an IDE++ that the developers are using in the classes to support code review, automatic backups, and more. Pyret is being designed with the goal of encouraging good code, with tests being an integral part of every function, and clear differentiation between mutation and simple let bindings. I would teach this language just for those features, so my students would see how easy it is to get lost in spooky action at a distance, or in debugging the wrong portion of your code.
- ricw 13y agoI'd disagree with the "end" keyword. You could add more whitespace, which our brains naturally deal with very well, or you add more "cruft" which we have to actively think about. In typography white space is what makes good layout work. And here we're going back to replacing white space with a word. So from those perspectives I think the "end" keyword is a regression. Having said that, it's the first language that I prefer from a typographical perspective to python. So very well done on everything else.
- skrishnamurthi 13y agoWe tried very hard to do without an ending delimiter. But it boils down to a simple matter: either make whitespace significant or make the grammar hugely (and perhaps irredeemably) ambiguous. Our position on whitespace is: - it's very important for readability - it should not be semantic - it should be possible for a program to reindent your code That is, if I copy-and-paste code from email or a Web page, my environment should be able to "move it into place". Significant whitespace means that that's no longer possible. Therefore, we want whitespace to be a context-sensitive check that is layered atop the language. You could even see turning this off for code that is machine-generated, sent over a wire, etc. We are looking at actual usage patterns before we decide on the precise rules of indentation. To this end, we needed some way of indicating that a block had ended. Ergo "end" and its alias, preferred for one-liners, ";". Let me add one more argument in favor of an ending keyword: quality error messages. The more complex the grammar and hence the parsing job, the much more likely parse errors will be very complex. What we've learned over a few years of doing user-study research into error messages is that ultimately there is a complex algorithm running underneath and the more we can minimize surprise the better, because the user (especially the beginning programmer) simply has no mental model for what that algorithm is doing.
- jpolitz 13y agoThanks for the questions! As to why we're advertising it as a teaching language: Our group has a design sense of how to do this, and Pyret's success in the classroom is what we're able to study, measure, and focus on improving. That doesn't mean we won't be thinking about managing million-line codebases or getting great performance out of the runtime, but those concerns won't necessarily be the main guide of our design decisions. We may very well end up with something that's a superb general-purpose language, but I'm not yet willing to give folks that expectation, or do so at the expense of the learning experience. Make sense? EDIT to add: One thing that the Racket community has very successfully done is separate teaching languages from the main Racket language. A probable future for Pyret is splitting it into teaching and professional versions. I'd love to hear feedback about what more you'd like to see in Pyret, with this split in mind. The getting started guide (http://www.pyret.org/getting-started/ http://www.pyret.org/getting-started/) and tour (http://www.pyret.org/tour/ http://www.pyret.org/tour/) is the best reference for getting started right now. If you didn't see those then they probably need more prominent placement.
- jpolitz 13y agoThere's another response to this that I didn't mention. Shriram is writing a textbook that includes all the material for our advanced intro course and our programming languages course. There's a lot of good examples here: http://papl.cs.brown.edu/2013/ http://papl.cs.brown.edu/2013/
- rdtsc 13y agoDid you know about Elixir? It has a Ruby like syntax, pattern matching, functional, has macros so can build DSLs with it. Also most importantly, runs on BEAM VM (Erlang's VM). http://elixir-lang.org/ http://elixir-lang.org/
- lmm 13y agoIf you're looking for a more mature language that feels like that, I very much recommend scala.
- skrishnamurthi 13y agoScala is statically typed through-and-through. Pyret is designed to always offer a dynamic account of the language. We do have a static type checker under development (it's all-but-ready to release), but it will always work over a language where type annotations are optional. We also have a radically different idea about type inference, which we are currently trying out. In short, Pyret and Scala are already quite different and will grow even more so soon.
- lmm 13y agoI'd be interested in seeing some more explicit examples of the differences, because I get a very scala-like vibe from all the examples in the article (I accept that dynamic vs static is a fundamental difference that doesn't really show up in syntax).
- skrishnamurthi 13y agoScala 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: 1. We have a growing family of language support for writing tests well (e.g., see "satisfies" on the Pyret home page). I expect this to grow richer and richer. 2. We are working on some interesting ideas about the scope of testing blocks. We don't say this on the home page, but you can also write "test" blocks for data definitions, not only for functions. But now the functions that operate over those data are going to want to use instances of the data. We're working on a "scope conduit" to take definitions from the data definition to its functions. 3. As some readers have noted, in most languages, you simply cannot write unit tests for a function nested inside another, because you can't even name it. In Pyret, because definitions can include tests, this creates no problem at all. 4. We are now working on a type-inference approach that uses tests, rather than code, to infer types. The code is then checked against these inferred types. Essentially, testing is a kind of metaprogramming, and metaprogramming works best when you integrate it into the language (what Racket has shown) rather than as ad hoc external tools. Each of the above four examples is really just a specific instance of this general issue. Since testing is an especially important form of (dynamic) metaprogramming, integrating it well into the language from the very beginning is likely to lead to expressiveness, flexibility, and cleanliness that may be harder to achieve from the outside. This is part of a more general philosophy. To me, testing is a form of _specification_, and we want to see rich descriptions of program invariants expressed with a gentle blending of static and dynamic methods. We don't want to be so grandiose as to call Pyret a "testing-oriented" programming language, but in our minds it is, with testing having both the base role of making sure we (as programmers) didn't screw up but also the exalted role of providing an alternate, independent description of the program we're trying to write. (This is something I emphasize a lot in my teaching: eg, http://cs.brown.edu/courses/cs019/2012/assignments/sortacle http://cs.brown.edu/courses/cs019/2012/assignments/sortacle, http://cs.brown.edu/courses/cs019/2012/assignments/oracle http://cs.brown.edu/courses/cs019/2012/assignments/oracle). This is a philosophical position, and so hard to quantify through individual bits of code, but I already see small influences of this (as above) and I expect it to guide us to a very different point in the design space over time. It feels safe to say this is quite different from Scala's viewpoint.
- terhechte 13y ago"""Pyret makes testing a natural part of the programming process. Functions can end in a where: clause that holds unit tests for the function. These assertions are checked dynamically.""" Fantastic idea! I'll keep that in mind, should be fairly easy to extend Lisps or other AST-Macro enabled languages (Elixir, Julia, Python) with such a functionality. I really like that. It makes it easy to work on a function and code tests down without switching contexts (files, workspaces, etc)
- deleted 13y ago[deleted]
- jacques_chester 13y agoD has something like this[1]. It might have come from a still-earlier language. [1] http://dlang.org/unittest.html http://dlang.org/unittest.html
- sparkie 13y agoMy biggest gripe with these is the inability to name the tests. What exactly is a unittest block testing for? You need to rely on comments or read the test code where none exists. Doesn't seem like Pyret fixed that issue.
- skrishnamurthi 13y agoEverything is fixable in a new language (-:. Say more!
- sitkack 13y agoCould the tests be more declarative, defining properties over a space?
- skrishnamurthi 13y agoAbsolutely! Pyret's test section has a "satisfies" keyword for property tests. E.g.: check: insert(a-value, a-balanced-tree) satisfies is-balanced end or even check: tree-examples = [ ... ] values = [ ... ] for each2(t in tree-examples, v in values): insert(t, v) satisfies is-rbtree end end
- tinco 13y agoWhy the superfluous syntax? I think remembering syntax like this is orthogonal to the goal of being easy to learn. The syntax is basically Ruby + Python + Haskell. Each of those languages has a lighter, more intuitive and memorable syntax. Why would the syntax be: data BinTree: | leaf | node(value, left, right) end Instead of just data BinTree = leaf | node(value, left, right) The whole colon thing in Python is a mistake, it should have never been in Python, and it definitely not be repeated in other languages..
- clarkevans 13y agoI think the colon isn't a mistake, it clearly delineates an indented block; I think it's a great marker that indented languages might want to standardize on. Perhaps syntax issue is that it has both a colon and an "end" marker? The former indicates indentation-based syntax, the latter is often used in white-space agnostic contexts. The result of using both is confusion.
- sirclueless 13y agoPyret doesn't actually have an indentation-based format (so far as I know) it just happens to look like python.
- dbpatterson 13y agoThat's correct. There is a preferred indentation (enforced by the emacs mode and our online editor built on CodeMirror), but whitespace is only needed to separate things - the actual amount of whitespace never matters. So, for example, you can move chunks of code from one place to another and select it all and re-indent - something that you can't do (in general) in Python. It also makes it easier to programatically generate code.
- ptx 13y agoWhen you have both braces/keywords and whitespace, it seems to me that you're essentially storing the same information about the program structure in two places, of which one is read by the machine and the other is read by humans. The "re-indent" operation reads the master copy and updates the other one. (And if you forget to re-indent, your human readers will be interpreting an outdated copy and be very confused.) In Python, on the other hand, the information only exists in one place: the indentation. This is read both my machines and humans. There is no "re-indent" operation as the indentation is the only place the information exists, so there is nothing to sync. I have heard people bring up programatically generated code before, but as another commenter put it "where Ruby usually denotes code blocks with a `do` and an `end`, Python denotes code blocks with a `:` and an outdent" – so is that really a problem? Isn't it just a slightly different way of encoding the same information? (As to moving chunks of code in the editor: If the editor has a command to re-indent a selected block, it probably also has a command to shift it left or right.)
- gizmo 13y agoPyret looks like a there's a lot going on, based on the examples. It has implicit returns, special purpose syntax for data structures, iterators, assertions, refinements, etc. Having support for more stuff makes it less suitable as a teaching language, not more. Pyret looks like a has the good bits of Python plus a whole bunch of other cool stuff. But the language is pretty complex as a result. Cool? Yup! Good for teaching? Probably not. Take a look at the grammar and judge for yourself: https://github.com/brownplt/pyret-lang/blob/master/src/lang/grammar.rkt https://github.com/brownplt/pyret-lang/blob/master/src/lang/...
- saosebastiao 13y agoEdit: deleting snark. Oz is one of the best languages ever for learning CS.
- xfs 13y agoActually Brown teaches Intro to Programming Languages using Pyret. http://cs.brown.edu/courses/cs173/2013/software.html http://cs.brown.edu/courses/cs173/2013/software.html
- legutierr 13y agoBy looks of the course number, this is a third or fourth year elective for undergrads. It seems that what is being taught here is the design and engineering of programming languages, not programming itself.
- dbpatterson 13y agoThat's correct - 173 is definitely not an intro course. But, we also are teaching an intro course with it: http://cs.brown.edu/courses/csci0190/2013/software.html http://cs.brown.edu/courses/csci0190/2013/software.html
- fgoodman 13y agoThey also teach the Accelerated Intro to Computer Science (the first cs course some students take) using Pyret. http://cs.brown.edu/courses/cs019/2013/ http://cs.brown.edu/courses/cs019/2013/
- klrr 13y agoThis project seems really promising, but I got one concern. Lisp's syntax have been one of its strength for beginners. Easy to learn, easy to solve common errors. I don't see the point of having Python-like syntax really, the user could learn other syntax after they've understood programming.
- andybak 13y agoMy jaw dropped slightly to see someone suggest Lisp syntax would be a better starting place for beginners than Python's syntax. Is it just me or is that a fairly unorthodox point of view?
- f7t7ft7 13y agoMIT used to teach intro to CS using Scheme, I thought. It's significantly simpler than Python.
- dagw 13y agoHow many people taking intro to CS at MIT do you think are beginners who have never programmed before?
- geofft 13y agoQuite a few, actually, which is why the Scheme class ended up being awful in practice -- you'd get a bimodal distribution of students where some are already familiar with multiple languages (usually more mainstream than Lisp) and some aren't familiar with any, and the class, by necessity, targeted the trough right between those. So it was too fast for the students who never programmed before, and either too slow or too _different_ for the students who had, and served neither group very well. The new (Python-based) classes handle this a little bit better, from what I hear.
- f7t7ft7 13y agoI'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 see how anyone would ever want to use that.
- kudu 13y ago> end -.-
- takikawa 13y agoPyret has lots of nice ideas, looking forward to see it evolve. That said, the title of this post is a bit misleading so I wanted to correct it. The group of people who develop Racket and Pyret are mostly disjoint. I'm not trying to diminish Pyret at all, but wanted to make sure the right people get the credit. You can find out who develops Pyret here: http://www.pyret.org/crew/ http://www.pyret.org/crew/
- pekk 13y agoLooks more like Ruby than Python, why the comparison to Python?
- L8D 13y agoWhere Ruby usually denotes code blocks with a `do` and an `end`, Python denotes code blocks with a `:` and an outdent. But also, Ruby has a lot more implicit syntax and uses methods as operators(`1 + 1 == 1.+(1)`). There are a few more things that wouldn’t be obvious, like how it is still indentation sensitive yet you still need to use an `end`. Also, you can avoid the `end` keyword is you include it on the same line, like so: fun square(n): n * n
- skrishnamurthi 13y agoOkay, there's a Ruby example on the home page now, and probably one more on the way.
- skrishnamurthi 13y agoSecond Ruby example is in place now.
- k_bx 13y ago> Python-inspired syntax for functions > fun to-celsius(f): > (f * (5 / 9)) - 32 > end Wait a minute..
- garysweaver 13y ago> Most “scripting” languages don't support annotations for checking parameters and return values I coded in Java for many years and Ruby for the last several, the lack of explicit type checking in method signatures or via annotations built into Ruby has not gotten in the way enough where I felt I needed to add something to decorate methods to do some generic form of type checking in Ruby. When I really need to check the type of an object sent into a method, it is typically a method that can handle different types, and in that case, I'll use respond_to?(...) to see that an object passed in as an argument responds to a method, use a case statement, is_a?(...), etc. but that is certainly not on every method- probably more like 1 in 20-30 methods. Also, in the comparison section of the doc, OCaml and Python were represented, but not Ruby. As of late 2013, there are more jobs containing "Ruby" in the job description than "OCaml": http://www.indeed.com/jobtrends?q=ocaml%2C+ruby&l= http://www.indeed.com/jobtrends?q=ocaml%2C+ruby&l= So, imo it should give Ruby some love with a comparison.
- skrishnamurthi 13y agoAs you wish! We now have two Ruby examples on the home page. You may not call it love. <-:
- garysweaver 13y agoThanks, but may want to correct: method_as_fun = o.my-method which should be: method_as_fun = o.my_method and the examples themselves just look a little crazy, imo. Not crazy because of what you are trying to do, but in how you are trying to do it. What was the intent of calling a method that defines an argument without an argument? That's not a problem of the language; that's just an error in coding. There are all kinds of things in Ruby to handle method definition. Arguments can have defaults. You can use splat and unsplat to handle unspecified arguments and composing arguments of various # on the fly. You can pass in blocks specifically (&something) or optionally (yield, etc.). Procs allow argument sillyness and returning the parent method by explicit return in the proc body, lambdas don't, etc. Ruby is a great language, and you should give it a college try for several months to get the hang of it. By the same token, I have no clue what you are trying to do here: def f(x); def g(y); x + y; end; g(2); end; f(2) # undefined local variable or method `x' You can define methods on object instances, if that is what you are getting at (define_method/class_eval/etc.), and getting familiar with blocks, procs/lambdas might help. It isn't JavaScript, but I can't think of that much that I couldn't do in Ruby (barring high performance, compile-time type checking, etc.)
- mrcactu5 13y agoit sounds great to blend Python and Lisp!
- sparkie 13y agoExcept it abandons most of the benefits of lisp.
- skrishnamurthi 13y agoIf 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.
- samth 13y agoWell, the word "macro" doesn't appear on the Pyret home page ... :)
- skrishnamurthi 13y agoNo, but there is an AST module described in the documentation. (-:
- kolev 13y agoI lot more Ruby-like than Python. Not sure why it both has ":" and "end" and the "|" is kinda ugly the way it's used.
- kerryritter 13y agoThis doesn't seem like it would be easy for novices to grasp, though it looks like a solid language. For teaching, I think Quorum (http://www.quorumlanguage.com http://www.quorumlanguage.com) seems like a stronger alternative (disclosure, I am a member of a CS senior project team building their web system).
- dragonbonheur 13y agoThose "new" languages keep looking more and more like BASIC.
- gosub 13y agoWe should have been using very different dialects of BASIC, since I can't remember mine having algebraic data types, pattern matching, integrated testing, first class functions, high order functions and bignums.
- mageofmath 13y agoI 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.
- symbaton 13y agoWow, I didn't think of that. That is actually amazing.
- tbenst 13y agoI took CS019 with Shriram a few years back and immediately guessed the authors based on paradigms like making testing a natural part of the language and the encouragement to use annotations. In the class, we were taught a design process for Racket that will work very well for Pyret: 1. Identify the data - create data definitions (You are gixen x and expected to produce y) 2. Write concrete examples of the data (This is hard and takes time) 3. Write contract, purpose, header for functions (contract and header are annotations in Pyret, purpose should be a commented statement) 4. Write concrete examples of the function (This is hard and takes time. This means test cases!) 5. Write the template (This may only apply to recursion in Racket, but the idea is if you're dealing with a cons, you always have the same structure of checking if a cons? or empty? and must recur) 6. Fill in the template (ie, complete the function)
- sesm 13y agoThere is a book about this approach (http://htdp.org/ http://htdp.org/), as well as a MOOC on Coursera (https://www.coursera.org/course/programdesign https://www.coursera.org/course/programdesign)
- m_for_monkey 13y agoThe second edition of How to Design Programs is not finished yet, but I recommend it anyway: http://www.ccs.neu.edu/home/matthias/HtDP2e/index.html http://www.ccs.neu.edu/home/matthias/HtDP2e/index.html
- oahziur 13y agohtdp was my first programming book, and it is really helpful.
- agumonkey 13y agoCan't suggest these enough for any programming student.
- skrishnamurthi 13y agoWell done, T.B.! The same idea applies to recursive data in any language; you'd use exactly this to write a tree-walker in Java, for instance. And likewise in Racket. E.g.: fun f(l :: List<T>): cases (List) l: | empty => ... | link(f, r) => ... f ... f(r) ... end end Note that because you can put type annotations in the cases statement, you can remind yourself of the type of the locals: fun f(l :: List<T>): cases (List) l: | empty => ... | link(f :: T, r :: List<T>) => ... f ... f(r) ... end end which further nudges you towards a possibly recursive solution.
- JulianMorrison 13y agoThis looks like it could be useful as a way to prototype a real program.
- zem 13y agoI really love the surface design decisions taken here. Particularly * ML-like syntax for algebraic datatypes and matching. ML got it right; it always seems a bit off when languages try to make ADTs look like some other syntactic construct * the cyclic and graph declarations * accessing datatype variants using an OO-like syntax. simply brilliant. * non-significant whitespace. for all the pros and cons, autoindenting is something i hate to give up.
- kazagistar 13y agoSomehow, it looks a lot more like lua with a bunch of type-checks and tests added then like python. No named parameters, no generators, no comprehensions that I can see, no focus on iteration in general, no significant indentation, etc. Instead: "end" syntax, unified number type, all blocks produce new scopes (not just functions), local variables are explicit instead of default, etc.
- pygy_ 13y agoIndeed, but apparently, it doesn't have multiple return values, and I don't know if there is an equivalent to metamethods.
- skrishnamurthi 13y agoIt's easy to obtain the equivalent of multiple return values by using a literal object. I've been burned by multiple return values numerous times in Scheme and Racket. They're very subtle and hard to make performant. It's one of those language features that very much does _not_ pay its own way, so you have to really, really need it to want to put it in your language. My view is that its uses are not many, and most (all?) can easily be achieved with literal objects. That's why Pyret doesn't have them and is unlikely to get them.
- gruseom 13y agoCan you say more about how multiple return is "very subtle and hard to make performant" and leads to getting burned? As far as I can tell the main advantage of multiple-return over literal objects is that callers who only care about the primary value can call the function the normal way, whereas if it's wrapped in an object they have to "pay" for it by explicitly extracting it. That's a nice-to-have but you seem to be saying that it isn't worth the trouble because the trouble is considerable. I'd like to hear more about why. (A friend is working on a language where this is an issue.) p.s. This thread is just awesome. Thank you for engaging so extensively here.
- 13y ago
- jdnier 13y ago> Most “scripting” languages don't support annotations for checking parameters and return values PEP 3107 introduced function annotations to Python 3. The following syntax is valid: >>> def square(n: int) -> int: ... return n * n ... >>> square(3) 9 Nothing is done with annotations by default. Here's an article discussing this "unused feature": http://ceronman.com/2013/03/12/a-powerful-unused-feature-of-python-function-annotations/ http://ceronman.com/2013/03/12/a-powerful-unused-feature-of-...
- skrishnamurthi 13y agoUnless I'm missing something, all the examples in that PEP are first-order. There's no discussion of what the semantics is in the higher-order case. Pyret's annotations are perfectly well-defined and draw on a long history of research of getting these very subtle cases right (starting with Findler and Felleisen's ICFP 2002 paper). There's much more to this than just syntax.
- pcmonk 13y agoI wonder how well this integrates with Racket? I see that it's built with Racket, but I'd be curious if I could mix and match this with all my Racket code.
- skrishnamurthi 13y agoThat is not an explicit design goal, because we feel that would be too restrictive -- we may even diverge semantically. We are in fact working on compilers for the language that don't involve going through Racket (though Racket is so awesome, it's not a given that this will be any better -- these are all just experiments in progress). But without Racket's #lang, which is absolutely a rock star language creation mechanism, Pyret probably wouldn't exist. In short, though, sorry, we can't commit to helping you interop with your existing Racket code. But you're already in Racket, so life is probably as good as it's ever going to get. (-:
- jimktrains2 13y agoMostly OT: I've been working on the spec for a lang I'd like to implement at some point and would like feed back if anyone cares to give any? https://github.com/jimktrains/k5 https://github.com/jimktrains/k5
- yashodhan 13y agodashes in function names! I'm in love.
- b6fan 13y agoThe Ruby examples are unfair. Ruby intentionally makes parenthesis optional. So `do_something` is `do_something()`. For the first example, - method_as_fun = o.my-method - method_as_fun(5) # not reached + method_as_fun = o.method(:my_method) + method_as_fun.call(5) # or method_as_fun[5] And for the lexical scope thing, def f(x) g = ->y {x + y} g[2] end f(2) Or, explicitly use class variables, def f(x) @x = x def g(y); @x + y; end g(2) end f(2)
- skrishnamurthi 13y agoIf one has to rewrite code like this, you're making our point.
- b6fan 13y agoThe Ruby way is: 1. common (not all) things are simple / elegant. 2. Advanced things are doable, usually require a slightly more complex syntax. For example, Ruby allows one "block" (anonymous function) per method. Why not 2 or more blocks? Because Matz has studied common lisp (likely, maybe something else) standard library and noticed that in ~97% (maybe not exact number) cases, one anonymous function is enough. But you can use more anonymous functions using a different syntax. And here is the same case. People call methods much more often than to get the method. Therefore Ruby makes it default to call the method, but not stop you from getting the method object. It's just unfair to say Ruby cannot do these things.
- jpolitz 13y agoThanks for the feedback! There are tradeoffs here, and I appreciate that it's a little glib to say things are necessarily right or wrong. I took down the scope example for now, but in relation to the method example, I posted some thoughts about why I disagree on this post: https://news.ycombinator.com/item?id=6708420 https://news.ycombinator.com/item?id=6708420 See if that helps clarify my position for you.
- colanderman 13y agoI can't find any documentation on the type system. In particular, I'm interested in how objects are typed (that they're both structurally typed and may be abstract is novel), and the capability of the type refinements. I loathe template-based OO due to the possibility of monkey-patching but the fact that objects are immutable looks like it might ease this. (Generating efficient code might still be difficult.) I don't see the use cases for the cyclic structure as presented. If your data at all resembles a database relation, then (a) you have scalar keys anyway so you don't need language support, and (b) you probably need to key off of more than one column. The "method-as-fun" semantics seem weird. Given this code: o = { x(self): self.y end, y: 10 } f = o.x f() returns 10, as per the examples on the front page. But then: p = o.{y: 15} q = { x: o.x, y: 15 } Clearly p.x() should return 15, but what does q.x() return? It doesn't seem clear whether it should return 10 or 15. (Without reading through the reference manual (it's late), my guess would be that method definition is special-cased, so that the answer would be 10.)
- skrishnamurthi 13y agoThe type system hasn't been published yet. We don't have monkey-patching. We've been burned too much by JavaScript and the like. Cyclic structures: think about trying to teach graph algorithms. Let's say you believe it's important to write tests. Many graph algorithms aren't inherently mutational. But you need mutation just to create examples of your data. The graph construct gets around this problem entirely, so mutation and graph algorithms become orthogonal topics. In general, I'm a big believer in eliminating unnecessary curricular dependencies. Having taught graph algorithms this way for a few years now, I can't imagine going back. See the notes on graphs in PAPL (papl.cs.brown.edu/2013/).
- colanderman 13y agoBut you need mutation just to create examples of your data. OK, I'll buy this.
- breezydon 13y agoPyret is so hot these days.
- fedvasu 13y agosounds like ML+contracts, but wait is it statically typed? Maybe not Racket folks hate types (with great dredd)
- skrishnamurthi 13y agoIt's gradually typed. Everything has both a static and dynamic account. We have a prototype type checker and a pre-prototype type inferencer. If Racket people "hate types", you'd have a hard time explaining the existence of Typed Racket, or that some of the most cited research on types is by one of Racket's creators. But please, don't let facts get in the way. (-:
- fedvasu 13y agoSorry Professor, there is only one person behind typed-racket Sam, AFAIK. typed racket isn't very well supported or documented or even advertised by racket folks.
- samth 13y agoIf you're unhappy with our documentation, please let us know what would be helpful -- we know it isn't perfect, but specific requests are always helpful. As for whether other people in the racket community like typed racket, the answer is clearly yes. if you look at recent work on racket, much of it integrates with or its motivated by, typed racket. And there are a number of us who work on it currently. Have a look at the list of authors in the documentation. Sam, creator of Typed Racket
- skrishnamurthi 13y agoIn short, things are in a state of development, with limited resources. It's a big jump from that to say that Racket folks "hate types". If you look at the "Start Quickly" section of racket-lang.org, right there is an example of Typed Racket. Your claim that it's "not advertised" would make sense if they'd somehow hidden it from that list. There are several people contributing to Typed Racket. See the different names on the papers. The documentation could be better. Sam's gotten some flames from me about that. But all documentation for just about everything could be better. (I'm hardly one to throw stones.) It usually takes about 10 years for a project's documentation to reach a state of suitable quality -- so comparing against the documentation for Java or Python or even Racket is really not fair. It just takes a long time to get this material together. If you like Typed Racket -- which I do encourage you to study more -- do send mail to the Racket list. It's very active, and by asking questions, not only do you learn, you help others learn, and you give Sam and the others cues as to what it is they should be adding to the documentation.
- progman 13y agoPyret 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?
- skrishnamurthi 13y agoThanks for the encouragement. You can indeed run it using raco 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.
- mcpherson 13y agofunctions are fun
- lars512 13y agoIncidentally, a Gist for installing Pyret using Marelle: https://gist.github.com/larsyencken/7424864 https://gist.github.com/larsyencken/7424864