
Pyret: A new programming language from the creators of Racket - sergimansilla
http://www.pyret.org
======
terhechte
"""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)

~~~
6ren
It clutters the code.

Tests are a form of documentation, but too much in the code, like too many
comments, obscures. Higher level unit tests (acceptance tests) can be quite
long, especially if there's a lot of setup - unlike their example code.
Literate programming tried embedded documentation, but didn't catch on (even
with Knuth's backing). Embedding tests makes them easier to keep in sync, but
tests are already kept in sync by (hopefully) failing when not. However, their
idea of automatically running tests is interesting, so there's no
infrastructure to set-up, run etc (though you'd want to be able to disable
them).

Nice for teaching.

~~~
stiff
I don't think the story of literate programming can be of any help predicting
how well this idea here can work out.

Literate programming is not "embedding documentation". The main idea was to
separate the order in which the code is read from the order in which the
compiler sees it, and it embeds the code in the documentation, not vice versa.
It was a very idiosyncratic thing, hard to imagine a team of programmers in a
typical current commercial setting, developing a nice LaTeX essay around the
actual code of the next social network web-app. As the program grows larger it
also gets harder and harder to maintain the "story" around it.

~~~
jashkenas
That's not the "main idea". Originally, it was a part of the suggested way to
accomplish the goal ... but the _main idea_ is this:

    
    
        > Let us change our traditional attitude to the construction of programs: 
        > Instead of imagining that our main task is to instruct a computer what 
        > to do, let us concentrate rather on explaining to human beings what we 
        > want a computer to do.
        >                          — Knuth
    

If your program can be read more as an enlightening explanation of the job-to-
be-done, and is more oriented toward the human reader of the code than the
machine that will execute it, then you've succeeded.

Hopefully, it's clear how a program written in such a way could potentially be
beneficial to a large team, trying to understand, modify, and improve it.

~~~
tokenrove
Right, but it's important to emphasize what stiff was talking about, that the
structure of the narrative needs to be oriented towards the human instead of
the machine, because so many people don't bother to do this and decide that
literate programming just means having LaTeX or docbook comments in your code.
That total inversion (the code is in the documentation, not the documentation
is in the code) is important. (That said, I admit that most modern languages
are so much more flexible compared to C or Pascal with regards the ordering of
code.)

------
tbenst
I 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
There 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
The 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)

------
gizmo
Pyret 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/...](https://github.com/brownplt/pyret-
lang/blob/master/src/lang/grammar.rkt)

~~~
carterschonwald
The grammar can be described with a single page in actual BNF. Thats AMAZING.
The only languages have shorter grammars are core lisp/scheme. Ruby is
fundamentally impossible to describe with a BNF.

~~~
vidarh
> Thats AMAZING. The only languages have shorter grammars are core
> lisp/scheme.

It's nice, but I'm not sure I'd go with _amazing_. Most or all of Niklaus
Wirth's languages have shorter grammars, for example. I'd imagine quite a few
others do as well.

E.g. Oberon-2 has 33 EBNF productions:
[http://en.wikipedia.org/wiki/Oberon-2_(programming_language)](http://en.wikipedia.org/wiki/Oberon-2_\(programming_language\))
\- that fits fully on screen for me with my default font size...

Regarding Ruby, I agree. I'm working on a Ruby compiler, and "decoding" the
MRI parser into something closer to optimal will still leave an awful mess no
matter what you do. I love programming Ruby, but implementing it is hell (and
one of the reasons I'm trying it...)

~~~
skrishnamurthi
If you think parsing is the hard part, wait for the semantics. See, for
instance, the Ruby examples on the Pyret home page.

~~~
vidarh
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 scoping (EDIT: for blocks), or if it's
lack of understanding of what what "def" is.

The Ruby way of achieving what that example is trying to do is:

    
    
        def f(x)
          g = proc do |y|
            x + y
          end
          g[2]
        end
        f(2)
    

(g[2] is shorthand for g.call(2))

"def" explicitly introduced a method-level scope of the innermost wrapping
class scope. Nesting 'def's is not in any way idiomatic Ruby. It's not
necessarily very useful to nest them given those semantics. But "def" is
really just syntactic sugar for #define_method, and so it is logical for it to
work where #define_method does.

I might be inclined to agree that the different Ruby ways of defining blocks,
methods and closures could do with some simplification. Allowing "def" to bind
surrounding variables would remove a lot of the need for class instance
variable or class variables, for example. )

EDIT:

Also, the currying example would look like this in Ruby:

    
    
        o = Object.new
        def o.my_method(x)
          self.y + x
        end
        def o.y
          10
        end
        method_as_fun = o.method(:my_method)
        method_as_fun[5]
    

You can argue for implicit currying if you want, but to me that's far more
confusing. That said, it is extremely rare to find currying used in Ruby code.

~~~
dnc
> Incidentally I don't know if that scoping example is intentionally ignoring
> the fact that Ruby does support lexical scoping (EDIT: for blocks), or if
> it's lack of understanding of what what "def" is

I also don't think it is fair to say that ruby "failed to nail lexical scope
in fundamental ways".

I like how it enables lexical scoping with blocks, instead of enabling it in,
maybe, more common way with embedded functions. To me, the ruby way is more
intuitive.

Also, 'breaking scope' with block (that acts as anonymous function) instead of
defining new (embedded) function feels more explicit wrt real scoping
intentions.

~~~
jpolitz
I've done a fair amount of programming in Ruby (two reasonably large Rails
applications, spanning about two years of development time). When switching to
Ruby from just about anything else that I program in from JavaScript to Python
to Racket to ML, I get tripped up on exactly this issue because it doesn't
match my expectations at all.

My gripe is that the simplest, cleanest construct in the language for defining
named functional abstractions---"def"\---doesn't support closing over
variables, which other languages do, so I have to warp my thinking a bit to
program in Ruby. The analogous program in the four languages I mentioned above
(and Pyret, and more) works and creates a closure. Maybe I just don't think
well in Ruby, because I end up feeling frustrated that Ruby seems to not like
functions.

All that said, "in fundamental ways" is a little harsh. At least in this
example, Ruby hasn't done anything to violate the integrity of static scoping
the way, say, JavaScript's "with" does. I'll try to see if I can come up with
a better example that's a clearer problem and less a personal dislike.

------
takikawa
Pyret 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/)

------
tinco
Why 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..

~~~
ek
I would encourage you to view the syntax as "Python, but repaired", for the
following reasons:

1\. Pyret comes out of Shriram's group's expertise with pinning down exactly
what Python and other dynamic scripting languages do right, and (mostly) do
wrong. Check out their recent paper Python: The Full Monty: A Tested Semantics
for the Python Programming Language
[http://cs.brown.edu/~sk/Publications/Papers/Published/pmmwpl...](http://cs.brown.edu/~sk/Publications/Papers/Published/pmmwplck-
python-full-monty/) for more context.

2\. Ruby is far and away not the originator of 'end' to end blocks -- this
comes from Pascal and is in other languages that have nothing to do with Ruby,
like Lua.

3\. Languages that aren't Haskell have ADTs too; it happens that they've
lifted an ML-style syntax for defining them.

4\. Python is widely used pedagogically, so for better or for worse, students
are already being familiarized with the colon, which I agree is a bit
anomalous.

~~~
timtadh
Thanks for the link to that paper. Super interesting to see actual semantics
for python come out. It would be nice if this leads to better tooling for
analysis of the language. Currently, it is pretty hard to bootstrap anything
for the language in comparison with what you can do for the JVM.

~~~
skrishnamurthi
You'd first have to fix Python's broken notion of scope. If you want to read
only one, simple, page, read the last page (appendix 2 on variable renaming).
Pyret was created to not have such problems by design.

------
zem
I 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.

------
tel
Python-like syntax with pattern matching and recursive ADTs!? What a great
idea!

~~~
rhizome31
+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?

~~~
ricw
I'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
We 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.

------
mageofmath
I 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
Wow, I didn't think of that. That is actually amazing.

------
klrr
This 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
My 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?

~~~
sparkie
I'd say the real trouble is teaching any syntax at all to beginners, because
their first language really taints them for life. Most people will think of
successive languages in terms of their first, until they learn many and are
able to think more generally.

Lisp has the advantage that it really teaches the general semantics of
programming languages, because it's syntax is just the syntax tree, and it
basically only has one form, which is function application. There's some
"special forms" built into the implementation of a lisp to make it useful, but
those shouldn't be confused with syntax. In fact, the parenthesis and space
between function and arguments shouldn't be considered _the_ lisp syntax
either - it's just one way to represent a tree structure in linear text.

I think the real issue is the confusion in teaching is between Computer
Science and Computing as a vocation. Nobody teaches the former any more,
because it's less useful _in the real world_. As a result, we have languages
which try to make a distinction between "programmer" and "programming language
implementer", where the programmer generally knows less about what he is doing
because someone has imposed a specific, narrow set of ideas on him.

~~~
skrishnamurthi
I've programmed in and taught Lisp syntax for 24 years, much of it exclusively
in that syntax. I've also extensively researched errors in parenthetical
languages.

The simplicity of parens is widely regarded as a strength, but I believe it is
also a weakness. There is too much regularity in the syntax, resulting in
numerous errors. Programmers, especially beginning programmers, need more
"guideposts" in their programs. Additionally, parsers also benefit from this
when producing errors.

The developers of Pyret are drenched in Lisp syntax; we know it profoundly
well. Pyret is a conscious attempt to fix what we regard as flaws with that
syntax.

------
kazagistar
Somehow, 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.

~~~
jpolitz
That's a useful comparison, thanks. While we were certainly _inspired_ by
Pythonic syntax, we have ended up somewhere slightly different.

The note about local variables is particularly important; we actively _don 't_
want Python's model of variables and scope.

~~~
kazagistar
Note: this wasn't a criticism of your language: I rather prefer lua's way of
doing numbers, co-routines, and even scoping to some degree. I was more
criticizing your comparison.

The language itself looks pretty slick, and I am a sucker for gradual/optional
typing. Do the type annotations result in performance/compiler optimization,
as in Julia?

~~~
jpolitz
> Do the type annotations result in performance/compiler optimization, as in
> Julia?

We've been designing the static system with exactly this in mind. The current
implementation doesn't do anything fancy yet, but that's just because we've
been getting off the ground and focusing on ergonomics and curriculum first.
Getting performance in return for types is absolutely where we're going.

------
b6fan
The 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
If one has to rewrite code like this, you're making our point.

~~~
b6fan
The 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
Thanks 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
I 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
The 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
_But you need mutation just to create examples of your data._

OK, I'll buy this.

------
jdnier
> 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-...](http://ceronman.com/2013/03/12/a-powerful-unused-feature-of-python-
function-annotations/)

~~~
skrishnamurthi
Unless 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.

------
kolev
I 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
This 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).

------
progman
Pyret 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
Thanks 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.

------
garysweaver
> 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
As you wish! We now have two Ruby examples on the home page. You may not call
it love. <-:

~~~
garysweaver
Thanks, 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.)

~~~
skrishnamurthi
I appreciate the examples may not be working for you. We'll try to improve
them.

However: Some of our programming environment's server infrastructure is built
in Ruby (mainly because it has great git support, and we commit all edits to
repos). One of Pyret's lead developers spent over a year on a widely-used RoR
system. We've given it far more than the old collegiate try. Some of us have
lived in it.

If you're happy with Ruby, great! We're not trying to convert you. But there
are people who would find the Ruby code we've written "natural" and the
resulting behavior thus unnatural.

We've had the same conversation with lots of JavaScript and Python users based
on our semantics work
([http://cs.brown.edu/~sk/Publications/Papers/Published/gsk-
es...](http://cs.brown.edu/~sk/Publications/Papers/Published/gsk-essence-
javascript/),
[http://cs.brown.edu/~sk/Publications/Papers/Published/pclpk-...](http://cs.brown.edu/~sk/Publications/Papers/Published/pclpk-s5-semantics/),
[http://cs.brown.edu/~sk/Publications/Papers/Published/pmmwpl...](http://cs.brown.edu/~sk/Publications/Papers/Published/pmmwplck-
python-full-monty/)). Some people are appalled, others don't get the point.
[This may be correlated with their reaction to Gary Bernhardt's WAT talk.]

But you also don't get partial static type-checking, etc. Again, those are
features that don't appeal to you, and that's perfectly cool.

------
jimktrains2
Mostly 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)

------
dragonbonheur
Those "new" languages keep looking more and more like BASIC.

~~~
gosub
We 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.

------
lars512
Incidentally, a Gist for installing Pyret using Marelle:

[https://gist.github.com/larsyencken/7424864](https://gist.github.com/larsyencken/7424864)

------
pekk
Looks more like Ruby than Python, why the comparison to Python?

~~~
skrishnamurthi
Okay, there's a Ruby example on the home page now, and probably one more on
the way.

~~~
skrishnamurthi
Second Ruby example is in place now.

------
pcmonk
I 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
That 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. (-:

------
yashodhan
dashes in function names! I'm in love.

------
JulianMorrison
This looks like it could be useful as a way to prototype a real program.

------
fedvasu
sounds like ML+contracts, but wait is it statically typed? Maybe not Racket
folks hate types (with great dredd)

~~~
skrishnamurthi
It'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
Sorry 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
If 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

------
breezydon
Pyret is so hot these days.

------
mrcactu5
it sounds great to blend Python and Lisp!

~~~
sparkie
Except it abandons most of the benefits of lisp.

~~~
skrishnamurthi
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.

~~~
samth
Well, the word "macro" doesn't appear on the Pyret home page ... :)

~~~
skrishnamurthi
No, but there is an AST module described in the documentation. (-:

------
mcpherson
functions are fun

------
kudu
> end

-.-

------
k_bx
> Python-inspired syntax for functions

> fun to-celsius(f):

> (f * (5 / 9)) - 32

> end

Wait a minute..

