
Pyret – A language exploring scripting and functional programming - gknoy
http://www.pyret.org/
======
gfodor
I've never understood the idea of a 'teaching' programming language. (Modulo
examples like Logo and Scratch, which offer much more than a language as part
of a wider teaching/computing system.)

You spend all this time ramping up on a language, toolchain, library, etc,
that you will eventually be unable to leverage beyond a certain point since it
is not one used by everyday programmers. The delta in "quality learning"
between a teaching language and a non-teaching language would have to be
astronomically high, imho, to offset the difference in capability and the
opportunity cost of learning an applicable skill to a wider problem set.
Something that is just a slightly better Python or a slightly better Clojure
for the purpose of illustrating computer science concepts seems like something
that you'd be doing a disservice to students to teach, vs the "real thing"
which they could carry for the rest of their lives into future projects ad
infinitum.

~~~
jswrenn
Languages such as C, Java, Python, and Rust are usually designed _by_
experienced programmers in industry, _for_ experienced programmers in
industry. Pyret, on the other hand, is designed by computer science educators,
_for_ computer science education.

This does not preclude Pyret from being a useful language for general-purpose
programming; it just means that language design decisions are driven foremost
by pedagogy. For example, Pyret trades performance for mathematical
familiarity by using exact representations of rational numbers as its primary
number type. Language like C, Java, Python, and Rust are all distinguished by
different priorities that have guided their language design, too.

I disagree with your characterization of any language as being the "real
thing" because it privileges some languages above others, but let's run with
it for a moment: A systems programmer might call Rust or C the "real thing",
in contrast to Python, and perhaps they would even consider delta "quality
performance". A sysadmin might call Python the "real thing" in contrast to C,
and consider delta "quality productivity". Assuming learning one programming
language does not preclude you from learning another, why shouldn't a computer
science education call "Pyret" the "real thing" and be asked to justify the
"delta learning" of moving to language that isn't designed with pedagogic
interests in mind?

(Disclosure: I am an occasional developer to Pyret, and this comment might not
represent the views of the rest of the team. If skrishnamurthi or jpolitz
replies, read their comment instead!)

~~~
dom0
> Languages such as C, Java, Python, and Rust are usually designed by
> experienced programmers in industry, for experienced programmers in
> industry. Pyret, on the other hand, is designed by computer science
> educators, for computer science education.

Honestly, looking at the examples on the Pyret main page makes me think that
this isn't a good approach at all. I have been in software engineering for
many years now and worked with quite some languages, yet I find the code
practically in-understandable and the language looks very complex. So likely
someone who "learned" using this language will have a lot of trouble actually
working with _real_ languages, assuming that he actually managed to learn this
language as his first, which is rather unlikely I believe.

I was also involved in CS education - in first semester programming courses.
And the language is really the last problem there (C was used, I think the
dept. is moving to Python for that course though). Especially eg. Python is a
good language overall and is already widely used in CS education.

In short, I don't see why the world needs this, and I actually think that
using it would be _actively harmful_.

~~~
jswrenn
What characteristics makes a programming language a " _real_ " programming
language?

~~~
threatofrain
The most important distinction would be that you don't have to make a
transition from education contexts to production contexts.

I mean, why isn't it possible to design a language that is both quite fit for
education & production? Is Python vs. Pyret really that big a difference in
education outcomes?

This is important for professors & TA's, educators, or enthusiast parents who
wish to teach their children. All have to master a toolset and environment
prior to teaching others, and maintaining the environment is also an ongoing
cost. Some of this cost will be assuredly transferred to students, so we want
to be sure that a "pedagogical" language without production traction has such
powerful gains that it offsets the losses.

~~~
skrishnamurthi
Yes, it _is_ a big difference, _depending on what you 're trying to teach_. If
you want to teach a conventional CS curriculum recognizable from the 80s,
Python is great (though some people really prefer teaching with static types,
which Python does not have and which are absurdly hard to add now). Here are
several other differences:
[https://news.ycombinator.com/item?id=13189513](https://news.ycombinator.com/item?id=13189513)

------
danso
Example from the OP:

    
    
            fun to-celsius(f):
              (f - 32) * (5 / 9)
            end
    
    

What's the justification for allowing the use of hyphens/dashes in reference
names, when underscores would seemingly provide the same purpose? One of the
most common problems I notice in newbie code is inconsistency in using
whitespace, e.g. `a-b` vs `a - b`, though in that situation, for Python and
virtually every other language I've used, those both result in subtracting b
from a. But in Pyret, it seems that `a-b` would be interpreted as a reference?
That seems needlessly confusing for no benefit in readability over using
snakecase.

Beginners frequently have issues with grammar, that is, they are pretty much
unaware of it when trying to figure out the many other things they have to
learn about programming. Even in SQL, I forget that it must be quite confusing
for beginners to parse out the meaning of the ` _` in something as simple as:

    
    
         SELECT mytable.*, (a * b) AS myproduct, 
              COUNT(*) AS the count
         FROM mytable ...
    

Doesn't seem worth it to make the hyphen, which is so frequently associated
with subtraction and negative numbers, have just a decorative meaning when
used between word tokens (as opposed to subtraction of values represented by
variables).

~~~
jswrenn
Pyret inherits hyphens-in-identifiers from Scheme/Racket. One of Pyret's
largest users, Bootstrap [1], has long-used a dialect of Scheme, and has
recently introduced a curriculum that uses Pyret. For these users, "virtually
every other language" allows for hyphens in identifiers.

Scheme mitigates the spacing issue with s-expressions. Pyret attempts to
mitigate it by enforcing that operators should be separated from their operand
with at least one space.

(Disclosure: I am an occasional developer of Pyret.)

[1] [http://www.bootstrapworld.org/](http://www.bootstrapworld.org/)

~~~
eridius
Scheme and Racket are both LISPs, with very different syntax. Hyphens in
identifiers aren't a hazard, because binary operators don't go between two
other identifiers, and operators must be separated with spaces, e.g.
subtraction looks like `(- 2 1)` instead of `2 - 1`. This means that using
hyphens in identifiers is quite safe.

But Pyret is using more traditional syntax, where binary operators go between
their operands, e.g. `2 - 1`, which means using hyphens in identifiers is a
hazard as the parent comment describes.

~~~
simplify
The problem is overblown. It's not going to cause any deep, hard-to-debug
errors. If you accidentally type `a-b`, you'll get an error message that says
"a-b is not defined". Fix it and you're done.

~~~
samcal
While I agree that the problem is not a very big deal, I think that you might
be surprised how difficult understanding compiler errors can be for newcomers.

~~~
CodeMage
I regard that as a valuable teaching moment: "This, kids, is a great example
of what you'll have to deal with all the time. Computers are not smart and
neither are compilers. Forget a semicolon or some whitespace, and it's your
job to clean up the mess after your compiler shits its bed."

~~~
dkersten
Having been a tutor of first-year beginner programming students many years
ago, my experience has been that its not quite as simple as this.

The number of people who forgot even the most simple syntax rules towards the
end of the semester, even after having shown them during each lab session, was
surprisingly high.

You tell them that the computer is super dumb and pedantic and they understand
this. So you tell them the rules (semi colon at the end of line perhaps) and
they understand. Then an hour later and they're staring blankly at the screen
wondering why they got the exact same error again.

Obviously not all students are like this and almost all did get it after a
while, but you'll be repeating your statement to them enough times that you
wished the language didn't have whatever warts is causing the confusion.

I found Java particularly bad, because you have to tell beginners to ignore
90% of the hello world program (class ... public static void main ... - you
have to tell them "hey, ignore class, public, static, void etc for now, we
will cover it later"), which isn't satisfying at all and in my experience
caused more confusion still...

Yes, you've got to treat it as a learning experience, but the students usually
see it as a roadblock and cause of frustration. Often one that doesn't make
sense to them and they question why its even a thing. ("why can I use '_' in
identifiers and not '-'?", not too hard to explain of course but its yet
another bit of incidental complexity to them)

------
mattangriffel
As someone who teaches coding to beginners for a living (I founded One Month
and I teach Python to business students at Columbia University), this language
looks really intimidating to beginners.

Maybe Pyret isn't for beginners, and it's intended to teach people who already
have some basic knowledge more advanced concepts like functional programming.
That's fine.

But to a total beginner, the syntax of Pyret is definitely a step back in
terms of readability.

In what world is:

    
    
      fun square(n :: Number) -> Number:
        n * n
      end
    

...easier for a beginner to understand than:

    
    
      def square(n):
        return n * n
    

I get that the intention of this language seems to be to help beginners avoid
some of the more common pitfalls that they may run into (ex. unexpected
parameters and return values), but it seems like they do it at the expense of
the total beginner's ability to understand and keep track of lots of new
concepts when they're just starting out.

~~~
adjkant
Pyret is inspired from Racket, which starts at step 1 with functional
programming. It's not about readability or getting people to learn as fast as
possible to write basic code, but to try and teach core program design
principles easily and build a solid base within a single semester. The syntax
is not as clean as Python, but it offers much more clarity in terms of
testing, signatures, and offers a very interesting method of writing loops
with map/filter/foldr.

I have a bias here, as I help teach an introductory course using DrRacket, and
many of my colleagues are very aware of Pyret, some even helping to develop
it. In one semester, however, we have students with a full understanding of
recursion, linked lists, many other common data structures, anonymous
functions, functions as data, and understanding of map/filter/fold and how to
use them. The class is specifically aimed at people who do not have prior
programming skills, and works very well in my experience. Yes, it is a lot,
but it builds an incredible base, and if taught to build on itself slowly, is
actually very minimal conceptually. The optional features in Pyret are
probably allowed with that in mind.

One of its weaknesses, arguably, is that it doesn't look like much else out
there in common use, since it's a Scheme. This syntax is an attempt to try and
make the same ideas translate to other languages easier, such as Python/Java.

~~~
emidln
If the goal is to teach functional programming with testing and signatures, is
the awkward syntax (that isn't really very close to C#, Java, or Python)
better than a set of macros on top of typed Racket?

It seems like it'd be easy to define a typedracket-derived #lang where you had
to write:

    
    
        (define (sum a b) : [-> Integer Integer Integer]
          (where (= (sum 0 1) 1)
                 (= (sum 2 2) 4))
          (+ a b))
    

And make the type signature and where clause non-optional with at least a
single test.

~~~
adjkant
I think that's a very valid question. I think Pyret is attempting to reach out
to people who may not view Lisp's favorably and still convey many of the
valuable concepts. Whether or not it is the right approach or if it will
translate properly is yet to be tested.

------
makmanalp
Yarr! Pyret always seemed like a great idea to me. It's still quite-scheme-y,
and so can introduce functional programming ideas easily, without the hangups
people normally have about syntax. It also has minimal weird-language-cruft
that is hard to explain to beginners, that you'd normally have to be like "ok
ignore the int argc, char __argv for now ". And it runs in the browser.
Awesome. Can't wait to get a chance to dig in further.

Also, try code samples in here:
[https://code.pyret.org/editor](https://code.pyret.org/editor)

Also, scroll down to see the comparison vs other languages:
[http://www.pyret.org/#examples](http://www.pyret.org/#examples)

------
labrador
I really like this sensible policy:

 _Some thoughts on syntax

We believe indentation is critical for readable code, but we don't want the
whitespace of the program to determine its meaning. Rather, the meaning of the
program should determine its indentation structure. Indentation becomes just
another context-sensitive rule.

Unambiguous syntax (the reason for explicit end delimiters) means you can
copy-and-paste code from email or the Web, and its meaning won't change. Your
IDE can help you reindent code without worrying that doing so will change the
meaning of the program._

------
eykanal
So, as someone without too much experience in language development, the
concept of having unit tests being an extension of the functions themselves
seems very interesting. Clearly this doesn't work for all scenarios—multiple
functions interacting, any sort of GUI interaction—but that's a very
intriguing concept.

~~~
jstimpfle
Is there something that prevents you from making functions that only check how
other functions interact?

~~~
eykanal
No, not at all. The point is that there's specific syntax in the language for
making this part of the function definition, as it were. New concept for me.

------
gr3yh47
Honestly imo Python is the best language to start with for learning.

It has all the basic constructs of both functional and object oriented
programming in plain english without a bunch of syntax to worry about. I
personally think it's the most readable language. it's also quite intuitive
imo. Lastly, there's a fantastic community and instant help is available for
all skill levels but _especially_ beginners on #python on freenode irc

Pyret... isnt very readable, doesnt seem very intuitive, has somewhat odd
syntax, and generally seems like a terrible choice for learning. Doubt it has
the resources quality python has (community, docs, tutorials)

i dont get it.

~~~
zem
i think the pyret syntax is wonderful, personally. it takes a lot of good bits
from my two favourite languages, ruby and ocaml, and blends them into a nicely
coherent whole. there are a few minor things i'd probably have done
differently, but on the whole i find pyret code very pleasant to read.

~~~
a0
> there are a few minor things i'd probably have done differently, but on the
> whole i find pyret code very pleasant to read.

Curious to know what would you have done differently. I'm working on a
programming language based on OCaml with Ruby-like syntax.

~~~
zem
just bikesheddy stuff like

* |> rather than ^ for the pipe operator (more consistent with several other languages)

* [list| 1, 2, 3] rather than [list: 1, 2, 3] (just for better visual distinction, though the current syntax does look pretty clean and uncluttered)

* having a separate code block for methods of individual variants rather than interspersing them with data definitions (because i think it's important that the basic data definition be as uncluttered as possible)

if you'd like some syntax feedback on your language i'd be happy to take a
peek :)

~~~
skrishnamurthi
I'd disagree with the second one. `[list: 1, 2, 3]` reads more like in
English: "I'm going to define a list: one, two, three…". Whereas `[list| 1, 2,
3]` has no obvious vocalization. (Vocalization is an important characteristic
for us; it's how `ask` came to have its syntax.) In addition, we usually use
`|` in programming languages in a separator kind of way (even `||` for "or"
separates expressions), which it's certainly not in the list expression.

~~~
zem
"list where the elements are 1, 2, 3", by analogy with set builder notation or
list comprehensions :) but i agree the current one reads better as english.

it's the separator aspect i was getting at with my proposal though - visually
it's [ datatype | elements ] whereas the current one looks more like the colon
is part of the first element - [(list : 1), 2, 3]

~~~
skrishnamurthi
Not once you learn to vocalize it, the way I just showed you how (-:.

Frankly, I'm really trying, and I'm having a _very_ hard time suffering from
the "list: 1" confusion you claim. I admit, that's just me.

Also, `|` as a separator suggests a kind of symmetry. But the two sides are
not symmetric at all. Whereas in English, `:` does not imply symmetry.

------
hajderr
"We need better languages for introductory computing." and "One of the
enduring lessons from the Racket project is that no full-blown, general-
purpose programming language is particularly appropriate for introductory
education."

Well not really, we need better teachers and methods for teaching programming
and computing. A good language on its own is not gonna lift the interest.

~~~
jswrenn
> Well not really, we need better teachers and methods for teaching
> programming and computing.

I think most of the Pyret developers would agree wholeheartedly! To this end,
the Pyret development team works closely (and in some cases, overlaps) with
Bootstrap [1], a nation-wide program to teach programming to middle school
students. The feedback we get from these teachers (and the process of teaching
teachers) directly informs language design.

Furthermore, at Brown University, where many of Pyret's developers have ties,
Pyret is dogfooded on two courses: an "Accelerated Introduction to Computer
Science" [2] and "Programming Languages" [3].

(Disclosure: I am a developer of Pyret.)

[1] [http://www.bootstrapworld.org/](http://www.bootstrapworld.org/) [2]
[https://cs.brown.edu/courses/cs019/2016/](https://cs.brown.edu/courses/cs019/2016/)
[3]
[https://cs.brown.edu/courses/cs173/2016/](https://cs.brown.edu/courses/cs173/2016/)

~~~
webwanderings
Is there a good quality MOOC on Pyret? I am not in high school but am not a
programmer either. I started using DrRacket MOOC fairly recently on Edx and
had no idea about Pyret until today. My interest in finding good quality
teaching, led me to Racket, all the way from the hype of Python/Ruby, and
anyone else in between. I am trying to follow Racket but now I am confused
between Racket and Pyret.

~~~
jpolitz
There is no MOOC I know of that uses Pyret (yet).

Racket is great! If you're already deep into Racket, I wouldn't say stop to
try Pyret unless you particularly have the goal of learning more languages, or
there's something about Pyret that really gets you interested.

We taught a programming languages course that uses Racket back in 2012, but
all the material is still online:

[https://cs.brown.edu/courses/cs173/2012/](https://cs.brown.edu/courses/cs173/2012/)

So if you're looking for online content that we recommend, that could be an
interesting next step that makes use of the momentum you have in following
Racket.

The Pyret book PAPL is free online, and it's possible to dive in and follow
that if you're curious about learning Pyret, though it doesn't have the
infrastructure of assignments with autograders, etc, that a MOOC would have:

[http://papl.cs.brown.edu/2015/](http://papl.cs.brown.edu/2015/)

~~~
webwanderings
Thank you. I am not deep into Racket yet, but it requires concentration which
I lack at the moment. Based on your suggestion, I'm going to stay focused and
attempt to complete, instead of distracting myself.

I started reading HtDP2e before finding the Edx. The MOOC helped reinforce
what I was reading. I realized that through Racket, learning to program is a
superior experience. This, compared to any other (popular) languages, people
are teaching (or coding on the screen). I spent too much time watching people
code. People attempt to teach online, but most of them lack the traditional
pedagogy. They know how to code, but they don't necessarily know how to teach.

The only exception I would make to above (as far as what I know right now), is
Harvard's CS50.

~~~
skrishnamurthi
Yep. Stay where you are. Work through the MOOC. You'll learn a ton.

------
AbrahamParangi
I strongly believe that people who are learning to program should learn in a
language that can actually be used to make things.

This may run counter to the 'work smarter, not harder' ethos I see here but I
feel that programming competency in practice is much more a function of
_literal hours_ writing code than any other factor.*

*with the caveat that competency tends to follow a sub-linear growth curve and people vary significantly with respect to their growth rate so this statement is more accurate when comparing individuals who are early in their growth curve aka beginners.

~~~
nine_k
People who learn to program have to get used to the idea that programming
languages are many, and they have to attain certain competence in _several_ of
them.

A typical frontend dev uses Javascript, CSS, HTML, likely some occasional
bash.

A backend developer probably faces the preferred backend language (Java /
Python / Ruby / PHP / whatever), SQL, and has to have at least a nebulous
understanding of HTML, CSS, and JS.

A devops person has to face a shell language, the Unix tools mini-languages,
have enough Python or Ruby chops to handle things like Ansible / Salt / Chef,
and likely some SQL to keep an eye on the databases.

This does not include smaller languages like regexps, or narrow-use languages
like XSLT, JSON Schema, etc.

There's no way you learn the One Practical Language That Matters and can be
limited to it. You could in past, with a Spectrum or a TRS-80 and Basic, but
the times have changed.

~~~
dom0
> There's no way you learn the One Practical Language That Matters and can be
> limited to it.

Most mainstream languages have very similar semantics overall, differing
wildly from FP-like approaches. So learning a mainstream-ish (imperative-ish,
OO-ish) language will enable mastering other mainstream languages with greater
ease.

If my first language is Lisp-1944, I'll likely have a hard time learning C or
Java. If, on the other hand, my first language was C, I'll likely have much
more and quicker success with Java, Python, C#...

~~~
nine_k
If the first language you learned was C, and you never rethought programming
from different angles, you'll miss the best parts of JavaScript, Python, and a
serious part of C# at least.

OTOH if your first language was Lisp (or even Python, to a lesser extent), and
it was _competently_ taught, the syntax of Java or C# would feel alien at
first, but you'd find out that many of the _concepts_ are already known to
you; chances are, you even have an idea how they work under the hood.

(Disclaimer: I majored in embedded systems, my first languages were Fortran IV
and PDP-11 assembly.)

------
nnq
Seems like a great _functional scripting_ language with _above-retard type
system._ This is _really cool_ , no sarcasm.

Just please don't label it as "educational" or "academic" or industry devs
will avoid it out of pure macho-ism :)

And find a way to marry it to a popular ecosystem, maybe a transpiler to js
(for nodejs ecosystem) or python or go. 'Cause _it really looks like a
language I 'd enjoy writing production code in if I could just `require` some
of my favorite libs and hit the ground running!_

~~~
jpolitz
Pyret's runtime is entirely built on JavaScript (seriously: you can load
[https://code.pyret.org/editor](https://code.pyret.org/editor), then turn off
the network, and your IDE still works), and Pyret programs compile to
JavaScript. At the command-line, it builds standalone JavaScript files that
run under node.

It's entirely possible to write pure JavaScript libraries that interface with
the language (the compiler expects AMD style and requires that you write some
small wrapping code). That's how the image library
([https://www.pyret.org/docs/latest/image.html](https://www.pyret.org/docs/latest/image.html))
works, for instance, and how we connect to Google Sheets
([https://github.com/brownplt/pyret-lang/wiki/TM028-Pyret-
and-...](https://github.com/brownplt/pyret-lang/wiki/TM028-Pyret-and-Google-
Sheets-\(Part-1\))).

Industry devs should be suspicious of Pyret's performance right now, though
that will improve as time goes on. We've been spending most of our effort
supporting our student and teacher users, so things that really build the
traditional out-of-the-box language experience aren't where a typical
application developer would hope.

I think that's fine since we've made our intentions and goals clear (the
educational audience and a coherent curricular design), and would be less fine
if we were offering Pyret as a general-purpose language today. Offering it as
general-purpose will become more and more reasonable as time goes on.

------
AstralStorm
Unexplained important things:

* concurrency, is there any nice built in syntax like Python async? Any kind of threading? Multiprocessing support?

* error handling, how is it done? Where are exceptions?

* standard and file io, string operations, serialisation?

* no builtin higher math types (matrix etc.), is math done on decimal floating point numbers?

* foreign functions, interfacing with other languages, embedding?

~~~
davexunit
Judging from the red/blue colors in the logo and that the website was
generated with Frog, I assume that once you feel too big for Pyret's shoes
you'll discover that you've actually been using Racket all along and will
start using the Racket language directly.

~~~
AstralStorm
But why? Best languages are truly general. This should aim to replace Racket,
not be bait for a switch.

~~~
baldfat
Racket is both a programming language and a framework for building programming
languages.

[http://queue.acm.org/detail.cfm?id=2068896](http://queue.acm.org/detail.cfm?id=2068896)

Racket is the most fun I have had in Programming and the more I "get it" the
more I enjoy it. I can't say that for any other language.

------
reacweb
When I was student, my favorite language syntax was Caml, the ancestor of
OCaml. I am surprise there was comparison with many languages but not OCaml.

~~~
throwaway009912
I was also surprised. The syntax they use is basically Standard ML. Also I'd
really like to see a paper on their static type checking, because they mix
objects and algebraic data types, which is not trivial at all.

~~~
mkolosick
Hi, I'm actually the person who wrote the static type checker. Essentially we
get around the difficulties of mixing objects and ADTs by having very limited
support for subtyping. This way we can still carry out unification-based
inference. The subtyping bounds are not propagated during unification so we
don't need to worry about calculating closures. This does mean that type
inference is incomplete with respect to subtyping, but I haven't found a
satisfactory system that would let us do otherwise.

I would also like to note that we do also have a new feature where types can
be inferred if you provide tests in a "where:" block attached to a function.
This infers a function's type solely from the examples of usage provided.

If you have any other questions feel free to ask!

~~~
throw_again99
Hi, thanks. Primarily I wondered about actual mixing of ADTs and objects,
which is limited even in OCaml, see e.g.:

[http://caml.inria.fr/pub/ml-archives/caml-
list/2003/06/bed28...](http://caml.inria.fr/pub/ml-archives/caml-
list/2003/06/bed2822602ed37484c166cef1d57f7be.en.html)

But does Pyret always translate an ADT to a class hierarchy behind the scenes?
This example sure looks like it does:

    
    
      data Animal:
        | elephant(name, weight)
        | tiger(name, stripes)
        | horse(name, races-won)
        ...
      end
    
      fun animal-name(a :: Animal):
        a.name
      end

~~~
mkolosick
Good question! Pyret does not translate to a class hierarchy. Pyret
dynamically allows dot lookups on both objects and ADTs. In the type checker
this means that an ADT permits dot lookup on any field that all variants have
(in this case, `name`), as this will always be safe.

Additionally, Pyret's type system internally tracks each of the different
constructors as a refinement on the type. With the animal example this would
be represented internally as something like

    
    
      Animal%(is-elephant)
    

if the type is known to only be an elephant. Though this is not used
everywhere it could be right now it is part of the system. This means we have
room to do things like if-splitting e.g.

    
    
      if is-elephant(x): ...
    

would be able to treat x as an

    
    
      Animal%(is-elephant)
    

in the body rather than just an `Animal`.

~~~
throw_again99
This is rather nice. You get a lot of convenience for that one type
annotation!

------
swat17
For what it's worth, I'm a student at the University at which J Politz
teaches. I haven't taken the programming languages course which is taught in
Pyret, but it's worth noting that it's an upper level course here and everyone
I know who's taken it is a fairly experienced programmer (relative to
university CS standards, of course). So, if the fear is that Pyret is an
unrealistic/overly complex/non transferable language to learn, it's definitely
not marketted towards beginners here. By the time you're taking this class,
you should already be well versed in Python and C++.

~~~
jpolitz
Hey fellow Swattie! [Actually, I'm at UC San Diego as of this fall, so I'm a
former fellow Swattie, I suppose :-) ]

The programming languages course in question
([https://www.cs.swarthmore.edu/~jpolitz/cs91/s15/](https://www.cs.swarthmore.edu/~jpolitz/cs91/s15/))
indeed used Pyret, and that course is a heavy functional programming
implementation course (writing interpreters, type inference, GC, etc).

That's using Pyret for more complex programming, and is the upper end of where
we use it pedagogically right now. Ditto for CS019 (the advanced introduction
to data structures), and CS173 (PL) at Brown. In all of those cases, students
_are_ expected to have some prior programming experience, so they get a faster
introduction to Pyret.

In the other direction, Pyret is in active use at the middle and high school
level in math, cs, and physics classes, and this is where much of our active
design work is tailored (tables, reactors, etc have some explicit curricular
goals they target). They have scaffolding and workbooks written for their
grade level, use features suitable for the context they are in, and so on.

The use in CS91 in particular is

(1) appropriate in the first place, since many functional languages could work
in that setting, (2) eating my own dogfood, and (3) an excellent opportunity
to discuss design decisions of a language that students are learning in a PL
course, while it is still having design decisions made about it!

------
phkahler
What's the point? One would hope they start with a description of why this is
better for education than something like Python. I just gave it a quick
glance, and it looks like many other programming languages - a bunch of odd
text gibberish. I don't think the problem dividing people into "gets it" and
"doesn't get it" has anything to do with nuances in syntax or semantics.

~~~
steego
Despite what the down voters think, I actually found this comment useful
because I had the exact opposite reaction. I took a quick look at the
examples, saw familiar syntax and features and quickly concluded it looks like
a nice toy, but I'd probably never use it because there are way too many
unknowns (Performance, runtime, buggy, etc. etc.).

I was actually a little flabbergasted when you said it looked like "odd text
gibberish", but then I took another look at the the first example and saw it.

    
    
        data BinTree:
          | leaf
          | node(value, left, right)
        end
    

Unless I'm familiar with union types, what part of that code tells me this is
a parameterized enum? Why should I assume we're even talking about data types?

I'm relatively flexible when it comes to syntax, but clearly syntax is a huge
hurdle that almost always gets in the way of adoption. I understand Pyret
isn't looking to be the next Python, but for an educational language I would
argue it's not living up to Python's Principle of Least Surprise. It's great
if you know Haskell, OCaml, Python and other languages, but it's not so great
if you're an unsuspecting student who's sharpened your teeth on Java/Python.

I suspect most people could pick up the syntax pretty quickly, but I suspect
most people still need some hand-holding on the first page. Most programmers
still don't know what this short paragraph means:

    
    
        Pyret allows for concise, expressive, recursive data declarations. Type annotations 
        are optional and can be added incrementally, to serve a variety of pedagogic 
        styles and curricular needs.

~~~
phkahler
>> Unless I'm familiar with union types, what part of that code tells me this
is a parameterized enum? Why should I assume we're even talking about data
types?

I have fond memories of learning to program as a kid. Concepts like trees,
nodes, and data types have no place in an introductory programming for kids.
The initial idea to teach is the notion of getting the machine to follow a set
of instructions. IMHO even functions should not be forced until that notion of
writing instructions for the computer to follow is mastered. Imperative is the
word I'm looking for. You need to start with that. Then move on to loops,
arrays (or list but don't try to explain the difference for a while),
functions. You don't want to require any of the concepts that we all take for
granted just to get started. Type systems? structures? Objects? Those need to
be introduced through examples where they are used to solve specific problems.

I have some examples of how an absolute beginner may think.

I was learning about BASIC and had worked up (yeah up) to using FOR loops, IF
and GOTO. Then I read about the PLOT(h,v) function which would light up a
pixel on the screen - awesomeness was about to ensue. But I had the notion
that - as the instruction said - I had to pass the variable h and v to that
function, not whatever pair I choose. That would mean copying values from
other variables (i.e. h=x, v=y, plot(h,v) and then h=i, v=k, plot(h,v)).
Fortunately that notion got cleared up very quickly, but it illustrates the
point that a noob may take something quite literally and not understand the
simplest abstractions that we all take for granted.

On another occasion I wanted to write Pac-Man so I had variables (we didn't
even had structures available) for the player and I figured I'd use x1,y1,
x2,y2, x3,y3, x4,y4 to track the positions of the ghosts. I could see in
advance that I'd have to replicate the ghost logic 4 times using different
variables in each instance (or write a subroutine and copy variables around
like I suggested above). What I wanted was to put the logic inside a loop (for
n=1 to 4) and reference the ghost variable as xn, yn but that wouldn't work
because those are just different 2-letter variables. So I asked someone if
there was a way to solve this and was pointed to arrays. The notion that a
construct existed that matched exactly what I wanted to do was amazing and I
felt like I really must understand something if my ideas about what should be
possible were already there. Try to imagine that type of discovery compared to
being presented a bunch of such concepts and being expected to understand form
the start.

When I got to college I figured I already knew programming. Hah! The data
structures course was incredible, I could already see how all of that stuff
could be applied to different things. It made perfect sense because I could
already imagine how to use it in all kinds of situations.

Even the most simple concepts need to be taught slowly at first, and
preferably to solve a specific problem. If your language requires too much
boilerplate, type definitions, or anything else it's too much.

So when I said this language looked like a bunch of gibberish, I was looking
at it through the lens of a kid who doesn't know shit about any of this.
Because for some reason I can remember what its like to think that way.

~~~
skrishnamurthi
I too learned BASIC first. It was fine for what it was. And computing has come
a long, long way from there, and our pedagogy has evolved substantially. In
fact, kids have no trouble with concepts like lists and trees — I see more
trouble with it from people who learned programming poorly before than people
who didn't learn to program before at all.

Also, nobody said Pyret is for kids (defined as pre-teen). It's not.

------
branchly2
Every time I see a project pop up touted as being simple and a good "teaching
language", it has some weirdness or pet features thrown in that turns enough
people off to keep adoption low.

If you want a good teaching language which will receive substantial adoption,
do this:

* syntax-wise, use curlies and semicolons like C, Java, Perl, JS, etc.

* use many of the good function names that Perl uses.

* have all variables be refs to objects, like Python does.

* use nice normal lexical scoping like Scheme et al

* this shouldn't have to be mentioned, but provide data literals for lists, maps, and sets

* keep it small, and written in C, like Lua.

* resist the temptation to complicate things by adding this really amazing advanced feature that it's just got to have to distinguish itself.

* plan for it to become used for general purpose programming, as it very likely will.

And some "don'ts":

* don't worry about performance, that can come later

* don't worry about lack of libs --- your implementation is in C, and you should get good ffi down the road. And with the substantial adoption you'll see, libs will come later anyway.

* don't have it be on the JVM, LLVM, or any other existing VM. Keep it simple. Even an interpreter is fine for now.

That's it. That's all you need to do for amazing success in a teaching
language that will also see serious adoption.

That said, no one does this. Presumably because if you're skilled enough to
implement it, you have some neat but obscure features you'd like to add, or a
unique syntax you'd prefer, which ... turns users off and keeps adoption low.

~~~
jpolitz
Thanks for the advice! What are some examples where a teaching language has
followed these points and succeeded?

What is the weirdness and/or pet features you see in Pyret?

~~~
branchly2
I'm an old curmudgeonly programmer (more hobby than pro), have kids in middle
and high school, and have some meager amount of teaching experience. Here's my
take: your students (especially in middle and high school) are generally a
captive audience. Maybe later, if they have more interest in comp sci, they
may be interested in using a more alternative language, but right now they
want you to give them something that looks mostly like the current lingua
franca and then get out of their way.

For the language I described above:

* it's like JS but with warts removed

* it's like C or C++, but higher level

* it's like Java but doesn't require types or the JVM

* it's like Perl but without the context rules and other zaniness

* it's like Python but with better names, more familiar syntax, and better scoping

(It's even a little like Scheme but with more conventional syntax, and regular
lists, maps, and sets.)

Students can use it in your class, then if they want to pursue programming in
earnest, can very easily segue to any of those common languages above. Not
only that:

* They can easily re-type their classwork programs in any of the above langs, and not feel like their teacher had them using something that was only applicable to their particular class.

* They can show their classwork programs to any JS/C/C++/Java/Perl/Python programmer and it will be easy for that person to make sense of what they're looking at (with no previous experience with the lang described above).

I have no experience with Pyret, and don't want to cast any judgement on it or
the people working on it. Maybe it's great and will benefit students even when
they move on from their class which uses it.

~~~
skrishnamurthi
Your initial list pretty much exactly describes Pyret. It doesn't have JS's
warts, but still runs in the browser entirely. It's higher-level than C and
C++. It doesn't require types or a JVM. It isn't like Perl in any of the zany
ways. It's a bit like Python and with totally sane scoping. And it's very much
like Scheme but with conventional (infix) syntax and lists, sets, maps… And
it's used in several high schools already.

------
good_gnu
For me, this looks MUCH more like Haskell than Python and I think that this is
symptomatic of an erroneous claim that some functional programming proponents
seem to constantly make: That declarative, "mathy","deconstructive"
programming is somehow easier to learn than imperative, "algorithmic", step-
by-step constructive programming.

In reality, most people in the world struggle with abstract mathematics and
find it much more intuitive to think about a program as a series of steps and
in terms of control flow. Programming beginners want to draw nice pictures on
their computer, not struggle with understanding and implementing some
recursive function.

This is of course not to say that recursion is not an important concept or
that functional languages have no merits. They are however complicated
abstractions over simple concretions that are much easier to understand for a
beginner.

~~~
natec425
Do you have any measurable (preferably peer-reviewed) evidence that suggests
imperative programming is inherently easier? That sounds like a challenging
claim to make.

~~~
nnq
> a challenging claim to make

...or more like the obvious intuition and wisdom of 99% of working software
developers. The intuition is not backed up by any peer-reviewed evidence but
by the _real world fact_ that most production code ends up written in C++,
Java, C#, JavaScript, PHP, Python,Ruby etc. and not Haskell, OCaml, F#,
Clojure etc.

Since they made the first stone tools and cave drawings, humans have always
defaulted to "how to" reasoning and not "what is" reasoning. You may have the
opposite intuition for the simple reason that 99% of what you read, write or
see on TV is produced by the the 0.01% percent of people with decent
communication skills and a larger percent of them have better developed "what
is" type thinking. Also, "what is" type knowledge is easier to communicate in
compact form.

Also, most people who tend to learn programming are "makers" types, like me,
which have a huge bias towards "process based intuition": for examples, for
us, intuitively, an "ellipse" is firstly "the abstract equivalent of what you
get by drawing a curve constrained by a string constrained by 2 pins"
([http://www.sems.und.edu/FrameA/SolarEclipses/ellipse.jpg](http://www.sems.und.edu/FrameA/SolarEclipses/ellipse.jpg)),
_not_ "the points whose sum of the distances from 2 fixed points is constant",
and a "bubble sort" is "what you get by walking over an array and for each..."
etc.

And the obvious companion to "how to" or "procedure based" reasoning is
extensive mutability because... this is how the physical world seems to work
at our level: even writing an equation on paper is actually just "mutating the
position of particles of ink from a pen to precise distinct locations on the
piece of paper", and results in "changing the information stored at particular
'addresses' of the paper. Even pointers ended up being used not because they
are a very smart or appropriate concept or anything, but because they map
obviously to the intuition of "pointing at things scribbled on a piece of
paper or a blackboard"...

But yeah, "how to" reasoning scales horribly, creates huge misunderstanding
and communication problems, and is extremely hard to debug, and we should
start moving software engineering past the "cave drawing" stage... but this
doesn't mean we should ignore where we're starting from :)

~~~
jhbadger
Based on ancient literature and holy texts, people from early cultures seemed
to be obsessed with their lineage, stating "I am X son of Y, who was son of Z"
etc. Do you think they thought about it in terms of procedures for determining
lineages or just definitions of relationships? The latter would be easier to
model in languages like Prolog rather than C++ or Java.

~~~
nnq
Their kings were. Imho there's a certain minority of people, maybe 0.001%, who
are definitely not what I call "makers", with waaaay above average
"communication/leadership/manipulation + sword swindling" skills who end up
kings/emperors/etc. (at least the first time; then it's just because they were
born in the right bloodline - hence another reason for "bloodline obsession").
And their scribes (the guys with good communication but bad sword swindling
skills and of the wrong bloodline).

The rest of the people were more obsessed with "what steps to follow to plant
my seeds in the ground so as to increase the probability of crop yield" or
"what steps to take when preserving food so as not to get really sick" or
"what steps to do in what order when building my house do it does not fall
down on me at the next storm" etc.

Oh, and lineage is pretty much retrospective "how-to knowledge" anyway: it
describes what the sequences of actions where that resulted in someone
existing today: 'X1 and X2 _had a baby_ ", then "the son of X1 and X2
_married_ Y0" and " _moved_ to village Q" after " _fighting_ in war Z" etc.
History is pretty much recorded procedure.

Not until we got to philosophy, geometry and other types of math did we really
have clear what-is knowledge... (Except maybe for religion, and no wonder that
smart priests and monks were pretty damn good at math.)

As an example, go to any remote village with and ask them "where is X" and
what they'll inevitable tell you is "what actions to perform to get from here
to place X". (The infuriating part is that some of the modern humans kept this
thought pattern and good luck getting indications to how to get anywhere from
them... thank god for the "what is" knowledge provided easily by google maps
:) )

------
sergiotapia
I really like the idea of tests right beside the code. I don't like how it's
code though. Muddles what the actual implementation is a bit. Maybe with more
usage the where statements start to blur and you don't notice them as much.

I like Elixir's approach better where your test cases live as documentation
examples in comment form, right above the function declaration. It's fantastic
and free. Your mix test command runs tests, in addition to any examples you
have as tests.

[http://elixir-lang.org/getting-started/mix-otp/docs-tests-
an...](http://elixir-lang.org/getting-started/mix-otp/docs-tests-and-
with.html)

You put your tests as comments below an ## Example header. Oh and these
examples go into your auto generated documentation as well. Ridiculously
effective and free. You feel bad not using them.

~~~
jpolitz
Pedagogically, the nice thing about the examples/tests just being code for
beginners is that they are... just code!

Once we've taught students about function calls and values, it's a small jump
to write an example with "is" in the middle. The syntax errors, static errors
about unbound identifiers, and dynamic behavior all act the same as everywhere
else in the program, so it's less friction to write the first test.

For getting off the ground writing that first test, I've been really happy
with what Pyret lets us do. There is more involved in getting better
testing/reporting options as systems scale up (we have lots of test-only files
for the compiler), but pedagogically, the testing block infrastructure has
worked well.

------
fridsun
I've long thought that Haskell is much more intuitive than any engineering
languages out there for people with no programming experience, since it builds
on mathematics that everyone has already learned. It's great to see functional
programming placed at the center of intro-level programming teaching.

------
sdegutis
> _" while exploring the confluence of scripting and functional programming"_

Scripting and functional go amazing together, as long as it's (mostly) dynamic
typing. In general, types really just get in the way when scripting or
prototyping or trying to do anything fast, especially when you don't know the
types of data you're going to be working with ahead of time, e.g. when it
comes from a file or from an external API, etc.

But what is BinTree in the following example on the website? Is it a type? Is
it a function, or constructor, or what? I'm confused.

    
    
        data BinTree:
          | leaf
          | node(value, left, right)
        end

~~~
xearl
> "In general, types really just get in the way when scripting or prototyping
> or trying to do anything fast"

I've found the opposite of that claim to be true. Types are absurdly helpful
in prototyping or trying to do anything fast, especially when exploring data
coming from a file or an external API.

Anecdotes aside, BinTree in the example is both a data type and a type testing
function ("detector") of signature `Any -> Bool`. See
[http://www.pyret.org/docs/latest/Declarations.html#%28part._...](http://www.pyret.org/docs/latest/Declarations.html#%28part._s~3adata-
decl%29) for details.

~~~
AstralStorm
Types are great unless you are forced to be explicit instead of the compiler
doing automated type deduction.

------
gre
The docs at
[http://www.pyret.org/docs/latest/](http://www.pyret.org/docs/latest/) link to
the outdated book. Update the link?

~~~
skrishnamurthi
Yes, thanks. We weren't expecting to end up on HN today. (-:

------
yagga
"We need better languages for introductory computing. A good introductory
language makes good compromises between expressiveness and performance, and
between simplicity and feature-richness. Pyret is our evolving experiment in
this space."

Object Pascal is the best language I know for education.

Programming education first must be about understansing algorithms I think.

However, learning something old or not useful in real world can be harmful.
The best I think is to learn modern tech. The development world evolves too
and other skills become more relevant.

------
thecity2
Why not just use the "easy" parts of Haskell as a teaching language for
functional programming?

No monads, applicatives, etc. No category theory. Just immutability, laziness,
pattern matching, and type classes. I feel like that makes as much sense as
developing an entirely new language that most likely will only be used by a
complete novice. Conversely, one can grow with a language like Haskell for an
entire lifetime. Just my two cents.

~~~
skrishnamurthi
Because we also use Pyret to teach program complexity, and big-O is a whole
'nother can of worms in Haskell (the cost model is totally non-traditional).
Because we use Pyret to introduce students to state, and even basic equality
is a whole 'nother can of worms in Haskell. Because we teach basic algorithms
in Pyret, and even something like DFS in Haskell is complicated (because of
the preceding issues).

~~~
codygman
> even basic equality is a whole 'nother can of worms in Haskell

How so?

~~~
skrishnamurthi
I'm afraid I don't have time here to explain Haskell. Think about how graph
reduction and reference equality would interact.

~~~
codygman
I know a fair amount of Haskell. For instance I know Haskell doesn't use
reference equality.

~~~
skrishnamurthi
And the lack of it makes it hard to test for things like node equality when
doing graph algorithms. There's an extra layer of encoding you need to be able
to simulate reference equality. And even if you addressed the equality issue,
I brought up two other issues that you didn't address.

------
vog
_> Functions can end in a where: clause that holds unit tests for the
function. These assertions are checked dynamically._

Wouldn't it be even better to check these statically, such that a program with
failing unit tests doesn't even compile?

There may be tests that can't be checked statically, but I think these
wouldn't quality as unit tests anyway. (These would be more at the level of
integration tests.)

~~~
skrishnamurthi
Tests are, by definition, checked dynamically. And setting aside terminology,
there's a small issue called the Halting Problem that makes most tests unable
to be checked statically.

------
romanovcode
> Pyret is a programming language designed to serve as an outstanding choice
> for programming education

For me these examples look super complicated.

~~~
jpolitz
Thanks for the feedback – we've gotten this a few times, and I think the
homepage is targeted too much towards getting across Pyret's design to an
already multi-lingual audience, and not enough towards actual beginner uses of
the language (of which we have many).

This is something we're working on changing to make it easier to see what true
beginner examples look like.

------
Insanity
The annoying banner was distracting from the actual content unfortunatenly.
From what I did see I don't see a reason to start using it in education to be
honest. I don't see the problem with just teaching Java or Python. Sure it
might be a bit harder, but it's what you'll end up using in the real world

~~~
skrishnamurthi
[https://news.ycombinator.com/edit?id=13189513](https://news.ycombinator.com/edit?id=13189513)

------
leeoniya
[http://www.nicolasbize.com/blog/30-years-later-qbasic-is-
sti...](http://www.nicolasbize.com/blog/30-years-later-qbasic-is-still-the-
best/)

------
rogerbinns
I'm somewhat confused by the indentation rules. Is this code valid?

    
    
           fun abc(d):
         d+1
                 end

~~~
jswrenn
Yes, Pyret is totally indentation-insensitive.

~~~
skrishnamurthi
FOR NOW. We have a plan for making the indentation checked but it's not been
our top priority, but it is on our stack. Languages take a while to cook.
Welcome to the kitchen. (-:

~~~
rogerbinns
I must admit to being a fan of the python approach. My example code above is
obviously "wrong", and is immediately so in Python. In other languages it is
valid, and then brings a burden for a reader of trying to determine why the
indentation doesn't match the intent. Since code is read a lot more than it is
written, that seems like pointless complications for no real benefit.

~~~
skrishnamurthi
You're conflating two things. Indentation can be _enforced_ without being
_semantic_. In Python, indentation is semantic: if you move certain statements
two lines out, you've changed the meaning of the program.

In Pyret, our goal is to _enforce_ indentation but never make it semantic:
i.e., there's an unambiguous place for every bit of code. You can select-all
and hit Tab in the Pyret editor and it'll reindent your whole program
according to the rules. We just haven't yet implemented the _checker_ for
these rules (in part because we still don't all agree on exactly what they
will be). Once we agree, the program you wrote would be a syntax error, but a
user could have the system automatically indent it for them to make it right.
(Even now, they can have the line be automatically indented for them.)

------
PudgePacket
Looks fun actually ! Lots of critique in here, but you know what they say,
there are only two types of languages ;)

------
ebbv
No offense but I really don't think it's a good idea to teach beginners a
language with such a goofy syntax. It's fine if you want to make a language
with a unique and "innovative" syntax. But beginners are best served by
learning something mainstream, and ideally simple. They can expand into crazy
stuff as they are ready for new languages.

~~~
AstralStorm
The syntax is the converse of innovative. Standard ML is very old. End keyword
telegraphs Pascal and Algol.

About the only new thing here is the testing, documentation and contract
support and it is great to have.

------
kofejnik
tbh, it looks like ruby with minor changes

~~~
AstralStorm
It is quite different syntax from Ruby.

------
xbeta
Yet another language - excuse for my lack of context/background, but why? If
you go into a job now, how many will expect you to code in Pyret?

Don't get me wrong, I love learning new languages and every language does give
me a slightly different perspective when it comes to programming. It sometimes
change how I think in my mind to code.

But do we need a new language just for the sake of someone wants to write a
new language?

~~~
AstralStorm
We do. I'd love a more readable variant of Rust for example, with built in
testing and contract support.

