6 ms·
First impressions apply to languages too. A lot of mathematicians went into AI but didn't start out with any programming experience. They dabbled in some langua
by nomilk 3y ago
First impressions apply to languages too. A lot of mathematicians went into AI but didn't start out with any programming experience. They dabbled in some languages and gravitated toward the one(s) they found most useful.
Paraphrasing Guy Steele [1]:
> It's important that when you design a language that does a familiar thing, that you do the familiar thing exactly... it's criminal that you can write 1/2 and get values nowhere near one-half.
Python
>>> 1/2
0.5
Ruby
irb(main):001> 1/2
0
To a novice programmer, ruby's result makes no sense, and introduces an incredible degree of doubt into the mind of the user. Sure, they could explore why it gives that result, but if that's not helping them get toward solving the problem they're using the programming language for in the first place, then it could seem like an indulgent tangent.
[1] https://www.youtube.com/watch?v=agw-wlHGi0E&t=19m27s https://www.youtube.com/watch?v=agw-wlHGi0E&t=19m27s
- wodenokoto 3y agoBack when Python was winning over the AI crowd, they did the same thing as Ruby, if you didn't remember to call some voodoo chants "from future import ..."
- polemic 3y agoNotable that this was python behaviour until Py3.
- lou1306 3y agoThe shift towards // vs / also shows great acumen by the Python designers: they tried (and arguably, largely succeeded) in catering to the greater data science/statistics/numerical analysis communities, where 1/2=0.5 is obvious, rather than sticking to the "compsci-obvious" 1/2=0.
- crabbone 3y agoNeither is obvious in either community... And this isn't the reason Python succeeded. Nor is this the reason for the particular change. The reason Python succeeded with data-science is NumPy and related group of libraries. They happened to be the first to offer easy access to R-like features of other statistically-flavored languages in an all-purpose language. I.e. it makes it easy to combine general-purpose code with statistics-specific code, and once it accumulated critical mass, the process became self-sustaining and alternatives died off quickly. The reason for most of the changes that happened to Python in the last fifteen or so years is design driven by fashion. Which means the majority decides what to do with the language. Which also means that Python is made to look more and more like other mainstream languages (eg. Java, JavaScript, C++...) So, a lot of changes, this one included were made out of subconscious fear of non-conformity.
- lou1306 3y agoSurely 1/2 = 0.5 is what a statistician would expect? Whereas 1/2 = 0 is what happens in C, C++, Ruby, Java, C#, F#, Rust... Essentially most of the popular programming languages with the exception of Python and JS/Typescript. Anyway. Maybe my original comment was poorly phrased, but I was not implying that Python succeeded because of this form of catering. Rather, the designers took note of Python becoming popular in that field and made changes (see also the matrix multiplication operator @) that accommodate those users rather than the more "typical" CompSci crowd.
- crabbone 3y agoMy wife's mom is a statistician (and has been since like 70's). She also used to do a lot of programming in the line of her work (working for a telco, and later as biostatistician), in the latest iteration in R, where things are like you expect them to be. But, before then it was also Matlab, where 1 / 2 = 0. But, none of that is really relevant. Both operations are useful and common in statistics. Which one is more common will depend on your domain. > the designers took note of Python [...] made changes That's putting too much faith in designers of Python. Even calling these people "designers" is giving them too much credit. By their own admission they don't have any sort of vision or strategy for how to deal with the language, they just add random stuff and see if a lot of people complain or thank them. In other words, matrix multiplication operator is there not because there was some kind of intention or design on the part of the small group of people who are responsible for releasing the language, it was more of a "genetic algorithm" kind of thing: change - iterate - see if change optimizes some metric - repeat.
- mgaunard 3y ago0 is also the behaviour of C and of pretty much any serious programming language.
- leadingthenet 3y agoI feel like everyone making comments along this line is completely missing his point. It's not wrong that 0 is the behaviour of C/Ruby, it's just that 1/2=0.5 is the expected result of much of Python's target audience.
- xdennis 3y agoBut it's not. In second grade I was taught that 1/2 is 0 (with a remainder of 1). Fractions, real numbers, complex... are taught afterwards.
- Hamuko 3y agoI don't think the target audience of Python are second-graders, but rather people who have graduated elementary school and realise that 1/2 comes out to 0.5.
- mgaunard 3y agoThat's silly, in math those two are just different notations for the same thing, and usually fractions are preferred. Also anyone who's done any bit of programming should know that numbers as represented by a computer are discrete, while mathematics deal with symbolic relations which might require infinite amount of data to numerically represent. Binary floating-point can't even represent 0.1.
- Joker_vD 3y agoI've always suspected that Pascal and Haskell were not serious programming languages, thank you for confirming my suspicion.
- 3y ago
- bhaak 3y agoDoes any of the programming languages Guy Steele worked with do the former and not the latter? Java certainly doesn't: https://godbolt.org/z/b847KeaGv https://godbolt.org/z/b847KeaGv There's a good reason for this. Computer numbers are not the same as numbers in mathematics. Floating point numbers are not real numbers and ints are not natural numbers.
- guenthert 3y agoScheme, Common Lisp. Neither Java nor CL were intended for the novice; I'm sure Mr. Steele had Scheme in mind.
- bhaak 3y agoI think there is also a gotcha there as you get a ratio in Common Lisp and not a floating point number. > (print (format t "1 divided by 2 is ~a and its type is ~a" (/ 1 2) (type-of (/ 1 2)))) > 1 divided by 2 is 1/2 and its type is RATIO I don't think there is a simple solution. Numbers are harder than they seem and you just need to know what happens in the particular language you are programming in.
- regularfry 3y agoArguably that's not a gotcha. It's (probably) his point.
- mihaaly 3y agoIt was not debated that there is no reason some languages behave one way or the other - it is quite the opposite - only that for supporting the pratical use cases - which is the sole purpose of any language, to be useful for practical cases - then it is not a good reason. When one has to jump hoops of the language - being the user for the whims of the language and not the language for the user - that is wasting efforts and adding complications instead of helping. Being more like puzzle for fun that practical application. Those want to keep close to the soul of the hardware and computing should use C or other low level languages, existing for long. Not made recently to make programming easier ... on paper only apparently...
- boffinAudio 3y agoOkay, I'll bite: how much of this is the responsibility of the language designers versus how much of it is the responsibility of the language user? If I had a junior programmer complain to me about this case, I'd simply tell them "you didn't RTFM", because RTFM'ing before you use a language is not only the professional thing to do, but vital to your accurate and correct use of the language. Sure, language designers shouldn't build-in these kinds of foot-bullets, but then again, kids shouldn't play with guns. >First impressions apply to languages too. The duty of responsibility applies to all languages, and it is the users responsibility to understand the language they are attempting to use, before using it. No?
- otherme123 3y agoIf a language clearly states in the FM that something "criminal", in the words of your parent comment, is known to be criminal but they leave it as it is without any clear reason behind it (even recognizing it as a past error they have to carry for backward compatibility), the junior has all the right to think the language is criminal and is against them. In the extreme case, take something like brainfuck. Everything is in the RTFM, but that doesn't make the language less criminal. I like to remember that we are not here to program for the sake of programming. We are mainly solving problems. I have a problem that I know I need to solve with "a gun", and maybe I'm a novice to gun usage. After having a look at some guns, I choose the one who seems to be less dangerous and have a friendlier and more intuitive usage. When your very powerful but a deathtrap with 1000 page manual of a gun is used by no one, don't complain with "why you don't use my powerful and clearly better gun!?". Because the key here is that this is not the 1970's anymore, when all guns were complicated. Learning by doing is the best way to learn, way better than learning by reading (https://thepeakperformancecenter.com/educational-learning/learning/principles-of-learning/learning-pyramid/ https://thepeakperformancecenter.com/educational-learning/le...). If a language requires me to RTFM is at a big disadvantage with any other language that allows me to easily learn by doing.
- comradesmith 3y agoI don’t think it’s fair to say integer division is an error, it’s more so a lack of an abstraction of “number” over floats and ints.
- kibwen 3y ago> it's criminal that you can write 1/2 and get values nowhere near one-half This is a foolish argument and Guy Steele should know better. What makes 1/2, which has an accurate floating point representation, any more important than 1/10, which doesn't? Every novice programmer, every single one, trips over floating point, and pretending that floating point numbers match our intuition from mathematics doesn't do anyone any favors.
- deleted 3y ago[deleted]
- tinco 3y agoI don't think his attention was specifically to have 1/2 be a floating point number, like for example Javascript does, but to call to attention the fact that we design programming languages for a specific audience, not realising that if we widened our perspective it could be intuitive for a much wider audience. For example, Ruby was designed for experienced software developers. Experienced software developers expect that if you divide an integer by another integer, that it performs integer division, and 1/0 would be 0 in integer maths. If the creator of Ruby had broadened their horizon, and instead realised that outside the world of experienced software developers, the expression "1/2" means something totally different, maybe they could have chosen a different behaviour. In a different universe perhaps any numeric literal in Ruby would always be a `Number` (like in Javascript), that for division would instead return a `Rational`. So that the end user could at the end simply call `.to_i` or `.to_f` or `.to_s` according to their needs. I don't know if that would be a better universe though. I agree with your point that every programmer eventually needs to learn about floating point numbers and their sometimes surprising properties. And in the end Ruby was designed for programming computers, and the goal of any programming language is to expose the abilities of a computer, which include at the core integer maths, however surprising that maths might be to a novice.
- nordsieck 3y ago> If the creator of Ruby had broadened their horizon, and instead realised that outside the world of experienced software developers, the expression "1/2" means something totally different, maybe they could have chosen a different behaviour. IMO, that would be a tragedy. In every language that does it implicit type coercion is the cause of a litany of bugs. It's the cause of many problems in php. It's why people are told not to use == in javascript. Maybe it is more difficult for beginners. But people are only beginners for a couple of weeks. It makes no sense to design the language to make those couple of weeks a little better and the rest of their programming lives a lot worse.
- crabbone 3y agoHaving to work with scientists and mathematicians, as in offering my programming help to them... I see no value in making languages look like math formulas. Math formulas are an awful language. It served its purpose to discover how to do things better, but it became obsolete many decades ago. People who hold on to these ideas create truly awful languages like Haskell. These languages make comprehension prohibitively difficult. So much so that a lot of people who would otherwise benefit from using the language and would have enough mental capacity to appreciate its higher-level concepts are prevented from doing so by a very superficial thing s.a. syntax. Also, have had you done any math beyond high-school, you'd not have a problem understanding why the result you see in Ruby makes sense. I think some high schools today also include set theory in math curriculum, which would include concepts like closure, domain / co-domain etc. So... this is really not a good example of the concept you mention. In general, I think that being correct, minimal and internally consistent is a lot more valuable for the language than to be similar to the prior knowledge newcomers might have. It's nice to be also newcomer-friendly, but that shouldn't come at the expense of sacrificing any of the aforementioned desirable properties.
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]
- ochoseis 3y agoFWIW that comparison would’ve been identical in Python 2, where to get floating point division in Python would’ve been: >>> 1//2
- roelschroeven 3y ago1//2 always resulted in an integer, even in Python 2, with or without "from __future__ import division". To get floating point division in Python 2, you had to convert at least on of the operands to float (much like in C or C++). You can try it online at tio.run, they still have Python 2 among their available languages, as well as Python 3.
- Lio 3y agoI respect Guy Steel a lot but this argument is like complaining that b = 1 doesn't compare b to 1 and return a boolean. Lots of novice programmer think that's what equals should do based on familiarity with mathematics. Using = for assignment doesn't help them solve problems either but it's what those with experience of programming generally expect.
- chasd00 3y ago> it's criminal that you can write 1/2 and get values nowhere near one-half. that's sort of ridiculous. Would he be more ok with the output 0.48? what about 0.51? Ironically, in the age of LLMs and non-deterministic output, maybe he would.
- pjmlp 3y agoActually it is more like this: Python 2.x >>> 1/2 0 Python 3.x >>> 1/2 0.5