An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
Posted Jul 17, 2015 16:57 UTC (Fri) by raiph (guest, #89283)In reply to: An interview with Larry Wall (LinuxVoice) by nevets
Parent article: An interview with Larry Wall (LinuxVoice)
In the meantime Perl 6 has basic math right in places where python et al go wrong: https://news.ycombinator.com/item?id=9791211
I think it'll be years before the Rakudo implementation really shines the way the design does, but the Perl 6 language is designed to be significantly better for number crunching than Perl 5 and Rakudo will ship with some of those improvements in place by the end of this year.
Posted Jul 17, 2015 19:06 UTC (Fri)
by juliank (guest, #45896)
[Link] (25 responses)
Yes, .1+.2-.3 = 5.551115123125783e-17, but that is the expected in almost any programming language. Even Haskell does this. If you want decimal floating point, use decimal floating point. If you want rational numbers, use the fractions module.
This form of floating point arithmetic is an industry standard and deviating from it by default does not mean your language is better.
Posted Jul 18, 2015 1:54 UTC (Sat)
by raiph (guest, #89283)
[Link] (24 responses)
Yes, almost all languages convert values like 0.1 and 1/10 in to floating point approximations, including Haskell, Python 3, and Perl 5. It is indeed not the end of the world; one simply has to learn to expect that, and learn to explicitly use a factional/rational/decimal type when the loss of precision matters.
But the primary reason it's that way is that the performance boost of fp approximation was considered worth the loss of precision and consequent violation of the principle of least surprise for naive users -- and that rationale hasn't held water for contemporary computer chips for years.
So, while it isn't the end of the world to work with the old ways of thinking, I expect robust new languages to trend toward, by default, automatically maintaining full precision (modulo range limits) for literals like 0.1 or 1/10.
Posted Jul 18, 2015 2:10 UTC (Sat)
by Cyberax (✭ supporter ✭, #52523)
[Link] (18 responses)
You CAN NOT store 0.1 as a limited binary fraction precisely. You can try to play games like "0.10000000000000009" is really "0.1" but that will inevitably bite some users who actually expect floating point to be precise and it won't be reliable anyway (what we should do with 0.10000000000000010?).
If you need decimal fractions - then use a decimal type.
Posted Jul 18, 2015 6:12 UTC (Sat)
by epa (subscriber, #39769)
[Link] (12 responses)
Posted Jul 22, 2015 17:00 UTC (Wed)
by salimma (subscriber, #34460)
[Link]
Posted Jul 22, 2015 17:53 UTC (Wed)
by anselm (subscriber, #2796)
[Link] (10 responses)
So you would presumably use 22/7 (or something like it) for π?
Posted Jul 22, 2015 18:33 UTC (Wed)
by rsidd (subscriber, #2582)
[Link] (9 responses)
A sensible thing for a language to do, if it must bother with rational numbers without being asked, would be to use a rational representation when the number is explicitly given as a ratio of integers, and the machine floating point representation otherwise. So 1/10 would be rational and 0.1 would be a float, and their product would be coerced to be a float. Lisp, for instance, does this (at least common lisp does). Python on the other hand has a fractions module that must be used if this behaviour is desired, otherwise python 2 treats 1/10 as an int (0) and python 3 treats it as a float (0.1).
Posted Jul 22, 2015 19:49 UTC (Wed)
by raiph (guest, #89283)
[Link]
Posted Jul 23, 2015 3:49 UTC (Thu)
by raiph (guest, #89283)
[Link] (7 responses)
Yes. Pi is irrational, not rational. Any finite representation of an irrational number is going to be approximate, no matter what.
> One has two choices then -- store [0.1] as 1/10 ... or store it in the proper machine representation.
Do you see that you've indulged in circular reasoning there? You've implied that a particular machine storage representation of rational numbers is not proper simply because it isn't floating point. (And, most ironically, you're saying this despite the former being a 100% accurate representation and the latter approximate.)
> Most of us prefer [an inaccurate representation over an accurate one]
I don't think that's true. I think most of us prefer the most appropriate representation for a particular use case if it makes a difference worth making for that use case.
This often means floating point. But, for many uses of rationals, especially decimals, exact rationals are a viable choice, indeed may I say obvious choice, if you care about accuracy and simplicity.
> From raiph's remarks it would seem perl defaults to an integer-ratio for 0.1, and possibly even for π.
Yes, for 0.1.
The π value built in to Perl 6 is stored as a floating point number.
> What puzzles the rest of us is what is the benefit of this.
Almost all practical rational math, eg decimal math where input and output values have any number of digits before the decimal point and up to 15 or so digits after, will be 100% accurate by default, whereas floating point can go wrong at one digit after the decimal point, such as with `0.1 + 0.2 - 0.3`.
So, treating rationals as rationals can provide two crystal clear benefits over floating point: accuracy and simplicity.
> A sensible thing for a language to do ... would be to use a rational representation when the number is explicitly given as a ratio of integers ... So 1/10 would be rational
Right. That's what Perl 6 does and most other languages do not.
> and 0.1 would be a float
0.1 is *exactly* the same number as 1/10. It's just specified with a different notation. Given that Perl 6 supports accurate rational processing it makes little sense to treat `123456789.987654321` as anything other than 123456789987654321/1000000000.
In Perl 6, if you want floating point then you explicitly coerce, eg `Num(0.1)`, or use scientific notation, which is universally understood to be approximate, such as eg `1e-1` for 0.1 or `2.99792458e+8` for the m/s speed of light.
Posted Jul 23, 2015 4:38 UTC (Thu)
by rsidd (subscriber, #2582)
[Link] (6 responses)
Posted Jul 23, 2015 21:59 UTC (Thu)
by flussence (guest, #85566)
[Link]
Why do you hold Perl 6 to an absurd standard here but languages like Javascript, PHP and Python get a silent free pass?
Posted Jul 24, 2015 4:29 UTC (Fri)
by raiph (guest, #89283)
[Link]
Without installing anything you can compile:
say e**(i*π) + 1
... and get an approximation of the right result. (Yes, that i is the square root of -1.)
But I'm pretty sure that's about the maximum extent of it at the moment ie there aren't (m)any other mathematical constants defined in the standard setting.
> > whereas floating point can go wrong at one digit after the decimal point, such as with `0.1 + 0.2 - 0.3`.
> Huh? python (both 2 and 3) give me 5.551115123125783e-17 which is 17 digits after the decimal point, not 1 digit.
I was talking about the user *input* (one decimal digit, presumed accurate) not the computer generated *output*.
> When you have a number with more than two or three digits after the decimal ...
Numbers with just one or two digits after the decimal are considered an important use case. For example, writing 4.10 to represent 4 dollars and 10 cents.
Posted Jul 24, 2015 5:53 UTC (Fri)
by rsidd (subscriber, #2582)
[Link] (3 responses)
Normally (ie when it's some other quantity, not money), when you write 4.10 you mean that it is known to a precision of two digits after the decimal point. If you write 4.1 it means you know it to 1 digit precision. If you mean the exact fraction you will write 4 1/10, not either of the above.
Anyway, enough of this argument. It is clear that you are convinced treating 4.1 or 3.14159 as fractions is the correct thing to do, will not be persuaded that it is wrong, and will not succeed in persuading others that it is right. Let us see if the Perl 6 way catches on. It's only been 15 years so far. Me, I have my eye on Julia.
Posted Jul 24, 2015 9:53 UTC (Fri)
by raiph (guest, #89283)
[Link]
Thanks for the exchange. :)
Posted Jul 26, 2015 15:56 UTC (Sun)
by flussence (guest, #85566)
[Link]
Posted Jul 28, 2015 9:06 UTC (Tue)
by dvdeug (guest, #10998)
[Link]
It's a trade-off of speed for less user surprise, and for a language with as little stress on raw speed as Perl, that's usually a good trade off. Accuracy is probably a wash; I bet there's a lot of times where you get back the exact best answer you could get with rationals where floats are less then precise, especially for less experienced users who aren't thinking in terms of IEEE754. I don't know Perl or Perl 6, but I assume if you want floats, you can explicitly demand them.
Posted Jul 18, 2015 7:49 UTC (Sat)
by Wol (subscriber, #4433)
[Link] (4 responses)
Mind you, it is a pain. The user/programmer has to explicitly manage the exponent ...
Cheers,
Posted Jul 18, 2015 19:05 UTC (Sat)
by raiph (guest, #89283)
[Link] (3 responses)
I'd enjoy comparing the Perl 6 design in this regard with pick's. I didn't find anything helpful when I spent a few minutes searching SO and wikipedia and googling; I'd appreciate a brief elaboration or link.
Perl 6 has a Rational role that is parameterized with a numerator and denominator. FatRats are Rational[Int,Int] which means they are arbitrary precision. Rats are (Rat64s which are) Rational[Int,Uint64] which means the denominator is limited to an unsigned 64 bit int; if a Rat overflows, "the denominator is automatically converted either to a Num or to a lesser-precision Rat, at the discretion of the implementation." (Hmm. Why not to a FatRat?)
The full gory details for this part of the Perl 6 language design (which may or may not exactly match the current Rakudo Perl 6 compiler implementation but ought to be close) are at http://design.perl6.org/S02.html#Numeric_Types
Posted Jul 19, 2015 9:11 UTC (Sun)
by Wol (subscriber, #4433)
[Link] (2 responses)
The Pr1me CPU was capable of doing BCD arithmetic, and had a load of microcode specifically to optimise all this sort of stuff. The Pick database was designed to store integers, and to store the mantissa in the data definition, not the data itself. As an example, let's store some price information in pounds in Pick - you'd put "199" in the data field, and "MD2" in the definition ("masked decimal 2"). That converts data at display time to 2dp, ie 1.99
So when you as the programmer are doing the maths, you have to be wary of multiplying MD-type fields, because MD2 * MD2 is, of course, MD4 and if you don't "correct" it to whatever datatype you're storing the result as, you can get some right funnies ...
Cheers,
Posted Jul 19, 2015 22:43 UTC (Sun)
by raiph (guest, #89283)
[Link] (1 responses)
Gotchya.
Iirc pick doesn't have (much of) a type system and you're describing the kind of problem that type systems address.
I don't see a parallel with anything Perl 6 specific atm.
Thanks for following up. :)
Posted Jul 20, 2015 14:34 UTC (Mon)
by Wol (subscriber, #4433)
[Link]
imho that is both a great strength, and a massive weakness. Everything is a string. Works great (it really does). But the fact that all of your definitions are DEscriptive, rather than PREscriptive, *can* (not *is*) be a nightmare when you really really want to be certain something is, say, a number.
But on the other hand, it does make it easy to store things like "dead" or "unknown" in an age field :-)
Cheers,
Posted Jul 19, 2015 8:12 UTC (Sun)
by zlynx (guest, #2285)
[Link] (4 responses)
I suppose it depends on what you are using your computer for. In a scripting language I suppose you don't care about speed, so that would make sense.
But in some kind of physics simulation the user definitely cares about speed. No computer or computer cluster is ever fast enough and every 1% of FPU performance is desired and valuable.
Posted Jul 19, 2015 18:10 UTC (Sun)
by raiph (guest, #89283)
[Link] (3 responses)
Sure.
> In a scripting language I suppose you don't care about speed
Not at all. The (supposed) language genre is irrelevant. Either a language can easily do what needs to be done or it can't. Speed often matters and when it does a tool is either capable of the performance you need or it is not.
> so that would make sense.
What makes sense (to me) is that a language has the right behavior by *default* as well as the right *possible* behavior if you want that instead.
In Perl 6 the default behavior is that `1/10 + 2/10 - 3/10` evaluates to zero rather than a small number. Imo a 10 year old that's just learned addition of simple fractions will consider this simple and accurate and appreciate this default way of looking at things.
> in some kind of physics simulation the user definitely cares about speed.
Sure.
In Perl 6 one can explicitly use a different type that explicitly represents a floating point number. The most generic floating point type in Perl 6 is Num.
One can write a Num literal:
my $foo = 1.234e-5; # use an 'e' to make a floating point literal
Now $foo contains a floating point number.
Or one can type a variable:
my Num $bar = 0.00001234
Now $bar contains a floating point number because Perl 6 automatically coerced the value to a Num.
> No computer or computer cluster is ever fast enough
Sure.
The misunderstanding in this thread about what Perl 6 does and doesn't do regarding floating point operations is just the start. The current Rakudo Perl 6 compiler implementation is too slow for it to be obvious, but Perl 6 has many features aimed at high-performance computing, from practical, easy-to-use parallel processing constructs to its sweet FFI with automated struct/object mapping.
Posted Jul 20, 2015 0:13 UTC (Mon)
by raiph (guest, #89283)
[Link] (2 responses)
> my Num $bar = 0.00001234
> Now $bar contains a floating point number because Perl 6 automatically coerced the value to a Num.
Turns out I'm wrong. Rakudo gives a compile time error:
Type check failed in assignment to '$bar'; expected 'Num' but got 'Rat'
It seems like one has to explicitly coerce (I've just checked this works):
my Num $bar = Num(0.00001234)
That slightly surprises me. I don't know why the compiler doesn't just coerce the rational literal in to a floating point number for me. I guess they can always upgrade it later from a compile-time error to a coercion if that's deemed wise.
Posted Dec 28, 2020 19:59 UTC (Mon)
by raiph (guest, #89283)
[Link] (1 responses)
my Num() $bar = 0.00001234
which will store a float in $bar by converting the rational 0.00001234.
Posted Dec 31, 2020 15:07 UTC (Thu)
by flussence (guest, #85566)
[Link]
Posted Jul 18, 2015 13:13 UTC (Sat)
by rsidd (subscriber, #2582)
[Link] (75 responses)
Posted Jul 18, 2015 19:51 UTC (Sat)
by raiph (guest, #89283)
[Link] (73 responses)
Sure, but that's irrelevant. I was commenting on things like 0.1, which isn't a floating point number, and 1/10, which isn't either. (Or even 1/3, which isn't even decimal.) These are all rational numbers that can easily be stored in binary storage with no loss of precision by storing two integers instead of one floating point number.
This isn't rocket science; it's just that folk have gotten used to old ways of thinking and, in this thread at least, one can see that some folk aren't naturally open-minded.
> your claim about python 3 is wrong (this is an incompatible change from python 2 that will perhaps benefit newcomers, like my 8-year-old son, but trips me up).
Using ideone.com, Python 3.4:
print(.1 - .2 + .3)
returns
5.551115123125783e-17
(i.e. a very small number)
Afaik this has not changed in Python 3.5.
> the above example suggests that [Perl 6] will be worse than other languages that treat floating-point numbers as the hardware treats them.
Because you're still missing the point that this isn't about floating point numbers.
Perl 6 supports floating point numbers just fine. According to the relevant design doc: "On most platforms that means an IEEE 754 64-bit floating point number, aka "double precision".
> any workaround to get around the realities of how the hardware works is going to slow down your number-crunching for no practical benefit.
Imo accuracy-by-default and simplicity (math says 0.1 + 0.2 - 0.3 is zero and I would expect your 8 year old son to soon agree with that if he doesn't already) are both very practical benefits if they don't unduly slow down your number-crunching, especially if it's trivial to use floating point numbers if you so wish (which you may in most languages, including Perl 6).
Posted Jul 18, 2015 20:25 UTC (Sat)
by juliank (guest, #45896)
[Link] (6 responses)
He was probably refering to division (/) always producing floating point instead of int now (which has //).
> > any workaround to get around the realities of how the hardware works is going to slow down your number-crunching for no practical benefit.
True. But knowing about fractions at year 8 is quite advanced. That's more something for children >= 10. And even they mostly cannot really handle it.
Posted Jul 18, 2015 20:26 UTC (Sat)
by juliank (guest, #45896)
[Link]
Posted Jul 19, 2015 3:29 UTC (Sun)
by raiph (guest, #89283)
[Link] (4 responses)
OK.
So, to summarize, given the expressions `7/2` and `1/10 + 2/10 - 3/10`, Python 2 gets neither "right" where "right" is defined as what the correct basic math result would be; Python 3 and Perl 5 get one of them right (`7/2`); and Perl 6 gets both right.
> But knowing about fractions at year 8 is quite advanced.
Sure. That's why I lead with the likelihood of his son agreeing (that `0.1 + 0.2 - 0.3` is zero) "soon", by which I meant in a year or two, rather than already.)
> That's more something for children >= 10. And even they mostly cannot really handle it.
Sure. But I think kids who've finally gotten fractions will handle `0.1 + 0.2 - 0.3` being zero a whole lot more easily than they will handle it being a small number "because floating point".
Posted Jul 19, 2015 4:29 UTC (Sun)
by Cyberax (✭ supporter ✭, #52523)
[Link] (3 responses)
So no, Perl 6 doesn't get them right. Python (and C, Haskell, Rust, Go, ...) get them right.
Posted Jul 19, 2015 21:46 UTC (Sun)
by raiph (guest, #89283)
[Link] (2 responses)
Would you object if I tweeted that?
Posted Jul 20, 2015 6:27 UTC (Mon)
by Cyberax (✭ supporter ✭, #52523)
[Link]
Posted Jul 20, 2015 6:36 UTC (Mon)
by rsidd (subscriber, #2582)
[Link]
Posted Jul 18, 2015 21:12 UTC (Sat)
by Cyberax (✭ supporter ✭, #52523)
[Link] (6 responses)
However, once you start doing moderately complex math with true rationals, denominator grows really fast. Sooner or later you have to start normalizing them, causing precision losses.
That's why flexible rationals are not really popular, despite their seductive allure. People just stick to f64 if they want speed, since f64 peculiarities are well-known and are taught in all CS courses. Or people stick to decimal types if they need to mimick the way 'humans' do the arithmetic (primarily for financial stuff).
Posted Jul 18, 2015 22:35 UTC (Sat)
by juliank (guest, #45896)
[Link] (5 responses)
Why does normalization cause precision loss?
Posted Jul 19, 2015 4:49 UTC (Sun)
by Cyberax (✭ supporter ✭, #52523)
[Link] (4 responses)
Additionally, if you try to use trascedentals (even a simple square root!) then rationals again become useless.
So there's only a very narrow niche for them, and they are not used widely even though lots of languages have libraries supporting them.
Posted Jul 19, 2015 6:07 UTC (Sun)
by mchapman (subscriber, #66589)
[Link] (3 responses)
It seems to me that the people that are going to be using calculations involving a large number of coprime denominators are precisely the same set of people that will be quite happy to keep using floating-point numbers anyway. So long as it's clear where the transition from rational values to floating-point values lies (e.g. through a warning, or more explicitly through a lexically-scoped pragma), I see no reason why we can't satisfy all parties here.
Posted Jul 19, 2015 11:20 UTC (Sun)
by khim (subscriber, #9252)
[Link] (2 responses)
Posted Jul 19, 2015 12:03 UTC (Sun)
by mchapman (subscriber, #66589)
[Link]
I don't think of 0.1 as "requesting" any kind of numeric type. It's just a real number.
In Perl 6 that literal does happen to create a Rat value. But that sounds reasonable to me -- all decimal real numbers *are* rational. 0.1 and <1/10> are just two different textual representations for the same value.
So what if you really want to "request" a floating-point value for some reason? Easy: simply use that Rat as a floating-point value. You could assign it to a Num scalar, or you could use it with some operator or method that only works with Nums. It's easy enough to do the conversion. It is, after all, exactly the same conversion most other programming languages do when they interpret the decimal form in the first place.
To be honest, I would not be surprised if Perl implementations skip the Rat value completely if the decimal literal is used somewhere where it will be immediately used as a floating-point value. If the Rat temporary value isn't externally visible, constant-folding can turn it into a constant Num instead.
Posted Jul 20, 2015 8:39 UTC (Mon)
by jezuch (subscriber, #52988)
[Link]
Any programmer who thinks that computers implement "basic math" is simply incompetent... unless you're doing purely symbolic calculations and/or have infinite-length registers.
[Yes, I did fall into that trap once or twice when I was at the university. But then I learned about proper numerical algorithms, numerical (in)stability etc. and I'm no longer incompetent ;)]
Posted Jul 19, 2015 4:50 UTC (Sun)
by rsidd (subscriber, #2582)
[Link] (58 responses)
But 0.1 is very much a floating point number. If you want a fraction, you will write 1/10 and not 0.1. Python has a fractions module for those who need it. As cyberax and others said, 0.1 in decimal is not a terminating fraction in binary and until you design hardware that works in decimal, the alleged "correctness" of perl6 isn't correctness at all and is of no practical benefit to numbercrunchers.
Posted Jul 19, 2015 6:11 UTC (Sun)
by mchapman (subscriber, #66589)
[Link] (57 responses)
That would be very un-Perlish. 0.1 is as much a rational value as 1/10 is, *until such time* you use it where it being a rational value does not make sense (e.g. as the input of a transcendental function). There's little need to do the rational-to-floating-point conversion (which is all that "parsing a decimal number" is in most languages, after all) before then.
Posted Jul 19, 2015 6:28 UTC (Sun)
by rsidd (subscriber, #2582)
[Link] (56 responses)
Posted Jul 19, 2015 6:43 UTC (Sun)
by mchapman (subscriber, #66589)
[Link] (55 responses)
I'm not sure that it needs to. If something can only be efficiently calculated using floating-point values, it's perfectly fine for the implementation to use that. I gave the example of transcendental functions. Except in a few specific cases, there's no sense in keeping rational values around there. I'm sure you can think of other examples.
So the discussion is really about *when* the rational-to-floating-point conversion takes place. In most mainstream languages, that happens pretty much immediately -- in those languages, 0.1 turns into the closest representable floating-point number straight away. But it doesn't have to work like that. That conversion could be delayed if it turns out be more useful. I suspect performance is not severely diminished by having this conversion done later.
And that is why keeping I say keeping 0.1 as a rational value, for as long as it makes sense to, is the Perlish way to do things. One of the ongoing themes in the Perl language is that "how you use a value" is more important than what type the value is -- e.g. a scalar *is* a number because you happen to use it in numeric operations, not because it has some kind of intrinsic "numberness". So if you have a value and you keep doing fairly sane, rational-value operations on it, why not keep it as a rational for as long as possible?
As noted by Cyberax, the denominator can easily blow up if you happen to use very *non*-rational operations on it. But I suspect the people doing such operations would be quite happen for it to switch to floating-point when that happens.
Posted Jul 19, 2015 18:08 UTC (Sun)
by Cyberax (✭ supporter ✭, #52523)
[Link] (54 responses)
I'm a great believer that such things must be done explicitly. Want a rational? Sure, use a Rat type that limit you to sane operations representable with rational types (i.e. no transcedentals, easy on division, etc.). It might even be useful occasionally.
If you want speed, then use f64/f32 - they have known problems, but these problems are _known_ and they are taught in every CS 101 course. And floats are fast.
If you want "calculator-like" arithmetic with an occasional transcedental (think interest rate computation) then use fixed-point decimals. That's what people do in finance.
Mixing all three of them is a recipe for disaster. There's a reason this picture describes Perl6 pretty succinctly: http://bleaklow.com/images/2003/p6_cover_big.gif
Posted Jul 20, 2015 8:41 UTC (Mon)
by epa (subscriber, #39769)
[Link]
Posted Jul 23, 2015 1:14 UTC (Thu)
by dvdeug (guest, #10998)
[Link] (52 responses)
Posted Jul 23, 2015 17:51 UTC (Thu)
by Cyberax (✭ supporter ✭, #52523)
[Link] (49 responses)
Posted Jul 23, 2015 22:36 UTC (Thu)
by dvdeug (guest, #10998)
[Link] (48 responses)
I don't see how this is any different from what you're talking about with Perl. The type choices aren't static; they depend on the input types.
Posted Jul 23, 2015 22:51 UTC (Thu)
by Cyberax (✭ supporter ✭, #52523)
[Link] (47 responses)
Posted Jul 23, 2015 23:42 UTC (Thu)
by dvdeug (guest, #10998)
[Link] (7 responses)
I don't know what you meant by that; it is not true for the two obvious meanings. Untyped could mean that variables at compile time don't have defined types, as is true in both Python and Perl, or it could mean that values stored in variables don't have types at runtime or compile time, which is true for assembly languages and BLISS, but by no means Python and Perl.
Yes, Perl implicitly converts strings to either integers or floats before feeding it to the "+" operator, whereas Python doesn't. Python is hardly predictable, though; if your function takes two arguments and adds them, it could be adding integers or floats or any thing that overloads "+".
The big difference I see is the silent conversion of strings, and I suspect that's part of a bigger pattern of silent conversions in Perl that Python does have. But if you're dealing with just numbers, I don't see the Python model as being all that different from the Perl model.
Posted Jul 24, 2015 6:18 UTC (Fri)
by raiph (guest, #89283)
[Link]
In Perl 6, variables are a kind of container. Containers in Perl 6 have a container type. For example, by default, an `@array` variable has an `Array` container type:
my @foo;
Container types have an 'of' type, the type of the things contained in the container. So one might have an `Array of Int`.
my Int @bar;
> or it could mean that values stored in variables don't have types at runtime or compile time
Values have a static type in Perl 6.
say 42.WHAT # (Int)
Binding of values to containers can have additional dynamic constraints, used to select or reject arguments based on their run-time value not just their compile time type.
subset NameOfFileThatExists of Str where *.IO.e;
"file".IO.e returns True if "file" exists in the current directory. So the bar("foo") call will dispatch to the first bar if "foo" exists and to the second bar if not.
Posted Jul 24, 2015 8:26 UTC (Fri)
by Cyberax (✭ supporter ✭, #52523)
[Link] (5 responses)
Actually, I got bitten by it today. As if on cue, someone used "==" to compare numeric values in Perl, and it even worked fine. That is, until someone started using fractional values as an input.
Posted Jul 24, 2015 8:50 UTC (Fri)
by dvdeug (guest, #10998)
[Link] (4 responses)
If you want to argue that strings should not silently convert to numbers, that's an argument. It seems far away from any discussion of rational numbers in Perl 6.
"use warnings" would tell you if you use "==" on strings. There's shared responsibility when you screw up by using a questionable feature in a language that the system you use has warnings on.
Posted Jul 24, 2015 9:34 UTC (Fri)
by rsidd (subscriber, #2582)
[Link] (1 responses)
What happens when interfacing with a C library (say GSL)? Are these "rationals" then converted into floats before calling? And are the return values converted back to "rationals"?
Posted Jul 24, 2015 19:19 UTC (Fri)
by raiph (guest, #89283)
[Link]
I can't imagine any language doing that. If your comment is aimed at Perl (5 or 6) then I think this is another manifestation of overall confusion about decimal fractions.
https://en.wikipedia.org/wiki/Decimal#Decimal_fractions
> Merely writing "3.14159" makes perl6 treat it as 314159/100000.
Just for emphasis: https://en.wikipedia.org/wiki/Decimal#Decimal_fractions
Hopefully you'll spend a few seconds reading this wikipedia link and you'll go "ahhh". :)
> What happens when interfacing with a C library (say GSL)?
One uses explicit typing in the signature (the list of parameters) of the Perl 6 functions that call the C functions. For example:
sub add(int32, int32) returns int32 is native("libcalculator") { * }
means that one must call the `add` function with two native 32 bit ints.
See http://doc.perl6.org/language/nativecall#Passing_and_Retu... for some more details.
> Are these "rationals" then converted into floats before calling?
They can be. It's controlled by explicit types and explicit type coercions in the signature. For example:
sub foo(Num(Rat), Num) ...
would be callable with:
foo(13/17, 26e3)
> And are the return values converted back to "rationals"?
Rakudo does not currently support signature based coercion of the return value; I don't know whether there's a plan to one day support that.
Posted Jul 24, 2015 20:43 UTC (Fri)
by raiph (guest, #89283)
[Link] (1 responses)
Perl 6 lets users directly specify input types for command line args:
perl6 -e 'sub MAIN (Int $int, Rat $rat, $string) { .print and "\t".print and .WHAT.say for $int, $rat, $string }' 42 2 Foo
Usage:
perl6 -e 'sub MAIN (Int $int, Rat $rat, $string) { .say and .WHAT.say for $int, $rat, $string }' 42 2/10 Foo
42
Perl 6 displays an automatically generated usage message until you pass arguments that correspond to the specified types.
When you do, it stores the typed values and the original string values so you can use either as appropriate to your needs.
The design docs suggest a similar mechanism is supposed to be applicable to input other than command line args but Rakudo doesn't support that yet afaik.
> You implicitly told Perl to convert them to numbers when you used a numeric operator on them
A nit: I'd say that treating operands of the `+` operator as numbers is explicit, not implicit.
Posted Jul 24, 2015 22:36 UTC (Fri)
by raiph (guest, #89283)
[Link]
And, if I did, I'd be wrong.
Posted Jul 24, 2015 0:26 UTC (Fri)
by mchapman (subscriber, #66589)
[Link] (2 responses)
You're making a false comparison there. It would be equally predictable in your Perl code had it used string concatenation instead.
I don't see a big difference between what Perl and Python are doing here. In both cases, the programmer has to know what kinds of values they are working with. With Python that's encoded in the value's type; with Perl that's encoded in the value itself. But either way, if you're taking in a string from the outside world and want to use it in your program you still need to *validate* that string -- in Perl you might use Scalar::Util::looks_like_number. Once validated, the way that value's type is encoded seems to be largely irrelevant.
Posted Jul 24, 2015 8:21 UTC (Fri)
by Cyberax (✭ supporter ✭, #52523)
[Link] (1 responses)
> I don't see a big difference between what Perl and Python are doing here. In both cases, the programmer has to know what kinds of values they are working with. With Python that's encoded in the value's type; with Perl that's encoded in the value itself.
Really.
> Scalar::Util::looks_like_number.
Posted Jul 24, 2015 11:46 UTC (Fri)
by mchapman (subscriber, #66589)
[Link]
Your Python code asked for it. It seems reasonable to expect that if you're comparing two code snippets you wanted them to do roughly the same thing.
> There's a fundamental difference here - with Perl6's braindead number treatment, $a + $b can mean DIFFERENT things for different numbers.
When does it not mean "add them together and produce a result that is the closest representable value to the answer"?
I have only passing familiarity with Perl 6, but I would be totally surprised if this were ever not the case.
But in Perl 5, whether a particular scalar should be treated as a number or a string depends only on the operator or builtin doing the interpretation. The + operator, for instance, interprets whatever you give it as a number.
There are rules as to how this interpretation is done, and those rules are consistently applied. It seems that you think those rules aren't legitimate because they are based on the value, rather than some "type" associated with that value. If that's actually the case, then I'm afraid no explanation is likely to satisfy you. That's simply how Perl works.
> Which number? Rational, float, integer, bigint?
Again, I refer to Perl 5 only.
Scalar::Util::looks_like_number returns a true value iff Perl thinks the scalar "looks like a number". It's really just as simple as that. "Looks like a number" is quite well-defined by Perl. It has nothing to do with "types", because Perl doesn't have types in that sense.
In practice, something that "looks like a number" can be used as if it actually were an integer or a float, assuming Perl actually had such things.
Why does it not matter whether it's an integer or a float? Simple: that only matters when you use the value. The integer-ness or float-ness of the value is not intrinsic to the value itself. If you use it in an operation that demands a float, it will act like a float. If you use it in an operation that demands an integer, it will act like an integer. Same for strings and booleans. The value isn't any of these, but it will happily act like one if you ask it to.
I really hope this explanation makes sense to you, even if you don't happen to like it. I'm out of ways to explain it!
Posted Jul 24, 2015 0:29 UTC (Fri)
by mrons (subscriber, #1751)
[Link] (9 responses)
You used the + operator so in "$a+$b" $a and $b are to be treated as numbers.
If you wanted $a and $b to be treated as strings, you would use "$a . $b"
If the python code, when I look at "a+b", I have to examine the rest of the code to determine what "a+b" means (addition or concatenation).
Posted Jul 24, 2015 8:18 UTC (Fri)
by Cyberax (✭ supporter ✭, #52523)
[Link] (8 responses)
> You used the + operator so in "$a+$b" $a and $b are to be treated as numbers.
And the answer, of course, is ANY OF THEM (depending on the Moon's current phase and Mars's relative position to it).
> If you wanted $a and $b to be treated as strings, you would use "$a . $b"
Posted Jul 26, 2015 16:17 UTC (Sun)
by flussence (guest, #85566)
[Link] (7 responses)
Perl 5 has errors for that. You can enable them by typing "-w" on the command line. They're off by default; little things like that are why code from 20 years ago still runs correctly in it unmodified.
I'd say any language where I can't be sure of the return type of "a + b" at a glance is more brain damaged.
Posted Jul 26, 2015 18:57 UTC (Sun)
by Cyberax (✭ supporter ✭, #52523)
[Link] (6 responses)
Posted Jul 26, 2015 20:06 UTC (Sun)
by dvdeug (guest, #10998)
[Link] (1 responses)
Posted Jul 26, 2015 23:02 UTC (Sun)
by anselm (subscriber, #2796)
[Link]
That applies to Perl, too – see “perldoc overload”.
Posted Jul 27, 2015 0:03 UTC (Mon)
by mchapman (subscriber, #66589)
[Link] (1 responses)
Perl guarantees it's a scalar. If the result is an integer, the scalar will "look like" an integer. If the result is a floating-point value, the scalar will "look like" an integer.
"Looks like" in Perl is as strong a guarantee as "has a type of" in Python or some other languages. I would like to think you are merely unwilling to acknowledge this idea, not incapable of it. Either way though, I don't think there's anything more I have to say on the matter.
Posted Jul 27, 2015 0:06 UTC (Mon)
by mchapman (subscriber, #66589)
[Link]
And obviously that should be "... floating-point value".
Posted Jul 27, 2015 17:08 UTC (Mon)
by flussence (guest, #85566)
[Link] (1 responses)
You're almost getting it now, yes. Don't you just hate it when mathematical operators are commutative and return *numbers*? How dare they.
Maybe I should have used a more extreme example: "(a + b) * a / b". Does that return a number, a string, or a runtime error?
Posted Jul 27, 2015 17:13 UTC (Mon)
by Cyberax (✭ supporter ✭, #52523)
[Link]
> Maybe I should have used a more extreme example: "(a + b) * a / b". Does that return a number, a string, or a runtime error?
Posted Jul 24, 2015 9:26 UTC (Fri)
by rschroev (subscriber, #4164)
[Link]
Maybe close enough for the discussion, but not exactly right. For the sake of correctness: Python variables (names really) aren't typed; Python values are. See e.g. Python Objects for an explanation how Python objects work.
Posted Jul 24, 2015 11:00 UTC (Fri)
by raiph (guest, #89283)
[Link] (24 responses)
Python variables are not typed.
> Not so with Perl.
Perl 6 variables are typed.
--------
A Perl 6 equivalent of your examples:
echo -e "1\n2" | perl6 -e 'say get() + get()'
Posted Jul 24, 2015 11:14 UTC (Fri)
by rsidd (subscriber, #2582)
[Link] (16 responses)
Why is this a good thing? Why isn't it telling me that I can't use the "+" operator on strings?
Posted Jul 24, 2015 11:48 UTC (Fri)
by mchapman (subscriber, #66589)
[Link] (14 responses)
Why should it? You asked for numeric addition; you got numeric addition. Why would you want it not do what you asked for?
Posted Jul 24, 2015 12:03 UTC (Fri)
by rsidd (subscriber, #2582)
[Link] (9 responses)
Posted Jul 24, 2015 12:28 UTC (Fri)
by mchapman (subscriber, #66589)
[Link] (1 responses)
It could be, yes. All code can be wrong.
I'm sure Perl 6 has a way to say "test that $a and $b are both Ints, throw an exception if they're not, otherwise add them together and, if the result can be stored in an Int, return that result, else throw an exception". You'll probably find it's a few more characters than + though.
Posted Jul 24, 2015 22:19 UTC (Fri)
by raiph (guest, #89283)
[Link]
The first thing I came up with:
($a,$b) ~~ :(Int, Int) or fail; $a + $b;
The `:(...)` bit is a literal signature, exactly like the ones that appear in function definitions. The `~~` "smartmatch" operator, with these operands, does a trial bind of the argument list on its left with the signature on its right.
I skipped testing the result because an Int can store arbitrarily large integers, and if all of RAM was consumed by a truly vast integer, an exception would (should) be raised by lower levels of the stack.
Posted Jul 24, 2015 21:21 UTC (Fri)
by dvdeug (guest, #10998)
[Link] (6 responses)
* I found that frustrating in the early 90s, as C was widely available and PL/I was not.
Posted Jul 25, 2015 4:12 UTC (Sat)
by rsidd (subscriber, #2582)
[Link] (5 responses)
Posted Jul 25, 2015 5:02 UTC (Sat)
by dvdeug (guest, #10998)
[Link] (4 responses)
Posted Jul 25, 2015 11:56 UTC (Sat)
by anselm (subscriber, #2796)
[Link] (3 responses)
It's pretty safe to say that Python's use of indentation for structure was not a Haskell influence. This is fairly obvious considering that the ABC programming language, which Guido van Rossum worked on at CWI before starting Python, also used indentation for structure. ABC had been around for more than a decade before Python was released. List comprehensions, OTOH, were only added to Python way later, namely with version 2.0, which was released in 2000. It would not be entirely unreasonable to consider them influenced by Haskell. As far as the type systems of Perl and Python are concerned, I think there are considerable differences. The observation that Perl doesn't really differentiate between numbers and strings, calling them “scalars”, while in Python strings are a special case of a (“non-scalar”) container type that also includes tuples and lists would be one's first clue that the type systems of Perl and Python are not really very similar at all.
Posted Jul 25, 2015 12:37 UTC (Sat)
by dvdeug (guest, #10998)
[Link] (2 responses)
"Considerable" is in the eye of the beholder. When compared to Haskell, they look quite similar, both dynamic systems with heavy OO mixture and no type inference.
Posted Jul 26, 2015 3:19 UTC (Sun)
by mathstuf (subscriber, #69389)
[Link] (1 responses)
Maybe I'm just not parsing your statement properly, but Haskell does all kinds of type inference…
Posted Jul 26, 2015 18:47 UTC (Sun)
by nix (subscriber, #2304)
[Link]
When compared to Haskell, Perl and Python look quite similar, both dynamic systems with heavy OO mixture and no type inference.
Posted Jul 24, 2015 15:59 UTC (Fri)
by anselm (subscriber, #2796)
[Link] (3 responses)
The problem is really that, as far as the “+” operator in Perl (5, at least – I haven't looked at Perl 6) is concerned, "123foobar" or for that matter "bazquux" are bona-fide numbers and therefore perfectly eligible to be added numerically. This tends to throw people off at times when instead they expect their compiler or interpreter to complain about a type mismatch.
Having said that, in Perl you wouldn't expect “+” to do string concatenation because that operator is called “.”. Now as far as the “.” operator in Perl 5 is concerned, 123 and 3.1415 are bona-fide strings and therefore perfectly eligible to be concatenated.
I teach Perl classes (among other subjects) for a living and in my considered opinion it is not a simple language to teach. Perl's idiosyncratic approach to evaluating expressions is something that many people find difficult to get to grips with, and previous experience with saner languages doesn't really seem to help a lot. It's not that what Perl does is illogical – it does have a certain twisted logic to it –, it's just that it's strange. Also, to really appreciate Perl you need to know C, the shell, sed, and awk, and few people nowadays do (at least the ones who end up in my classes generally don't). These days I prefer teaching Python because for all its shortcomings it is much easier to explain to people.
Posted Jul 24, 2015 23:40 UTC (Fri)
by raiph (guest, #89283)
[Link] (2 responses)
Fwiw, Perl 6 no longer accepts "baz" as a number, insisting that a string must start with decimal digits if it's to successfully coerce to a number.
There's a saying on #perl6 that every DWIM ("Do What I Mean") has a corresponding WAT. One has to weigh the supposedly positive value of DWIMs against the negative value of their WAT(s).
I hear that, in your opinion, the WAT is not worth the DWIM, especially when it comes time to teach the language.
I'm curious if you can see and thus express any significant value to the DWIM even while it's not enough to counter the WAT?
> I teach Perl classes (among other subjects) for a living and in my considered opinion it is not a simple language to teach.
I'm curious what your student mix is between non-programmers learning programming by learning Perl and programmers in other languages learning Perl.
There are a bunch of programming teachers in the Perl community and I've watched their input help shape Perl 6, which was in part about cleaning up the language and making easy things easier. Perhaps you yourself contributed.
The upshot is that one can get a whole lot done with truly trivial code like:
say lines
> Also, to really appreciate Perl you need to know C, the shell, sed, and awk
Fwiw I don't think that applies to Perl 6.
Posted Jul 25, 2015 0:15 UTC (Sat)
by anselm (subscriber, #2796)
[Link] (1 responses)
Most of the people I've taught Perl to over the years were programmers with experience in other languages, ranging from Visual BASIC to things like C++ or Java. These people have the advantage that they already know about things like variables, conditionals, and loops. Stuff like $foo[1] vs. @foo[1] tends to confuse them, as does scalar context vs. list context in general. As I said, this stuff has its own twisted logic behind it, but from a language-learner POV it wasn't the smartest idea to design the language that way.
I'm getting the distinct impression that Perl 6 should not have been called Perl. If it ever actually comes around it will create lots of confusion among our customers because they will have to figure out whether they want us to teach Perl 5 or Perl 6.
Posted Jul 25, 2015 3:55 UTC (Sat)
by raiph (guest, #89283)
[Link]
Yeah. That's gone in Perl 6:
my @foo = 0,1,2,3; say @foo[1];
> scalar context vs. list context
Yeah. Context is still very much a thing in Perl 6.
> I'm getting the distinct impression that Perl 6 should not have been called Perl.
Right. I can see it being renamed sometime in the next 5 years, with the leading candidate new name being Camelia. But Larry has refused to even consider that prior to getting a 6.0.0 shipped (which is currently scheduled for this Christmas).
> If it ever actually comes around it will create lots of confusion among our customers because they will have to figure out whether they want us to teach Perl 5 or Perl 6.
I'm sure it's going to put in enough of an appearance globally to at least cause confusion. :)
> In any case, demand for Perl classes hereabouts has dwindled to near-zero anyway.
Where's here?
> I'm teaching way more Python these days than Perl, and I can't even say I'm sorry.
Sure. I like the Perl 5 community, and love Perl 6, but when I've eased newbies into scripting in the last few years I've started with Python, not Perl.
> I don't use Perl for new projects anymore. Not if the code will take more than one screenful of lines, anyway.
I think the same is true of a lot of folk.
The Perl 6 design is clearly aiming at programming-in-the-large just as much as it is scripting. But the only semi-serious test of its characteristics in that regard that I'm aware of is the compiler toolchain. So it seems like the jury is going to still be out for at least another few years on that.
Posted Jul 24, 2015 21:52 UTC (Fri)
by raiph (guest, #89283)
[Link]
Sorry, my previous comment may have been confusing. The default Perl 6 number parsing now rejects a string that does not start with a decimal number.
> $ perl6 -e 'say "2" ~ "2" '
> Why is this a good thing?
There are several things I can do with your question. I can consider it a simple, well-formed question and process it that way. I can consider it potentially dangerous, in part or whole, and process it on my own terms, picking out what's non-dangerous about the question and deal with that bit. Or I could just reject it as not something I am willing to process.
For subjective input, Python tends toward the third option, to keep itself and its users sane in their world. Perl tends towards the middle, to keep itself and its users sane in theirs.
> Why isn't it telling me that I can't use the "+" operator on strings?
Well, first, because you can. :)
If you don't want that you can stop it in a given lexical scope:
multi sub infix:<+> (Str, Any) { fail "nope" }
One of the design assumptions in Perl 6 is that companies, teams and individual developers, will want to tighten or loosen strictness to suit their own view of what's dangerous, what's ill formed. Perl 6 makes it simple to bundle such policies in to single `use` statements that apply lexically. And these can be added to the ecosystem so that those with a similar philosophical mindset for a particular use-case can easily follow the same policies.
Posted Jul 24, 2015 11:26 UTC (Fri)
by rsidd (subscriber, #2582)
[Link] (6 responses)
They're typed. The following is an example of how it should work.
>>> a = "2"
Posted Jul 24, 2015 11:55 UTC (Fri)
by mchapman (subscriber, #66589)
[Link] (5 responses)
No, they're not. Your code is printing out the types of the *values* inside those variables.
Python quite happily lets you do:
>>> a = 4
If these Python variables were typed, then the second assignment would throw an exception. It doesn't.
Posted Jul 24, 2015 12:11 UTC (Fri)
by rsidd (subscriber, #2582)
[Link] (4 responses)
Posted Jul 24, 2015 12:24 UTC (Fri)
by mchapman (subscriber, #66589)
[Link] (2 responses)
OK, this just sounds like a problem of nomenclature. When I think of "variable", I think of "the symbol typed by the programmer", not "the value to which that symbol is currently referring".
Posted Jul 24, 2015 16:00 UTC (Fri)
by peter-b (guest, #66996)
[Link] (1 responses)
1. The symbol
Most programming languages attach type annotations to (2) or (3).
Posted Jul 24, 2015 16:15 UTC (Fri)
by anselm (subscriber, #2796)
[Link]
As far as Python is concerned, it is counterproductive to think of variables in terms of “slots” that can have “values” stored in them because that isn't really how the language works. Names in Python are really more like sticky labels attached to objects. If you stick your label on a new object, the type of the previous object you stuck it on doesn't matter, but as long as the label sticks to the same object, the type of that object determines what you get to do with it. Also, objects can have more than one label sticking to them.
Posted Jul 24, 2015 21:46 UTC (Fri)
by dvdeug (guest, #10998)
[Link]
r_t funct (a_t a, b_t b) {return a + b;}
a, b and the return value all have specific types known at compile time and invariant at runtime. On the other hand, you can pass values of arbitrary type to
def add (a, b): return a + b
and a and b and the return value have no types at compile time, and can have a number of different types during the runtime of the program. There's a big difference there.
And it seems weird to say that Python variables are typed in this sense; it's like bragging that Python supports lowercase characters, except that way more programming language (implementations) have had problems with lowercase characters then have not had typed variables in this sense. As far as my memory will reach, only BLISS of all the non-assembly languages has not had types attached to their values either at compile or runtime.
Posted Jul 24, 2015 4:48 UTC (Fri)
by raiph (guest, #89283)
[Link] (1 responses)
Posted Jul 24, 2015 6:37 UTC (Fri)
by dvdeug (guest, #10998)
[Link]
Posted Jul 18, 2015 19:55 UTC (Sat)
by flussence (guest, #85566)
[Link]
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
No. Your 'full precision' actually means "precision loss".
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
The π value built in to Perl 6 is stored as a floating point number
Ok, so π is built in -- is every conceivable required irrational also built in? e I would guess, but what about the golden ratio, the Euler-Mascheroni constant, etc etc? What about physical constants like the electronic charge, Planck's constant, etc, which are quantities measured to some accuracy and not exact fractions?
whereas floating point can go wrong at one digit after the decimal point, such as with `0.1 + 0.2 - 0.3`.
Huh? python (both 2 and 3) give me 5.551115123125783e-17 which is 17 digits after the decimal point, not 1 digit. Who exactly cares about this? If you were building a football stadium and your calculation gave you this sort of error, you would be wrong by one-hundredth the radius of an atomic nucleus.
Given that Perl 6 supports accurate rational processing it makes little sense to treat `123456789.987654321` as anything other than 123456789987654321/1000000000.
This is exactly where we disagree. You think treating 123456789.987654321 as a fraction is reasonable and even desirable. I think it is ridiculous. When you have a number with more than two or three digits after the decimal, it is almost certainly an inexact value -- a roundoff, or a measurement, or just a ballpark figure. There is absolutely no reason to treat it as a fraction. It hurts performance and does not improve accuracy. And when people want the fraction 1/10, they will write 1/10, not 0.1. Out of curiosity, were there any mathematical/scientific programmers behind these Perl 6 decisions?
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
Why do you hold Perl 6 to an absurd standard here but languages like Javascript, PHP and Python get a silent free pass?
I guess I wasn't clear enough. You said pi is a float because it's built-in and you know it is irrational, but if you write 3.14159265 it will be treated as the fraction 314159265/100000000. So I was asking what about other constants? If I write phi=1.61803398 why should perl assume that I have a fraction in mind? If I wanted a fraction I'd write a fraction. Other languages don't have this problem, you can define what constants you like and they will be treated as floats without coercion. In Perl 6, even you managed to get the coercion wrong here.
Numbers with just one or two digits after the decimal are considered an important use case. For example, writing 4.10 to represent 4 dollars and 10 cents.
This is a special case. For 4 dollars 10 cents, you will write 4.10, not 4.1 or 4.100. Changing how floats are treated in the language because of this special case is just weird. Counting in cents, as integers, is the sensible thing to do. But if you want smaller units than one cent (eg compound interest calculations), you want floats, not fractions.
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
Wol
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
Wol
An interview with Larry Wall (LinuxVoice)
> you have to be wary of multiplying [such] fields
An interview with Larry Wall (LinuxVoice)
Wol
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
In the meantime Perl 6 has basic math right
In the first place, as others have pointed out, this is not "right". One needs to recognise that floating point numbers are stored in binary, not decimal, and to a limited precision. And your claim about python 3 is wrong (this is an incompatible change from python 2 that will perhaps benefit newcomers, like my 8-year-old son, but trips me up).
the Perl 6 language is designed to be significantly better for number crunching than Perl 5
Better than perl 5 maybe, but the above example suggests that it will be worse than other languages that treat floating-point numbers as the hardware treats them. I.e., any workaround to get around the realities of how the hardware works is going to slow down your number-crunching for no practical benefit.
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
> Using ideone.com, Python 3.4:
> print(.1 - .2 + .3)
> returns
> 5.551115123125783e-17
> Imo accuracy-by-default and simplicity (math says 0.1 + 0.2 - 0.3 is zero and I would expect your 8 year old son to soon agree with that if he doesn't already) are both very practical benefits if they don't unduly slow down your number-crunching
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
Let's see, basic math says that 1/10 number doesn't exist. Every child knows that it's 0.00011(0011) and thus can't be written precisely inside a finite number of digits.
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
The problem is in details. If you just want to store a rational number then it's perfectly OK.
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
You can's satisfy all parties because use of fractions where floating point numbers are requested satisfy noone. It's like UTF-8 vs UTF-16. With UTF-8 you need to learn to live with with variable character width early and thus have a chance to produce working program. With UTF-16 your program pass all tests with flying colors (beause they all use BMP) yet fail for real users. Similarly with "fractions vs floating point numbers": if you language introduces floating point numbers early in (as in: 0.1 is not precisely 0.1) and distinguishes it from fractions (think guile: 7/2 will be 7/2 there it'll never automagically become 3.5) then you have a chance, if your language "does basic math" right then you will happily rely on it till you'll need sinus or square. Then you'll continue to rely in the fact that you language does basic math right, only to find out too late that An interview with Larry Wall (LinuxVoice)
sin2x + cos2x
is not always 1.
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
Python 2.7.10 (default, Jul 1 2015, 10:54:53)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 0
>>> b = 0
>>> a + b
0
>>> a = 0.0
>>> a + b
0.0
An interview with Larry Wall (LinuxVoice)
I don't see how this is any different from what you're talking about with Perl. The type choices aren't static; they depend on the input types.
Python variables are typed. Not so with Perl. So:
cat script.pl
$a=<STDIN>;
$b=<STDIN>;
print $a+$b;
echo -e "1\n2" | perl script.pl
3
echo -e "1.1\n2" | perl script.pl
3.1
echo -e "aa\n2" | perl script.pl
2
Now let's try that with Python:
$ cat script.py
import sys
a = sys.stdin.readline().strip()
b = sys.stdin.readline().strip()
print a+b
$ echo -e "1\n2" | python script.py
12
$ echo -e "1.1\n2" | python script.py
1.12
$ echo -e "aa\n2" | python script.py
aa2
Everything is _predictable_. If you want your input to be treated as floats - you need to spell it out explicitly:
$ cat script.py
import sys
a = float(sys.stdin.readline().strip())
b = float(sys.stdin.readline().strip())
print a+b
$ echo -e "1\n2" | python script.py
3.0
$ echo -e "1.1\n2" | python script.py
3.1
$ echo -e "aa\n2" | python script.py
Traceback (most recent call last):
File "script.py", line 2, in <module>
a = float(sys.stdin.readline().strip())
ValueError: could not convert string to float: aa
The Perl's way is simply madness incarnate, and instead of fixing it, they are making it even more complicated with lots of potential for mischief.
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
say @foo.WHAT; # (Array)
say @bar.WHAT # (Array[Int])
multi sub bar (NameOfFileThatExists $name) { ... }
multi sub bar ($doesntexist) { ... }
bar("foo")
An interview with Larry Wall (LinuxVoice)
There's a small but crucial difference - Python does not do any guessing when you read a variable from an external source. And there's no heuristics for incompatible types - you simply get errors.
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
If you want to argue that strings should not silently convert to numbers, that's an argument. It seems far away from any discussion of rational numbers in Perl 6.
Floats should not silently convert to rationals. And apparently this doesn't even require an operation. Merely writing "3.14159" makes perl6 treat it as 314159/100000. It's hard to imagine that this has security implications, though. Just needless complexity and inefficiency.
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
-e '...' <int> <rat> <string>
(Int+{orig-string[Str]})
2/10
(Rat+{orig-string[Str]})
Foo
(Str)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
Who said that I want concatenation? I simply want a behavior that doesn't depend on the exact details of input (which very well might be malicious).
There's a fundamental difference here - with Perl6's braindead number treatment, $a + $b can mean DIFFERENT things for different numbers.
Which number? Rational, float, integer, bigint?
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
It's not.
Which numbers? Rationals, floats, doubles, integers, bigints?
BTW, the fact that "+" happily works with strings without any errors is another braindead idea.
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
Ah, so you do agree that not being able to tell what comes out of "a+b" is braindamaged. Like not being able to tell whether it's float, rational or bigint.
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
In Python, "a + b" could return literally any type, any value. All it takes is the appropriate "def __add__ (a, b): return value" in some class somewhere.
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
WHICH numbers? They behave differently.
In Python it's either a floating number or a runtime error (barring bizarre operator overloads).
An interview with Larry Wall (LinuxVoice)
Python variables are typed.
An interview with Larry Wall (LinuxVoice)
3
echo -e "1.1\n2" | perl6 -e 'say get() + get()'
3.1
echo -e "aa\n2" | perl6 -e 'say get() + get()'
Cannot convert string to number: base-10 number must begin with valid digits or '.' in '⏏aa' (indicated by ⏏)
in block <unit> at -e:1
An interview with Larry Wall (LinuxVoice)
---
$ perl6 -e 'say "2" ~ "2" '
22
$ perl6 -e 'say "2" + "2"'
4
---
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
I'm curious what your student mix is between non-programmers learning programming by learning Perl and programmers in other languages learning Perl.
say lines
An interview with Larry Wall (LinuxVoice)
1
An interview with Larry Wall (LinuxVoice)
> 22
> $ perl6 -e 'say "2" + "2"'
> 4
say "2" + 4 # dies with "nope" message
An interview with Larry Wall (LinuxVoice)
>>> type(a)
<type 'str'>
>>> from fractions import Fraction as Fr
>>> a = Fr(3,4)
>>> type(a)
<class 'fractions.Fraction'>
>>> b = 2.5
>>> type(b)
<type 'float'>
>>> c = a*b
>>> print c
1.875
>>> type(c)
<type 'float'>
>>> d = Fr(4,5)
>>> e = a*d
>>> type(e)
<class 'fractions.Fraction'>
>>> print e
3/5
An interview with Larry Wall (LinuxVoice)
>>> a = "forty two"
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
2. The slot bound to the symbol
3. The value stored in the slot
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)