Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

>\lambda x.\, 6 was also surprisingly difficult for him to guess (though he did get it right eventually). I think he was just stuck on the idea of the function doing something arithmetical to the input, and was having trouble coming up with some sort of arithmetic procedure which would result in 6 no matter what you put in! It simply hadn’t occurred to him that the machine might not care about the input. (Interestingly, many students in my functional programming class this semester were also confused by constant functions when we were learning about the lambda calculus; they really wanted to substitute the input somewhere and were upset/confused by the fact that the bound variable did not occur in the body at all!)

Just goes to show, our intuition works on linear types.



I have a series of programming assignments in my introductory course that has students write simple functions in Python. One of those functions is to consume nothing and returns their (the programmer's) current age. So for example, you might write

    def get_my_age():
        return 21
The students' reaction to this in office hours can be... interesting. I am curious how many of them actually follow the comment at the bottom of the question, and what they think:

> Reflect on the difference between creating a variable with a constant value and creating a function with no arguments and a constant return value.

Up to you to decide if this has any pedagogical value. The real learning objective was to "write a function that has no arguments but returns a constant value", so getting them to draw big conclusions about the nature of functions and values and so on is outside the scope of this little activity.


One of those functions is to consume nothing and returns their (the programmer's) current age.

This is - or at least might be - ambiguous. Current age as of implementation time or current age as of function invocation time? And while a result in whole years is a pretty natural and obvious choice for the age of a person in absence of an explicit requirement, it is certainly not the only sensible choice.


I'd argue it's not ambiguous: current age would have to be a function of invocation time, while "age at time of writing the function" would be a constant.

Expressing "age" in whole years is acceptable in English, but using a decimal would be highly defensible. That's an issue of grading though.


Yea, that would have stumped me, expecting a trick/trap. What if my birthday is tomorrow? By the time my teacher checks it, it's wrong. "Your birth year" would have prevented that.

This is a problem I have with certain parts of computer science and math education. Everything is encouraged to be exact, then, suddenly, variable names are used inconsistently, niche cases are ignored arbitrarily and explained with essentially referring to "common sense".


It's graded immediately (automatically), so there wouldn't be any issues. Further, the text of the problem makes it clear that I'm not actually going to check their age - they can return any valid number (although it does check >0 and <100, perhaps discriminatorily). It would be a little invasive to their privacy otherwise, I think.


Isn't that more or less what happens in the real world?

Software engineering is all about mapping dirty nuance to formal systems.


But general purpose education isn’t „the real world“. I think the opposite argument is often made to justify teaching theory when it doesn’t seem to have many real world applications.


If we were talking about pure functions, I would certainly agree, but in Python it would of course be perfectly fine and not unusual to have an impure function implicitly depending on the current time. Obviously assuming »consume nothing« only refers to the parameters of the function, so this too could be less ambiguous.


That section reminded me of how constants are implemented via functions in Perl e.g.

  use constant PI => 4 * atan2(1, 1);
under the hood becomes

  sub PI () { 4 * atan2 1, 1 }
http://perldoc.perl.org/constant.html#TECHNICAL-NOTES


What I find surprising is how easy it is to understand functions as being made up of other functions (+), as opposed to functions that are not (constant functions).


I'm curious what you mean. Is the problem that it is a constant function, or that you are asking them to ignore parameters? Or is that missing the point, still?


A function with a linear type uses it's parameters exactly once. The concept of "linear type" doesn't relate to a the concept of "linear function" except in an abstract mathematical way.


Well, a linear function is a function where you can only use the parameter once when expressed in its Taylor expansion. E.g. these are not linear: x^2=x*x (used twice), exp(x)=1+x+... (used infinite times). It’s a very symbolic way of thinking about it though, and not what you usually consider an important property of linearity.


Not all linear functions possess a Taylor expansion, as not all linear functions are continuous, example: https://en.wikipedia.org/wiki/Discontinuous_linear_map

But, your statement is true for all real-valued linear functions AFAIK.


You still need to worry about the domain, in general there are plenty of real valued discontinuous linear functions (or functionals) from an infinite dimensional Banach space to R.

In finite dimension however linear functions are continuous


That is a badly written article. And the ones for linear map and continuity linked there, which would be important to the topic, too. The good mathematical articles start with a definition after the intro.

So much for teaching year olds. This is not rocket science, but mathematicians (almost inherent) inability to have language skills makes it seem so, notably.


This makes sense, but I don't see how it explains the difficulty the kid was having.


6+a*x, a->0

same but different:

6+x/a, a->infinity

imho constant is a special case of linear


The child was stuck on the intuition that the argument must change in some way (i.e. that the function was linearly typed).


Oddly, I think I'm stuck on the idea that it has to be "just once." Curious if the child could have figured out a function that needed the input twice, as an example. (So, x^2+x, or something similar.)

So, is it that it is linearly typed, or that it is greedy and wants to use all inputs given at least once?

Or, are those the same thing?


This and this:

>> I think he was just stuck on the idea of the function doing something arithmetical to the input, and was having trouble coming up with some sort of arithmetic procedure which would result in 6 no matter what you put in

don't really seem, to me, like they can explain what's happening -- f(x) = 6 is trivially easy to express in terms of arithmetic operations being applied to x. If you assume that a function that multiplies by 2 is intuitively ok, what's wrong with a function that multiplies by 0?


>what's wrong with a function that multiplies by 0?

Obviously the fact that it doesn't seem to have any visible effect on the input -- and people expect the input to be affected.


I think it's more that it doesn't make use of its input. If you aren't using the input, why is the input in its type signature?


Affected? f(x) = 6 has a pretty obvious effect on all input other than 6.

Your comment is more of an indictment of identity functions than dimension-losing functions.


A phrasing more to the point is that one expects the input to have some effect on the output. One usually obtains this by, colloquially speaking, performing actions on the input, since if you don't act upon the input in some way, you're going to get a constant result. Of course, you are correct in that some actions don't really do anything, but they're observationally indistinguishable from not acting on the input in the first place.


Your comment seems confused in exactly the same way as coldtea's. How are you imagining turning input 20 into output 6 without acting on the input?

If you don't act on the input, you have an identity function, not a constant function. Constant functions must alter their input whenever it doesn't match the constant output. Nobody ever complained that the problem with Procrustes was that he didn't do anything to the guests in his bed.

And in the other direction, I don't understand why you want to characterize "multiply the input by zero" as an action that "doesn't do anything"? In what sense would that be true?


>Your comment seems confused in exactly the same way as coldtea's. How are you imagining turning input 20 into output 6 without acting on the input?

Easily:

f(x) = 20

No action on the input -- discarding the input is not an intuitive action for a 6-year old that just got a handful of of ax+k and xk + n style examples.

>Nobody ever complained that the problem with Procrustes was that he didn't do anything to the guests in his bed.*

You seem confused. Procrustes operated on his guests, which is neither the identity (they would come of unscratched) or the constant function (in which the same person or thing would emerge out of the bed).

Their height in the end was the same, but that's not the argument to the Procrustes function -- their overall body was.

>And in the other direction, I don't understand why you want to characterize "multiply the input by zero" as an action that "doesn't do anything"? In what sense would that be true?

Obviously in the intuitive sense for a 6-year old -- which is what we're discussing, and which was based on some operation on the argument that resulted in a different value each time, not degenerate versions of functions like the identity, constant, 0, etc.

(That said, it "doesn't do anything to the input" in the sense that it's not dependent on the particular input. 2x gives you 4 and 10 if you pass 2 and 5. 0x gives you 0 whatever you pass it, so could just as well be a constant fx = 0).


> f(x) = 6

Fixed, for the sake of corresponding more exactly with the challenge. Not that it wasn't clear what you meant :)


Yep, that!


A constant function doesn't act on its input. `f(x) = 6` doesn't perform a different action on each input. But given your comparison to `f(x) = 0*x + 6`, let's move away from numbers and consider a different function. `f'` which I'll define as:

    const :: a -> b -> a
    const a _ = a
    
    f' :: a -> ()
    f' = const ()
Now I can give `f'` anything at all. Can you try to explain the action of `f'` in any way but that it ignores its argument?


Functions don't alter anything. 20 is still 20 even after you evaluate f(20) to be 6.


That's where linear logic differs, if you will. The highest voted comment in this sub-thread already alluded to that.


I'm a big fan of linear typing but I think of it as more like "consuming" the input than "changing" it.


>Affected? f(x) = 6 has a pretty obvious effect on all input other than 6.

It wasn't "what would the result be" that eluded the child (or those students).

It was the question "in what way is this an operation on x" -- which in their minds was intuitively, put x in and add/subtract/multiply by something(s) to get another result.

fx=K, fx=0, or fx=x didn't seem as substantial enough transformations (given the other examples) to qualify with their notion of a function.


I wonder if it would have made it any more obvious to explicitly define it as:

f(x) = 0*x + 6

EDIT: Or even, if multiplication is a problem, f(x) = (x - x) + 6


"Trivially easy" to a six-year old? Who may or may not even have a good grasp of the concept of zero yet? You don't seem to be very self-aware of the extent of your knowledge and understanding compared to a preschooler.


I think the problem is that our intuition is more or less based on a mechanical world in which the concept of a side-effect free or ineffective input is foreign.


I suspect it's more that our intuition is that everything is meaningful, or at least something is, so when the solution to is to ignore the only thing you have at hand, it's hidden in plain sight.


This goes so far that the phrase "nobody knows" is described by grammarians as having a zero pronoun, ie. "nobody knows (it)". "it" doesn't need to be specified, because nobody would know what it is, and so nobody cares. Correspondingly, functional programmers use to write "f(_)" and in prolog for example that acts as a catch all glob operator, if I recall correctly, not sure about Haskell.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: