News for hackers. Stuff that matters.

cdsmith

Re:Upcoming/proposed breaking changes to Haskell on Thursday November 18, 2021 @12:09PM (#29267772)
That is certainly an interpretation that has been retrofitted onto the motto...
Re:Upcoming/proposed breaking changes to Haskell on Thursday November 18, 2021 @12:07PM (#29267748)
As for why... it's complicated.

On the one hand, this is a change whose software engineering benefit is very small. (There is a small performance advantage, but it's not significant.) It has a large aesthetic benefit, though, in that it makes the standard library have one less ugly wart. But that wart wasn't really doing anything except being ugly. Some community members have a point of view that "ugly" shouldn't matter, and that in particular, the bar for breaking changes should be very high, and far higher than wart removal.

On the other hand, this particular change should affect extremely little actual code, because defining (/=) explicitly is dumb. When it does affect code, the solution is just to delete the lines of code that are doing the dumb thing. They don't even need to be replaced, because the only reasonable behavior is already provided by the default. Just deleting the dumb code is enough.

On the OTHER other hand, even a small amount of code change can add up to a lot of dependency management work. If just one library somewhere at the leaf of a dependency tree needs it's explicit (/=) deleted, then version bounds need to be added for all upstream bodies of code to ensure that they don't try to build against the old now-broken. Changing all those version bounds across perhaps dozens of packages is far, far more work than just deleting those few lines of code. You can look at this as a broken process, but I don't think anyone has a great answer to dependency management.

So I think it's in the end kind of a coin flip between (a) it's infuriating to some people not that this specific change is being made, but that it indicates the community values aesthetics above backward compatibility, and the absence of almost any practical software engineering benefit makes this a compelling test case upon which to direct their fury, and (b) despite the tiny amount of actual code change, it's quite possible it could lead to a non-trivial amount of coordination work between libraries, and THAT is a real (and not very fun) job.

Re:Upcoming/proposed breaking changes to Haskell on Thursday November 18, 2021 @11:54AM (#29267593)
One of the most important lessons learned by the Haskell community is that we shouldn't worry about whether complete type inference is possible. We should worry about whether type inference can be maintained in the easy cases, while falling back to explicit annotation for the hard cases. All of rank-n types, GADTs, type families, even basic type classes, break complete type inference. The solution has always been to document the limitations, draw as clear a line in the sand as possible, and then go on and introduce those features. This doesn't affect the usability of the language.

What does affect the usability of the language is when (a) the line in the sand isn't very clear from an end-user point of view [see simplified subsumption in GHC 9, for example], or (b) the line is on the wrong side of simple features [see monomorphic local bindings, for example].

I guess what I'm saying is that Idris having minimal type inference is kind of terrible, and the excuse that it's not decidable for dependent types is a flimsy one.

Re:Upcoming/proposed breaking changes to Haskell on Thursday November 18, 2021 @11:46AM (#29267492)
Yeah, I'd say that Haskell has done a phenomenal job for most of its history of maintaining a balance between the interests of researchers, commercial programmers, educators, and enthusiasts/hobbyists. At different times, each of these communities has been inconvenienced by decisions made by the Haskell community, but the community has nevertheless been for the most part welcoming to all of them. On the other hand, some of the darkest chapters of the community have involved power plays where one of these groups feels entitled to sideline the others and decides it should be in charge.

By contrast, a typical mainstream programming language might, say, completely neglect one or more of these communities in favor of whatever is best for commercial programmers. Particularly when, like most mainstream languages, it's mainly funded by those interests.

Re:Why I Support the Haskell Foundation on Thursday June 17, 2021 @02:11PM (#27542590)
Fair enough. For my part, I didn't include that comment as just an obligatory remark, though. I did so because it occurs to me that, for instance, the only tech community I'm involved in where I have regularly met people who identify as non-binary gender is Haskell. I don't think that's entirely a coincidence, and I do think it's related to the strong role played by non-industry Haskell programmers in the community. So I said so.
Re:Why I Support the Haskell Foundation on Thursday June 17, 2021 @07:50AM (#27538556)
As the author of the article, I hope it's clear that we're talking about the community that has formed around the programming language. Racial diversity isn't, to the best of my knowledge, mentioned at all in the Haskell Report or the source code to the GHC compiler. But when I'm talking about the community, that is all about the people in that community. Some of the people in that community have very different backgrounds from myself, and I think that's a valuable thing to celebrate and acknowledge.

That said, it wasn't the point of the article. It's fast becoming the point of this comment thread, though, which is unfortunate.

Re:Why I Support the Haskell Foundation on Thursday June 17, 2021 @07:16AM (#27538381)
Thanks for the question. I'm the author of the article, and I can talk about why I included that paragraph. It's not because everything has to be about racial diversity. Rather, it's because I was already writing about some kinds of diversity, and when I reflected on people I know in the Haskell community, I realized that we've got some pretty interesting characters, and that this is due to communities like Tidal Cycles. Tidal Cycles is a great example of why something that's not at all important to corporate sponsors is nevertheless a cornerstone of the language community. I've had the chance to meet some really interesting people with interesting stories who I wouldn't have met if Haskell were just a language for writing web services.
Re:Gibbard’s Theorem vs. Stable Matching on Friday June 04, 2021 @11:24PM (#27401831)
To be clear, the algorithm is proposer-optimal only when compared to other stable matchings. It is still possible that there exists some other matching that would make all proposers happier. It just won't be stable: there will be some pair of proposer and proposee that could switch to immediately increase their happiness, BUT it would set off a chain reaction of further swaps that leave everyone less happy in the end. This was a bit surprising to me.

There's a variant where you run the deferred acceptance algorithm, but then only the proposees who never rejected anyone finalize their decision. All other proposees and their matched proposers split up, and the whole algorithm is run again with the unmatched participants. This time, you end up with a Pareto-optimal matching for the proposers, with respect to their stated preferences. That is, there's no possible way to make anyone happier without making someone else less happy. But it's not stable, and the algorithm is no longer strategy-proof. (In fact, one can prove that no strategy-proof algorithm can guarantee a Pareto-optimal matching!)

Re:Gibbard’s Theorem vs. Stable Matching on Friday June 04, 2021 @11:09PM (#27401744)
If the result of the election is the choice of two finalists, then as long as there are more than two candidates, there are more than two possible outcomes. For example, if the candidates are A, B, and C, then the possible outcomes are: (A and B), (A and C), or (B and C), so 3 in all. In general, for n candidates, there are n * (n - 1) / 2 outcomes. By Gibbard's Theorem, then, either there is a dictator, or there is strategy.

Another way to see this: the entire process of choosing two finalists and then having a runoff to choose an ultimate winner counts as a collective decision-making process. That there are two separate votes doesn't actually matter. By Gibbard's theorem, then, if there isn't a dictator, then the entire process is strategic. Since the chance to use strategy doesn't occur in the simple-majority final runoff, by process of elimination, it must occur in choosing the candidates who qualify for the runoff.

Re:Gibbard’s Theorem vs. Stable Matching on Friday June 04, 2021 @02:33PM (#27397232)
Author here. No, it doesn't mean that. If the election is held to determine who wins, then the outcome is who wins, and everyone has opinions about that same outcome.

Contrast this to the matching problem, where the outcome is where ALL the candidates are assigned. You're allowed to have an opinion about where you are assigned. I'm allowed to have an opinion about where I am assigned. These opinions might conflict indirectly because of limited spots, but they don't conflict directly. This is very different from the election case, where if you and I have different opinions about who we want to win, those opinions are always contradictory.

Keep in mind that this article was written by a reporter who was unable to talk to the district, and got all their information from a lawyer representing the kid who was suspended. The district itself is prohibited from releasing any information about the case by privacy laws, no matter what the family says or how accurate it is. The same evidence was presented to the school board in an appeal hearing, and they (granted, probably not technical people) did not find it convincing. That doesn't mean the family's lawyer is wrong, but it is worth keeping in mind as you evaluate this. We don't have the whole story here.
Something's weird with that. Gwinnett County schools are out for the summer starting late next week. Most of the "three months" will be when school isn't in session, unless he was planning to attend summer school.
Re:Continued Fractions in Haskell on Wednesday April 21, 2021 @09:18AM (#26889271)
Mathematicians use words differently. What you're talking about is what the article calls a generalized continued fraction. Generalized continued fractions are not unique, and there are actually many of them for pi, which have different rates of convergence. The article here contains a (different) nice generalized continued fraction for pi, and an algorithm for converting from generalized continued fractions to standard ones, thereby computing the exact standard continued fraction for pi as a result.

(These were later edits to the article, so if you read it early on, you may not have read those parts.)

Re:Continued Fractions in Haskell on Wednesday April 21, 2021 @09:14AM (#26889218)
It's actually worse than that. Even knowing the very first term of the continued fraction result would already tell you that the number is at least 2. So the computation will hang without ever producing even a single term.

This is a fundamental problem shared by any form of exact real arithmetic with unique representations; you can always then be forced to make a choice, before emitting any information, that depends on infinite amounts of information about the operands. To solve this problem, you would need to choose a representation with redundancy. (With redundancy, equality comparison becomes harder, and it can still diverge, but you can still get approximations of the answer.)

Re:Continued Fractions in Haskell on Wednesday April 21, 2021 @09:09AM (#26889175)
As the author, I have just updated the article to try to make this clearer. Thanks.
I'm puzzled that you feel we are losing this, when it seems clear that with every passing day, we are moving further and further into a world where anyone can freely express anything they like. You and I and everyone around us has the ability to write whatever opinions we have, and immediately share them to tens of thousands of people. This is something that would have been unthinkable 20 or 30 years ago. Groups that were for much of history suppressed by dominant cultures are now vibrant and active. The LGBT community certainly doesn't wish for a return to the past, for instance. Whole social movements have been organized between people who, prior to recent history, would have been logistically unable to communicate with each other.

At the same time, certain people have views that are morally abhorrent. Or, heck, even just not very interesting. It's important to NOT to shoehorn some kind of homesteading right over public attention in the name of free speech. In the past, society's way of protecting itself against this was mainly that speech was expensive, and extremists frequently lacked the money to impose themselves on others' attention. This was in some ways a horrifying way to solve the problem, since it suppressed the disadvantaged, and didn't work anyway. In any case, it's gone. Speech is no longer expensive.

What remains to see how we can regain some semblance of sanity in a world where all public communication devolves into people shouting at each other. I'm sick of living in that world. I don't particularly care whether Facebook takes down Trump's comments; they've already been heard. But I do care about notions of free speech that prevent tech companies from trying to solve the pressing social challenge of how to let people regain control over their own attention spans.

That's exactly what it is. It's all Haskell, just with tuples as arguments. If you want normal Haskell back, just do this:

    {-# LANGUAGE NoImplicitPrelude #-}
    import HaskellPrelude
    import CodeWorld  -- for pictures, colors, etc.
The stuff from CodeWorld is still uncurried, but the rest of the language is still there.
Yes and no... not to make it easier, per se, but to make it more like math. I built CodeWorld, not to teach Haskell, but to teach middle school math! So the main motivation was to make it easier for students to see the connection between the functions they write here, and the f(x,y) that they see in algebra.

That said, uncurrying functions also has a huge benefit when it comes to understanding error messages in Haskell. I love currying in Haskell, and it's very powerful... but it's one of the features that sometimes leads to obscure or misleading errors -- especially when you leave out type signatures... which I do for the first month or two.

Hey! I built CodeWorld. Thanks for the kind words!

Yeah, the examples are a mess right now. Let me point you to a couple things: first, there's a partially complete tutorial (click the Help button) with some simple examples. Second, (and this is very early on, so please be forgiving!) there's a draft of a textbook at https://docs.google.com/document/d/1NbMtySIDNK40Bk4ImrUAE95S... So yeah, we're working very hard on fixing the documentation issues. Patience!

I don't have such a good answer about syntax. The syntax is about as good as I can make it. There is autocomplete (Ctrl-Space) for built-in function names, and brace highlighting, and I'd love to work on more features to make the programming more interactive with immediate feedback. I also wrote a simplified version of Haskell's standard library and wrote a simple post-processor to reword the more confusing error messages, in an attempt to make it easier to find and fix problems that do occur. If you have ideas or find particularly bad examples, please add a quick example at https://github.com/google/codeworld/issues/new

If this doesn't work, and you look for alternatives to teach programming to your daughter, you might consider Scratch or (if you're still into doing it with functional programming) bootstrapworld.org.

Thanks for looking!

Re:Teenage Haskell on Thursday July 03, 2014 @04:50PM (#7985711)
There are various arguments for the benefits of functional programming. But that's really beside the point here.

In this particular case, the point was that I created an educational tool for teaching mathematics. It happens to involve a programming language; but the goal isn't to train computer programmers. It's to teach math. So the language used is one that lets you describe functions and quantities the same way as you would in math, and mostly avoids the need to think about a computer doing some sequence of operations.

Re:Teenage Haskell on Tuesday July 01, 2014 @08:11PM (#7974320)
> I don't get this example. If the function is f = t, where t is time, then f will give different results on Wed and Fri.

I assume you meant something like f(t) = t?

If so, then right, if you pass in the current time as a parameter to the function, then the result can depend on it. But in Python, you don't pass in the current time. That's because "function" means something entirely different in Python.

In math, at the simplest possible level [1], a function is a set of ordered pairs, with the property that no two different ordered pairs have the same first element. That's all there is to it. So when I write f(x) = 3x - 5, that's just shorthand for saying that f is the infinite set { (0, -5), (1, -2), (2, 1), (1/2, -7/2), ...}. That's all there is to it. There's no sequences of operations, no process, etc. It's just a set of ordered pairs.

Python's functions, on the other hand, are at their core a sequence of instructions. Some of those instructions (like loops or conditionals) have other sequences of instructions as components. They share an environment, which consists of storage locations called local variables. A Python function is actually a pretty complex thing, when you get down to it.

You could model Python's functions using standard mathematics, if you play some tricks: add hidden parameters, give interpretations to the results in terms of physical effects, etc. But this just tells you that math is powerful enough to model Python functions (and, well, anything else) in terms of its much simpler ideas. It doesn't mean that those ideas are the same as the things in Python that go by the same name.

> For example, I can build a graph of a parabola in Python. The way my code does it is pretty much the same as if I did it by hand with a pencil: I assign multiple values to x, and find corresponding values for y.

Okay, but you're describing the process of drawing the parabola. In math, f(x) = 3x^2 + 2x + 1 isn't a process for drawing a parabola. It is a parabola. So f, here, is itself the set of ordered pairs, which make up a parabola if you treat them as points on the coordinate place. That's the basic difference.

[1] Okay, for the pedants out there, this depends on your choice of foundations. I'm assuming the standard interpretation using ZFC, but a similar point would apply if you prefer a different foundational theory.

Re:Teenage Haskell on Saturday June 28, 2014 @05:30AM (#7957836)
It's worth mentioning that the tool this blog post is about defines a simplified version of Haskell's standard library. In particular, there are no type classes exported from Prelude, much less monads or functors. In the end, it's not really any more complex than Scheme, except for syntax.

Now, true, the syntax is much more complicated than Scheme. You can operators and precedence and all that. But while definitely complex, it is mostly consistent with math notation. I tried to teach with Scheme first (following www.bootstrapworld.org) before I created this, and I found the change in syntax from what they are used to can be a real obstacle for children. This is also consistent with the comment about MIT moving to Python, which similarly has much more complex but familiar syntax.

Re:Teenage Haskell on Friday June 27, 2014 @10:59PM (#7957299)
Basically, the difference is that in a functional programming language, words like "variable" and "function" have the same meaning they do in mathematics.

In C or Python, a "variable" is a storage location in which you can place different values at different times. This is completely different from mathematics, where "x" doesn't equal something different just because you progress to the next step of computation. (But "x" might refer to something different in a different context, such as when evaluating a function with a different argument; that's the sense in which it varies.)

Similarly, in mathematics, there's no such thing as a function that returns something different each time you evaluate it, or that gives one result on Wednesday but a different result on Friday, or that even gives no result at all but causes letters to appear on a nearby computer screen. Yet in C or Python, all of these things are called functions.

At first, it might seem surprising that you can do much programming without the C or Python version of functions and variables. But:

1. You can do more than you think without reassigning variables or using functions that aren't "real" functions in the sense of mathematics, and

2. Of course, in the end, all languages - including functional languages - do have a way to create boxes to store values over time, or to perform actions that make things appear on computer screens. It's just that in a functional language, these things are not the basic bread and butter tools of programming to the extent that they are in C or Python. So you have variables and functions (in the mathematical sense), and you also have other things that act like storage locations and actions, but you only use the latter when you have a real need for them.

That's the general character of the difference. There is, of course, a lot of detail that I am leaving out in a response on a web site.

The reason people were speculating about whether this would work better with people not yet accustomed to programming is that it's often thought that experience in an imperative language (like C or Python) leads you to naturally try to do things with actions and storage locations, even when it's not necessary... and then it can get frustrating and confusing to work in a language where most things are actually not done that way. There's a theory that says if you maybe learned the functional way first, you wouldn't find it as frustrating.

I'm of two minds about that. I spent a year teaching Haskell with this system (I'm the Chris Smith mentioned in the article), and I found that it's partly true that students don't get as frustrated... sometimes. But there are other cases where students naturally fall into trying to do things in imperative ways, despite not having past experience in a programming language. I actually think, computer programming aside, that this is one of the things that trip up kids in math classes. So it's not just programming languages where this comes up: a lot of teachers present math as step-by-step processes, as well. Essentially, they introduce imperative programming without the computer. This is what happens when teachers tell students that parentheses are about what to do "first", instead of about which sub-expressions are meaningful on their own. Partly, I think this is just how the human mind works, too, and it's an inherent tendency that we have to overcome to really "get" algebra and other mathematics in a deeper sense than knowing how to do specific problems. It's still frustrating, then, for kids to adapt to having to describe processes using equations and expressions, which at their core do not list things to do, but instead describe and state facts about relationships between quantities.

I still think it's an important skill to learn. Indeed, I'm a lot more interested in teaching that kind of reasoning than I am about teaching computer programming. That's why I made changes in the new CodeWorld (the site discussed in this article) that are designed to deliberately thwart students who try to think of their programs as sequences of actions, and encourage those who think in terms of compositional expressions.