Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #67493 > unrolled thread

Re: Functional programming

Started byNed Batchelder <ned@nedbatchelder.com>
First post2014-03-02 20:27 -0500
Last post2014-03-03 16:35 -0800
Articles 20 on this page of 60 — 15 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Functional programming Ned Batchelder <ned@nedbatchelder.com> - 2014-03-02 20:27 -0500
    Re: Functional programming Rustom Mody <rustompmody@gmail.com> - 2014-03-03 03:45 -0800
      Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-03 23:20 +1100
        Re: Functional programming Rustom Mody <rustompmody@gmail.com> - 2014-03-03 05:48 -0800
          Re: Functional programming Rustom Mody <rustompmody@gmail.com> - 2014-03-03 05:51 -0800
          Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-04 01:00 +1100
            Re: Functional programming Rustom Mody <rustompmody@gmail.com> - 2014-03-03 06:08 -0800
              Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-04 01:23 +1100
                Re: Functional programming Rustom Mody <rustompmody@gmail.com> - 2014-03-03 06:38 -0800
                  Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-04 02:01 +1100
                    Re: Functional programming Rustom Mody <rustompmody@gmail.com> - 2014-03-03 07:28 -0800
                    Re: Functional programming Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-03 17:27 +0000
                      Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-04 05:37 +1100
                        Re: Functional programming Steven D'Aprano <steve@pearwood.info> - 2014-03-04 05:35 +0000
                          Re: Functional programming Rustom Mody <rustompmody@gmail.com> - 2014-03-03 21:59 -0800
                          Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-04 17:04 +1100
                            Re: Functional programming Rustom Mody <rustompmody@gmail.com> - 2014-03-03 22:20 -0800
                            Re: Functional programming Steven D'Aprano <steve@pearwood.info> - 2014-03-04 08:56 +0000
                              Re: Functional programming Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2014-03-04 11:56 +0100
                                Re: Functional programming Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-04 11:47 +0000
                                  Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-05 00:01 +1100
                                    OT Sine Rule [was Re: Functional programming] Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-04 14:25 +0000
                                      Re: OT Sine Rule [was Re: Functional programming] Tim Chase <python.list@tim.thechases.com> - 2014-03-04 08:37 -0600
                                      Re: OT Sine Rule [was Re: Functional programming] Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-04 14:42 +0000
                                      Re: OT Sine Rule [was Re: Functional programming] Chris Angelico <rosuav@gmail.com> - 2014-03-05 02:06 +1100
                                      Re: OT Sine Rule [was Re: Functional programming] Tim Chase <python.list@tim.thechases.com> - 2014-03-04 09:21 -0600
                                  Re: Functional programming Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2014-03-05 09:59 +0100
                                Re: Functional programming Marko Rauhamaa <marko@pacujo.net> - 2014-03-04 21:49 +0200
                                  Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-05 07:01 +1100
                                    Re: Functional programming Marko Rauhamaa <marko@pacujo.net> - 2014-03-04 22:50 +0200
                                      Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-05 08:06 +1100
                                        Re: Functional programming Marko Rauhamaa <marko@pacujo.net> - 2014-03-04 23:21 +0200
                                          Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-05 08:26 +1100
                                            Re: Functional programming Marko Rauhamaa <marko@pacujo.net> - 2014-03-04 23:43 +0200
                                              Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-05 08:52 +1100
                                              Re: Functional programming Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-03-05 12:57 +1300
                                                Re: Functional programming Marko Rauhamaa <marko@pacujo.net> - 2014-03-05 02:11 +0200
                              Re: Functional programming "BartC" <bc@freeuk.com> - 2014-03-04 13:30 +0000
                                Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-05 00:47 +1100
                                Re: Functional programming Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-04 14:05 +0000
                                  Re: Functional programming Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-04 14:55 +0000
                                    Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-05 02:13 +1100
                                    Re: Functional programming MRAB <python@mrabarnett.plus.com> - 2014-03-04 17:07 +0000
                                Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-05 01:17 +1100
                                Re: Functional programming Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-04 15:18 +0000
                                  Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-05 02:28 +1100
                                    Re: Functional programming Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-04 15:45 +0000
                                      Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-05 03:04 +1100
                                  Re: Functional programming Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2014-03-05 10:09 +0100
                                  Re: Functional programming "BartC" <bc@freeuk.com> - 2014-03-05 11:28 +0000
                                    Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-05 23:04 +1100
                                      Re: Functional programming Marko Rauhamaa <marko@pacujo.net> - 2014-03-05 14:11 +0200
                      Re: Functional programming Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-03-04 11:06 +1300
                        Re: Functional programming Ben Finney <ben+python@benfinney.id.au> - 2014-03-04 09:31 +1100
                          Re: Functional programming Grant Edwards <invalid@invalid.invalid> - 2014-03-04 14:59 +0000
                            Re: Functional programming Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-04 15:22 +0000
                        Re: Functional programming Chris Angelico <rosuav@gmail.com> - 2014-03-04 09:42 +1100
                        Re: Functional programming Ben Finney <ben+python@benfinney.id.au> - 2014-03-04 10:52 +1100
                      Re: Functional programming "BartC" <bc@freeuk.com> - 2014-03-04 09:41 +0000
              Re: Functional programming 88888 Dihedral <dihedral88888@gmail.com> - 2014-03-03 16:35 -0800

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#67670

FromChris Angelico <rosuav@gmail.com>
Date2014-03-05 00:01 +1100
Message-ID<mailman.7707.1393938071.18130.python-list@python.org>
In reply to#67664
On Tue, Mar 4, 2014 at 10:47 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> Not even close. I'd like to see the compiler that can work out for itself
> that this function is buggy:
>
> def sine_rule(side_a, side_b, angle_a):
>     """Return the angle opposite side_b."""
>     return math.sin(side_b/side_a)*angle_a
>
>
> If you don't remember your Sine Rule from trigonometry, that's okay.
> Trust me, the function is badly wrong. It's rubbish really.

I'm not entirely sure what it's trying to do, but you're taking the
sine of a ratio. That... seems wrong, gut-feeling-wise. You take the
sine of an angle and get a ratio, or the arcsine of a ratio and get an
angle. Also, trig functions apply only to right triangles, so the
other angle is either going to be 90°-angle_a or 90°, depending on
whether you want the angle opposite the hypotenuse or not.

But it's years since I studied any of that.

ChrisA

[toc] | [prev] | [next] | [standalone]


#67679 — OT Sine Rule [was Re: Functional programming]

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-03-04 14:25 +0000
SubjectOT Sine Rule [was Re: Functional programming]
Message-ID<5315e24a$0$29985$c3e8da3$5496439d@news.astraweb.com>
In reply to#67670
On Wed, 05 Mar 2014 00:01:01 +1100, Chris Angelico wrote:

> On Tue, Mar 4, 2014 at 10:47 PM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> Not even close. I'd like to see the compiler that can work out for
>> itself that this function is buggy:
>>
>> def sine_rule(side_a, side_b, angle_a):
>>     """Return the angle opposite side_b.""" return
>>     math.sin(side_b/side_a)*angle_a
>>
>>
>> If you don't remember your Sine Rule from trigonometry, that's okay.
>> Trust me, the function is badly wrong. It's rubbish really.
> 
> I'm not entirely sure what it's trying to do, 

The Sine Rule applies to any triangle, right-angled or not. I'm not going 
to try to draw an ASCII-art triangle here, so you just have to imagine 
one. Label the three sides "a", "b" and "c". Now label the angle opposite 
each side as "A", "B" and "C", so angle A is opposite side a, and so 
forth. The Sine Rule, or Law of Sines, tells us that the ratio of the 
length of a side and the sine of the angle opposite that side is constant 
for any triangle. That is:

a/sin(A) == b/sin(B) == c/sin(C)


Given any two sides and one corresponding angle, let's say a, b and A, 
you can calculate the other angle B. The correct formula would be:

B = asin( sin(A)*b/a )

which is not what my bogus function does.


> but you're taking the sine
> of a ratio. That... seems wrong, gut-feeling-wise. 

Well of course it's wrong. Given the intended geometric meanings of the 
function parameters, the quantity calculated is meaningless. But 
mathematically, it's okay to calculate the sine of a ratio of two other 
quantities. It's just a number. These even a whole lot of double-angle 
formulae that allow you to calculate sin(2*x) given sin(x), or sin(x/2) 
given sin(x), etc.

But, giving that ratio physical or geometric meaning is another story, 
and in this case the semantics of the function is entirely bogus. That 
was my point -- the compiler cannot possibly tell what the function is 
intended to do, it can only check that it is self-consistent.


> You take the sine of
> an angle and get a ratio, or the arcsine of a ratio and get an angle.
> Also, trig functions apply only to right triangles, 

Not quite. Or to put it another way, not at all :-)

Trig functions are *defined* in terms of right-angled triangles, but 
(say) the sine of 30° is 0.5 regardless of whether that 30° angle is in a 
right-angled triangle, an acute triangle or an obtuse triangle. 30° is 
30° regardless of what the rest of the triangle is doing.



Ask-me-about-versine-and-haversine-ly y'rs,

-- 
Steven D'Aprano
http://import-that.dreamwidth.org/

[toc] | [prev] | [next] | [standalone]


#67681 — Re: OT Sine Rule [was Re: Functional programming]

FromTim Chase <python.list@tim.thechases.com>
Date2014-03-04 08:37 -0600
SubjectRe: OT Sine Rule [was Re: Functional programming]
Message-ID<mailman.7716.1393943818.18130.python-list@python.org>
In reply to#67679
On 2014-03-04 14:25, Steven D'Aprano wrote:
> Ask-me-about-versine-and-haversine-ly y'rs,

More interested in a karosine, cuisine, and a limousine. ;-)

-tkc

[toc] | [prev] | [next] | [standalone]


#67682 — Re: OT Sine Rule [was Re: Functional programming]

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2014-03-04 14:42 +0000
SubjectRe: OT Sine Rule [was Re: Functional programming]
Message-ID<mailman.7717.1393944165.18130.python-list@python.org>
In reply to#67679
On 04/03/2014 14:37, Tim Chase wrote:
> On 2014-03-04 14:25, Steven D'Aprano wrote:
>> Ask-me-about-versine-and-haversine-ly y'rs,
>
> More interested in a karosine, cuisine, and a limousine. ;-)
>
> -tkc
>
>

What do you get if you differentiate versines, haversines, karosines, 
cuisines and limosines?

-- 
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.

Mark Lawrence

---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com

[toc] | [prev] | [next] | [standalone]


#67685 — Re: OT Sine Rule [was Re: Functional programming]

FromChris Angelico <rosuav@gmail.com>
Date2014-03-05 02:06 +1100
SubjectRe: OT Sine Rule [was Re: Functional programming]
Message-ID<mailman.7718.1393945575.18130.python-list@python.org>
In reply to#67679
On Wed, Mar 5, 2014 at 1:25 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
>
> The Sine Rule, or Law of Sines, tells us that the ratio of the
> length of a side and the sine of the angle opposite that side is constant
> for any triangle. That is:
>
> a/sin(A) == b/sin(B) == c/sin(C)

Oh! Right. Now I remember. Yeah. Still, it looks wrong to... well,
what I said next:

> On Wed, 05 Mar 2014 00:01:01 +1100, Chris Angelico wrote:
>> but you're taking the sine
>> of a ratio. That... seems wrong, gut-feeling-wise.
>
> Well of course it's wrong. Given the intended geometric meanings of the
> function parameters, the quantity calculated is meaningless. But
> mathematically, it's okay to calculate the sine of a ratio of two other
> quantities. It's just a number. These even a whole lot of double-angle
> formulae that allow you to calculate sin(2*x) given sin(x), or sin(x/2)
> given sin(x), etc.

What I meant there was "ratio of side lengths". The definition of sine
is that, in a right triangle, the ratio of the lengths of the side
opposite an angle and the hypotenuse is the sine of that angle. So I
consider sine to be a function that takes an angle and returns a
side-length-ratio, and arcsine does the reverse. It's like asking for
the length of an integer and getting back a string - it just looks
wrong. The sine of double an angle makes sense - it's still an angle.
You don't multiply an angle by a side length, you don't take the sine
of a number of meters per second, and you don't calculate the number
of parsecs it takes you to get to Kessel. The units are just wrong.
Maybe there's some specific situation where that makes sense, but I'd
call it "formula smell". And note that your corrected form still
applies the functions the way I describe - the units are maintained.
(Technically the sine of an angle is a pure number, a straight ratio.
I'm not sure that "pure number" is a unit - it's kinda the absence of
any unit - but that's still something to be maintained.)

> But, giving that ratio physical or geometric meaning is another story,
> and in this case the semantics of the function is entirely bogus. That
> was my point -- the compiler cannot possibly tell what the function is
> intended to do, it can only check that it is self-consistent.

Right. It's a consequence of a type system that distinguishes floating
point from string, but not angle_in_degrees from length_in_meters.
It's theoretically possible to build a type system that's like that
(sometimes you can subclass to do that, and create explicit operations
only), but I've never really felt the need to. But that's the theory
behind some forms of Hungarian notation - identifying a "data type"
concept that's broader than the compiler knows.

>> You take the sine of
>> an angle and get a ratio, or the arcsine of a ratio and get an angle.
>> Also, trig functions apply only to right triangles,
>
> Not quite. Or to put it another way, not at all :-)
>
> Trig functions are *defined* in terms of right-angled triangles, but
> (say) the sine of 30° is 0.5 regardless of whether that 30° angle is in a
> right-angled triangle, an acute triangle or an obtuse triangle. 30° is
> 30° regardless of what the rest of the triangle is doing.

Yes indeed. Like I said, I'm a bit rusty on all that, and forgot about
the ways of using them in non-right triangles :) But that 0.5 doesn't
have intrinsic meaning if you don't have a right triangle around it;
it needs something else to give it useful meaning, like another
angle's sine.

ChrisA

[toc] | [prev] | [next] | [standalone]


#67689 — Re: OT Sine Rule [was Re: Functional programming]

FromTim Chase <python.list@tim.thechases.com>
Date2014-03-04 09:21 -0600
SubjectRe: OT Sine Rule [was Re: Functional programming]
Message-ID<mailman.7721.1393946468.18130.python-list@python.org>
In reply to#67679
On 2014-03-04 14:42, Mark Lawrence wrote:
> What do you get if you differentiate versines, haversines,
> karosines, cuisines and limosines?

Well, with cuisines, you can usually differentiate by seasoning:
your Tex/Mex is spicier and tends to have chili & cumin, while your
Indian tends to lean more towards the garam masala.

With your limosines, you have stretch and non-stretch, and some are
these crazy contraptions made out of Hummers or buses rather than
luxury sedans.

And if I could spell "kerosine" instead of "karosine", I guess they
would differentiate from other hydrocarbons by the length of the
carbon chain. ;-)

-tkc

[toc] | [prev] | [next] | [standalone]


#67826

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2014-03-05 09:59 +0100
Message-ID<mailman.7801.1394009956.18130.python-list@python.org>
In reply to#67664
Op 04-03-14 12:47, Steven D'Aprano schreef:

> On Tue, 04 Mar 2014 11:56:07 +0100, Antoon Pardon wrote:
>
>> Op 04-03-14 09:56, Steven D'Aprano schreef:
>>>> If you
>>>> explicitly say that this is an int, then yes, that should be
>>>> disallowed;
>>> It's that "explicitly" part that doesn't follow. Having to manage types
>>> is the most tedious, boring, annoying, *unproductive* part of languages
>>> like Java, C and Pascal. Almost always, you're telling the compiler
>>> stuff that it can work out for itself.
>> In the same way writing unit tests is the most tedious, boring,
>> annoying, *unproductive* part. 
> Actually, I like writing unit tests. How do you know what the function 
> does until you test it? I'm not a TDD fanatic, but often I write tests 
> before I write the code, and there's really nothing nicer than seeing a 
> whole lot of failing unit tests suddenly start working.

You examine the code. Just like you examine the code to interfere the type. 

> Well, maybe a nice BLT sandwich, when the bacon is nice and lean and the 
> lettuce crisp and the tomato flavourful and not too soggy. But other than 
> that, writing unit tests and seeing them pass is great.
>
> On the other hand, writing
>
>     int n, m
>     double x, y
>
> and similar three hundred times throughout your program is not terribly 
> exciting. Even when it compiles, it doesn't mean it works.

Even if your unit tests pass, that doesn't mean your program works.
 

>> Amost always you are giving the program 
>> results it can work out for itself.
> Not even close. I'd like to see the compiler that can work out for itself 
> that this function is buggy:

Who said anything about buggy. If you want to test the function add1, what do you do?
You call for example add1(5) and check that it is equal to 6. In other words you provide
the result yourself you want the function to produce.

> def sine_rule(side_a, side_b, angle_a):
>     """Return the angle opposite side_b."""
>     return math.sin(side_b/side_a)*angle_a
>
>
> If you don't remember your Sine Rule from trigonometry, that's okay. 
> Trust me, the function is badly wrong. It's rubbish really. But short of 
> some really impressive AI coupled with a Mathematica-level of maths 
> knowledge, how is the compiler supposed to know that?
>
> Static type testing, while valuable, cannot tell you that the program 
> does what you wanted it to do.

In the same way it can't interfere the return type you want the function to have.

[toc] | [prev] | [next] | [standalone]


#67712

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-03-04 21:49 +0200
Message-ID<87bnxloibq.fsf@elektro.pacujo.net>
In reply to#67658
Antoon Pardon <antoon.pardon@rece.vub.ac.be>:

> In the same way writing unit tests is the most tedious, boring,
> annoying, *unproductive* part. Amost always you are giving the program
> results it can work out for itself.

Undoubtedly, explicit type declarations add a dimension of quality to
software. However, they also significantly reduce readability and tempt
you to dirty shortcuts (to avoid writing truckloads of boilerplate
code).

On the balance, I estimate the explicit style reduces code quality.

Example (found by a random Google search):

===JAVA BEGIN===========================================================

class WrappedSqlException extends RuntimeException {
    static final long serialVersionUID = 20130808044800000L;
    public WrappedSqlException(SQLException cause) { super(cause); }
    public SQLException getSqlException() { return (SQLException) getCause(); }
}

public ConnectionPool(int maxConnections, String url) throws SQLException {
    try {
        super(() -> {
            try {
                return DriverManager.getConnection(url);
            } catch ( SQLException ex ) {
                throw new WrappedSqlException(ex);
            }
        }, maxConnections);
    } catch (WrappedSqlException wse) {
        throw wse.getSqlException();
    }
}

===JAVA END=============================================================

===PYTHON BEGIN=========================================================

def __init__(self, max_connections, url):
    super().__init__(lambda: DriverManager.get_connection(url), max_connections)

===PYTHON END===========================================================

or, a bit less cryptically:

===PYTHON BEGIN=========================================================

def __init__(self, max_connections, url):
    def get_connection():
        return DriverManager.get_connection(url)

    super().__init__(get_connection, max_connections)

===PYTHON END===========================================================


Marko

[toc] | [prev] | [next] | [standalone]


#67714

FromChris Angelico <rosuav@gmail.com>
Date2014-03-05 07:01 +1100
Message-ID<mailman.7737.1393963318.18130.python-list@python.org>
In reply to#67712
On Wed, Mar 5, 2014 at 6:49 AM, Marko Rauhamaa <marko@pacujo.net> wrote:
> public ConnectionPool(int maxConnections, String url) throws SQLException {
>     try {
>         super(() -> {
>             try {
>                 return DriverManager.getConnection(url);
>             } catch ( SQLException ex ) {
>                 throw new WrappedSqlException(ex);
>             }
>         }, maxConnections);
>     } catch (WrappedSqlException wse) {
>         throw wse.getSqlException();
>     }
> }
>
> ===JAVA END=============================================================
>
> ===PYTHON BEGIN=========================================================
>
> def __init__(self, max_connections, url):
>     super().__init__(lambda: DriverManager.get_connection(url), max_connections)

You're not doing the same thing, though. The Java rigmarole is to
ensure that an SQLException thrown in getConnection will propagate up,
despite (presumably) something inside the equivalent of
super().__init__ that swallows SQLExceptions. Of course it looks
tidier when you don't do the messy bit.

ChrisA

[toc] | [prev] | [next] | [standalone]


#67717

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-03-04 22:50 +0200
Message-ID<8738ixofhl.fsf@elektro.pacujo.net>
In reply to#67714
Chris Angelico <rosuav@gmail.com>:

> On Wed, Mar 5, 2014 at 6:49 AM, Marko Rauhamaa <marko@pacujo.net> wrote:
>> public ConnectionPool(int maxConnections, String url) throws SQLException {
>>     try {
>>         super(() -> {
>>             try {
>>                 return DriverManager.getConnection(url);
>>             } catch ( SQLException ex ) {
>>                 throw new WrappedSqlException(ex);
>>             }
>>         }, maxConnections);
>>     } catch (WrappedSqlException wse) {
>>         throw wse.getSqlException();
>>     }
>> }
>>
>> ===JAVA END=============================================================
>
> You're not doing the same thing, though. The Java rigmarole is to
> ensure that an SQLException thrown in getConnection will propagate up,
> despite (presumably) something inside the equivalent of
> super().__init__ that swallows SQLExceptions. Of course it looks
> tidier when you don't do the messy bit.

See <URL: http://stackoverflow.com/questions/14039995/
java-8-mandatory-checked-exceptions-handling-in-lambd
a-expressions-for-standard>.

The "rigmarole" is trying to get around Java's mandatory exception
handling limitations, which Python doesn't have.

You are not allowed to pass a lambda to the super constructor that
throws an SQLException. To get around the limitation, a RuntimeException
wrapper is created to smuggle the SQLException through the compiler's
defenses. Any code is free to throw a RuntimeException.

I don't know, though, if this is that good of an example. I don't know
if the lambda gets called within the constructor or, as I would guess,
whenever a new connection is needed. The whole wrapping exercise would
be for nothing, then.

Here's a more prosaic example (probably contains errors):

===JAVA BEGIN===========================================================

private Map<TaxpayerIdNumber, Map<FormId, Form>> filings =
    new TreeMap<TaxpayerIdNumber, Map<FormId, Form>>();

class FormFiling {
    public FormFiling(TaxpayerIdNumber taxpayerId, Form form) {
        this.taxpayerId = taxpayerId;
        this.form = form;
    }

    public TaxpayerIdNumber getTaxpayerId() { return taxpayerId; }
    public Form getForm() { return form; }

    private TaxpayerIdNumber taxpayerId;
    private Form form;
};

List<FormFiling> getForms(FormId formId)
{
    List<FormFiling> forms = new LinkedList<FormFiling>();
    for (Map.Entry<TaxpayerIdNumber, Map<FormId, Form>> payerEntry :
         filings.entrySet()) {
        TaxpayerIdNumber taxpayerId = payerEntry.getKey();
        Map<FormId, Form> filing = payerEntry.getValue();
        if (filing.containsKey(formId))
            forms.add(new FormFiling(taxpayerId, filing.get(formId)))
    }
    return forms;
}

===JAVA END=============================================================

===PYTHON BEGIN=========================================================

filings = {}

def getForms(formId):
    forms = []
    for taxpayerId, filing in filings.iteritems():
         if formId in filing:
             forms.append((taxpayerId, filing[formId]))
    return forms

===PYTHON END===========================================================

or:

===PYTHON BEGIN=========================================================

filings = {}

def getForms(formId):
    return ((taxpayerId, filing[formId])
            for (taxpayerId, filing) in filings.iteritems()
            if formId in filing)

===PYTHON END===========================================================


Marko

[toc] | [prev] | [next] | [standalone]


#67721

FromChris Angelico <rosuav@gmail.com>
Date2014-03-05 08:06 +1100
Message-ID<mailman.7741.1393967180.18130.python-list@python.org>
In reply to#67717
On Wed, Mar 5, 2014 at 7:50 AM, Marko Rauhamaa <marko@pacujo.net> wrote:
> The "rigmarole" is trying to get around Java's mandatory exception
> handling limitations, which Python doesn't have.
>
> You are not allowed to pass a lambda to the super constructor that
> throws an SQLException. To get around the limitation, a RuntimeException
> wrapper is created to smuggle the SQLException through the compiler's
> defenses. Any code is free to throw a RuntimeException.
>

Oh, it's THAT problem. Well, it's still not really a fair comparison
of declared types. It shows how Python's much easier to work with, but
what you're showing off is the simpler exception handling :)

ChrisA

[toc] | [prev] | [next] | [standalone]


#67723

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-03-04 23:21 +0200
Message-ID<87txbdmzh3.fsf@elektro.pacujo.net>
In reply to#67721
Chris Angelico <rosuav@gmail.com>:

> Oh, it's THAT problem. Well, it's still not really a fair comparison
> of declared types. It shows how Python's much easier to work with, but
> what you're showing off is the simpler exception handling :)

The other example I gave is really bread-and-butter Java. An ergonomic
disaster and takes some staring at to figure out what's going on.

Note that Java doesn't possess typedef's so you really are pretty much
forced to write those < , < >>'s a lot.


Marko

[toc] | [prev] | [next] | [standalone]


#67724

FromChris Angelico <rosuav@gmail.com>
Date2014-03-05 08:26 +1100
Message-ID<mailman.7743.1393968417.18130.python-list@python.org>
In reply to#67723
On Wed, Mar 5, 2014 at 8:21 AM, Marko Rauhamaa <marko@pacujo.net> wrote:
> Chris Angelico <rosuav@gmail.com>:
>
>> Oh, it's THAT problem. Well, it's still not really a fair comparison
>> of declared types. It shows how Python's much easier to work with, but
>> what you're showing off is the simpler exception handling :)
>
> The other example I gave is really bread-and-butter Java. An ergonomic
> disaster and takes some staring at to figure out what's going on.
>
> Note that Java doesn't possess typedef's so you really are pretty much
> forced to write those < , < >>'s a lot.

C++ at least has typedefs, and in the newer standards, the 'auto'
keyword was repurposed.

ChrisA

[toc] | [prev] | [next] | [standalone]


#67727

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-03-04 23:43 +0200
Message-ID<87ppm1myhi.fsf@elektro.pacujo.net>
In reply to#67724
Chris Angelico <rosuav@gmail.com>:

> C++ at least has typedefs, and in the newer standards, the 'auto'
> keyword was repurposed.

Last I checked, C++ had no satisfactory way to express
callbacks/functors/listeners/lambdas. That's why Qt came up with a
metacompiler to supplement C++'s facilities.

No, STL and Boost can't remedy the situation.

The main reason was the unfortunate way method pointers were defined in
C++. C#'s delegates and Java's anonymous inner classes are something a
C++ developer can only dream of (unless something has already been
dreamt up in a recent standard).

Python, of course, has delegates:

   that_object.register_callback(self.handle_it)

Python doesn't have anonymous inner classes, but it has named inner
classes, and that's quite sufficient.


Marko

[toc] | [prev] | [next] | [standalone]


#67731

FromChris Angelico <rosuav@gmail.com>
Date2014-03-05 08:52 +1100
Message-ID<mailman.7749.1393969981.18130.python-list@python.org>
In reply to#67727
On Wed, Mar 5, 2014 at 8:43 AM, Marko Rauhamaa <marko@pacujo.net> wrote:
> Chris Angelico <rosuav@gmail.com>:
>
>> C++ at least has typedefs, and in the newer standards, the 'auto'
>> keyword was repurposed.
>
> Last I checked, C++ had no satisfactory way to express
> callbacks/functors/listeners/lambdas. That's why Qt came up with a
> metacompiler to supplement C++'s facilities.

I think one of the recent standards added some kind of closure for
callbacks. I tried to grok it and couldn't figure out what it was
doing, so I gave it up as a bad job. It got hairy. Really hairy.
Either that, or I was reading a poorly-written article, which is also
possible.

ChrisA

[toc] | [prev] | [next] | [standalone]


#67759

FromGregory Ewing <greg.ewing@canterbury.ac.nz>
Date2014-03-05 12:57 +1300
Message-ID<bnn7idFdlqhU1@mid.individual.net>
In reply to#67727
Marko Rauhamaa wrote:
> Python doesn't have anonymous inner classes, but it has named inner
> classes, and that's quite sufficient.

I would say it's Python's closures that make up for
not having Java's inner classes.

Or to put it another way, inner classes are Java's
kludgy way of working around a lack of closures.

-- 
Greg

[toc] | [prev] | [next] | [standalone]


#67761

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-03-05 02:11 +0200
Message-ID<878uspmrmu.fsf@elektro.pacujo.net>
In reply to#67759
Gregory Ewing <greg.ewing@canterbury.ac.nz>:

> Marko Rauhamaa wrote:
>> Python doesn't have anonymous inner classes, but it has named inner
>> classes, and that's quite sufficient.
>
> I would say it's Python's closures that make up for not having Java's
> inner classes.
>
> Or to put it another way, inner classes are Java's kludgy way of
> working around a lack of closures.

I actually quite like Java's inner classes. In fact, I think introducing
lambdas into Java was a grave mistake; the silly competitive pressure
from C# made them accept a very ugly and disheveled syntax.

Inner classes *are* closures. They are more general than (Lisp-style)
lambda's because they accept more than one method.

Python, of course, has all of the above.


Marko

[toc] | [prev] | [next] | [standalone]


#67674

From"BartC" <bc@freeuk.com>
Date2014-03-04 13:30 +0000
Message-ID<XzkRu.27$O_6.17@fx04.am4>
In reply to#67652
"Steven D'Aprano" <steve@pearwood.info> wrote in message
news:53159540$0$2923$c3e8da3$76491128@news.astraweb.com...

> It's that "explicitly" part that doesn't follow. Having to manage types
> is the most tedious, boring, annoying, *unproductive* part of languages
> like Java, C and Pascal. Almost always, you're telling the compiler stuff
> that it can work out for itself.

Isn't creating classes in Python similar to creating types elsewhere?

> In the same way that managing jumps for GOTO has been automated with for
> loops, while, etc., and managing memory has been automated, there's no
> good reason not to allow the compiler to manage types. Dynamically typed
> languages like Python do so at runtime. Type inference simply allows
> statically typed languages to do the same only at compile time.

Eliminating 'goto' is simple code-generation logic; type inference is more
of an art.

But declaring variables is not just about specifying a type; it registers
the name too so that misspelled names can be picked up very early rather
than at runtime (and that's if you're lucky).

> # Yes
> [1, 3, 4, 2, 5, 9]
> (1, "hello", None, 3.5)
>
> # No
> [1, "hello", None, 3.5]
>
>
> That is, lists are for collections of data of arbitrary length, tuples
> are for records or structs with dedicated fields.
>
> That convention is a bit weaker these days than it used to be. Tuples now
> have list-like methods, and we have namedtuple for record/struct-like
> objects with named fields.

(Aren't tuples immutable? They wouldn't work well for records then, because 
it would be impossible to change a field of a record.)

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#67675

FromChris Angelico <rosuav@gmail.com>
Date2014-03-05 00:47 +1100
Message-ID<mailman.7712.1393940878.18130.python-list@python.org>
In reply to#67674
On Wed, Mar 5, 2014 at 12:30 AM, BartC <bc@freeuk.com> wrote:
> But declaring variables is not just about specifying a type; it registers
> the name too so that misspelled names can be picked up very early rather
> than at runtime (and that's if you're lucky).

The two are separate. I don't know of any language that lets you
declare a type without catching the names, but there's certainly the
other way around (ECMAScript just has "var x, y, z"). It'd be
theoretically possible to have a Python-style "variable inference"
system (if I can call it that - the rules of "if you assign to it and
don't declare it as global/nonlocal, it's local") coupled with an
optional type declaration system; if you don't declare, then it can
hold anything. I just don't know of any language that does it.

>> That convention is a bit weaker these days than it used to be. Tuples now
>> have list-like methods, and we have namedtuple for record/struct-like
>> objects with named fields.
>
> (Aren't tuples immutable? They wouldn't work well for records then, because
> it would be impossible to change a field of a record.)

They are, including namedtuples. But an object() can be used that way,
if you want.

ChrisA

[toc] | [prev] | [next] | [standalone]


#67676

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2014-03-04 14:05 +0000
Message-ID<mailman.7713.1393941971.18130.python-list@python.org>
In reply to#67674
On 04/03/2014 13:30, BartC wrote:
>
> But declaring variables is not just about specifying a type; it registers
> the name too so that misspelled names can be picked up very early rather
> than at runtime (and that's if you're lucky).
>

I've said before that this, to me, is one of the major downsides of 
dynamic typing.  Once a statically typed language has been compiled the 
programmer can head down to the pub.  The programmer using dynamically 
typed languages has to hang around doing long, boring, tedious testing. 
  Unless they're using an IDE like Pydev and have Pylint turned on so it 
picks up errors as they type, in which case they can also head down to 
the pub.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.

Mark Lawrence

---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.python


csiph-web